diff options
Diffstat (limited to 'drivers/staging/gma500')
35 files changed, 0 insertions, 15452 deletions
diff --git a/drivers/staging/gma500/Kconfig b/drivers/staging/gma500/Kconfig deleted file mode 100644 index ce8bedaeaac..00000000000 --- a/drivers/staging/gma500/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -config DRM_PSB - tristate "Intel GMA500 KMS Framebuffer" - depends on DRM && PCI && X86 - select FB_CFB_COPYAREA - select FB_CFB_FILLRECT - select FB_CFB_IMAGEBLIT - select DRM_KMS_HELPER - select DRM_TTM - help - Say yes for an experimental KMS framebuffer driver for the - Intel GMA500 ('Poulsbo') graphics support. - diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile deleted file mode 100644 index db73ec6d812..00000000000 --- a/drivers/staging/gma500/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# -# KMS driver for the GMA500 -# -ccflags-y += -Iinclude/drm - -psb_gfx-y += psb_bl.o \ - psb_drv.o \ - psb_gem.o \ - psb_fb.o \ - psb_2d.o \ - psb_gtt.o \ - psb_intel_bios.o \ - psb_intel_opregion.o \ - psb_intel_display.o \ - psb_intel_i2c.o \ - psb_intel_lvds.o \ - psb_intel_modes.o \ - psb_intel_sdvo.o \ - psb_lid.o \ - psb_mmu.o \ - psb_powermgmt.o \ - psb_irq.o \ - mrst_crtc.o \ - mrst_lvds.o - -obj-$(CONFIG_DRM_PSB) += psb_gfx.o diff --git a/drivers/staging/gma500/TODO b/drivers/staging/gma500/TODO deleted file mode 100644 index f692ce1d242..00000000000 --- a/drivers/staging/gma500/TODO +++ /dev/null @@ -1,26 +0,0 @@ -- Test on more platforms -- Clean up the various chunks of unused code -- Sort out the power management side. Not important for Poulsbo but - matters for Moorestown -- Add Moorestown support (single pipe, no BIOS, no stolen memory, - some other differences) -- Sort out the bo and ttm code to support userframe buffers and DRM - interfaces rather than just faking it enough for a framebuffer -- Add 2D acceleration via console and DRM - -As per kernel policy and the in the interest of the safety of various -kittens there is no support or plans to add hooks for the closed user space -stuff. - - -Why bother ? -- Proper display configuration -- Can be made to work on Moorestown where VESA won't -- Works on systems where the VESA BIOS is bust or the tables are broken - without hacks -- 2D acceleration - -Currently tested on -+ Dell Mini 10 100x600 - - diff --git a/drivers/staging/gma500/mrst.h b/drivers/staging/gma500/mrst.h deleted file mode 100644 index 5e4aaeb3711..00000000000 --- a/drivers/staging/gma500/mrst.h +++ /dev/null @@ -1,217 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007-2011, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -/* MID device specific descriptors */ - -struct mrst_vbt { - s8 signature[4]; /*4 bytes,"$GCT" */ - u8 revision; - u8 size; - u8 checksum; - void *mrst_gct; -} __attribute__ ((packed)); - -struct mrst_timing_info { - u16 pixel_clock; - u8 hactive_lo; - u8 hblank_lo; - u8 hblank_hi:4; - u8 hactive_hi:4; - u8 vactive_lo; - u8 vblank_lo; - u8 vblank_hi:4; - u8 vactive_hi:4; - u8 hsync_offset_lo; - u8 hsync_pulse_width_lo; - u8 vsync_pulse_width_lo:4; - u8 vsync_offset_lo:4; - u8 vsync_pulse_width_hi:2; - u8 vsync_offset_hi:2; - u8 hsync_pulse_width_hi:2; - u8 hsync_offset_hi:2; - u8 width_mm_lo; - u8 height_mm_lo; - u8 height_mm_hi:4; - u8 width_mm_hi:4; - u8 hborder; - u8 vborder; - u8 unknown0:1; - u8 hsync_positive:1; - u8 vsync_positive:1; - u8 separate_sync:2; - u8 stereo:1; - u8 unknown6:1; - u8 interlaced:1; -} __attribute__((packed)); - -struct gct_r10_timing_info { - u16 pixel_clock; - u32 hactive_lo:8; - u32 hactive_hi:4; - u32 hblank_lo:8; - u32 hblank_hi:4; - u32 hsync_offset_lo:8; - u16 hsync_offset_hi:2; - u16 hsync_pulse_width_lo:8; - u16 hsync_pulse_width_hi:2; - u16 hsync_positive:1; - u16 rsvd_1:3; - u8 vactive_lo:8; - u16 vactive_hi:4; - u16 vblank_lo:8; - u16 vblank_hi:4; - u16 vsync_offset_lo:4; - u16 vsync_offset_hi:2; - u16 vsync_pulse_width_lo:4; - u16 vsync_pulse_width_hi:2; - u16 vsync_positive:1; - u16 rsvd_2:3; -} __attribute__((packed)); - -struct mrst_panel_descriptor_v1 { - u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ - /* 0x61190 if MIPI */ - u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ - u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ - u32 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */ - /* Register 0x61210 */ - struct mrst_timing_info DTD;/*18 bytes, Standard definition */ - u16 Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */ - /* Bit 0, Frequency, 15 bits,0 - 32767Hz */ - /* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */ - u16 Panel_MIPI_Display_Descriptor; - /*16 bits, Defined as follows: */ - /* if MIPI, 0x0000 if LVDS */ - /* Bit 0, Type, 2 bits, */ - /* 0: Type-1, */ - /* 1: Type-2, */ - /* 2: Type-3, */ - /* 3: Type-4 */ - /* Bit 2, Pixel Format, 4 bits */ - /* Bit0: 16bpp (not supported in LNC), */ - /* Bit1: 18bpp loosely packed, */ - /* Bit2: 18bpp packed, */ - /* Bit3: 24bpp */ - /* Bit 6, Reserved, 2 bits, 00b */ - /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ - /* Bit 14, Reserved, 2 bits, 00b */ -} __attribute__ ((packed)); - -struct mrst_panel_descriptor_v2 { - u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ - /* 0x61190 if MIPI */ - u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ - u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ - u8 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */ - /* Register 0x61210 */ - struct mrst_timing_info DTD;/*18 bytes, Standard definition */ - u16 Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/ - /*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/ - u8 Panel_Initial_Brightness;/* [7:0] 0 - 100% */ - /*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/ - u16 Panel_MIPI_Display_Descriptor; - /*16 bits, Defined as follows: */ - /* if MIPI, 0x0000 if LVDS */ - /* Bit 0, Type, 2 bits, */ - /* 0: Type-1, */ - /* 1: Type-2, */ - /* 2: Type-3, */ - /* 3: Type-4 */ - /* Bit 2, Pixel Format, 4 bits */ - /* Bit0: 16bpp (not supported in LNC), */ - /* Bit1: 18bpp loosely packed, */ - /* Bit2: 18bpp packed, */ - /* Bit3: 24bpp */ - /* Bit 6, Reserved, 2 bits, 00b */ - /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ - /* Bit 14, Reserved, 2 bits, 00b */ -} __attribute__ ((packed)); - -union mrst_panel_rx { - struct{ - u16 NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/ - /* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */ - u16 MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */ - /*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/ - u16 SupportedVideoTransferMode:2; /*0: Non-burst only */ - /* 1: Burst and non-burst */ - /* 2/3: Reserved */ - u16 HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/ - u16 DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/ - u16 ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/ - u16 BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */ - u16 Rsvd:5;/*5 bits,00000b */ - } panelrx; - u16 panel_receiver; -} __attribute__ ((packed)); - -struct mrst_gct_v1 { - union{ /*8 bits,Defined as follows: */ - struct { - u8 PanelType:4; /*4 bits, Bit field for panels*/ - /* 0 - 3: 0 = LVDS, 1 = MIPI*/ - /*2 bits,Specifies which of the*/ - u8 BootPanelIndex:2; - /* 4 panels to use by default*/ - u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ - /* the 4 MIPI DSI receivers to use*/ - } PD; - u8 PanelDescriptor; - }; - struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/ - union mrst_panel_rx panelrx[4]; /* panel receivers*/ -} __attribute__ ((packed)); - -struct mrst_gct_v2 { - union{ /*8 bits,Defined as follows: */ - struct { - u8 PanelType:4; /*4 bits, Bit field for panels*/ - /* 0 - 3: 0 = LVDS, 1 = MIPI*/ - /*2 bits,Specifies which of the*/ - u8 BootPanelIndex:2; - /* 4 panels to use by default*/ - u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ - /* the 4 MIPI DSI receivers to use*/ - } PD; - u8 PanelDescriptor; - }; - struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/ - union mrst_panel_rx panelrx[4]; /* panel receivers*/ -} __attribute__ ((packed)); - -struct mrst_gct_data { - u8 bpi; /* boot panel index, number of panel used during boot */ - u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */ - struct mrst_timing_info DTD; /* timing info for the selected panel */ - u32 Panel_Port_Control; - u32 PP_On_Sequencing;/*1 dword,Register 0x61208,*/ - u32 PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/ - u32 PP_Cycle_Delay; - u16 Panel_Backlight_Inverter_Descriptor; - u16 Panel_MIPI_Display_Descriptor; -} __attribute__ ((packed)); - -#define MODE_SETTING_IN_CRTC 0x1 -#define MODE_SETTING_IN_ENCODER 0x2 -#define MODE_SETTING_ON_GOING 0x3 -#define MODE_SETTING_IN_DSR 0x4 -#define MODE_SETTING_ENCODER_DONE 0x8 -#define GCT_R10_HEADER_SIZE 16 -#define GCT_R10_DISPLAY_DESC_SIZE 28 - diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c deleted file mode 100644 index e4a0c033b5b..00000000000 --- a/drivers/staging/gma500/mrst_crtc.c +++ /dev/null @@ -1,619 +0,0 @@ -/* - * Copyright © 2009 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <linux/i2c.h> -#include <linux/pm_runtime.h> - -#include <drm/drmP.h> -#include "psb_fb.h" -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "psb_intel_display.h" -#include "psb_powermgmt.h" - -struct psb_intel_range_t { - int min, max; -}; - -struct mrst_limit_t { - struct psb_intel_range_t dot, m, p1; -}; - -struct mrst_clock_t { - /* derived values */ - int dot; - int m; - int p1; -}; - -#define MRST_LIMIT_LVDS_100L 0 -#define MRST_LIMIT_LVDS_83 1 -#define MRST_LIMIT_LVDS_100 2 - -#define MRST_DOT_MIN 19750 -#define MRST_DOT_MAX 120000 -#define MRST_M_MIN_100L 20 -#define MRST_M_MIN_100 10 -#define MRST_M_MIN_83 12 -#define MRST_M_MAX_100L 34 -#define MRST_M_MAX_100 17 -#define MRST_M_MAX_83 20 -#define MRST_P1_MIN 2 -#define MRST_P1_MAX_0 7 -#define MRST_P1_MAX_1 8 - -static const struct mrst_limit_t mrst_limits[] = { - { /* MRST_LIMIT_LVDS_100L */ - .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, - .m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L}, - .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1}, - }, - { /* MRST_LIMIT_LVDS_83L */ - .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, - .m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83}, - .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0}, - }, - { /* MRST_LIMIT_LVDS_100 */ - .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, - .m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100}, - .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1}, - }, -}; - -#define MRST_M_MIN 10 -static const u32 mrst_m_converts[] = { - 0x2B, 0x15, 0x2A, 0x35, 0x1A, 0x0D, 0x26, 0x33, 0x19, 0x2C, - 0x36, 0x3B, 0x1D, 0x2E, 0x37, 0x1B, 0x2D, 0x16, 0x0B, 0x25, - 0x12, 0x09, 0x24, 0x32, 0x39, 0x1c, -}; - -static const struct mrst_limit_t *mrst_limit(struct drm_crtc *crtc) -{ - const struct mrst_limit_t *limit = NULL; - struct drm_device *dev = crtc->dev; - DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private; - - if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) - || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) { - switch (dev_priv->core_freq) { - case 100: - limit = &mrst_limits[MRST_LIMIT_LVDS_100L]; - break; - case 166: - limit = &mrst_limits[MRST_LIMIT_LVDS_83]; - break; - case 200: - limit = &mrst_limits[MRST_LIMIT_LVDS_100]; - break; - } - } else { - limit = NULL; - PSB_DEBUG_ENTRY("mrst_limit Wrong display type.\n"); - } - - return limit; -} - -/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ -static void mrst_clock(int refclk, struct mrst_clock_t *clock) -{ - clock->dot = (refclk * clock->m) / (14 * clock->p1); -} - -void mrstPrintPll(char *prefix, struct mrst_clock_t *clock) -{ - PSB_DEBUG_ENTRY("%s: dotclock = %d, m = %d, p1 = %d.\n", - prefix, clock->dot, clock->m, clock->p1); -} - -/** - * Returns a set of divisors for the desired target clock with the given refclk, - * or FALSE. Divisor values are the actual divisors for - */ -static bool -mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk, - struct mrst_clock_t *best_clock) -{ - struct mrst_clock_t clock; - const struct mrst_limit_t *limit = mrst_limit(crtc); - int err = target; - - memset(best_clock, 0, sizeof(*best_clock)); - - for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) { - for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max; - clock.p1++) { - int this_err; - - mrst_clock(refclk, &clock); - - this_err = abs(clock.dot - target); - if (this_err < err) { - *best_clock = clock; - err = this_err; - } - } - } - DRM_DEBUG("mrstFindBestPLL err = %d.\n", err); - - return err != target; -} - -/** - * Sets the power management mode of the pipe and plane. - * - * This code should probably grow support for turning the cursor off and back - * on appropriately at the same time as we're turning the pipe off/on. - */ -static void mrst_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - int dspbase_reg = (pipe == 0) ? MRST_DSPABASE : DSPBBASE; - int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; - u32 temp; - bool enabled; - - PSB_DEBUG_ENTRY("mode = %d, pipe = %d\n", mode, pipe); - - if (!gma_power_begin(dev, true)) - return; - - /* XXX: When our outputs are all unaware of DPMS modes other than off - * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. - */ - switch (mode) { - case DRM_MODE_DPMS_ON: - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - /* Enable the DPLL */ - temp = REG_READ(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) == 0) { - REG_WRITE(dpll_reg, temp); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - } - /* Enable the pipe */ - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) == 0) - REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); - /* Enable the plane */ - temp = REG_READ(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) == 0) { - REG_WRITE(dspcntr_reg, - temp | DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - } - - psb_intel_crtc_load_lut(crtc); - - /* Give the overlay scaler a chance to enable - if it's on this pipe */ - /* psb_intel_crtc_dpms_video(crtc, true); TODO */ - break; - case DRM_MODE_DPMS_OFF: - /* Give the overlay scaler a chance to disable - * if it's on this pipe */ - /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ - - /* Disable the VGA plane that we never use */ - REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); - /* Disable display plane */ - temp = REG_READ(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - REG_WRITE(dspcntr_reg, - temp & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - REG_READ(dspbase_reg); - } - - /* Next, disable display pipes */ - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) != 0) { - REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); - REG_READ(pipeconf_reg); - } - /* Wait for for the pipe disable to take effect. */ - psb_intel_wait_for_vblank(dev); - - temp = REG_READ(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) != 0) { - REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - } - - /* Wait for the clocks to turn off. */ - udelay(150); - break; - } - - enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF; - - /*Set FIFO Watermarks*/ - REG_WRITE(DSPARB, 0x3FFF); - REG_WRITE(DSPFW1, 0x3F88080A); - REG_WRITE(DSPFW2, 0x0b060808); - REG_WRITE(DSPFW3, 0x0); - REG_WRITE(DSPFW4, 0x08030404); - REG_WRITE(DSPFW5, 0x04040404); - REG_WRITE(DSPFW6, 0x78); - REG_WRITE(0x70400, REG_READ(0x70400) | 0x4000); - /* Must write Bit 14 of the Chicken Bit Register */ - - gma_power_end(dev); -} - -/** - * Return the pipe currently connected to the panel fitter, - * or -1 if the panel fitter is not present or not in use - */ -static int mrst_panel_fitter_pipe(struct drm_device *dev) -{ - u32 pfit_control; - - pfit_control = REG_READ(PFIT_CONTROL); - - /* See if the panel fitter is in use */ - if ((pfit_control & PFIT_ENABLE) == 0) - return -1; - return (pfit_control >> 29) & 3; -} - -static int mrst_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private; - int pipe = psb_intel_crtc->pipe; - int fp_reg = (pipe == 0) ? MRST_FPA0 : FPB0; - int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; - int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; - int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; - int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; - int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; - int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; - int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; - int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; - int refclk = 0; - struct mrst_clock_t clock; - u32 dpll = 0, fp = 0, dspcntr, pipeconf; - bool ok, is_sdvo = false; - bool is_crt = false, is_lvds = false, is_tv = false; - bool is_mipi = false; - struct drm_mode_config *mode_config = &dev->mode_config; - struct psb_intel_output *psb_intel_output = NULL; - uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN; - struct drm_encoder *encoder; - - PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe); - - if (!gma_power_begin(dev, true)) - return 0; - - memcpy(&psb_intel_crtc->saved_mode, - mode, - sizeof(struct drm_display_mode)); - memcpy(&psb_intel_crtc->saved_adjusted_mode, - adjusted_mode, - sizeof(struct drm_display_mode)); - - list_for_each_entry(encoder, &mode_config->encoder_list, head) { - - if (encoder->crtc != crtc) - continue; - - psb_intel_output = enc_to_psb_intel_output(encoder); - switch (psb_intel_output->type) { - case INTEL_OUTPUT_LVDS: - is_lvds = true; - break; - case INTEL_OUTPUT_SDVO: - is_sdvo = true; - break; - case INTEL_OUTPUT_TVOUT: - is_tv = true; - break; - case INTEL_OUTPUT_ANALOG: - is_crt = true; - break; - case INTEL_OUTPUT_MIPI: - is_mipi = true; - break; - } - } - - /* Disable the VGA plane that we never use */ - REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); - - /* Disable the panel fitter if it was on our pipe */ - if (mrst_panel_fitter_pipe(dev) == pipe) - REG_WRITE(PFIT_CONTROL, 0); - - REG_WRITE(pipesrc_reg, - ((mode->crtc_hdisplay - 1) << 16) | - (mode->crtc_vdisplay - 1)); - - if (psb_intel_output) - drm_connector_property_get_value(&psb_intel_output->base, - dev->mode_config.scaling_mode_property, &scalingType); - - if (scalingType == DRM_MODE_SCALE_NO_SCALE) { - /* Moorestown doesn't have register support for centering so - * we need to mess with the h/vblank and h/vsync start and - * ends to get centering */ - int offsetX = 0, offsetY = 0; - - offsetX = (adjusted_mode->crtc_hdisplay - - mode->crtc_hdisplay) / 2; - offsetY = (adjusted_mode->crtc_vdisplay - - mode->crtc_vdisplay) / 2; - - REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(hblank_reg, - (adjusted_mode->crtc_hblank_start - offsetX - 1) | - ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16)); - REG_WRITE(hsync_reg, - (adjusted_mode->crtc_hsync_start - offsetX - 1) | - ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16)); - REG_WRITE(vblank_reg, - (adjusted_mode->crtc_vblank_start - offsetY - 1) | - ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16)); - REG_WRITE(vsync_reg, - (adjusted_mode->crtc_vsync_start - offsetY - 1) | - ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16)); - } else { - REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | - ((adjusted_mode->crtc_hblank_end - 1) << 16)); - REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | - ((adjusted_mode->crtc_hsync_end - 1) << 16)); - REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | - ((adjusted_mode->crtc_vblank_end - 1) << 16)); - REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | - ((adjusted_mode->crtc_vsync_end - 1) << 16)); - } - - /* Flush the plane changes */ - { - struct drm_crtc_helper_funcs *crtc_funcs = - crtc->helper_private; - crtc_funcs->mode_set_base(crtc, x, y, old_fb); - } - - /* setup pipeconf */ - pipeconf = REG_READ(pipeconf_reg); - - /* Set up the display plane register */ - dspcntr = REG_READ(dspcntr_reg); - dspcntr |= DISPPLANE_GAMMA_ENABLE; - - if (pipe == 0) - dspcntr |= DISPPLANE_SEL_PIPE_A; - else - dspcntr |= DISPPLANE_SEL_PIPE_B; - - dev_priv->dspcntr = dspcntr |= DISPLAY_PLANE_ENABLE; - dev_priv->pipeconf = pipeconf |= PIPEACONF_ENABLE; - - if (is_mipi) - goto mrst_crtc_mode_set_exit; - - refclk = dev_priv->core_freq * 1000; - - dpll = 0; /*BIT16 = 0 for 100MHz reference */ - - ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock); - - if (!ok) { - PSB_DEBUG_ENTRY( - "mrstFindBestPLL fail in mrst_crtc_mode_set.\n"); - } else { - PSB_DEBUG_ENTRY("mrst_crtc_mode_set pixel clock = %d," - "m = %x, p1 = %x.\n", clock.dot, clock.m, - clock.p1); - } - - fp = mrst_m_converts[(clock.m - MRST_M_MIN)] << 8; - - dpll |= DPLL_VGA_MODE_DIS; - - - dpll |= DPLL_VCO_ENABLE; - - if (is_lvds) - dpll |= DPLLA_MODE_LVDS; - else - dpll |= DPLLB_MODE_DAC_SERIAL; - - if (is_sdvo) { - int sdvo_pixel_multiply = - adjusted_mode->clock / mode->clock; - - dpll |= DPLL_DVO_HIGH_SPEED; - dpll |= - (sdvo_pixel_multiply - - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; - } - - - /* compute bitmask from p1 value */ - dpll |= (1 << (clock.p1 - 2)) << 17; - - dpll |= DPLL_VCO_ENABLE; - - mrstPrintPll("chosen", &clock); - - if (dpll & DPLL_VCO_ENABLE) { - REG_WRITE(fp_reg, fp); - REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - /* Check the DPLLA lock bit PIPEACONF[29] */ - udelay(150); - } - - REG_WRITE(fp_reg, fp); - REG_WRITE(dpll_reg, dpll); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - - /* write it again -- the BIOS does, after all */ - REG_WRITE(dpll_reg, dpll); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - - REG_WRITE(pipeconf_reg, pipeconf); - REG_READ(pipeconf_reg); - psb_intel_wait_for_vblank(dev); - - REG_WRITE(dspcntr_reg, dspcntr); - psb_intel_wait_for_vblank(dev); - -mrst_crtc_mode_set_exit: - gma_power_end(dev); - return 0; -} - -static bool mrst_crtc_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -int mrst_pipe_set_base(struct drm_crtc *crtc, - int x, int y, struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - /* struct drm_i915_master_private *master_priv; */ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); - int pipe = psb_intel_crtc->pipe; - unsigned long start, offset; - /* FIXME: check if we need this surely MRST is pipe 0 only */ - int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE); - int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); - int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - u32 dspcntr; - int ret = 0; - - PSB_DEBUG_ENTRY("\n"); - - /* no fb bound */ - if (!crtc->fb) { - DRM_DEBUG("No FB bound\n"); - return 0; - } - - if (!gma_power_begin(dev, true)) - return 0; - - start = psbfb->gtt->offset; - offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); - - REG_WRITE(dspstride, crtc->fb->pitch); - - dspcntr = REG_READ(dspcntr_reg); - dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; - - switch (crtc->fb->bits_per_pixel) { - case 8: - dspcntr |= DISPPLANE_8BPP; - break; - case 16: - if (crtc->fb->depth == 15) - dspcntr |= DISPPLANE_15_16BPP; - else - dspcntr |= DISPPLANE_16BPP; - break; - case 24: - case 32: - dspcntr |= DISPPLANE_32BPP_NO_ALPHA; - break; - default: - DRM_ERROR("Unknown color depth\n"); - ret = -EINVAL; - goto pipe_set_base_exit; - } - REG_WRITE(dspcntr_reg, dspcntr); - - DRM_DEBUG("Writing base %08lX %08lX %d %d\n", start, offset, x, y); - if (0 /* FIXMEAC - check what PSB needs */) { - REG_WRITE(dspbase, offset); - REG_READ(dspbase); - REG_WRITE(dspsurf, start); - REG_READ(dspsurf); - } else { - REG_WRITE(dspbase, start + offset); - REG_READ(dspbase); - } - -pipe_set_base_exit: - gma_power_end(dev); - return ret; -} - -static void mrst_crtc_prepare(struct drm_crtc *crtc) -{ - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); -} - -static void mrst_crtc_commit(struct drm_crtc *crtc) -{ - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); -} - -const struct drm_crtc_helper_funcs mrst_helper_funcs = { - .dpms = mrst_crtc_dpms, - .mode_fixup = mrst_crtc_mode_fixup, - .mode_set = mrst_crtc_mode_set, - .mode_set_base = mrst_pipe_set_base, - .prepare = mrst_crtc_prepare, - .commit = mrst_crtc_commit, -}; - diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c deleted file mode 100644 index 4a08b74f5ff..00000000000 --- a/drivers/staging/gma500/mrst_lvds.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright © 2006-2009 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt <eric@anholt.net> - * Dave Airlie <airlied@linux.ie> - * Jesse Barnes <jesse.barnes@intel.com> - */ - -#include <linux/i2c.h> -#include <drm/drmP.h> -#include <asm/mrst.h> - -#include "psb_intel_bios.h" -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "psb_powermgmt.h" -#include <linux/pm_runtime.h> - -/* The max/min PWM frequency in BPCR[31:17] - */ -/* The smallest number is 1 (not 0) that can fit in the - * 15-bit field of the and then*/ -/* shifts to the left by one bit to get the actual 16-bit - * value that the 15-bits correspond to.*/ -#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF -#define BRIGHTNESS_MAX_LEVEL 100 - -/** - * Sets the power state for the panel. - */ -static void mrst_lvds_set_power(struct drm_device *dev, - struct psb_intel_output *output, bool on) -{ - u32 pp_status; - DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private; - PSB_DEBUG_ENTRY("\n"); - - if (!gma_power_begin(dev, true)) - return; - - if (on) { - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | - POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while ((pp_status & (PP_ON | PP_READY)) == PP_READY); - dev_priv->is_lvds_on = true; - } else { - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & - ~POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while (pp_status & PP_ON); - dev_priv->is_lvds_on = false; - pm_request_idle(&dev->pdev->dev); - } - - gma_power_end(dev); -} - -static void mrst_lvds_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct psb_intel_output *output = enc_to_psb_intel_output(encoder); - - PSB_DEBUG_ENTRY("\n"); - - if (mode == DRM_MODE_DPMS_ON) - mrst_lvds_set_power(dev, output, true); - else - mrst_lvds_set_power(dev, output, false); - - /* XXX: We never power down the LVDS pairs. */ -} - -static void mrst_lvds_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct psb_intel_mode_device *mode_dev = - enc_to_psb_intel_output(encoder)->mode_dev; - struct drm_device *dev = encoder->dev; - u32 lvds_port; - uint64_t v = DRM_MODE_SCALE_FULLSCREEN; - - PSB_DEBUG_ENTRY("\n"); - - if (!gma_power_begin(dev, true)) - return; - - /* - * The LVDS pin pair will already have been turned on in the - * psb_intel_crtc_mode_set since it has a large impact on the DPLL - * settings. - */ - lvds_port = (REG_READ(LVDS) & - (~LVDS_PIPEB_SELECT)) | - LVDS_PORT_EN | - LVDS_BORDER_EN; - - if (mode_dev->panel_wants_dither) - lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE; - - REG_WRITE(LVDS, lvds_port); - - drm_connector_property_get_value( - &enc_to_psb_intel_output(encoder)->base, - dev->mode_config.scaling_mode_property, - &v); - - if (v == DRM_MODE_SCALE_NO_SCALE) - REG_WRITE(PFIT_CONTROL, 0); - else if (v == DRM_MODE_SCALE_ASPECT) { - if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) || - (mode->hdisplay != adjusted_mode->crtc_hdisplay)) { - if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) == - (mode->hdisplay * adjusted_mode->crtc_vdisplay)) - REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); - else if ((adjusted_mode->crtc_hdisplay * - mode->vdisplay) > (mode->hdisplay * - adjusted_mode->crtc_vdisplay)) - REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | - PFIT_SCALING_MODE_PILLARBOX); - else - REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | - PFIT_SCALING_MODE_LETTERBOX); - } else - REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); - } else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/ - REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); - - gma_power_end(dev); -} - - -static const struct drm_encoder_helper_funcs mrst_lvds_helper_funcs = { - .dpms = mrst_lvds_dpms, - .mode_fixup = psb_intel_lvds_mode_fixup, - .prepare = psb_intel_lvds_prepare, - .mode_set = mrst_lvds_mode_set, - .commit = psb_intel_lvds_commit, -}; - -static struct drm_display_mode lvds_configuration_modes[] = { - /* hard coded fixed mode for TPO LTPS LPJ040K001A */ - { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 33264, 800, 836, - 846, 1056, 0, 480, 489, 491, 525, 0, 0) }, - /* hard coded fixed mode for LVDS 800x480 */ - { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 30994, 800, 801, - 802, 1024, 0, 480, 481, 482, 525, 0, 0) }, - /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */ - { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1072, - 1104, 1184, 0, 600, 603, 604, 608, 0, 0) }, - /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */ - { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1104, - 1136, 1184, 0, 600, 603, 604, 608, 0, 0) }, - /* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */ - { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 48885, 1024, 1124, - 1204, 1312, 0, 600, 607, 610, 621, 0, 0) }, - /* hard coded fixed mode for LVDS 1024x768 */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, - 1184, 1344, 0, 768, 771, 777, 806, 0, 0) }, - /* hard coded fixed mode for LVDS 1366x768 */ - { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 77500, 1366, 1430, - 1558, 1664, 0, 768, 769, 770, 776, 0, 0) }, -}; - -/* Returns the panel fixed mode from configuration. */ - -static struct drm_display_mode * -mrst_lvds_get_configuration_mode(struct drm_device *dev) -{ - struct drm_display_mode *mode = NULL; - struct drm_psb_private *dev_priv = dev->dev_private; - struct mrst_timing_info *ti = &dev_priv->gct_data.DTD; - - if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/ - mode = kzalloc(sizeof(*mode), GFP_KERNEL); - if (!mode) - return NULL; - - mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; - mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; - mode->hsync_start = mode->hdisplay + \ - ((ti->hsync_offset_hi << 8) | \ - ti->hsync_offset_lo); - mode->hsync_end = mode->hsync_start + \ - ((ti->hsync_pulse_width_hi << 8) | \ - ti->hsync_pulse_width_lo); - mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \ - ti->hblank_lo); - mode->vsync_start = \ - mode->vdisplay + ((ti->vsync_offset_hi << 4) | \ - ti->vsync_offset_lo); - mode->vsync_end = \ - mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \ - ti->vsync_pulse_width_lo); - mode->vtotal = mode->vdisplay + \ - ((ti->vblank_hi << 8) | ti->vblank_lo); - mode->clock = ti->pixel_clock * 10; -#if 0 - printk(KERN_INFO "hdisplay is %d\n", mode->hdisplay); - printk(KERN_INFO "vdisplay is %d\n", mode->vdisplay); - printk(KERN_INFO "HSS is %d\n", mode->hsync_start); - printk(KERN_INFO "HSE is %d\n", mode->hsync_end); - printk(KERN_INFO "htotal is %d\n", mode->htotal); - printk(KERN_INFO "VSS is %d\n", mode->vsync_start); - printk(KERN_INFO "VSE is %d\n", mode->vsync_end); - printk(KERN_INFO "vtotal is %d\n", mode->vtotal); - printk(KERN_INFO "clock is %d\n", mode->clock); -#endif - } else - mode = drm_mode_duplicate(dev, &lvds_configuration_modes[2]); - - drm_mode_set_name(mode); - drm_mode_set_crtcinfo(mode, 0); - - return mode; -} - -/** - * mrst_lvds_init - setup LVDS connectors on this device - * @dev: drm device - * - * Create the connector, register the LVDS DDC bus, and try to figure out what - * modes we can display on the LVDS panel (if present). - */ -void mrst_lvds_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev) -{ - struct psb_intel_output *psb_intel_output; - struct drm_connector *connector; - struct drm_encoder *encoder; - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - struct edid *edid; - int ret = 0; - struct i2c_adapter *i2c_adap; - struct drm_display_mode *scan; /* *modes, *bios_mode; */ - - PSB_DEBUG_ENTRY("\n"); - - psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL); - if (!psb_intel_output) - return; - - psb_intel_output->mode_dev = mode_dev; - connector = &psb_intel_output->base; - encoder = &psb_intel_output->enc; - dev_priv->is_lvds_on = true; - drm_connector_init(dev, &psb_intel_output->base, - &psb_intel_lvds_connector_funcs, - DRM_MODE_CONNECTOR_LVDS); - - drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs, - DRM_MODE_ENCODER_LVDS); - - drm_mode_connector_attach_encoder(&psb_intel_output->base, - &psb_intel_output->enc); - psb_intel_output->type = INTEL_OUTPUT_LVDS; - - drm_encoder_helper_add(encoder, &mrst_lvds_helper_funcs); - drm_connector_helper_add(connector, - &psb_intel_lvds_connector_helper_funcs); - connector->display_info.subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - - drm_connector_attach_property(connector, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_FULLSCREEN); - drm_connector_attach_property(connector, - dev_priv->backlight_property, - BRIGHTNESS_MAX_LEVEL); - - mode_dev->panel_wants_dither = false; - if (dev_priv->vbt_data.size != 0x00) - mode_dev->panel_wants_dither = (dev_priv->gct_data. - Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE); - - /* - * LVDS discovery: - * 1) check for EDID on DDC - * 2) check for VBT data - * 3) check to see if LVDS is already on - * if none of the above, no panel - * 4) make sure lid is open - * if closed, act like it's not there for now - */ - - /* This ifdef can go once the cpu ident stuff is cleaned up in arch */ -#if defined(CONFIG_X86_MRST) - if (mrst_identify_cpu()) - i2c_adap = i2c_get_adapter(2); - else /* Oaktrail uses I2C 1 */ -#endif - i2c_adap = i2c_get_adapter(1); - - if (i2c_adap == NULL) - printk(KERN_ALERT "No ddc adapter available!\n"); - /* - * Attempt to get the fixed panel mode from DDC. Assume that the - * preferred mode is the right one. - */ - if (i2c_adap) { - edid = drm_get_edid(connector, i2c_adap); - if (edid) { - drm_mode_connector_update_edid_property(connector, - edid); - ret = drm_add_edid_modes(connector, edid); - kfree(edid); - } - - list_for_each_entry(scan, &connector->probed_modes, head) { - if (scan->type & DRM_MODE_TYPE_PREFERRED) { - mode_dev->panel_fixed_mode = - drm_mode_duplicate(dev, scan); - goto out; /* FIXME: check for quirks */ - } - } - } - - /* - * If we didn't get EDID, try geting panel timing - * from configuration data - */ - mode_dev->panel_fixed_mode = mrst_lvds_get_configuration_mode(dev); - - if (mode_dev->panel_fixed_mode) { - mode_dev->panel_fixed_mode->type |= - DRM_MODE_TYPE_PREFERRED; - goto out; /* FIXME: check for quirks */ - } - - /* If we still don't have a mode after all that, give up. */ - if (!mode_dev->panel_fixed_mode) { - DRM_DEBUG - ("Found no modes on the lvds, ignoring the LVDS\n"); - goto failed_find; - } - -out: - drm_sysfs_connector_add(connector); - return; - -failed_find: - DRM_DEBUG("No LVDS modes found, disabling.\n"); - if (psb_intel_output->ddc_bus) - psb_intel_i2c_destroy(psb_intel_output->ddc_bus); - -/* failed_ddc: */ - - drm_encoder_cleanup(encoder); - drm_connector_cleanup(connector); - kfree(connector); -} - diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c deleted file mode 100644 index 0bd834c982d..00000000000 --- a/drivers/staging/gma500/psb_2d.c +++ /dev/null @@ -1,410 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - * develop this driver. - * - **************************************************************************/ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/tty.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/console.h> - -#include <drm/drmP.h> -#include <drm/drm.h> -#include <drm/drm_crtc.h> - -#include "psb_drv.h" -#include "psb_reg.h" -#include "psb_drv.h" -#include "psb_fb.h" - -void psb_spank(struct drm_psb_private *dev_priv) -{ - PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET | - _PSB_CS_RESET_TA_RESET | _PSB_CS_RESET_USE_RESET | - _PSB_CS_RESET_ISP_RESET | _PSB_CS_RESET_TSP_RESET | - _PSB_CS_RESET_TWOD_RESET, PSB_CR_SOFT_RESET); - (void) PSB_RSGX32(PSB_CR_SOFT_RESET); - - msleep(1); - - PSB_WSGX32(0, PSB_CR_SOFT_RESET); - wmb(); - PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_CB_CTRL_CLEAR_FAULT, - PSB_CR_BIF_CTRL); - wmb(); - (void) PSB_RSGX32(PSB_CR_BIF_CTRL); - - msleep(1); - PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) & ~_PSB_CB_CTRL_CLEAR_FAULT, - PSB_CR_BIF_CTRL); - (void) PSB_RSGX32(PSB_CR_BIF_CTRL); - PSB_WSGX32(dev_priv->pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); -} - -static int psb_2d_wait_available(struct drm_psb_private *dev_priv, - unsigned size) -{ - uint32_t avail = PSB_RSGX32(PSB_CR_2D_SOCIF); - unsigned long t = jiffies + HZ; - - while(avail < size) { - avail = PSB_RSGX32(PSB_CR_2D_SOCIF); - if (time_after(jiffies, t)) { - psb_spank(dev_priv); - return -EIO; - } - } - return 0; -} - -/* FIXME: Remember if we expose the 2D engine to the DRM we need to serialize - it with console use */ - -int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, - unsigned size) -{ - int ret = 0; - int i; - unsigned submit_size; - - while (size > 0) { - submit_size = (size < 0x60) ? size : 0x60; - size -= submit_size; - ret = psb_2d_wait_available(dev_priv, submit_size); - if (ret) - return ret; - - submit_size <<= 2; - for (i = 0; i < submit_size; i += 4) { - PSB_WSGX32(*cmdbuf++, PSB_SGX_2D_SLAVE_PORT + i); - } - (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4); - } - return 0; -} - -static int psb_accel_2d_fillrect(struct drm_psb_private *dev_priv, - uint32_t dst_offset, uint32_t dst_stride, - uint32_t dst_format, uint16_t dst_x, - uint16_t dst_y, uint16_t size_x, - uint16_t size_y, uint32_t fill) -{ - uint32_t buffer[10]; - uint32_t *buf; - - buf = buffer; - - *buf++ = PSB_2D_FENCE_BH; - - *buf++ = - PSB_2D_DST_SURF_BH | dst_format | (dst_stride << - PSB_2D_DST_STRIDE_SHIFT); - *buf++ = dst_offset; - - *buf++ = - PSB_2D_BLIT_BH | - PSB_2D_ROT_NONE | - PSB_2D_COPYORDER_TL2BR | - PSB_2D_DSTCK_DISABLE | - PSB_2D_SRCCK_DISABLE | PSB_2D_USE_FILL | PSB_2D_ROP3_PATCOPY; - - *buf++ = fill << PSB_2D_FILLCOLOUR_SHIFT; - *buf++ = - (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y << - PSB_2D_DST_YSTART_SHIFT); - *buf++ = - (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y << - PSB_2D_DST_YSIZE_SHIFT); - *buf++ = PSB_2D_FLUSH_BH; - - return psbfb_2d_submit(dev_priv, buffer, buf - buffer); -} - -static void psbfb_fillrect_accel(struct fb_info *info, - const struct fb_fillrect *r) -{ - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = fbdev->pfb; - struct drm_device *dev = psbfb->base.dev; - struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; - struct drm_psb_private *dev_priv = dev->dev_private; - - uint32_t offset; - uint32_t stride; - uint32_t format; - - if (!fb) - return; - - offset = psbfb->gtt->offset; - stride = fb->pitch; - - switch (fb->depth) { - case 8: - format = PSB_2D_DST_332RGB; - break; - case 15: - format = PSB_2D_DST_555RGB; - break; - case 16: - format = PSB_2D_DST_565RGB; - break; - case 24: - case 32: - /* this is wrong but since we don't do blending its okay */ - format = PSB_2D_DST_8888ARGB; - break; - default: - /* software fallback */ - cfb_fillrect(info, r); - return; - } - - psb_accel_2d_fillrect(dev_priv, - offset, stride, format, - r->dx, r->dy, r->width, r->height, r->color); -} - -void psbfb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -{ - if (unlikely(info->state != FBINFO_STATE_RUNNING)) - return; - - if (1 || (info->flags & FBINFO_HWACCEL_DISABLED)) - return cfb_fillrect(info, rect); - - /*psb_check_power_state(dev, PSB_DEVICE_SGX); */ - psbfb_fillrect_accel(info, rect); - /* Drop power again here on MRST FIXMEAC */ -} - -static u32 psb_accel_2d_copy_direction(int xdir, int ydir) -{ - if (xdir < 0) - return (ydir < 0) ? PSB_2D_COPYORDER_BR2TL : - PSB_2D_COPYORDER_TR2BL; - else - return (ydir < 0) ? PSB_2D_COPYORDER_BL2TR : - PSB_2D_COPYORDER_TL2BR; -} - -/* - * @src_offset in bytes - * @src_stride in bytes - * @src_format psb 2D format defines - * @dst_offset in bytes - * @dst_stride in bytes - * @dst_format psb 2D format defines - * @src_x offset in pixels - * @src_y offset in pixels - * @dst_x offset in pixels - * @dst_y offset in pixels - * @size_x of the copied area - * @size_y of the copied area - */ -static int psb_accel_2d_copy(struct drm_psb_private *dev_priv, - uint32_t src_offset, uint32_t src_stride, - uint32_t src_format, uint32_t dst_offset, - uint32_t dst_stride, uint32_t dst_format, - uint16_t src_x, uint16_t src_y, - uint16_t dst_x, uint16_t dst_y, - uint16_t size_x, uint16_t size_y) -{ - uint32_t blit_cmd; - uint32_t buffer[10]; - uint32_t *buf; - uint32_t direction; - - buf = buffer; - - direction = - psb_accel_2d_copy_direction(src_x - dst_x, src_y - dst_y); - - if (direction == PSB_2D_COPYORDER_BR2TL || - direction == PSB_2D_COPYORDER_TR2BL) { - src_x += size_x - 1; - dst_x += size_x - 1; - } - if (direction == PSB_2D_COPYORDER_BR2TL || - direction == PSB_2D_COPYORDER_BL2TR) { - src_y += size_y - 1; - dst_y += size_y - 1; - } - - blit_cmd = - PSB_2D_BLIT_BH | - PSB_2D_ROT_NONE | - PSB_2D_DSTCK_DISABLE | - PSB_2D_SRCCK_DISABLE | - PSB_2D_USE_PAT | PSB_2D_ROP3_SRCCOPY | direction; - - *buf++ = PSB_2D_FENCE_BH; - *buf++ = - PSB_2D_DST_SURF_BH | dst_format | (dst_stride << - PSB_2D_DST_STRIDE_SHIFT); - *buf++ = dst_offset; - *buf++ = - PSB_2D_SRC_SURF_BH | src_format | (src_stride << - PSB_2D_SRC_STRIDE_SHIFT); - *buf++ = src_offset; - *buf++ = - PSB_2D_SRC_OFF_BH | (src_x << PSB_2D_SRCOFF_XSTART_SHIFT) | - (src_y << PSB_2D_SRCOFF_YSTART_SHIFT); - *buf++ = blit_cmd; - *buf++ = - (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y << - PSB_2D_DST_YSTART_SHIFT); - *buf++ = - (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y << - PSB_2D_DST_YSIZE_SHIFT); - *buf++ = PSB_2D_FLUSH_BH; - - return psbfb_2d_submit(dev_priv, buffer, buf - buffer); -} - -static void psbfb_copyarea_accel(struct fb_info *info, - const struct fb_copyarea *a) -{ - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = fbdev->pfb; - struct drm_device *dev = psbfb->base.dev; - struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; - struct drm_psb_private *dev_priv = dev->dev_private; - uint32_t offset; - uint32_t stride; - uint32_t src_format; - uint32_t dst_format; - - if (!fb) - return; - - offset = psbfb->gtt->offset; - stride = fb->pitch; - - switch (fb->depth) { - case 8: - src_format = PSB_2D_SRC_332RGB; - dst_format = PSB_2D_DST_332RGB; - break; - case 15: - src_format = PSB_2D_SRC_555RGB; - dst_format = PSB_2D_DST_555RGB; - break; - case 16: - src_format = PSB_2D_SRC_565RGB; - dst_format = PSB_2D_DST_565RGB; - break; - case 24: - case 32: - /* this is wrong but since we don't do blending its okay */ - src_format = PSB_2D_SRC_8888ARGB; - dst_format = PSB_2D_DST_8888ARGB; - break; - default: - /* software fallback */ - cfb_copyarea(info, a); - return; - } - - psb_accel_2d_copy(dev_priv, - offset, stride, src_format, - offset, stride, dst_format, - a->sx, a->sy, a->dx, a->dy, a->width, a->height); -} - -void psbfb_copyarea(struct fb_info *info, - const struct fb_copyarea *region) -{ - if (unlikely(info->state != FBINFO_STATE_RUNNING)) - return; - - if (info->flags & FBINFO_HWACCEL_DISABLED) - return cfb_copyarea(info, region); - - /* psb_check_power_state(dev, PSB_DEVICE_SGX); */ - psbfb_copyarea_accel(info, region); - /* Need to power back off here for MRST FIXMEAC */ -} - -void psbfb_imageblit(struct fb_info *info, const struct fb_image *image) -{ - /* For now */ - cfb_imageblit(info, image); -} - -int psbfb_sync(struct fb_info *info) -{ - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = fbdev->pfb; - struct drm_device *dev = psbfb->base.dev; - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long _end = jiffies + DRM_HZ; - int busy = 0; - -#if 0 - /* Just a way to quickly test if cmd issue explodes */ - u32 test[2] = { - PSB_2D_FENCE_BH, - }; - psbfb_2d_submit(dev_priv, test, 1); -#endif - /* - * First idle the 2D engine. - */ - - if ((PSB_RSGX32(PSB_CR_2D_SOCIF) == _PSB_C2_SOCIF_EMPTY) && - ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & _PSB_C2B_STATUS_BUSY) == 0)) - goto out; - - do { - busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY); - cpu_relax(); - } while (busy && !time_after_eq(jiffies, _end)); - - if (busy) - busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY); - if (busy) - goto out; - - do { - busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & - _PSB_C2B_STATUS_BUSY) != 0); - cpu_relax(); - } while (busy && !time_after_eq(jiffies, _end)); - if (busy) - busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & - _PSB_C2B_STATUS_BUSY) != 0); - -out: - return (busy) ? -EBUSY : 0; -} - -/* - info->fix.accel = FB_ACCEL_I830; - info->flags = FBINFO_DEFAULT; -*/ diff --git a/drivers/staging/gma500/psb_bl.c b/drivers/staging/gma500/psb_bl.c deleted file mode 100644 index 5dffc71c512..00000000000 --- a/drivers/staging/gma500/psb_bl.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * psb backlight interface - * - * Copyright (c) 2009, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: Eric Knopp - * - */ - -#include <linux/backlight.h> -#include <linux/version.h> -#include "psb_drv.h" -#include "psb_intel_reg.h" -#include "psb_intel_drv.h" -#include "psb_intel_bios.h" -#include "psb_powermgmt.h" - -#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF -#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ -#define BLC_PWM_FREQ_CALC_CONSTANT 32 -#define MHz 1000000 -#define BRIGHTNESS_MIN_LEVEL 1 -#define BRIGHTNESS_MASK 0xFF -#define BLC_POLARITY_NORMAL 0 -#define BLC_POLARITY_INVERSE 1 -#define BLC_ADJUSTMENT_MAX 100 - -#define PSB_BLC_PWM_PRECISION_FACTOR 10 -#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE -#define PSB_BLC_MIN_PWM_REG_FREQ 0x2 - -#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) -#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) - -static int psb_brightness; -static struct backlight_device *psb_backlight_device; -static u8 blc_brightnesscmd; -static u8 blc_pol; -static u8 blc_type; - -int psb_set_brightness(struct backlight_device *bd) -{ - struct drm_device *dev = bl_get_data(psb_backlight_device); - int level = bd->props.brightness; - - DRM_DEBUG_DRIVER("backlight level set to %d\n", level); - - /* Percentage 1-100% being valid */ - if (level < 1) - level = 1; - - psb_intel_lvds_set_brightness(dev, level); - psb_brightness = level; - return 0; -} - -int mrst_set_brightness(struct backlight_device *bd) -{ - struct drm_device *dev = bl_get_data(psb_backlight_device); - struct drm_psb_private *dev_priv = dev->dev_private; - int level = bd->props.brightness; - u32 blc_pwm_ctl; - u32 max_pwm_blc; - - DRM_DEBUG_DRIVER("backlight level set to %d\n", level); - - /* Percentage 1-100% being valid */ - if (level < 1) - level = 1; - - if (gma_power_begin(dev, 0)) { - /* Calculate and set the brightness value */ - max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16; - blc_pwm_ctl = level * max_pwm_blc / 100; - - /* Adjust the backlight level with the percent in - * dev_priv->blc_adj1; - */ - blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1; - blc_pwm_ctl = blc_pwm_ctl / 100; - - /* Adjust the backlight level with the percent in - * dev_priv->blc_adj2; - */ - blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2; - blc_pwm_ctl = blc_pwm_ctl / 100; - - if (blc_pol == BLC_POLARITY_INVERSE) - blc_pwm_ctl = max_pwm_blc - blc_pwm_ctl; - /* force PWM bit on */ - REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2))); - REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl); - gma_power_end(dev); - } - psb_brightness = level; - return 0; -} - -int psb_get_brightness(struct backlight_device *bd) -{ - DRM_DEBUG_DRIVER("brightness = 0x%x\n", psb_brightness); - - /* return locally cached var instead of HW read (due to DPST etc.) */ - /* FIXME: ideally return actual value in case firmware fiddled with - it */ - return psb_brightness; -} - -static const struct backlight_ops psb_ops = { - .get_brightness = psb_get_brightness, - .update_status = psb_set_brightness, -}; - -static int device_backlight_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long core_clock; - /* u32 bl_max_freq; */ - /* unsigned long value; */ - u16 bl_max_freq; - uint32_t value; - uint32_t blc_pwm_precision_factor; - - if (IS_MRST(dev)) { - dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX; - dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX; - bl_max_freq = 256; - /* this needs to be set elsewhere */ - blc_pol = BLC_POLARITY_NORMAL; - blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR; - } else { - /* get bl_max_freq and pol from dev_priv*/ - if (!dev_priv->lvds_bl) { - DRM_ERROR("Has no valid LVDS backlight info\n"); - return 1; - } - bl_max_freq = dev_priv->lvds_bl->freq; - blc_pol = dev_priv->lvds_bl->pol; - blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR; - blc_brightnesscmd = dev_priv->lvds_bl->brightnesscmd; - blc_type = dev_priv->lvds_bl->type; - } - - core_clock = dev_priv->core_freq; - - value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; - value *= blc_pwm_precision_factor; - value /= bl_max_freq; - value /= blc_pwm_precision_factor; - - if (gma_power_begin(dev, false)) { - if (IS_MRST(dev)) { - if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ) - return 2; - else { - REG_WRITE(BLC_PWM_CTL2, - (0x80000000 | REG_READ(BLC_PWM_CTL2))); - REG_WRITE(BLC_PWM_CTL, value | (value << 16)); - } - } else { - if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ || - value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ) - return 2; - else { - value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; - REG_WRITE(BLC_PWM_CTL, - (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | - (value)); - } - } - gma_power_end(dev); - } - return 0; -} - -int psb_backlight_init(struct drm_device *dev) -{ -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - int ret = 0; - - struct backlight_properties props; - memset(&props, 0, sizeof(struct backlight_properties)); - props.max_brightness = 100; - props.type = BACKLIGHT_PLATFORM; - - psb_backlight_device = backlight_device_register("psb-bl", NULL, - (void *)dev, &psb_ops, &props); - if (IS_ERR(psb_backlight_device)) - return PTR_ERR(psb_backlight_device); - - ret = device_backlight_init(dev); - if (ret < 0) - return ret; - - psb_backlight_device->props.brightness = 100; - psb_backlight_device->props.max_brightness = 100; - backlight_update_status(psb_backlight_device); -#endif - return 0; -} - -void psb_backlight_exit(void) -{ -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - psb_backlight_device->props.brightness = 0; - backlight_update_status(psb_backlight_device); - backlight_device_unregister(psb_backlight_device); -#endif -} - -struct backlight_device *psb_get_backlight_device(void) -{ - return psb_backlight_device; -} diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h deleted file mode 100644 index 49ffdd5b90e..00000000000 --- a/drivers/staging/gma500/psb_drm.h +++ /dev/null @@ -1,275 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007, Intel Corporation. - * All Rights Reserved. - * Copyright (c) 2008, Tungsten Graphics Inc. Cedar Park, TX., USA. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#ifndef _PSB_DRM_H_ -#define _PSB_DRM_H_ - -#if defined(__linux__) && !defined(__KERNEL__) -#include<stdint.h> -#include <linux/types.h> -#include "drm_mode.h" -#endif - -#define DRM_PSB_SAREA_MAJOR 0 -#define DRM_PSB_SAREA_MINOR 2 -#define PSB_FIXED_SHIFT 16 - -#define PSB_NUM_PIPE 3 - -/* - * Public memory types. - */ - -typedef s32 psb_fixed; -typedef u32 psb_ufixed; - -static inline s32 psb_int_to_fixed(int a) -{ - return a * (1 << PSB_FIXED_SHIFT); -} - -static inline u32 psb_unsigned_to_ufixed(unsigned int a) -{ - return a << PSB_FIXED_SHIFT; -} - -/*Status of the command sent to the gfx device.*/ -typedef enum { - DRM_CMD_SUCCESS, - DRM_CMD_FAILED, - DRM_CMD_HANG -} drm_cmd_status_t; - -struct drm_psb_scanout { - u32 buffer_id; /* DRM buffer object ID */ - u32 rotation; /* Rotation as in RR_rotation definitions */ - u32 stride; /* Buffer stride in bytes */ - u32 depth; /* Buffer depth in bits (NOT) bpp */ - u32 width; /* Buffer width in pixels */ - u32 height; /* Buffer height in lines */ - s32 transform[3][3]; /* Buffer composite transform */ - /* (scaling, rot, reflect) */ -}; - -#define DRM_PSB_SAREA_OWNERS 16 -#define DRM_PSB_SAREA_OWNER_2D 0 -#define DRM_PSB_SAREA_OWNER_3D 1 - -#define DRM_PSB_SAREA_SCANOUTS 3 - -struct drm_psb_sarea { - /* Track changes of this data structure */ - - u32 major; - u32 minor; - - /* Last context to touch part of hw */ - u32 ctx_owners[DRM_PSB_SAREA_OWNERS]; - - /* Definition of front- and rotated buffers */ - u32 num_scanouts; - struct drm_psb_scanout scanouts[DRM_PSB_SAREA_SCANOUTS]; - - int planeA_x; - int planeA_y; - int planeA_w; - int planeA_h; - int planeB_x; - int planeB_y; - int planeB_w; - int planeB_h; - /* Number of active scanouts */ - u32 num_active_scanouts; -}; - -#define PSB_GPU_ACCESS_READ (1ULL << 32) -#define PSB_GPU_ACCESS_WRITE (1ULL << 33) -#define PSB_GPU_ACCESS_MASK (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE) - -#define PSB_BO_FLAG_COMMAND (1ULL << 52) - -/* - * Feedback components: - */ - -struct drm_psb_sizes_arg { - u32 ta_mem_size; - u32 mmu_size; - u32 pds_size; - u32 rastgeom_size; - u32 tt_size; - u32 vram_size; -}; - -struct drm_psb_dpst_lut_arg { - uint8_t lut[256]; - int output_id; -}; - -#define PSB_DC_CRTC_SAVE 0x01 -#define PSB_DC_CRTC_RESTORE 0x02 -#define PSB_DC_OUTPUT_SAVE 0x04 -#define PSB_DC_OUTPUT_RESTORE 0x08 -#define PSB_DC_CRTC_MASK 0x03 -#define PSB_DC_OUTPUT_MASK 0x0C - -struct drm_psb_dc_state_arg { - u32 flags; - u32 obj_id; -}; - -struct drm_psb_mode_operation_arg { - u32 obj_id; - u16 operation; - struct drm_mode_modeinfo mode; - void *data; -}; - -struct drm_psb_stolen_memory_arg { - u32 base; - u32 size; -}; - -/*Display Register Bits*/ -#define REGRWBITS_PFIT_CONTROLS (1 << 0) -#define REGRWBITS_PFIT_AUTOSCALE_RATIOS (1 << 1) -#define REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS (1 << 2) -#define REGRWBITS_PIPEASRC (1 << 3) -#define REGRWBITS_PIPEBSRC (1 << 4) -#define REGRWBITS_VTOTAL_A (1 << 5) -#define REGRWBITS_VTOTAL_B (1 << 6) -#define REGRWBITS_DSPACNTR (1 << 8) -#define REGRWBITS_DSPBCNTR (1 << 9) -#define REGRWBITS_DSPCCNTR (1 << 10) - -/*Overlay Register Bits*/ -#define OV_REGRWBITS_OVADD (1 << 0) -#define OV_REGRWBITS_OGAM_ALL (1 << 1) - -#define OVC_REGRWBITS_OVADD (1 << 2) -#define OVC_REGRWBITS_OGAM_ALL (1 << 3) - -struct drm_psb_register_rw_arg { - u32 b_force_hw_on; - - u32 display_read_mask; - u32 display_write_mask; - - struct { - u32 pfit_controls; - u32 pfit_autoscale_ratios; - u32 pfit_programmed_scale_ratios; - u32 pipeasrc; - u32 pipebsrc; - u32 vtotal_a; - u32 vtotal_b; - } display; - - u32 overlay_read_mask; - u32 overlay_write_mask; - - struct { - u32 OVADD; - u32 OGAMC0; - u32 OGAMC1; - u32 OGAMC2; - u32 OGAMC3; - u32 OGAMC4; - u32 OGAMC5; - u32 IEP_ENABLED; - u32 IEP_BLE_MINMAX; - u32 IEP_BSSCC_CONTROL; - u32 b_wait_vblank; - } overlay; - - u32 sprite_enable_mask; - u32 sprite_disable_mask; - - struct { - u32 dspa_control; - u32 dspa_key_value; - u32 dspa_key_mask; - u32 dspc_control; - u32 dspc_stride; - u32 dspc_position; - u32 dspc_linear_offset; - u32 dspc_size; - u32 dspc_surface; - } sprite; - - u32 subpicture_enable_mask; - u32 subpicture_disable_mask; -}; - -/* Controlling the kernel modesetting buffers */ - -#define DRM_PSB_KMS_OFF 0x00 -#define DRM_PSB_KMS_ON 0x01 -#define DRM_PSB_VT_LEAVE 0x02 -#define DRM_PSB_VT_ENTER 0x03 -#define DRM_PSB_EXTENSION 0x06 -#define DRM_PSB_SIZES 0x07 -#define DRM_PSB_FUSE_REG 0x08 -#define DRM_PSB_VBT 0x09 -#define DRM_PSB_DC_STATE 0x0A -#define DRM_PSB_ADB 0x0B -#define DRM_PSB_MODE_OPERATION 0x0C -#define DRM_PSB_STOLEN_MEMORY 0x0D -#define DRM_PSB_REGISTER_RW 0x0E -#define DRM_PSB_GTT_MAP 0x0F -#define DRM_PSB_GTT_UNMAP 0x10 -#define DRM_PSB_GETPAGEADDRS 0x11 -/** - * NOTE: Add new commands here, but increment - * the values below and increment their - * corresponding defines where they're - * defined elsewhere. - */ -#define DRM_PVR_RESERVED1 0x12 -#define DRM_PVR_RESERVED2 0x13 -#define DRM_PVR_RESERVED3 0x14 -#define DRM_PVR_RESERVED4 0x15 -#define DRM_PVR_RESERVED5 0x16 - -#define DRM_PSB_HIST_ENABLE 0x17 -#define DRM_PSB_HIST_STATUS 0x18 -#define DRM_PSB_UPDATE_GUARD 0x19 -#define DRM_PSB_INIT_COMM 0x1A -#define DRM_PSB_DPST 0x1B -#define DRM_PSB_GAMMA 0x1C -#define DRM_PSB_DPST_BL 0x1D - -#define DRM_PVR_RESERVED6 0x1E - -#define DRM_PSB_GET_PIPE_FROM_CRTC_ID 0x1F - -#define PSB_MODE_OPERATION_MODE_VALID 0x01 -#define PSB_MODE_OPERATION_SET_DC_BASE 0x02 - -struct drm_psb_get_pipe_from_crtc_id_arg { - /** ID of CRTC being requested **/ - u32 crtc_id; - - /** pipe of requested CRTC **/ - u32 pipe; -}; - -#endif diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c deleted file mode 100644 index 1c45c11a774..00000000000 --- a/drivers/staging/gma500/psb_drv.c +++ /dev/null @@ -1,1454 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007, Intel Corporation. - * All Rights Reserved. - * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX., USA. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#include <drm/drmP.h> -#include <drm/drm.h> -#include "psb_drm.h" -#include "psb_drv.h" -#include "psb_fb.h" -#include "psb_reg.h" -#include "psb_intel_reg.h" -#include "psb_intel_bios.h" -#include <drm/drm_pciids.h> -#include "psb_powermgmt.h" -#include <linux/cpu.h> -#include <linux/notifier.h> -#include <linux/spinlock.h> -#include <linux/pm_runtime.h> -#include <acpi/video.h> - -int drm_psb_debug; -static int drm_psb_trap_pagefaults; - -int drm_psb_no_fb; - -static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent); - -MODULE_PARM_DESC(debug, "Enable debug output"); -MODULE_PARM_DESC(no_fb, "Disable FBdev"); -MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults"); -module_param_named(debug, drm_psb_debug, int, 0600); -module_param_named(no_fb, drm_psb_no_fb, int, 0600); -module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600); - - -static struct pci_device_id pciidlist[] = { - { 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8108 }, - { 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8109 }, - { 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0, 0, 0} -}; -MODULE_DEVICE_TABLE(pci, pciidlist); - -/* - * Standard IOCTLs. - */ - -#define DRM_IOCTL_PSB_KMS_OFF \ - DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE) -#define DRM_IOCTL_PSB_KMS_ON \ - DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE) -#define DRM_IOCTL_PSB_SIZES \ - DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \ - struct drm_psb_sizes_arg) -#define DRM_IOCTL_PSB_FUSE_REG \ - DRM_IOWR(DRM_PSB_FUSE_REG + DRM_COMMAND_BASE, uint32_t) -#define DRM_IOCTL_PSB_DC_STATE \ - DRM_IOW(DRM_PSB_DC_STATE + DRM_COMMAND_BASE, \ - struct drm_psb_dc_state_arg) -#define DRM_IOCTL_PSB_ADB \ - DRM_IOWR(DRM_PSB_ADB + DRM_COMMAND_BASE, uint32_t) -#define DRM_IOCTL_PSB_MODE_OPERATION \ - DRM_IOWR(DRM_PSB_MODE_OPERATION + DRM_COMMAND_BASE, \ - struct drm_psb_mode_operation_arg) -#define DRM_IOCTL_PSB_STOLEN_MEMORY \ - DRM_IOWR(DRM_PSB_STOLEN_MEMORY + DRM_COMMAND_BASE, \ - struct drm_psb_stolen_memory_arg) -#define DRM_IOCTL_PSB_REGISTER_RW \ - DRM_IOWR(DRM_PSB_REGISTER_RW + DRM_COMMAND_BASE, \ - struct drm_psb_register_rw_arg) -#define DRM_IOCTL_PSB_DPST \ - DRM_IOWR(DRM_PSB_DPST + DRM_COMMAND_BASE, \ - uint32_t) -#define DRM_IOCTL_PSB_GAMMA \ - DRM_IOWR(DRM_PSB_GAMMA + DRM_COMMAND_BASE, \ - struct drm_psb_dpst_lut_arg) -#define DRM_IOCTL_PSB_DPST_BL \ - DRM_IOWR(DRM_PSB_DPST_BL + DRM_COMMAND_BASE, \ - uint32_t) -#define DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID \ - DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \ - struct drm_psb_get_pipe_from_crtc_id_arg) - -static int psb_sizes_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -static int psb_dc_state_ioctl(struct drm_device *dev, void * data, - struct drm_file *file_priv); -static int psb_adb_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -static int psb_register_rw_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -static int psb_dpst_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -static int psb_gamma_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -#define PSB_IOCTL_DEF(ioctl, func, flags) \ - [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func} - -static struct drm_ioctl_desc psb_ioctls[] = { - PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_OFF, psbfb_kms_off_ioctl, - DRM_ROOT_ONLY), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_ON, - psbfb_kms_on_ioctl, - DRM_ROOT_ONLY), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_SIZES, psb_sizes_ioctl, DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_DC_STATE, psb_dc_state_ioctl, DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_MODE_OPERATION, psb_mode_operation_ioctl, - DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_STOLEN_MEMORY, psb_stolen_memory_ioctl, - DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_REGISTER_RW, psb_register_rw_ioctl, - DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST, psb_dpst_ioctl, DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID, - psb_intel_get_pipe_from_crtc_id, 0), - -}; - -static void psb_lastclose(struct drm_device *dev) -{ - return; -} - -static void psb_do_takedown(struct drm_device *dev) -{ - /* FIXME: do we need to clean up the gtt here ? */ -} - -void mrst_get_fuse_settings(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); - uint32_t fuse_value = 0; - uint32_t fuse_value_tmp = 0; - -#define FB_REG06 0xD0810600 -#define FB_MIPI_DISABLE (1 << 11) -#define FB_REG09 0xD0810900 -#define FB_REG09 0xD0810900 -#define FB_SKU_MASK 0x7000 -#define FB_SKU_SHIFT 12 -#define FB_SKU_100 0 -#define FB_SKU_100L 1 -#define FB_SKU_83 2 - pci_write_config_dword(pci_root, 0xD0, FB_REG06); - pci_read_config_dword(pci_root, 0xD4, &fuse_value); - - dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE; - - DRM_INFO("internal display is %s\n", - dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display"); - - /*prevent Runtime suspend at start*/ - if (dev_priv->iLVDS_enable) { - dev_priv->is_lvds_on = true; - dev_priv->is_mipi_on = false; - } - else { - dev_priv->is_mipi_on = true; - dev_priv->is_lvds_on = false; - } - - dev_priv->video_device_fuse = fuse_value; - - pci_write_config_dword(pci_root, 0xD0, FB_REG09); - pci_read_config_dword(pci_root, 0xD4, &fuse_value); - - DRM_INFO("SKU values is 0x%x. \n", fuse_value); - fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT; - - dev_priv->fuse_reg_value = fuse_value; - - switch (fuse_value_tmp) { - case FB_SKU_100: - dev_priv->core_freq = 200; - break; - case FB_SKU_100L: - dev_priv->core_freq = 100; - break; - case FB_SKU_83: - dev_priv->core_freq = 166; - break; - default: - DRM_ERROR("Invalid SKU values, SKU value = 0x%08x\n", fuse_value_tmp); - dev_priv->core_freq = 0; - } - DRM_INFO("LNC core clk is %dMHz.\n", dev_priv->core_freq); - pci_dev_put(pci_root); -} - -void mid_get_pci_revID (struct drm_psb_private *dev_priv) -{ - uint32_t platform_rev_id = 0; - struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); - - /*get the revison ID, B0:D2:F0;0x08 */ - pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id); - dev_priv->platform_rev_id = (uint8_t) platform_rev_id; - pci_dev_put(pci_gfx_root); - PSB_DEBUG_ENTRY("platform_rev_id is %x\n", dev_priv->platform_rev_id); -} - -void mrst_get_vbt_data(struct drm_psb_private *dev_priv) -{ - struct mrst_vbt *vbt = &dev_priv->vbt_data; - u32 platform_config_address; - u16 new_size; - u8 *vbt_virtual; - u8 bpi; - u8 number_desc = 0; - struct mrst_timing_info *dp_ti = &dev_priv->gct_data.DTD; - struct gct_r10_timing_info ti; - void *pGCT; - struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); - - /*get the address of the platform config vbt, B0:D2:F0;0xFC */ - pci_read_config_dword(pci_gfx_root, 0xFC, &platform_config_address); - pci_dev_put(pci_gfx_root); - DRM_INFO("drm platform config address is %x\n", - platform_config_address); - - /* check for platform config address == 0. */ - /* this means fw doesn't support vbt */ - - if (platform_config_address == 0) { - vbt->size = 0; - return; - } - - /* get the virtual address of the vbt */ - vbt_virtual = ioremap(platform_config_address, sizeof(*vbt)); - - memcpy(vbt, vbt_virtual, sizeof(*vbt)); - iounmap(vbt_virtual); /* Free virtual address space */ - - printk(KERN_ALERT "GCT revision is %x\n", vbt->revision); - - switch (vbt->revision) { - case 0: - vbt->mrst_gct = NULL; - vbt->mrst_gct = \ - ioremap(platform_config_address + sizeof(*vbt) - 4, - vbt->size - sizeof(*vbt) + 4); - pGCT = vbt->mrst_gct; - bpi = ((struct mrst_gct_v1 *)pGCT)->PD.BootPanelIndex; - dev_priv->gct_data.bpi = bpi; - dev_priv->gct_data.pt = - ((struct mrst_gct_v1 *)pGCT)->PD.PanelType; - memcpy(&dev_priv->gct_data.DTD, - &((struct mrst_gct_v1 *)pGCT)->panel[bpi].DTD, - sizeof(struct mrst_timing_info)); - dev_priv->gct_data.Panel_Port_Control = - ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control; - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; - break; - case 1: - vbt->mrst_gct = NULL; - vbt->mrst_gct = \ - ioremap(platform_config_address + sizeof(*vbt) - 4, - vbt->size - sizeof(*vbt) + 4); - pGCT = vbt->mrst_gct; - bpi = ((struct mrst_gct_v2 *)pGCT)->PD.BootPanelIndex; - dev_priv->gct_data.bpi = bpi; - dev_priv->gct_data.pt = - ((struct mrst_gct_v2 *)pGCT)->PD.PanelType; - memcpy(&dev_priv->gct_data.DTD, - &((struct mrst_gct_v2 *)pGCT)->panel[bpi].DTD, - sizeof(struct mrst_timing_info)); - dev_priv->gct_data.Panel_Port_Control = - ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control; - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; - break; - case 0x10: - /*header definition changed from rev 01 (v2) to rev 10h. */ - /*so, some values have changed location*/ - new_size = vbt->checksum; /*checksum contains lo size byte*/ - /*LSB of mrst_gct contains hi size byte*/ - new_size |= ((0xff & (unsigned int)vbt->mrst_gct)) << 8; - - vbt->checksum = vbt->size; /*size contains the checksum*/ - if (new_size > 0xff) - vbt->size = 0xff; /*restrict size to 255*/ - else - vbt->size = new_size; - - /* number of descriptors defined in the GCT */ - number_desc = ((0xff00 & (unsigned int)vbt->mrst_gct)) >> 8; - bpi = ((0xff0000 & (unsigned int)vbt->mrst_gct)) >> 16; - vbt->mrst_gct = NULL; - vbt->mrst_gct = \ - ioremap(platform_config_address + GCT_R10_HEADER_SIZE, - GCT_R10_DISPLAY_DESC_SIZE * number_desc); - pGCT = vbt->mrst_gct; - pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE); - dev_priv->gct_data.bpi = bpi; /*save boot panel id*/ - - /*copy the GCT display timings into a temp structure*/ - memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info)); - - /*now copy the temp struct into the dev_priv->gct_data*/ - dp_ti->pixel_clock = ti.pixel_clock; - dp_ti->hactive_hi = ti.hactive_hi; - dp_ti->hactive_lo = ti.hactive_lo; - dp_ti->hblank_hi = ti.hblank_hi; - dp_ti->hblank_lo = ti.hblank_lo; - dp_ti->hsync_offset_hi = ti.hsync_offset_hi; - dp_ti->hsync_offset_lo = ti.hsync_offset_lo; - dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi; - dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo; - dp_ti->vactive_hi = ti.vactive_hi; - dp_ti->vactive_lo = ti.vactive_lo; - dp_ti->vblank_hi = ti.vblank_hi; - dp_ti->vblank_lo = ti.vblank_lo; - dp_ti->vsync_offset_hi = ti.vsync_offset_hi; - dp_ti->vsync_offset_lo = ti.vsync_offset_lo; - dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi; - dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo; - - /*mov the MIPI_Display_Descriptor data from GCT to dev priv*/ - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - *((u8 *)pGCT + 0x0d); - dev_priv->gct_data.Panel_MIPI_Display_Descriptor |= - (*((u8 *)pGCT + 0x0e)) << 8; - break; - default: - printk(KERN_ERR "Unknown revision of GCT!\n"); - vbt->size = 0; - } -} - -static void psb_get_core_freq(struct drm_device *dev) -{ - uint32_t clock; - struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); - struct drm_psb_private *dev_priv = dev->dev_private; - - /*pci_write_config_dword(pci_root, 0xD4, 0x00C32004);*/ - /*pci_write_config_dword(pci_root, 0xD0, 0xE0033000);*/ - - pci_write_config_dword(pci_root, 0xD0, 0xD0050300); - pci_read_config_dword(pci_root, 0xD4, &clock); - pci_dev_put(pci_root); - - switch (clock & 0x07) { - case 0: - dev_priv->core_freq = 100; - break; - case 1: - dev_priv->core_freq = 133; - break; - case 2: - dev_priv->core_freq = 150; - break; - case 3: - dev_priv->core_freq = 178; - break; - case 4: - dev_priv->core_freq = 200; - break; - case 5: - case 6: - case 7: - dev_priv->core_freq = 266; - default: - dev_priv->core_freq = 0; - } -} - -static int psb_do_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - struct psb_gtt *pg = dev_priv->pg; - - uint32_t stolen_gtt; - uint32_t tt_start; - uint32_t tt_pages; - - int ret = -ENOMEM; - - if (pg->mmu_gatt_start & 0x0FFFFFFF) { - DRM_ERROR("Gatt must be 256M aligned. This is a bug.\n"); - ret = -EINVAL; - goto out_err; - } - - - stolen_gtt = (pg->stolen_size >> PAGE_SHIFT) * 4; - stolen_gtt = (stolen_gtt + PAGE_SIZE - 1) >> PAGE_SHIFT; - stolen_gtt = - (stolen_gtt < pg->gtt_pages) ? stolen_gtt : pg->gtt_pages; - - dev_priv->gatt_free_offset = pg->mmu_gatt_start + - (stolen_gtt << PAGE_SHIFT) * 1024; - - if (1 || drm_debug) { - uint32_t core_id = PSB_RSGX32(PSB_CR_CORE_ID); - uint32_t core_rev = PSB_RSGX32(PSB_CR_CORE_REVISION); - DRM_INFO("SGX core id = 0x%08x\n", core_id); - DRM_INFO("SGX core rev major = 0x%02x, minor = 0x%02x\n", - (core_rev & _PSB_CC_REVISION_MAJOR_MASK) >> - _PSB_CC_REVISION_MAJOR_SHIFT, - (core_rev & _PSB_CC_REVISION_MINOR_MASK) >> - _PSB_CC_REVISION_MINOR_SHIFT); - DRM_INFO - ("SGX core rev maintenance = 0x%02x, designer = 0x%02x\n", - (core_rev & _PSB_CC_REVISION_MAINTENANCE_MASK) >> - _PSB_CC_REVISION_MAINTENANCE_SHIFT, - (core_rev & _PSB_CC_REVISION_DESIGNER_MASK) >> - _PSB_CC_REVISION_DESIGNER_SHIFT); - } - - - spin_lock_init(&dev_priv->irqmask_lock); - - tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? - pg->gatt_pages : PSB_TT_PRIV0_PLIMIT; - tt_start = dev_priv->gatt_free_offset - pg->mmu_gatt_start; - tt_pages -= tt_start >> PAGE_SHIFT; - /* FIXME: can we kill ta_mem_size ? */ - dev_priv->sizes.ta_mem_size = 0; - - PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0); - PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1); - PSB_RSGX32(PSB_CR_BIF_BANK1); - PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK, - PSB_CR_BIF_CTRL); - psb_spank(dev_priv); - - /* mmu_gatt ?? */ - PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); - - return 0; -out_err: - psb_do_takedown(dev); - return ret; -} - -static int psb_driver_unload(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - - /* Kill vblank etc here */ - - psb_backlight_exit(); /*writes minimum value to backlight HW reg */ - - if (drm_psb_no_fb == 0) - psb_modeset_cleanup(dev); - - if (dev_priv) { - psb_lid_timer_takedown(dev_priv); - - psb_do_takedown(dev); - - - if (dev_priv->pf_pd) { - psb_mmu_free_pagedir(dev_priv->pf_pd); - dev_priv->pf_pd = NULL; - } - if (dev_priv->mmu) { - struct psb_gtt *pg = dev_priv->pg; - - down_read(&pg->sem); - psb_mmu_remove_pfn_sequence( - psb_mmu_get_default_pd - (dev_priv->mmu), - pg->mmu_gatt_start, - dev_priv->vram_stolen_size >> PAGE_SHIFT); - up_read(&pg->sem); - psb_mmu_driver_takedown(dev_priv->mmu); - dev_priv->mmu = NULL; - } - psb_gtt_takedown(dev); - if (dev_priv->scratch_page) { - __free_page(dev_priv->scratch_page); - dev_priv->scratch_page = NULL; - } - if (dev_priv->vdc_reg) { - iounmap(dev_priv->vdc_reg); - dev_priv->vdc_reg = NULL; - } - if (dev_priv->sgx_reg) { - iounmap(dev_priv->sgx_reg); - dev_priv->sgx_reg = NULL; - } - - kfree(dev_priv); - dev->dev_private = NULL; - - /*destroy VBT data*/ - psb_intel_destroy_bios(dev); - } - - gma_power_uninit(dev); - - return 0; -} - - -static int psb_driver_load(struct drm_device *dev, unsigned long chipset) -{ - struct drm_psb_private *dev_priv; - unsigned long resource_start; - struct psb_gtt *pg; - unsigned long irqflags; - int ret = -ENOMEM; - uint32_t tt_pages; - - dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); - if (dev_priv == NULL) - return -ENOMEM; - - if (IS_MRST(dev)) - dev_priv->num_pipe = 1; - else - dev_priv->num_pipe = 2; - - dev_priv->dev = dev; - - dev->dev_private = (void *) dev_priv; - dev_priv->chipset = chipset; - - PSB_DEBUG_INIT("Mapping MMIO\n"); - resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE); - - dev_priv->vdc_reg = - ioremap(resource_start + PSB_VDC_OFFSET, PSB_VDC_SIZE); - if (!dev_priv->vdc_reg) - goto out_err; - - if (IS_MRST(dev)) - dev_priv->sgx_reg = ioremap(resource_start + MRST_SGX_OFFSET, - PSB_SGX_SIZE); - else - dev_priv->sgx_reg = ioremap(resource_start + PSB_SGX_OFFSET, - PSB_SGX_SIZE); - - if (!dev_priv->sgx_reg) - goto out_err; - - if (IS_MRST(dev)) { - mrst_get_fuse_settings(dev); - mrst_get_vbt_data(dev_priv); - mid_get_pci_revID(dev_priv); - } else { - psb_get_core_freq(dev); - psb_intel_opregion_init(dev); - psb_intel_init_bios(dev); - } - - /* Init OSPM support */ - gma_power_init(dev); - - ret = -ENOMEM; - - dev_priv->scratch_page = alloc_page(GFP_DMA32 | __GFP_ZERO); - if (!dev_priv->scratch_page) - goto out_err; - - set_pages_uc(dev_priv->scratch_page, 1); - - ret = psb_gtt_init(dev, 0); - if (ret) - goto out_err; - - dev_priv->mmu = psb_mmu_driver_init((void *)0, - drm_psb_trap_pagefaults, 0, - dev_priv); - if (!dev_priv->mmu) - goto out_err; - - pg = dev_priv->pg; - - tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? - (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT; - - - dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0); - if (!dev_priv->pf_pd) - goto out_err; - - psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0); - psb_mmu_set_pd_context(dev_priv->pf_pd, 1); - - ret = psb_do_init(dev); - if (ret) - return ret; - - PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE); - PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE); - -/* igd_opregion_init(&dev_priv->opregion_dev); */ - acpi_video_register(); - if (dev_priv->lid_state) - psb_lid_timer_init(dev_priv); - - ret = drm_vblank_init(dev, dev_priv->num_pipe); - if (ret) - goto out_err; - - /* - * Install interrupt handlers prior to powering off SGX or else we will - * crash. - */ - dev_priv->vdc_irq_mask = 0; - dev_priv->pipestat[0] = 0; - dev_priv->pipestat[1] = 0; - dev_priv->pipestat[2] = 0; - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R); - PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R); - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_irq_install(dev); - - dev->vblank_disable_allowed = 1; - - dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ - - dev->driver->get_vblank_counter = psb_get_vblank_counter; - - if (drm_psb_no_fb == 0) { - psb_modeset_init(dev); - psb_fbdev_init(dev); - drm_kms_helper_poll_init(dev); - } - - ret = psb_backlight_init(dev); - if (ret) - return ret; -#if 0 - /*enable runtime pm at last*/ - pm_runtime_enable(&dev->pdev->dev); - pm_runtime_set_active(&dev->pdev->dev); -#endif - /*Intel drm driver load is done, continue doing pvr load*/ - DRM_DEBUG("Pvr driver load\n"); - return 0; -out_err: - psb_driver_unload(dev); - return ret; -} - -int psb_driver_device_is_agp(struct drm_device *dev) -{ - return 0; -} - - -static int psb_sizes_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_private *dev_priv = psb_priv(dev); - struct drm_psb_sizes_arg *arg = - (struct drm_psb_sizes_arg *) data; - - *arg = dev_priv->sizes; - return 0; -} - -static int psb_dc_state_ioctl(struct drm_device *dev, void * data, - struct drm_file *file_priv) -{ - uint32_t flags; - uint32_t obj_id; - struct drm_mode_object *obj; - struct drm_connector *connector; - struct drm_crtc *crtc; - struct drm_psb_dc_state_arg *arg = - (struct drm_psb_dc_state_arg *)data; - - flags = arg->flags; - obj_id = arg->obj_id; - - if (flags & PSB_DC_CRTC_MASK) { - obj = drm_mode_object_find(dev, obj_id, - DRM_MODE_OBJECT_CRTC); - if (!obj) { - DRM_DEBUG("Invalid CRTC object.\n"); - return -EINVAL; - } - - crtc = obj_to_crtc(obj); - - mutex_lock(&dev->mode_config.mutex); - if (drm_helper_crtc_in_use(crtc)) { - if (flags & PSB_DC_CRTC_SAVE) - crtc->funcs->save(crtc); - else - crtc->funcs->restore(crtc); - } - mutex_unlock(&dev->mode_config.mutex); - - return 0; - } else if (flags & PSB_DC_OUTPUT_MASK) { - obj = drm_mode_object_find(dev, obj_id, - DRM_MODE_OBJECT_CONNECTOR); - if (!obj) { - DRM_DEBUG("Invalid connector id.\n"); - return -EINVAL; - } - - connector = obj_to_connector(obj); - if (flags & PSB_DC_OUTPUT_SAVE) - connector->funcs->save(connector); - else - connector->funcs->restore(connector); - - return 0; - } - - DRM_DEBUG("Bad flags 0x%x\n", flags); - return -EINVAL; -} - -static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_private *dev_priv = psb_priv(dev); - uint32_t *arg = data; - struct backlight_device bd; - dev_priv->blc_adj2 = *arg; - -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - bd.props.brightness = psb_get_brightness(&bd); - psb_set_brightness(&bd); -#endif - return 0; -} - -static int psb_adb_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_private *dev_priv = psb_priv(dev); - uint32_t *arg = data; - struct backlight_device bd; - dev_priv->blc_adj1 = *arg; - -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - bd.props.brightness = psb_get_brightness(&bd); - psb_set_brightness(&bd); -#endif - return 0; -} - -/* return the current mode to the dpst module */ -static int psb_dpst_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_private *dev_priv = psb_priv(dev); - uint32_t *arg = data; - uint32_t x; - uint32_t y; - uint32_t reg; - - if (!gma_power_begin(dev, 0)) - return -EIO; - - reg = PSB_RVDC32(PIPEASRC); - - gma_power_end(dev); - - /* horizontal is the left 16 bits */ - x = reg >> 16; - /* vertical is the right 16 bits */ - y = reg & 0x0000ffff; - - /* the values are the image size minus one */ - x++; - y++; - - *arg = (x << 16) | y; - - return 0; -} -static int psb_gamma_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_dpst_lut_arg *lut_arg = data; - struct drm_mode_object *obj; - struct drm_crtc *crtc; - struct drm_connector *connector; - struct psb_intel_crtc *psb_intel_crtc; - int i = 0; - int32_t obj_id; - - obj_id = lut_arg->output_id; - obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR); - if (!obj) { - DRM_DEBUG("Invalid Connector object.\n"); - return -EINVAL; - } - - connector = obj_to_connector(obj); - crtc = connector->encoder->crtc; - psb_intel_crtc = to_psb_intel_crtc(crtc); - - for (i = 0; i < 256; i++) - psb_intel_crtc->lut_adj[i] = lut_arg->lut[i]; - - psb_intel_crtc_load_lut(crtc); - - return 0; -} - -static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - uint32_t obj_id; - uint16_t op; - struct drm_mode_modeinfo *umode; - struct drm_display_mode *mode = NULL; - struct drm_psb_mode_operation_arg *arg; - struct drm_mode_object *obj; - struct drm_connector *connector; - struct drm_framebuffer *drm_fb; - struct psb_framebuffer *psb_fb; - struct drm_connector_helper_funcs *connector_funcs; - int ret = 0; - int resp = MODE_OK; - struct drm_psb_private *dev_priv = psb_priv(dev); - - arg = (struct drm_psb_mode_operation_arg *)data; - obj_id = arg->obj_id; - op = arg->operation; - - switch (op) { - case PSB_MODE_OPERATION_SET_DC_BASE: - obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_FB); - if (!obj) { - DRM_ERROR("Invalid FB id %d\n", obj_id); - return -EINVAL; - } - - drm_fb = obj_to_fb(obj); - psb_fb = to_psb_fb(drm_fb); - - if (gma_power_begin(dev, 0)) { - REG_WRITE(DSPASURF, psb_fb->gtt->offset); - REG_READ(DSPASURF); - gma_power_end(dev); - } else { - dev_priv->saveDSPASURF = psb_fb->gtt->offset; - } - - return 0; - case PSB_MODE_OPERATION_MODE_VALID: - umode = &arg->mode; - - mutex_lock(&dev->mode_config.mutex); - - obj = drm_mode_object_find(dev, obj_id, - DRM_MODE_OBJECT_CONNECTOR); - if (!obj) { - ret = -EINVAL; - goto mode_op_out; - } - - connector = obj_to_connector(obj); - - mode = drm_mode_create(dev); - if (!mode) { - ret = -ENOMEM; - goto mode_op_out; - } - - /* drm_crtc_convert_umode(mode, umode); */ - { - mode->clock = umode->clock; - mode->hdisplay = umode->hdisplay; - mode->hsync_start = umode->hsync_start; - mode->hsync_end = umode->hsync_end; - mode->htotal = umode->htotal; - mode->hskew = umode->hskew; - mode->vdisplay = umode->vdisplay; - mode->vsync_start = umode->vsync_start; - mode->vsync_end = umode->vsync_end; - mode->vtotal = umode->vtotal; - mode->vscan = umode->vscan; - mode->vrefresh = umode->vrefresh; - mode->flags = umode->flags; - mode->type = umode->type; - strncpy(mode->name, umode->name, DRM_DISPLAY_MODE_LEN); - mode->name[DRM_DISPLAY_MODE_LEN-1] = 0; - } - - connector_funcs = (struct drm_connector_helper_funcs *) - connector->helper_private; - - if (connector_funcs->mode_valid) { - resp = connector_funcs->mode_valid(connector, mode); - arg->data = (void *)resp; - } - - /*do some clean up work*/ - if (mode) - drm_mode_destroy(dev, mode); -mode_op_out: - mutex_unlock(&dev->mode_config.mutex); - return ret; - - default: - DRM_DEBUG("Unsupported psb mode operation"); - return -EOPNOTSUPP; - } - - return 0; -} - -static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_private *dev_priv = psb_priv(dev); - struct drm_psb_stolen_memory_arg *arg = data; - - arg->base = dev_priv->stolen_base; - arg->size = dev_priv->vram_stolen_size; - - return 0; -} - -static int psb_register_rw_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_private *dev_priv = psb_priv(dev); - struct drm_psb_register_rw_arg *arg = data; - bool usage = arg->b_force_hw_on ? true : false; - - if (arg->display_write_mask != 0) { - if (gma_power_begin(dev, usage)) { - if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS) - PSB_WVDC32(arg->display.pfit_controls, - PFIT_CONTROL); - if (arg->display_write_mask & - REGRWBITS_PFIT_AUTOSCALE_RATIOS) - PSB_WVDC32(arg->display.pfit_autoscale_ratios, - PFIT_AUTO_RATIOS); - if (arg->display_write_mask & - REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS) - PSB_WVDC32( - arg->display.pfit_programmed_scale_ratios, - PFIT_PGM_RATIOS); - if (arg->display_write_mask & REGRWBITS_PIPEASRC) - PSB_WVDC32(arg->display.pipeasrc, - PIPEASRC); - if (arg->display_write_mask & REGRWBITS_PIPEBSRC) - PSB_WVDC32(arg->display.pipebsrc, - PIPEBSRC); - if (arg->display_write_mask & REGRWBITS_VTOTAL_A) - PSB_WVDC32(arg->display.vtotal_a, - VTOTAL_A); - if (arg->display_write_mask & REGRWBITS_VTOTAL_B) - PSB_WVDC32(arg->display.vtotal_b, - VTOTAL_B); - gma_power_end(dev); - } else { - if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS) - dev_priv->savePFIT_CONTROL = - arg->display.pfit_controls; - if (arg->display_write_mask & - REGRWBITS_PFIT_AUTOSCALE_RATIOS) - dev_priv->savePFIT_AUTO_RATIOS = - arg->display.pfit_autoscale_ratios; - if (arg->display_write_mask & - REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS) - dev_priv->savePFIT_PGM_RATIOS = - arg->display.pfit_programmed_scale_ratios; - if (arg->display_write_mask & REGRWBITS_PIPEASRC) - dev_priv->savePIPEASRC = arg->display.pipeasrc; - if (arg->display_write_mask & REGRWBITS_PIPEBSRC) - dev_priv->savePIPEBSRC = arg->display.pipebsrc; - if (arg->display_write_mask & REGRWBITS_VTOTAL_A) - dev_priv->saveVTOTAL_A = arg->display.vtotal_a; - if (arg->display_write_mask & REGRWBITS_VTOTAL_B) - dev_priv->saveVTOTAL_B = arg->display.vtotal_b; - } - } - - if (arg->display_read_mask != 0) { - if (gma_power_begin(dev, usage)) { - if (arg->display_read_mask & - REGRWBITS_PFIT_CONTROLS) - arg->display.pfit_controls = - PSB_RVDC32(PFIT_CONTROL); - if (arg->display_read_mask & - REGRWBITS_PFIT_AUTOSCALE_RATIOS) - arg->display.pfit_autoscale_ratios = - PSB_RVDC32(PFIT_AUTO_RATIOS); - if (arg->display_read_mask & - REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS) - arg->display.pfit_programmed_scale_ratios = - PSB_RVDC32(PFIT_PGM_RATIOS); - if (arg->display_read_mask & REGRWBITS_PIPEASRC) - arg->display.pipeasrc = PSB_RVDC32(PIPEASRC); - if (arg->display_read_mask & REGRWBITS_PIPEBSRC) - arg->display.pipebsrc = PSB_RVDC32(PIPEBSRC); - if (arg->display_read_mask & REGRWBITS_VTOTAL_A) - arg->display.vtotal_a = PSB_RVDC32(VTOTAL_A); - if (arg->display_read_mask & REGRWBITS_VTOTAL_B) - arg->display.vtotal_b = PSB_RVDC32(VTOTAL_B); - gma_power_end(dev); - } else { - if (arg->display_read_mask & - REGRWBITS_PFIT_CONTROLS) - arg->display.pfit_controls = - dev_priv->savePFIT_CONTROL; - if (arg->display_read_mask & - REGRWBITS_PFIT_AUTOSCALE_RATIOS) - arg->display.pfit_autoscale_ratios = - dev_priv->savePFIT_AUTO_RATIOS; - if (arg->display_read_mask & - REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS) - arg->display.pfit_programmed_scale_ratios = - dev_priv->savePFIT_PGM_RATIOS; - if (arg->display_read_mask & REGRWBITS_PIPEASRC) - arg->display.pipeasrc = dev_priv->savePIPEASRC; - if (arg->display_read_mask & REGRWBITS_PIPEBSRC) - arg->display.pipebsrc = dev_priv->savePIPEBSRC; - if (arg->display_read_mask & REGRWBITS_VTOTAL_A) - arg->display.vtotal_a = dev_priv->saveVTOTAL_A; - if (arg->display_read_mask & REGRWBITS_VTOTAL_B) - arg->display.vtotal_b = dev_priv->saveVTOTAL_B; - } - } - - if (arg->overlay_write_mask != 0) { - if (gma_power_begin(dev, usage)) { - if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) { - PSB_WVDC32(arg->overlay.OGAMC5, OV_OGAMC5); - PSB_WVDC32(arg->overlay.OGAMC4, OV_OGAMC4); - PSB_WVDC32(arg->overlay.OGAMC3, OV_OGAMC3); - PSB_WVDC32(arg->overlay.OGAMC2, OV_OGAMC2); - PSB_WVDC32(arg->overlay.OGAMC1, OV_OGAMC1); - PSB_WVDC32(arg->overlay.OGAMC0, OV_OGAMC0); - } - if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) { - PSB_WVDC32(arg->overlay.OGAMC5, OVC_OGAMC5); - PSB_WVDC32(arg->overlay.OGAMC4, OVC_OGAMC4); - PSB_WVDC32(arg->overlay.OGAMC3, OVC_OGAMC3); - PSB_WVDC32(arg->overlay.OGAMC2, OVC_OGAMC2); - PSB_WVDC32(arg->overlay.OGAMC1, OVC_OGAMC1); - PSB_WVDC32(arg->overlay.OGAMC0, OVC_OGAMC0); - } - - if (arg->overlay_write_mask & OV_REGRWBITS_OVADD) { - PSB_WVDC32(arg->overlay.OVADD, OV_OVADD); - - if (arg->overlay.b_wait_vblank) { - /* Wait for 20ms.*/ - unsigned long vblank_timeout = jiffies - + HZ/50; - uint32_t temp; - while (time_before_eq(jiffies, - vblank_timeout)) { - temp = PSB_RVDC32(OV_DOVASTA); - if ((temp & (0x1 << 31)) != 0) - break; - cpu_relax(); - } - } - } - if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD) { - PSB_WVDC32(arg->overlay.OVADD, OVC_OVADD); - if (arg->overlay.b_wait_vblank) { - /* Wait for 20ms.*/ - unsigned long vblank_timeout = - jiffies + HZ/50; - uint32_t temp; - while (time_before_eq(jiffies, - vblank_timeout)) { - temp = PSB_RVDC32(OVC_DOVCSTA); - if ((temp & (0x1 << 31)) != 0) - break; - cpu_relax(); - } - } - } - gma_power_end(dev); - } else { - if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) { - dev_priv->saveOV_OGAMC5 = arg->overlay.OGAMC5; - dev_priv->saveOV_OGAMC4 = arg->overlay.OGAMC4; - dev_priv->saveOV_OGAMC3 = arg->overlay.OGAMC3; - dev_priv->saveOV_OGAMC2 = arg->overlay.OGAMC2; - dev_priv->saveOV_OGAMC1 = arg->overlay.OGAMC1; - dev_priv->saveOV_OGAMC0 = arg->overlay.OGAMC0; - } - if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) { - dev_priv->saveOVC_OGAMC5 = arg->overlay.OGAMC5; - dev_priv->saveOVC_OGAMC4 = arg->overlay.OGAMC4; - dev_priv->saveOVC_OGAMC3 = arg->overlay.OGAMC3; - dev_priv->saveOVC_OGAMC2 = arg->overlay.OGAMC2; - dev_priv->saveOVC_OGAMC1 = arg->overlay.OGAMC1; - dev_priv->saveOVC_OGAMC0 = arg->overlay.OGAMC0; - } - if (arg->overlay_write_mask & OV_REGRWBITS_OVADD) - dev_priv->saveOV_OVADD = arg->overlay.OVADD; - if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD) - dev_priv->saveOVC_OVADD = arg->overlay.OVADD; - } - } - - if (arg->overlay_read_mask != 0) { - if (gma_power_begin(dev, usage)) { - if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) { - arg->overlay.OGAMC5 = PSB_RVDC32(OV_OGAMC5); - arg->overlay.OGAMC4 = PSB_RVDC32(OV_OGAMC4); - arg->overlay.OGAMC3 = PSB_RVDC32(OV_OGAMC3); - arg->overlay.OGAMC2 = PSB_RVDC32(OV_OGAMC2); - arg->overlay.OGAMC1 = PSB_RVDC32(OV_OGAMC1); - arg->overlay.OGAMC0 = PSB_RVDC32(OV_OGAMC0); - } - if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) { - arg->overlay.OGAMC5 = PSB_RVDC32(OVC_OGAMC5); - arg->overlay.OGAMC4 = PSB_RVDC32(OVC_OGAMC4); - arg->overlay.OGAMC3 = PSB_RVDC32(OVC_OGAMC3); - arg->overlay.OGAMC2 = PSB_RVDC32(OVC_OGAMC2); - arg->overlay.OGAMC1 = PSB_RVDC32(OVC_OGAMC1); - arg->overlay.OGAMC0 = PSB_RVDC32(OVC_OGAMC0); - } - if (arg->overlay_read_mask & OV_REGRWBITS_OVADD) - arg->overlay.OVADD = PSB_RVDC32(OV_OVADD); - if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD) - arg->overlay.OVADD = PSB_RVDC32(OVC_OVADD); - gma_power_end(dev); - } else { - if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) { - arg->overlay.OGAMC5 = dev_priv->saveOV_OGAMC5; - arg->overlay.OGAMC4 = dev_priv->saveOV_OGAMC4; - arg->overlay.OGAMC3 = dev_priv->saveOV_OGAMC3; - arg->overlay.OGAMC2 = dev_priv->saveOV_OGAMC2; - arg->overlay.OGAMC1 = dev_priv->saveOV_OGAMC1; - arg->overlay.OGAMC0 = dev_priv->saveOV_OGAMC0; - } - if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) { - arg->overlay.OGAMC5 = dev_priv->saveOVC_OGAMC5; - arg->overlay.OGAMC4 = dev_priv->saveOVC_OGAMC4; - arg->overlay.OGAMC3 = dev_priv->saveOVC_OGAMC3; - arg->overlay.OGAMC2 = dev_priv->saveOVC_OGAMC2; - arg->overlay.OGAMC1 = dev_priv->saveOVC_OGAMC1; - arg->overlay.OGAMC0 = dev_priv->saveOVC_OGAMC0; - } - if (arg->overlay_read_mask & OV_REGRWBITS_OVADD) - arg->overlay.OVADD = dev_priv->saveOV_OVADD; - if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD) - arg->overlay.OVADD = dev_priv->saveOVC_OVADD; - } - } - - if (arg->sprite_enable_mask != 0) { - if (gma_power_begin(dev, usage)) { - PSB_WVDC32(0x1F3E, DSPARB); - PSB_WVDC32(arg->sprite.dspa_control - | PSB_RVDC32(DSPACNTR), DSPACNTR); - PSB_WVDC32(arg->sprite.dspa_key_value, DSPAKEYVAL); - PSB_WVDC32(arg->sprite.dspa_key_mask, DSPAKEYMASK); - PSB_WVDC32(PSB_RVDC32(DSPASURF), DSPASURF); - PSB_RVDC32(DSPASURF); - PSB_WVDC32(arg->sprite.dspc_control, DSPCCNTR); - PSB_WVDC32(arg->sprite.dspc_stride, DSPCSTRIDE); - PSB_WVDC32(arg->sprite.dspc_position, DSPCPOS); - PSB_WVDC32(arg->sprite.dspc_linear_offset, DSPCLINOFF); - PSB_WVDC32(arg->sprite.dspc_size, DSPCSIZE); - PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF); - PSB_RVDC32(DSPCSURF); - gma_power_end(dev); - } - } - - if (arg->sprite_disable_mask != 0) { - if (gma_power_begin(dev, usage)) { - PSB_WVDC32(0x3F3E, DSPARB); - PSB_WVDC32(0x0, DSPCCNTR); - PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF); - PSB_RVDC32(DSPCSURF); - gma_power_end(dev); - } - } - - if (arg->subpicture_enable_mask != 0) { - if (gma_power_begin(dev, usage)) { - uint32_t temp; - if (arg->subpicture_enable_mask & REGRWBITS_DSPACNTR) { - temp = PSB_RVDC32(DSPACNTR); - temp &= ~DISPPLANE_PIXFORMAT_MASK; - temp &= ~DISPPLANE_BOTTOM; - temp |= DISPPLANE_32BPP; - PSB_WVDC32(temp, DSPACNTR); - - temp = PSB_RVDC32(DSPABASE); - PSB_WVDC32(temp, DSPABASE); - PSB_RVDC32(DSPABASE); - temp = PSB_RVDC32(DSPASURF); - PSB_WVDC32(temp, DSPASURF); - PSB_RVDC32(DSPASURF); - } - if (arg->subpicture_enable_mask & REGRWBITS_DSPBCNTR) { - temp = PSB_RVDC32(DSPBCNTR); - temp &= ~DISPPLANE_PIXFORMAT_MASK; - temp &= ~DISPPLANE_BOTTOM; - temp |= DISPPLANE_32BPP; - PSB_WVDC32(temp, DSPBCNTR); - - temp = PSB_RVDC32(DSPBBASE); - PSB_WVDC32(temp, DSPBBASE); - PSB_RVDC32(DSPBBASE); - temp = PSB_RVDC32(DSPBSURF); - PSB_WVDC32(temp, DSPBSURF); - PSB_RVDC32(DSPBSURF); - } - if (arg->subpicture_enable_mask & REGRWBITS_DSPCCNTR) { - temp = PSB_RVDC32(DSPCCNTR); - temp &= ~DISPPLANE_PIXFORMAT_MASK; - temp &= ~DISPPLANE_BOTTOM; - temp |= DISPPLANE_32BPP; - PSB_WVDC32(temp, DSPCCNTR); - - temp = PSB_RVDC32(DSPCBASE); - PSB_WVDC32(temp, DSPCBASE); - PSB_RVDC32(DSPCBASE); - temp = PSB_RVDC32(DSPCSURF); - PSB_WVDC32(temp, DSPCSURF); - PSB_RVDC32(DSPCSURF); - } - gma_power_end(dev); - } - } - - if (arg->subpicture_disable_mask != 0) { - if (gma_power_begin(dev, usage)) { - uint32_t temp; - if (arg->subpicture_disable_mask & REGRWBITS_DSPACNTR) { - temp = PSB_RVDC32(DSPACNTR); - temp &= ~DISPPLANE_PIXFORMAT_MASK; - temp |= DISPPLANE_32BPP_NO_ALPHA; - PSB_WVDC32(temp, DSPACNTR); - - temp = PSB_RVDC32(DSPABASE); - PSB_WVDC32(temp, DSPABASE); - PSB_RVDC32(DSPABASE); - temp = PSB_RVDC32(DSPASURF); - PSB_WVDC32(temp, DSPASURF); - PSB_RVDC32(DSPASURF); - } - if (arg->subpicture_disable_mask & REGRWBITS_DSPBCNTR) { - temp = PSB_RVDC32(DSPBCNTR); - temp &= ~DISPPLANE_PIXFORMAT_MASK; - temp |= DISPPLANE_32BPP_NO_ALPHA; - PSB_WVDC32(temp, DSPBCNTR); - - temp = PSB_RVDC32(DSPBBASE); - PSB_WVDC32(temp, DSPBBASE); - PSB_RVDC32(DSPBBASE); - temp = PSB_RVDC32(DSPBSURF); - PSB_WVDC32(temp, DSPBSURF); - PSB_RVDC32(DSPBSURF); - } - if (arg->subpicture_disable_mask & REGRWBITS_DSPCCNTR) { - temp = PSB_RVDC32(DSPCCNTR); - temp &= ~DISPPLANE_PIXFORMAT_MASK; - temp |= DISPPLANE_32BPP_NO_ALPHA; - PSB_WVDC32(temp, DSPCCNTR); - - temp = PSB_RVDC32(DSPCBASE); - PSB_WVDC32(temp, DSPCBASE); - PSB_RVDC32(DSPCBASE); - temp = PSB_RVDC32(DSPCSURF); - PSB_WVDC32(temp, DSPCSURF); - PSB_RVDC32(DSPCSURF); - } - gma_power_end(dev); - } - } - - return 0; -} - -static int psb_driver_open(struct drm_device *dev, struct drm_file *priv) -{ - return 0; -} - -static void psb_driver_close(struct drm_device *dev, struct drm_file *priv) -{ -} - -static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -{ - struct drm_file *file_priv = filp->private_data; - struct drm_device *dev = file_priv->minor->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - static unsigned int runtime_allowed; - unsigned int nr = DRM_IOCTL_NR(cmd); - - DRM_DEBUG("cmd = %x, nr = %x\n", cmd, nr); - - if (runtime_allowed == 1 && dev_priv->is_lvds_on) { - runtime_allowed++; - pm_runtime_allow(&dev->pdev->dev); - dev_priv->rpm_enabled = 1; - } - return drm_ioctl(filp, cmd, arg); - - /* FIXME: do we need to wrap the other side of this */ -} - - -/* When a client dies: - * - Check for and clean up flipped page state - */ -void psb_driver_preclose(struct drm_device *dev, struct drm_file *priv) -{ -} - -static void psb_remove(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - drm_put_dev(dev); -} - -static const struct dev_pm_ops psb_pm_ops = { - .runtime_suspend = psb_runtime_suspend, - .runtime_resume = psb_runtime_resume, - .runtime_idle = psb_runtime_idle, -}; - -static struct vm_operations_struct psb_gem_vm_ops = { - .fault = psb_gem_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - -static struct drm_driver driver = { - .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \ - DRIVER_IRQ_VBL | DRIVER_MODESET| DRIVER_GEM , - .load = psb_driver_load, - .unload = psb_driver_unload, - - .ioctls = psb_ioctls, - .num_ioctls = DRM_ARRAY_SIZE(psb_ioctls), - .device_is_agp = psb_driver_device_is_agp, - .irq_preinstall = psb_irq_preinstall, - .irq_postinstall = psb_irq_postinstall, - .irq_uninstall = psb_irq_uninstall, - .irq_handler = psb_irq_handler, - .enable_vblank = psb_enable_vblank, - .disable_vblank = psb_disable_vblank, - .get_vblank_counter = psb_get_vblank_counter, - .lastclose = psb_lastclose, - .open = psb_driver_open, - .preclose = psb_driver_preclose, - .postclose = psb_driver_close, - .reclaim_buffers = drm_core_reclaim_buffers, - - .gem_init_object = psb_gem_init_object, - .gem_free_object = psb_gem_free_object, - .gem_vm_ops = &psb_gem_vm_ops, - .dumb_create = psb_gem_dumb_create, - .dumb_map_offset = psb_gem_dumb_map_gtt, - .dumb_destroy = psb_gem_dumb_destroy, - - .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = psb_unlocked_ioctl, - .mmap = drm_gem_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - .read = drm_read, - }, - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = PSB_DRM_DRIVER_DATE, - .major = PSB_DRM_DRIVER_MAJOR, - .minor = PSB_DRM_DRIVER_MINOR, - .patchlevel = PSB_DRM_DRIVER_PATCHLEVEL -}; - -static struct pci_driver psb_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - .resume = gma_power_resume, - .suspend = gma_power_suspend, - .probe = psb_probe, - .remove = psb_remove, -#ifdef CONFIG_PM - .driver.pm = &psb_pm_ops, -#endif -}; - -static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - /* MLD Added this from Inaky's patch */ - if (pci_enable_msi(pdev)) - DRM_ERROR("Enable MSI failed!\n"); - return drm_get_pci_dev(pdev, ent, &driver); -} - -static int __init psb_init(void) -{ - return drm_pci_init(&driver, &psb_pci_driver); -} - -static void __exit psb_exit(void) -{ - drm_pci_exit(&driver, &psb_pci_driver); -} - -late_initcall(psb_init); -module_exit(psb_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h deleted file mode 100644 index e19a4547875..00000000000 --- a/drivers/staging/gma500/psb_drv.h +++ /dev/null @@ -1,845 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007-2008, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#ifndef _PSB_DRV_H_ -#define _PSB_DRV_H_ - -#include <linux/version.h> -#include <linux/kref.h> - -#include <drm/drmP.h> -#include "drm_global.h" -#include "psb_drm.h" -#include "psb_reg.h" -#include "psb_intel_drv.h" -#include "psb_gtt.h" -#include "psb_powermgmt.h" -#include "mrst.h" - -/*Append new drm mode definition here, align with libdrm definition*/ -#define DRM_MODE_SCALE_NO_SCALE 2 - -enum { - CHIP_PSB_8108 = 0, - CHIP_PSB_8109 = 1, - CHIP_MRST_4100 = 2, -}; - -#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100) - -/* - *Hardware bugfixes - */ - -#define DRIVER_NAME "pvrsrvkm" -#define DRIVER_DESC "drm driver for the Intel GMA500" -#define DRIVER_AUTHOR "Intel Corporation" - -#define PSB_DRM_DRIVER_DATE "2009-03-10" -#define PSB_DRM_DRIVER_MAJOR 8 -#define PSB_DRM_DRIVER_MINOR 1 -#define PSB_DRM_DRIVER_PATCHLEVEL 0 - -/* - *TTM driver private offsets. - */ - -#define DRM_PSB_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) - -#define PSB_OBJECT_HASH_ORDER 13 -#define PSB_FILE_OBJECT_HASH_ORDER 12 -#define PSB_BO_HASH_ORDER 12 - -#define PSB_VDC_OFFSET 0x00000000 -#define PSB_VDC_SIZE 0x000080000 -#define MRST_MMIO_SIZE 0x0000C0000 -#define MDFLD_MMIO_SIZE 0x000100000 -#define PSB_SGX_SIZE 0x8000 -#define PSB_SGX_OFFSET 0x00040000 -#define MRST_SGX_OFFSET 0x00080000 -#define PSB_MMIO_RESOURCE 0 -#define PSB_GATT_RESOURCE 2 -#define PSB_GTT_RESOURCE 3 -#define PSB_GMCH_CTRL 0x52 -#define PSB_BSM 0x5C -#define _PSB_GMCH_ENABLED 0x4 -#define PSB_PGETBL_CTL 0x2020 -#define _PSB_PGETBL_ENABLED 0x00000001 -#define PSB_SGX_2D_SLAVE_PORT 0x4000 -#define PSB_TT_PRIV0_LIMIT (256*1024*1024) -#define PSB_TT_PRIV0_PLIMIT (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT) -#define PSB_NUM_VALIDATE_BUFFERS 2048 - -/* - *Flags for external memory type field. - */ - -#define PSB_MMU_CACHED_MEMORY 0x0001 /* Bind to MMU only */ -#define PSB_MMU_RO_MEMORY 0x0002 /* MMU RO memory */ -#define PSB_MMU_WO_MEMORY 0x0004 /* MMU WO memory */ - -/* - *PTE's and PDE's - */ - -#define PSB_PDE_MASK 0x003FFFFF -#define PSB_PDE_SHIFT 22 -#define PSB_PTE_SHIFT 12 - -#define PSB_PTE_VALID 0x0001 /* PTE / PDE valid */ -#define PSB_PTE_WO 0x0002 /* Write only */ -#define PSB_PTE_RO 0x0004 /* Read only */ -#define PSB_PTE_CACHED 0x0008 /* CPU cache coherent */ - -/* - *VDC registers and bits - */ -#define PSB_MSVDX_CLOCKGATING 0x2064 -#define PSB_TOPAZ_CLOCKGATING 0x2068 -#define PSB_HWSTAM 0x2098 -#define PSB_INSTPM 0x20C0 -#define PSB_INT_IDENTITY_R 0x20A4 -#define _MDFLD_PIPEC_EVENT_FLAG (1<<2) -#define _MDFLD_PIPEC_VBLANK_FLAG (1<<3) -#define _PSB_DPST_PIPEB_FLAG (1<<4) -#define _MDFLD_PIPEB_EVENT_FLAG (1<<4) -#define _PSB_VSYNC_PIPEB_FLAG (1<<5) -#define _PSB_DPST_PIPEA_FLAG (1<<6) -#define _PSB_PIPEA_EVENT_FLAG (1<<6) -#define _PSB_VSYNC_PIPEA_FLAG (1<<7) -#define _MDFLD_MIPIA_FLAG (1<<16) -#define _MDFLD_MIPIC_FLAG (1<<17) -#define _PSB_IRQ_SGX_FLAG (1<<18) -#define _PSB_IRQ_MSVDX_FLAG (1<<19) -#define _LNC_IRQ_TOPAZ_FLAG (1<<20) - -/* This flag includes all the display IRQ bits excepts the vblank irqs. */ -#define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | _MDFLD_PIPEB_EVENT_FLAG | \ - _PSB_PIPEA_EVENT_FLAG | _PSB_VSYNC_PIPEA_FLAG | _MDFLD_MIPIA_FLAG | _MDFLD_MIPIC_FLAG) -#define PSB_INT_IDENTITY_R 0x20A4 -#define PSB_INT_MASK_R 0x20A8 -#define PSB_INT_ENABLE_R 0x20A0 - -#define _PSB_MMU_ER_MASK 0x0001FF00 -#define _PSB_MMU_ER_HOST (1 << 16) -#define GPIOA 0x5010 -#define GPIOB 0x5014 -#define GPIOC 0x5018 -#define GPIOD 0x501c -#define GPIOE 0x5020 -#define GPIOF 0x5024 -#define GPIOG 0x5028 -#define GPIOH 0x502c -#define GPIO_CLOCK_DIR_MASK (1 << 0) -#define GPIO_CLOCK_DIR_IN (0 << 1) -#define GPIO_CLOCK_DIR_OUT (1 << 1) -#define GPIO_CLOCK_VAL_MASK (1 << 2) -#define GPIO_CLOCK_VAL_OUT (1 << 3) -#define GPIO_CLOCK_VAL_IN (1 << 4) -#define GPIO_CLOCK_PULLUP_DISABLE (1 << 5) -#define GPIO_DATA_DIR_MASK (1 << 8) -#define GPIO_DATA_DIR_IN (0 << 9) -#define GPIO_DATA_DIR_OUT (1 << 9) -#define GPIO_DATA_VAL_MASK (1 << 10) -#define GPIO_DATA_VAL_OUT (1 << 11) -#define GPIO_DATA_VAL_IN (1 << 12) -#define GPIO_DATA_PULLUP_DISABLE (1 << 13) - -#define VCLK_DIVISOR_VGA0 0x6000 -#define VCLK_DIVISOR_VGA1 0x6004 -#define VCLK_POST_DIV 0x6010 - -#define PSB_COMM_2D (PSB_ENGINE_2D << 4) -#define PSB_COMM_3D (PSB_ENGINE_3D << 4) -#define PSB_COMM_TA (PSB_ENGINE_TA << 4) -#define PSB_COMM_HP (PSB_ENGINE_HP << 4) -#define PSB_COMM_USER_IRQ (1024 >> 2) -#define PSB_COMM_USER_IRQ_LOST (PSB_COMM_USER_IRQ + 1) -#define PSB_COMM_FW (2048 >> 2) - -#define PSB_UIRQ_VISTEST 1 -#define PSB_UIRQ_OOM_REPLY 2 -#define PSB_UIRQ_FIRE_TA_REPLY 3 -#define PSB_UIRQ_FIRE_RASTER_REPLY 4 - -#define PSB_2D_SIZE (256*1024*1024) -#define PSB_MAX_RELOC_PAGES 1024 - -#define PSB_LOW_REG_OFFS 0x0204 -#define PSB_HIGH_REG_OFFS 0x0600 - -#define PSB_NUM_VBLANKS 2 - - -#define PSB_2D_SIZE (256*1024*1024) -#define PSB_MAX_RELOC_PAGES 1024 - -#define PSB_LOW_REG_OFFS 0x0204 -#define PSB_HIGH_REG_OFFS 0x0600 - -#define PSB_NUM_VBLANKS 2 -#define PSB_WATCHDOG_DELAY (DRM_HZ * 2) -#define PSB_LID_DELAY (DRM_HZ / 10) - -#define MDFLD_PNW_A0 0x00 -#define MDFLD_PNW_B0 0x04 -#define MDFLD_PNW_C0 0x08 - -#define PSB_PWR_STATE_ON 1 -#define PSB_PWR_STATE_OFF 2 - -#define PSB_PMPOLICY_NOPM 0 -#define PSB_PMPOLICY_CLOCKGATING 1 -#define PSB_PMPOLICY_POWERDOWN 2 - -#define PSB_PMSTATE_POWERUP 0 -#define PSB_PMSTATE_CLOCKGATED 1 -#define PSB_PMSTATE_POWERDOWN 2 -#define PSB_PCIx_MSI_ADDR_LOC 0x94 -#define PSB_PCIx_MSI_DATA_LOC 0x98 - -struct opregion_header; -struct opregion_acpi; -struct opregion_swsci; -struct opregion_asle; - -struct psb_intel_opregion { - struct opregion_header *header; - struct opregion_acpi *acpi; - struct opregion_swsci *swsci; - struct opregion_asle *asle; - int enabled; -}; - - -struct drm_psb_private { - struct drm_device *dev; - - unsigned long chipset; - - struct psb_gtt *pg; - - /* GTT Memory manager */ - struct psb_gtt_mm *gtt_mm; - struct page *scratch_page; - u32 *gtt_map; - uint32_t stolen_base; - void *vram_addr; - unsigned long vram_stolen_size; - int gtt_initialized; - u16 gmch_ctrl; /* Saved GTT setup */ - u32 pge_ctl; - - struct mutex gtt_mutex; - struct resource *gtt_mem; /* Our PCI resource */ - - struct psb_mmu_driver *mmu; - struct psb_mmu_pd *pf_pd; - - /* - * Register base - */ - - uint8_t *sgx_reg; - uint8_t *vdc_reg; - uint32_t gatt_free_offset; - - /* - * Fencing / irq. - */ - - uint32_t vdc_irq_mask; - uint32_t pipestat[PSB_NUM_PIPE]; - - spinlock_t irqmask_lock; - - /* - * Power - */ - - bool suspended; - bool display_power; - int display_count; - - /* - *Modesetting - */ - struct psb_intel_mode_device mode_dev; - - struct drm_crtc *plane_to_crtc_mapping[PSB_NUM_PIPE]; - struct drm_crtc *pipe_to_crtc_mapping[PSB_NUM_PIPE]; - uint32_t num_pipe; - - /* - *Memory managers - */ - - /* - *OSPM info - */ - uint32_t ospm_base; - - /* - * Sizes info - */ - - struct drm_psb_sizes_arg sizes; - - u32 fuse_reg_value; - u32 video_device_fuse; - - /* pci revision id for B0:D2:F0 */ - uint8_t platform_rev_id; - - /* - *LVDS info - */ - int backlight_duty_cycle; /* restore backlight to this value */ - bool panel_wants_dither; - struct drm_display_mode *panel_fixed_mode; - struct drm_display_mode *lfp_lvds_vbt_mode; - struct drm_display_mode *sdvo_lvds_vbt_mode; - - struct bdb_lvds_backlight *lvds_bl; /*LVDS backlight info from VBT*/ - struct psb_intel_i2c_chan *lvds_i2c_bus; - - /* Feature bits from the VBIOS*/ - unsigned int int_tv_support:1; - unsigned int lvds_dither:1; - unsigned int lvds_vbt:1; - unsigned int int_crt_support:1; - unsigned int lvds_use_ssc:1; - int lvds_ssc_freq; - bool is_lvds_on; - bool is_mipi_on; - - unsigned int core_freq; - uint32_t iLVDS_enable; - - /*runtime PM state*/ - int rpm_enabled; - - /* Moorestown specific */ - struct mrst_vbt vbt_data; - struct mrst_gct_data gct_data; - - /* Moorestown pipe config register value cache */ - uint32_t pipeconf; - uint32_t pipeconf1; - uint32_t pipeconf2; - - /* Moorestown plane control register value cache */ - uint32_t dspcntr; - uint32_t dspcntr1; - uint32_t dspcntr2; - - /* - *Register state - */ - uint32_t saveDSPACNTR; - uint32_t saveDSPBCNTR; - uint32_t savePIPEACONF; - uint32_t savePIPEBCONF; - uint32_t savePIPEASRC; - uint32_t savePIPEBSRC; - uint32_t saveFPA0; - uint32_t saveFPA1; - uint32_t saveDPLL_A; - uint32_t saveDPLL_A_MD; - uint32_t saveHTOTAL_A; - uint32_t saveHBLANK_A; - uint32_t saveHSYNC_A; - uint32_t saveVTOTAL_A; - uint32_t saveVBLANK_A; - uint32_t saveVSYNC_A; - uint32_t saveDSPASTRIDE; - uint32_t saveDSPASIZE; - uint32_t saveDSPAPOS; - uint32_t saveDSPABASE; - uint32_t saveDSPASURF; - uint32_t saveFPB0; - uint32_t saveFPB1; - uint32_t saveDPLL_B; - uint32_t saveDPLL_B_MD; - uint32_t saveHTOTAL_B; - uint32_t saveHBLANK_B; - uint32_t saveHSYNC_B; - uint32_t saveVTOTAL_B; - uint32_t saveVBLANK_B; - uint32_t saveVSYNC_B; - uint32_t saveDSPBSTRIDE; - uint32_t saveDSPBSIZE; - uint32_t saveDSPBPOS; - uint32_t saveDSPBBASE; - uint32_t saveDSPBSURF; - uint32_t saveVCLK_DIVISOR_VGA0; - uint32_t saveVCLK_DIVISOR_VGA1; - uint32_t saveVCLK_POST_DIV; - uint32_t saveVGACNTRL; - uint32_t saveADPA; - uint32_t saveLVDS; - uint32_t saveDVOA; - uint32_t saveDVOB; - uint32_t saveDVOC; - uint32_t savePP_ON; - uint32_t savePP_OFF; - uint32_t savePP_CONTROL; - uint32_t savePP_CYCLE; - uint32_t savePFIT_CONTROL; - uint32_t savePaletteA[256]; - uint32_t savePaletteB[256]; - uint32_t saveBLC_PWM_CTL2; - uint32_t saveBLC_PWM_CTL; - uint32_t saveCLOCKGATING; - uint32_t saveDSPARB; - uint32_t saveDSPATILEOFF; - uint32_t saveDSPBTILEOFF; - uint32_t saveDSPAADDR; - uint32_t saveDSPBADDR; - uint32_t savePFIT_AUTO_RATIOS; - uint32_t savePFIT_PGM_RATIOS; - uint32_t savePP_ON_DELAYS; - uint32_t savePP_OFF_DELAYS; - uint32_t savePP_DIVISOR; - uint32_t saveBSM; - uint32_t saveVBT; - uint32_t saveBCLRPAT_A; - uint32_t saveBCLRPAT_B; - uint32_t saveDSPALINOFF; - uint32_t saveDSPBLINOFF; - uint32_t savePERF_MODE; - uint32_t saveDSPFW1; - uint32_t saveDSPFW2; - uint32_t saveDSPFW3; - uint32_t saveDSPFW4; - uint32_t saveDSPFW5; - uint32_t saveDSPFW6; - uint32_t saveCHICKENBIT; - uint32_t saveDSPACURSOR_CTRL; - uint32_t saveDSPBCURSOR_CTRL; - uint32_t saveDSPACURSOR_BASE; - uint32_t saveDSPBCURSOR_BASE; - uint32_t saveDSPACURSOR_POS; - uint32_t saveDSPBCURSOR_POS; - uint32_t save_palette_a[256]; - uint32_t save_palette_b[256]; - uint32_t saveOV_OVADD; - uint32_t saveOV_OGAMC0; - uint32_t saveOV_OGAMC1; - uint32_t saveOV_OGAMC2; - uint32_t saveOV_OGAMC3; - uint32_t saveOV_OGAMC4; - uint32_t saveOV_OGAMC5; - uint32_t saveOVC_OVADD; - uint32_t saveOVC_OGAMC0; - uint32_t saveOVC_OGAMC1; - uint32_t saveOVC_OGAMC2; - uint32_t saveOVC_OGAMC3; - uint32_t saveOVC_OGAMC4; - uint32_t saveOVC_OGAMC5; - - /* MSI reg save */ - uint32_t msi_addr; - uint32_t msi_data; - - /* - * LID-Switch - */ - spinlock_t lid_lock; - struct timer_list lid_timer; - struct psb_intel_opregion opregion; - u32 *lid_state; - u32 lid_last_state; - - /* - *Watchdog - */ - - uint32_t apm_reg; - uint16_t apm_base; - - /* - * Used for modifying backlight from - * xrandr -- consider removing and using HAL instead - */ - struct drm_property *backlight_property; - uint32_t blc_adj1; - uint32_t blc_adj2; - - void * fbdev; -}; - - -struct psb_mmu_driver; - -extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int); -extern int drm_pick_crtcs(struct drm_device *dev); - -static inline struct drm_psb_private *psb_priv(struct drm_device *dev) -{ - return (struct drm_psb_private *) dev->dev_private; -} - -/* - *MMU stuff. - */ - -extern struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers, - int trap_pagefaults, - int invalid_type, - struct drm_psb_private *dev_priv); -extern void psb_mmu_driver_takedown(struct psb_mmu_driver *driver); -extern struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver - *driver); -extern void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, uint32_t mmu_offset, - uint32_t gtt_start, uint32_t gtt_pages); -extern struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver, - int trap_pagefaults, - int invalid_type); -extern void psb_mmu_free_pagedir(struct psb_mmu_pd *pd); -extern void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot); -extern void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd, - unsigned long address, - uint32_t num_pages); -extern int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, - uint32_t start_pfn, - unsigned long address, - uint32_t num_pages, int type); -extern int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual, - unsigned long *pfn); - -/* - *Enable / disable MMU for different requestors. - */ - - -extern void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context); -extern int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages, - unsigned long address, uint32_t num_pages, - uint32_t desired_tile_stride, - uint32_t hw_tile_stride, int type); -extern void psb_mmu_remove_pages(struct psb_mmu_pd *pd, - unsigned long address, uint32_t num_pages, - uint32_t desired_tile_stride, - uint32_t hw_tile_stride); -/* - *psb_irq.c - */ - -extern irqreturn_t psb_irq_handler(DRM_IRQ_ARGS); -extern int psb_irq_enable_dpst(struct drm_device *dev); -extern int psb_irq_disable_dpst(struct drm_device *dev); -extern void psb_irq_preinstall(struct drm_device *dev); -extern int psb_irq_postinstall(struct drm_device *dev); -extern void psb_irq_uninstall(struct drm_device *dev); -extern void psb_irq_turn_on_dpst(struct drm_device *dev); -extern void psb_irq_turn_off_dpst(struct drm_device *dev); - -extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands); -extern int psb_vblank_wait2(struct drm_device *dev,unsigned int *sequence); -extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence); -extern int psb_enable_vblank(struct drm_device *dev, int crtc); -extern void psb_disable_vblank(struct drm_device *dev, int crtc); -void -psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); - -void -psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); - -extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc); - -/* - * psb_opregion.c - */ -extern int psb_intel_opregion_init(struct drm_device *dev); - -/* - *psb_fb.c - */ -extern int psbfb_probed(struct drm_device *dev); -extern int psbfb_remove(struct drm_device *dev, - struct drm_framebuffer *fb); -extern int psbfb_kms_off_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psbfb_kms_on_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern void *psbfb_vdc_reg(struct drm_device* dev); - -/* - * psb_2d.c - */ -extern void psbfb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect); -extern void psbfb_copyarea(struct fb_info *info, - const struct fb_copyarea *region); -extern void psbfb_imageblit(struct fb_info *info, - const struct fb_image *image); -extern int psbfb_sync(struct fb_info *info); - -extern void psb_spank(struct drm_psb_private *dev_priv); - -extern int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, - unsigned size); - -/* - *psb_reset.c - */ - -extern void psb_lid_timer_init(struct drm_psb_private *dev_priv); -extern void psb_lid_timer_takedown(struct drm_psb_private *dev_priv); -extern void psb_print_pagefault(struct drm_psb_private *dev_priv); - -/* modesetting */ -extern void psb_modeset_init(struct drm_device *dev); -extern void psb_modeset_cleanup(struct drm_device *dev); -extern int psb_fbdev_init(struct drm_device * dev); - -/* psb_bl.c */ -int psb_backlight_init(struct drm_device *dev); -void psb_backlight_exit(void); -int psb_set_brightness(struct backlight_device *bd); -int psb_get_brightness(struct backlight_device *bd); -struct backlight_device * psb_get_backlight_device(void); - -/* mrst_crtc.c */ -extern const struct drm_crtc_helper_funcs mrst_helper_funcs; - -/* mrst_lvds.c */ -extern void mrst_lvds_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev); - -/* psb_intel_lvds.c */ -extern void psb_intel_lvds_prepare(struct drm_encoder *encoder); -extern void psb_intel_lvds_commit(struct drm_encoder *encoder); -extern const struct drm_connector_helper_funcs - psb_intel_lvds_connector_helper_funcs; -extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs; - -/* psb_gem.c */ -extern int psb_gem_init_object(struct drm_gem_object *obj); -extern void psb_gem_free_object(struct drm_gem_object *obj); -extern int psb_gem_get_aperture(struct drm_device *dev, void *data, - struct drm_file *file); -extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev, - struct drm_mode_create_dumb *args); -extern int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, - uint32_t handle); -extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, - uint32_t handle, uint64_t *offset); -extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); - - -/* - * Debug print bits setting - */ -#define PSB_D_GENERAL (1 << 0) -#define PSB_D_INIT (1 << 1) -#define PSB_D_IRQ (1 << 2) -#define PSB_D_ENTRY (1 << 3) -/* debug the get H/V BP/FP count */ -#define PSB_D_HV (1 << 4) -#define PSB_D_DBI_BF (1 << 5) -#define PSB_D_PM (1 << 6) -#define PSB_D_RENDER (1 << 7) -#define PSB_D_REG (1 << 8) -#define PSB_D_MSVDX (1 << 9) -#define PSB_D_TOPAZ (1 << 10) - -#ifndef DRM_DEBUG_CODE -/* To enable debug printout, set drm_psb_debug in psb_drv.c - * to any combination of above print flags. - */ -/* #define DRM_DEBUG_CODE 2 */ -#endif - -extern int drm_psb_debug; -extern int drm_psb_no_fb; -extern int drm_idle_check_interval; - -#define PSB_DEBUG_GENERAL(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_GENERAL, _fmt, ##_arg) -#define PSB_DEBUG_INIT(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_INIT, _fmt, ##_arg) -#define PSB_DEBUG_IRQ(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_IRQ, _fmt, ##_arg) -#define PSB_DEBUG_ENTRY(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_ENTRY, _fmt, ##_arg) -#define PSB_DEBUG_HV(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_HV, _fmt, ##_arg) -#define PSB_DEBUG_DBI_BF(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_DBI_BF, _fmt, ##_arg) -#define PSB_DEBUG_PM(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_PM, _fmt, ##_arg) -#define PSB_DEBUG_RENDER(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_RENDER, _fmt, ##_arg) -#define PSB_DEBUG_REG(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_REG, _fmt, ##_arg) -#define PSB_DEBUG_MSVDX(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_MSVDX, _fmt, ##_arg) -#define PSB_DEBUG_TOPAZ(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_TOPAZ, _fmt, ##_arg) - -#if DRM_DEBUG_CODE -#define PSB_DEBUG(_flag, _fmt, _arg...) \ - do { \ - if (unlikely((_flag) & drm_psb_debug)) \ - printk(KERN_DEBUG \ - "[psb:0x%02x:%s] " _fmt , _flag, \ - __func__ , ##_arg); \ - } while (0) -#else -#define PSB_DEBUG(_fmt, _arg...) do { } while (0) -#endif - -/* - *Utilities - */ -#define DRM_DRIVER_PRIVATE_T struct drm_psb_private - -static inline u32 MRST_MSG_READ32(uint port, uint offset) -{ - int mcr = (0xD0<<24) | (port << 16) | (offset << 8); - uint32_t ret_val = 0; - struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0); - pci_write_config_dword (pci_root, 0xD0, mcr); - pci_read_config_dword (pci_root, 0xD4, &ret_val); - pci_dev_put(pci_root); - return ret_val; -} -static inline void MRST_MSG_WRITE32(uint port, uint offset, u32 value) -{ - int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0; - struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0); - pci_write_config_dword (pci_root, 0xD4, value); - pci_write_config_dword (pci_root, 0xD0, mcr); - pci_dev_put(pci_root); -} -static inline u32 MDFLD_MSG_READ32(uint port, uint offset) -{ - int mcr = (0x10<<24) | (port << 16) | (offset << 8); - uint32_t ret_val = 0; - struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0); - pci_write_config_dword (pci_root, 0xD0, mcr); - pci_read_config_dword (pci_root, 0xD4, &ret_val); - pci_dev_put(pci_root); - return ret_val; -} -static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value) -{ - int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0; - struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0); - pci_write_config_dword (pci_root, 0xD4, value); - pci_write_config_dword (pci_root, 0xD0, mcr); - pci_dev_put(pci_root); -} - -static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - int reg_val = ioread32(dev_priv->vdc_reg + (reg)); - PSB_DEBUG_REG("reg = 0x%x. reg_val = 0x%x. \n", reg, reg_val); - return reg_val; -} - -#define REG_READ(reg) REGISTER_READ(dev, (reg)) -static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg, - uint32_t val) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - if ((reg < 0x70084 || reg >0x70088) && (reg < 0xa000 || reg >0xa3ff)) - PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val); - - iowrite32((val), dev_priv->vdc_reg + (reg)); -} - -#define REG_WRITE(reg, val) REGISTER_WRITE(dev, (reg), (val)) - -static inline void REGISTER_WRITE16(struct drm_device *dev, - uint32_t reg, uint32_t val) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val); - - iowrite16((val), dev_priv->vdc_reg + (reg)); -} - -#define REG_WRITE16(reg, val) REGISTER_WRITE16(dev, (reg), (val)) - -static inline void REGISTER_WRITE8(struct drm_device *dev, - uint32_t reg, uint32_t val) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val); - - iowrite8((val), dev_priv->vdc_reg + (reg)); -} - -#define REG_WRITE8(reg, val) REGISTER_WRITE8(dev, (reg), (val)) - -#define PSB_ALIGN_TO(_val, _align) \ - (((_val) + ((_align) - 1)) & ~((_align) - 1)) -#define PSB_WVDC32(_val, _offs) \ - iowrite32(_val, dev_priv->vdc_reg + (_offs)) -#define PSB_RVDC32(_offs) \ - ioread32(dev_priv->vdc_reg + (_offs)) - -/* #define TRAP_SGX_PM_FAULT 1 */ -#ifdef TRAP_SGX_PM_FAULT -#define PSB_RSGX32(_offs) \ -({ \ - if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) { \ - printk(KERN_ERR "access sgx when it's off!! (READ) %s, %d\n", \ - __FILE__, __LINE__); \ - mdelay(1000); \ - } \ - ioread32(dev_priv->sgx_reg + (_offs)); \ -}) -#else -#define PSB_RSGX32(_offs) \ - ioread32(dev_priv->sgx_reg + (_offs)) -#endif -#define PSB_WSGX32(_val, _offs) \ - iowrite32(_val, dev_priv->sgx_reg + (_offs)) - -#define MSVDX_REG_DUMP 0 -#if MSVDX_REG_DUMP - -#define PSB_WMSVDX32(_val, _offs) \ - printk("MSVDX: write %08x to reg 0x%08x\n", (unsigned int)(_val), (unsigned int)(_offs));\ - iowrite32(_val, dev_priv->msvdx_reg + (_offs)) -#define PSB_RMSVDX32(_offs) \ - ioread32(dev_priv->msvdx_reg + (_offs)) - -#else - -#define PSB_WMSVDX32(_val, _offs) \ - iowrite32(_val, dev_priv->msvdx_reg + (_offs)) -#define PSB_RMSVDX32(_offs) \ - ioread32(dev_priv->msvdx_reg + (_offs)) - -#endif - -#define PSB_ALPL(_val, _base) \ - (((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT)) -#define PSB_ALPLM(_val, _base) \ - ((((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT)) & (_base ## _MASK)) - -#endif diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c deleted file mode 100644 index 99c03a2e06b..00000000000 --- a/drivers/staging/gma500/psb_fb.c +++ /dev/null @@ -1,817 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/tty.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/console.h> - -#include <drm/drmP.h> -#include <drm/drm.h> -#include <drm/drm_crtc.h> - -#include "psb_drv.h" -#include "psb_intel_reg.h" -#include "psb_intel_drv.h" -#include "psb_fb.h" - -static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb); -static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int *handle); - -static const struct drm_framebuffer_funcs psb_fb_funcs = { - .destroy = psb_user_framebuffer_destroy, - .create_handle = psb_user_framebuffer_create_handle, -}; - -#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16) - -void *psbfb_vdc_reg(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv; - dev_priv = (struct drm_psb_private *) dev->dev_private; - return dev_priv->vdc_reg; -} -/*EXPORT_SYMBOL(psbfb_vdc_reg); */ - -static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, - struct fb_info *info) -{ - struct psb_fbdev *fbdev = info->par; - struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; - uint32_t v; - - if (!fb) - return -ENOMEM; - - if (regno > 255) - return 1; - - red = CMAP_TOHW(red, info->var.red.length); - blue = CMAP_TOHW(blue, info->var.blue.length); - green = CMAP_TOHW(green, info->var.green.length); - transp = CMAP_TOHW(transp, info->var.transp.length); - - v = (red << info->var.red.offset) | - (green << info->var.green.offset) | - (blue << info->var.blue.offset) | - (transp << info->var.transp.offset); - - if (regno < 16) { - switch (fb->bits_per_pixel) { - case 16: - ((uint32_t *) info->pseudo_palette)[regno] = v; - break; - case 24: - case 32: - ((uint32_t *) info->pseudo_palette)[regno] = v; - break; - } - } - - return 0; -} - -static int psbfb_kms_off(struct drm_device *dev, int suspend) -{ - struct drm_framebuffer *fb = 0; - struct psb_framebuffer *psbfb = to_psb_fb(fb); - DRM_DEBUG("psbfb_kms_off_ioctl\n"); - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(fb, &dev->mode_config.fb_list, head) { - struct fb_info *info = psbfb->fbdev; - - if (suspend) { - fb_set_suspend(info, 1); - drm_fb_helper_blank(FB_BLANK_POWERDOWN, info); - } - } - mutex_unlock(&dev->mode_config.mutex); - return 0; -} - -int psbfb_kms_off_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - int ret; - - if (drm_psb_no_fb) - return 0; - console_lock(); - ret = psbfb_kms_off(dev, 0); - console_unlock(); - - return ret; -} - -static int psbfb_kms_on(struct drm_device *dev, int resume) -{ - struct drm_framebuffer *fb = 0; - struct psb_framebuffer *psbfb = to_psb_fb(fb); - - DRM_DEBUG("psbfb_kms_on_ioctl\n"); - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(fb, &dev->mode_config.fb_list, head) { - struct fb_info *info = psbfb->fbdev; - - if (resume) { - fb_set_suspend(info, 0); - drm_fb_helper_blank(FB_BLANK_UNBLANK, info); - } - } - mutex_unlock(&dev->mode_config.mutex); - - return 0; -} - -int psbfb_kms_on_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - int ret; - - if (drm_psb_no_fb) - return 0; - console_lock(); - ret = psbfb_kms_on(dev, 0); - console_unlock(); - drm_helper_disable_unused_functions(dev); - return ret; -} - -void psbfb_suspend(struct drm_device *dev) -{ - console_lock(); - psbfb_kms_off(dev, 1); - console_unlock(); -} - -void psbfb_resume(struct drm_device *dev) -{ - console_lock(); - psbfb_kms_on(dev, 1); - console_unlock(); - drm_helper_disable_unused_functions(dev); -} - -static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - int page_num = 0; - int i; - unsigned long address = 0; - int ret; - unsigned long pfn; - struct psb_framebuffer *psbfb = vma->vm_private_data; - struct drm_device *dev = psbfb->base.dev; - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long phys_addr = (unsigned long)dev_priv->stolen_base; - - page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; - - address = (unsigned long)vmf->virtual_address; - - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - for (i = 0; i < page_num; i++) { - pfn = (phys_addr >> PAGE_SHIFT); /* phys_to_pfn(phys_addr); */ - - ret = vm_insert_mixed(vma, address, pfn); - if (unlikely((ret == -EBUSY) || (ret != 0 && i > 0))) - break; - else if (unlikely(ret != 0)) { - ret = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS; - return ret; - } - - address += PAGE_SIZE; - phys_addr += PAGE_SIZE; - } - - return VM_FAULT_NOPAGE; -} - -static void psbfb_vm_open(struct vm_area_struct *vma) -{ - DRM_DEBUG("vm_open\n"); -} - -static void psbfb_vm_close(struct vm_area_struct *vma) -{ - DRM_DEBUG("vm_close\n"); -} - -static struct vm_operations_struct psbfb_vm_ops = { - .fault = psbfb_vm_fault, - .open = psbfb_vm_open, - .close = psbfb_vm_close -}; - -static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma) -{ - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = fbdev->pfb; - char *fb_screen_base = NULL; - struct drm_device *dev = psbfb->base.dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (vma->vm_pgoff != 0) - return -EINVAL; - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) - return -EINVAL; - - if (!psbfb->addr_space) - psbfb->addr_space = vma->vm_file->f_mapping; - - fb_screen_base = (char *)info->screen_base; - - DRM_DEBUG("vm_pgoff 0x%lx, screen base %p vram_addr %p\n", - vma->vm_pgoff, fb_screen_base, - dev_priv->vram_addr); - - /* FIXME: ultimately this needs to become 'if entirely stolen memory' */ - if (1 || fb_screen_base == dev_priv->vram_addr) { - vma->vm_ops = &psbfb_vm_ops; - vma->vm_private_data = (void *)psbfb; - vma->vm_flags |= VM_RESERVED | VM_IO | - VM_MIXEDMAP | VM_DONTEXPAND; - } else { - /* GTT memory backed by kernel/user pages, needs a different - approach ? - GEM ? */ - } - - return 0; -} - -static int psbfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) -{ - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = fbdev->pfb; - struct drm_device *dev = psbfb->base.dev; - struct drm_psb_private *dev_priv = dev->dev_private; - u32 __user *p = (u32 __user *)arg; - u32 l; - u32 buf[32]; - switch (cmd) { - case 0x12345678: - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - if (get_user(l, p)) - return -EFAULT; - if (l > 32) - return -EMSGSIZE; - if (copy_from_user(buf, p + 1, l * sizeof(u32))) - return -EFAULT; - psbfb_2d_submit(dev_priv, buf, l); - return 0; - default: - return -ENOTTY; - } -} - -static struct fb_ops psbfb_ops = { - .owner = THIS_MODULE, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, - .fb_blank = drm_fb_helper_blank, - .fb_setcolreg = psbfb_setcolreg, - .fb_fillrect = psbfb_fillrect, - .fb_copyarea = psbfb_copyarea, - .fb_imageblit = psbfb_imageblit, - .fb_mmap = psbfb_mmap, - .fb_sync = psbfb_sync, - .fb_ioctl = psbfb_ioctl, -}; - -static struct drm_framebuffer *psb_framebuffer_create - (struct drm_device *dev, struct drm_mode_fb_cmd *r, - struct gtt_range *gt) -{ - struct psb_framebuffer *fb; - int ret; - - fb = kzalloc(sizeof(*fb), GFP_KERNEL); - if (!fb) - return NULL; - - ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs); - - if (ret) - goto err; - - drm_helper_mode_fill_fb_struct(&fb->base, r); - - fb->gtt = gt; - - return &fb->base; - -err: - kfree(fb); - return NULL; -} - -/** - * psbfb_alloc - allocate frame buffer memory - * @dev: the DRM device - * @aligned_size: space needed - * - * Allocate the frame buffer. In the usual case we get a GTT range that - * is stolen memory backed and life is simple. If there isn't sufficient - * stolen memory or the system has no stolen memory we allocate a range - * and back it with a GEM object. - * - * In this case the GEM object has no handle. - */ -static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size) -{ - struct gtt_range *backing; - /* Begin by trying to use stolen memory backing */ - backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1); - if (backing) - return backing; - /* Next try using GEM host memory */ - backing = psb_gtt_alloc_range(dev, aligned_size, "fb(gem)", 0); - if (backing == NULL) - return NULL; - - /* Now back it with an object */ - if (drm_gem_object_init(dev, &backing->gem, aligned_size) != 0) { - psb_gtt_free_range(dev, backing); - return NULL; - } - return backing; -} - -/** - * psbfb_create - create a framebuffer - * @fbdev: the framebuffer device - * @sizes: specification of the layout - * - * Create a framebuffer to the specifications provided - */ -static int psbfb_create(struct psb_fbdev *fbdev, - struct drm_fb_helper_surface_size *sizes) -{ - struct drm_device *dev = fbdev->psb_fb_helper.dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct fb_info *info; - struct drm_framebuffer *fb; - struct psb_framebuffer *psbfb; - struct drm_mode_fb_cmd mode_cmd; - struct device *device = &dev->pdev->dev; - int size, aligned_size; - int ret; - struct gtt_range *backing; - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - - mode_cmd.bpp = 32; - /* HW requires pitch to be 64 byte aligned */ - mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64); - mode_cmd.depth = 24; - - size = mode_cmd.pitch * mode_cmd.height; - aligned_size = ALIGN(size, PAGE_SIZE); - - /* Allocate the framebuffer in the GTT with stolen page backing */ - backing = psbfb_alloc(dev, aligned_size); - if (backing == NULL) - return -ENOMEM; - - mutex_lock(&dev->struct_mutex); - fb = psb_framebuffer_create(dev, &mode_cmd, backing); - if (!fb) { - DRM_ERROR("failed to allocate fb.\n"); - ret = -ENOMEM; - goto out_err1; - } - psbfb = to_psb_fb(fb); - - info = framebuffer_alloc(sizeof(struct psb_fbdev), device); - if (!info) { - ret = -ENOMEM; - goto out_err0; - } - - info->par = fbdev; - - psbfb->fbdev = info; - - fbdev->psb_fb_helper.fb = fb; - fbdev->psb_fb_helper.fbdev = info; - fbdev->pfb = psbfb; - - strcpy(info->fix.id, "psbfb"); - - info->flags = FBINFO_DEFAULT; - info->fbops = &psbfb_ops; - info->fix.smem_start = dev->mode_config.fb_base; - info->fix.smem_len = size; - - /* Accessed via stolen memory directly, This only works for stolem - memory however. Need to address this once we start using gtt - pages we allocate */ - info->screen_base = (char *)dev_priv->vram_addr + backing->offset; - info->screen_size = size; - memset(info->screen_base, 0, size); - - drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); - drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper, - sizes->fb_width, sizes->fb_height); - - info->fix.mmio_start = pci_resource_start(dev->pdev, 0); - info->fix.mmio_len = pci_resource_len(dev->pdev, 0); - - info->pixmap.size = 64 * 1024; - info->pixmap.buf_align = 8; - info->pixmap.access_align = 32; - info->pixmap.flags = FB_PIXMAP_SYSTEM; - info->pixmap.scan_align = 1; - - DRM_DEBUG("fb depth is %d\n", fb->depth); - DRM_DEBUG(" pitch is %d\n", fb->pitch); - - printk(KERN_INFO"allocated %dx%d fb\n", - psbfb->base.width, psbfb->base.height); - - mutex_unlock(&dev->struct_mutex); - - return 0; -out_err0: - fb->funcs->destroy(fb); -out_err1: - mutex_unlock(&dev->struct_mutex); - psb_gtt_free_range(dev, backing); - return ret; -} - -/** - * psb_user_framebuffer_create - create framebuffer - * @dev: our DRM device - * @filp: client file - * @cmd: mode request - * - * Create a new framebuffer backed by a userspace GEM object - */ -static struct drm_framebuffer *psb_user_framebuffer_create - (struct drm_device *dev, struct drm_file *filp, - struct drm_mode_fb_cmd *cmd) -{ - struct gtt_range *r; - struct drm_gem_object *obj; - struct psb_framebuffer *psbfb; - - /* Find the GEM object and thus the gtt range object that is - to back this space */ - obj = drm_gem_object_lookup(dev, filp, cmd->handle); - if (obj == NULL) - return ERR_PTR(-ENOENT); - - /* Allocate a framebuffer */ - psbfb = kzalloc(sizeof(*psbfb), GFP_KERNEL); - if (psbfb == NULL) { - drm_gem_object_unreference_unlocked(obj); - return ERR_PTR(-ENOMEM); - } - - /* Let the core code do all the work */ - r = container_of(obj, struct gtt_range, gem); - if (psb_framebuffer_create(dev, cmd, r) == NULL) { - drm_gem_object_unreference_unlocked(obj); - kfree(psbfb); - return ERR_PTR(-EINVAL); - } - /* Return the drm_framebuffer contained within the psb fbdev which - has been initialized by the framebuffer creation */ - return &psbfb->base; -} - -static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno) -{ - DRM_DEBUG("%s\n", __func__); -} - -static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red, - u16 *green, u16 *blue, int regno) -{ - DRM_DEBUG("%s\n", __func__); -} - -static int psbfb_probe(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct psb_fbdev *psb_fbdev = (struct psb_fbdev *)helper; - int new_fb = 0; - int ret; - - DRM_DEBUG("%s\n", __func__); - - if (!helper->fb) { - ret = psbfb_create(psb_fbdev, sizes); - if (ret) - return ret; - new_fb = 1; - } - return new_fb; -} - -struct drm_fb_helper_funcs psb_fb_helper_funcs = { - .gamma_set = psbfb_gamma_set, - .gamma_get = psbfb_gamma_get, - .fb_probe = psbfb_probe, -}; - -int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev) -{ - struct fb_info *info; - struct psb_framebuffer *psbfb = fbdev->pfb; - - if (fbdev->psb_fb_helper.fbdev) { - info = fbdev->psb_fb_helper.fbdev; - /* FIXME: this is a bit more inside knowledge than I'd like - but I don't see how to make a fake GEM object of the - stolen space nicely */ - if (psbfb->gtt->stolen) - psb_gtt_free_range(dev, psbfb->gtt); - else - drm_gem_object_unreference(&psbfb->gtt->gem); - unregister_framebuffer(info); - iounmap(info->screen_base); - framebuffer_release(info); - } - - drm_fb_helper_fini(&fbdev->psb_fb_helper); - drm_framebuffer_cleanup(&psbfb->base); - return 0; -} - -int psb_fbdev_init(struct drm_device *dev) -{ - struct psb_fbdev *fbdev; - struct drm_psb_private *dev_priv = dev->dev_private; - int num_crtc; - - fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL); - if (!fbdev) { - DRM_ERROR("no memory\n"); - return -ENOMEM; - } - - dev_priv->fbdev = fbdev; - fbdev->psb_fb_helper.funcs = &psb_fb_helper_funcs; - - num_crtc = 2; - - drm_fb_helper_init(dev, &fbdev->psb_fb_helper, num_crtc, - INTELFB_CONN_LIMIT); - - drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper); - drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32); - return 0; -} - -void psb_fbdev_fini(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - if (!dev_priv->fbdev) - return; - - psb_fbdev_destroy(dev, dev_priv->fbdev); - kfree(dev_priv->fbdev); - dev_priv->fbdev = NULL; -} - -static void psbfb_output_poll_changed(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_fbdev *fbdev = (struct psb_fbdev *)dev_priv->fbdev; - drm_fb_helper_hotplug_event(&fbdev->psb_fb_helper); -} - -int psbfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) -{ - struct fb_info *info; - struct psb_framebuffer *psbfb = to_psb_fb(fb); - - if (drm_psb_no_fb) - return 0; - - info = psbfb->fbdev; - - if (info) - framebuffer_release(info); - return 0; -} -/*EXPORT_SYMBOL(psbfb_remove); */ - -/** - * psb_user_framebuffer_create_handle - add hamdle to a framebuffer - * @fb: framebuffer - * @file_priv: our DRM file - * @handle: returned handle - * - * Our framebuffer object is a GTT range which also contains a GEM - * object. We need to turn it into a handle for userspace. GEM will do - * the work for us - */ -static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int *handle) -{ - struct psb_framebuffer *psbfb = to_psb_fb(fb); - struct gtt_range *r = psbfb->gtt; - if (r->stolen) - return -EOPNOTSUPP; - return drm_gem_handle_create(file_priv, &r->gem, handle); -} - -/** - * psb_user_framebuffer_destroy - destruct user created fb - * @fb: framebuffer - * - * User framebuffers are backed by GEM objects so all we have to do is - * clean up a bit and drop the reference, GEM will handle the fallout - */ -static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb) -{ - struct drm_device *dev = fb->dev; - struct psb_framebuffer *psbfb = to_psb_fb(fb); - struct gtt_range *r = psbfb->gtt; - - if (psbfb->fbdev) - psbfb_remove(dev, fb); - - /* Let DRM do its clean up */ - drm_framebuffer_cleanup(fb); - /* We are no longer using the resource in GEM */ - drm_gem_object_unreference_unlocked(&r->gem); - - kfree(fb); -} - -static const struct drm_mode_config_funcs psb_mode_funcs = { - .fb_create = psb_user_framebuffer_create, - .output_poll_changed = psbfb_output_poll_changed, -}; - -static int psb_create_backlight_property(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv - = (struct drm_psb_private *) dev->dev_private; - struct drm_property *backlight; - - if (dev_priv->backlight_property) - return 0; - - backlight = drm_property_create(dev, - DRM_MODE_PROP_RANGE, - "backlight", - 2); - backlight->values[0] = 0; - backlight->values[1] = 100; - - dev_priv->backlight_property = backlight; - - return 0; -} - -static void psb_setup_outputs(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - struct drm_connector *connector; - - PSB_DEBUG_ENTRY("\n"); - - drm_mode_create_scaling_mode_property(dev); - - psb_create_backlight_property(dev); - - if (IS_MRST(dev)) { - if (dev_priv->iLVDS_enable) - mrst_lvds_init(dev, &dev_priv->mode_dev); - else - DRM_ERROR("DSI is not supported\n"); - } else { - psb_intel_lvds_init(dev, &dev_priv->mode_dev); - psb_intel_sdvo_init(dev, SDVOB); - } - - list_for_each_entry(connector, &dev->mode_config.connector_list, - head) { - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - struct drm_encoder *encoder = &psb_intel_output->enc; - int crtc_mask = 0, clone_mask = 0; - - /* valid crtcs */ - switch (psb_intel_output->type) { - case INTEL_OUTPUT_SDVO: - crtc_mask = ((1 << 0) | (1 << 1)); - clone_mask = (1 << INTEL_OUTPUT_SDVO); - break; - case INTEL_OUTPUT_LVDS: - PSB_DEBUG_ENTRY("LVDS.\n"); - if (IS_MRST(dev)) - crtc_mask = (1 << 0); - else - crtc_mask = (1 << 1); - clone_mask = (1 << INTEL_OUTPUT_LVDS); - break; - case INTEL_OUTPUT_MIPI: - PSB_DEBUG_ENTRY("MIPI.\n"); - crtc_mask = (1 << 0); - clone_mask = (1 << INTEL_OUTPUT_MIPI); - break; - case INTEL_OUTPUT_MIPI2: - PSB_DEBUG_ENTRY("MIPI2.\n"); - crtc_mask = (1 << 2); - clone_mask = (1 << INTEL_OUTPUT_MIPI2); - break; - case INTEL_OUTPUT_HDMI: - PSB_DEBUG_ENTRY("HDMI.\n"); - crtc_mask = (1 << 1); - clone_mask = (1 << INTEL_OUTPUT_HDMI); - break; - } - - encoder->possible_crtcs = crtc_mask; - encoder->possible_clones = - psb_intel_connector_clones(dev, clone_mask); - - } -} - -void psb_modeset_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - int i; - - PSB_DEBUG_ENTRY("\n"); - - drm_mode_config_init(dev); - - dev->mode_config.min_width = 0; - dev->mode_config.min_height = 0; - - dev->mode_config.funcs = (void *) &psb_mode_funcs; - - /* set memory base */ - /* MRST and PSB should use BAR 2*/ - pci_read_config_dword(dev->pdev, PSB_BSM, (u32 *) - &(dev->mode_config.fb_base)); - - /* num pipes is 2 for PSB but 1 for Mrst */ - for (i = 0; i < dev_priv->num_pipe; i++) - psb_intel_crtc_init(dev, i, mode_dev); - - dev->mode_config.max_width = 2048; - dev->mode_config.max_height = 2048; - - psb_setup_outputs(dev); - - /* setup fbs */ - /* drm_initial_config(dev); */ -} - -void psb_modeset_cleanup(struct drm_device *dev) -{ - mutex_lock(&dev->struct_mutex); - - drm_kms_helper_poll_fini(dev); - psb_fbdev_fini(dev); - - drm_mode_config_cleanup(dev); - - mutex_unlock(&dev->struct_mutex); -} diff --git a/drivers/staging/gma500/psb_fb.h b/drivers/staging/gma500/psb_fb.h deleted file mode 100644 index c8ec0d6febb..00000000000 --- a/drivers/staging/gma500/psb_fb.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2008, Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt <eric@anholt.net> - * - */ - -#ifndef _PSB_FB_H_ -#define _PSB_FB_H_ - -#include <linux/version.h> -#include <drm/drmP.h> -#include <drm/drm_fb_helper.h> - -#include "psb_drv.h" - -struct psb_framebuffer { - struct drm_framebuffer base; - struct address_space *addr_space; - struct fb_info *fbdev; - struct gtt_range *gtt; -}; - -struct psb_fbdev { - struct drm_fb_helper psb_fb_helper; - struct psb_framebuffer *pfb; -}; - - -#define to_psb_fb(x) container_of(x, struct psb_framebuffer, base) - -extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask); - -#endif - diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c deleted file mode 100644 index 76ff7bacd35..00000000000 --- a/drivers/staging/gma500/psb_gem.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * psb GEM interface - * - * Copyright (c) 2011, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: Alan Cox - * - * TODO: - * - we don't actually put GEM objects into the GART yet - * - we need to work out if the MMU is relevant as well (eg for - * accelerated operations on a GEM object) - * - cache coherency - * - * ie this is just an initial framework to get us going. - */ - -#include <drm/drmP.h> -#include <drm/drm.h> -#include "psb_drm.h" -#include "psb_drv.h" - -int psb_gem_init_object(struct drm_gem_object *obj) -{ - return -EINVAL; -} - -void psb_gem_free_object(struct drm_gem_object *obj) -{ - struct gtt_range *gtt = container_of(obj, struct gtt_range, gem); - psb_gtt_free_range(obj->dev, gtt); - if (obj->map_list.map) { - /* Do things GEM should do for us */ - struct drm_gem_mm *mm = obj->dev->mm_private; - struct drm_map_list *list = &obj->map_list; - drm_ht_remove_item(&mm->offset_hash, &list->hash); - drm_mm_put_block(list->file_offset_node); - kfree(list->map); - list->map = NULL; - } - drm_gem_object_release(obj); -} - -int psb_gem_get_aperture(struct drm_device *dev, void *data, - struct drm_file *file) -{ - return -EINVAL; -} - -/** - * psb_gem_create_mmap_offset - invent an mmap offset - * @obj: our object - * - * This is basically doing by hand a pile of ugly crap which should - * be done automatically by the GEM library code but isn't - */ -static int psb_gem_create_mmap_offset(struct drm_gem_object *obj) -{ - struct drm_device *dev = obj->dev; - struct drm_gem_mm *mm = dev->mm_private; - struct drm_map_list *list; - struct drm_local_map *map; - int ret; - - list = &obj->map_list; - list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); - if (list->map == NULL) - return -ENOMEM; - map = list->map; - map->type = _DRM_GEM; - map->size = obj->size; - map->handle =obj; - - list->file_offset_node = drm_mm_search_free(&mm->offset_manager, - obj->size / PAGE_SIZE, 0, 0); - if (!list->file_offset_node) { - DRM_ERROR("failed to allocate offset for bo %d\n", obj->name); - ret = -ENOSPC; - goto free_it; - } - list->file_offset_node = drm_mm_get_block(list->file_offset_node, - obj->size / PAGE_SIZE, 0); - if (!list->file_offset_node) { - ret = -ENOMEM; - goto free_it; - } - list->hash.key = list->file_offset_node->start; - ret = drm_ht_insert_item(&mm->offset_hash, &list->hash); - if (ret) { - DRM_ERROR("failed to add to map hash\n"); - goto free_mm; - } - return 0; - -free_mm: - drm_mm_put_block(list->file_offset_node); -free_it: - kfree(list->map); - list->map = NULL; - return ret; -} - -/** - * psb_gem_dumb_map_gtt - buffer mapping for dumb interface - * @file: our drm client file - * @dev: drm device - * @handle: GEM handle to the object (from dumb_create) - * - * Do the necessary setup to allow the mapping of the frame buffer - * into user memory. We don't have to do much here at the moment. - */ -int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, - uint32_t handle, uint64_t *offset) -{ - int ret = 0; - struct drm_gem_object *obj; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - mutex_lock(&dev->struct_mutex); - - /* GEM does all our handle to object mapping */ - obj = drm_gem_object_lookup(dev, file, handle); - if (obj == NULL) { - ret = -ENOENT; - goto unlock; - } - /* What validation is needed here ? */ - - /* Make it mmapable */ - if (!obj->map_list.map) { - ret = psb_gem_create_mmap_offset(obj); - if (ret) - goto out; - } - /* GEM should really work out the hash offsets for us */ - *offset = (u64)obj->map_list.hash.key << PAGE_SHIFT; -out: - drm_gem_object_unreference(obj); -unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -/** - * psb_gem_create - create a mappable object - * @file: the DRM file of the client - * @dev: our device - * @size: the size requested - * @handlep: returned handle (opaque number) - * - * Create a GEM object, fill in the boilerplate and attach a handle to - * it so that userspace can speak about it. This does the core work - * for the various methods that do/will create GEM objects for things - */ -static int psb_gem_create(struct drm_file *file, - struct drm_device *dev, uint64_t size, uint32_t *handlep) -{ - struct gtt_range *r; - int ret; - u32 handle; - - size = roundup(size, PAGE_SIZE); - - /* Allocate our object - for now a direct gtt range which is not - stolen memory backed */ - r = psb_gtt_alloc_range(dev, size, "gem", 0); - if (r == NULL) - return -ENOSPC; - /* Initialize the extra goodies GEM needs to do all the hard work */ - if (drm_gem_object_init(dev, &r->gem, size) != 0) { - psb_gtt_free_range(dev, r); - /* GEM doesn't give an error code and we don't have an - EGEMSUCKS so make something up for now - FIXME */ - return -ENOMEM; - } - /* Give the object a handle so we can carry it more easily */ - ret = drm_gem_handle_create(file, &r->gem, &handle); - if (ret) { - drm_gem_object_release(&r->gem); - psb_gtt_free_range(dev, r); - return ret; - } - /* We have the initial and handle reference but need only one now */ - drm_gem_object_unreference(&r->gem); - *handlep = handle; - return 0; -} - -/** - * psb_gem_dumb_create - create a dumb buffer - * @drm_file: our client file - * @dev: our device - * @args: the requested arguments copied from userspace - * - * Allocate a buffer suitable for use for a frame buffer of the - * form described by user space. Give userspace a handle by which - * to reference it. - */ -int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - args->pitch = ALIGN(args->width * ((args->bpp + 7) / 8), 64); - args->size = args->pitch * args->height; - return psb_gem_create(file, dev, args->size, &args->handle); -} - -/** - * psb_gem_dumb_destroy - destroy a dumb buffer - * @file: client file - * @dev: our DRM device - * @handle: the object handle - * - * Destroy a handle that was created via psb_gem_dumb_create, at least - * we hope it was created that way. i915 seems to assume the caller - * does the checking but that might be worth review ! FIXME - */ -int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, - uint32_t handle) -{ - /* No special work needed, drop the reference and see what falls out */ - return drm_gem_handle_delete(file, handle); -} - -/** - * psb_gem_fault - pagefault handler for GEM objects - * @vma: the VMA of the GEM object - * @vmf: fault detail - * - * Invoked when a fault occurs on an mmap of a GEM managed area. GEM - * does most of the work for us including the actual map/unmap calls - * but we need to do the actual page work. - * - * This code eventually needs to handle faulting objects in and out - * of the GART and repacking it when we run out of space. We can put - * that off for now and for our simple uses - * - * The VMA was set up by GEM. In doing so it also ensured that the - * vma->vm_private_data points to the GEM object that is backing this - * mapping. - * - * To avoid aliasing and cache funnies we want to map the object - * through the GART. For the moment this is slightly hackish. It would - * be nicer if GEM provided mmap opened/closed hooks for us giving - * the object so that we could track things nicely. That needs changes - * to the core GEM code so must be tackled post staging - * - * FIXME - */ -int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_gem_object *obj; - struct gtt_range *r; - int ret; - unsigned long pfn; - pgoff_t page_offset; - struct drm_device *dev; - - obj = vma->vm_private_data; /* GEM object */ - dev = obj->dev; - - r = container_of(obj, struct gtt_range, gem); /* Get the gtt range */ - - /* Make sure we don't parallel update on a fault, nor move or remove - something from beneath our feet */ - mutex_lock(&dev->struct_mutex); - - /* For now the mmap pins the object and it stays pinned. As things - stand that will do us no harm */ - if (r->mmapping == 0) { - ret = psb_gtt_pin(r); - if (ret < 0) { - DRM_ERROR("gma500: pin failed: %d\n", ret); - goto fail; - } - r->mmapping = 1; - } - - /* FIXME: Locking. We may also need to repack the GART sometimes */ - - /* Page relative to the VMA start */ - page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start) - >> PAGE_SHIFT; - - /* Bus address of the page is gart + object offset + page offset */ - /* Assumes gtt allocations are page aligned */ - pfn = (r->resource.start >> PAGE_SHIFT) + page_offset; - - pr_debug("Object GTT base at %p\n", (void *)(r->resource.start)); - pr_debug("Inserting %p pfn %lx, pa %lx\n", vmf->virtual_address, - pfn, pfn << PAGE_SHIFT); - - ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); - -fail: - mutex_unlock(&dev->struct_mutex); - switch (ret) { - case 0: - case -ERESTARTSYS: - case -EINTR: - return VM_FAULT_NOPAGE; - case -ENOMEM: - return VM_FAULT_OOM; - default: - return VM_FAULT_SIGBUS; - } -} diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c deleted file mode 100644 index 74c5a6569d0..00000000000 --- a/drivers/staging/gma500/psb_gtt.c +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Copyright (c) 2007, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com> - * Alan Cox <alan@linux.intel.com> - */ - -#include <drm/drmP.h> -#include "psb_drv.h" - - -/* - * GTT resource allocator - manage page mappings in GTT space - */ - -/** - * psb_gtt_mask_pte - generate GART pte entry - * @pfn: page number to encode - * @type: type of memory in the GART - * - * Set the GART entry for the appropriate memory type. - */ -static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type) -{ - uint32_t mask = PSB_PTE_VALID; - - if (type & PSB_MMU_CACHED_MEMORY) - mask |= PSB_PTE_CACHED; - if (type & PSB_MMU_RO_MEMORY) - mask |= PSB_PTE_RO; - if (type & PSB_MMU_WO_MEMORY) - mask |= PSB_PTE_WO; - - return (pfn << PAGE_SHIFT) | mask; -} - -/** - * psb_gtt_entry - find the GART entries for a gtt_range - * @dev: our DRM device - * @r: our GTT range - * - * Given a gtt_range object return the GART offset of the page table - * entries for this gtt_range - */ -u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long offset; - - offset = r->resource.start - dev_priv->gtt_mem->start; - - return dev_priv->gtt_map + (offset >> PAGE_SHIFT); -} - -/** - * psb_gtt_insert - put an object into the GART - * @dev: our DRM device - * @r: our GTT range - * - * Take our preallocated GTT range and insert the GEM object into - * the GART. - * - * FIXME: gtt lock ? - */ -static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 *gtt_slot, pte; - int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT; - struct page **pages; - int i; - - if (r->pages == NULL) { - WARN_ON(1); - return -EINVAL; - } - - WARN_ON(r->stolen); /* refcount these maybe ? */ - - gtt_slot = psb_gtt_entry(dev, r); - pages = r->pages; - - /* Make sure we have no alias present */ - wbinvd(); - - /* Write our page entries into the GART itself */ - for (i = 0; i < numpages; i++) { - pte = psb_gtt_mask_pte(page_to_pfn(*pages++), 0/*type*/); - iowrite32(pte, gtt_slot++); - } - /* Make sure all the entries are set before we return */ - ioread32(gtt_slot - 1); - - return 0; -} - -/** - * psb_gtt_remove - remove an object from the GART - * @dev: our DRM device - * @r: our GTT range - * - * Remove a preallocated GTT range from the GART. Overwrite all the - * page table entries with the dummy page - */ - -static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 *gtt_slot, pte; - int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT; - int i; - - WARN_ON(r->stolen); - - gtt_slot = psb_gtt_entry(dev, r); - pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);; - - for (i = 0; i < numpages; i++) - iowrite32(pte, gtt_slot++); - ioread32(gtt_slot - 1); -} - -/** - * psb_gtt_attach_pages - attach and pin GEM pages - * @gt: the gtt range - * - * Pin and build an in kernel list of the pages that back our GEM object. - * While we hold this the pages cannot be swapped out - * - * FIXME: Do we need to cache flush when we update the GTT - */ -static int psb_gtt_attach_pages(struct gtt_range *gt) -{ - struct inode *inode; - struct address_space *mapping; - int i; - struct page *p; - int pages = (gt->resource.end + 1 - gt->resource.start) >> PAGE_SHIFT; - - WARN_ON(gt->pages); - - /* This is the shared memory object that backs the GEM resource */ - inode = gt->gem.filp->f_path.dentry->d_inode; - mapping = inode->i_mapping; - - gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL); - if (gt->pages == NULL) - return -ENOMEM; - for (i = 0; i < pages; i++) { - /* FIXME: review flags later */ - p = read_cache_page_gfp(mapping, i, - __GFP_COLD | GFP_KERNEL); - if (IS_ERR(p)) - goto err; - gt->pages[i] = p; - } - return 0; - -err: - while (i--) - page_cache_release(gt->pages[i]); - kfree(gt->pages); - gt->pages = NULL; - return PTR_ERR(p); -} - -/** - * psb_gtt_detach_pages - attach and pin GEM pages - * @gt: the gtt range - * - * Undo the effect of psb_gtt_attach_pages. At this point the pages - * must have been removed from the GART as they could now be paged out - * and move bus address. - * - * FIXME: Do we need to cache flush when we update the GTT - */ -static void psb_gtt_detach_pages(struct gtt_range *gt) -{ - int i; - int pages = (gt->resource.end + 1 - gt->resource.start) >> PAGE_SHIFT; - - for (i = 0; i < pages; i++) { - /* FIXME: do we need to force dirty */ - set_page_dirty(gt->pages[i]); - /* Undo the reference we took when populating the table */ - page_cache_release(gt->pages[i]); - } - kfree(gt->pages); - gt->pages = NULL; -} - -/** - * psb_gtt_pin - pin pages into the GTT - * @gt: range to pin - * - * Pin a set of pages into the GTT. The pins are refcounted so that - * multiple pins need multiple unpins to undo. - * - * Non GEM backed objects treat this as a no-op as they are always GTT - * backed objects. - */ -int psb_gtt_pin(struct gtt_range *gt) -{ - int ret; - struct drm_device *dev = gt->gem.dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - mutex_lock(&dev_priv->gtt_mutex); - - if (gt->in_gart == 0 && gt->stolen == 0) { - ret = psb_gtt_attach_pages(gt); - if (ret < 0) - goto out; - ret = psb_gtt_insert(dev, gt); - if (ret < 0) { - psb_gtt_detach_pages(gt); - goto out; - } - } - gt->in_gart++; -out: - mutex_unlock(&dev_priv->gtt_mutex); - return ret; -} - -/** - * psb_gtt_unpin - Drop a GTT pin requirement - * @gt: range to pin - * - * Undoes the effect of psb_gtt_pin. On the last drop the GEM object - * will be removed from the GTT which will also drop the page references - * and allow the VM to clean up or page stuff. - * - * Non GEM backed objects treat this as a no-op as they are always GTT - * backed objects. - */ -void psb_gtt_unpin(struct gtt_range *gt) -{ - struct drm_device *dev = gt->gem.dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - mutex_lock(&dev_priv->gtt_mutex); - - WARN_ON(!gt->in_gart); - - gt->in_gart--; - if (gt->in_gart == 0 && gt->stolen == 0) { - psb_gtt_remove(dev, gt); - psb_gtt_detach_pages(gt); - } - mutex_unlock(&dev_priv->gtt_mutex); -} - -/* - * GTT resource allocator - allocate and manage GTT address space - */ - -/** - * psb_gtt_alloc_range - allocate GTT address space - * @dev: Our DRM device - * @len: length (bytes) of address space required - * @name: resource name - * @backed: resource should be backed by stolen pages - * - * Ask the kernel core to find us a suitable range of addresses - * to use for a GTT mapping. - * - * Returns a gtt_range structure describing the object, or NULL on - * error. On successful return the resource is both allocated and marked - * as in use. - */ -struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, - const char *name, int backed) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct gtt_range *gt; - struct resource *r = dev_priv->gtt_mem; - int ret; - unsigned long start, end; - - if (backed) { - /* The start of the GTT is the stolen pages */ - start = r->start; - end = r->start + dev_priv->pg->stolen_size - 1; - } else { - /* The rest we will use for GEM backed objects */ - start = r->start + dev_priv->pg->stolen_size; - end = r->end; - } - - gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL); - if (gt == NULL) - return NULL; - gt->resource.name = name; - gt->stolen = backed; - gt->in_gart = backed; - /* Ensure this is set for non GEM objects */ - gt->gem.dev = dev; - kref_init(>->kref); - - ret = allocate_resource(dev_priv->gtt_mem, >->resource, - len, start, end, PAGE_SIZE, NULL, NULL); - if (ret == 0) { - gt->offset = gt->resource.start - r->start; - return gt; - } - kfree(gt); - return NULL; -} - -/** - * psb_gtt_destroy - final free up of a gtt - * @kref: the kref of the gtt - * - * Called from the kernel kref put when the final reference to our - * GTT object is dropped. At that point we can free up the resources. - * - * For now we handle mmap clean up here to work around limits in GEM - */ -static void psb_gtt_destroy(struct kref *kref) -{ - struct gtt_range *gt = container_of(kref, struct gtt_range, kref); - - /* Undo the mmap pin if we are destroying the object */ - if (gt->mmapping) { - psb_gtt_unpin(gt); - gt->mmapping = 0; - } - WARN_ON(gt->in_gart && !gt->stolen); - release_resource(>->resource); - kfree(gt); -} - -/** - * psb_gtt_kref_put - drop reference to a GTT object - * @gt: the GT being dropped - * - * Drop a reference to a psb gtt - */ -void psb_gtt_kref_put(struct gtt_range *gt) -{ - kref_put(>->kref, psb_gtt_destroy); -} - -/** - * psb_gtt_free_range - release GTT address space - * @dev: our DRM device - * @gt: a mapping created with psb_gtt_alloc_range - * - * Release a resource that was allocated with psb_gtt_alloc_range - */ -void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt) -{ - psb_gtt_kref_put(gt); -} - - -struct psb_gtt *psb_gtt_alloc(struct drm_device *dev) -{ - struct psb_gtt *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); - - if (!tmp) - return NULL; - - init_rwsem(&tmp->sem); - tmp->dev = dev; - - return tmp; -} - -void psb_gtt_takedown(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - /* FIXME: iounmap dev_priv->vram_addr etc */ - if (dev_priv->gtt_map) { - iounmap(dev_priv->gtt_map); - dev_priv->gtt_map = NULL; - } - if (dev_priv->gtt_initialized) { - pci_write_config_word(dev->pdev, PSB_GMCH_CTRL, - dev_priv->gmch_ctrl); - PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL); - (void) PSB_RVDC32(PSB_PGETBL_CTL); - } - kfree(dev_priv->pg); - dev_priv->pg = NULL; -} - -int psb_gtt_init(struct drm_device *dev, int resume) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned gtt_pages; - unsigned long stolen_size, vram_stolen_size; - unsigned i, num_pages; - unsigned pfn_base; - uint32_t vram_pages; - uint32_t tt_pages; - uint32_t *ttm_gtt_map; - uint32_t dvmt_mode = 0; - struct psb_gtt *pg; - - int ret = 0; - uint32_t pte; - - mutex_init(&dev_priv->gtt_mutex); - - dev_priv->pg = pg = psb_gtt_alloc(dev); - if (pg == NULL) - return -ENOMEM; - - pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl); - pci_write_config_word(dev->pdev, PSB_GMCH_CTRL, - dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED); - - dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL); - PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL); - (void) PSB_RVDC32(PSB_PGETBL_CTL); - - /* The root resource we allocate address space from */ - dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE]; - - dev_priv->gtt_initialized = 1; - - pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK; - - pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE); - /* fix me: video mmu has hw bug to access 0x0D0000000, - * then make gatt start at 0x0e000,0000 */ - pg->mmu_gatt_start = 0xE0000000; - pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); - gtt_pages = - pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT; - pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE) - >> PAGE_SHIFT; - - pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base); - vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE; - - stolen_size = vram_stolen_size; - - printk(KERN_INFO"GMMADR(region 0) start: 0x%08x (%dM).\n", - pg->gatt_start, pg->gatt_pages/256); - printk(KERN_INFO"GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n", - pg->gtt_start, gtt_pages * 4, pg->gtt_phys_start); - printk(KERN_INFO "Stolen memory information\n"); - printk(KERN_INFO " base in RAM: 0x%x\n", dev_priv->stolen_base); - printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n", - vram_stolen_size/1024); - dvmt_mode = (dev_priv->gmch_ctrl >> 4) & 0x7; - printk(KERN_INFO " the correct size should be: %dM(dvmt mode=%d)\n", - (dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode); - - if (resume && (gtt_pages != pg->gtt_pages) && - (stolen_size != pg->stolen_size)) { - DRM_ERROR("GTT resume error.\n"); - ret = -EINVAL; - goto out_err; - } - - pg->gtt_pages = gtt_pages; - pg->stolen_size = stolen_size; - dev_priv->vram_stolen_size = vram_stolen_size; - dev_priv->gtt_map = - ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT); - if (!dev_priv->gtt_map) { - DRM_ERROR("Failure to map gtt.\n"); - ret = -ENOMEM; - goto out_err; - } - - dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size); - if (!dev_priv->vram_addr) { - DRM_ERROR("Failure to map stolen base.\n"); - ret = -ENOMEM; - goto out_err; - } - - DRM_DEBUG("%s: vram kernel virtual address %p\n", dev_priv->vram_addr); - - tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? - (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT; - - ttm_gtt_map = dev_priv->gtt_map + tt_pages / 2; - - /* - * insert vram stolen pages. - */ - - pfn_base = dev_priv->stolen_base >> PAGE_SHIFT; - vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT; - printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n", - num_pages, pfn_base, 0); - for (i = 0; i < num_pages; ++i) { - pte = psb_gtt_mask_pte(pfn_base + i, 0); - iowrite32(pte, dev_priv->gtt_map + i); - } - - /* - * Init rest of gtt managed by IMG. - */ - pfn_base = page_to_pfn(dev_priv->scratch_page); - pte = psb_gtt_mask_pte(pfn_base, 0); - for (; i < tt_pages / 2 - 1; ++i) - iowrite32(pte, dev_priv->gtt_map + i); - - /* - * Init rest of gtt managed by TTM. - */ - - pfn_base = page_to_pfn(dev_priv->scratch_page); - pte = psb_gtt_mask_pte(pfn_base, 0); - PSB_DEBUG_INIT("Initializing the rest of a total " - "of %d gtt pages.\n", pg->gatt_pages); - - for (; i < pg->gatt_pages - tt_pages / 2; ++i) - iowrite32(pte, ttm_gtt_map + i); - (void) ioread32(dev_priv->gtt_map + i - 1); - - return 0; - -out_err: - psb_gtt_takedown(dev); - return ret; -} diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/psb_gtt.h deleted file mode 100644 index 535ae00f2ab..00000000000 --- a/drivers/staging/gma500/psb_gtt.h +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007-2008, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#ifndef _PSB_GTT_H_ -#define _PSB_GTT_H_ - -#include <drm/drmP.h> - -struct psb_gtt { - struct drm_device *dev; - uint32_t gatt_start; - uint32_t mmu_gatt_start; - uint32_t gtt_start; - uint32_t gtt_phys_start; - unsigned gtt_pages; - unsigned gatt_pages; - unsigned long stolen_size; - unsigned long vram_stolen_size; - struct rw_semaphore sem; -}; - -/*Exported functions*/ -extern int psb_gtt_init(struct drm_device *dev, int resume); -extern void psb_gtt_takedown(struct drm_device *dev); - -/* Each gtt_range describes an allocation in the GTT area */ -struct gtt_range { - struct resource resource; - u32 offset; - struct kref kref; - struct drm_gem_object gem; /* GEM high level stuff */ - int in_gart; /* Currently in the GART (ref ct) */ - bool stolen; /* Backed from stolen RAM */ - bool mmapping; /* Is mmappable */ - struct page **pages; /* Backing pages if present */ -}; - -extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, - const char *name, int backed); -extern void psb_gtt_kref_put(struct gtt_range *gt); -extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt); -extern int psb_gtt_pin(struct gtt_range *gt); -extern void psb_gtt_unpin(struct gtt_range *gt); - -#endif diff --git a/drivers/staging/gma500/psb_intel_bios.c b/drivers/staging/gma500/psb_intel_bios.c deleted file mode 100644 index 48ac8ba7f40..00000000000 --- a/drivers/staging/gma500/psb_intel_bios.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (c) 2006 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt <eric@anholt.net> - * - */ -#include <drm/drmP.h> -#include <drm/drm.h> -#include "psb_drm.h" -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "psb_intel_bios.h" - - -static void *find_section(struct bdb_header *bdb, int section_id) -{ - u8 *base = (u8 *)bdb; - int index = 0; - u16 total, current_size; - u8 current_id; - - /* skip to first section */ - index += bdb->header_size; - total = bdb->bdb_size; - - /* walk the sections looking for section_id */ - while (index < total) { - current_id = *(base + index); - index++; - current_size = *((u16 *)(base + index)); - index += 2; - if (current_id == section_id) - return base + index; - index += current_size; - } - - return NULL; -} - -static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, - struct lvds_dvo_timing *dvo_timing) -{ - panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) | - dvo_timing->hactive_lo; - panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay + - ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo); - panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start + - dvo_timing->hsync_pulse_width; - panel_fixed_mode->htotal = panel_fixed_mode->hdisplay + - ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo); - - panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) | - dvo_timing->vactive_lo; - panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay + - dvo_timing->vsync_off; - panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start + - dvo_timing->vsync_pulse_width; - panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay + - ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo); - panel_fixed_mode->clock = dvo_timing->clock * 10; - panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; - - /* Some VBTs have bogus h/vtotal values */ - if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) - panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; - if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal) - panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1; - - drm_mode_set_name(panel_fixed_mode); -} - -static void parse_backlight_data(struct drm_psb_private *dev_priv, - struct bdb_header *bdb) -{ - struct bdb_lvds_backlight *vbt_lvds_bl = NULL; - struct bdb_lvds_backlight *lvds_bl; - u8 p_type = 0; - void *bl_start = NULL; - struct bdb_lvds_options *lvds_opts - = find_section(bdb, BDB_LVDS_OPTIONS); - - dev_priv->lvds_bl = NULL; - - if (lvds_opts) { - DRM_DEBUG("lvds_options found at %p\n", lvds_opts); - p_type = lvds_opts->panel_type; - } else { - DRM_DEBUG("no lvds_options\n"); - return; - } - - bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT); - vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type; - - lvds_bl = kzalloc(sizeof(*vbt_lvds_bl), GFP_KERNEL); - if (!lvds_bl) { - DRM_DEBUG("No memory\n"); - return; - } - - memcpy(lvds_bl, vbt_lvds_bl, sizeof(*vbt_lvds_bl)); - - dev_priv->lvds_bl = lvds_bl; -} - -/* Try to find integrated panel data */ -static void parse_lfp_panel_data(struct drm_psb_private *dev_priv, - struct bdb_header *bdb) -{ - struct bdb_lvds_options *lvds_options; - struct bdb_lvds_lfp_data *lvds_lfp_data; - struct bdb_lvds_lfp_data_entry *entry; - struct lvds_dvo_timing *dvo_timing; - struct drm_display_mode *panel_fixed_mode; - - /* Defaults if we can't find VBT info */ - dev_priv->lvds_dither = 0; - dev_priv->lvds_vbt = 0; - - lvds_options = find_section(bdb, BDB_LVDS_OPTIONS); - if (!lvds_options) - return; - - dev_priv->lvds_dither = lvds_options->pixel_dither; - if (lvds_options->panel_type == 0xff) - return; - - lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA); - if (!lvds_lfp_data) - return; - - dev_priv->lvds_vbt = 1; - - entry = &lvds_lfp_data->data[lvds_options->panel_type]; - dvo_timing = &entry->dvo_timing; - - panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), - GFP_KERNEL); - - fill_detail_timing_data(panel_fixed_mode, dvo_timing); - - dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode; - - DRM_DEBUG("Found panel mode in BIOS VBT tables:\n"); - drm_mode_debug_printmodeline(panel_fixed_mode); - - return; -} - -/* Try to find sdvo panel data */ -static void parse_sdvo_panel_data(struct drm_psb_private *dev_priv, - struct bdb_header *bdb) -{ - struct bdb_sdvo_lvds_options *sdvo_lvds_options; - struct lvds_dvo_timing *dvo_timing; - struct drm_display_mode *panel_fixed_mode; - - dev_priv->sdvo_lvds_vbt_mode = NULL; - - sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS); - if (!sdvo_lvds_options) - return; - - dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS); - if (!dvo_timing) - return; - - panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); - - if (!panel_fixed_mode) - return; - - fill_detail_timing_data(panel_fixed_mode, - dvo_timing + sdvo_lvds_options->panel_type); - - dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode; - - return; -} - -static void parse_general_features(struct drm_psb_private *dev_priv, - struct bdb_header *bdb) -{ - struct bdb_general_features *general; - - /* Set sensible defaults in case we can't find the general block */ - dev_priv->int_tv_support = 1; - dev_priv->int_crt_support = 1; - - general = find_section(bdb, BDB_GENERAL_FEATURES); - if (general) { - dev_priv->int_tv_support = general->int_tv_support; - dev_priv->int_crt_support = general->int_crt_support; - dev_priv->lvds_use_ssc = general->enable_ssc; - - if (dev_priv->lvds_use_ssc) { - dev_priv->lvds_ssc_freq - = general->ssc_freq ? 100 : 96; - } - } -} - -/** - * psb_intel_init_bios - initialize VBIOS settings & find VBT - * @dev: DRM device - * - * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers - * to appropriate values. - * - * VBT existence is a sanity check that is relied on by other i830_bios.c code. - * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may - * feed an updated VBT back through that, compared to what we'll fetch using - * this method of groping around in the BIOS data. - * - * Returns 0 on success, nonzero on failure. - */ -bool psb_intel_init_bios(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct pci_dev *pdev = dev->pdev; - struct vbt_header *vbt = NULL; - struct bdb_header *bdb; - u8 __iomem *bios; - size_t size; - int i; - - bios = pci_map_rom(pdev, &size); - if (!bios) - return -1; - - /* Scour memory looking for the VBT signature */ - for (i = 0; i + 4 < size; i++) { - if (!memcmp(bios + i, "$VBT", 4)) { - vbt = (struct vbt_header *)(bios + i); - break; - } - } - - if (!vbt) { - DRM_ERROR("VBT signature missing\n"); - pci_unmap_rom(pdev, bios); - return -1; - } - - bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); - - /* Grab useful general definitions */ - parse_general_features(dev_priv, bdb); - parse_lfp_panel_data(dev_priv, bdb); - parse_sdvo_panel_data(dev_priv, bdb); - parse_backlight_data(dev_priv, bdb); - - pci_unmap_rom(pdev, bios); - - return 0; -} - -/** - * Destroy and free VBT data - */ -void psb_intel_destroy_bios(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_display_mode *sdvo_lvds_vbt_mode = - dev_priv->sdvo_lvds_vbt_mode; - struct drm_display_mode *lfp_lvds_vbt_mode = - dev_priv->lfp_lvds_vbt_mode; - struct bdb_lvds_backlight *lvds_bl = - dev_priv->lvds_bl; - - /*free sdvo panel mode*/ - if (sdvo_lvds_vbt_mode) { - dev_priv->sdvo_lvds_vbt_mode = NULL; - kfree(sdvo_lvds_vbt_mode); - } - - if (lfp_lvds_vbt_mode) { - dev_priv->lfp_lvds_vbt_mode = NULL; - kfree(lfp_lvds_vbt_mode); - } - - if (lvds_bl) { - dev_priv->lvds_bl = NULL; - kfree(lvds_bl); - } -} diff --git a/drivers/staging/gma500/psb_intel_bios.h b/drivers/staging/gma500/psb_intel_bios.h deleted file mode 100644 index 70f1bf01818..00000000000 --- a/drivers/staging/gma500/psb_intel_bios.h +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Copyright (c) 2006 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt <eric@anholt.net> - * - */ - -#ifndef _I830_BIOS_H_ -#define _I830_BIOS_H_ - -#include <drm/drmP.h> - -struct vbt_header { - u8 signature[20]; /**< Always starts with 'VBT$' */ - u16 version; /**< decimal */ - u16 header_size; /**< in bytes */ - u16 vbt_size; /**< in bytes */ - u8 vbt_checksum; - u8 reserved0; - u32 bdb_offset; /**< from beginning of VBT */ - u32 aim_offset[4]; /**< from beginning of VBT */ -} __attribute__((packed)); - - -struct bdb_header { - u8 signature[16]; /**< Always 'BIOS_DATA_BLOCK' */ - u16 version; /**< decimal */ - u16 header_size; /**< in bytes */ - u16 bdb_size; /**< in bytes */ -}; - -/* strictly speaking, this is a "skip" block, but it has interesting info */ -struct vbios_data { - u8 type; /* 0 == desktop, 1 == mobile */ - u8 relstage; - u8 chipset; - u8 lvds_present:1; - u8 tv_present:1; - u8 rsvd2:6; /* finish byte */ - u8 rsvd3[4]; - u8 signon[155]; - u8 copyright[61]; - u16 code_segment; - u8 dos_boot_mode; - u8 bandwidth_percent; - u8 rsvd4; /* popup memory size */ - u8 resize_pci_bios; - u8 rsvd5; /* is crt already on ddc2 */ -} __attribute__((packed)); - -/* - * There are several types of BIOS data blocks (BDBs), each block has - * an ID and size in the first 3 bytes (ID in first, size in next 2). - * Known types are listed below. - */ -#define BDB_GENERAL_FEATURES 1 -#define BDB_GENERAL_DEFINITIONS 2 -#define BDB_OLD_TOGGLE_LIST 3 -#define BDB_MODE_SUPPORT_LIST 4 -#define BDB_GENERIC_MODE_TABLE 5 -#define BDB_EXT_MMIO_REGS 6 -#define BDB_SWF_IO 7 -#define BDB_SWF_MMIO 8 -#define BDB_DOT_CLOCK_TABLE 9 -#define BDB_MODE_REMOVAL_TABLE 10 -#define BDB_CHILD_DEVICE_TABLE 11 -#define BDB_DRIVER_FEATURES 12 -#define BDB_DRIVER_PERSISTENCE 13 -#define BDB_EXT_TABLE_PTRS 14 -#define BDB_DOT_CLOCK_OVERRIDE 15 -#define BDB_DISPLAY_SELECT 16 -/* 17 rsvd */ -#define BDB_DRIVER_ROTATION 18 -#define BDB_DISPLAY_REMOVE 19 -#define BDB_OEM_CUSTOM 20 -#define BDB_EFP_LIST 21 /* workarounds for VGA hsync/vsync */ -#define BDB_SDVO_LVDS_OPTIONS 22 -#define BDB_SDVO_PANEL_DTDS 23 -#define BDB_SDVO_LVDS_PNP_IDS 24 -#define BDB_SDVO_LVDS_POWER_SEQ 25 -#define BDB_TV_OPTIONS 26 -#define BDB_LVDS_OPTIONS 40 -#define BDB_LVDS_LFP_DATA_PTRS 41 -#define BDB_LVDS_LFP_DATA 42 -#define BDB_LVDS_BACKLIGHT 43 -#define BDB_LVDS_POWER 44 -#define BDB_SKIP 254 /* VBIOS private block, ignore */ - -struct bdb_general_features { - /* bits 1 */ - u8 panel_fitting:2; - u8 flexaim:1; - u8 msg_enable:1; - u8 clear_screen:3; - u8 color_flip:1; - - /* bits 2 */ - u8 download_ext_vbt:1; - u8 enable_ssc:1; - u8 ssc_freq:1; - u8 enable_lfp_on_override:1; - u8 disable_ssc_ddt:1; - u8 rsvd8:3; /* finish byte */ - - /* bits 3 */ - u8 disable_smooth_vision:1; - u8 single_dvi:1; - u8 rsvd9:6; /* finish byte */ - - /* bits 4 */ - u8 legacy_monitor_detect; - - /* bits 5 */ - u8 int_crt_support:1; - u8 int_tv_support:1; - u8 rsvd11:6; /* finish byte */ -} __attribute__((packed)); - -struct bdb_general_definitions { - /* DDC GPIO */ - u8 crt_ddc_gmbus_pin; - - /* DPMS bits */ - u8 dpms_acpi:1; - u8 skip_boot_crt_detect:1; - u8 dpms_aim:1; - u8 rsvd1:5; /* finish byte */ - - /* boot device bits */ - u8 boot_display[2]; - u8 child_dev_size; - - /* device info */ - u8 tv_or_lvds_info[33]; - u8 dev1[33]; - u8 dev2[33]; - u8 dev3[33]; - u8 dev4[33]; - /* may be another device block here on some platforms */ -}; - -struct bdb_lvds_options { - u8 panel_type; - u8 rsvd1; - /* LVDS capabilities, stored in a dword */ - u8 pfit_mode:2; - u8 pfit_text_mode_enhanced:1; - u8 pfit_gfx_mode_enhanced:1; - u8 pfit_ratio_auto:1; - u8 pixel_dither:1; - u8 lvds_edid:1; - u8 rsvd2:1; - u8 rsvd4; -} __attribute__((packed)); - -struct bdb_lvds_backlight { - u8 type:2; - u8 pol:1; - u8 gpio:3; - u8 gmbus:2; - u16 freq; - u8 minbrightness; - u8 i2caddr; - u8 brightnesscmd; - /*FIXME: more...*/ -} __attribute__((packed)); - -/* LFP pointer table contains entries to the struct below */ -struct bdb_lvds_lfp_data_ptr { - u16 fp_timing_offset; /* offsets are from start of bdb */ - u8 fp_table_size; - u16 dvo_timing_offset; - u8 dvo_table_size; - u16 panel_pnp_id_offset; - u8 pnp_table_size; -} __attribute__((packed)); - -struct bdb_lvds_lfp_data_ptrs { - u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */ - struct bdb_lvds_lfp_data_ptr ptr[16]; -} __attribute__((packed)); - -/* LFP data has 3 blocks per entry */ -struct lvds_fp_timing { - u16 x_res; - u16 y_res; - u32 lvds_reg; - u32 lvds_reg_val; - u32 pp_on_reg; - u32 pp_on_reg_val; - u32 pp_off_reg; - u32 pp_off_reg_val; - u32 pp_cycle_reg; - u32 pp_cycle_reg_val; - u32 pfit_reg; - u32 pfit_reg_val; - u16 terminator; -} __attribute__((packed)); - -struct lvds_dvo_timing { - u16 clock; /**< In 10khz */ - u8 hactive_lo; - u8 hblank_lo; - u8 hblank_hi:4; - u8 hactive_hi:4; - u8 vactive_lo; - u8 vblank_lo; - u8 vblank_hi:4; - u8 vactive_hi:4; - u8 hsync_off_lo; - u8 hsync_pulse_width; - u8 vsync_pulse_width:4; - u8 vsync_off:4; - u8 rsvd0:6; - u8 hsync_off_hi:2; - u8 h_image; - u8 v_image; - u8 max_hv; - u8 h_border; - u8 v_border; - u8 rsvd1:3; - u8 digital:2; - u8 vsync_positive:1; - u8 hsync_positive:1; - u8 rsvd2:1; -} __attribute__((packed)); - -struct lvds_pnp_id { - u16 mfg_name; - u16 product_code; - u32 serial; - u8 mfg_week; - u8 mfg_year; -} __attribute__((packed)); - -struct bdb_lvds_lfp_data_entry { - struct lvds_fp_timing fp_timing; - struct lvds_dvo_timing dvo_timing; - struct lvds_pnp_id pnp_id; -} __attribute__((packed)); - -struct bdb_lvds_lfp_data { - struct bdb_lvds_lfp_data_entry data[16]; -} __attribute__((packed)); - -struct aimdb_header { - char signature[16]; - char oem_device[20]; - u16 aimdb_version; - u16 aimdb_header_size; - u16 aimdb_size; -} __attribute__((packed)); - -struct aimdb_block { - u8 aimdb_id; - u16 aimdb_size; -} __attribute__((packed)); - -struct vch_panel_data { - u16 fp_timing_offset; - u8 fp_timing_size; - u16 dvo_timing_offset; - u8 dvo_timing_size; - u16 text_fitting_offset; - u8 text_fitting_size; - u16 graphics_fitting_offset; - u8 graphics_fitting_size; -} __attribute__((packed)); - -struct vch_bdb_22 { - struct aimdb_block aimdb_block; - struct vch_panel_data panels[16]; -} __attribute__((packed)); - -struct bdb_sdvo_lvds_options { - u8 panel_backlight; - u8 h40_set_panel_type; - u8 panel_type; - u8 ssc_clk_freq; - u16 als_low_trip; - u16 als_high_trip; - u8 sclalarcoeff_tab_row_num; - u8 sclalarcoeff_tab_row_size; - u8 coefficient[8]; - u8 panel_misc_bits_1; - u8 panel_misc_bits_2; - u8 panel_misc_bits_3; - u8 panel_misc_bits_4; -} __attribute__((packed)); - - -extern bool psb_intel_init_bios(struct drm_device *dev); -extern void psb_intel_destroy_bios(struct drm_device *dev); - -/* - * Driver<->VBIOS interaction occurs through scratch bits in - * GR18 & SWF*. - */ - -/* GR18 bits are set on display switch and hotkey events */ -#define GR18_DRIVER_SWITCH_EN (1<<7) /* 0: VBIOS control, 1: driver control */ -#define GR18_HOTKEY_MASK 0x78 /* See also SWF4 15:0 */ -#define GR18_HK_NONE (0x0<<3) -#define GR18_HK_LFP_STRETCH (0x1<<3) -#define GR18_HK_TOGGLE_DISP (0x2<<3) -#define GR18_HK_DISP_SWITCH (0x4<<3) /* see SWF14 15:0 for what to enable */ -#define GR18_HK_POPUP_DISABLED (0x6<<3) -#define GR18_HK_POPUP_ENABLED (0x7<<3) -#define GR18_HK_PFIT (0x8<<3) -#define GR18_HK_APM_CHANGE (0xa<<3) -#define GR18_HK_MULTIPLE (0xc<<3) -#define GR18_USER_INT_EN (1<<2) -#define GR18_A0000_FLUSH_EN (1<<1) -#define GR18_SMM_EN (1<<0) - -/* Set by driver, cleared by VBIOS */ -#define SWF00_YRES_SHIFT 16 -#define SWF00_XRES_SHIFT 0 -#define SWF00_RES_MASK 0xffff - -/* Set by VBIOS at boot time and driver at runtime */ -#define SWF01_TV2_FORMAT_SHIFT 8 -#define SWF01_TV1_FORMAT_SHIFT 0 -#define SWF01_TV_FORMAT_MASK 0xffff - -#define SWF10_VBIOS_BLC_I2C_EN (1<<29) -#define SWF10_GTT_OVERRIDE_EN (1<<28) -#define SWF10_LFP_DPMS_OVR (1<<27) /* override DPMS on display switch */ -#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24) -#define SWF10_OLD_TOGGLE 0x0 -#define SWF10_TOGGLE_LIST_1 0x1 -#define SWF10_TOGGLE_LIST_2 0x2 -#define SWF10_TOGGLE_LIST_3 0x3 -#define SWF10_TOGGLE_LIST_4 0x4 -#define SWF10_PANNING_EN (1<<23) -#define SWF10_DRIVER_LOADED (1<<22) -#define SWF10_EXTENDED_DESKTOP (1<<21) -#define SWF10_EXCLUSIVE_MODE (1<<20) -#define SWF10_OVERLAY_EN (1<<19) -#define SWF10_PLANEB_HOLDOFF (1<<18) -#define SWF10_PLANEA_HOLDOFF (1<<17) -#define SWF10_VGA_HOLDOFF (1<<16) -#define SWF10_ACTIVE_DISP_MASK 0xffff -#define SWF10_PIPEB_LFP2 (1<<15) -#define SWF10_PIPEB_EFP2 (1<<14) -#define SWF10_PIPEB_TV2 (1<<13) -#define SWF10_PIPEB_CRT2 (1<<12) -#define SWF10_PIPEB_LFP (1<<11) -#define SWF10_PIPEB_EFP (1<<10) -#define SWF10_PIPEB_TV (1<<9) -#define SWF10_PIPEB_CRT (1<<8) -#define SWF10_PIPEA_LFP2 (1<<7) -#define SWF10_PIPEA_EFP2 (1<<6) -#define SWF10_PIPEA_TV2 (1<<5) -#define SWF10_PIPEA_CRT2 (1<<4) -#define SWF10_PIPEA_LFP (1<<3) -#define SWF10_PIPEA_EFP (1<<2) -#define SWF10_PIPEA_TV (1<<1) -#define SWF10_PIPEA_CRT (1<<0) - -#define SWF11_MEMORY_SIZE_SHIFT 16 -#define SWF11_SV_TEST_EN (1<<15) -#define SWF11_IS_AGP (1<<14) -#define SWF11_DISPLAY_HOLDOFF (1<<13) -#define SWF11_DPMS_REDUCED (1<<12) -#define SWF11_IS_VBE_MODE (1<<11) -#define SWF11_PIPEB_ACCESS (1<<10) /* 0 here means pipe a */ -#define SWF11_DPMS_MASK 0x07 -#define SWF11_DPMS_OFF (1<<2) -#define SWF11_DPMS_SUSPEND (1<<1) -#define SWF11_DPMS_STANDBY (1<<0) -#define SWF11_DPMS_ON 0 - -#define SWF14_GFX_PFIT_EN (1<<31) -#define SWF14_TEXT_PFIT_EN (1<<30) -#define SWF14_LID_STATUS_CLOSED (1<<29) /* 0 here means open */ -#define SWF14_POPUP_EN (1<<28) -#define SWF14_DISPLAY_HOLDOFF (1<<27) -#define SWF14_DISP_DETECT_EN (1<<26) -#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */ -#define SWF14_DRIVER_STATUS (1<<24) -#define SWF14_OS_TYPE_WIN9X (1<<23) -#define SWF14_OS_TYPE_WINNT (1<<22) -/* 21:19 rsvd */ -#define SWF14_PM_TYPE_MASK 0x00070000 -#define SWF14_PM_ACPI_VIDEO (0x4 << 16) -#define SWF14_PM_ACPI (0x3 << 16) -#define SWF14_PM_APM_12 (0x2 << 16) -#define SWF14_PM_APM_11 (0x1 << 16) -#define SWF14_HK_REQUEST_MASK 0x0000ffff /* see GR18 6:3 for event type */ - /* if GR18 indicates a display switch */ -#define SWF14_DS_PIPEB_LFP2_EN (1<<15) -#define SWF14_DS_PIPEB_EFP2_EN (1<<14) -#define SWF14_DS_PIPEB_TV2_EN (1<<13) -#define SWF14_DS_PIPEB_CRT2_EN (1<<12) -#define SWF14_DS_PIPEB_LFP_EN (1<<11) -#define SWF14_DS_PIPEB_EFP_EN (1<<10) -#define SWF14_DS_PIPEB_TV_EN (1<<9) -#define SWF14_DS_PIPEB_CRT_EN (1<<8) -#define SWF14_DS_PIPEA_LFP2_EN (1<<7) -#define SWF14_DS_PIPEA_EFP2_EN (1<<6) -#define SWF14_DS_PIPEA_TV2_EN (1<<5) -#define SWF14_DS_PIPEA_CRT2_EN (1<<4) -#define SWF14_DS_PIPEA_LFP_EN (1<<3) -#define SWF14_DS_PIPEA_EFP_EN (1<<2) -#define SWF14_DS_PIPEA_TV_EN (1<<1) -#define SWF14_DS_PIPEA_CRT_EN (1<<0) - /* if GR18 indicates a panel fitting request */ -#define SWF14_PFIT_EN (1<<0) /* 0 means disable */ - /* if GR18 indicates an APM change request */ -#define SWF14_APM_HIBERNATE 0x4 -#define SWF14_APM_SUSPEND 0x3 -#define SWF14_APM_STANDBY 0x1 -#define SWF14_APM_RESTORE 0x0 - -#endif /* _I830_BIOS_H_ */ diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c deleted file mode 100644 index 4f47d09d65d..00000000000 --- a/drivers/staging/gma500/psb_intel_display.c +++ /dev/null @@ -1,1492 +0,0 @@ -/* - * Copyright © 2006-2007 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt <eric@anholt.net> - */ - -#include <linux/i2c.h> -#include <linux/pm_runtime.h> - -#include <drm/drmP.h> -#include "psb_fb.h" -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "psb_intel_display.h" -#include "psb_powermgmt.h" - - -struct psb_intel_clock_t { - /* given values */ - int n; - int m1, m2; - int p1, p2; - /* derived values */ - int dot; - int vco; - int m; - int p; -}; - -struct psb_intel_range_t { - int min, max; -}; - -struct psb_intel_p2_t { - int dot_limit; - int p2_slow, p2_fast; -}; - -#define INTEL_P2_NUM 2 - -struct psb_intel_limit_t { - struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1; - struct psb_intel_p2_t p2; -}; - -#define I8XX_DOT_MIN 25000 -#define I8XX_DOT_MAX 350000 -#define I8XX_VCO_MIN 930000 -#define I8XX_VCO_MAX 1400000 -#define I8XX_N_MIN 3 -#define I8XX_N_MAX 16 -#define I8XX_M_MIN 96 -#define I8XX_M_MAX 140 -#define I8XX_M1_MIN 18 -#define I8XX_M1_MAX 26 -#define I8XX_M2_MIN 6 -#define I8XX_M2_MAX 16 -#define I8XX_P_MIN 4 -#define I8XX_P_MAX 128 -#define I8XX_P1_MIN 2 -#define I8XX_P1_MAX 33 -#define I8XX_P1_LVDS_MIN 1 -#define I8XX_P1_LVDS_MAX 6 -#define I8XX_P2_SLOW 4 -#define I8XX_P2_FAST 2 -#define I8XX_P2_LVDS_SLOW 14 -#define I8XX_P2_LVDS_FAST 14 /* No fast option */ -#define I8XX_P2_SLOW_LIMIT 165000 - -#define I9XX_DOT_MIN 20000 -#define I9XX_DOT_MAX 400000 -#define I9XX_VCO_MIN 1400000 -#define I9XX_VCO_MAX 2800000 -#define I9XX_N_MIN 3 -#define I9XX_N_MAX 8 -#define I9XX_M_MIN 70 -#define I9XX_M_MAX 120 -#define I9XX_M1_MIN 10 -#define I9XX_M1_MAX 20 -#define I9XX_M2_MIN 5 -#define I9XX_M2_MAX 9 -#define I9XX_P_SDVO_DAC_MIN 5 -#define I9XX_P_SDVO_DAC_MAX 80 -#define I9XX_P_LVDS_MIN 7 -#define I9XX_P_LVDS_MAX 98 -#define I9XX_P1_MIN 1 -#define I9XX_P1_MAX 8 -#define I9XX_P2_SDVO_DAC_SLOW 10 -#define I9XX_P2_SDVO_DAC_FAST 5 -#define I9XX_P2_SDVO_DAC_SLOW_LIMIT 200000 -#define I9XX_P2_LVDS_SLOW 14 -#define I9XX_P2_LVDS_FAST 7 -#define I9XX_P2_LVDS_SLOW_LIMIT 112000 - -#define INTEL_LIMIT_I8XX_DVO_DAC 0 -#define INTEL_LIMIT_I8XX_LVDS 1 -#define INTEL_LIMIT_I9XX_SDVO_DAC 2 -#define INTEL_LIMIT_I9XX_LVDS 3 - -static const struct psb_intel_limit_t psb_intel_limits[] = { - { /* INTEL_LIMIT_I8XX_DVO_DAC */ - .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX}, - .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX}, - .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX}, - .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX}, - .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX}, - .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX}, - .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX}, - .p1 = {.min = I8XX_P1_MIN, .max = I8XX_P1_MAX}, - .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT, - .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST}, - }, - { /* INTEL_LIMIT_I8XX_LVDS */ - .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX}, - .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX}, - .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX}, - .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX}, - .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX}, - .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX}, - .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX}, - .p1 = {.min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX}, - .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT, - .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST}, - }, - { /* INTEL_LIMIT_I9XX_SDVO_DAC */ - .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, - .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX}, - .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX}, - .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX}, - .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX}, - .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX}, - .p = {.min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX}, - .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX}, - .p2 = {.dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, - .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = - I9XX_P2_SDVO_DAC_FAST}, - }, - { /* INTEL_LIMIT_I9XX_LVDS */ - .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, - .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX}, - .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX}, - .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX}, - .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX}, - .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX}, - .p = {.min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX}, - .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX}, - /* The single-channel range is 25-112Mhz, and dual-channel - * is 80-224Mhz. Prefer single channel as much as possible. - */ - .p2 = {.dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, - .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST}, - }, -}; - -static const struct psb_intel_limit_t *psb_intel_limit(struct drm_crtc *crtc) -{ - const struct psb_intel_limit_t *limit; - - if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) - limit = &psb_intel_limits[INTEL_LIMIT_I9XX_LVDS]; - else - limit = &psb_intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; - return limit; -} - -/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ - -static void i8xx_clock(int refclk, struct psb_intel_clock_t *clock) -{ - clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); - clock->p = clock->p1 * clock->p2; - clock->vco = refclk * clock->m / (clock->n + 2); - clock->dot = clock->vco / clock->p; -} - -/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */ - -static void i9xx_clock(int refclk, struct psb_intel_clock_t *clock) -{ - clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); - clock->p = clock->p1 * clock->p2; - clock->vco = refclk * clock->m / (clock->n + 2); - clock->dot = clock->vco / clock->p; -} - -static void psb_intel_clock(struct drm_device *dev, int refclk, - struct psb_intel_clock_t *clock) -{ - return i9xx_clock(refclk, clock); -} - -/** - * Returns whether any output on the specified pipe is of the specified type - */ -bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type) -{ - struct drm_device *dev = crtc->dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *l_entry; - - list_for_each_entry(l_entry, &mode_config->connector_list, head) { - if (l_entry->encoder && l_entry->encoder->crtc == crtc) { - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(l_entry); - if (psb_intel_output->type == type) - return true; - } - } - return false; -} - -#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; } -/** - * Returns whether the given set of divisors are valid for a given refclk with - * the given connectors. - */ - -static bool psb_intel_PLL_is_valid(struct drm_crtc *crtc, - struct psb_intel_clock_t *clock) -{ - const struct psb_intel_limit_t *limit = psb_intel_limit(crtc); - - if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) - INTELPllInvalid("p1 out of range\n"); - if (clock->p < limit->p.min || limit->p.max < clock->p) - INTELPllInvalid("p out of range\n"); - if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2) - INTELPllInvalid("m2 out of range\n"); - if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) - INTELPllInvalid("m1 out of range\n"); - if (clock->m1 <= clock->m2) - INTELPllInvalid("m1 <= m2\n"); - if (clock->m < limit->m.min || limit->m.max < clock->m) - INTELPllInvalid("m out of range\n"); - if (clock->n < limit->n.min || limit->n.max < clock->n) - INTELPllInvalid("n out of range\n"); - if (clock->vco < limit->vco.min || limit->vco.max < clock->vco) - INTELPllInvalid("vco out of range\n"); - /* XXX: We may need to be checking "Dot clock" - * depending on the multiplier, connector, etc., - * rather than just a single range. - */ - if (clock->dot < limit->dot.min || limit->dot.max < clock->dot) - INTELPllInvalid("dot out of range\n"); - - return true; -} - -/** - * Returns a set of divisors for the desired target clock with the given - * refclk, or FALSE. The returned values represent the clock equation: - * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. - */ -static bool psb_intel_find_best_PLL(struct drm_crtc *crtc, int target, - int refclk, - struct psb_intel_clock_t *best_clock) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_clock_t clock; - const struct psb_intel_limit_t *limit = psb_intel_limit(crtc); - int err = target; - - if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && - (REG_READ(LVDS) & LVDS_PORT_EN) != 0) { - /* - * For LVDS, if the panel is on, just rely on its current - * settings for dual-channel. We haven't figured out how to - * reliably set up different single/dual channel state, if we - * even can. - */ - if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) == - LVDS_CLKB_POWER_UP) - clock.p2 = limit->p2.p2_fast; - else - clock.p2 = limit->p2.p2_slow; - } else { - if (target < limit->p2.dot_limit) - clock.p2 = limit->p2.p2_slow; - else - clock.p2 = limit->p2.p2_fast; - } - - memset(best_clock, 0, sizeof(*best_clock)); - - for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; - clock.m1++) { - for (clock.m2 = limit->m2.min; - clock.m2 < clock.m1 && clock.m2 <= limit->m2.max; - clock.m2++) { - for (clock.n = limit->n.min; - clock.n <= limit->n.max; clock.n++) { - for (clock.p1 = limit->p1.min; - clock.p1 <= limit->p1.max; - clock.p1++) { - int this_err; - - psb_intel_clock(dev, refclk, &clock); - - if (!psb_intel_PLL_is_valid - (crtc, &clock)) - continue; - - this_err = abs(clock.dot - target); - if (this_err < err) { - *best_clock = clock; - err = this_err; - } - } - } - } - } - - return err != target; -} - -void psb_intel_wait_for_vblank(struct drm_device *dev) -{ - /* Wait for 20ms, i.e. one cycle at 50hz. */ - udelay(20000); -} - -int psb_intel_pipe_set_base(struct drm_crtc *crtc, - int x, int y, struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - /* struct drm_i915_master_private *master_priv; */ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); - int pipe = psb_intel_crtc->pipe; - unsigned long start, offset; - int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE); - int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); - int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - u32 dspcntr; - int ret = 0; - - PSB_DEBUG_ENTRY("\n"); - - /* no fb bound */ - if (!crtc->fb) { - DRM_DEBUG("No FB bound\n"); - return 0; - } - - if (!gma_power_begin(dev, true)) - return 0; - - /* We are displaying this buffer, make sure it is actually loaded - into the GTT */ - ret = psb_gtt_pin(psbfb->gtt); - if (ret < 0) - goto psb_intel_pipe_set_base_exit; - start = psbfb->gtt->offset; - - offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); - - REG_WRITE(dspstride, crtc->fb->pitch); - - dspcntr = REG_READ(dspcntr_reg); - dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; - - switch (crtc->fb->bits_per_pixel) { - case 8: - dspcntr |= DISPPLANE_8BPP; - break; - case 16: - if (crtc->fb->depth == 15) - dspcntr |= DISPPLANE_15_16BPP; - else - dspcntr |= DISPPLANE_16BPP; - break; - case 24: - case 32: - dspcntr |= DISPPLANE_32BPP_NO_ALPHA; - break; - default: - DRM_ERROR("Unknown color depth\n"); - ret = -EINVAL; - psb_gtt_unpin(psbfb->gtt); - goto psb_intel_pipe_set_base_exit; - } - REG_WRITE(dspcntr_reg, dspcntr); - - - DRM_DEBUG("Writing base %08lX %08lX %d %d\n", start, offset, x, y); - if (0 /* FIXMEAC - check what PSB needs */) { - REG_WRITE(dspbase, offset); - REG_READ(dspbase); - REG_WRITE(dspsurf, start); - REG_READ(dspsurf); - } else { - REG_WRITE(dspbase, start + offset); - REG_READ(dspbase); - } - - /* If there was a previous display we can now unpin it */ - if (old_fb) - psb_gtt_unpin(to_psb_fb(old_fb)->gtt); - -psb_intel_pipe_set_base_exit: - gma_power_end(dev); - return ret; -} - -/** - * Sets the power management mode of the pipe and plane. - * - * This code should probably grow support for turning the cursor off and back - * on appropriately at the same time as we're turning the pipe off/on. - */ -static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct drm_device *dev = crtc->dev; - /* struct drm_i915_master_private *master_priv; */ - /* struct drm_i915_private *dev_priv = dev->dev_private; */ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE; - int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; - u32 temp; - bool enabled; - - /* XXX: When our outputs are all unaware of DPMS modes other than off - * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. - */ - switch (mode) { - case DRM_MODE_DPMS_ON: - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - /* Enable the DPLL */ - temp = REG_READ(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) == 0) { - REG_WRITE(dpll_reg, temp); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - } - - /* Enable the pipe */ - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) == 0) - REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); - - /* Enable the plane */ - temp = REG_READ(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) == 0) { - REG_WRITE(dspcntr_reg, - temp | DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - } - - psb_intel_crtc_load_lut(crtc); - - /* Give the overlay scaler a chance to enable - * if it's on this pipe */ - /* psb_intel_crtc_dpms_video(crtc, true); TODO */ - break; - case DRM_MODE_DPMS_OFF: - /* Give the overlay scaler a chance to disable - * if it's on this pipe */ - /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ - - /* Disable the VGA plane that we never use */ - REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); - - /* Disable display plane */ - temp = REG_READ(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - REG_WRITE(dspcntr_reg, - temp & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - REG_READ(dspbase_reg); - } - - /* Next, disable display pipes */ - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) != 0) { - REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); - REG_READ(pipeconf_reg); - } - - /* Wait for vblank for the disable to take effect. */ - psb_intel_wait_for_vblank(dev); - - temp = REG_READ(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) != 0) { - REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - } - - /* Wait for the clocks to turn off. */ - udelay(150); - break; - } - - enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF; - - /*Set FIFO Watermarks*/ - REG_WRITE(DSPARB, 0x3F3E); -} - -static void psb_intel_crtc_prepare(struct drm_crtc *crtc) -{ - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); -} - -static void psb_intel_crtc_commit(struct drm_crtc *crtc) -{ - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); -} - -void psb_intel_encoder_prepare(struct drm_encoder *encoder) -{ - struct drm_encoder_helper_funcs *encoder_funcs = - encoder->helper_private; - /* lvds has its own version of prepare see psb_intel_lvds_prepare */ - encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); -} - -void psb_intel_encoder_commit(struct drm_encoder *encoder) -{ - struct drm_encoder_helper_funcs *encoder_funcs = - encoder->helper_private; - /* lvds has its own version of commit see psb_intel_lvds_commit */ - encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); -} - -static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - - -/** - * Return the pipe currently connected to the panel fitter, - * or -1 if the panel fitter is not present or not in use - */ -static int psb_intel_panel_fitter_pipe(struct drm_device *dev) -{ - u32 pfit_control; - - pfit_control = REG_READ(PFIT_CONTROL); - - /* See if the panel fitter is in use */ - if ((pfit_control & PFIT_ENABLE) == 0) - return -1; - /* Must be on PIPE 1 for PSB */ - return 1; -} - -static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - int fp_reg = (pipe == 0) ? FPA0 : FPB0; - int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; - int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; - int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; - int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; - int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; - int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; - int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; - int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; - int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; - int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; - int refclk; - struct psb_intel_clock_t clock; - u32 dpll = 0, fp = 0, dspcntr, pipeconf; - bool ok, is_sdvo = false, is_dvo = false; - bool is_crt = false, is_lvds = false, is_tv = false; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *connector; - - list_for_each_entry(connector, &mode_config->connector_list, head) { - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - - if (!connector->encoder - || connector->encoder->crtc != crtc) - continue; - - switch (psb_intel_output->type) { - case INTEL_OUTPUT_LVDS: - is_lvds = true; - break; - case INTEL_OUTPUT_SDVO: - is_sdvo = true; - break; - case INTEL_OUTPUT_DVO: - is_dvo = true; - break; - case INTEL_OUTPUT_TVOUT: - is_tv = true; - break; - case INTEL_OUTPUT_ANALOG: - is_crt = true; - break; - } - } - - refclk = 96000; - - ok = psb_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, - &clock); - if (!ok) { - DRM_ERROR("Couldn't find PLL settings for mode!\n"); - return 0; - } - - fp = clock.n << 16 | clock.m1 << 8 | clock.m2; - - dpll = DPLL_VGA_MODE_DIS; - if (is_lvds) { - dpll |= DPLLB_MODE_LVDS; - dpll |= DPLL_DVO_HIGH_SPEED; - } else - dpll |= DPLLB_MODE_DAC_SERIAL; - if (is_sdvo) { - int sdvo_pixel_multiply = - adjusted_mode->clock / mode->clock; - dpll |= DPLL_DVO_HIGH_SPEED; - dpll |= - (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; - } - - /* compute bitmask from p1 value */ - dpll |= (1 << (clock.p1 - 1)) << 16; - switch (clock.p2) { - case 5: - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; - break; - case 7: - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7; - break; - case 10: - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10; - break; - case 14: - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; - break; - } - - if (is_tv) { - /* XXX: just matching BIOS for now */ -/* dpll |= PLL_REF_INPUT_TVCLKINBC; */ - dpll |= 3; - } - dpll |= PLL_REF_INPUT_DREFCLK; - - /* setup pipeconf */ - pipeconf = REG_READ(pipeconf_reg); - - /* Set up the display plane register */ - dspcntr = DISPPLANE_GAMMA_ENABLE; - - if (pipe == 0) - dspcntr |= DISPPLANE_SEL_PIPE_A; - else - dspcntr |= DISPPLANE_SEL_PIPE_B; - - dspcntr |= DISPLAY_PLANE_ENABLE; - pipeconf |= PIPEACONF_ENABLE; - dpll |= DPLL_VCO_ENABLE; - - - /* Disable the panel fitter if it was on our pipe */ - if (psb_intel_panel_fitter_pipe(dev) == pipe) - REG_WRITE(PFIT_CONTROL, 0); - - DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); - drm_mode_debug_printmodeline(mode); - - if (dpll & DPLL_VCO_ENABLE) { - REG_WRITE(fp_reg, fp); - REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - udelay(150); - } - - /* The LVDS pin pair needs to be on before the DPLLs are enabled. - * This is an exception to the general rule that mode_set doesn't turn - * things on. - */ - if (is_lvds) { - u32 lvds = REG_READ(LVDS); - - lvds |= - LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | - LVDS_PIPEB_SELECT; - /* Set the B0-B3 data pairs corresponding to - * whether we're going to - * set the DPLLs for dual-channel mode or not. - */ - if (clock.p2 == 7) - lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; - else - lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); - - /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) - * appropriately here, but we need to look more - * thoroughly into how panels behave in the two modes. - */ - - REG_WRITE(LVDS, lvds); - REG_READ(LVDS); - } - - REG_WRITE(fp_reg, fp); - REG_WRITE(dpll_reg, dpll); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - - /* write it again -- the BIOS does, after all */ - REG_WRITE(dpll_reg, dpll); - - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - - REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | - ((adjusted_mode->crtc_hblank_end - 1) << 16)); - REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | - ((adjusted_mode->crtc_hsync_end - 1) << 16)); - REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | - ((adjusted_mode->crtc_vblank_end - 1) << 16)); - REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | - ((adjusted_mode->crtc_vsync_end - 1) << 16)); - /* pipesrc and dspsize control the size that is scaled from, - * which should always be the user's requested size. - */ - REG_WRITE(dspsize_reg, - ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); - REG_WRITE(dsppos_reg, 0); - REG_WRITE(pipesrc_reg, - ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - REG_WRITE(pipeconf_reg, pipeconf); - REG_READ(pipeconf_reg); - - psb_intel_wait_for_vblank(dev); - - REG_WRITE(dspcntr_reg, dspcntr); - - /* Flush the plane changes */ - { - struct drm_crtc_helper_funcs *crtc_funcs = - crtc->helper_private; - crtc_funcs->mode_set_base(crtc, x, y, old_fb); - } - - psb_intel_wait_for_vblank(dev); - - return 0; -} - -/** Loads the palette/gamma unit for the CRTC with the prepared values */ -void psb_intel_crtc_load_lut(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int palreg = PALETTE_A; - int i; - - /* The clocks have to be on to load the palette. */ - if (!crtc->enabled) - return; - - switch (psb_intel_crtc->pipe) { - case 0: - break; - case 1: - palreg = PALETTE_B; - break; - case 2: - palreg = PALETTE_C; - break; - default: - DRM_ERROR("Illegal Pipe Number.\n"); - return; - } - - if (gma_power_begin(dev, false)) { - for (i = 0; i < 256; i++) { - REG_WRITE(palreg + 4 * i, - ((psb_intel_crtc->lut_r[i] + - psb_intel_crtc->lut_adj[i]) << 16) | - ((psb_intel_crtc->lut_g[i] + - psb_intel_crtc->lut_adj[i]) << 8) | - (psb_intel_crtc->lut_b[i] + - psb_intel_crtc->lut_adj[i])); - } - gma_power_end(dev); - } else { - for (i = 0; i < 256; i++) { - dev_priv->save_palette_a[i] = - ((psb_intel_crtc->lut_r[i] + - psb_intel_crtc->lut_adj[i]) << 16) | - ((psb_intel_crtc->lut_g[i] + - psb_intel_crtc->lut_adj[i]) << 8) | - (psb_intel_crtc->lut_b[i] + - psb_intel_crtc->lut_adj[i]); - } - - } -} - -/** - * Save HW states of giving crtc - */ -static void psb_intel_crtc_save(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - /* struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; */ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; - int pipeA = (psb_intel_crtc->pipe == 0); - uint32_t paletteReg; - int i; - - DRM_DEBUG("\n"); - - if (!crtc_state) { - DRM_DEBUG("No CRTC state found\n"); - return; - } - - crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR); - crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF); - crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC); - crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0); - crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1); - crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B); - crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B); - crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B); - crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B); - crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B); - crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B); - crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B); - crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE); - - /*NOTE: DSPSIZE DSPPOS only for psb*/ - crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE); - crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS); - - crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE); - - DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", - crtc_state->saveDSPCNTR, - crtc_state->savePIPECONF, - crtc_state->savePIPESRC, - crtc_state->saveFP0, - crtc_state->saveFP1, - crtc_state->saveDPLL, - crtc_state->saveHTOTAL, - crtc_state->saveHBLANK, - crtc_state->saveHSYNC, - crtc_state->saveVTOTAL, - crtc_state->saveVBLANK, - crtc_state->saveVSYNC, - crtc_state->saveDSPSTRIDE, - crtc_state->saveDSPSIZE, - crtc_state->saveDSPPOS, - crtc_state->saveDSPBASE - ); - - paletteReg = pipeA ? PALETTE_A : PALETTE_B; - for (i = 0; i < 256; ++i) - crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2)); -} - -/** - * Restore HW states of giving crtc - */ -static void psb_intel_crtc_restore(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - /* struct drm_psb_private * dev_priv = - (struct drm_psb_private *)dev->dev_private; */ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; - /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */ - int pipeA = (psb_intel_crtc->pipe == 0); - uint32_t paletteReg; - int i; - - DRM_DEBUG("\n"); - - if (!crtc_state) { - DRM_DEBUG("No crtc state\n"); - return; - } - - DRM_DEBUG( - "current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", - REG_READ(pipeA ? DSPACNTR : DSPBCNTR), - REG_READ(pipeA ? PIPEACONF : PIPEBCONF), - REG_READ(pipeA ? PIPEASRC : PIPEBSRC), - REG_READ(pipeA ? FPA0 : FPB0), - REG_READ(pipeA ? FPA1 : FPB1), - REG_READ(pipeA ? DPLL_A : DPLL_B), - REG_READ(pipeA ? HTOTAL_A : HTOTAL_B), - REG_READ(pipeA ? HBLANK_A : HBLANK_B), - REG_READ(pipeA ? HSYNC_A : HSYNC_B), - REG_READ(pipeA ? VTOTAL_A : VTOTAL_B), - REG_READ(pipeA ? VBLANK_A : VBLANK_B), - REG_READ(pipeA ? VSYNC_A : VSYNC_B), - REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE), - REG_READ(pipeA ? DSPASIZE : DSPBSIZE), - REG_READ(pipeA ? DSPAPOS : DSPBPOS), - REG_READ(pipeA ? DSPABASE : DSPBBASE) - ); - - DRM_DEBUG( - "saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", - crtc_state->saveDSPCNTR, - crtc_state->savePIPECONF, - crtc_state->savePIPESRC, - crtc_state->saveFP0, - crtc_state->saveFP1, - crtc_state->saveDPLL, - crtc_state->saveHTOTAL, - crtc_state->saveHBLANK, - crtc_state->saveHSYNC, - crtc_state->saveVTOTAL, - crtc_state->saveVBLANK, - crtc_state->saveVSYNC, - crtc_state->saveDSPSTRIDE, - crtc_state->saveDSPSIZE, - crtc_state->saveDSPPOS, - crtc_state->saveDSPBASE - ); - - - if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) { - REG_WRITE(pipeA ? DPLL_A : DPLL_B, - crtc_state->saveDPLL & ~DPLL_VCO_ENABLE); - REG_READ(pipeA ? DPLL_A : DPLL_B); - DRM_DEBUG("write dpll: %x\n", - REG_READ(pipeA ? DPLL_A : DPLL_B)); - udelay(150); - } - - REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0); - REG_READ(pipeA ? FPA0 : FPB0); - - REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1); - REG_READ(pipeA ? FPA1 : FPB1); - - REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL); - REG_READ(pipeA ? DPLL_A : DPLL_B); - udelay(150); - - REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL); - REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK); - REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC); - REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL); - REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK); - REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC); - REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE); - - REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE); - REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS); - - REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC); - REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); - REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF); - - psb_intel_wait_for_vblank(dev); - - REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR); - REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); - - psb_intel_wait_for_vblank(dev); - - paletteReg = pipeA ? PALETTE_A : PALETTE_B; - for (i = 0; i < 256; ++i) - REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]); -} - -static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, uint32_t height) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; - uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; - uint32_t temp; - size_t addr = 0; - struct gtt_range *gt; - struct drm_gem_object *obj; - int ret; - - DRM_DEBUG("\n"); - - /* if we want to turn of the cursor ignore width and height */ - if (!handle) { - DRM_DEBUG("cursor off\n"); - /* turn off the cursor */ - temp = CURSOR_MODE_DISABLE; - - if (gma_power_begin(dev, false)) { - REG_WRITE(control, temp); - REG_WRITE(base, 0); - gma_power_end(dev); - } - - /* Unpin the old GEM object */ - if (psb_intel_crtc->cursor_obj) { - gt = container_of(psb_intel_crtc->cursor_obj, - struct gtt_range, gem); - psb_gtt_unpin(gt); - drm_gem_object_unreference(psb_intel_crtc->cursor_obj); - psb_intel_crtc->cursor_obj = NULL; - } - - return 0; - } - - /* Currently we only support 64x64 cursors */ - if (width != 64 || height != 64) { - DRM_ERROR("we currently only support 64x64 cursors\n"); - return -EINVAL; - } - - obj = drm_gem_object_lookup(dev, file_priv, handle); - if (!obj) - return -ENOENT; - - if (obj->size < width * height * 4) { - DRM_ERROR("buffer is to small\n"); - return -ENOMEM; - } - - gt = container_of(obj, struct gtt_range, gem); - - /* Pin the memory into the GTT */ - ret = psb_gtt_pin(gt); - if (ret) { - DRM_ERROR("Can not pin down handle 0x%x\n", handle); - return ret; - } - - - addr = gt->offset; /* Or resource.start ??? */ - - psb_intel_crtc->cursor_addr = addr; - - temp = 0; - /* set the pipe for the cursor */ - temp |= (pipe << 28); - temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; - - if (gma_power_begin(dev, false)) { - REG_WRITE(control, temp); - REG_WRITE(base, addr); - gma_power_end(dev); - } - - /* unpin the old bo */ - if (psb_intel_crtc->cursor_obj && psb_intel_crtc->cursor_obj != obj) { - gt = container_of(psb_intel_crtc->cursor_obj, - struct gtt_range, gem); - psb_gtt_unpin(gt); - drm_gem_object_unreference(psb_intel_crtc->cursor_obj); - psb_intel_crtc->cursor_obj = obj; - } - - return 0; -} - -static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - uint32_t temp = 0; - uint32_t addr; - - - if (x < 0) { - temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT); - x = -x; - } - if (y < 0) { - temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT); - y = -y; - } - - temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT); - temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); - - addr = psb_intel_crtc->cursor_addr; - - if (gma_power_begin(dev, false)) { - REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp); - REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, addr); - gma_power_end(dev); - } - return 0; -} - -static void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, - u16 *green, u16 *blue, uint32_t type, uint32_t size) -{ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int i; - - if (size != 256) - return; - - for (i = 0; i < 256; i++) { - psb_intel_crtc->lut_r[i] = red[i] >> 8; - psb_intel_crtc->lut_g[i] = green[i] >> 8; - psb_intel_crtc->lut_b[i] = blue[i] >> 8; - } - - psb_intel_crtc_load_lut(crtc); -} - -static int psb_crtc_set_config(struct drm_mode_set *set) -{ - int ret; - struct drm_device *dev = set->crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (!dev_priv->rpm_enabled) - return drm_crtc_helper_set_config(set); - - pm_runtime_forbid(&dev->pdev->dev); - ret = drm_crtc_helper_set_config(set); - pm_runtime_allow(&dev->pdev->dev); - return ret; -} - -/* Returns the clock of the currently programmed mode of the given pipe. */ -static int psb_intel_crtc_clock_get(struct drm_device *dev, - struct drm_crtc *crtc) -{ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - u32 dpll; - u32 fp; - struct psb_intel_clock_t clock; - bool is_lvds; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (gma_power_begin(dev, false)) { - dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B); - if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) - fp = REG_READ((pipe == 0) ? FPA0 : FPB0); - else - fp = REG_READ((pipe == 0) ? FPA1 : FPB1); - is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN); - gma_power_end(dev); - } else { - dpll = (pipe == 0) ? - dev_priv->saveDPLL_A : dev_priv->saveDPLL_B; - - if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) - fp = (pipe == 0) ? - dev_priv->saveFPA0 : - dev_priv->saveFPB0; - else - fp = (pipe == 0) ? - dev_priv->saveFPA1 : - dev_priv->saveFPB1; - - is_lvds = (pipe == 1) && (dev_priv->saveLVDS & LVDS_PORT_EN); - } - - clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; - clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; - clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; - - if (is_lvds) { - clock.p1 = - ffs((dpll & - DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> - DPLL_FPA01_P1_POST_DIV_SHIFT); - clock.p2 = 14; - - if ((dpll & PLL_REF_INPUT_MASK) == - PLLB_REF_INPUT_SPREADSPECTRUMIN) { - /* XXX: might not be 66MHz */ - i8xx_clock(66000, &clock); - } else - i8xx_clock(48000, &clock); - } else { - if (dpll & PLL_P1_DIVIDE_BY_TWO) - clock.p1 = 2; - else { - clock.p1 = - ((dpll & - DPLL_FPA01_P1_POST_DIV_MASK_I830) >> - DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; - } - if (dpll & PLL_P2_DIVIDE_BY_4) - clock.p2 = 4; - else - clock.p2 = 2; - - i8xx_clock(48000, &clock); - } - - /* XXX: It would be nice to validate the clocks, but we can't reuse - * i830PllIsValid() because it relies on the xf86_config connector - * configuration being accurate, which it isn't necessarily. - */ - - return clock.dot; -} - -/** Returns the currently programmed mode of the given pipe. */ -struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev, - struct drm_crtc *crtc) -{ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - struct drm_display_mode *mode; - int htot; - int hsync; - int vtot; - int vsync; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (gma_power_begin(dev, false)) { - htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B); - hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B); - vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B); - vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B); - gma_power_end(dev); - } else { - htot = (pipe == 0) ? - dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B; - hsync = (pipe == 0) ? - dev_priv->saveHSYNC_A : dev_priv->saveHSYNC_B; - vtot = (pipe == 0) ? - dev_priv->saveVTOTAL_A : dev_priv->saveVTOTAL_B; - vsync = (pipe == 0) ? - dev_priv->saveVSYNC_A : dev_priv->saveVSYNC_B; - } - - mode = kzalloc(sizeof(*mode), GFP_KERNEL); - if (!mode) - return NULL; - - mode->clock = psb_intel_crtc_clock_get(dev, crtc); - mode->hdisplay = (htot & 0xffff) + 1; - mode->htotal = ((htot & 0xffff0000) >> 16) + 1; - mode->hsync_start = (hsync & 0xffff) + 1; - mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1; - mode->vdisplay = (vtot & 0xffff) + 1; - mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1; - mode->vsync_start = (vsync & 0xffff) + 1; - mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1; - - drm_mode_set_name(mode); - drm_mode_set_crtcinfo(mode, 0); - - return mode; -} - -static void psb_intel_crtc_destroy(struct drm_crtc *crtc) -{ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct gtt_range *gt; - - /* Unpin the old GEM object */ - if (psb_intel_crtc->cursor_obj) { - gt = container_of(psb_intel_crtc->cursor_obj, - struct gtt_range, gem); - psb_gtt_unpin(gt); - drm_gem_object_unreference(psb_intel_crtc->cursor_obj); - psb_intel_crtc->cursor_obj = NULL; - } - kfree(psb_intel_crtc->crtc_state); - drm_crtc_cleanup(crtc); - kfree(psb_intel_crtc); -} - -static const struct drm_crtc_helper_funcs psb_intel_helper_funcs = { - .dpms = psb_intel_crtc_dpms, - .mode_fixup = psb_intel_crtc_mode_fixup, - .mode_set = psb_intel_crtc_mode_set, - .mode_set_base = psb_intel_pipe_set_base, - .prepare = psb_intel_crtc_prepare, - .commit = psb_intel_crtc_commit, -}; - -const struct drm_crtc_funcs psb_intel_crtc_funcs = { - .save = psb_intel_crtc_save, - .restore = psb_intel_crtc_restore, - .cursor_set = psb_intel_crtc_cursor_set, - .cursor_move = psb_intel_crtc_cursor_move, - .gamma_set = psb_intel_crtc_gamma_set, - .set_config = psb_crtc_set_config, - .destroy = psb_intel_crtc_destroy, -}; - -void psb_intel_crtc_init(struct drm_device *dev, int pipe, - struct psb_intel_mode_device *mode_dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_crtc *psb_intel_crtc; - int i; - uint16_t *r_base, *g_base, *b_base; - - PSB_DEBUG_ENTRY("\n"); - - /* We allocate a extra array of drm_connector pointers - * for fbdev after the crtc */ - psb_intel_crtc = - kzalloc(sizeof(struct psb_intel_crtc) + - (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), - GFP_KERNEL); - if (psb_intel_crtc == NULL) - return; - - psb_intel_crtc->crtc_state = - kzalloc(sizeof(struct psb_intel_crtc_state), GFP_KERNEL); - if (!psb_intel_crtc->crtc_state) { - DRM_INFO("Crtc state error: No memory\n"); - kfree(psb_intel_crtc); - return; - } - - drm_crtc_init(dev, &psb_intel_crtc->base, &psb_intel_crtc_funcs); - - drm_mode_crtc_set_gamma_size(&psb_intel_crtc->base, 256); - psb_intel_crtc->pipe = pipe; - psb_intel_crtc->plane = pipe; - - r_base = psb_intel_crtc->base.gamma_store; - g_base = r_base + 256; - b_base = g_base + 256; - for (i = 0; i < 256; i++) { - psb_intel_crtc->lut_r[i] = i; - psb_intel_crtc->lut_g[i] = i; - psb_intel_crtc->lut_b[i] = i; - r_base[i] = i << 8; - g_base[i] = i << 8; - b_base[i] = i << 8; - - psb_intel_crtc->lut_adj[i] = 0; - } - - psb_intel_crtc->mode_dev = mode_dev; - psb_intel_crtc->cursor_addr = 0; - - if (IS_MRST(dev)) - drm_crtc_helper_add(&psb_intel_crtc->base, - &mrst_helper_funcs); - else - drm_crtc_helper_add(&psb_intel_crtc->base, - &psb_intel_helper_funcs); - - /* Setup the array of drm_connector pointer array */ - psb_intel_crtc->mode_set.crtc = &psb_intel_crtc->base; - BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || - dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] != NULL); - dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] = - &psb_intel_crtc->base; - dev_priv->pipe_to_crtc_mapping[psb_intel_crtc->pipe] = - &psb_intel_crtc->base; - psb_intel_crtc->mode_set.connectors = - (struct drm_connector **) (psb_intel_crtc + 1); - psb_intel_crtc->mode_set.num_connectors = 0; -} - -int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_psb_get_pipe_from_crtc_id_arg *pipe_from_crtc_id = data; - struct drm_mode_object *drmmode_obj; - struct psb_intel_crtc *crtc; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id, - DRM_MODE_OBJECT_CRTC); - - if (!drmmode_obj) { - DRM_ERROR("no such CRTC id\n"); - return -EINVAL; - } - - crtc = to_psb_intel_crtc(obj_to_crtc(drmmode_obj)); - pipe_from_crtc_id->pipe = crtc->pipe; - - return 0; -} - -struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) -{ - struct drm_crtc *crtc = NULL; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - if (psb_intel_crtc->pipe == pipe) - break; - } - return crtc; -} - -int psb_intel_connector_clones(struct drm_device *dev, int type_mask) -{ - int index_mask = 0; - struct drm_connector *connector; - int entry = 0; - - list_for_each_entry(connector, &dev->mode_config.connector_list, - head) { - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - if (type_mask & (1 << psb_intel_output->type)) - index_mask |= (1 << entry); - entry++; - } - return index_mask; -} - - -void psb_intel_modeset_cleanup(struct drm_device *dev) -{ - drm_mode_config_cleanup(dev); -} - - -/* current intel driver doesn't take advantage of encoders - always give back the encoder for the connector -*/ -struct drm_encoder *psb_intel_best_encoder(struct drm_connector *connector) -{ - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - - return &psb_intel_output->enc; -} - diff --git a/drivers/staging/gma500/psb_intel_display.h b/drivers/staging/gma500/psb_intel_display.h deleted file mode 100644 index 3724b971e91..00000000000 --- a/drivers/staging/gma500/psb_intel_display.h +++ /dev/null @@ -1,25 +0,0 @@ -/* copyright (c) 2008, Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt <eric@anholt.net> - */ - -#ifndef _INTEL_DISPLAY_H_ -#define _INTEL_DISPLAY_H_ - -bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type); - -#endif diff --git a/drivers/staging/gma500/psb_intel_drv.h b/drivers/staging/gma500/psb_intel_drv.h deleted file mode 100644 index 6006ddd993f..00000000000 --- a/drivers/staging/gma500/psb_intel_drv.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2009, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef __INTEL_DRV_H__ -#define __INTEL_DRV_H__ - -#include <linux/i2c.h> -#include <linux/i2c-algo-bit.h> -#include <drm/drm_crtc.h> -#include <drm/drm_crtc_helper.h> -#include <linux/gpio.h> - -/* - * MOORESTOWN defines - */ -#define DELAY_TIME1 2000 /* 1000 = 1ms */ - -/* - * Display related stuff - */ - -/* store information about an Ixxx DVO */ -/* The i830->i865 use multiple DVOs with multiple i2cs */ -/* the i915, i945 have a single sDVO i2c bus - which is different */ -#define MAX_OUTPUTS 6 -/* maximum connectors per crtcs in the mode set */ -#define INTELFB_CONN_LIMIT 4 - -#define INTEL_I2C_BUS_DVO 1 -#define INTEL_I2C_BUS_SDVO 2 - -/* these are outputs from the chip - integrated only - * external chips are via DVO or SDVO output */ -#define INTEL_OUTPUT_UNUSED 0 -#define INTEL_OUTPUT_ANALOG 1 -#define INTEL_OUTPUT_DVO 2 -#define INTEL_OUTPUT_SDVO 3 -#define INTEL_OUTPUT_LVDS 4 -#define INTEL_OUTPUT_TVOUT 5 -#define INTEL_OUTPUT_HDMI 6 -#define INTEL_OUTPUT_MIPI 7 -#define INTEL_OUTPUT_MIPI2 8 - -#define INTEL_DVO_CHIP_NONE 0 -#define INTEL_DVO_CHIP_LVDS 1 -#define INTEL_DVO_CHIP_TMDS 2 -#define INTEL_DVO_CHIP_TVOUT 4 - -enum mipi_panel_type { - NSC_800X480 = 1, - LGE_480X1024 = 2, - TPO_864X480 = 3 -}; - -/** - * Hold information useally put on the device driver privates here, - * since it needs to be shared across multiple of devices drivers privates. -*/ -struct psb_intel_mode_device { - - /* - * Abstracted memory manager operations - */ - size_t(*bo_offset) (struct drm_device *dev, void *bo); - - /* - * Cursor - */ - int cursor_needs_physical; - - /* - * LVDS info - */ - int backlight_duty_cycle; /* restore backlight to this value */ - bool panel_wants_dither; - struct drm_display_mode *panel_fixed_mode; - struct drm_display_mode *panel_fixed_mode2; - struct drm_display_mode *vbt_mode; /* if any */ - - uint32_t saveBLC_PWM_CTL; -}; - -struct psb_intel_i2c_chan { - /* for getting at dev. private (mmio etc.) */ - struct drm_device *drm_dev; - u32 reg; /* GPIO reg */ - struct i2c_adapter adapter; - struct i2c_algo_bit_data algo; - u8 slave_addr; -}; - -struct psb_intel_output { - struct drm_connector base; - - struct drm_encoder enc; - int type; - - struct psb_intel_i2c_chan *i2c_bus; /* for control functions */ - struct psb_intel_i2c_chan *ddc_bus; /* for DDC only stuff */ - bool load_detect_temp; - void *dev_priv; - - struct psb_intel_mode_device *mode_dev; - -}; - -struct psb_intel_crtc_state { - uint32_t saveDSPCNTR; - uint32_t savePIPECONF; - uint32_t savePIPESRC; - uint32_t saveDPLL; - uint32_t saveFP0; - uint32_t saveFP1; - uint32_t saveHTOTAL; - uint32_t saveHBLANK; - uint32_t saveHSYNC; - uint32_t saveVTOTAL; - uint32_t saveVBLANK; - uint32_t saveVSYNC; - uint32_t saveDSPSTRIDE; - uint32_t saveDSPSIZE; - uint32_t saveDSPPOS; - uint32_t saveDSPBASE; - uint32_t savePalette[256]; -}; - -struct psb_intel_crtc { - struct drm_crtc base; - int pipe; - int plane; - uint32_t cursor_addr; - u8 lut_r[256], lut_g[256], lut_b[256]; - u8 lut_adj[256]; - struct psb_intel_framebuffer *fbdev_fb; - /* a mode_set for fbdev users on this crtc */ - struct drm_mode_set mode_set; - - /* GEM object that holds our cursor */ - struct drm_gem_object *cursor_obj; - - struct drm_display_mode saved_mode; - struct drm_display_mode saved_adjusted_mode; - - struct psb_intel_mode_device *mode_dev; - - /*crtc mode setting flags*/ - u32 mode_flags; - - /* Saved Crtc HW states */ - struct psb_intel_crtc_state *crtc_state; -}; - -#define to_psb_intel_crtc(x) \ - container_of(x, struct psb_intel_crtc, base) -#define to_psb_intel_output(x) \ - container_of(x, struct psb_intel_output, base) -#define enc_to_psb_intel_output(x) \ - container_of(x, struct psb_intel_output, enc) -#define to_psb_intel_framebuffer(x) \ - container_of(x, struct psb_intel_framebuffer, base) - -struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev, - const u32 reg, const char *name); -void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan); -int psb_intel_ddc_get_modes(struct psb_intel_output *psb_intel_output); -extern bool psb_intel_ddc_probe(struct psb_intel_output *psb_intel_output); - -extern void psb_intel_crtc_init(struct drm_device *dev, int pipe, - struct psb_intel_mode_device *mode_dev); -extern void psb_intel_crt_init(struct drm_device *dev); -extern void psb_intel_sdvo_init(struct drm_device *dev, int output_device); -extern void psb_intel_dvo_init(struct drm_device *dev); -extern void psb_intel_tv_init(struct drm_device *dev); -extern void psb_intel_lvds_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev); -extern void psb_intel_lvds_set_brightness(struct drm_device *dev, int level); -extern void mrst_lvds_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev); -extern void mrst_wait_for_INTR_PKT_SENT(struct drm_device *dev); -extern void mrst_dsi_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev); -extern void mid_dsi_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev, int dsi_num); - -extern void psb_intel_crtc_load_lut(struct drm_crtc *crtc); -extern void psb_intel_encoder_prepare(struct drm_encoder *encoder); -extern void psb_intel_encoder_commit(struct drm_encoder *encoder); - -extern struct drm_encoder *psb_intel_best_encoder(struct drm_connector - *connector); - -extern struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev, - struct drm_crtc *crtc); -extern void psb_intel_wait_for_vblank(struct drm_device *dev); -extern int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, - int pipe); -extern struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev, - int sdvoB); -extern int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector); -extern void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, - int enable); -extern int intelfb_probe(struct drm_device *dev); -extern int intelfb_remove(struct drm_device *dev, - struct drm_framebuffer *fb); -extern struct drm_framebuffer *psb_intel_framebuffer_create(struct drm_device - *dev, struct - drm_mode_fb_cmd - *mode_cmd, - void *mm_private); -extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); -extern int psb_intel_lvds_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode); -extern int psb_intel_lvds_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t value); -extern void psb_intel_lvds_destroy(struct drm_connector *connector); -extern const struct drm_encoder_funcs psb_intel_lvds_enc_funcs; - -#endif /* __INTEL_DRV_H__ */ diff --git a/drivers/staging/gma500/psb_intel_i2c.c b/drivers/staging/gma500/psb_intel_i2c.c deleted file mode 100644 index e33432df510..00000000000 --- a/drivers/staging/gma500/psb_intel_i2c.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright © 2006-2007 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt <eric@anholt.net> - */ - -#include <linux/i2c.h> -#include <linux/i2c-algo-bit.h> - -#include "psb_drv.h" -#include "psb_intel_reg.h" - -/* - * Intel GPIO access functions - */ - -#define I2C_RISEFALL_TIME 20 - -static int get_clock(void *data) -{ - struct psb_intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - u32 val; - - val = REG_READ(chan->reg); - return (val & GPIO_CLOCK_VAL_IN) != 0; -} - -static int get_data(void *data) -{ - struct psb_intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - u32 val; - - val = REG_READ(chan->reg); - return (val & GPIO_DATA_VAL_IN) != 0; -} - -static void set_clock(void *data, int state_high) -{ - struct psb_intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - u32 reserved = 0, clock_bits; - - /* On most chips, these bits must be preserved in software. */ - reserved = - REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | - GPIO_CLOCK_PULLUP_DISABLE); - - if (state_high) - clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK; - else - clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | - GPIO_CLOCK_VAL_MASK; - REG_WRITE(chan->reg, reserved | clock_bits); - udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ -} - -static void set_data(void *data, int state_high) -{ - struct psb_intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - u32 reserved = 0, data_bits; - - /* On most chips, these bits must be preserved in software. */ - reserved = - REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | - GPIO_CLOCK_PULLUP_DISABLE); - - if (state_high) - data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK; - else - data_bits = - GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | - GPIO_DATA_VAL_MASK; - - REG_WRITE(chan->reg, reserved | data_bits); - udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ -} - -/** - * psb_intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg - * @dev: DRM device - * @output: driver specific output device - * @reg: GPIO reg to use - * @name: name for this bus - * - * Creates and registers a new i2c bus with the Linux i2c layer, for use - * in output probing and control (e.g. DDC or SDVO control functions). - * - * Possible values for @reg include: - * %GPIOA - * %GPIOB - * %GPIOC - * %GPIOD - * %GPIOE - * %GPIOF - * %GPIOG - * %GPIOH - * see PRM for details on how these different busses are used. - */ -struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev, - const u32 reg, const char *name) -{ - struct psb_intel_i2c_chan *chan; - - chan = kzalloc(sizeof(struct psb_intel_i2c_chan), GFP_KERNEL); - if (!chan) - goto out_free; - - chan->drm_dev = dev; - chan->reg = reg; - snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name); - chan->adapter.owner = THIS_MODULE; - chan->adapter.algo_data = &chan->algo; - chan->adapter.dev.parent = &dev->pdev->dev; - chan->algo.setsda = set_data; - chan->algo.setscl = set_clock; - chan->algo.getsda = get_data; - chan->algo.getscl = get_clock; - chan->algo.udelay = 20; - chan->algo.timeout = usecs_to_jiffies(2200); - chan->algo.data = chan; - - i2c_set_adapdata(&chan->adapter, chan); - - if (i2c_bit_add_bus(&chan->adapter)) - goto out_free; - - /* JJJ: raise SCL and SDA? */ - set_data(chan, 1); - set_clock(chan, 1); - udelay(20); - - return chan; - -out_free: - kfree(chan); - return NULL; -} - -/** - * psb_intel_i2c_destroy - unregister and free i2c bus resources - * @output: channel to free - * - * Unregister the adapter from the i2c layer, then free the structure. - */ -void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan) -{ - if (!chan) - return; - - i2c_del_adapter(&chan->adapter); - kfree(chan); -} diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c deleted file mode 100644 index b0a225b9f56..00000000000 --- a/drivers/staging/gma500/psb_intel_lvds.c +++ /dev/null @@ -1,885 +0,0 @@ -/* - * Copyright © 2006-2007 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt <eric@anholt.net> - * Dave Airlie <airlied@linux.ie> - * Jesse Barnes <jesse.barnes@intel.com> - */ - -#include <linux/i2c.h> -/* #include <drm/drm_crtc.h> */ -/* #include <drm/drm_edid.h> */ -#include <drm/drmP.h> - -#include "psb_intel_bios.h" -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "psb_powermgmt.h" -#include <linux/pm_runtime.h> - -u32 CoreClock; -u32 PWMControlRegFreq; - -/** - * LVDS I2C backlight control macros - */ -#define BRIGHTNESS_MAX_LEVEL 100 -#define BRIGHTNESS_MASK 0xFF -#define BLC_I2C_TYPE 0x01 -#define BLC_PWM_TYPT 0x02 - -#define BLC_POLARITY_NORMAL 0 -#define BLC_POLARITY_INVERSE 1 - -#define PSB_BLC_MAX_PWM_REG_FREQ (0xFFFE) -#define PSB_BLC_MIN_PWM_REG_FREQ (0x2) -#define PSB_BLC_PWM_PRECISION_FACTOR (10) -#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) -#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) - -struct psb_intel_lvds_priv { - /** - * Saved LVDO output states - */ - uint32_t savePP_ON; - uint32_t savePP_OFF; - uint32_t saveLVDS; - uint32_t savePP_CONTROL; - uint32_t savePP_CYCLE; - uint32_t savePFIT_CONTROL; - uint32_t savePFIT_PGM_RATIOS; - uint32_t saveBLC_PWM_CTL; -}; - -/* MRST defines end */ - -/** - * Returns the maximum level of the backlight duty cycle field. - */ -static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 retVal; - - if (gma_power_begin(dev, false)) { - retVal = ((REG_READ(BLC_PWM_CTL) & - BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; - - gma_power_end(dev); - } else - retVal = ((dev_priv->saveBLC_PWM_CTL & - BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; - - return retVal; -} - -/* - * Set LVDS backlight level by I2C command - * - * FIXME: at some point we need to both track this for PM and also - * disable runtime pm on MRST if the brightness is nil (ie blanked) - */ -static int psb_lvds_i2c_set_brightness(struct drm_device *dev, - unsigned int level) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; - - struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus; - u8 out_buf[2]; - unsigned int blc_i2c_brightness; - - struct i2c_msg msgs[] = { - { - .addr = lvds_i2c_bus->slave_addr, - .flags = 0, - .len = 2, - .buf = out_buf, - } - }; - - blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level * - BRIGHTNESS_MASK / - BRIGHTNESS_MAX_LEVEL); - - if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE) - blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness; - - out_buf[0] = dev_priv->lvds_bl->brightnesscmd; - out_buf[1] = (u8)blc_i2c_brightness; - - if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) { - DRM_DEBUG("I2C set brightness.(command, value) (%d, %d)\n", - dev_priv->lvds_bl->brightnesscmd, - blc_i2c_brightness); - return 0; - } - - DRM_ERROR("I2C transfer error\n"); - return -1; -} - - -static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; - - u32 max_pwm_blc; - u32 blc_pwm_duty_cycle; - - max_pwm_blc = psb_intel_lvds_get_max_backlight(dev); - - /*BLC_PWM_CTL Should be initiated while backlight device init*/ - BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0); - - blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL; - - if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE) - blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle; - - blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; - REG_WRITE(BLC_PWM_CTL, - (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | - (blc_pwm_duty_cycle)); - - return 0; -} - -/** - * Set LVDS backlight level either by I2C or PWM - */ -void psb_intel_lvds_set_brightness(struct drm_device *dev, int level) -{ - /*u32 blc_pwm_ctl;*/ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; - - DRM_DEBUG("backlight level is %d\n", level); - - if (!dev_priv->lvds_bl) { - DRM_ERROR("NO LVDS Backlight Info\n"); - return; - } - - if (dev_priv->lvds_bl->type == BLC_I2C_TYPE) - psb_lvds_i2c_set_brightness(dev, level); - else - psb_lvds_pwm_set_brightness(dev, level); -} - -/** - * Sets the backlight level. - * - * \param level backlight level, from 0 to psb_intel_lvds_get_max_backlight(). - */ -static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 blc_pwm_ctl; - - if (gma_power_begin(dev, false)) { - blc_pwm_ctl = - REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; - REG_WRITE(BLC_PWM_CTL, - (blc_pwm_ctl | - (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); - gma_power_end(dev); - } else { - blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL & - ~BACKLIGHT_DUTY_CYCLE_MASK; - dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl | - (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); - } -} - -/** - * Sets the power state for the panel. - */ -static void psb_intel_lvds_set_power(struct drm_device *dev, - struct psb_intel_output *output, bool on) -{ - u32 pp_status; - - if (!gma_power_begin(dev, true)) - return; - - if (on) { - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | - POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while ((pp_status & PP_ON) == 0); - - psb_intel_lvds_set_backlight(dev, - output-> - mode_dev->backlight_duty_cycle); - } else { - psb_intel_lvds_set_backlight(dev, 0); - - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & - ~POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while (pp_status & PP_ON); - } - - gma_power_end(dev); -} - -static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct psb_intel_output *output = enc_to_psb_intel_output(encoder); - - if (mode == DRM_MODE_DPMS_ON) - psb_intel_lvds_set_power(dev, output, true); - else - psb_intel_lvds_set_power(dev, output, false); - - /* XXX: We never power down the LVDS pairs. */ -} - -static void psb_intel_lvds_save(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - struct psb_intel_lvds_priv *lvds_priv = - (struct psb_intel_lvds_priv *)psb_intel_output->dev_priv; - - lvds_priv->savePP_ON = REG_READ(LVDSPP_ON); - lvds_priv->savePP_OFF = REG_READ(LVDSPP_OFF); - lvds_priv->saveLVDS = REG_READ(LVDS); - lvds_priv->savePP_CONTROL = REG_READ(PP_CONTROL); - lvds_priv->savePP_CYCLE = REG_READ(PP_CYCLE); - /*lvds_priv->savePP_DIVISOR = REG_READ(PP_DIVISOR);*/ - lvds_priv->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); - lvds_priv->savePFIT_CONTROL = REG_READ(PFIT_CONTROL); - lvds_priv->savePFIT_PGM_RATIOS = REG_READ(PFIT_PGM_RATIOS); - - /*TODO: move backlight_duty_cycle to psb_intel_lvds_priv*/ - dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL & - BACKLIGHT_DUTY_CYCLE_MASK); - - /* - * If the light is off at server startup, - * just make it full brightness - */ - if (dev_priv->backlight_duty_cycle == 0) - dev_priv->backlight_duty_cycle = - psb_intel_lvds_get_max_backlight(dev); - - DRM_DEBUG("(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", - lvds_priv->savePP_ON, - lvds_priv->savePP_OFF, - lvds_priv->saveLVDS, - lvds_priv->savePP_CONTROL, - lvds_priv->savePP_CYCLE, - lvds_priv->saveBLC_PWM_CTL); -} - -static void psb_intel_lvds_restore(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - u32 pp_status; - - /*struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private;*/ - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - struct psb_intel_lvds_priv *lvds_priv = - (struct psb_intel_lvds_priv *)psb_intel_output->dev_priv; - - DRM_DEBUG("(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", - lvds_priv->savePP_ON, - lvds_priv->savePP_OFF, - lvds_priv->saveLVDS, - lvds_priv->savePP_CONTROL, - lvds_priv->savePP_CYCLE, - lvds_priv->saveBLC_PWM_CTL); - - REG_WRITE(BLC_PWM_CTL, lvds_priv->saveBLC_PWM_CTL); - REG_WRITE(PFIT_CONTROL, lvds_priv->savePFIT_CONTROL); - REG_WRITE(PFIT_PGM_RATIOS, lvds_priv->savePFIT_PGM_RATIOS); - REG_WRITE(LVDSPP_ON, lvds_priv->savePP_ON); - REG_WRITE(LVDSPP_OFF, lvds_priv->savePP_OFF); - /*REG_WRITE(PP_DIVISOR, lvds_priv->savePP_DIVISOR);*/ - REG_WRITE(PP_CYCLE, lvds_priv->savePP_CYCLE); - REG_WRITE(PP_CONTROL, lvds_priv->savePP_CONTROL); - REG_WRITE(LVDS, lvds_priv->saveLVDS); - - if (lvds_priv->savePP_CONTROL & POWER_TARGET_ON) { - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | - POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while ((pp_status & PP_ON) == 0); - } else { - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & - ~POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while (pp_status & PP_ON); - } -} - -int psb_intel_lvds_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - struct drm_display_mode *fixed_mode = - psb_intel_output->mode_dev->panel_fixed_mode; - - PSB_DEBUG_ENTRY("\n"); - - if (psb_intel_output->type == INTEL_OUTPUT_MIPI2) - fixed_mode = psb_intel_output->mode_dev->panel_fixed_mode2; - - /* just in case */ - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - /* just in case */ - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - return MODE_NO_INTERLACE; - - if (fixed_mode) { - if (mode->hdisplay > fixed_mode->hdisplay) - return MODE_PANEL; - if (mode->vdisplay > fixed_mode->vdisplay) - return MODE_PANEL; - } - return MODE_OK; -} - -bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct psb_intel_mode_device *mode_dev = - enc_to_psb_intel_output(encoder)->mode_dev; - struct drm_device *dev = encoder->dev; - struct psb_intel_crtc *psb_intel_crtc = - to_psb_intel_crtc(encoder->crtc); - struct drm_encoder *tmp_encoder; - struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode; - struct psb_intel_output *psb_intel_output = - enc_to_psb_intel_output(encoder); - - PSB_DEBUG_ENTRY("type = 0x%x, pipe = %d.\n", - psb_intel_output->type, psb_intel_crtc->pipe); - - if (psb_intel_output->type == INTEL_OUTPUT_MIPI2) - panel_fixed_mode = mode_dev->panel_fixed_mode2; - - /* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */ - if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) { - printk(KERN_ERR "Can't support LVDS on pipe A\n"); - return false; - } - if (IS_MRST(dev) && psb_intel_crtc->pipe != 0) { - printk(KERN_ERR "Must use PIPE A\n"); - return false; - } - /* Should never happen!! */ - list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, - head) { - if (tmp_encoder != encoder - && tmp_encoder->crtc == encoder->crtc) { - printk(KERN_ERR "Can't enable LVDS and another " - "encoder on the same pipe\n"); - return false; - } - } - - /* - * If we have timings from the BIOS for the panel, put them in - * to the adjusted mode. The CRTC will be set up for this mode, - * with the panel scaling set up to source from the H/VDisplay - * of the original mode. - */ - if (panel_fixed_mode != NULL) { - adjusted_mode->hdisplay = panel_fixed_mode->hdisplay; - adjusted_mode->hsync_start = panel_fixed_mode->hsync_start; - adjusted_mode->hsync_end = panel_fixed_mode->hsync_end; - adjusted_mode->htotal = panel_fixed_mode->htotal; - adjusted_mode->vdisplay = panel_fixed_mode->vdisplay; - adjusted_mode->vsync_start = panel_fixed_mode->vsync_start; - adjusted_mode->vsync_end = panel_fixed_mode->vsync_end; - adjusted_mode->vtotal = panel_fixed_mode->vtotal; - adjusted_mode->clock = panel_fixed_mode->clock; - drm_mode_set_crtcinfo(adjusted_mode, - CRTC_INTERLACE_HALVE_V); - } - - /* - * XXX: It would be nice to support lower refresh rates on the - * panels to reduce power consumption, and perhaps match the - * user's requested refresh rate. - */ - - return true; -} - -void psb_intel_lvds_prepare(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct psb_intel_output *output = enc_to_psb_intel_output(encoder); - struct psb_intel_mode_device *mode_dev = output->mode_dev; - - PSB_DEBUG_ENTRY("\n"); - - if (!gma_power_begin(dev, true)) - return; - - mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); - mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL & - BACKLIGHT_DUTY_CYCLE_MASK); - - psb_intel_lvds_set_power(dev, output, false); - - gma_power_end(dev); -} - -void psb_intel_lvds_commit(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct psb_intel_output *output = enc_to_psb_intel_output(encoder); - struct psb_intel_mode_device *mode_dev = output->mode_dev; - - PSB_DEBUG_ENTRY("\n"); - - if (mode_dev->backlight_duty_cycle == 0) - mode_dev->backlight_duty_cycle = - psb_intel_lvds_get_max_backlight(dev); - - psb_intel_lvds_set_power(dev, output, true); -} - -static void psb_intel_lvds_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct psb_intel_mode_device *mode_dev = - enc_to_psb_intel_output(encoder)->mode_dev; - struct drm_device *dev = encoder->dev; - u32 pfit_control; - - /* - * The LVDS pin pair will already have been turned on in the - * psb_intel_crtc_mode_set since it has a large impact on the DPLL - * settings. - */ - - /* - * Enable automatic panel scaling so that non-native modes fill the - * screen. Should be enabled before the pipe is enabled, according to - * register description and PRM. - */ - if (mode->hdisplay != adjusted_mode->hdisplay || - mode->vdisplay != adjusted_mode->vdisplay) - pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | - HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - else - pfit_control = 0; - - if (mode_dev->panel_wants_dither) - pfit_control |= PANEL_8TO6_DITHER_ENABLE; - - REG_WRITE(PFIT_CONTROL, pfit_control); -} - -/** - * Detect the LVDS connection. - * - * This always returns CONNECTOR_STATUS_CONNECTED. - * This connector should only have - * been set up if the LVDS was actually connected anyway. - */ -static enum drm_connector_status psb_intel_lvds_detect(struct drm_connector - *connector, bool force) -{ - return connector_status_connected; -} - -/** - * Return the list of DDC modes if available, or the BIOS fixed mode otherwise. - */ -static int psb_intel_lvds_get_modes(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - struct psb_intel_mode_device *mode_dev = - psb_intel_output->mode_dev; - int ret = 0; - - ret = psb_intel_ddc_get_modes(psb_intel_output); - - if (ret) - return ret; - - /* Didn't get an EDID, so - * Set wide sync ranges so we get all modes - * handed to valid_mode for checking - */ - connector->display_info.min_vfreq = 0; - connector->display_info.max_vfreq = 200; - connector->display_info.min_hfreq = 0; - connector->display_info.max_hfreq = 200; - - if (mode_dev->panel_fixed_mode != NULL) { - struct drm_display_mode *mode = - drm_mode_duplicate(dev, mode_dev->panel_fixed_mode); - drm_mode_probed_add(connector, mode); - return 1; - } - - return 0; -} - -/** - * psb_intel_lvds_destroy - unregister and free LVDS structures - * @connector: connector to free - * - * Unregister the DDC bus for this connector then free the driver private - * structure. - */ -void psb_intel_lvds_destroy(struct drm_connector *connector) -{ - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - - if (psb_intel_output->ddc_bus) - psb_intel_i2c_destroy(psb_intel_output->ddc_bus); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -int psb_intel_lvds_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t value) -{ - struct drm_encoder *pEncoder = connector->encoder; - - PSB_DEBUG_ENTRY("\n"); - - if (!strcmp(property->name, "scaling mode") && pEncoder) { - struct psb_intel_crtc *pPsbCrtc = - to_psb_intel_crtc(pEncoder->crtc); - uint64_t curValue; - - PSB_DEBUG_ENTRY("scaling mode\n"); - - if (!pPsbCrtc) - goto set_prop_error; - - switch (value) { - case DRM_MODE_SCALE_FULLSCREEN: - break; - case DRM_MODE_SCALE_NO_SCALE: - break; - case DRM_MODE_SCALE_ASPECT: - break; - default: - goto set_prop_error; - } - - if (drm_connector_property_get_value(connector, - property, - &curValue)) - goto set_prop_error; - - if (curValue == value) - goto set_prop_done; - - if (drm_connector_property_set_value(connector, - property, - value)) - goto set_prop_error; - - if (pPsbCrtc->saved_mode.hdisplay != 0 && - pPsbCrtc->saved_mode.vdisplay != 0) { - if (!drm_crtc_helper_set_mode(pEncoder->crtc, - &pPsbCrtc->saved_mode, - pEncoder->crtc->x, - pEncoder->crtc->y, - pEncoder->crtc->fb)) - goto set_prop_error; - } - } else if (!strcmp(property->name, "backlight") && pEncoder) { - PSB_DEBUG_ENTRY("backlight\n"); - - if (drm_connector_property_set_value(connector, - property, - value)) - goto set_prop_error; - else { -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - struct backlight_device bd; - bd.props.brightness = value; - psb_set_brightness(&bd); -#endif - } - } else if (!strcmp(property->name, "DPMS") && pEncoder) { - struct drm_encoder_helper_funcs *pEncHFuncs - = pEncoder->helper_private; - PSB_DEBUG_ENTRY("DPMS\n"); - pEncHFuncs->dpms(pEncoder, value); - } - -set_prop_done: - return 0; -set_prop_error: - return -1; -} - -static const struct drm_encoder_helper_funcs psb_intel_lvds_helper_funcs = { - .dpms = psb_intel_lvds_encoder_dpms, - .mode_fixup = psb_intel_lvds_mode_fixup, - .prepare = psb_intel_lvds_prepare, - .mode_set = psb_intel_lvds_mode_set, - .commit = psb_intel_lvds_commit, -}; - -const struct drm_connector_helper_funcs - psb_intel_lvds_connector_helper_funcs = { - .get_modes = psb_intel_lvds_get_modes, - .mode_valid = psb_intel_lvds_mode_valid, - .best_encoder = psb_intel_best_encoder, -}; - -const struct drm_connector_funcs psb_intel_lvds_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .save = psb_intel_lvds_save, - .restore = psb_intel_lvds_restore, - .detect = psb_intel_lvds_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = psb_intel_lvds_set_property, - .destroy = psb_intel_lvds_destroy, -}; - - -static void psb_intel_lvds_enc_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); -} - -const struct drm_encoder_funcs psb_intel_lvds_enc_funcs = { - .destroy = psb_intel_lvds_enc_destroy, -}; - - - -/** - * psb_intel_lvds_init - setup LVDS connectors on this device - * @dev: drm device - * - * Create the connector, register the LVDS DDC bus, and try to figure out what - * modes we can display on the LVDS panel (if present). - */ -void psb_intel_lvds_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev) -{ - struct psb_intel_output *psb_intel_output; - struct psb_intel_lvds_priv *lvds_priv; - struct drm_connector *connector; - struct drm_encoder *encoder; - struct drm_display_mode *scan; /* *modes, *bios_mode; */ - struct drm_crtc *crtc; - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; - u32 lvds; - int pipe; - - psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL); - if (!psb_intel_output) - return; - - lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL); - if (!lvds_priv) { - kfree(psb_intel_output); - DRM_DEBUG("LVDS private allocation error\n"); - return; - } - - psb_intel_output->dev_priv = lvds_priv; - - psb_intel_output->mode_dev = mode_dev; - connector = &psb_intel_output->base; - encoder = &psb_intel_output->enc; - drm_connector_init(dev, &psb_intel_output->base, - &psb_intel_lvds_connector_funcs, - DRM_MODE_CONNECTOR_LVDS); - - drm_encoder_init(dev, &psb_intel_output->enc, - &psb_intel_lvds_enc_funcs, - DRM_MODE_ENCODER_LVDS); - - drm_mode_connector_attach_encoder(&psb_intel_output->base, - &psb_intel_output->enc); - psb_intel_output->type = INTEL_OUTPUT_LVDS; - - drm_encoder_helper_add(encoder, &psb_intel_lvds_helper_funcs); - drm_connector_helper_add(connector, - &psb_intel_lvds_connector_helper_funcs); - connector->display_info.subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - - /*Attach connector properties*/ - drm_connector_attach_property(connector, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_FULLSCREEN); - drm_connector_attach_property(connector, - dev_priv->backlight_property, - BRIGHTNESS_MAX_LEVEL); - - /** - * Set up I2C bus - * FIXME: distroy i2c_bus when exit - */ - psb_intel_output->i2c_bus = psb_intel_i2c_create(dev, - GPIOB, - "LVDSBLC_B"); - if (!psb_intel_output->i2c_bus) { - dev_printk(KERN_ERR, - &dev->pdev->dev, "I2C bus registration failed.\n"); - goto failed_blc_i2c; - } - psb_intel_output->i2c_bus->slave_addr = 0x2C; - dev_priv->lvds_i2c_bus = psb_intel_output->i2c_bus; - - /* - * LVDS discovery: - * 1) check for EDID on DDC - * 2) check for VBT data - * 3) check to see if LVDS is already on - * if none of the above, no panel - * 4) make sure lid is open - * if closed, act like it's not there for now - */ - - /* Set up the DDC bus. */ - psb_intel_output->ddc_bus = psb_intel_i2c_create(dev, - GPIOC, - "LVDSDDC_C"); - if (!psb_intel_output->ddc_bus) { - dev_printk(KERN_ERR, &dev->pdev->dev, - "DDC bus registration " "failed.\n"); - goto failed_ddc; - } - - /* - * Attempt to get the fixed panel mode from DDC. Assume that the - * preferred mode is the right one. - */ - psb_intel_ddc_get_modes(psb_intel_output); - list_for_each_entry(scan, &connector->probed_modes, head) { - if (scan->type & DRM_MODE_TYPE_PREFERRED) { - mode_dev->panel_fixed_mode = - drm_mode_duplicate(dev, scan); - goto out; /* FIXME: check for quirks */ - } - } - - /* Failed to get EDID, what about VBT? do we need this?*/ - if (mode_dev->vbt_mode) - mode_dev->panel_fixed_mode = - drm_mode_duplicate(dev, mode_dev->vbt_mode); - - if (!mode_dev->panel_fixed_mode) - if (dev_priv->lfp_lvds_vbt_mode) - mode_dev->panel_fixed_mode = - drm_mode_duplicate(dev, - dev_priv->lfp_lvds_vbt_mode); - - /* - * If we didn't get EDID, try checking if the panel is already turned - * on. If so, assume that whatever is currently programmed is the - * correct mode. - */ - lvds = REG_READ(LVDS); - pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; - crtc = psb_intel_get_crtc_from_pipe(dev, pipe); - - if (crtc && (lvds & LVDS_PORT_EN)) { - mode_dev->panel_fixed_mode = - psb_intel_crtc_mode_get(dev, crtc); - if (mode_dev->panel_fixed_mode) { - mode_dev->panel_fixed_mode->type |= - DRM_MODE_TYPE_PREFERRED; - goto out; /* FIXME: check for quirks */ - } - } - - /* If we still don't have a mode after all that, give up. */ - if (!mode_dev->panel_fixed_mode) { - DRM_DEBUG - ("Found no modes on the lvds, ignoring the LVDS\n"); - goto failed_find; - } - - /* - * Blacklist machines with BIOSes that list an LVDS panel without - * actually having one. - */ -out: - drm_sysfs_connector_add(connector); - - PSB_DEBUG_ENTRY("hdisplay = %d\n", - mode_dev->panel_fixed_mode->hdisplay); - PSB_DEBUG_ENTRY(" vdisplay = %d\n", - mode_dev->panel_fixed_mode->vdisplay); - PSB_DEBUG_ENTRY(" hsync_start = %d\n", - mode_dev->panel_fixed_mode->hsync_start); - PSB_DEBUG_ENTRY(" hsync_end = %d\n", - mode_dev->panel_fixed_mode->hsync_end); - PSB_DEBUG_ENTRY(" htotal = %d\n", - mode_dev->panel_fixed_mode->htotal); - PSB_DEBUG_ENTRY(" vsync_start = %d\n", - mode_dev->panel_fixed_mode->vsync_start); - PSB_DEBUG_ENTRY(" vsync_end = %d\n", - mode_dev->panel_fixed_mode->vsync_end); - PSB_DEBUG_ENTRY(" vtotal = %d\n", - mode_dev->panel_fixed_mode->vtotal); - PSB_DEBUG_ENTRY(" clock = %d\n", - mode_dev->panel_fixed_mode->clock); - - return; - -failed_find: - if (psb_intel_output->ddc_bus) - psb_intel_i2c_destroy(psb_intel_output->ddc_bus); -failed_ddc: - if (psb_intel_output->i2c_bus) - psb_intel_i2c_destroy(psb_intel_output->i2c_bus); -failed_blc_i2c: - drm_encoder_cleanup(encoder); - drm_connector_cleanup(connector); - kfree(connector); -} - diff --git a/drivers/staging/gma500/psb_intel_modes.c b/drivers/staging/gma500/psb_intel_modes.c deleted file mode 100644 index bde1aff9619..00000000000 --- a/drivers/staging/gma500/psb_intel_modes.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2007 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authers: Jesse Barnes <jesse.barnes@intel.com> - */ - -#include <linux/i2c.h> -#include <linux/fb.h> -#include <drm/drmP.h> -#include "psb_intel_drv.h" - -/** - * psb_intel_ddc_probe - * - */ -bool psb_intel_ddc_probe(struct psb_intel_output *psb_intel_output) -{ - u8 out_buf[] = { 0x0, 0x0 }; - u8 buf[2]; - int ret; - struct i2c_msg msgs[] = { - { - .addr = 0x50, - .flags = 0, - .len = 1, - .buf = out_buf, - }, - { - .addr = 0x50, - .flags = I2C_M_RD, - .len = 1, - .buf = buf, - } - }; - - ret = i2c_transfer(&psb_intel_output->ddc_bus->adapter, msgs, 2); - if (ret == 2) - return true; - - return false; -} - -/** - * psb_intel_ddc_get_modes - get modelist from monitor - * @connector: DRM connector device to use - * - * Fetch the EDID information from @connector using the DDC bus. - */ -int psb_intel_ddc_get_modes(struct psb_intel_output *psb_intel_output) -{ - struct edid *edid; - int ret = 0; - - edid = - drm_get_edid(&psb_intel_output->base, - &psb_intel_output->ddc_bus->adapter); - if (edid) { - drm_mode_connector_update_edid_property(&psb_intel_output-> - base, edid); - ret = drm_add_edid_modes(&psb_intel_output->base, edid); - kfree(edid); - } - return ret; -} diff --git a/drivers/staging/gma500/psb_intel_opregion.c b/drivers/staging/gma500/psb_intel_opregion.c deleted file mode 100644 index 65e3e9b8dc1..00000000000 --- a/drivers/staging/gma500/psb_intel_opregion.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "psb_drv.h" - -struct opregion_header { - u8 signature[16]; - u32 size; - u32 opregion_ver; - u8 bios_ver[32]; - u8 vbios_ver[16]; - u8 driver_ver[16]; - u32 mboxes; - u8 reserved[164]; -} __attribute__((packed)); - -struct opregion_apci { - /*FIXME: add it later*/ -} __attribute__((packed)); - -struct opregion_swsci { - /*FIXME: add it later*/ -} __attribute__((packed)); - -struct opregion_acpi { - /*FIXME: add it later*/ -} __attribute__((packed)); - -int psb_intel_opregion_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - /*struct psb_intel_opregion * opregion = &dev_priv->opregion;*/ - u32 opregion_phy; - void *base; - u32 *lid_state; - - dev_priv->lid_state = NULL; - - pci_read_config_dword(dev->pdev, 0xfc, &opregion_phy); - if (opregion_phy == 0) { - DRM_DEBUG("Opregion not supported, won't support lid-switch\n"); - return -ENOTSUPP; - } - DRM_DEBUG("OpRegion detected at 0x%8x\n", opregion_phy); - - base = ioremap(opregion_phy, 8*1024); - if (!base) - return -ENOMEM; - - lid_state = base + 0x01ac; - - DRM_DEBUG("Lid switch state 0x%08x\n", *lid_state); - - dev_priv->lid_state = lid_state; - dev_priv->lid_last_state = *lid_state; - return 0; -} diff --git a/drivers/staging/gma500/psb_intel_reg.h b/drivers/staging/gma500/psb_intel_reg.h deleted file mode 100644 index 1c283140bcc..00000000000 --- a/drivers/staging/gma500/psb_intel_reg.h +++ /dev/null @@ -1,1137 +0,0 @@ -/* - * Copyright (c) 2009, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef __PSB_INTEL_REG_H__ -#define __PSB_INTEL_REG_H__ - -#define BLC_PWM_CTL 0x61254 -#define BLC_PWM_CTL2 0x61250 -#define BLC_PWM_CTL_C 0x62254 -#define BLC_PWM_CTL2_C 0x62250 -#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) -/* - * This is the most significant 15 bits of the number of backlight cycles in a - * complete cycle of the modulated backlight control. - * - * The actual value is this field multiplied by two. - */ -#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) -#define BLM_LEGACY_MODE (1 << 16) -/* - * This is the number of cycles out of the backlight modulation cycle for which - * the backlight is on. - * - * This field must be no greater than the number of cycles in the complete - * backlight modulation cycle. - */ -#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) -#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) - -#define I915_GCFGC 0xf0 -#define I915_LOW_FREQUENCY_ENABLE (1 << 7) -#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) -#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) -#define I915_DISPLAY_CLOCK_MASK (7 << 4) - -#define I855_HPLLCC 0xc0 -#define I855_CLOCK_CONTROL_MASK (3 << 0) -#define I855_CLOCK_133_200 (0 << 0) -#define I855_CLOCK_100_200 (1 << 0) -#define I855_CLOCK_100_133 (2 << 0) -#define I855_CLOCK_166_250 (3 << 0) - -/* I830 CRTC registers */ -#define HTOTAL_A 0x60000 -#define HBLANK_A 0x60004 -#define HSYNC_A 0x60008 -#define VTOTAL_A 0x6000c -#define VBLANK_A 0x60010 -#define VSYNC_A 0x60014 -#define PIPEASRC 0x6001c -#define BCLRPAT_A 0x60020 -#define VSYNCSHIFT_A 0x60028 - -#define HTOTAL_B 0x61000 -#define HBLANK_B 0x61004 -#define HSYNC_B 0x61008 -#define VTOTAL_B 0x6100c -#define VBLANK_B 0x61010 -#define VSYNC_B 0x61014 -#define PIPEBSRC 0x6101c -#define BCLRPAT_B 0x61020 -#define VSYNCSHIFT_B 0x61028 - -#define HTOTAL_C 0x62000 -#define HBLANK_C 0x62004 -#define HSYNC_C 0x62008 -#define VTOTAL_C 0x6200c -#define VBLANK_C 0x62010 -#define VSYNC_C 0x62014 -#define PIPECSRC 0x6201c -#define BCLRPAT_C 0x62020 -#define VSYNCSHIFT_C 0x62028 - -#define PP_STATUS 0x61200 -# define PP_ON (1 << 31) -/* - * Indicates that all dependencies of the panel are on: - * - * - PLL enabled - * - pipe enabled - * - LVDS/DVOB/DVOC on - */ -# define PP_READY (1 << 30) -# define PP_SEQUENCE_NONE (0 << 28) -# define PP_SEQUENCE_ON (1 << 28) -# define PP_SEQUENCE_OFF (2 << 28) -# define PP_SEQUENCE_MASK 0x30000000 -#define PP_CONTROL 0x61204 -# define POWER_TARGET_ON (1 << 0) - -#define LVDSPP_ON 0x61208 -#define LVDSPP_OFF 0x6120c -#define PP_CYCLE 0x61210 - -#define PFIT_CONTROL 0x61230 -# define PFIT_ENABLE (1 << 31) -# define PFIT_PIPE_MASK (3 << 29) -# define PFIT_PIPE_SHIFT 29 -# define PFIT_SCALING_MODE_PILLARBOX (1 << 27) -# define PFIT_SCALING_MODE_LETTERBOX (3 << 26) -# define VERT_INTERP_DISABLE (0 << 10) -# define VERT_INTERP_BILINEAR (1 << 10) -# define VERT_INTERP_MASK (3 << 10) -# define VERT_AUTO_SCALE (1 << 9) -# define HORIZ_INTERP_DISABLE (0 << 6) -# define HORIZ_INTERP_BILINEAR (1 << 6) -# define HORIZ_INTERP_MASK (3 << 6) -# define HORIZ_AUTO_SCALE (1 << 5) -# define PANEL_8TO6_DITHER_ENABLE (1 << 3) - -#define PFIT_PGM_RATIOS 0x61234 -# define PFIT_VERT_SCALE_MASK 0xfff00000 -# define PFIT_HORIZ_SCALE_MASK 0x0000fff0 - -#define PFIT_AUTO_RATIOS 0x61238 - - -#define DPLL_A 0x06014 -#define DPLL_B 0x06018 -# define DPLL_VCO_ENABLE (1 << 31) -# define DPLL_DVO_HIGH_SPEED (1 << 30) -# define DPLL_SYNCLOCK_ENABLE (1 << 29) -# define DPLL_VGA_MODE_DIS (1 << 28) -# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ -# define DPLLB_MODE_LVDS (2 << 26) /* i915 */ -# define DPLL_MODE_MASK (3 << 26) -# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ -# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ -# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ -# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ -# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ -# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ -/* - * The i830 generation, in DAC/serial mode, defines p1 as two plus this - * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. - */ -# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 -/* - * The i830 generation, in LVDS mode, defines P1 as the bit number set within - * this field (only one bit may be set). - */ -# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 -# define DPLL_FPA01_P1_POST_DIV_SHIFT 16 -# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required - * in DVO non-gang */ -# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ -# define PLL_REF_INPUT_DREFCLK (0 << 13) -# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ -# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO - * TVCLKIN */ -# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) -# define PLL_REF_INPUT_MASK (3 << 13) -# define PLL_LOAD_PULSE_PHASE_SHIFT 9 -/* - * Parallel to Serial Load Pulse phase selection. - * Selects the phase for the 10X DPLL clock for the PCIe - * digital display port. The range is 4 to 13; 10 or more - * is just a flip delay. The default is 6 - */ -# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) -# define DISPLAY_RATE_SELECT_FPA1 (1 << 8) - -/* - * SDVO multiplier for 945G/GM. Not used on 965. - * - * DPLL_MD_UDI_MULTIPLIER_MASK - */ -# define SDVO_MULTIPLIER_MASK 0x000000ff -# define SDVO_MULTIPLIER_SHIFT_HIRES 4 -# define SDVO_MULTIPLIER_SHIFT_VGA 0 - -/* - * PLL_MD - */ -/* Pipe A SDVO/UDI clock multiplier/divider register for G965. */ -#define DPLL_A_MD 0x0601c -/* Pipe B SDVO/UDI clock multiplier/divider register for G965. */ -#define DPLL_B_MD 0x06020 -/* - * UDI pixel divider, controlling how many pixels are stuffed into a packet. - * - * Value is pixels minus 1. Must be set to 1 pixel for SDVO. - */ -# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 -# define DPLL_MD_UDI_DIVIDER_SHIFT 24 -/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ -# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 -# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 -/* - * SDVO/UDI pixel multiplier. - * - * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus - * clock rate is 10 times the DPLL clock. At low resolution/refresh rate - * modes, the bus rate would be below the limits, so SDVO allows for stuffing - * dummy bytes in the datastream at an increased clock rate, with both sides of - * the link knowing how many bytes are fill. - * - * So, for a mode with a dotclock of 65Mhz, we would want to double the clock - * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be - * set to 130Mhz, and the SDVO multiplier set to 2x in this register and - * through an SDVO command. - * - * This register field has values of multiplication factor minus 1, with - * a maximum multiplier of 5 for SDVO. - */ -# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 -# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 -/* - * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. - * This best be set to the default value (3) or the CRT won't work. No, - * I don't entirely understand what this does... - */ -# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f -# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 - -#define DPLL_TEST 0x606c -# define DPLLB_TEST_SDVO_DIV_1 (0 << 22) -# define DPLLB_TEST_SDVO_DIV_2 (1 << 22) -# define DPLLB_TEST_SDVO_DIV_4 (2 << 22) -# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) -# define DPLLB_TEST_N_BYPASS (1 << 19) -# define DPLLB_TEST_M_BYPASS (1 << 18) -# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) -# define DPLLA_TEST_N_BYPASS (1 << 3) -# define DPLLA_TEST_M_BYPASS (1 << 2) -# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) - -#define ADPA 0x61100 -#define ADPA_DAC_ENABLE (1<<31) -#define ADPA_DAC_DISABLE 0 -#define ADPA_PIPE_SELECT_MASK (1<<30) -#define ADPA_PIPE_A_SELECT 0 -#define ADPA_PIPE_B_SELECT (1<<30) -#define ADPA_USE_VGA_HVPOLARITY (1<<15) -#define ADPA_SETS_HVPOLARITY 0 -#define ADPA_VSYNC_CNTL_DISABLE (1<<11) -#define ADPA_VSYNC_CNTL_ENABLE 0 -#define ADPA_HSYNC_CNTL_DISABLE (1<<10) -#define ADPA_HSYNC_CNTL_ENABLE 0 -#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) -#define ADPA_VSYNC_ACTIVE_LOW 0 -#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) -#define ADPA_HSYNC_ACTIVE_LOW 0 - -#define FPA0 0x06040 -#define FPA1 0x06044 -#define FPB0 0x06048 -#define FPB1 0x0604c -# define FP_N_DIV_MASK 0x003f0000 -# define FP_N_DIV_SHIFT 16 -# define FP_M1_DIV_MASK 0x00003f00 -# define FP_M1_DIV_SHIFT 8 -# define FP_M2_DIV_MASK 0x0000003f -# define FP_M2_DIV_SHIFT 0 - - -#define PORT_HOTPLUG_EN 0x61110 -# define SDVOB_HOTPLUG_INT_EN (1 << 26) -# define SDVOC_HOTPLUG_INT_EN (1 << 25) -# define TV_HOTPLUG_INT_EN (1 << 18) -# define CRT_HOTPLUG_INT_EN (1 << 9) -# define CRT_HOTPLUG_FORCE_DETECT (1 << 3) - -#define PORT_HOTPLUG_STAT 0x61114 -# define CRT_HOTPLUG_INT_STATUS (1 << 11) -# define TV_HOTPLUG_INT_STATUS (1 << 10) -# define CRT_HOTPLUG_MONITOR_MASK (3 << 8) -# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) -# define CRT_HOTPLUG_MONITOR_MONO (2 << 8) -# define CRT_HOTPLUG_MONITOR_NONE (0 << 8) -# define SDVOC_HOTPLUG_INT_STATUS (1 << 7) -# define SDVOB_HOTPLUG_INT_STATUS (1 << 6) - -#define SDVOB 0x61140 -#define SDVOC 0x61160 -#define SDVO_ENABLE (1 << 31) -#define SDVO_PIPE_B_SELECT (1 << 30) -#define SDVO_STALL_SELECT (1 << 29) -#define SDVO_INTERRUPT_ENABLE (1 << 26) -/** - * 915G/GM SDVO pixel multiplier. - * - * Programmed value is multiplier - 1, up to 5x. - * - * DPLL_MD_UDI_MULTIPLIER_MASK - */ -#define SDVO_PORT_MULTIPLY_MASK (7 << 23) -#define SDVO_PORT_MULTIPLY_SHIFT 23 -#define SDVO_PHASE_SELECT_MASK (15 << 19) -#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) -#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) -#define SDVOC_GANG_MODE (1 << 16) -#define SDVO_BORDER_ENABLE (1 << 7) -#define SDVOB_PCIE_CONCURRENCY (1 << 3) -#define SDVO_DETECTED (1 << 2) -/* Bits to be preserved when writing */ -#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14)) -#define SDVOC_PRESERVE_MASK (1 << 17) - -/* - * This register controls the LVDS output enable, pipe selection, and data - * format selection. - * - * All of the clock/data pairs are force powered down by power sequencing. - */ -#define LVDS 0x61180 -/* - * Enables the LVDS port. This bit must be set before DPLLs are enabled, as - * the DPLL semantics change when the LVDS is assigned to that pipe. - */ -# define LVDS_PORT_EN (1 << 31) -/* Selects pipe B for LVDS data. Must be set on pre-965. */ -# define LVDS_PIPEB_SELECT (1 << 30) - -/* Turns on border drawing to allow centered display. */ -# define LVDS_BORDER_EN (1 << 15) - -/* - * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per - * pixel. - */ -# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) -# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) -# define LVDS_A0A2_CLKA_POWER_UP (3 << 8) -/* - * Controls the A3 data pair, which contains the additional LSBs for 24 bit - * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be - * on. - */ -# define LVDS_A3_POWER_MASK (3 << 6) -# define LVDS_A3_POWER_DOWN (0 << 6) -# define LVDS_A3_POWER_UP (3 << 6) -/* - * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP - * is set. - */ -# define LVDS_CLKB_POWER_MASK (3 << 4) -# define LVDS_CLKB_POWER_DOWN (0 << 4) -# define LVDS_CLKB_POWER_UP (3 << 4) -/* - * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 - * setting for whether we are in dual-channel mode. The B3 pair will - * additionally only be powered up when LVDS_A3_POWER_UP is set. - */ -# define LVDS_B0B3_POWER_MASK (3 << 2) -# define LVDS_B0B3_POWER_DOWN (0 << 2) -# define LVDS_B0B3_POWER_UP (3 << 2) - -#define PIPEACONF 0x70008 -#define PIPEACONF_ENABLE (1<<31) -#define PIPEACONF_DISABLE 0 -#define PIPEACONF_DOUBLE_WIDE (1<<30) -#define PIPECONF_ACTIVE (1<<30) -#define I965_PIPECONF_ACTIVE (1<<30) -#define PIPECONF_DSIPLL_LOCK (1<<29) -#define PIPEACONF_SINGLE_WIDE 0 -#define PIPEACONF_PIPE_UNLOCKED 0 -#define PIPEACONF_DSR (1<<26) -#define PIPEACONF_PIPE_LOCKED (1<<25) -#define PIPEACONF_PALETTE 0 -#define PIPECONF_FORCE_BORDER (1<<25) -#define PIPEACONF_GAMMA (1<<24) -#define PIPECONF_PROGRESSIVE (0 << 21) -#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) -#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) -#define PIPECONF_PLANE_OFF (1<<19) -#define PIPECONF_CURSOR_OFF (1<<18) - - -#define PIPEBCONF 0x71008 -#define PIPEBCONF_ENABLE (1<<31) -#define PIPEBCONF_DISABLE 0 -#define PIPEBCONF_DOUBLE_WIDE (1<<30) -#define PIPEBCONF_DISABLE 0 -#define PIPEBCONF_GAMMA (1<<24) -#define PIPEBCONF_PALETTE 0 - -#define PIPECCONF 0x72008 - -#define PIPEBGCMAXRED 0x71010 -#define PIPEBGCMAXGREEN 0x71014 -#define PIPEBGCMAXBLUE 0x71018 - -#define PIPEASTAT 0x70024 -#define PIPEBSTAT 0x71024 -#define PIPECSTAT 0x72024 -#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) -#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) -#define PIPE_VBLANK_CLEAR (1 << 1) -#define PIPE_VBLANK_STATUS (1 << 1) -#define PIPE_TE_STATUS (1UL<<6) -#define PIPE_DPST_EVENT_STATUS (1UL<<7) -#define PIPE_VSYNC_CLEAR (1UL<<9) -#define PIPE_VSYNC_STATUS (1UL<<9) -#define PIPE_HDMI_AUDIO_UNDERRUN_STATUS (1UL<<10) -#define PIPE_HDMI_AUDIO_BUFFER_DONE_STATUS (1UL<<11) -#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17) -#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) -#define PIPE_TE_ENABLE (1UL<<22) -#define PIPE_DPST_EVENT_ENABLE (1UL<<23) -#define PIPE_VSYNC_ENABL (1UL<<25) -#define PIPE_HDMI_AUDIO_UNDERRUN (1UL<<26) -#define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL<<27) -#define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | PIPE_HDMI_AUDIO_BUFFER_DONE) -#define PIPE_EVENT_MASK ((1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)|(1 << 22)|(1 << 21)|(1 << 20)|(1 << 16)) -#define PIPE_VBLANK_MASK ((1 << 25)|(1 << 24)|(1 << 18)|(1 << 17)) -#define HISTOGRAM_INT_CONTROL 0x61268 -#define HISTOGRAM_BIN_DATA 0X61264 -#define HISTOGRAM_LOGIC_CONTROL 0x61260 -#define PWM_CONTROL_LOGIC 0x61250 -#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10) -#define HISTOGRAM_INTERRUPT_ENABLE (1UL<<31) -#define HISTOGRAM_LOGIC_ENABLE (1UL<<31) -#define PWM_LOGIC_ENABLE (1UL<<31) -#define PWM_PHASEIN_ENABLE (1UL<<25) -#define PWM_PHASEIN_INT_ENABLE (1UL<<24) -#define PWM_PHASEIN_VB_COUNT 0x00001f00 -#define PWM_PHASEIN_INC 0x0000001f -#define HISTOGRAM_INT_CTRL_CLEAR (1UL<<30) -#define DPST_YUV_LUMA_MODE 0 - -struct dpst_ie_histogram_control { - union { - uint32_t data; - struct { - uint32_t bin_reg_index:7; - uint32_t reserved:4; - uint32_t bin_reg_func_select:1; - uint32_t sync_to_phase_in:1; - uint32_t alt_enhancement_mode:2; - uint32_t reserved1:1; - uint32_t sync_to_phase_in_count:8; - uint32_t histogram_mode_select:1; - uint32_t reserved2:4; - uint32_t ie_pipe_assignment:1; - uint32_t ie_mode_table_enabled:1; - uint32_t ie_histogram_enable:1; - }; - }; -}; - -struct dpst_guardband { - union { - uint32_t data; - struct { - uint32_t guardband:22; - uint32_t guardband_interrupt_delay:8; - uint32_t interrupt_status:1; - uint32_t interrupt_enable:1; - }; - }; -}; - -#define PIPEAFRAMEHIGH 0x70040 -#define PIPEAFRAMEPIXEL 0x70044 -#define PIPEBFRAMEHIGH 0x71040 -#define PIPEBFRAMEPIXEL 0x71044 -#define PIPECFRAMEHIGH 0x72040 -#define PIPECFRAMEPIXEL 0x72044 -#define PIPE_FRAME_HIGH_MASK 0x0000ffff -#define PIPE_FRAME_HIGH_SHIFT 0 -#define PIPE_FRAME_LOW_MASK 0xff000000 -#define PIPE_FRAME_LOW_SHIFT 24 -#define PIPE_PIXEL_MASK 0x00ffffff -#define PIPE_PIXEL_SHIFT 0 - -#define DSPARB 0x70030 -#define DSPFW1 0x70034 -#define DSPFW2 0x70038 -#define DSPFW3 0x7003c -#define DSPFW4 0x70050 -#define DSPFW5 0x70054 -#define DSPFW6 0x70058 -#define DSPCHICKENBIT 0x70400 -#define DSPACNTR 0x70180 -#define DSPBCNTR 0x71180 -#define DSPCCNTR 0x72180 -#define DISPLAY_PLANE_ENABLE (1<<31) -#define DISPLAY_PLANE_DISABLE 0 -#define DISPPLANE_GAMMA_ENABLE (1<<30) -#define DISPPLANE_GAMMA_DISABLE 0 -#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) -#define DISPPLANE_8BPP (0x2<<26) -#define DISPPLANE_15_16BPP (0x4<<26) -#define DISPPLANE_16BPP (0x5<<26) -#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) -#define DISPPLANE_32BPP (0x7<<26) -#define DISPPLANE_STEREO_ENABLE (1<<25) -#define DISPPLANE_STEREO_DISABLE 0 -#define DISPPLANE_SEL_PIPE_MASK (1<<24) -#define DISPPLANE_SEL_PIPE_POS 24 -#define DISPPLANE_SEL_PIPE_A 0 -#define DISPPLANE_SEL_PIPE_B (1<<24) -#define DISPPLANE_SRC_KEY_ENABLE (1<<22) -#define DISPPLANE_SRC_KEY_DISABLE 0 -#define DISPPLANE_LINE_DOUBLE (1<<20) -#define DISPPLANE_NO_LINE_DOUBLE 0 -#define DISPPLANE_STEREO_POLARITY_FIRST 0 -#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) -/* plane B only */ -#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) -#define DISPPLANE_ALPHA_TRANS_DISABLE 0 -#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 -#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) -#define DISPPLANE_BOTTOM (4) - -#define DSPABASE 0x70184 -#define DSPALINOFF 0x70184 -#define DSPASTRIDE 0x70188 - -#define DSPBBASE 0x71184 -#define DSPBLINOFF 0X71184 -#define DSPBADDR DSPBBASE -#define DSPBSTRIDE 0x71188 - -#define DSPCBASE 0x72184 -#define DSPCLINOFF 0x72184 -#define DSPCSTRIDE 0x72188 - -#define DSPAKEYVAL 0x70194 -#define DSPAKEYMASK 0x70198 - -#define DSPAPOS 0x7018C /* reserved */ -#define DSPASIZE 0x70190 -#define DSPBPOS 0x7118C -#define DSPBSIZE 0x71190 -#define DSPCPOS 0x7218C -#define DSPCSIZE 0x72190 - -#define DSPASURF 0x7019C -#define DSPATILEOFF 0x701A4 - -#define DSPBSURF 0x7119C -#define DSPBTILEOFF 0x711A4 - -#define DSPCSURF 0x7219C -#define DSPCTILEOFF 0x721A4 -#define DSPCKEYMAXVAL 0x721A0 -#define DSPCKEYMINVAL 0x72194 -#define DSPCKEYMSK 0x72198 - -#define VGACNTRL 0x71400 -# define VGA_DISP_DISABLE (1 << 31) -# define VGA_2X_MODE (1 << 30) -# define VGA_PIPE_B_SELECT (1 << 29) - -/* - * Overlay registers - */ -#define OV_C_OFFSET 0x08000 -#define OV_OVADD 0x30000 -#define OV_DOVASTA 0x30008 -# define OV_PIPE_SELECT ((1 << 6)|(1 << 7)) -# define OV_PIPE_SELECT_POS 6 -# define OV_PIPE_A 0 -# define OV_PIPE_C 1 -#define OV_OGAMC5 0x30010 -#define OV_OGAMC4 0x30014 -#define OV_OGAMC3 0x30018 -#define OV_OGAMC2 0x3001C -#define OV_OGAMC1 0x30020 -#define OV_OGAMC0 0x30024 -#define OVC_OVADD 0x38000 -#define OVC_DOVCSTA 0x38008 -#define OVC_OGAMC5 0x38010 -#define OVC_OGAMC4 0x38014 -#define OVC_OGAMC3 0x38018 -#define OVC_OGAMC2 0x3801C -#define OVC_OGAMC1 0x38020 -#define OVC_OGAMC0 0x38024 - -/* - * Some BIOS scratch area registers. The 845 (and 830?) store the amount - * of video memory available to the BIOS in SWF1. - */ -#define SWF0 0x71410 -#define SWF1 0x71414 -#define SWF2 0x71418 -#define SWF3 0x7141c -#define SWF4 0x71420 -#define SWF5 0x71424 -#define SWF6 0x71428 - -/* - * 855 scratch registers. - */ -#define SWF00 0x70410 -#define SWF01 0x70414 -#define SWF02 0x70418 -#define SWF03 0x7041c -#define SWF04 0x70420 -#define SWF05 0x70424 -#define SWF06 0x70428 - -#define SWF10 SWF0 -#define SWF11 SWF1 -#define SWF12 SWF2 -#define SWF13 SWF3 -#define SWF14 SWF4 -#define SWF15 SWF5 -#define SWF16 SWF6 - -#define SWF30 0x72414 -#define SWF31 0x72418 -#define SWF32 0x7241c - - -/* - * Palette registers - */ -#define PALETTE_A 0x0a000 -#define PALETTE_B 0x0a800 -#define PALETTE_C 0x0ac00 - -/* Cursor A & B regs */ -#define CURACNTR 0x70080 -#define CURSOR_MODE_DISABLE 0x00 -#define CURSOR_MODE_64_32B_AX 0x07 -#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) -#define MCURSOR_GAMMA_ENABLE (1 << 26) -#define CURABASE 0x70084 -#define CURAPOS 0x70088 -#define CURSOR_POS_MASK 0x007FF -#define CURSOR_POS_SIGN 0x8000 -#define CURSOR_X_SHIFT 0 -#define CURSOR_Y_SHIFT 16 -#define CURBCNTR 0x700c0 -#define CURBBASE 0x700c4 -#define CURBPOS 0x700c8 -#define CURCCNTR 0x700e0 -#define CURCBASE 0x700e4 -#define CURCPOS 0x700e8 - -/* - * Interrupt Registers - */ -#define IER 0x020a0 -#define IIR 0x020a4 -#define IMR 0x020a8 -#define ISR 0x020ac - -/* - * MOORESTOWN delta registers - */ -#define MRST_DPLL_A 0x0f014 -#define MDFLD_DPLL_B 0x0f018 -#define MDFLD_INPUT_REF_SEL (1 << 14) -#define MDFLD_VCO_SEL (1 << 16) -#define DPLLA_MODE_LVDS (2 << 26) /* mrst */ -#define MDFLD_PLL_LATCHEN (1 << 28) -#define MDFLD_PWR_GATE_EN (1 << 30) -#define MDFLD_P1_MASK (0x1FF << 17) -#define MRST_FPA0 0x0f040 -#define MRST_FPA1 0x0f044 -#define MDFLD_DPLL_DIV0 0x0f048 -#define MDFLD_DPLL_DIV1 0x0f04c -#define MRST_PERF_MODE 0x020f4 - -/* - * MEDFIELD HDMI registers - */ -#define HDMIPHYMISCCTL 0x61134 -# define HDMI_PHY_POWER_DOWN 0x7f -#define HDMIB_CONTROL 0x61140 -# define HDMIB_PORT_EN (1 << 31) -# define HDMIB_PIPE_B_SELECT (1 << 30) -# define HDMIB_NULL_PACKET (1 << 9) -#define HDMIB_HDCP_PORT (1 << 5) - -/* #define LVDS 0x61180 */ -# define MRST_PANEL_8TO6_DITHER_ENABLE (1 << 25) -# define MRST_PANEL_24_DOT_1_FORMAT (1 << 24) -# define LVDS_A3_POWER_UP_0_OUTPUT (1 << 6) - -#define MIPI 0x61190 -#define MIPI_C 0x62190 -# define MIPI_PORT_EN (1 << 31) -/* Turns on border drawing to allow centered display. */ -# define SEL_FLOPPED_HSTX (1 << 23) -# define PASS_FROM_SPHY_TO_AFE (1 << 16) -# define MIPI_BORDER_EN (1 << 15) -# define MIPIA_3LANE_MIPIC_1LANE 0x1 -# define MIPIA_2LANE_MIPIC_2LANE 0x2 -# define TE_TRIGGER_DSI_PROTOCOL (1 << 2) -# define TE_TRIGGER_GPIO_PIN (1 << 3) -#define MIPI_TE_COUNT 0x61194 - -/* #define PP_CONTROL 0x61204 */ -# define POWER_DOWN_ON_RESET (1 << 1) - -/* #define PFIT_CONTROL 0x61230 */ -# define PFIT_PIPE_SELECT (3 << 29) -# define PFIT_PIPE_SELECT_SHIFT (29) - -/* #define BLC_PWM_CTL 0x61254 */ -#define MRST_BACKLIGHT_MODULATION_FREQ_SHIFT (16) -#define MRST_BACKLIGHT_MODULATION_FREQ_MASK (0xffff << 16) - -/* #define PIPEACONF 0x70008 */ -#define PIPEACONF_PIPE_STATE (1<<30) -/* #define DSPACNTR 0x70180 */ - -#define MRST_DSPABASE 0x7019c -#define MRST_DSPBBASE 0x7119c -#define MDFLD_DSPCBASE 0x7219c - -/* - * Moorestown registers. - */ - -/* - * MIPI IP registers - */ -#define MIPIC_REG_OFFSET 0x800 -#define DEVICE_READY_REG 0xb000 -#define LP_OUTPUT_HOLD (1 << 16) -#define EXIT_ULPS_DEV_READY 0x3 -#define LP_OUTPUT_HOLD_RELEASE 0x810000 -# define ENTERING_ULPS (2 << 1) -# define EXITING_ULPS (1 << 1) -# define ULPS_MASK (3 << 1) -# define BUS_POSSESSION (1 << 3) -#define INTR_STAT_REG 0xb004 -#define RX_SOT_ERROR (1 << 0) -#define RX_SOT_SYNC_ERROR (1 << 1) -#define RX_ESCAPE_MODE_ENTRY_ERROR (1 << 3) -#define RX_LP_TX_SYNC_ERROR (1 << 4) -#define RX_HS_RECEIVE_TIMEOUT_ERROR (1 << 5) -#define RX_FALSE_CONTROL_ERROR (1 << 6) -#define RX_ECC_SINGLE_BIT_ERROR (1 << 7) -#define RX_ECC_MULTI_BIT_ERROR (1 << 8) -#define RX_CHECKSUM_ERROR (1 << 9) -#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 10) -#define RX_DSI_VC_ID_INVALID (1 << 11) -#define TX_FALSE_CONTROL_ERROR (1 << 12) -#define TX_ECC_SINGLE_BIT_ERROR (1 << 13) -#define TX_ECC_MULTI_BIT_ERROR (1 << 14) -#define TX_CHECKSUM_ERROR (1 << 15) -#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 16) -#define TX_DSI_VC_ID_INVALID (1 << 17) -#define HIGH_CONTENTION (1 << 18) -#define LOW_CONTENTION (1 << 19) -#define DPI_FIFO_UNDER_RUN (1 << 20) -#define HS_TX_TIMEOUT (1 << 21) -#define LP_RX_TIMEOUT (1 << 22) -#define TURN_AROUND_ACK_TIMEOUT (1 << 23) -#define ACK_WITH_NO_ERROR (1 << 24) -#define HS_GENERIC_WR_FIFO_FULL (1 << 27) -#define LP_GENERIC_WR_FIFO_FULL (1 << 28) -#define SPL_PKT_SENT (1 << 30) -#define INTR_EN_REG 0xb008 -#define DSI_FUNC_PRG_REG 0xb00c -#define DPI_CHANNEL_NUMBER_POS 0x03 -#define DBI_CHANNEL_NUMBER_POS 0x05 -#define FMT_DPI_POS 0x07 -#define FMT_DBI_POS 0x0A -#define DBI_DATA_WIDTH_POS 0x0D -/* DPI PIXEL FORMATS */ -#define RGB_565_FMT 0x01 /* RGB 565 FORMAT */ -#define RGB_666_FMT 0x02 /* RGB 666 FORMAT */ -#define LRGB_666_FMT 0x03 /* RGB LOOSELY PACKED - * 666 FORMAT - */ -#define RGB_888_FMT 0x04 /* RGB 888 FORMAT */ -#define VIRTUAL_CHANNEL_NUMBER_0 0x00 /* Virtual channel 0 */ -#define VIRTUAL_CHANNEL_NUMBER_1 0x01 /* Virtual channel 1 */ -#define VIRTUAL_CHANNEL_NUMBER_2 0x02 /* Virtual channel 2 */ -#define VIRTUAL_CHANNEL_NUMBER_3 0x03 /* Virtual channel 3 */ -#define DBI_NOT_SUPPORTED 0x00 /* command mode - * is not supported - */ -#define DBI_DATA_WIDTH_16BIT 0x01 /* 16 bit data */ -#define DBI_DATA_WIDTH_9BIT 0x02 /* 9 bit data */ -#define DBI_DATA_WIDTH_8BIT 0x03 /* 8 bit data */ -#define DBI_DATA_WIDTH_OPT1 0x04 /* option 1 */ -#define DBI_DATA_WIDTH_OPT2 0x05 /* option 2 */ -#define HS_TX_TIMEOUT_REG 0xb010 -#define LP_RX_TIMEOUT_REG 0xb014 -#define TURN_AROUND_TIMEOUT_REG 0xb018 -#define DEVICE_RESET_REG 0xb01C -#define DPI_RESOLUTION_REG 0xb020 -#define RES_V_POS 0x10 -#define DBI_RESOLUTION_REG 0xb024 /* Reserved for MDFLD */ -#define HORIZ_SYNC_PAD_COUNT_REG 0xb028 -#define HORIZ_BACK_PORCH_COUNT_REG 0xb02C -#define HORIZ_FRONT_PORCH_COUNT_REG 0xb030 -#define HORIZ_ACTIVE_AREA_COUNT_REG 0xb034 -#define VERT_SYNC_PAD_COUNT_REG 0xb038 -#define VERT_BACK_PORCH_COUNT_REG 0xb03c -#define VERT_FRONT_PORCH_COUNT_REG 0xb040 -#define HIGH_LOW_SWITCH_COUNT_REG 0xb044 -#define DPI_CONTROL_REG 0xb048 -#define DPI_SHUT_DOWN (1 << 0) -#define DPI_TURN_ON (1 << 1) -#define DPI_COLOR_MODE_ON (1 << 2) -#define DPI_COLOR_MODE_OFF (1 << 3) -#define DPI_BACK_LIGHT_ON (1 << 4) -#define DPI_BACK_LIGHT_OFF (1 << 5) -#define DPI_LP (1 << 6) -#define DPI_DATA_REG 0xb04c -#define DPI_BACK_LIGHT_ON_DATA 0x07 -#define DPI_BACK_LIGHT_OFF_DATA 0x17 -#define INIT_COUNT_REG 0xb050 -#define MAX_RET_PAK_REG 0xb054 -#define VIDEO_FMT_REG 0xb058 -#define COMPLETE_LAST_PCKT (1 << 2) -#define EOT_DISABLE_REG 0xb05c -#define ENABLE_CLOCK_STOPPING (1 << 1) -#define LP_BYTECLK_REG 0xb060 -#define LP_GEN_DATA_REG 0xb064 -#define HS_GEN_DATA_REG 0xb068 -#define LP_GEN_CTRL_REG 0xb06C -#define HS_GEN_CTRL_REG 0xb070 -#define DCS_CHANNEL_NUMBER_POS 0x06 -#define MCS_COMMANDS_POS 0x8 -#define WORD_COUNTS_POS 0x8 -#define MCS_PARAMETER_POS 0x10 -#define GEN_FIFO_STAT_REG 0xb074 -#define HS_DATA_FIFO_FULL (1 << 0) -#define HS_DATA_FIFO_HALF_EMPTY (1 << 1) -#define HS_DATA_FIFO_EMPTY (1 << 2) -#define LP_DATA_FIFO_FULL (1 << 8) -#define LP_DATA_FIFO_HALF_EMPTY (1 << 9) -#define LP_DATA_FIFO_EMPTY (1 << 10) -#define HS_CTRL_FIFO_FULL (1 << 16) -#define HS_CTRL_FIFO_HALF_EMPTY (1 << 17) -#define HS_CTRL_FIFO_EMPTY (1 << 18) -#define LP_CTRL_FIFO_FULL (1 << 24) -#define LP_CTRL_FIFO_HALF_EMPTY (1 << 25) -#define LP_CTRL_FIFO_EMPTY (1 << 26) -#define DBI_FIFO_EMPTY (1 << 27) -#define DPI_FIFO_EMPTY (1 << 28) -#define HS_LS_DBI_ENABLE_REG 0xb078 -#define TXCLKESC_REG 0xb07c -#define DPHY_PARAM_REG 0xb080 -#define DBI_BW_CTRL_REG 0xb084 -#define CLK_LANE_SWT_REG 0xb088 - -/* - * MIPI Adapter registers - */ -#define MIPI_CONTROL_REG 0xb104 -#define MIPI_2X_CLOCK_BITS ((1 << 0) | (1 << 1)) -#define MIPI_DATA_ADDRESS_REG 0xb108 -#define MIPI_DATA_LENGTH_REG 0xb10C -#define MIPI_COMMAND_ADDRESS_REG 0xb110 -#define MIPI_COMMAND_LENGTH_REG 0xb114 -#define MIPI_READ_DATA_RETURN_REG0 0xb118 -#define MIPI_READ_DATA_RETURN_REG1 0xb11C -#define MIPI_READ_DATA_RETURN_REG2 0xb120 -#define MIPI_READ_DATA_RETURN_REG3 0xb124 -#define MIPI_READ_DATA_RETURN_REG4 0xb128 -#define MIPI_READ_DATA_RETURN_REG5 0xb12C -#define MIPI_READ_DATA_RETURN_REG6 0xb130 -#define MIPI_READ_DATA_RETURN_REG7 0xb134 -#define MIPI_READ_DATA_VALID_REG 0xb138 -/* DBI COMMANDS */ -#define soft_reset 0x01 -/* - * The display module performs a software reset. - * Registers are written with their SW Reset default values. - */ -#define get_power_mode 0x0a -/* - * The display module returns the current power mode - */ -#define get_address_mode 0x0b -/* - * The display module returns the current status. - */ -#define get_pixel_format 0x0c -/* - * This command gets the pixel format for the RGB image data - * used by the interface. - */ -#define get_display_mode 0x0d -/* - * The display module returns the Display Image Mode status. - */ -#define get_signal_mode 0x0e -/* - * The display module returns the Display Signal Mode. - */ -#define get_diagnostic_result 0x0f -/* - * The display module returns the self-diagnostic results following - * a Sleep Out command. - */ -#define enter_sleep_mode 0x10 -/* - * This command causes the display module to enter the Sleep mode. - * In this mode, all unnecessary blocks inside the display module are - * disabled except interface communication. This is the lowest power - * mode the display module supports. - */ -#define exit_sleep_mode 0x11 -/* - * This command causes the display module to exit Sleep mode. - * All blocks inside the display module are enabled. - */ -#define enter_partial_mode 0x12 -/* - * This command causes the display module to enter the Partial Display - * Mode. The Partial Display Mode window is described by the - * set_partial_area command. - */ -#define enter_normal_mode 0x13 -/* - * This command causes the display module to enter the Normal mode. - * Normal Mode is defined as Partial Display mode and Scroll mode are off - */ -#define exit_invert_mode 0x20 -/* - * This command causes the display module to stop inverting the image - * data on the display device. The frame memory contents remain unchanged. - * No status bits are changed. - */ -#define enter_invert_mode 0x21 -/* - * This command causes the display module to invert the image data only on - * the display device. The frame memory contents remain unchanged. - * No status bits are changed. - */ -#define set_gamma_curve 0x26 -/* - * This command selects the desired gamma curve for the display device. - * Four fixed gamma curves are defined in section DCS spec. - */ -#define set_display_off 0x28 -/* ************************************************************************* *\ -This command causes the display module to stop displaying the image data -on the display device. The frame memory contents remain unchanged. -No status bits are changed. -\* ************************************************************************* */ -#define set_display_on 0x29 -/* ************************************************************************* *\ -This command causes the display module to start displaying the image data -on the display device. The frame memory contents remain unchanged. -No status bits are changed. -\* ************************************************************************* */ -#define set_column_address 0x2a -/* - * This command defines the column extent of the frame memory accessed by - * the hostprocessor with the read_memory_continue and - * write_memory_continue commands. - * No status bits are changed. - */ -#define set_page_addr 0x2b -/* - * This command defines the page extent of the frame memory accessed by - * the host processor with the write_memory_continue and - * read_memory_continue command. - * No status bits are changed. - */ -#define write_mem_start 0x2c -/* - * This command transfers image data from the host processor to the - * display module s frame memory starting at the pixel location specified - * by preceding set_column_address and set_page_address commands. - */ -#define set_partial_area 0x30 -/* - * This command defines the Partial Display mode s display area. - * There are two parameters associated with this command, the first - * defines the Start Row (SR) and the second the End Row (ER). SR and ER - * refer to the Frame Memory Line Pointer. - */ -#define set_scroll_area 0x33 -/* - * This command defines the display modules Vertical Scrolling Area. - */ -#define set_tear_off 0x34 -/* - * This command turns off the display modules Tearing Effect output - * signal on the TE signal line. - */ -#define set_tear_on 0x35 -/* - * This command turns on the display modules Tearing Effect output signal - * on the TE signal line. - */ -#define set_address_mode 0x36 -/* - * This command sets the data order for transfers from the host processor - * to display modules frame memory,bits B[7:5] and B3, and from the - * display modules frame memory to the display device, bits B[2:0] and B4. - */ -#define set_scroll_start 0x37 -/* - * This command sets the start of the vertical scrolling area in the frame - * memory. The vertical scrolling area is fully defined when this command - * is used with the set_scroll_area command The set_scroll_start command - * has one parameter, the Vertical Scroll Pointer. The VSP defines the - * line in the frame memory that is written to the display device as the - * first line of the vertical scroll area. - */ -#define exit_idle_mode 0x38 -/* - * This command causes the display module to exit Idle mode. - */ -#define enter_idle_mode 0x39 -/* - * This command causes the display module to enter Idle Mode. - * In Idle Mode, color expression is reduced. Colors are shown on the - * display device using the MSB of each of the R, G and B color - * components in the frame memory - */ -#define set_pixel_format 0x3a -/* - * This command sets the pixel format for the RGB image data used by the - * interface. - * Bits D[6:4] DPI Pixel Format Definition - * Bits D[2:0] DBI Pixel Format Definition - * Bits D7 and D3 are not used. - */ - #define DCS_PIXEL_FORMAT_3bbp 0x1 - #define DCS_PIXEL_FORMAT_8bbp 0x2 - #define DCS_PIXEL_FORMAT_12bbp 0x3 - #define DCS_PIXEL_FORMAT_16bbp 0x5 - #define DCS_PIXEL_FORMAT_18bbp 0x6 - #define DCS_PIXEL_FORMAT_24bbp 0x7 -#define write_mem_cont 0x3c -/* - * This command transfers image data from the host processor to the - * display module's frame memory continuing from the pixel location - * following the previous write_memory_continue or write_memory_start - * command. - */ -#define set_tear_scanline 0x44 -/* - * This command turns on the display modules Tearing Effect output signal - * on the TE signal line when the display module reaches line N. - */ -#define get_scanline 0x45 -/* - * The display module returns the current scanline, N, used to update the - * display device. The total number of scanlines on a display device is - * defined as VSYNC + VBP + VACT + VFP.The first scanline is defined as - * the first line of V Sync and is denoted as Line 0. - * When in Sleep Mode, the value returned by get_scanline is undefined. - */ - -/* MCS or Generic COMMANDS */ -/* MCS/generic data type */ -#define GEN_SHORT_WRITE_0 0x03 /* generic short write, no parameters */ -#define GEN_SHORT_WRITE_1 0x13 /* generic short write, 1 parameters */ -#define GEN_SHORT_WRITE_2 0x23 /* generic short write, 2 parameters */ -#define GEN_READ_0 0x04 /* generic read, no parameters */ -#define GEN_READ_1 0x14 /* generic read, 1 parameters */ -#define GEN_READ_2 0x24 /* generic read, 2 parameters */ -#define GEN_LONG_WRITE 0x29 /* generic long write */ -#define MCS_SHORT_WRITE_0 0x05 /* MCS short write, no parameters */ -#define MCS_SHORT_WRITE_1 0x15 /* MCS short write, 1 parameters */ -#define MCS_READ 0x06 /* MCS read, no parameters */ -#define MCS_LONG_WRITE 0x39 /* MCS long write */ -/* MCS/generic commands */ -/* TPO MCS */ -#define write_display_profile 0x50 -#define write_display_brightness 0x51 -#define write_ctrl_display 0x53 -#define write_ctrl_cabc 0x55 - #define UI_IMAGE 0x01 - #define STILL_IMAGE 0x02 - #define MOVING_IMAGE 0x03 -#define write_hysteresis 0x57 -#define write_gamma_setting 0x58 -#define write_cabc_min_bright 0x5e -#define write_kbbc_profile 0x60 -/* TMD MCS */ -#define tmd_write_display_brightness 0x8c - -/* - * This command is used to control ambient light, panel backlight - * brightness and gamma settings. - */ -#define BRIGHT_CNTL_BLOCK_ON (1 << 5) -#define AMBIENT_LIGHT_SENSE_ON (1 << 4) -#define DISPLAY_DIMMING_ON (1 << 3) -#define BACKLIGHT_ON (1 << 2) -#define DISPLAY_BRIGHTNESS_AUTO (1 << 1) -#define GAMMA_AUTO (1 << 0) - -/* DCS Interface Pixel Formats */ -#define DCS_PIXEL_FORMAT_3BPP 0x1 -#define DCS_PIXEL_FORMAT_8BPP 0x2 -#define DCS_PIXEL_FORMAT_12BPP 0x3 -#define DCS_PIXEL_FORMAT_16BPP 0x5 -#define DCS_PIXEL_FORMAT_18BPP 0x6 -#define DCS_PIXEL_FORMAT_24BPP 0x7 -/* ONE PARAMETER READ DATA */ -#define addr_mode_data 0xfc -#define diag_res_data 0x00 -#define disp_mode_data 0x23 -#define pxl_fmt_data 0x77 -#define pwr_mode_data 0x74 -#define sig_mode_data 0x00 -/* TWO PARAMETERS READ DATA */ -#define scanline_data1 0xff -#define scanline_data2 0xff -#define NON_BURST_MODE_SYNC_PULSE 0x01 /* Non Burst Mode - * with Sync Pulse - */ -#define NON_BURST_MODE_SYNC_EVENTS 0x02 /* Non Burst Mode - * with Sync events - */ -#define BURST_MODE 0x03 /* Burst Mode */ -#define DBI_COMMAND_BUFFER_SIZE 0x240 /* 0x32 */ /* 0x120 */ /* Allocate at least - * 0x100 Byte with 32 - * byte alignment - */ -#define DBI_DATA_BUFFER_SIZE 0x120 /* Allocate at least - * 0x100 Byte with 32 - * byte alignment - */ -#define DBI_CB_TIME_OUT 0xFFFF - -#define GEN_FB_TIME_OUT 2000 -#define ALIGNMENT_32BYTE_MASK (~((1 << 0)|(1 << 1)|(1 << 2)|(1 << 3)|(1 << 4))) -#define SKU_83 0x01 -#define SKU_100 0x02 -#define SKU_100L 0x04 -#define SKU_BYPASS 0x08 - -#endif diff --git a/drivers/staging/gma500/psb_intel_sdvo.c b/drivers/staging/gma500/psb_intel_sdvo.c deleted file mode 100644 index df1c006ecfa..00000000000 --- a/drivers/staging/gma500/psb_intel_sdvo.c +++ /dev/null @@ -1,1298 +0,0 @@ -/* - * Copyright (c) 2006-2007 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt <eric@anholt.net> - */ - -#include <linux/i2c.h> -#include <linux/delay.h> -/* #include <drm/drm_crtc.h> */ -#include <drm/drmP.h> -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "psb_intel_sdvo_regs.h" - -struct psb_intel_sdvo_priv { - struct psb_intel_i2c_chan *i2c_bus; - int slaveaddr; - int output_device; - - u16 active_outputs; - - struct psb_intel_sdvo_caps caps; - int pixel_clock_min, pixel_clock_max; - - int save_sdvo_mult; - u16 save_active_outputs; - struct psb_intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; - struct psb_intel_sdvo_dtd save_output_dtd[16]; - u32 save_SDVOX; - u8 in_out_map[4]; - - u8 by_input_wiring; - u32 active_device; -}; - -/** - * Writes the SDVOB or SDVOC with the given value, but always writes both - * SDVOB and SDVOC to work around apparent hardware issues (according to - * comments in the BIOS). - */ -void psb_intel_sdvo_write_sdvox(struct psb_intel_output *psb_intel_output, - u32 val) -{ - struct drm_device *dev = psb_intel_output->base.dev; - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; - u32 bval = val, cval = val; - int i; - - if (sdvo_priv->output_device == SDVOB) - cval = REG_READ(SDVOC); - else - bval = REG_READ(SDVOB); - /* - * Write the registers twice for luck. Sometimes, - * writing them only once doesn't appear to 'stick'. - * The BIOS does this too. Yay, magic - */ - for (i = 0; i < 2; i++) { - REG_WRITE(SDVOB, bval); - REG_READ(SDVOB); - REG_WRITE(SDVOC, cval); - REG_READ(SDVOC); - } -} - -static bool psb_intel_sdvo_read_byte( - struct psb_intel_output *psb_intel_output, - u8 addr, u8 *ch) -{ - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; - u8 out_buf[2]; - u8 buf[2]; - int ret; - - struct i2c_msg msgs[] = { - { - .addr = sdvo_priv->i2c_bus->slave_addr, - .flags = 0, - .len = 1, - .buf = out_buf, - }, - { - .addr = sdvo_priv->i2c_bus->slave_addr, - .flags = I2C_M_RD, - .len = 1, - .buf = buf, - } - }; - - out_buf[0] = addr; - out_buf[1] = 0; - - ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2); - if (ret == 2) { - /* DRM_DEBUG("got back from addr %02X = %02x\n", - * out_buf[0], buf[0]); - */ - *ch = buf[0]; - return true; - } - - DRM_DEBUG("i2c transfer returned %d\n", ret); - return false; -} - -static bool psb_intel_sdvo_write_byte( - struct psb_intel_output *psb_intel_output, - int addr, u8 ch) -{ - u8 out_buf[2]; - struct i2c_msg msgs[] = { - { - .addr = psb_intel_output->i2c_bus->slave_addr, - .flags = 0, - .len = 2, - .buf = out_buf, - } - }; - - out_buf[0] = addr; - out_buf[1] = ch; - - if (i2c_transfer(&psb_intel_output->i2c_bus->adapter, msgs, 1) == 1) - return true; - return false; -} - -#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} -/** Mapping of command numbers to names, for debug output */ -static const struct _sdvo_cmd_name { - u8 cmd; - char *name; -} sdvo_cmd_names[] = { -SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG), - SDVO_CMD_NAME_ENTRY - (SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY - (SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING), - SDVO_CMD_NAME_ENTRY - (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1), - SDVO_CMD_NAME_ENTRY - (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2), - SDVO_CMD_NAME_ENTRY - (SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE), - SDVO_CMD_NAME_ENTRY - (SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE), - SDVO_CMD_NAME_ENTRY - (SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT), - SDVO_CMD_NAME_ENTRY - (SDVO_CMD_SET_TV_RESOLUTION_SUPPORT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),}; - -#define SDVO_NAME(dev_priv) \ - ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") -#define SDVO_PRIV(output) ((struct psb_intel_sdvo_priv *) (output)->dev_priv) - -static void psb_intel_sdvo_write_cmd(struct psb_intel_output *psb_intel_output, - u8 cmd, - void *args, - int args_len) -{ - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; - int i; - - if (0) { - DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd); - for (i = 0; i < args_len; i++) - printk(KERN_INFO"%02X ", ((u8 *) args)[i]); - for (; i < 8; i++) - printk(" "); - for (i = 0; - i < - sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); - i++) { - if (cmd == sdvo_cmd_names[i].cmd) { - printk("(%s)", sdvo_cmd_names[i].name); - break; - } - } - if (i == - sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0])) - printk("(%02X)", cmd); - printk("\n"); - } - - for (i = 0; i < args_len; i++) { - psb_intel_sdvo_write_byte(psb_intel_output, - SDVO_I2C_ARG_0 - i, - ((u8 *) args)[i]); - } - - psb_intel_sdvo_write_byte(psb_intel_output, SDVO_I2C_OPCODE, cmd); -} - -static const char *const cmd_status_names[] = { - "Power on", - "Success", - "Not supported", - "Invalid arg", - "Pending", - "Target not specified", - "Scaling not supported" -}; - -static u8 psb_intel_sdvo_read_response( - struct psb_intel_output *psb_intel_output, - void *response, int response_len) -{ - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; - int i; - u8 status; - u8 retry = 50; - - while (retry--) { - /* Read the command response */ - for (i = 0; i < response_len; i++) { - psb_intel_sdvo_read_byte(psb_intel_output, - SDVO_I2C_RETURN_0 + i, - &((u8 *) response)[i]); - } - - /* read the return status */ - psb_intel_sdvo_read_byte(psb_intel_output, - SDVO_I2C_CMD_STATUS, - &status); - - if (0) { - DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv)); - for (i = 0; i < response_len; i++) - printk(KERN_INFO"%02X ", ((u8 *) response)[i]); - for (; i < 8; i++) - printk(" "); - if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) - printk(KERN_INFO"(%s)", - cmd_status_names[status]); - else - printk(KERN_INFO"(??? %d)", status); - printk("\n"); - } - - if (status != SDVO_CMD_STATUS_PENDING) - return status; - - mdelay(50); - } - - return status; -} - -int psb_intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) -{ - if (mode->clock >= 100000) - return 1; - else if (mode->clock >= 50000) - return 2; - else - return 4; -} - -/** - * Don't check status code from this as it switches the bus back to the - * SDVO chips which defeats the purpose of doing a bus switch in the first - * place. - */ -void psb_intel_sdvo_set_control_bus_switch( - struct psb_intel_output *psb_intel_output, - u8 target) -{ - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_SET_CONTROL_BUS_SWITCH, - &target, - 1); -} - -static bool psb_intel_sdvo_set_target_input( - struct psb_intel_output *psb_intel_output, - bool target_0, bool target_1) -{ - struct psb_intel_sdvo_set_target_input_args targets = { 0 }; - u8 status; - - if (target_0 && target_1) - return SDVO_CMD_STATUS_NOTSUPP; - - if (target_1) - targets.target_1 = 1; - - psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_INPUT, - &targets, sizeof(targets)); - - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); - - return status == SDVO_CMD_STATUS_SUCCESS; -} - -/** - * Return whether each input is trained. - * - * This function is making an assumption about the layout of the response, - * which should be checked against the docs. - */ -static bool psb_intel_sdvo_get_trained_inputs(struct psb_intel_output - *psb_intel_output, bool *input_1, - bool *input_2) -{ - struct psb_intel_sdvo_get_trained_inputs_response response; - u8 status; - - psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_TRAINED_INPUTS, - NULL, 0); - status = - psb_intel_sdvo_read_response(psb_intel_output, &response, - sizeof(response)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return false; - - *input_1 = response.input0_trained; - *input_2 = response.input1_trained; - return true; -} - -static bool psb_intel_sdvo_get_active_outputs(struct psb_intel_output - *psb_intel_output, u16 *outputs) -{ - u8 status; - - psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, - NULL, 0); - status = - psb_intel_sdvo_read_response(psb_intel_output, outputs, - sizeof(*outputs)); - - return status == SDVO_CMD_STATUS_SUCCESS; -} - -static bool psb_intel_sdvo_set_active_outputs(struct psb_intel_output - *psb_intel_output, u16 outputs) -{ - u8 status; - - psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, - &outputs, sizeof(outputs)); - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); - return status == SDVO_CMD_STATUS_SUCCESS; -} - -static bool psb_intel_sdvo_set_encoder_power_state(struct psb_intel_output - *psb_intel_output, int mode) -{ - u8 status, state = SDVO_ENCODER_STATE_ON; - - switch (mode) { - case DRM_MODE_DPMS_ON: - state = SDVO_ENCODER_STATE_ON; - break; - case DRM_MODE_DPMS_STANDBY: - state = SDVO_ENCODER_STATE_STANDBY; - break; - case DRM_MODE_DPMS_SUSPEND: - state = SDVO_ENCODER_STATE_SUSPEND; - break; - case DRM_MODE_DPMS_OFF: - state = SDVO_ENCODER_STATE_OFF; - break; - } - - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_SET_ENCODER_POWER_STATE, &state, - sizeof(state)); - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); - - return status == SDVO_CMD_STATUS_SUCCESS; -} - -static bool psb_intel_sdvo_get_input_pixel_clock_range(struct psb_intel_output - *psb_intel_output, - int *clock_min, - int *clock_max) -{ - struct psb_intel_sdvo_pixel_clock_range clocks; - u8 status; - - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, NULL, - 0); - - status = - psb_intel_sdvo_read_response(psb_intel_output, &clocks, - sizeof(clocks)); - - if (status != SDVO_CMD_STATUS_SUCCESS) - return false; - - /* Convert the values from units of 10 kHz to kHz. */ - *clock_min = clocks.min * 10; - *clock_max = clocks.max * 10; - - return true; -} - -static bool psb_intel_sdvo_set_target_output( - struct psb_intel_output *psb_intel_output, - u16 outputs) -{ - u8 status; - - psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_OUTPUT, - &outputs, sizeof(outputs)); - - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); - return status == SDVO_CMD_STATUS_SUCCESS; -} - -static bool psb_intel_sdvo_get_timing(struct psb_intel_output *psb_intel_output, - u8 cmd, struct psb_intel_sdvo_dtd *dtd) -{ - u8 status; - - psb_intel_sdvo_write_cmd(psb_intel_output, cmd, NULL, 0); - status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part1, - sizeof(dtd->part1)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return false; - - psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, NULL, 0); - status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part2, - sizeof(dtd->part2)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return false; - - return true; -} - -static bool psb_intel_sdvo_get_input_timing( - struct psb_intel_output *psb_intel_output, - struct psb_intel_sdvo_dtd *dtd) -{ - return psb_intel_sdvo_get_timing(psb_intel_output, - SDVO_CMD_GET_INPUT_TIMINGS_PART1, - dtd); -} - -static bool psb_intel_sdvo_set_timing( - struct psb_intel_output *psb_intel_output, - u8 cmd, - struct psb_intel_sdvo_dtd *dtd) -{ - u8 status; - - psb_intel_sdvo_write_cmd(psb_intel_output, cmd, &dtd->part1, - sizeof(dtd->part1)); - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); - if (status != SDVO_CMD_STATUS_SUCCESS) - return false; - - psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, &dtd->part2, - sizeof(dtd->part2)); - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); - if (status != SDVO_CMD_STATUS_SUCCESS) - return false; - - return true; -} - -static bool psb_intel_sdvo_set_input_timing( - struct psb_intel_output *psb_intel_output, - struct psb_intel_sdvo_dtd *dtd) -{ - return psb_intel_sdvo_set_timing(psb_intel_output, - SDVO_CMD_SET_INPUT_TIMINGS_PART1, - dtd); -} - -static bool psb_intel_sdvo_set_output_timing( - struct psb_intel_output *psb_intel_output, - struct psb_intel_sdvo_dtd *dtd) -{ - return psb_intel_sdvo_set_timing(psb_intel_output, - SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, - dtd); -} - -static int psb_intel_sdvo_get_clock_rate_mult(struct psb_intel_output - *psb_intel_output) -{ - u8 response, status; - - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_GET_CLOCK_RATE_MULT, - NULL, - 0); - - status = psb_intel_sdvo_read_response(psb_intel_output, &response, 1); - - if (status != SDVO_CMD_STATUS_SUCCESS) { - DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n"); - return SDVO_CLOCK_RATE_MULT_1X; - } else { - DRM_DEBUG("Current clock rate multiplier: %d\n", response); - } - - return response; -} - -static bool psb_intel_sdvo_set_clock_rate_mult(struct psb_intel_output - *psb_intel_output, u8 val) -{ - u8 status; - - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_SET_CLOCK_RATE_MULT, - &val, - 1); - - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); - if (status != SDVO_CMD_STATUS_SUCCESS) - return false; - - return true; -} - -static bool psb_sdvo_set_current_inoutmap(struct psb_intel_output *output, - u32 in0outputmask, - u32 in1outputmask) -{ - u8 byArgs[4]; - u8 status; - int i; - struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv; - - /* Make all fields of the args/ret to zero */ - memset(byArgs, 0, sizeof(byArgs)); - - /* Fill up the argument values; */ - byArgs[0] = (u8) (in0outputmask & 0xFF); - byArgs[1] = (u8) ((in0outputmask >> 8) & 0xFF); - byArgs[2] = (u8) (in1outputmask & 0xFF); - byArgs[3] = (u8) ((in1outputmask >> 8) & 0xFF); - - - /*save inoutmap arg here*/ - for (i = 0; i < 4; i++) - sdvo_priv->in_out_map[i] = byArgs[0]; - - psb_intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, byArgs, 4); - status = psb_intel_sdvo_read_response(output, NULL, 0); - - if (status != SDVO_CMD_STATUS_SUCCESS) - return false; - return true; -} - - -static void psb_intel_sdvo_set_iomap(struct psb_intel_output *output) -{ - u32 dwCurrentSDVOIn0 = 0; - u32 dwCurrentSDVOIn1 = 0; - u32 dwDevMask = 0; - - - struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv; - - /* Please DO NOT change the following code. */ - /* SDVOB_IN0 or SDVOB_IN1 ==> sdvo_in0 */ - /* SDVOC_IN0 or SDVOC_IN1 ==> sdvo_in1 */ - if (sdvo_priv->by_input_wiring & (SDVOB_IN0 | SDVOC_IN0)) { - switch (sdvo_priv->active_device) { - case SDVO_DEVICE_LVDS: - dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1; - break; - case SDVO_DEVICE_TMDS: - dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1; - break; - case SDVO_DEVICE_TV: - dwDevMask = - SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 | - SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 | - SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 | - SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1; - break; - case SDVO_DEVICE_CRT: - dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1; - break; - } - dwCurrentSDVOIn0 = (sdvo_priv->active_outputs & dwDevMask); - } else if (sdvo_priv->by_input_wiring & (SDVOB_IN1 | SDVOC_IN1)) { - switch (sdvo_priv->active_device) { - case SDVO_DEVICE_LVDS: - dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1; - break; - case SDVO_DEVICE_TMDS: - dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1; - break; - case SDVO_DEVICE_TV: - dwDevMask = - SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 | - SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 | - SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 | - SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1; - break; - case SDVO_DEVICE_CRT: - dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1; - break; - } - dwCurrentSDVOIn1 = (sdvo_priv->active_outputs & dwDevMask); - } - - psb_sdvo_set_current_inoutmap(output, dwCurrentSDVOIn0, - dwCurrentSDVOIn1); -} - - -static bool psb_intel_sdvo_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - /* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO - * device will be told of the multiplier during mode_set. - */ - adjusted_mode->clock *= psb_intel_sdvo_get_pixel_multiplier(mode); - return true; -} - -static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_crtc *crtc = encoder->crtc; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_intel_output *psb_intel_output = - enc_to_psb_intel_output(encoder); - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; - u16 width, height; - u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len; - u16 h_sync_offset, v_sync_offset; - u32 sdvox; - struct psb_intel_sdvo_dtd output_dtd; - int sdvo_pixel_multiply; - - if (!mode) - return; - - psb_intel_sdvo_set_target_output(psb_intel_output, 0); - - width = mode->crtc_hdisplay; - height = mode->crtc_vdisplay; - - /* do some mode translations */ - h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start; - h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; - - v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start; - v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; - - h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; - v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; - - output_dtd.part1.clock = mode->clock / 10; - output_dtd.part1.h_active = width & 0xff; - output_dtd.part1.h_blank = h_blank_len & 0xff; - output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) | - ((h_blank_len >> 8) & 0xf); - output_dtd.part1.v_active = height & 0xff; - output_dtd.part1.v_blank = v_blank_len & 0xff; - output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) | - ((v_blank_len >> 8) & 0xf); - - output_dtd.part2.h_sync_off = h_sync_offset; - output_dtd.part2.h_sync_width = h_sync_len & 0xff; - output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | - (v_sync_len & 0xf); - output_dtd.part2.sync_off_width_high = - ((h_sync_offset & 0x300) >> 2) | ((h_sync_len & 0x300) >> 4) | - ((v_sync_offset & 0x30) >> 2) | ((v_sync_len & 0x30) >> 4); - - output_dtd.part2.dtd_flags = 0x18; - if (mode->flags & DRM_MODE_FLAG_PHSYNC) - output_dtd.part2.dtd_flags |= 0x2; - if (mode->flags & DRM_MODE_FLAG_PVSYNC) - output_dtd.part2.dtd_flags |= 0x4; - - output_dtd.part2.sdvo_flags = 0; - output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0; - output_dtd.part2.reserved = 0; - - /* Set the output timing to the screen */ - psb_intel_sdvo_set_target_output(psb_intel_output, - sdvo_priv->active_outputs); - - /* Set the input timing to the screen. Assume always input 0. */ - psb_intel_sdvo_set_target_input(psb_intel_output, true, false); - - psb_intel_sdvo_set_output_timing(psb_intel_output, &output_dtd); - - /* We would like to use i830_sdvo_create_preferred_input_timing() to - * provide the device with a timing it can support, if it supports that - * feature. However, presumably we would need to adjust the CRTC to - * output the preferred timing, and we don't support that currently. - */ - psb_intel_sdvo_set_input_timing(psb_intel_output, &output_dtd); - - switch (psb_intel_sdvo_get_pixel_multiplier(mode)) { - case 1: - psb_intel_sdvo_set_clock_rate_mult(psb_intel_output, - SDVO_CLOCK_RATE_MULT_1X); - break; - case 2: - psb_intel_sdvo_set_clock_rate_mult(psb_intel_output, - SDVO_CLOCK_RATE_MULT_2X); - break; - case 4: - psb_intel_sdvo_set_clock_rate_mult(psb_intel_output, - SDVO_CLOCK_RATE_MULT_4X); - break; - } - - /* Set the SDVO control regs. */ - sdvox = REG_READ(sdvo_priv->output_device); - switch (sdvo_priv->output_device) { - case SDVOB: - sdvox &= SDVOB_PRESERVE_MASK; - break; - case SDVOC: - sdvox &= SDVOC_PRESERVE_MASK; - break; - } - sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; - if (psb_intel_crtc->pipe == 1) - sdvox |= SDVO_PIPE_B_SELECT; - - sdvo_pixel_multiply = psb_intel_sdvo_get_pixel_multiplier(mode); - - psb_intel_sdvo_write_sdvox(psb_intel_output, sdvox); - - psb_intel_sdvo_set_iomap(psb_intel_output); -} - -static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct psb_intel_output *psb_intel_output = - enc_to_psb_intel_output(encoder); - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; - u32 temp; - - if (mode != DRM_MODE_DPMS_ON) { - psb_intel_sdvo_set_active_outputs(psb_intel_output, 0); - if (0) - psb_intel_sdvo_set_encoder_power_state( - psb_intel_output, - mode); - - if (mode == DRM_MODE_DPMS_OFF) { - temp = REG_READ(sdvo_priv->output_device); - if ((temp & SDVO_ENABLE) != 0) { - psb_intel_sdvo_write_sdvox(psb_intel_output, - temp & - ~SDVO_ENABLE); - } - } - } else { - bool input1, input2; - int i; - u8 status; - - temp = REG_READ(sdvo_priv->output_device); - if ((temp & SDVO_ENABLE) == 0) - psb_intel_sdvo_write_sdvox(psb_intel_output, - temp | SDVO_ENABLE); - for (i = 0; i < 2; i++) - psb_intel_wait_for_vblank(dev); - - status = - psb_intel_sdvo_get_trained_inputs(psb_intel_output, - &input1, - &input2); - - - /* Warn if the device reported failure to sync. - * A lot of SDVO devices fail to notify of sync, but it's - * a given it the status is a success, we succeeded. - */ - if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { - DRM_DEBUG - ("First %s output reported failure to sync\n", - SDVO_NAME(sdvo_priv)); - } - - if (0) - psb_intel_sdvo_set_encoder_power_state( - psb_intel_output, - mode); - psb_intel_sdvo_set_active_outputs(psb_intel_output, - sdvo_priv->active_outputs); - } - return; -} - -static void psb_intel_sdvo_save(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; - /*int o;*/ - - sdvo_priv->save_sdvo_mult = - psb_intel_sdvo_get_clock_rate_mult(psb_intel_output); - psb_intel_sdvo_get_active_outputs(psb_intel_output, - &sdvo_priv->save_active_outputs); - - if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { - psb_intel_sdvo_set_target_input(psb_intel_output, - true, - false); - psb_intel_sdvo_get_input_timing(psb_intel_output, - &sdvo_priv->save_input_dtd_1); - } - - if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { - psb_intel_sdvo_set_target_input(psb_intel_output, - false, - true); - psb_intel_sdvo_get_input_timing(psb_intel_output, - &sdvo_priv->save_input_dtd_2); - } - sdvo_priv->save_SDVOX = REG_READ(sdvo_priv->output_device); - - /*TODO: save the in_out_map state*/ -} - -static void psb_intel_sdvo_restore(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; - /*int o;*/ - int i; - bool input1, input2; - u8 status; - - psb_intel_sdvo_set_active_outputs(psb_intel_output, 0); - - if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { - psb_intel_sdvo_set_target_input(psb_intel_output, true, false); - psb_intel_sdvo_set_input_timing(psb_intel_output, - &sdvo_priv->save_input_dtd_1); - } - - if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { - psb_intel_sdvo_set_target_input(psb_intel_output, false, true); - psb_intel_sdvo_set_input_timing(psb_intel_output, - &sdvo_priv->save_input_dtd_2); - } - - psb_intel_sdvo_set_clock_rate_mult(psb_intel_output, - sdvo_priv->save_sdvo_mult); - - REG_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX); - - if (sdvo_priv->save_SDVOX & SDVO_ENABLE) { - for (i = 0; i < 2; i++) - psb_intel_wait_for_vblank(dev); - status = - psb_intel_sdvo_get_trained_inputs(psb_intel_output, - &input1, - &input2); - if (status == SDVO_CMD_STATUS_SUCCESS && !input1) - DRM_DEBUG - ("First %s output reported failure to sync\n", - SDVO_NAME(sdvo_priv)); - } - - psb_intel_sdvo_set_active_outputs(psb_intel_output, - sdvo_priv->save_active_outputs); - - /*TODO: restore in_out_map*/ - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_SET_IN_OUT_MAP, - sdvo_priv->in_out_map, - 4); - - psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); -} - -static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - if (sdvo_priv->pixel_clock_min > mode->clock) - return MODE_CLOCK_LOW; - - if (sdvo_priv->pixel_clock_max < mode->clock) - return MODE_CLOCK_HIGH; - - return MODE_OK; -} - -static bool psb_intel_sdvo_get_capabilities( - struct psb_intel_output *psb_intel_output, - struct psb_intel_sdvo_caps *caps) -{ - u8 status; - - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_GET_DEVICE_CAPS, - NULL, - 0); - status = psb_intel_sdvo_read_response(psb_intel_output, - caps, - sizeof(*caps)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return false; - - return true; -} - -struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev, int sdvoB) -{ - struct drm_connector *connector = NULL; - struct psb_intel_output *iout = NULL; - struct psb_intel_sdvo_priv *sdvo; - - /* find the sdvo connector */ - list_for_each_entry(connector, &dev->mode_config.connector_list, - head) { - iout = to_psb_intel_output(connector); - - if (iout->type != INTEL_OUTPUT_SDVO) - continue; - - sdvo = iout->dev_priv; - - if (sdvo->output_device == SDVOB && sdvoB) - return connector; - - if (sdvo->output_device == SDVOC && !sdvoB) - return connector; - - } - - return NULL; -} - -int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector) -{ - u8 response[2]; - u8 status; - struct psb_intel_output *psb_intel_output; - DRM_DEBUG("\n"); - - if (!connector) - return 0; - - psb_intel_output = to_psb_intel_output(connector); - - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_GET_HOT_PLUG_SUPPORT, - NULL, - 0); - status = psb_intel_sdvo_read_response(psb_intel_output, - &response, - 2); - - if (response[0] != 0) - return 1; - - return 0; -} - -void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, int on) -{ - u8 response[2]; - u8 status; - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_GET_ACTIVE_HOT_PLUG, - NULL, - 0); - psb_intel_sdvo_read_response(psb_intel_output, &response, 2); - - if (on) { - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, - 0); - status = psb_intel_sdvo_read_response(psb_intel_output, - &response, - 2); - - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_SET_ACTIVE_HOT_PLUG, - &response, 2); - } else { - response[0] = 0; - response[1] = 0; - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_SET_ACTIVE_HOT_PLUG, - &response, 2); - } - - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_GET_ACTIVE_HOT_PLUG, - NULL, - 0); - psb_intel_sdvo_read_response(psb_intel_output, &response, 2); -} - -static enum drm_connector_status psb_intel_sdvo_detect(struct drm_connector - *connector, bool force) -{ - u8 response[2]; - u8 status; - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - - psb_intel_sdvo_write_cmd(psb_intel_output, - SDVO_CMD_GET_ATTACHED_DISPLAYS, - NULL, - 0); - status = psb_intel_sdvo_read_response(psb_intel_output, &response, 2); - - DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]); - if ((response[0] != 0) || (response[1] != 0)) - return connector_status_connected; - else - return connector_status_disconnected; -} - -static int psb_intel_sdvo_get_modes(struct drm_connector *connector) -{ - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - - /* set the bus switch and get the modes */ - psb_intel_sdvo_set_control_bus_switch(psb_intel_output, - SDVO_CONTROL_BUS_DDC2); - psb_intel_ddc_get_modes(psb_intel_output); - - if (list_empty(&connector->probed_modes)) - return 0; - return 1; -} - -static void psb_intel_sdvo_destroy(struct drm_connector *connector) -{ - struct psb_intel_output *psb_intel_output = - to_psb_intel_output(connector); - - if (psb_intel_output->i2c_bus) - psb_intel_i2c_destroy(psb_intel_output->i2c_bus); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(psb_intel_output); -} - -static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = { - .dpms = psb_intel_sdvo_dpms, - .mode_fixup = psb_intel_sdvo_mode_fixup, - .prepare = psb_intel_encoder_prepare, - .mode_set = psb_intel_sdvo_mode_set, - .commit = psb_intel_encoder_commit, -}; - -static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .save = psb_intel_sdvo_save, - .restore = psb_intel_sdvo_restore, - .detect = psb_intel_sdvo_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = psb_intel_sdvo_destroy, -}; - -static const struct drm_connector_helper_funcs - psb_intel_sdvo_connector_helper_funcs = { - .get_modes = psb_intel_sdvo_get_modes, - .mode_valid = psb_intel_sdvo_mode_valid, - .best_encoder = psb_intel_best_encoder, -}; - -void psb_intel_sdvo_enc_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); -} - -static const struct drm_encoder_funcs psb_intel_sdvo_enc_funcs = { - .destroy = psb_intel_sdvo_enc_destroy, -}; - - -void psb_intel_sdvo_init(struct drm_device *dev, int output_device) -{ - struct drm_connector *connector; - struct psb_intel_output *psb_intel_output; - struct psb_intel_sdvo_priv *sdvo_priv; - struct psb_intel_i2c_chan *i2cbus = NULL; - int connector_type; - u8 ch[0x40]; - int i; - int encoder_type, output_id; - - psb_intel_output = - kcalloc(sizeof(struct psb_intel_output) + - sizeof(struct psb_intel_sdvo_priv), 1, GFP_KERNEL); - if (!psb_intel_output) - return; - - connector = &psb_intel_output->base; - - drm_connector_init(dev, connector, &psb_intel_sdvo_connector_funcs, - DRM_MODE_CONNECTOR_Unknown); - drm_connector_helper_add(connector, - &psb_intel_sdvo_connector_helper_funcs); - sdvo_priv = (struct psb_intel_sdvo_priv *) (psb_intel_output + 1); - psb_intel_output->type = INTEL_OUTPUT_SDVO; - - connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - /* setup the DDC bus. */ - if (output_device == SDVOB) - i2cbus = - psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); - else - i2cbus = - psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); - - if (!i2cbus) - goto err_connector; - - sdvo_priv->i2c_bus = i2cbus; - - if (output_device == SDVOB) { - output_id = 1; - sdvo_priv->by_input_wiring = SDVOB_IN0; - sdvo_priv->i2c_bus->slave_addr = 0x38; - } else { - output_id = 2; - sdvo_priv->i2c_bus->slave_addr = 0x39; - } - - sdvo_priv->output_device = output_device; - psb_intel_output->i2c_bus = i2cbus; - psb_intel_output->dev_priv = sdvo_priv; - - - /* Read the regs to test if we can talk to the device */ - for (i = 0; i < 0x40; i++) { - if (!psb_intel_sdvo_read_byte(psb_intel_output, i, &ch[i])) { - DRM_DEBUG("No SDVO device found on SDVO%c\n", - output_device == SDVOB ? 'B' : 'C'); - goto err_i2c; - } - } - - psb_intel_sdvo_get_capabilities(psb_intel_output, &sdvo_priv->caps); - - memset(&sdvo_priv->active_outputs, 0, - sizeof(sdvo_priv->active_outputs)); - - /* TODO, CVBS, SVID, YPRPB & SCART outputs. */ - if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) { - sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0; - sdvo_priv->active_device = SDVO_DEVICE_CRT; - connector->display_info.subpixel_order = - SubPixelHorizontalRGB; - encoder_type = DRM_MODE_ENCODER_DAC; - connector_type = DRM_MODE_CONNECTOR_VGA; - } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) { - sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1; - sdvo_priv->active_outputs = SDVO_DEVICE_CRT; - connector->display_info.subpixel_order = - SubPixelHorizontalRGB; - encoder_type = DRM_MODE_ENCODER_DAC; - connector_type = DRM_MODE_CONNECTOR_VGA; - } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) { - sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0; - sdvo_priv->active_device = SDVO_DEVICE_TMDS; - connector->display_info.subpixel_order = - SubPixelHorizontalRGB; - encoder_type = DRM_MODE_ENCODER_TMDS; - connector_type = DRM_MODE_CONNECTOR_DVID; - } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1) { - sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1; - sdvo_priv->active_device = SDVO_DEVICE_TMDS; - connector->display_info.subpixel_order = - SubPixelHorizontalRGB; - encoder_type = DRM_MODE_ENCODER_TMDS; - connector_type = DRM_MODE_CONNECTOR_DVID; - } else { - unsigned char bytes[2]; - - memcpy(bytes, &sdvo_priv->caps.output_flags, 2); - DRM_DEBUG - ("%s: No active RGB or TMDS outputs (0x%02x%02x)\n", - SDVO_NAME(sdvo_priv), bytes[0], bytes[1]); - goto err_i2c; - } - - drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_sdvo_enc_funcs, - encoder_type); - drm_encoder_helper_add(&psb_intel_output->enc, - &psb_intel_sdvo_helper_funcs); - connector->connector_type = connector_type; - - drm_mode_connector_attach_encoder(&psb_intel_output->base, - &psb_intel_output->enc); - drm_sysfs_connector_add(connector); - - /* Set the input timing to the screen. Assume always input 0. */ - psb_intel_sdvo_set_target_input(psb_intel_output, true, false); - - psb_intel_sdvo_get_input_pixel_clock_range(psb_intel_output, - &sdvo_priv->pixel_clock_min, - &sdvo_priv-> - pixel_clock_max); - - - DRM_DEBUG("%s device VID/DID: %02X:%02X.%02X, " - "clock range %dMHz - %dMHz, " - "input 1: %c, input 2: %c, " - "output 1: %c, output 2: %c\n", - SDVO_NAME(sdvo_priv), - sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id, - sdvo_priv->caps.device_rev_id, - sdvo_priv->pixel_clock_min / 1000, - sdvo_priv->pixel_clock_max / 1000, - (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', - (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', - /* check currently supported outputs */ - sdvo_priv->caps.output_flags & - (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', - sdvo_priv->caps.output_flags & - (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); - - psb_intel_output->ddc_bus = i2cbus; - - return; - -err_i2c: - psb_intel_i2c_destroy(psb_intel_output->i2c_bus); -err_connector: - drm_connector_cleanup(connector); - kfree(psb_intel_output); - - return; -} diff --git a/drivers/staging/gma500/psb_intel_sdvo_regs.h b/drivers/staging/gma500/psb_intel_sdvo_regs.h deleted file mode 100644 index c7107a37e33..00000000000 --- a/drivers/staging/gma500/psb_intel_sdvo_regs.h +++ /dev/null @@ -1,338 +0,0 @@ -/* - * SDVO command definitions and structures. - * - * Copyright (c) 2008, Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt <eric@anholt.net> - */ - -#define SDVO_OUTPUT_FIRST (0) -#define SDVO_OUTPUT_TMDS0 (1 << 0) -#define SDVO_OUTPUT_RGB0 (1 << 1) -#define SDVO_OUTPUT_CVBS0 (1 << 2) -#define SDVO_OUTPUT_SVID0 (1 << 3) -#define SDVO_OUTPUT_YPRPB0 (1 << 4) -#define SDVO_OUTPUT_SCART0 (1 << 5) -#define SDVO_OUTPUT_LVDS0 (1 << 6) -#define SDVO_OUTPUT_TMDS1 (1 << 8) -#define SDVO_OUTPUT_RGB1 (1 << 9) -#define SDVO_OUTPUT_CVBS1 (1 << 10) -#define SDVO_OUTPUT_SVID1 (1 << 11) -#define SDVO_OUTPUT_YPRPB1 (1 << 12) -#define SDVO_OUTPUT_SCART1 (1 << 13) -#define SDVO_OUTPUT_LVDS1 (1 << 14) -#define SDVO_OUTPUT_LAST (14) - -struct psb_intel_sdvo_caps { - u8 vendor_id; - u8 device_id; - u8 device_rev_id; - u8 sdvo_version_major; - u8 sdvo_version_minor; - unsigned int sdvo_inputs_mask:2; - unsigned int smooth_scaling:1; - unsigned int sharp_scaling:1; - unsigned int up_scaling:1; - unsigned int down_scaling:1; - unsigned int stall_support:1; - unsigned int pad:1; - u16 output_flags; -} __attribute__ ((packed)); - -/** This matches the EDID DTD structure, more or less */ -struct psb_intel_sdvo_dtd { - struct { - u16 clock; /**< pixel clock, in 10kHz units */ - u8 h_active; /**< lower 8 bits (pixels) */ - u8 h_blank; /**< lower 8 bits (pixels) */ - u8 h_high; /**< upper 4 bits each h_active, h_blank */ - u8 v_active; /**< lower 8 bits (lines) */ - u8 v_blank; /**< lower 8 bits (lines) */ - u8 v_high; /**< upper 4 bits each v_active, v_blank */ - } part1; - - struct { - u8 h_sync_off; - /**< lower 8 bits, from hblank start */ - u8 h_sync_width;/**< lower 8 bits (pixels) */ - /** lower 4 bits each vsync offset, vsync width */ - u8 v_sync_off_width; - /** - * 2 high bits of hsync offset, 2 high bits of hsync width, - * bits 4-5 of vsync offset, and 2 high bits of vsync width. - */ - u8 sync_off_width_high; - u8 dtd_flags; - u8 sdvo_flags; - /** bits 6-7 of vsync offset at bits 6-7 */ - u8 v_sync_off_high; - u8 reserved; - } part2; -} __attribute__ ((packed)); - -struct psb_intel_sdvo_pixel_clock_range { - u16 min; /**< pixel clock, in 10kHz units */ - u16 max; /**< pixel clock, in 10kHz units */ -} __attribute__ ((packed)); - -struct psb_intel_sdvo_preferred_input_timing_args { - u16 clock; - u16 width; - u16 height; -} __attribute__ ((packed)); - -/* I2C registers for SDVO */ -#define SDVO_I2C_ARG_0 0x07 -#define SDVO_I2C_ARG_1 0x06 -#define SDVO_I2C_ARG_2 0x05 -#define SDVO_I2C_ARG_3 0x04 -#define SDVO_I2C_ARG_4 0x03 -#define SDVO_I2C_ARG_5 0x02 -#define SDVO_I2C_ARG_6 0x01 -#define SDVO_I2C_ARG_7 0x00 -#define SDVO_I2C_OPCODE 0x08 -#define SDVO_I2C_CMD_STATUS 0x09 -#define SDVO_I2C_RETURN_0 0x0a -#define SDVO_I2C_RETURN_1 0x0b -#define SDVO_I2C_RETURN_2 0x0c -#define SDVO_I2C_RETURN_3 0x0d -#define SDVO_I2C_RETURN_4 0x0e -#define SDVO_I2C_RETURN_5 0x0f -#define SDVO_I2C_RETURN_6 0x10 -#define SDVO_I2C_RETURN_7 0x11 -#define SDVO_I2C_VENDOR_BEGIN 0x20 - -/* Status results */ -#define SDVO_CMD_STATUS_POWER_ON 0x0 -#define SDVO_CMD_STATUS_SUCCESS 0x1 -#define SDVO_CMD_STATUS_NOTSUPP 0x2 -#define SDVO_CMD_STATUS_INVALID_ARG 0x3 -#define SDVO_CMD_STATUS_PENDING 0x4 -#define SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED 0x5 -#define SDVO_CMD_STATUS_SCALING_NOT_SUPP 0x6 - -/* SDVO commands, argument/result registers */ - -#define SDVO_CMD_RESET 0x01 - -/** Returns a struct psb_intel_sdvo_caps */ -#define SDVO_CMD_GET_DEVICE_CAPS 0x02 - -#define SDVO_CMD_GET_FIRMWARE_REV 0x86 -# define SDVO_DEVICE_FIRMWARE_MINOR SDVO_I2C_RETURN_0 -# define SDVO_DEVICE_FIRMWARE_MAJOR SDVO_I2C_RETURN_1 -# define SDVO_DEVICE_FIRMWARE_PATCH SDVO_I2C_RETURN_2 - -/** - * Reports which inputs are trained (managed to sync). - * - * Devices must have trained within 2 vsyncs of a mode change. - */ -#define SDVO_CMD_GET_TRAINED_INPUTS 0x03 -struct psb_intel_sdvo_get_trained_inputs_response { - unsigned int input0_trained:1; - unsigned int input1_trained:1; - unsigned int pad:6; -} __attribute__ ((packed)); - -/** Returns a struct psb_intel_sdvo_output_flags of active outputs. */ -#define SDVO_CMD_GET_ACTIVE_OUTPUTS 0x04 - -/** - * Sets the current set of active outputs. - * - * Takes a struct psb_intel_sdvo_output_flags. - * Must be preceded by a SET_IN_OUT_MAP - * on multi-output devices. - */ -#define SDVO_CMD_SET_ACTIVE_OUTPUTS 0x05 - -/** - * Returns the current mapping of SDVO inputs to outputs on the device. - * - * Returns two struct psb_intel_sdvo_output_flags structures. - */ -#define SDVO_CMD_GET_IN_OUT_MAP 0x06 - -/** - * Sets the current mapping of SDVO inputs to outputs on the device. - * - * Takes two struct i380_sdvo_output_flags structures. - */ -#define SDVO_CMD_SET_IN_OUT_MAP 0x07 - -/** - * Returns a struct psb_intel_sdvo_output_flags of attached displays. - */ -#define SDVO_CMD_GET_ATTACHED_DISPLAYS 0x0b - -/** - * Returns a struct psb_intel_sdvo_ouptut_flags of displays supporting hot plugging. - */ -#define SDVO_CMD_GET_HOT_PLUG_SUPPORT 0x0c - -/** - * Takes a struct psb_intel_sdvo_output_flags. - */ -#define SDVO_CMD_SET_ACTIVE_HOT_PLUG 0x0d - -/** - * Returns a struct psb_intel_sdvo_output_flags of displays with hot plug - * interrupts enabled. - */ -#define SDVO_CMD_GET_ACTIVE_HOT_PLUG 0x0e - -#define SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE 0x0f -struct psb_intel_sdvo_get_interrupt_event_source_response { - u16 interrupt_status; - unsigned int ambient_light_interrupt:1; - unsigned int pad:7; -} __attribute__ ((packed)); - -/** - * Selects which input is affected by future input commands. - * - * Commands affected include SET_INPUT_TIMINGS_PART[12], - * GET_INPUT_TIMINGS_PART[12], GET_PREFERRED_INPUT_TIMINGS_PART[12], - * GET_INPUT_PIXEL_CLOCK_RANGE, and CREATE_PREFERRED_INPUT_TIMINGS. - */ -#define SDVO_CMD_SET_TARGET_INPUT 0x10 -struct psb_intel_sdvo_set_target_input_args { - unsigned int target_1:1; - unsigned int pad:7; -} __attribute__ ((packed)); - -/** - * Takes a struct psb_intel_sdvo_output_flags of which outputs are targeted by - * future output commands. - * - * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12], - * GET_OUTPUT_TIMINGS_PART[12], and GET_OUTPUT_PIXEL_CLOCK_RANGE. - */ -#define SDVO_CMD_SET_TARGET_OUTPUT 0x11 - -#define SDVO_CMD_GET_INPUT_TIMINGS_PART1 0x12 -#define SDVO_CMD_GET_INPUT_TIMINGS_PART2 0x13 -#define SDVO_CMD_SET_INPUT_TIMINGS_PART1 0x14 -#define SDVO_CMD_SET_INPUT_TIMINGS_PART2 0x15 -#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART1 0x16 -#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART2 0x17 -#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART1 0x18 -#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART2 0x19 -/* Part 1 */ -# define SDVO_DTD_CLOCK_LOW SDVO_I2C_ARG_0 -# define SDVO_DTD_CLOCK_HIGH SDVO_I2C_ARG_1 -# define SDVO_DTD_H_ACTIVE SDVO_I2C_ARG_2 -# define SDVO_DTD_H_BLANK SDVO_I2C_ARG_3 -# define SDVO_DTD_H_HIGH SDVO_I2C_ARG_4 -# define SDVO_DTD_V_ACTIVE SDVO_I2C_ARG_5 -# define SDVO_DTD_V_BLANK SDVO_I2C_ARG_6 -# define SDVO_DTD_V_HIGH SDVO_I2C_ARG_7 -/* Part 2 */ -# define SDVO_DTD_HSYNC_OFF SDVO_I2C_ARG_0 -# define SDVO_DTD_HSYNC_WIDTH SDVO_I2C_ARG_1 -# define SDVO_DTD_VSYNC_OFF_WIDTH SDVO_I2C_ARG_2 -# define SDVO_DTD_SYNC_OFF_WIDTH_HIGH SDVO_I2C_ARG_3 -# define SDVO_DTD_DTD_FLAGS SDVO_I2C_ARG_4 -# define SDVO_DTD_DTD_FLAG_INTERLACED (1 << 7) -# define SDVO_DTD_DTD_FLAG_STEREO_MASK (3 << 5) -# define SDVO_DTD_DTD_FLAG_INPUT_MASK (3 << 3) -# define SDVO_DTD_DTD_FLAG_SYNC_MASK (3 << 1) -# define SDVO_DTD_SDVO_FLAS SDVO_I2C_ARG_5 -# define SDVO_DTD_SDVO_FLAG_STALL (1 << 7) -# define SDVO_DTD_SDVO_FLAG_CENTERED (0 << 6) -# define SDVO_DTD_SDVO_FLAG_UPPER_LEFT (1 << 6) -# define SDVO_DTD_SDVO_FLAG_SCALING_MASK (3 << 4) -# define SDVO_DTD_SDVO_FLAG_SCALING_NONE (0 << 4) -# define SDVO_DTD_SDVO_FLAG_SCALING_SHARP (1 << 4) -# define SDVO_DTD_SDVO_FLAG_SCALING_SMOOTH (2 << 4) -# define SDVO_DTD_VSYNC_OFF_HIGH SDVO_I2C_ARG_6 - -/** - * Generates a DTD based on the given width, height, and flags. - * - * This will be supported by any device supporting scaling or interlaced - * modes. - */ -#define SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING 0x1a -# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_LOW SDVO_I2C_ARG_0 -# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_HIGH SDVO_I2C_ARG_1 -# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_LOW SDVO_I2C_ARG_2 -# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_HIGH SDVO_I2C_ARG_3 -# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_LOW SDVO_I2C_ARG_4 -# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_HIGH SDVO_I2C_ARG_5 -# define SDVO_PREFERRED_INPUT_TIMING_FLAGS SDVO_I2C_ARG_6 -# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_INTERLACED (1 << 0) -# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_SCALED (1 << 1) - -#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1 0x1b -#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2 0x1c - -/** Returns a struct psb_intel_sdvo_pixel_clock_range */ -#define SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE 0x1d -/** Returns a struct psb_intel_sdvo_pixel_clock_range */ -#define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE 0x1e - -/** Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */ -#define SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS 0x1f - -/** Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ -#define SDVO_CMD_GET_CLOCK_RATE_MULT 0x20 -/** Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ -#define SDVO_CMD_SET_CLOCK_RATE_MULT 0x21 -# define SDVO_CLOCK_RATE_MULT_1X (1 << 0) -# define SDVO_CLOCK_RATE_MULT_2X (1 << 1) -# define SDVO_CLOCK_RATE_MULT_4X (1 << 3) - -#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 - -#define SDVO_CMD_GET_TV_FORMAT 0x28 - -#define SDVO_CMD_SET_TV_FORMAT 0x29 - -#define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a -#define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b -#define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c -# define SDVO_ENCODER_STATE_ON (1 << 0) -# define SDVO_ENCODER_STATE_STANDBY (1 << 1) -# define SDVO_ENCODER_STATE_SUSPEND (1 << 2) -# define SDVO_ENCODER_STATE_OFF (1 << 3) - -#define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT 0x93 - -#define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a -# define SDVO_CONTROL_BUS_PROM 0x0 -# define SDVO_CONTROL_BUS_DDC1 0x1 -# define SDVO_CONTROL_BUS_DDC2 0x2 -# define SDVO_CONTROL_BUS_DDC3 0x3 - -/* SDVO Bus & SDVO Inputs wiring details*/ -/* Bit 0: Is SDVOB connected to In0 (1 = yes, 0 = no*/ -/* Bit 1: Is SDVOB connected to In1 (1 = yes, 0 = no*/ -/* Bit 2: Is SDVOC connected to In0 (1 = yes, 0 = no*/ -/* Bit 3: Is SDVOC connected to In1 (1 = yes, 0 = no*/ -#define SDVOB_IN0 0x01 -#define SDVOB_IN1 0x02 -#define SDVOC_IN0 0x04 -#define SDVOC_IN1 0x08 - -#define SDVO_DEVICE_NONE 0x00 -#define SDVO_DEVICE_CRT 0x01 -#define SDVO_DEVICE_TV 0x02 -#define SDVO_DEVICE_LVDS 0x04 -#define SDVO_DEVICE_TMDS 0x08 - diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c deleted file mode 100644 index 9ea37e58887..00000000000 --- a/drivers/staging/gma500/psb_irq.c +++ /dev/null @@ -1,575 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - * develop this driver. - * - **************************************************************************/ -/* - */ - -#include <drm/drmP.h> -#include "psb_drv.h" -#include "psb_reg.h" -#include "psb_intel_reg.h" -#include "psb_powermgmt.h" - - -/* - * inline functions - */ - -static inline u32 -psb_pipestat(int pipe) -{ - if (pipe == 0) - return PIPEASTAT; - if (pipe == 1) - return PIPEBSTAT; - if (pipe == 2) - return PIPECSTAT; - BUG(); -} - -static inline u32 -mid_pipe_event(int pipe) -{ - if (pipe == 0) - return _PSB_PIPEA_EVENT_FLAG; - if (pipe == 1) - return _MDFLD_PIPEB_EVENT_FLAG; - if (pipe == 2) - return _MDFLD_PIPEC_EVENT_FLAG; - BUG(); -} - -static inline u32 -mid_pipe_vsync(int pipe) -{ - if (pipe == 0) - return _PSB_VSYNC_PIPEA_FLAG; - if (pipe == 1) - return _PSB_VSYNC_PIPEB_FLAG; - if (pipe == 2) - return _MDFLD_PIPEC_VBLANK_FLAG; - BUG(); -} - -static inline u32 -mid_pipeconf(int pipe) -{ - if (pipe == 0) - return PIPEACONF; - if (pipe == 1) - return PIPEBCONF; - if (pipe == 2) - return PIPECCONF; - BUG(); -} - -void -psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) -{ - if ((dev_priv->pipestat[pipe] & mask) != mask) { - u32 reg = psb_pipestat(pipe); - dev_priv->pipestat[pipe] |= mask; - /* Enable the interrupt, clear any pending status */ - if (gma_power_begin(dev_priv->dev, false)) { - u32 writeVal = PSB_RVDC32(reg); - writeVal |= (mask | (mask >> 16)); - PSB_WVDC32(writeVal, reg); - (void) PSB_RVDC32(reg); - gma_power_end(dev_priv->dev); - } - } -} - -void -psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) -{ - if ((dev_priv->pipestat[pipe] & mask) != 0) { - u32 reg = psb_pipestat(pipe); - dev_priv->pipestat[pipe] &= ~mask; - if (gma_power_begin(dev_priv->dev, false)) { - u32 writeVal = PSB_RVDC32(reg); - writeVal &= ~mask; - PSB_WVDC32(writeVal, reg); - (void) PSB_RVDC32(reg); - gma_power_end(dev_priv->dev); - } - } -} - -void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe) -{ - if (gma_power_begin(dev_priv->dev, false)) { - u32 pipe_event = mid_pipe_event(pipe); - dev_priv->vdc_irq_mask |= pipe_event; - PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); - PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); - gma_power_end(dev_priv->dev); - } -} - -void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe) -{ - if (dev_priv->pipestat[pipe] == 0) { - if (gma_power_begin(dev_priv->dev, false)) { - u32 pipe_event = mid_pipe_event(pipe); - dev_priv->vdc_irq_mask &= ~pipe_event; - PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); - PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); - gma_power_end(dev_priv->dev); - } - } -} - -/** - * Display controller interrupt handler for vsync/vblank. - * - */ -static void mid_vblank_handler(struct drm_device *dev, uint32_t pipe) -{ - drm_handle_vblank(dev, pipe); -} - - -/** - * Display controller interrupt handler for pipe event. - * - */ -#define WAIT_STATUS_CLEAR_LOOP_COUNT 0xffff -static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - - uint32_t pipe_stat_val = 0; - uint32_t pipe_stat_reg = psb_pipestat(pipe); - uint32_t pipe_enable = dev_priv->pipestat[pipe]; - uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16; - uint32_t i = 0; - - spin_lock(&dev_priv->irqmask_lock); - - pipe_stat_val = PSB_RVDC32(pipe_stat_reg); - pipe_stat_val &= pipe_enable | pipe_status; - pipe_stat_val &= pipe_stat_val >> 16; - - spin_unlock(&dev_priv->irqmask_lock); - - /* clear the 2nd level interrupt status bits */ - /** - * FIXME: shouldn't use while loop here. However, the interrupt - * status 'sticky' bits cannot be cleared by setting '1' to that - * bit once... - */ - for (i = 0; i < WAIT_STATUS_CLEAR_LOOP_COUNT; i++) { - PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg); - (void) PSB_RVDC32(pipe_stat_reg); - - if ((PSB_RVDC32(pipe_stat_reg) & pipe_status) == 0) - break; - } - - if (i == WAIT_STATUS_CLEAR_LOOP_COUNT) - DRM_ERROR("%s, can't clear the status bits in pipe_stat_reg, its value = 0x%x.\n", - __func__, PSB_RVDC32(pipe_stat_reg)); - - if (pipe_stat_val & PIPE_VBLANK_STATUS) - mid_vblank_handler(dev, pipe); - - if (pipe_stat_val & PIPE_TE_STATUS) - drm_handle_vblank(dev, pipe); -} - -/* - * Display controller interrupt handler. - */ -static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) -{ - if (vdc_stat & _PSB_PIPEA_EVENT_FLAG) - mid_pipe_event_handler(dev, 0); -} - -irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - - uint32_t vdc_stat, dsp_int = 0, sgx_int = 0; - int handled = 0; - - spin_lock(&dev_priv->irqmask_lock); - - vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R); - - if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG) { - PSB_DEBUG_IRQ("Got DISP interrupt\n"); - dsp_int = 1; - } - - if (vdc_stat & _PSB_IRQ_SGX_FLAG) { - PSB_DEBUG_IRQ("Got SGX interrupt\n"); - sgx_int = 1; - } - if (vdc_stat & _PSB_IRQ_MSVDX_FLAG) - PSB_DEBUG_IRQ("Got MSVDX interrupt\n"); - - if (vdc_stat & _LNC_IRQ_TOPAZ_FLAG) - PSB_DEBUG_IRQ("Got TOPAZ interrupt\n"); - - - vdc_stat &= dev_priv->vdc_irq_mask; - spin_unlock(&dev_priv->irqmask_lock); - - if (dsp_int && gma_power_is_on(dev)) { - psb_vdc_interrupt(dev, vdc_stat); - handled = 1; - } - - if (sgx_int) { - /* Not expected - we have it masked, shut it up */ - u32 s, s2; - s = PSB_RSGX32(PSB_CR_EVENT_STATUS); - s2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2); - PSB_WSGX32(s, PSB_CR_EVENT_HOST_CLEAR); - PSB_WSGX32(s2, PSB_CR_EVENT_HOST_CLEAR2); - /* if s & _PSB_CE_TWOD_COMPLETE we have 2D done but - we may as well poll even if we add that ! */ - handled = 1; - } - - PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R); - (void) PSB_RVDC32(PSB_INT_IDENTITY_R); - DRM_READMEMORYBARRIER(); - - if (!handled) - return IRQ_NONE; - - return IRQ_HANDLED; -} - -void psb_irq_preinstall(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - if (gma_power_is_on(dev)) - PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - if (dev->vblank_enabled[0]) - dev_priv->vdc_irq_mask |= _PSB_PIPEA_EVENT_FLAG; - if (dev->vblank_enabled[1]) - dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG; - if (dev->vblank_enabled[2]) - dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; - - /*This register is safe even if display island is off*/ - PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); -} - -int psb_irq_postinstall(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - unsigned long irqflags; - - PSB_DEBUG_ENTRY("\n"); - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - /* This register is safe even if display island is off */ - PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); - PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - - if (dev->vblank_enabled[0]) - psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); - else - psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank_enabled[1]) - psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); - else - psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank_enabled[2]) - psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); - else - psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); - - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - return 0; -} - -void psb_irq_uninstall(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - unsigned long irqflags; - - PSB_DEBUG_ENTRY("\n"); - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - - if (dev->vblank_enabled[0]) - psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank_enabled[1]) - psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank_enabled[2]) - psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); - - dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG | - _PSB_IRQ_MSVDX_FLAG | - _LNC_IRQ_TOPAZ_FLAG; - - /* These two registers are safe even if display island is off */ - PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); - PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); - - wmb(); - - /* This register is safe even if display island is off */ - PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R); - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); -} - -void psb_irq_turn_on_dpst(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - u32 hist_reg; - u32 pwm_reg; - - if (gma_power_begin(dev, false)) { - PSB_WVDC32(1 << 31, HISTOGRAM_LOGIC_CONTROL); - hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); - PSB_WVDC32(1 << 31, HISTOGRAM_INT_CONTROL); - hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); - - PSB_WVDC32(0x80010100, PWM_CONTROL_LOGIC); - pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); - PSB_WVDC32(pwm_reg | PWM_PHASEIN_ENABLE - | PWM_PHASEIN_INT_ENABLE, - PWM_CONTROL_LOGIC); - pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); - - psb_enable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); - - hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); - PSB_WVDC32(hist_reg | HISTOGRAM_INT_CTRL_CLEAR, - HISTOGRAM_INT_CONTROL); - pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); - PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE, - PWM_CONTROL_LOGIC); - - gma_power_end(dev); - } -} - -int psb_irq_enable_dpst(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - unsigned long irqflags; - - PSB_DEBUG_ENTRY("\n"); - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - /* enable DPST */ - mid_enable_pipe_event(dev_priv, 0); - psb_irq_turn_on_dpst(dev); - - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - return 0; -} - -void psb_irq_turn_off_dpst(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - u32 hist_reg; - u32 pwm_reg; - - if (gma_power_begin(dev, false)) { - PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL); - hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); - - psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); - - pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); - PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE), - PWM_CONTROL_LOGIC); - pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); - - gma_power_end(dev); - } -} - -int psb_irq_disable_dpst(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - unsigned long irqflags; - - PSB_DEBUG_ENTRY("\n"); - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - mid_disable_pipe_event(dev_priv, 0); - psb_irq_turn_off_dpst(dev); - - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - - return 0; -} - -#ifdef PSB_FIXME -static int psb_vblank_do_wait(struct drm_device *dev, - unsigned int *sequence, atomic_t *counter) -{ - unsigned int cur_vblank; - int ret = 0; - DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, - (((cur_vblank = atomic_read(counter)) - - *sequence) <= (1 << 23))); - *sequence = cur_vblank; - - return ret; -} -#endif - -/* - * It is used to enable VBLANK interrupt - */ -int psb_enable_vblank(struct drm_device *dev, int pipe) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long irqflags; - uint32_t reg_val = 0; - uint32_t pipeconf_reg = mid_pipeconf(pipe); - - PSB_DEBUG_ENTRY("\n"); - - if (gma_power_begin(dev, false)) { - reg_val = REG_READ(pipeconf_reg); - gma_power_end(dev); - } - - if (!(reg_val & PIPEACONF_ENABLE)) - return -EINVAL; - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - mid_enable_pipe_event(dev_priv, pipe); - psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); - - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - - return 0; -} - -/* - * It is used to disable VBLANK interrupt - */ -void psb_disable_vblank(struct drm_device *dev, int pipe) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long irqflags; - - PSB_DEBUG_ENTRY("\n"); - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - mid_disable_pipe_event(dev_priv, pipe); - psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); - - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); -} - -/* Called from drm generic code, passed a 'crtc', which - * we use as a pipe index - */ -u32 psb_get_vblank_counter(struct drm_device *dev, int pipe) -{ - uint32_t high_frame = PIPEAFRAMEHIGH; - uint32_t low_frame = PIPEAFRAMEPIXEL; - uint32_t pipeconf_reg = PIPEACONF; - uint32_t reg_val = 0; - uint32_t high1 = 0, high2 = 0, low = 0, count = 0; - - switch (pipe) { - case 0: - break; - case 1: - high_frame = PIPEBFRAMEHIGH; - low_frame = PIPEBFRAMEPIXEL; - pipeconf_reg = PIPEBCONF; - break; - case 2: - high_frame = PIPECFRAMEHIGH; - low_frame = PIPECFRAMEPIXEL; - pipeconf_reg = PIPECCONF; - break; - default: - DRM_ERROR("%s, invalded pipe.\n", __func__); - return 0; - } - - if (!gma_power_begin(dev, false)) - return 0; - - reg_val = REG_READ(pipeconf_reg); - - if (!(reg_val & PIPEACONF_ENABLE)) { - DRM_ERROR("trying to get vblank count for disabled pipe %d\n", - pipe); - goto psb_get_vblank_counter_exit; - } - - /* - * High & low register fields aren't synchronized, so make sure - * we get a low value that's stable across two reads of the high - * register. - */ - do { - high1 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> - PIPE_FRAME_HIGH_SHIFT); - low = ((REG_READ(low_frame) & PIPE_FRAME_LOW_MASK) >> - PIPE_FRAME_LOW_SHIFT); - high2 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> - PIPE_FRAME_HIGH_SHIFT); - } while (high1 != high2); - - count = (high1 << 8) | low; - -psb_get_vblank_counter_exit: - - gma_power_end(dev); - - return count; -} - diff --git a/drivers/staging/gma500/psb_irq.h b/drivers/staging/gma500/psb_irq.h deleted file mode 100644 index 3e56f33efa6..00000000000 --- a/drivers/staging/gma500/psb_irq.h +++ /dev/null @@ -1,49 +0,0 @@ -/************************************************************************** - * Copyright (c) 2009, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Benjamin Defnet <benjamin.r.defnet@intel.com> - * Rajesh Poornachandran <rajesh.poornachandran@intel.com> - * - **************************************************************************/ - -#ifndef _SYSIRQ_H_ -#define _SYSIRQ_H_ - -#include <drm/drmP.h> - -bool sysirq_init(struct drm_device *dev); -void sysirq_uninit(struct drm_device *dev); - -void psb_irq_preinstall(struct drm_device *dev); -int psb_irq_postinstall(struct drm_device *dev); -void psb_irq_uninstall(struct drm_device *dev); -irqreturn_t psb_irq_handler(DRM_IRQ_ARGS); - -void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands); -int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands); -void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands); - -int psb_irq_enable_dpst(struct drm_device *dev); -int psb_irq_disable_dpst(struct drm_device *dev); -void psb_irq_turn_on_dpst(struct drm_device *dev); -void psb_irq_turn_off_dpst(struct drm_device *dev); -int psb_enable_vblank(struct drm_device *dev, int pipe); -void psb_disable_vblank(struct drm_device *dev, int pipe); -u32 psb_get_vblank_counter(struct drm_device *dev, int pipe); - -#endif //_SYSIRQ_H_ diff --git a/drivers/staging/gma500/psb_lid.c b/drivers/staging/gma500/psb_lid.c deleted file mode 100644 index 21fd202f293..00000000000 --- a/drivers/staging/gma500/psb_lid.c +++ /dev/null @@ -1,90 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> - **************************************************************************/ - -#include <drm/drmP.h> -#include "psb_drv.h" -#include "psb_reg.h" -#include "psb_intel_reg.h" -#include <linux/spinlock.h> - -static void psb_lid_timer_func(unsigned long data) -{ - struct drm_psb_private * dev_priv = (struct drm_psb_private *)data; - struct drm_device *dev = (struct drm_device *)dev_priv->dev; - struct timer_list *lid_timer = &dev_priv->lid_timer; - unsigned long irq_flags; - u32 *lid_state = dev_priv->lid_state; - u32 pp_status; - - if (*lid_state == dev_priv->lid_last_state) - goto lid_timer_schedule; - - if ((*lid_state) & 0x01) { - /*lid state is open*/ - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while ((pp_status & PP_ON) == 0); - - /*FIXME: should be backlight level before*/ - psb_intel_lvds_set_brightness(dev, 100); - } else { - psb_intel_lvds_set_brightness(dev, 0); - - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while ((pp_status & PP_ON) == 0); - } - /* printk(KERN_INFO"%s: lid: closed\n", __FUNCTION__); */ - - dev_priv->lid_last_state = *lid_state; - -lid_timer_schedule: - spin_lock_irqsave(&dev_priv->lid_lock, irq_flags); - if (!timer_pending(lid_timer)) { - lid_timer->expires = jiffies + PSB_LID_DELAY; - add_timer(lid_timer); - } - spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags); -} - -void psb_lid_timer_init(struct drm_psb_private *dev_priv) -{ - struct timer_list *lid_timer = &dev_priv->lid_timer; - unsigned long irq_flags; - - spin_lock_init(&dev_priv->lid_lock); - spin_lock_irqsave(&dev_priv->lid_lock, irq_flags); - - init_timer(lid_timer); - - lid_timer->data = (unsigned long)dev_priv; - lid_timer->function = psb_lid_timer_func; - lid_timer->expires = jiffies + PSB_LID_DELAY; - - add_timer(lid_timer); - spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags); -} - -void psb_lid_timer_takedown(struct drm_psb_private *dev_priv) -{ - del_timer_sync(&dev_priv->lid_timer); -} - diff --git a/drivers/staging/gma500/psb_mmu.c b/drivers/staging/gma500/psb_mmu.c deleted file mode 100644 index c904d73b1de..00000000000 --- a/drivers/staging/gma500/psb_mmu.c +++ /dev/null @@ -1,858 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ -#include <drm/drmP.h> -#include "psb_drv.h" -#include "psb_reg.h" - -/* - * Code for the SGX MMU: - */ - -/* - * clflush on one processor only: - * clflush should apparently flush the cache line on all processors in an - * SMP system. - */ - -/* - * kmap atomic: - * The usage of the slots must be completely encapsulated within a spinlock, and - * no other functions that may be using the locks for other purposed may be - * called from within the locked region. - * Since the slots are per processor, this will guarantee that we are the only - * user. - */ - -/* - * TODO: Inserting ptes from an interrupt handler: - * This may be desirable for some SGX functionality where the GPU can fault in - * needed pages. For that, we need to make an atomic insert_pages function, that - * may fail. - * If it fails, the caller need to insert the page using a workqueue function, - * but on average it should be fast. - */ - -struct psb_mmu_driver { - /* protects driver- and pd structures. Always take in read mode - * before taking the page table spinlock. - */ - struct rw_semaphore sem; - - /* protects page tables, directory tables and pt tables. - * and pt structures. - */ - spinlock_t lock; - - atomic_t needs_tlbflush; - - uint8_t __iomem *register_map; - struct psb_mmu_pd *default_pd; - /*uint32_t bif_ctrl;*/ - int has_clflush; - int clflush_add; - unsigned long clflush_mask; - - struct drm_psb_private *dev_priv; -}; - -struct psb_mmu_pd; - -struct psb_mmu_pt { - struct psb_mmu_pd *pd; - uint32_t index; - uint32_t count; - struct page *p; - uint32_t *v; -}; - -struct psb_mmu_pd { - struct psb_mmu_driver *driver; - int hw_context; - struct psb_mmu_pt **tables; - struct page *p; - struct page *dummy_pt; - struct page *dummy_page; - uint32_t pd_mask; - uint32_t invalid_pde; - uint32_t invalid_pte; -}; - -static inline uint32_t psb_mmu_pt_index(uint32_t offset) -{ - return (offset >> PSB_PTE_SHIFT) & 0x3FF; -} - -static inline uint32_t psb_mmu_pd_index(uint32_t offset) -{ - return offset >> PSB_PDE_SHIFT; -} - -static inline void psb_clflush(void *addr) -{ - __asm__ __volatile__("clflush (%0)\n" : : "r"(addr) : "memory"); -} - -static inline void psb_mmu_clflush(struct psb_mmu_driver *driver, - void *addr) -{ - if (!driver->has_clflush) - return; - - mb(); - psb_clflush(addr); - mb(); -} - -static void psb_page_clflush(struct psb_mmu_driver *driver, struct page* page) -{ - uint32_t clflush_add = driver->clflush_add >> PAGE_SHIFT; - uint32_t clflush_count = PAGE_SIZE / clflush_add; - int i; - uint8_t *clf; - - clf = kmap_atomic(page, KM_USER0); - mb(); - for (i = 0; i < clflush_count; ++i) { - psb_clflush(clf); - clf += clflush_add; - } - mb(); - kunmap_atomic(clf, KM_USER0); -} - -static void psb_pages_clflush(struct psb_mmu_driver *driver, - struct page *page[], unsigned long num_pages) -{ - int i; - - if (!driver->has_clflush) - return ; - - for (i = 0; i < num_pages; i++) - psb_page_clflush(driver, *page++); -} - -static void psb_mmu_flush_pd_locked(struct psb_mmu_driver *driver, - int force) -{ - atomic_set(&driver->needs_tlbflush, 0); -} - -static void psb_mmu_flush_pd(struct psb_mmu_driver *driver, int force) -{ - down_write(&driver->sem); - psb_mmu_flush_pd_locked(driver, force); - up_write(&driver->sem); -} - -void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot) -{ - if (rc_prot) - down_write(&driver->sem); - if (rc_prot) - up_write(&driver->sem); -} - -void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context) -{ - /*ttm_tt_cache_flush(&pd->p, 1);*/ - psb_pages_clflush(pd->driver, &pd->p, 1); - down_write(&pd->driver->sem); - wmb(); - psb_mmu_flush_pd_locked(pd->driver, 1); - pd->hw_context = hw_context; - up_write(&pd->driver->sem); - -} - -static inline unsigned long psb_pd_addr_end(unsigned long addr, - unsigned long end) -{ - - addr = (addr + PSB_PDE_MASK + 1) & ~PSB_PDE_MASK; - return (addr < end) ? addr : end; -} - -static inline uint32_t psb_mmu_mask_pte(uint32_t pfn, int type) -{ - uint32_t mask = PSB_PTE_VALID; - - if (type & PSB_MMU_CACHED_MEMORY) - mask |= PSB_PTE_CACHED; - if (type & PSB_MMU_RO_MEMORY) - mask |= PSB_PTE_RO; - if (type & PSB_MMU_WO_MEMORY) - mask |= PSB_PTE_WO; - - return (pfn << PAGE_SHIFT) | mask; -} - -struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver, - int trap_pagefaults, int invalid_type) -{ - struct psb_mmu_pd *pd = kmalloc(sizeof(*pd), GFP_KERNEL); - uint32_t *v; - int i; - - if (!pd) - return NULL; - - pd->p = alloc_page(GFP_DMA32); - if (!pd->p) - goto out_err1; - pd->dummy_pt = alloc_page(GFP_DMA32); - if (!pd->dummy_pt) - goto out_err2; - pd->dummy_page = alloc_page(GFP_DMA32); - if (!pd->dummy_page) - goto out_err3; - - if (!trap_pagefaults) { - pd->invalid_pde = - psb_mmu_mask_pte(page_to_pfn(pd->dummy_pt), - invalid_type); - pd->invalid_pte = - psb_mmu_mask_pte(page_to_pfn(pd->dummy_page), - invalid_type); - } else { - pd->invalid_pde = 0; - pd->invalid_pte = 0; - } - - v = kmap(pd->dummy_pt); - for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) - v[i] = pd->invalid_pte; - - kunmap(pd->dummy_pt); - - v = kmap(pd->p); - for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) - v[i] = pd->invalid_pde; - - kunmap(pd->p); - - clear_page(kmap(pd->dummy_page)); - kunmap(pd->dummy_page); - - pd->tables = vmalloc_user(sizeof(struct psb_mmu_pt *) * 1024); - if (!pd->tables) - goto out_err4; - - pd->hw_context = -1; - pd->pd_mask = PSB_PTE_VALID; - pd->driver = driver; - - return pd; - -out_err4: - __free_page(pd->dummy_page); -out_err3: - __free_page(pd->dummy_pt); -out_err2: - __free_page(pd->p); -out_err1: - kfree(pd); - return NULL; -} - -void psb_mmu_free_pt(struct psb_mmu_pt *pt) -{ - __free_page(pt->p); - kfree(pt); -} - -void psb_mmu_free_pagedir(struct psb_mmu_pd *pd) -{ - struct psb_mmu_driver *driver = pd->driver; - struct psb_mmu_pt *pt; - int i; - - down_write(&driver->sem); - if (pd->hw_context != -1) - psb_mmu_flush_pd_locked(driver, 1); - - /* Should take the spinlock here, but we don't need to do that - since we have the semaphore in write mode. */ - - for (i = 0; i < 1024; ++i) { - pt = pd->tables[i]; - if (pt) - psb_mmu_free_pt(pt); - } - - vfree(pd->tables); - __free_page(pd->dummy_page); - __free_page(pd->dummy_pt); - __free_page(pd->p); - kfree(pd); - up_write(&driver->sem); -} - -static struct psb_mmu_pt *psb_mmu_alloc_pt(struct psb_mmu_pd *pd) -{ - struct psb_mmu_pt *pt = kmalloc(sizeof(*pt), GFP_KERNEL); - void *v; - uint32_t clflush_add = pd->driver->clflush_add >> PAGE_SHIFT; - uint32_t clflush_count = PAGE_SIZE / clflush_add; - spinlock_t *lock = &pd->driver->lock; - uint8_t *clf; - uint32_t *ptes; - int i; - - if (!pt) - return NULL; - - pt->p = alloc_page(GFP_DMA32); - if (!pt->p) { - kfree(pt); - return NULL; - } - - spin_lock(lock); - - v = kmap_atomic(pt->p, KM_USER0); - clf = (uint8_t *) v; - ptes = (uint32_t *) v; - for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) - *ptes++ = pd->invalid_pte; - - - if (pd->driver->has_clflush && pd->hw_context != -1) { - mb(); - for (i = 0; i < clflush_count; ++i) { - psb_clflush(clf); - clf += clflush_add; - } - mb(); - } - - kunmap_atomic(v, KM_USER0); - spin_unlock(lock); - - pt->count = 0; - pt->pd = pd; - pt->index = 0; - - return pt; -} - -struct psb_mmu_pt *psb_mmu_pt_alloc_map_lock(struct psb_mmu_pd *pd, - unsigned long addr) -{ - uint32_t index = psb_mmu_pd_index(addr); - struct psb_mmu_pt *pt; - uint32_t *v; - spinlock_t *lock = &pd->driver->lock; - - spin_lock(lock); - pt = pd->tables[index]; - while (!pt) { - spin_unlock(lock); - pt = psb_mmu_alloc_pt(pd); - if (!pt) - return NULL; - spin_lock(lock); - - if (pd->tables[index]) { - spin_unlock(lock); - psb_mmu_free_pt(pt); - spin_lock(lock); - pt = pd->tables[index]; - continue; - } - - v = kmap_atomic(pd->p, KM_USER0); - pd->tables[index] = pt; - v[index] = (page_to_pfn(pt->p) << 12) | pd->pd_mask; - pt->index = index; - kunmap_atomic((void *) v, KM_USER0); - - if (pd->hw_context != -1) { - psb_mmu_clflush(pd->driver, (void *) &v[index]); - atomic_set(&pd->driver->needs_tlbflush, 1); - } - } - pt->v = kmap_atomic(pt->p, KM_USER0); - return pt; -} - -static struct psb_mmu_pt *psb_mmu_pt_map_lock(struct psb_mmu_pd *pd, - unsigned long addr) -{ - uint32_t index = psb_mmu_pd_index(addr); - struct psb_mmu_pt *pt; - spinlock_t *lock = &pd->driver->lock; - - spin_lock(lock); - pt = pd->tables[index]; - if (!pt) { - spin_unlock(lock); - return NULL; - } - pt->v = kmap_atomic(pt->p, KM_USER0); - return pt; -} - -static void psb_mmu_pt_unmap_unlock(struct psb_mmu_pt *pt) -{ - struct psb_mmu_pd *pd = pt->pd; - uint32_t *v; - - kunmap_atomic(pt->v, KM_USER0); - if (pt->count == 0) { - v = kmap_atomic(pd->p, KM_USER0); - v[pt->index] = pd->invalid_pde; - pd->tables[pt->index] = NULL; - - if (pd->hw_context != -1) { - psb_mmu_clflush(pd->driver, - (void *) &v[pt->index]); - atomic_set(&pd->driver->needs_tlbflush, 1); - } - kunmap_atomic(pt->v, KM_USER0); - spin_unlock(&pd->driver->lock); - psb_mmu_free_pt(pt); - return; - } - spin_unlock(&pd->driver->lock); -} - -static inline void psb_mmu_set_pte(struct psb_mmu_pt *pt, - unsigned long addr, uint32_t pte) -{ - pt->v[psb_mmu_pt_index(addr)] = pte; -} - -static inline void psb_mmu_invalidate_pte(struct psb_mmu_pt *pt, - unsigned long addr) -{ - pt->v[psb_mmu_pt_index(addr)] = pt->pd->invalid_pte; -} - - -void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, - uint32_t mmu_offset, uint32_t gtt_start, - uint32_t gtt_pages) -{ - uint32_t *v; - uint32_t start = psb_mmu_pd_index(mmu_offset); - struct psb_mmu_driver *driver = pd->driver; - int num_pages = gtt_pages; - - down_read(&driver->sem); - spin_lock(&driver->lock); - - v = kmap_atomic(pd->p, KM_USER0); - v += start; - - while (gtt_pages--) { - *v++ = gtt_start | pd->pd_mask; - gtt_start += PAGE_SIZE; - } - - /*ttm_tt_cache_flush(&pd->p, num_pages);*/ - psb_pages_clflush(pd->driver, &pd->p, num_pages); - kunmap_atomic(v, KM_USER0); - spin_unlock(&driver->lock); - - if (pd->hw_context != -1) - atomic_set(&pd->driver->needs_tlbflush, 1); - - up_read(&pd->driver->sem); - psb_mmu_flush_pd(pd->driver, 0); -} - -struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver *driver) -{ - struct psb_mmu_pd *pd; - - /* down_read(&driver->sem); */ - pd = driver->default_pd; - /* up_read(&driver->sem); */ - - return pd; -} - -/* Returns the physical address of the PD shared by sgx/msvdx */ -uint32_t psb_get_default_pd_addr(struct psb_mmu_driver *driver) -{ - struct psb_mmu_pd *pd; - - pd = psb_mmu_get_default_pd(driver); - return page_to_pfn(pd->p) << PAGE_SHIFT; -} - -void psb_mmu_driver_takedown(struct psb_mmu_driver *driver) -{ - psb_mmu_free_pagedir(driver->default_pd); - kfree(driver); -} - -struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers, - int trap_pagefaults, - int invalid_type, - struct drm_psb_private *dev_priv) -{ - struct psb_mmu_driver *driver; - - driver = kmalloc(sizeof(*driver), GFP_KERNEL); - - if (!driver) - return NULL; - driver->dev_priv = dev_priv; - - driver->default_pd = psb_mmu_alloc_pd(driver, trap_pagefaults, - invalid_type); - if (!driver->default_pd) - goto out_err1; - - spin_lock_init(&driver->lock); - init_rwsem(&driver->sem); - down_write(&driver->sem); - driver->register_map = registers; - atomic_set(&driver->needs_tlbflush, 1); - - driver->has_clflush = 0; - - if (boot_cpu_has(X86_FEATURE_CLFLSH)) { - uint32_t tfms, misc, cap0, cap4, clflush_size; - - /* - * clflush size is determined at kernel setup for x86_64 - * but not for i386. We have to do it here. - */ - - cpuid(0x00000001, &tfms, &misc, &cap0, &cap4); - clflush_size = ((misc >> 8) & 0xff) * 8; - driver->has_clflush = 1; - driver->clflush_add = - PAGE_SIZE * clflush_size / sizeof(uint32_t); - driver->clflush_mask = driver->clflush_add - 1; - driver->clflush_mask = ~driver->clflush_mask; - } - - up_write(&driver->sem); - return driver; - -out_err1: - kfree(driver); - return NULL; -} - -static void psb_mmu_flush_ptes(struct psb_mmu_pd *pd, - unsigned long address, uint32_t num_pages, - uint32_t desired_tile_stride, - uint32_t hw_tile_stride) -{ - struct psb_mmu_pt *pt; - uint32_t rows = 1; - uint32_t i; - unsigned long addr; - unsigned long end; - unsigned long next; - unsigned long add; - unsigned long row_add; - unsigned long clflush_add = pd->driver->clflush_add; - unsigned long clflush_mask = pd->driver->clflush_mask; - - if (!pd->driver->has_clflush) { - /*ttm_tt_cache_flush(&pd->p, num_pages);*/ - psb_pages_clflush(pd->driver, &pd->p, num_pages); - return; - } - - if (hw_tile_stride) - rows = num_pages / desired_tile_stride; - else - desired_tile_stride = num_pages; - - add = desired_tile_stride << PAGE_SHIFT; - row_add = hw_tile_stride << PAGE_SHIFT; - mb(); - for (i = 0; i < rows; ++i) { - - addr = address; - end = addr + add; - - do { - next = psb_pd_addr_end(addr, end); - pt = psb_mmu_pt_map_lock(pd, addr); - if (!pt) - continue; - do { - psb_clflush(&pt->v - [psb_mmu_pt_index(addr)]); - } while (addr += - clflush_add, - (addr & clflush_mask) < next); - - psb_mmu_pt_unmap_unlock(pt); - } while (addr = next, next != end); - address += row_add; - } - mb(); -} - -void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd, - unsigned long address, uint32_t num_pages) -{ - struct psb_mmu_pt *pt; - unsigned long addr; - unsigned long end; - unsigned long next; - unsigned long f_address = address; - - down_read(&pd->driver->sem); - - addr = address; - end = addr + (num_pages << PAGE_SHIFT); - - do { - next = psb_pd_addr_end(addr, end); - pt = psb_mmu_pt_alloc_map_lock(pd, addr); - if (!pt) - goto out; - do { - psb_mmu_invalidate_pte(pt, addr); - --pt->count; - } while (addr += PAGE_SIZE, addr < next); - psb_mmu_pt_unmap_unlock(pt); - - } while (addr = next, next != end); - -out: - if (pd->hw_context != -1) - psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1); - - up_read(&pd->driver->sem); - - if (pd->hw_context != -1) - psb_mmu_flush(pd->driver, 0); - - return; -} - -void psb_mmu_remove_pages(struct psb_mmu_pd *pd, unsigned long address, - uint32_t num_pages, uint32_t desired_tile_stride, - uint32_t hw_tile_stride) -{ - struct psb_mmu_pt *pt; - uint32_t rows = 1; - uint32_t i; - unsigned long addr; - unsigned long end; - unsigned long next; - unsigned long add; - unsigned long row_add; - unsigned long f_address = address; - - if (hw_tile_stride) - rows = num_pages / desired_tile_stride; - else - desired_tile_stride = num_pages; - - add = desired_tile_stride << PAGE_SHIFT; - row_add = hw_tile_stride << PAGE_SHIFT; - - /* down_read(&pd->driver->sem); */ - - /* Make sure we only need to flush this processor's cache */ - - for (i = 0; i < rows; ++i) { - - addr = address; - end = addr + add; - - do { - next = psb_pd_addr_end(addr, end); - pt = psb_mmu_pt_map_lock(pd, addr); - if (!pt) - continue; - do { - psb_mmu_invalidate_pte(pt, addr); - --pt->count; - - } while (addr += PAGE_SIZE, addr < next); - psb_mmu_pt_unmap_unlock(pt); - - } while (addr = next, next != end); - address += row_add; - } - if (pd->hw_context != -1) - psb_mmu_flush_ptes(pd, f_address, num_pages, - desired_tile_stride, hw_tile_stride); - - /* up_read(&pd->driver->sem); */ - - if (pd->hw_context != -1) - psb_mmu_flush(pd->driver, 0); -} - -int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, uint32_t start_pfn, - unsigned long address, uint32_t num_pages, - int type) -{ - struct psb_mmu_pt *pt; - uint32_t pte; - unsigned long addr; - unsigned long end; - unsigned long next; - unsigned long f_address = address; - int ret = 0; - - down_read(&pd->driver->sem); - - addr = address; - end = addr + (num_pages << PAGE_SHIFT); - - do { - next = psb_pd_addr_end(addr, end); - pt = psb_mmu_pt_alloc_map_lock(pd, addr); - if (!pt) { - ret = -ENOMEM; - goto out; - } - do { - pte = psb_mmu_mask_pte(start_pfn++, type); - psb_mmu_set_pte(pt, addr, pte); - pt->count++; - } while (addr += PAGE_SIZE, addr < next); - psb_mmu_pt_unmap_unlock(pt); - - } while (addr = next, next != end); - -out: - if (pd->hw_context != -1) - psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1); - - up_read(&pd->driver->sem); - - if (pd->hw_context != -1) - psb_mmu_flush(pd->driver, 1); - - return ret; -} - -int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages, - unsigned long address, uint32_t num_pages, - uint32_t desired_tile_stride, - uint32_t hw_tile_stride, int type) -{ - struct psb_mmu_pt *pt; - uint32_t rows = 1; - uint32_t i; - uint32_t pte; - unsigned long addr; - unsigned long end; - unsigned long next; - unsigned long add; - unsigned long row_add; - unsigned long f_address = address; - int ret = 0; - - if (hw_tile_stride) { - if (num_pages % desired_tile_stride != 0) - return -EINVAL; - rows = num_pages / desired_tile_stride; - } else { - desired_tile_stride = num_pages; - } - - add = desired_tile_stride << PAGE_SHIFT; - row_add = hw_tile_stride << PAGE_SHIFT; - - down_read(&pd->driver->sem); - - for (i = 0; i < rows; ++i) { - - addr = address; - end = addr + add; - - do { - next = psb_pd_addr_end(addr, end); - pt = psb_mmu_pt_alloc_map_lock(pd, addr); - if (!pt) { - ret = -ENOMEM; - goto out; - } - do { - pte = - psb_mmu_mask_pte(page_to_pfn(*pages++), - type); - psb_mmu_set_pte(pt, addr, pte); - pt->count++; - } while (addr += PAGE_SIZE, addr < next); - psb_mmu_pt_unmap_unlock(pt); - - } while (addr = next, next != end); - - address += row_add; - } -out: - if (pd->hw_context != -1) - psb_mmu_flush_ptes(pd, f_address, num_pages, - desired_tile_stride, hw_tile_stride); - - up_read(&pd->driver->sem); - - if (pd->hw_context != -1) - psb_mmu_flush(pd->driver, 1); - - return ret; -} - -int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual, - unsigned long *pfn) -{ - int ret; - struct psb_mmu_pt *pt; - uint32_t tmp; - spinlock_t *lock = &pd->driver->lock; - - down_read(&pd->driver->sem); - pt = psb_mmu_pt_map_lock(pd, virtual); - if (!pt) { - uint32_t *v; - - spin_lock(lock); - v = kmap_atomic(pd->p, KM_USER0); - tmp = v[psb_mmu_pd_index(virtual)]; - kunmap_atomic(v, KM_USER0); - spin_unlock(lock); - - if (tmp != pd->invalid_pde || !(tmp & PSB_PTE_VALID) || - !(pd->invalid_pte & PSB_PTE_VALID)) { - ret = -EINVAL; - goto out; - } - ret = 0; - *pfn = pd->invalid_pte >> PAGE_SHIFT; - goto out; - } - tmp = pt->v[psb_mmu_pt_index(virtual)]; - if (!(tmp & PSB_PTE_VALID)) { - ret = -EINVAL; - } else { - ret = 0; - *pfn = tmp >> PAGE_SHIFT; - } - psb_mmu_pt_unmap_unlock(pt); -out: - up_read(&pd->driver->sem); - return ret; -} diff --git a/drivers/staging/gma500/psb_powermgmt.c b/drivers/staging/gma500/psb_powermgmt.c deleted file mode 100644 index 1495415be6c..00000000000 --- a/drivers/staging/gma500/psb_powermgmt.c +++ /dev/null @@ -1,489 +0,0 @@ -/************************************************************************** - * Copyright (c) 2009, Intel Corporation. - * All Rights Reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Benjamin Defnet <benjamin.r.defnet@intel.com> - * Rajesh Poornachandran <rajesh.poornachandran@intel.com> - * Massively reworked - * Alan Cox <alan@linux.intel.com> - */ -#include "psb_powermgmt.h" -#include "psb_drv.h" -#include "psb_reg.h" -#include "psb_intel_reg.h" -#include <linux/mutex.h> -#include <linux/pm_runtime.h> - -static struct mutex power_mutex; - -/** - * gma_power_init - initialise power manager - * @dev: our device - * - * Set up for power management tracking of our hardware. - */ -void gma_power_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - dev_priv->apm_base = dev_priv->apm_reg & 0xffff; - dev_priv->ospm_base &= 0xffff; - - dev_priv->display_power = true; /* We start active */ - dev_priv->display_count = 0; /* Currently no users */ - dev_priv->suspended = false; /* And not suspended */ - mutex_init(&power_mutex); - - if (!IS_MRST(dev)) { - /* FIXME: wants further review */ - u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL); - /* Disable 2D clock gating */ - gating &= ~3; - gating |= 1; - PSB_WSGX32(gating, PSB_CR_CLKGATECTL); - PSB_RSGX32(PSB_CR_CLKGATECTL); - } -} - -/** - * gma_power_uninit - end power manager - * @dev: device to end for - * - * Undo the effects of gma_power_init - */ -void gma_power_uninit(struct drm_device *dev) -{ - mutex_destroy(&power_mutex); - pm_runtime_disable(&dev->pdev->dev); - pm_runtime_set_suspended(&dev->pdev->dev); -} - - -/** - * save_display_registers - save registers lost on suspend - * @dev: our DRM device - * - * Save the state we need in order to be able to restore the interface - * upon resume from suspend - */ -static int save_display_registers(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - struct drm_connector *connector; - - /* Display arbitration control + watermarks */ - dev_priv->saveDSPARB = PSB_RVDC32(DSPARB); - dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1); - dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2); - dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3); - dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4); - dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5); - dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6); - dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT); - - /* Save crtc and output state */ - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (drm_helper_crtc_in_use(crtc)) - crtc->funcs->save(crtc); - } - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - connector->funcs->save(connector); - - mutex_unlock(&dev->mode_config.mutex); - return 0; -} - -/** - * restore_display_registers - restore lost register state - * @dev: our DRM device - * - * Restore register state that was lost during suspend and resume. - */ -static int restore_display_registers(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - struct drm_connector *connector; - - /* Display arbitration + watermarks */ - PSB_WVDC32(dev_priv->saveDSPARB, DSPARB); - PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1); - PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2); - PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3); - PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4); - PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5); - PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6); - PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT); - - /*make sure VGA plane is off. it initializes to on after reset!*/ - PSB_WVDC32(0x80000000, VGACNTRL); - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - if (drm_helper_crtc_in_use(crtc)) - crtc->funcs->restore(crtc); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - connector->funcs->restore(connector); - - mutex_unlock(&dev->mode_config.mutex); - return 0; -} - -/** - * power_down - power down the display island - * @dev: our DRM device - * - * Power down the display interface of our device - */ -static void power_down(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pwr_mask ; - u32 pwr_sts; - - if (IS_MRST(dev)) { - pwr_mask = PSB_PWRGT_DISPLAY_MASK; - outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC); - - while (true) { - pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); - if ((pwr_sts & pwr_mask) == pwr_mask) - break; - else - udelay(10); - } - dev_priv->display_power = false; - } -} - - -/** - * gma_suspend_display - suspend the display logic - * @dev: our DRM device - * - * Suspend the display logic of the graphics interface - */ -static void gma_suspend_display(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - int pp_stat; - - if (dev_priv->suspended) - return; - - save_display_registers(dev); - - if (dev_priv->iLVDS_enable) { - /*shutdown the panel*/ - PSB_WVDC32(0, PP_CONTROL); - - do { - pp_stat = PSB_RVDC32(PP_STATUS); - } while (pp_stat & 0x80000000); - - /*turn off the plane*/ - PSB_WVDC32(0x58000000, DSPACNTR); - PSB_WVDC32(0, DSPASURF);/*trigger the plane disable*/ - /*wait ~4 ticks*/ - msleep(4); - - /*turn off pipe*/ - PSB_WVDC32(0x0, PIPEACONF); - /*wait ~8 ticks*/ - msleep(8); - - /*turn off PLLs*/ - PSB_WVDC32(0, MRST_DPLL_A); - } else { - PSB_WVDC32(DPI_SHUT_DOWN, DPI_CONTROL_REG); - PSB_WVDC32(0x0, PIPEACONF); - PSB_WVDC32(0x2faf0000, BLC_PWM_CTL); - while (REG_READ(0x70008) & 0x40000000); - while ((PSB_RVDC32(GEN_FIFO_STAT_REG) & DPI_FIFO_EMPTY) - != DPI_FIFO_EMPTY); - PSB_WVDC32(0, DEVICE_READY_REG); - /* turn off panel power */ - } - power_down(dev); -} - -/* - * power_up - * - * Description: Restore power to the specified island(s) (powergating) - */ -static void power_up(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK; - u32 pwr_sts, pwr_cnt; - - if (IS_MRST(dev)) { - pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC); - pwr_cnt &= ~pwr_mask; - outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC)); - - while (true) { - pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); - if ((pwr_sts & pwr_mask) == 0) - break; - else - udelay(10); - } - } - dev_priv->suspended = false; - dev_priv->display_power = true; -} - -/** - * gma_resume_display - resume display side logic - * - * Resume the display hardware restoring state and enabling - * as necessary. - */ -static void gma_resume_display(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - struct drm_psb_private *dev_priv = dev->dev_private; - - if (dev_priv->suspended == false) - return; - - /* turn on the display power island */ - power_up(dev); - - PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL); - pci_write_config_word(pdev, PSB_GMCH_CTRL, - dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED); - - /* Don't reinitialize the GTT as it is unnecessary. The gtt is - * stored in memory so it will automatically be restored. All - * we need to do is restore the PGETBL_CTL which we already do - * above. - */ - /*psb_gtt_init(dev_priv->pg, 1);*/ - - restore_display_registers(dev); -} - -/** - * gma_suspend_pci - suspend PCI side - * @pdev: PCI device - * - * Perform the suspend processing on our PCI device state - */ -static void gma_suspend_pci(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - struct drm_psb_private *dev_priv = dev->dev_private; - int bsm, vbt; - - if (dev_priv->suspended) - return; - - pci_save_state(pdev); - pci_read_config_dword(pdev, 0x5C, &bsm); - dev_priv->saveBSM = bsm; - pci_read_config_dword(pdev, 0xFC, &vbt); - dev_priv->saveVBT = vbt; - pci_read_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, &dev_priv->msi_addr); - pci_read_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, &dev_priv->msi_data); - - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - - dev_priv->suspended = true; -} - -/** - * gma_resume_pci - resume helper - * @dev: our PCI device - * - * Perform the resume processing on our PCI device state - rewrite - * register state and re-enable the PCI device - */ -static bool gma_resume_pci(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - struct drm_psb_private *dev_priv = dev->dev_private; - int ret; - - if (!dev_priv->suspended) - return true; - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM); - pci_write_config_dword(pdev, 0xFC, dev_priv->saveVBT); - /* retoring MSI address and data in PCIx space */ - pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr); - pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data); - ret = pci_enable_device(pdev); - - if (ret != 0) - dev_err(&pdev->dev, "pci_enable failed: %d\n", ret); - else - dev_priv->suspended = false; - return !dev_priv->suspended; -} - -/** - * gma_power_suspend - bus callback for suspend - * @pdev: our PCI device - * @state: suspend type - * - * Called back by the PCI layer during a suspend of the system. We - * perform the necessary shut down steps and save enough state that - * we can undo this when resume is called. - */ -int gma_power_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - struct drm_psb_private *dev_priv = dev->dev_private; - - mutex_lock(&power_mutex); - if (!dev_priv->suspended) { - if (dev_priv->display_count) { - mutex_unlock(&power_mutex); - return -EBUSY; - } - psb_irq_uninstall(dev); - gma_suspend_display(dev); - gma_suspend_pci(pdev); - } - mutex_unlock(&power_mutex); - return 0; -} - - -/** - * gma_power_resume - resume power - * @pdev: PCI device - * - * Resume the PCI side of the graphics and then the displays - */ -int gma_power_resume(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - - mutex_lock(&power_mutex); - gma_resume_pci(pdev); - gma_resume_display(pdev); - psb_irq_preinstall(dev); - psb_irq_postinstall(dev); - mutex_unlock(&power_mutex); - return 0; -} - - - -/** - * gma_power_is_on - returne true if power is on - * @dev: our DRM device - * - * Returns true if the display island power is on at this moment - */ -bool gma_power_is_on(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - return dev_priv->display_power; -} - - -/** - * gma_power_begin - begin requiring power - * @dev: our DRM device - * @force_on: true to force power on - * - * Begin an action that requires the display power island is enabled. - * We refcount the islands. - * - * FIXME: locking - */ -bool gma_power_begin(struct drm_device *dev, bool force_on) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - int ret; - - /* Power already on ? */ - if (dev_priv->display_power) { - dev_priv->display_count++; - pm_runtime_get(&dev->pdev->dev); - return true; - } - if (force_on == false) - return false; - - /* Ok power up needed */ - ret = gma_resume_pci(dev->pdev); - if (ret == 0) { - psb_irq_preinstall(dev); - psb_irq_postinstall(dev); - pm_runtime_get(&dev->pdev->dev); - dev_priv->display_count++; - return true; - } - return false; -} - - -/** - * gma_power_end - end use of power - * @dev: Our DRM device - * - * Indicate that one of our gma_power_begin() requested periods when - * the diplay island power is needed has completed. - */ -void gma_power_end(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - dev_priv->display_count--; - WARN_ON(dev_priv->display_count < 0); - pm_runtime_put(&dev->pdev->dev); -} - -int psb_runtime_suspend(struct device *dev) -{ - static pm_message_t dummy; - return gma_power_suspend(to_pci_dev(dev), dummy); -} - -int psb_runtime_resume(struct device *dev) -{ - return 0; -} - -int psb_runtime_idle(struct device *dev) -{ - struct drm_device *drmdev = pci_get_drvdata(to_pci_dev(dev)); - struct drm_psb_private *dev_priv = drmdev->dev_private; - if (dev_priv->display_count) - return 0; - else - return 1; -} - diff --git a/drivers/staging/gma500/psb_powermgmt.h b/drivers/staging/gma500/psb_powermgmt.h deleted file mode 100644 index e005229af79..00000000000 --- a/drivers/staging/gma500/psb_powermgmt.h +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************** - * Copyright (c) 2009, Intel Corporation. - * All Rights Reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Benjamin Defnet <benjamin.r.defnet@intel.com> - * Rajesh Poornachandran <rajesh.poornachandran@intel.com> - * Massively reworked - * Alan Cox <alan@linux.intel.com> - */ -#ifndef _PSB_POWERMGMT_H_ -#define _PSB_POWERMGMT_H_ - -#include <linux/pci.h> -#include <drm/drmP.h> - -void gma_power_init(struct drm_device *dev); -void gma_power_uninit(struct drm_device *dev); - -/* - * The kernel bus power management will call these functions - */ -int gma_power_suspend(struct pci_dev *pdev, pm_message_t state); -int gma_power_resume(struct pci_dev *pdev); - -/* - * These are the functions the driver should use to wrap all hw access - * (i.e. register reads and writes) - */ -bool gma_power_begin(struct drm_device *dev, bool force); -void gma_power_end(struct drm_device *dev); - -/* - * Use this function to do an instantaneous check for if the hw is on. - * Only use this in cases where you know the mutex is already held such - * as in irq install/uninstall and you need to - * prevent a deadlock situation. Otherwise use gma_power_begin(). - */ -bool gma_power_is_on(struct drm_device *dev); - -/* - * GFX-Runtime PM callbacks - */ -int psb_runtime_suspend(struct device *dev); -int psb_runtime_resume(struct device *dev); -int psb_runtime_idle(struct device *dev); - -#endif /*_PSB_POWERMGMT_H_*/ diff --git a/drivers/staging/gma500/psb_reg.h b/drivers/staging/gma500/psb_reg.h deleted file mode 100644 index 9ad49892070..00000000000 --- a/drivers/staging/gma500/psb_reg.h +++ /dev/null @@ -1,588 +0,0 @@ -/************************************************************************** - * - * Copyright (c) (2005-2007) Imagination Technologies Limited. - * Copyright (c) 2007, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.. - * - **************************************************************************/ - -#ifndef _PSB_REG_H_ -#define _PSB_REG_H_ - -#define PSB_CR_CLKGATECTL 0x0000 -#define _PSB_C_CLKGATECTL_AUTO_MAN_REG (1 << 24) -#define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT (20) -#define _PSB_C_CLKGATECTL_USE_CLKG_MASK (0x3 << 20) -#define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT (16) -#define _PSB_C_CLKGATECTL_DPM_CLKG_MASK (0x3 << 16) -#define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT (12) -#define _PSB_C_CLKGATECTL_TA_CLKG_MASK (0x3 << 12) -#define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT (8) -#define _PSB_C_CLKGATECTL_TSP_CLKG_MASK (0x3 << 8) -#define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT (4) -#define _PSB_C_CLKGATECTL_ISP_CLKG_MASK (0x3 << 4) -#define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT (0) -#define _PSB_C_CLKGATECTL_2D_CLKG_MASK (0x3 << 0) -#define _PSB_C_CLKGATECTL_CLKG_ENABLED (0) -#define _PSB_C_CLKGATECTL_CLKG_DISABLED (1) -#define _PSB_C_CLKGATECTL_CLKG_AUTO (2) - -#define PSB_CR_CORE_ID 0x0010 -#define _PSB_CC_ID_ID_SHIFT (16) -#define _PSB_CC_ID_ID_MASK (0xFFFF << 16) -#define _PSB_CC_ID_CONFIG_SHIFT (0) -#define _PSB_CC_ID_CONFIG_MASK (0xFFFF << 0) - -#define PSB_CR_CORE_REVISION 0x0014 -#define _PSB_CC_REVISION_DESIGNER_SHIFT (24) -#define _PSB_CC_REVISION_DESIGNER_MASK (0xFF << 24) -#define _PSB_CC_REVISION_MAJOR_SHIFT (16) -#define _PSB_CC_REVISION_MAJOR_MASK (0xFF << 16) -#define _PSB_CC_REVISION_MINOR_SHIFT (8) -#define _PSB_CC_REVISION_MINOR_MASK (0xFF << 8) -#define _PSB_CC_REVISION_MAINTENANCE_SHIFT (0) -#define _PSB_CC_REVISION_MAINTENANCE_MASK (0xFF << 0) - -#define PSB_CR_DESIGNER_REV_FIELD1 0x0018 - -#define PSB_CR_SOFT_RESET 0x0080 -#define _PSB_CS_RESET_TSP_RESET (1 << 6) -#define _PSB_CS_RESET_ISP_RESET (1 << 5) -#define _PSB_CS_RESET_USE_RESET (1 << 4) -#define _PSB_CS_RESET_TA_RESET (1 << 3) -#define _PSB_CS_RESET_DPM_RESET (1 << 2) -#define _PSB_CS_RESET_TWOD_RESET (1 << 1) -#define _PSB_CS_RESET_BIF_RESET (1 << 0) - -#define PSB_CR_DESIGNER_REV_FIELD2 0x001C - -#define PSB_CR_EVENT_HOST_ENABLE2 0x0110 - -#define PSB_CR_EVENT_STATUS2 0x0118 - -#define PSB_CR_EVENT_HOST_CLEAR2 0x0114 -#define _PSB_CE2_BIF_REQUESTER_FAULT (1 << 4) - -#define PSB_CR_EVENT_STATUS 0x012C - -#define PSB_CR_EVENT_HOST_ENABLE 0x0130 - -#define PSB_CR_EVENT_HOST_CLEAR 0x0134 -#define _PSB_CE_MASTER_INTERRUPT (1 << 31) -#define _PSB_CE_TA_DPM_FAULT (1 << 28) -#define _PSB_CE_TWOD_COMPLETE (1 << 27) -#define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS (1 << 25) -#define _PSB_CE_DPM_TA_MEM_FREE (1 << 24) -#define _PSB_CE_PIXELBE_END_RENDER (1 << 18) -#define _PSB_CE_SW_EVENT (1 << 14) -#define _PSB_CE_TA_FINISHED (1 << 13) -#define _PSB_CE_TA_TERMINATE (1 << 12) -#define _PSB_CE_DPM_REACHED_MEM_THRESH (1 << 3) -#define _PSB_CE_DPM_OUT_OF_MEMORY_GBL (1 << 2) -#define _PSB_CE_DPM_OUT_OF_MEMORY_MT (1 << 1) -#define _PSB_CE_DPM_3D_MEM_FREE (1 << 0) - - -#define PSB_USE_OFFSET_MASK 0x0007FFFF -#define PSB_USE_OFFSET_SIZE (PSB_USE_OFFSET_MASK + 1) -#define PSB_CR_USE_CODE_BASE0 0x0A0C -#define PSB_CR_USE_CODE_BASE1 0x0A10 -#define PSB_CR_USE_CODE_BASE2 0x0A14 -#define PSB_CR_USE_CODE_BASE3 0x0A18 -#define PSB_CR_USE_CODE_BASE4 0x0A1C -#define PSB_CR_USE_CODE_BASE5 0x0A20 -#define PSB_CR_USE_CODE_BASE6 0x0A24 -#define PSB_CR_USE_CODE_BASE7 0x0A28 -#define PSB_CR_USE_CODE_BASE8 0x0A2C -#define PSB_CR_USE_CODE_BASE9 0x0A30 -#define PSB_CR_USE_CODE_BASE10 0x0A34 -#define PSB_CR_USE_CODE_BASE11 0x0A38 -#define PSB_CR_USE_CODE_BASE12 0x0A3C -#define PSB_CR_USE_CODE_BASE13 0x0A40 -#define PSB_CR_USE_CODE_BASE14 0x0A44 -#define PSB_CR_USE_CODE_BASE15 0x0A48 -#define PSB_CR_USE_CODE_BASE(_i) (0x0A0C + ((_i) << 2)) -#define _PSB_CUC_BASE_DM_SHIFT (25) -#define _PSB_CUC_BASE_DM_MASK (0x3 << 25) -#define _PSB_CUC_BASE_ADDR_SHIFT (0) /* 1024-bit aligned address? */ -#define _PSB_CUC_BASE_ADDR_ALIGNSHIFT (7) -#define _PSB_CUC_BASE_ADDR_MASK (0x1FFFFFF << 0) -#define _PSB_CUC_DM_VERTEX (0) -#define _PSB_CUC_DM_PIXEL (1) -#define _PSB_CUC_DM_RESERVED (2) -#define _PSB_CUC_DM_EDM (3) - -#define PSB_CR_PDS_EXEC_BASE 0x0AB8 -#define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT (20) /* 1MB aligned address */ -#define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT (20) - -#define PSB_CR_EVENT_KICKER 0x0AC4 -#define _PSB_CE_KICKER_ADDRESS_SHIFT (4) /* 128-bit aligned address */ - -#define PSB_CR_EVENT_KICK 0x0AC8 -#define _PSB_CE_KICK_NOW (1 << 0) - - -#define PSB_CR_BIF_DIR_LIST_BASE1 0x0C38 - -#define PSB_CR_BIF_CTRL 0x0C00 -#define _PSB_CB_CTRL_CLEAR_FAULT (1 << 4) -#define _PSB_CB_CTRL_INVALDC (1 << 3) -#define _PSB_CB_CTRL_FLUSH (1 << 2) - -#define PSB_CR_BIF_INT_STAT 0x0C04 - -#define PSB_CR_BIF_FAULT 0x0C08 -#define _PSB_CBI_STAT_PF_N_RW (1 << 14) -#define _PSB_CBI_STAT_FAULT_SHIFT (0) -#define _PSB_CBI_STAT_FAULT_MASK (0x3FFF << 0) -#define _PSB_CBI_STAT_FAULT_CACHE (1 << 1) -#define _PSB_CBI_STAT_FAULT_TA (1 << 2) -#define _PSB_CBI_STAT_FAULT_VDM (1 << 3) -#define _PSB_CBI_STAT_FAULT_2D (1 << 4) -#define _PSB_CBI_STAT_FAULT_PBE (1 << 5) -#define _PSB_CBI_STAT_FAULT_TSP (1 << 6) -#define _PSB_CBI_STAT_FAULT_ISP (1 << 7) -#define _PSB_CBI_STAT_FAULT_USSEPDS (1 << 8) -#define _PSB_CBI_STAT_FAULT_HOST (1 << 9) - -#define PSB_CR_BIF_BANK0 0x0C78 - -#define PSB_CR_BIF_BANK1 0x0C7C - -#define PSB_CR_BIF_DIR_LIST_BASE0 0x0C84 - -#define PSB_CR_BIF_TWOD_REQ_BASE 0x0C88 -#define PSB_CR_BIF_3D_REQ_BASE 0x0CAC - -#define PSB_CR_2D_SOCIF 0x0E18 -#define _PSB_C2_SOCIF_FREESPACE_SHIFT (0) -#define _PSB_C2_SOCIF_FREESPACE_MASK (0xFF << 0) -#define _PSB_C2_SOCIF_EMPTY (0x80 << 0) - -#define PSB_CR_2D_BLIT_STATUS 0x0E04 -#define _PSB_C2B_STATUS_BUSY (1 << 24) -#define _PSB_C2B_STATUS_COMPLETE_SHIFT (0) -#define _PSB_C2B_STATUS_COMPLETE_MASK (0xFFFFFF << 0) - -/* - * 2D defs. - */ - -/* - * 2D Slave Port Data : Block Header's Object Type - */ - -#define PSB_2D_CLIP_BH (0x00000000) -#define PSB_2D_PAT_BH (0x10000000) -#define PSB_2D_CTRL_BH (0x20000000) -#define PSB_2D_SRC_OFF_BH (0x30000000) -#define PSB_2D_MASK_OFF_BH (0x40000000) -#define PSB_2D_RESERVED1_BH (0x50000000) -#define PSB_2D_RESERVED2_BH (0x60000000) -#define PSB_2D_FENCE_BH (0x70000000) -#define PSB_2D_BLIT_BH (0x80000000) -#define PSB_2D_SRC_SURF_BH (0x90000000) -#define PSB_2D_DST_SURF_BH (0xA0000000) -#define PSB_2D_PAT_SURF_BH (0xB0000000) -#define PSB_2D_SRC_PAL_BH (0xC0000000) -#define PSB_2D_PAT_PAL_BH (0xD0000000) -#define PSB_2D_MASK_SURF_BH (0xE0000000) -#define PSB_2D_FLUSH_BH (0xF0000000) - -/* - * Clip Definition block (PSB_2D_CLIP_BH) - */ -#define PSB_2D_CLIPCOUNT_MAX (1) -#define PSB_2D_CLIPCOUNT_MASK (0x00000000) -#define PSB_2D_CLIPCOUNT_CLRMASK (0xFFFFFFFF) -#define PSB_2D_CLIPCOUNT_SHIFT (0) -/* clip rectangle min & max */ -#define PSB_2D_CLIP_XMAX_MASK (0x00FFF000) -#define PSB_2D_CLIP_XMAX_CLRMASK (0xFF000FFF) -#define PSB_2D_CLIP_XMAX_SHIFT (12) -#define PSB_2D_CLIP_XMIN_MASK (0x00000FFF) -#define PSB_2D_CLIP_XMIN_CLRMASK (0x00FFF000) -#define PSB_2D_CLIP_XMIN_SHIFT (0) -/* clip rectangle offset */ -#define PSB_2D_CLIP_YMAX_MASK (0x00FFF000) -#define PSB_2D_CLIP_YMAX_CLRMASK (0xFF000FFF) -#define PSB_2D_CLIP_YMAX_SHIFT (12) -#define PSB_2D_CLIP_YMIN_MASK (0x00000FFF) -#define PSB_2D_CLIP_YMIN_CLRMASK (0x00FFF000) -#define PSB_2D_CLIP_YMIN_SHIFT (0) - -/* - * Pattern Control (PSB_2D_PAT_BH) - */ -#define PSB_2D_PAT_HEIGHT_MASK (0x0000001F) -#define PSB_2D_PAT_HEIGHT_SHIFT (0) -#define PSB_2D_PAT_WIDTH_MASK (0x000003E0) -#define PSB_2D_PAT_WIDTH_SHIFT (5) -#define PSB_2D_PAT_YSTART_MASK (0x00007C00) -#define PSB_2D_PAT_YSTART_SHIFT (10) -#define PSB_2D_PAT_XSTART_MASK (0x000F8000) -#define PSB_2D_PAT_XSTART_SHIFT (15) - -/* - * 2D Control block (PSB_2D_CTRL_BH) - */ -/* Present Flags */ -#define PSB_2D_SRCCK_CTRL (0x00000001) -#define PSB_2D_DSTCK_CTRL (0x00000002) -#define PSB_2D_ALPHA_CTRL (0x00000004) -/* Colour Key Colour (SRC/DST)*/ -#define PSB_2D_CK_COL_MASK (0xFFFFFFFF) -#define PSB_2D_CK_COL_CLRMASK (0x00000000) -#define PSB_2D_CK_COL_SHIFT (0) -/* Colour Key Mask (SRC/DST)*/ -#define PSB_2D_CK_MASK_MASK (0xFFFFFFFF) -#define PSB_2D_CK_MASK_CLRMASK (0x00000000) -#define PSB_2D_CK_MASK_SHIFT (0) -/* Alpha Control (Alpha/RGB)*/ -#define PSB_2D_GBLALPHA_MASK (0x000FF000) -#define PSB_2D_GBLALPHA_CLRMASK (0xFFF00FFF) -#define PSB_2D_GBLALPHA_SHIFT (12) -#define PSB_2D_SRCALPHA_OP_MASK (0x00700000) -#define PSB_2D_SRCALPHA_OP_CLRMASK (0xFF8FFFFF) -#define PSB_2D_SRCALPHA_OP_SHIFT (20) -#define PSB_2D_SRCALPHA_OP_ONE (0x00000000) -#define PSB_2D_SRCALPHA_OP_SRC (0x00100000) -#define PSB_2D_SRCALPHA_OP_DST (0x00200000) -#define PSB_2D_SRCALPHA_OP_SG (0x00300000) -#define PSB_2D_SRCALPHA_OP_DG (0x00400000) -#define PSB_2D_SRCALPHA_OP_GBL (0x00500000) -#define PSB_2D_SRCALPHA_OP_ZERO (0x00600000) -#define PSB_2D_SRCALPHA_INVERT (0x00800000) -#define PSB_2D_SRCALPHA_INVERT_CLR (0xFF7FFFFF) -#define PSB_2D_DSTALPHA_OP_MASK (0x07000000) -#define PSB_2D_DSTALPHA_OP_CLRMASK (0xF8FFFFFF) -#define PSB_2D_DSTALPHA_OP_SHIFT (24) -#define PSB_2D_DSTALPHA_OP_ONE (0x00000000) -#define PSB_2D_DSTALPHA_OP_SRC (0x01000000) -#define PSB_2D_DSTALPHA_OP_DST (0x02000000) -#define PSB_2D_DSTALPHA_OP_SG (0x03000000) -#define PSB_2D_DSTALPHA_OP_DG (0x04000000) -#define PSB_2D_DSTALPHA_OP_GBL (0x05000000) -#define PSB_2D_DSTALPHA_OP_ZERO (0x06000000) -#define PSB_2D_DSTALPHA_INVERT (0x08000000) -#define PSB_2D_DSTALPHA_INVERT_CLR (0xF7FFFFFF) - -#define PSB_2D_PRE_MULTIPLICATION_ENABLE (0x10000000) -#define PSB_2D_PRE_MULTIPLICATION_CLRMASK (0xEFFFFFFF) -#define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE (0x20000000) -#define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK (0xDFFFFFFF) - -/* - *Source Offset (PSB_2D_SRC_OFF_BH) - */ -#define PSB_2D_SRCOFF_XSTART_MASK ((0x00000FFF) << 12) -#define PSB_2D_SRCOFF_XSTART_SHIFT (12) -#define PSB_2D_SRCOFF_YSTART_MASK (0x00000FFF) -#define PSB_2D_SRCOFF_YSTART_SHIFT (0) - -/* - * Mask Offset (PSB_2D_MASK_OFF_BH) - */ -#define PSB_2D_MASKOFF_XSTART_MASK ((0x00000FFF) << 12) -#define PSB_2D_MASKOFF_XSTART_SHIFT (12) -#define PSB_2D_MASKOFF_YSTART_MASK (0x00000FFF) -#define PSB_2D_MASKOFF_YSTART_SHIFT (0) - -/* - * 2D Fence (see PSB_2D_FENCE_BH): bits 0:27 are ignored - */ - -/* - *Blit Rectangle (PSB_2D_BLIT_BH) - */ - -#define PSB_2D_ROT_MASK (3<<25) -#define PSB_2D_ROT_CLRMASK (~PSB_2D_ROT_MASK) -#define PSB_2D_ROT_NONE (0<<25) -#define PSB_2D_ROT_90DEGS (1<<25) -#define PSB_2D_ROT_180DEGS (2<<25) -#define PSB_2D_ROT_270DEGS (3<<25) - -#define PSB_2D_COPYORDER_MASK (3<<23) -#define PSB_2D_COPYORDER_CLRMASK (~PSB_2D_COPYORDER_MASK) -#define PSB_2D_COPYORDER_TL2BR (0<<23) -#define PSB_2D_COPYORDER_BR2TL (1<<23) -#define PSB_2D_COPYORDER_TR2BL (2<<23) -#define PSB_2D_COPYORDER_BL2TR (3<<23) - -#define PSB_2D_DSTCK_CLRMASK (0xFF9FFFFF) -#define PSB_2D_DSTCK_DISABLE (0x00000000) -#define PSB_2D_DSTCK_PASS (0x00200000) -#define PSB_2D_DSTCK_REJECT (0x00400000) - -#define PSB_2D_SRCCK_CLRMASK (0xFFE7FFFF) -#define PSB_2D_SRCCK_DISABLE (0x00000000) -#define PSB_2D_SRCCK_PASS (0x00080000) -#define PSB_2D_SRCCK_REJECT (0x00100000) - -#define PSB_2D_CLIP_ENABLE (0x00040000) - -#define PSB_2D_ALPHA_ENABLE (0x00020000) - -#define PSB_2D_PAT_CLRMASK (0xFFFEFFFF) -#define PSB_2D_PAT_MASK (0x00010000) -#define PSB_2D_USE_PAT (0x00010000) -#define PSB_2D_USE_FILL (0x00000000) -/* - * Tungsten Graphics note on rop codes: If rop A and rop B are - * identical, the mask surface will not be read and need not be - * set up. - */ - -#define PSB_2D_ROP3B_MASK (0x0000FF00) -#define PSB_2D_ROP3B_CLRMASK (0xFFFF00FF) -#define PSB_2D_ROP3B_SHIFT (8) -/* rop code A */ -#define PSB_2D_ROP3A_MASK (0x000000FF) -#define PSB_2D_ROP3A_CLRMASK (0xFFFFFF00) -#define PSB_2D_ROP3A_SHIFT (0) - -#define PSB_2D_ROP4_MASK (0x0000FFFF) -/* - * DWORD0: (Only pass if Pattern control == Use Fill Colour) - * Fill Colour RGBA8888 - */ -#define PSB_2D_FILLCOLOUR_MASK (0xFFFFFFFF) -#define PSB_2D_FILLCOLOUR_SHIFT (0) -/* - * DWORD1: (Always Present) - * X Start (Dest) - * Y Start (Dest) - */ -#define PSB_2D_DST_XSTART_MASK (0x00FFF000) -#define PSB_2D_DST_XSTART_CLRMASK (0xFF000FFF) -#define PSB_2D_DST_XSTART_SHIFT (12) -#define PSB_2D_DST_YSTART_MASK (0x00000FFF) -#define PSB_2D_DST_YSTART_CLRMASK (0xFFFFF000) -#define PSB_2D_DST_YSTART_SHIFT (0) -/* - * DWORD2: (Always Present) - * X Size (Dest) - * Y Size (Dest) - */ -#define PSB_2D_DST_XSIZE_MASK (0x00FFF000) -#define PSB_2D_DST_XSIZE_CLRMASK (0xFF000FFF) -#define PSB_2D_DST_XSIZE_SHIFT (12) -#define PSB_2D_DST_YSIZE_MASK (0x00000FFF) -#define PSB_2D_DST_YSIZE_CLRMASK (0xFFFFF000) -#define PSB_2D_DST_YSIZE_SHIFT (0) - -/* - * Source Surface (PSB_2D_SRC_SURF_BH) - */ -/* - * WORD 0 - */ - -#define PSB_2D_SRC_FORMAT_MASK (0x00078000) -#define PSB_2D_SRC_1_PAL (0x00000000) -#define PSB_2D_SRC_2_PAL (0x00008000) -#define PSB_2D_SRC_4_PAL (0x00010000) -#define PSB_2D_SRC_8_PAL (0x00018000) -#define PSB_2D_SRC_8_ALPHA (0x00020000) -#define PSB_2D_SRC_4_ALPHA (0x00028000) -#define PSB_2D_SRC_332RGB (0x00030000) -#define PSB_2D_SRC_4444ARGB (0x00038000) -#define PSB_2D_SRC_555RGB (0x00040000) -#define PSB_2D_SRC_1555ARGB (0x00048000) -#define PSB_2D_SRC_565RGB (0x00050000) -#define PSB_2D_SRC_0888ARGB (0x00058000) -#define PSB_2D_SRC_8888ARGB (0x00060000) -#define PSB_2D_SRC_8888UYVY (0x00068000) -#define PSB_2D_SRC_RESERVED (0x00070000) -#define PSB_2D_SRC_1555ARGB_LOOKUP (0x00078000) - - -#define PSB_2D_SRC_STRIDE_MASK (0x00007FFF) -#define PSB_2D_SRC_STRIDE_CLRMASK (0xFFFF8000) -#define PSB_2D_SRC_STRIDE_SHIFT (0) -/* - * WORD 1 - Base Address - */ -#define PSB_2D_SRC_ADDR_MASK (0x0FFFFFFC) -#define PSB_2D_SRC_ADDR_CLRMASK (0x00000003) -#define PSB_2D_SRC_ADDR_SHIFT (2) -#define PSB_2D_SRC_ADDR_ALIGNSHIFT (2) - -/* - * Pattern Surface (PSB_2D_PAT_SURF_BH) - */ -/* - * WORD 0 - */ - -#define PSB_2D_PAT_FORMAT_MASK (0x00078000) -#define PSB_2D_PAT_1_PAL (0x00000000) -#define PSB_2D_PAT_2_PAL (0x00008000) -#define PSB_2D_PAT_4_PAL (0x00010000) -#define PSB_2D_PAT_8_PAL (0x00018000) -#define PSB_2D_PAT_8_ALPHA (0x00020000) -#define PSB_2D_PAT_4_ALPHA (0x00028000) -#define PSB_2D_PAT_332RGB (0x00030000) -#define PSB_2D_PAT_4444ARGB (0x00038000) -#define PSB_2D_PAT_555RGB (0x00040000) -#define PSB_2D_PAT_1555ARGB (0x00048000) -#define PSB_2D_PAT_565RGB (0x00050000) -#define PSB_2D_PAT_0888ARGB (0x00058000) -#define PSB_2D_PAT_8888ARGB (0x00060000) - -#define PSB_2D_PAT_STRIDE_MASK (0x00007FFF) -#define PSB_2D_PAT_STRIDE_CLRMASK (0xFFFF8000) -#define PSB_2D_PAT_STRIDE_SHIFT (0) -/* - * WORD 1 - Base Address - */ -#define PSB_2D_PAT_ADDR_MASK (0x0FFFFFFC) -#define PSB_2D_PAT_ADDR_CLRMASK (0x00000003) -#define PSB_2D_PAT_ADDR_SHIFT (2) -#define PSB_2D_PAT_ADDR_ALIGNSHIFT (2) - -/* - * Destination Surface (PSB_2D_DST_SURF_BH) - */ -/* - * WORD 0 - */ - -#define PSB_2D_DST_FORMAT_MASK (0x00078000) -#define PSB_2D_DST_332RGB (0x00030000) -#define PSB_2D_DST_4444ARGB (0x00038000) -#define PSB_2D_DST_555RGB (0x00040000) -#define PSB_2D_DST_1555ARGB (0x00048000) -#define PSB_2D_DST_565RGB (0x00050000) -#define PSB_2D_DST_0888ARGB (0x00058000) -#define PSB_2D_DST_8888ARGB (0x00060000) -#define PSB_2D_DST_8888AYUV (0x00070000) - -#define PSB_2D_DST_STRIDE_MASK (0x00007FFF) -#define PSB_2D_DST_STRIDE_CLRMASK (0xFFFF8000) -#define PSB_2D_DST_STRIDE_SHIFT (0) -/* - * WORD 1 - Base Address - */ -#define PSB_2D_DST_ADDR_MASK (0x0FFFFFFC) -#define PSB_2D_DST_ADDR_CLRMASK (0x00000003) -#define PSB_2D_DST_ADDR_SHIFT (2) -#define PSB_2D_DST_ADDR_ALIGNSHIFT (2) - -/* - * Mask Surface (PSB_2D_MASK_SURF_BH) - */ -/* - * WORD 0 - */ -#define PSB_2D_MASK_STRIDE_MASK (0x00007FFF) -#define PSB_2D_MASK_STRIDE_CLRMASK (0xFFFF8000) -#define PSB_2D_MASK_STRIDE_SHIFT (0) -/* - * WORD 1 - Base Address - */ -#define PSB_2D_MASK_ADDR_MASK (0x0FFFFFFC) -#define PSB_2D_MASK_ADDR_CLRMASK (0x00000003) -#define PSB_2D_MASK_ADDR_SHIFT (2) -#define PSB_2D_MASK_ADDR_ALIGNSHIFT (2) - -/* - * Source Palette (PSB_2D_SRC_PAL_BH) - */ - -#define PSB_2D_SRCPAL_ADDR_SHIFT (0) -#define PSB_2D_SRCPAL_ADDR_CLRMASK (0xF0000007) -#define PSB_2D_SRCPAL_ADDR_MASK (0x0FFFFFF8) -#define PSB_2D_SRCPAL_BYTEALIGN (1024) - -/* - * Pattern Palette (PSB_2D_PAT_PAL_BH) - */ - -#define PSB_2D_PATPAL_ADDR_SHIFT (0) -#define PSB_2D_PATPAL_ADDR_CLRMASK (0xF0000007) -#define PSB_2D_PATPAL_ADDR_MASK (0x0FFFFFF8) -#define PSB_2D_PATPAL_BYTEALIGN (1024) - -/* - * Rop3 Codes (2 LS bytes) - */ - -#define PSB_2D_ROP3_SRCCOPY (0xCCCC) -#define PSB_2D_ROP3_PATCOPY (0xF0F0) -#define PSB_2D_ROP3_WHITENESS (0xFFFF) -#define PSB_2D_ROP3_BLACKNESS (0x0000) -#define PSB_2D_ROP3_SRC (0xCC) -#define PSB_2D_ROP3_PAT (0xF0) -#define PSB_2D_ROP3_DST (0xAA) - - -/* - * Sizes. - */ - -#define PSB_SCENE_HW_COOKIE_SIZE 16 -#define PSB_TA_MEM_HW_COOKIE_SIZE 16 - -/* - * Scene stuff. - */ - -#define PSB_NUM_HW_SCENES 2 - -/* - * Scheduler completion actions. - */ - -#define PSB_RASTER_BLOCK 0 -#define PSB_RASTER 1 -#define PSB_RETURN 2 -#define PSB_TA 3 - - -/*Power management*/ -#define PSB_PUNIT_PORT 0x04 -#define PSB_OSPMBA 0x78 -#define PSB_APMBA 0x7a -#define PSB_APM_CMD 0x0 -#define PSB_APM_STS 0x04 -#define PSB_PWRGT_VID_ENC_MASK 0x30 -#define PSB_PWRGT_VID_DEC_MASK 0xc -#define PSB_PWRGT_GL3_MASK 0xc0 - -#define PSB_PM_SSC 0x20 -#define PSB_PM_SSS 0x30 -#define PSB_PWRGT_DISPLAY_MASK 0xc /*on a different BA than video/gfx*/ -#define MDFLD_PWRGT_DISPLAY_A_CNTR 0x0000000c -#define MDFLD_PWRGT_DISPLAY_B_CNTR 0x0000c000 -#define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000 -#define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000 -#define MDFLD_PWRGT_DISPLAY_CNTR (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR)// 0x000fc00c -// Display SSS register bits are different in A0 vs. B0 -#define PSB_PWRGT_GFX_MASK 0x3 -#define MDFLD_PWRGT_DISPLAY_A_STS 0x000000c0 -#define MDFLD_PWRGT_DISPLAY_B_STS 0x00000300 -#define MDFLD_PWRGT_DISPLAY_C_STS 0x00000c00 -#define PSB_PWRGT_GFX_MASK_B0 0xc3 -#define MDFLD_PWRGT_DISPLAY_A_STS_B0 0x0000000c -#define MDFLD_PWRGT_DISPLAY_B_STS_B0 0x0000c000 -#define MDFLD_PWRGT_DISPLAY_C_STS_B0 0x00030000 -#define MDFLD_PWRGT_DISP_MIPI_STS 0x000c0000 -#define MDFLD_PWRGT_DISPLAY_STS_A0 (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS)// 0x000fc00c -#define MDFLD_PWRGT_DISPLAY_STS_B0 (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS)// 0x000fc00c -#endif |
