Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gma500: Add Oaktrail support

Oaktrail (GMA600) is found on some tablet/slate PC type systems. It's a bit
different to the GMA500 but similar enough it makes sense to plug it into
the same driver.

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by

Alan Cox and committed by
Dave Airlie
1b082ccf 89c78134

+2936
+252
drivers/gpu/drm/gma500/oaktrail.h
··· 1 + /************************************************************************** 2 + * Copyright (c) 2007-2011, Intel Corporation. 3 + * All Rights Reserved. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms and conditions of the GNU General Public License, 7 + * version 2, as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program; if not, write to the Free Software Foundation, Inc., 16 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 17 + * 18 + **************************************************************************/ 19 + 20 + /* MID device specific descriptors */ 21 + 22 + struct oaktrail_vbt { 23 + s8 signature[4]; /*4 bytes,"$GCT" */ 24 + u8 revision; 25 + u8 size; 26 + u8 checksum; 27 + void *oaktrail_gct; 28 + } __packed; 29 + 30 + struct oaktrail_timing_info { 31 + u16 pixel_clock; 32 + u8 hactive_lo; 33 + u8 hblank_lo; 34 + u8 hblank_hi:4; 35 + u8 hactive_hi:4; 36 + u8 vactive_lo; 37 + u8 vblank_lo; 38 + u8 vblank_hi:4; 39 + u8 vactive_hi:4; 40 + u8 hsync_offset_lo; 41 + u8 hsync_pulse_width_lo; 42 + u8 vsync_pulse_width_lo:4; 43 + u8 vsync_offset_lo:4; 44 + u8 vsync_pulse_width_hi:2; 45 + u8 vsync_offset_hi:2; 46 + u8 hsync_pulse_width_hi:2; 47 + u8 hsync_offset_hi:2; 48 + u8 width_mm_lo; 49 + u8 height_mm_lo; 50 + u8 height_mm_hi:4; 51 + u8 width_mm_hi:4; 52 + u8 hborder; 53 + u8 vborder; 54 + u8 unknown0:1; 55 + u8 hsync_positive:1; 56 + u8 vsync_positive:1; 57 + u8 separate_sync:2; 58 + u8 stereo:1; 59 + u8 unknown6:1; 60 + u8 interlaced:1; 61 + } __packed; 62 + 63 + struct gct_r10_timing_info { 64 + u16 pixel_clock; 65 + u32 hactive_lo:8; 66 + u32 hactive_hi:4; 67 + u32 hblank_lo:8; 68 + u32 hblank_hi:4; 69 + u32 hsync_offset_lo:8; 70 + u16 hsync_offset_hi:2; 71 + u16 hsync_pulse_width_lo:8; 72 + u16 hsync_pulse_width_hi:2; 73 + u16 hsync_positive:1; 74 + u16 rsvd_1:3; 75 + u8 vactive_lo:8; 76 + u16 vactive_hi:4; 77 + u16 vblank_lo:8; 78 + u16 vblank_hi:4; 79 + u16 vsync_offset_lo:4; 80 + u16 vsync_offset_hi:2; 81 + u16 vsync_pulse_width_lo:4; 82 + u16 vsync_pulse_width_hi:2; 83 + u16 vsync_positive:1; 84 + u16 rsvd_2:3; 85 + } __packed; 86 + 87 + struct oaktrail_panel_descriptor_v1 { 88 + u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ 89 + /* 0x61190 if MIPI */ 90 + u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ 91 + u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ 92 + u32 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */ 93 + /* Register 0x61210 */ 94 + struct oaktrail_timing_info DTD;/*18 bytes, Standard definition */ 95 + u16 Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */ 96 + /* Bit 0, Frequency, 15 bits,0 - 32767Hz */ 97 + /* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */ 98 + u16 Panel_MIPI_Display_Descriptor; 99 + /*16 bits, Defined as follows: */ 100 + /* if MIPI, 0x0000 if LVDS */ 101 + /* Bit 0, Type, 2 bits, */ 102 + /* 0: Type-1, */ 103 + /* 1: Type-2, */ 104 + /* 2: Type-3, */ 105 + /* 3: Type-4 */ 106 + /* Bit 2, Pixel Format, 4 bits */ 107 + /* Bit0: 16bpp (not supported in LNC), */ 108 + /* Bit1: 18bpp loosely packed, */ 109 + /* Bit2: 18bpp packed, */ 110 + /* Bit3: 24bpp */ 111 + /* Bit 6, Reserved, 2 bits, 00b */ 112 + /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ 113 + /* Bit 14, Reserved, 2 bits, 00b */ 114 + } __packed; 115 + 116 + struct oaktrail_panel_descriptor_v2 { 117 + u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ 118 + /* 0x61190 if MIPI */ 119 + u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ 120 + u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ 121 + u8 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */ 122 + /* Register 0x61210 */ 123 + struct oaktrail_timing_info DTD;/*18 bytes, Standard definition */ 124 + u16 Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/ 125 + /*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/ 126 + u8 Panel_Initial_Brightness;/* [7:0] 0 - 100% */ 127 + /*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/ 128 + u16 Panel_MIPI_Display_Descriptor; 129 + /*16 bits, Defined as follows: */ 130 + /* if MIPI, 0x0000 if LVDS */ 131 + /* Bit 0, Type, 2 bits, */ 132 + /* 0: Type-1, */ 133 + /* 1: Type-2, */ 134 + /* 2: Type-3, */ 135 + /* 3: Type-4 */ 136 + /* Bit 2, Pixel Format, 4 bits */ 137 + /* Bit0: 16bpp (not supported in LNC), */ 138 + /* Bit1: 18bpp loosely packed, */ 139 + /* Bit2: 18bpp packed, */ 140 + /* Bit3: 24bpp */ 141 + /* Bit 6, Reserved, 2 bits, 00b */ 142 + /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ 143 + /* Bit 14, Reserved, 2 bits, 00b */ 144 + } __packed; 145 + 146 + union oaktrail_panel_rx { 147 + struct { 148 + u16 NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/ 149 + /* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */ 150 + u16 MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */ 151 + /*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/ 152 + u16 SupportedVideoTransferMode:2; /*0: Non-burst only */ 153 + /* 1: Burst and non-burst */ 154 + /* 2/3: Reserved */ 155 + u16 HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/ 156 + u16 DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/ 157 + u16 ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/ 158 + u16 BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */ 159 + u16 Rsvd:5;/*5 bits,00000b */ 160 + } panelrx; 161 + u16 panel_receiver; 162 + } __packed; 163 + 164 + struct oaktrail_gct_v1 { 165 + union { /*8 bits,Defined as follows: */ 166 + struct { 167 + u8 PanelType:4; /*4 bits, Bit field for panels*/ 168 + /* 0 - 3: 0 = LVDS, 1 = MIPI*/ 169 + /*2 bits,Specifies which of the*/ 170 + u8 BootPanelIndex:2; 171 + /* 4 panels to use by default*/ 172 + u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ 173 + /* the 4 MIPI DSI receivers to use*/ 174 + } PD; 175 + u8 PanelDescriptor; 176 + }; 177 + struct oaktrail_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/ 178 + union oaktrail_panel_rx panelrx[4]; /* panel receivers*/ 179 + } __packed; 180 + 181 + struct oaktrail_gct_v2 { 182 + union { /*8 bits,Defined as follows: */ 183 + struct { 184 + u8 PanelType:4; /*4 bits, Bit field for panels*/ 185 + /* 0 - 3: 0 = LVDS, 1 = MIPI*/ 186 + /*2 bits,Specifies which of the*/ 187 + u8 BootPanelIndex:2; 188 + /* 4 panels to use by default*/ 189 + u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ 190 + /* the 4 MIPI DSI receivers to use*/ 191 + } PD; 192 + u8 PanelDescriptor; 193 + }; 194 + struct oaktrail_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/ 195 + union oaktrail_panel_rx panelrx[4]; /* panel receivers*/ 196 + } __packed; 197 + 198 + struct oaktrail_gct_data { 199 + u8 bpi; /* boot panel index, number of panel used during boot */ 200 + u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */ 201 + struct oaktrail_timing_info DTD; /* timing info for the selected panel */ 202 + u32 Panel_Port_Control; 203 + u32 PP_On_Sequencing;/*1 dword,Register 0x61208,*/ 204 + u32 PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/ 205 + u32 PP_Cycle_Delay; 206 + u16 Panel_Backlight_Inverter_Descriptor; 207 + u16 Panel_MIPI_Display_Descriptor; 208 + } __packed; 209 + 210 + #define MODE_SETTING_IN_CRTC 0x1 211 + #define MODE_SETTING_IN_ENCODER 0x2 212 + #define MODE_SETTING_ON_GOING 0x3 213 + #define MODE_SETTING_IN_DSR 0x4 214 + #define MODE_SETTING_ENCODER_DONE 0x8 215 + 216 + #define GCT_R10_HEADER_SIZE 16 217 + #define GCT_R10_DISPLAY_DESC_SIZE 28 218 + 219 + /* 220 + * Moorestown HDMI interfaces 221 + */ 222 + 223 + struct oaktrail_hdmi_dev { 224 + struct pci_dev *dev; 225 + void __iomem *regs; 226 + unsigned int mmio, mmio_len; 227 + int dpms_mode; 228 + struct hdmi_i2c_dev *i2c_dev; 229 + 230 + /* register state */ 231 + u32 saveDPLL_CTRL; 232 + u32 saveDPLL_DIV_CTRL; 233 + u32 saveDPLL_ADJUST; 234 + u32 saveDPLL_UPDATE; 235 + u32 saveDPLL_CLK_ENABLE; 236 + u32 savePCH_HTOTAL_B; 237 + u32 savePCH_HBLANK_B; 238 + u32 savePCH_HSYNC_B; 239 + u32 savePCH_VTOTAL_B; 240 + u32 savePCH_VBLANK_B; 241 + u32 savePCH_VSYNC_B; 242 + u32 savePCH_PIPEBCONF; 243 + u32 savePCH_PIPEBSRC; 244 + }; 245 + 246 + extern void oaktrail_hdmi_setup(struct drm_device *dev); 247 + extern void oaktrail_hdmi_teardown(struct drm_device *dev); 248 + extern int oaktrail_hdmi_i2c_init(struct pci_dev *dev); 249 + extern void oaktrail_hdmi_i2c_exit(struct pci_dev *dev); 250 + extern void oaktrail_hdmi_save(struct drm_device *dev); 251 + extern void oaktrail_hdmi_restore(struct drm_device *dev); 252 + extern void oaktrail_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev);
+610
drivers/gpu/drm/gma500/oaktrail_crtc.c
··· 1 + /* 2 + * Copyright © 2009 Intel Corporation 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + * 13 + * You should have received a copy of the GNU General Public License along with 14 + * this program; if not, write to the Free Software Foundation, Inc., 15 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 16 + */ 17 + 18 + #include <linux/i2c.h> 19 + #include <linux/pm_runtime.h> 20 + 21 + #include <drm/drmP.h> 22 + #include "framebuffer.h" 23 + #include "psb_drv.h" 24 + #include "psb_intel_drv.h" 25 + #include "psb_intel_reg.h" 26 + #include "psb_intel_display.h" 27 + #include "power.h" 28 + 29 + struct psb_intel_range_t { 30 + int min, max; 31 + }; 32 + 33 + struct oaktrail_limit_t { 34 + struct psb_intel_range_t dot, m, p1; 35 + }; 36 + 37 + struct oaktrail_clock_t { 38 + /* derived values */ 39 + int dot; 40 + int m; 41 + int p1; 42 + }; 43 + 44 + #define MRST_LIMIT_LVDS_100L 0 45 + #define MRST_LIMIT_LVDS_83 1 46 + #define MRST_LIMIT_LVDS_100 2 47 + 48 + #define MRST_DOT_MIN 19750 49 + #define MRST_DOT_MAX 120000 50 + #define MRST_M_MIN_100L 20 51 + #define MRST_M_MIN_100 10 52 + #define MRST_M_MIN_83 12 53 + #define MRST_M_MAX_100L 34 54 + #define MRST_M_MAX_100 17 55 + #define MRST_M_MAX_83 20 56 + #define MRST_P1_MIN 2 57 + #define MRST_P1_MAX_0 7 58 + #define MRST_P1_MAX_1 8 59 + 60 + static const struct oaktrail_limit_t oaktrail_limits[] = { 61 + { /* MRST_LIMIT_LVDS_100L */ 62 + .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, 63 + .m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L}, 64 + .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1}, 65 + }, 66 + { /* MRST_LIMIT_LVDS_83L */ 67 + .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, 68 + .m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83}, 69 + .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0}, 70 + }, 71 + { /* MRST_LIMIT_LVDS_100 */ 72 + .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, 73 + .m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100}, 74 + .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1}, 75 + }, 76 + }; 77 + 78 + #define MRST_M_MIN 10 79 + static const u32 oaktrail_m_converts[] = { 80 + 0x2B, 0x15, 0x2A, 0x35, 0x1A, 0x0D, 0x26, 0x33, 0x19, 0x2C, 81 + 0x36, 0x3B, 0x1D, 0x2E, 0x37, 0x1B, 0x2D, 0x16, 0x0B, 0x25, 82 + 0x12, 0x09, 0x24, 0x32, 0x39, 0x1c, 83 + }; 84 + 85 + static const struct oaktrail_limit_t *oaktrail_limit(struct drm_crtc *crtc) 86 + { 87 + const struct oaktrail_limit_t *limit = NULL; 88 + struct drm_device *dev = crtc->dev; 89 + struct drm_psb_private *dev_priv = dev->dev_private; 90 + 91 + if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) 92 + || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) { 93 + switch (dev_priv->core_freq) { 94 + case 100: 95 + limit = &oaktrail_limits[MRST_LIMIT_LVDS_100L]; 96 + break; 97 + case 166: 98 + limit = &oaktrail_limits[MRST_LIMIT_LVDS_83]; 99 + break; 100 + case 200: 101 + limit = &oaktrail_limits[MRST_LIMIT_LVDS_100]; 102 + break; 103 + } 104 + } else { 105 + limit = NULL; 106 + dev_err(dev->dev, "oaktrail_limit Wrong display type.\n"); 107 + } 108 + 109 + return limit; 110 + } 111 + 112 + /** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ 113 + static void oaktrail_clock(int refclk, struct oaktrail_clock_t *clock) 114 + { 115 + clock->dot = (refclk * clock->m) / (14 * clock->p1); 116 + } 117 + 118 + void mrstPrintPll(char *prefix, struct oaktrail_clock_t *clock) 119 + { 120 + pr_debug("%s: dotclock = %d, m = %d, p1 = %d.\n", 121 + prefix, clock->dot, clock->m, clock->p1); 122 + } 123 + 124 + /** 125 + * Returns a set of divisors for the desired target clock with the given refclk, 126 + * or FALSE. Divisor values are the actual divisors for 127 + */ 128 + static bool 129 + mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk, 130 + struct oaktrail_clock_t *best_clock) 131 + { 132 + struct oaktrail_clock_t clock; 133 + const struct oaktrail_limit_t *limit = oaktrail_limit(crtc); 134 + int err = target; 135 + 136 + memset(best_clock, 0, sizeof(*best_clock)); 137 + 138 + for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) { 139 + for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max; 140 + clock.p1++) { 141 + int this_err; 142 + 143 + oaktrail_clock(refclk, &clock); 144 + 145 + this_err = abs(clock.dot - target); 146 + if (this_err < err) { 147 + *best_clock = clock; 148 + err = this_err; 149 + } 150 + } 151 + } 152 + dev_dbg(crtc->dev->dev, "mrstFindBestPLL err = %d.\n", err); 153 + return err != target; 154 + } 155 + 156 + /** 157 + * Sets the power management mode of the pipe and plane. 158 + * 159 + * This code should probably grow support for turning the cursor off and back 160 + * on appropriately at the same time as we're turning the pipe off/on. 161 + */ 162 + static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode) 163 + { 164 + struct drm_device *dev = crtc->dev; 165 + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); 166 + int pipe = psb_intel_crtc->pipe; 167 + int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B; 168 + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; 169 + int dspbase_reg = (pipe == 0) ? MRST_DSPABASE : DSPBBASE; 170 + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; 171 + u32 temp; 172 + bool enabled; 173 + 174 + if (!gma_power_begin(dev, true)) 175 + return; 176 + 177 + /* XXX: When our outputs are all unaware of DPMS modes other than off 178 + * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. 179 + */ 180 + switch (mode) { 181 + case DRM_MODE_DPMS_ON: 182 + case DRM_MODE_DPMS_STANDBY: 183 + case DRM_MODE_DPMS_SUSPEND: 184 + /* Enable the DPLL */ 185 + temp = REG_READ(dpll_reg); 186 + if ((temp & DPLL_VCO_ENABLE) == 0) { 187 + REG_WRITE(dpll_reg, temp); 188 + REG_READ(dpll_reg); 189 + /* Wait for the clocks to stabilize. */ 190 + udelay(150); 191 + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); 192 + REG_READ(dpll_reg); 193 + /* Wait for the clocks to stabilize. */ 194 + udelay(150); 195 + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); 196 + REG_READ(dpll_reg); 197 + /* Wait for the clocks to stabilize. */ 198 + udelay(150); 199 + } 200 + /* Enable the pipe */ 201 + temp = REG_READ(pipeconf_reg); 202 + if ((temp & PIPEACONF_ENABLE) == 0) 203 + REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); 204 + /* Enable the plane */ 205 + temp = REG_READ(dspcntr_reg); 206 + if ((temp & DISPLAY_PLANE_ENABLE) == 0) { 207 + REG_WRITE(dspcntr_reg, 208 + temp | DISPLAY_PLANE_ENABLE); 209 + /* Flush the plane changes */ 210 + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); 211 + } 212 + 213 + psb_intel_crtc_load_lut(crtc); 214 + 215 + /* Give the overlay scaler a chance to enable 216 + if it's on this pipe */ 217 + /* psb_intel_crtc_dpms_video(crtc, true); TODO */ 218 + break; 219 + case DRM_MODE_DPMS_OFF: 220 + /* Give the overlay scaler a chance to disable 221 + * if it's on this pipe */ 222 + /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ 223 + 224 + /* Disable the VGA plane that we never use */ 225 + REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); 226 + /* Disable display plane */ 227 + temp = REG_READ(dspcntr_reg); 228 + if ((temp & DISPLAY_PLANE_ENABLE) != 0) { 229 + REG_WRITE(dspcntr_reg, 230 + temp & ~DISPLAY_PLANE_ENABLE); 231 + /* Flush the plane changes */ 232 + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); 233 + REG_READ(dspbase_reg); 234 + } 235 + 236 + /* Next, disable display pipes */ 237 + temp = REG_READ(pipeconf_reg); 238 + if ((temp & PIPEACONF_ENABLE) != 0) { 239 + REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); 240 + REG_READ(pipeconf_reg); 241 + } 242 + /* Wait for for the pipe disable to take effect. */ 243 + psb_intel_wait_for_vblank(dev); 244 + 245 + temp = REG_READ(dpll_reg); 246 + if ((temp & DPLL_VCO_ENABLE) != 0) { 247 + REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); 248 + REG_READ(dpll_reg); 249 + } 250 + 251 + /* Wait for the clocks to turn off. */ 252 + udelay(150); 253 + break; 254 + } 255 + 256 + enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF; 257 + 258 + /*Set FIFO Watermarks*/ 259 + REG_WRITE(DSPARB, 0x3FFF); 260 + REG_WRITE(DSPFW1, 0x3F88080A); 261 + REG_WRITE(DSPFW2, 0x0b060808); 262 + REG_WRITE(DSPFW3, 0x0); 263 + REG_WRITE(DSPFW4, 0x08030404); 264 + REG_WRITE(DSPFW5, 0x04040404); 265 + REG_WRITE(DSPFW6, 0x78); 266 + REG_WRITE(0x70400, REG_READ(0x70400) | 0x4000); 267 + /* Must write Bit 14 of the Chicken Bit Register */ 268 + 269 + gma_power_end(dev); 270 + } 271 + 272 + /** 273 + * Return the pipe currently connected to the panel fitter, 274 + * or -1 if the panel fitter is not present or not in use 275 + */ 276 + static int oaktrail_panel_fitter_pipe(struct drm_device *dev) 277 + { 278 + u32 pfit_control; 279 + 280 + pfit_control = REG_READ(PFIT_CONTROL); 281 + 282 + /* See if the panel fitter is in use */ 283 + if ((pfit_control & PFIT_ENABLE) == 0) 284 + return -1; 285 + return (pfit_control >> 29) & 3; 286 + } 287 + 288 + static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, 289 + struct drm_display_mode *mode, 290 + struct drm_display_mode *adjusted_mode, 291 + int x, int y, 292 + struct drm_framebuffer *old_fb) 293 + { 294 + struct drm_device *dev = crtc->dev; 295 + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); 296 + struct drm_psb_private *dev_priv = dev->dev_private; 297 + int pipe = psb_intel_crtc->pipe; 298 + int fp_reg = (pipe == 0) ? MRST_FPA0 : FPB0; 299 + int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B; 300 + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; 301 + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; 302 + int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; 303 + int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; 304 + int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; 305 + int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; 306 + int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; 307 + int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; 308 + int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; 309 + int refclk = 0; 310 + struct oaktrail_clock_t clock; 311 + u32 dpll = 0, fp = 0, dspcntr, pipeconf; 312 + bool ok, is_sdvo = false; 313 + bool is_crt = false, is_lvds = false, is_tv = false; 314 + bool is_mipi = false; 315 + struct drm_mode_config *mode_config = &dev->mode_config; 316 + struct psb_intel_output *psb_intel_output = NULL; 317 + uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN; 318 + struct drm_encoder *encoder; 319 + 320 + if (!gma_power_begin(dev, true)) 321 + return 0; 322 + 323 + memcpy(&psb_intel_crtc->saved_mode, 324 + mode, 325 + sizeof(struct drm_display_mode)); 326 + memcpy(&psb_intel_crtc->saved_adjusted_mode, 327 + adjusted_mode, 328 + sizeof(struct drm_display_mode)); 329 + 330 + list_for_each_entry(encoder, &mode_config->encoder_list, head) { 331 + 332 + if (encoder->crtc != crtc) 333 + continue; 334 + 335 + psb_intel_output = enc_to_psb_intel_output(encoder); 336 + switch (psb_intel_output->type) { 337 + case INTEL_OUTPUT_LVDS: 338 + is_lvds = true; 339 + break; 340 + case INTEL_OUTPUT_SDVO: 341 + is_sdvo = true; 342 + break; 343 + case INTEL_OUTPUT_TVOUT: 344 + is_tv = true; 345 + break; 346 + case INTEL_OUTPUT_ANALOG: 347 + is_crt = true; 348 + break; 349 + case INTEL_OUTPUT_MIPI: 350 + is_mipi = true; 351 + break; 352 + } 353 + } 354 + 355 + /* Disable the VGA plane that we never use */ 356 + REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); 357 + 358 + /* Disable the panel fitter if it was on our pipe */ 359 + if (oaktrail_panel_fitter_pipe(dev) == pipe) 360 + REG_WRITE(PFIT_CONTROL, 0); 361 + 362 + REG_WRITE(pipesrc_reg, 363 + ((mode->crtc_hdisplay - 1) << 16) | 364 + (mode->crtc_vdisplay - 1)); 365 + 366 + if (psb_intel_output) 367 + drm_connector_property_get_value(&psb_intel_output->base, 368 + dev->mode_config.scaling_mode_property, &scalingType); 369 + 370 + if (scalingType == DRM_MODE_SCALE_NO_SCALE) { 371 + /* Moorestown doesn't have register support for centering so 372 + * we need to mess with the h/vblank and h/vsync start and 373 + * ends to get centering */ 374 + int offsetX = 0, offsetY = 0; 375 + 376 + offsetX = (adjusted_mode->crtc_hdisplay - 377 + mode->crtc_hdisplay) / 2; 378 + offsetY = (adjusted_mode->crtc_vdisplay - 379 + mode->crtc_vdisplay) / 2; 380 + 381 + REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) | 382 + ((adjusted_mode->crtc_htotal - 1) << 16)); 383 + REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) | 384 + ((adjusted_mode->crtc_vtotal - 1) << 16)); 385 + REG_WRITE(hblank_reg, 386 + (adjusted_mode->crtc_hblank_start - offsetX - 1) | 387 + ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16)); 388 + REG_WRITE(hsync_reg, 389 + (adjusted_mode->crtc_hsync_start - offsetX - 1) | 390 + ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16)); 391 + REG_WRITE(vblank_reg, 392 + (adjusted_mode->crtc_vblank_start - offsetY - 1) | 393 + ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16)); 394 + REG_WRITE(vsync_reg, 395 + (adjusted_mode->crtc_vsync_start - offsetY - 1) | 396 + ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16)); 397 + } else { 398 + REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | 399 + ((adjusted_mode->crtc_htotal - 1) << 16)); 400 + REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | 401 + ((adjusted_mode->crtc_vtotal - 1) << 16)); 402 + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | 403 + ((adjusted_mode->crtc_hblank_end - 1) << 16)); 404 + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | 405 + ((adjusted_mode->crtc_hsync_end - 1) << 16)); 406 + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | 407 + ((adjusted_mode->crtc_vblank_end - 1) << 16)); 408 + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | 409 + ((adjusted_mode->crtc_vsync_end - 1) << 16)); 410 + } 411 + 412 + /* Flush the plane changes */ 413 + { 414 + struct drm_crtc_helper_funcs *crtc_funcs = 415 + crtc->helper_private; 416 + crtc_funcs->mode_set_base(crtc, x, y, old_fb); 417 + } 418 + 419 + /* setup pipeconf */ 420 + pipeconf = REG_READ(pipeconf_reg); 421 + 422 + /* Set up the display plane register */ 423 + dspcntr = REG_READ(dspcntr_reg); 424 + dspcntr |= DISPPLANE_GAMMA_ENABLE; 425 + 426 + if (pipe == 0) 427 + dspcntr |= DISPPLANE_SEL_PIPE_A; 428 + else 429 + dspcntr |= DISPPLANE_SEL_PIPE_B; 430 + 431 + dev_priv->dspcntr = dspcntr |= DISPLAY_PLANE_ENABLE; 432 + dev_priv->pipeconf = pipeconf |= PIPEACONF_ENABLE; 433 + 434 + if (is_mipi) 435 + goto oaktrail_crtc_mode_set_exit; 436 + 437 + refclk = dev_priv->core_freq * 1000; 438 + 439 + dpll = 0; /*BIT16 = 0 for 100MHz reference */ 440 + 441 + ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock); 442 + 443 + if (!ok) { 444 + dev_dbg(dev->dev, "mrstFindBestPLL fail in oaktrail_crtc_mode_set.\n"); 445 + } else { 446 + dev_dbg(dev->dev, "oaktrail_crtc_mode_set pixel clock = %d," 447 + "m = %x, p1 = %x.\n", clock.dot, clock.m, 448 + clock.p1); 449 + } 450 + 451 + fp = oaktrail_m_converts[(clock.m - MRST_M_MIN)] << 8; 452 + 453 + dpll |= DPLL_VGA_MODE_DIS; 454 + 455 + 456 + dpll |= DPLL_VCO_ENABLE; 457 + 458 + if (is_lvds) 459 + dpll |= DPLLA_MODE_LVDS; 460 + else 461 + dpll |= DPLLB_MODE_DAC_SERIAL; 462 + 463 + if (is_sdvo) { 464 + int sdvo_pixel_multiply = 465 + adjusted_mode->clock / mode->clock; 466 + 467 + dpll |= DPLL_DVO_HIGH_SPEED; 468 + dpll |= 469 + (sdvo_pixel_multiply - 470 + 1) << SDVO_MULTIPLIER_SHIFT_HIRES; 471 + } 472 + 473 + 474 + /* compute bitmask from p1 value */ 475 + dpll |= (1 << (clock.p1 - 2)) << 17; 476 + 477 + dpll |= DPLL_VCO_ENABLE; 478 + 479 + mrstPrintPll("chosen", &clock); 480 + 481 + if (dpll & DPLL_VCO_ENABLE) { 482 + REG_WRITE(fp_reg, fp); 483 + REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); 484 + REG_READ(dpll_reg); 485 + /* Check the DPLLA lock bit PIPEACONF[29] */ 486 + udelay(150); 487 + } 488 + 489 + REG_WRITE(fp_reg, fp); 490 + REG_WRITE(dpll_reg, dpll); 491 + REG_READ(dpll_reg); 492 + /* Wait for the clocks to stabilize. */ 493 + udelay(150); 494 + 495 + /* write it again -- the BIOS does, after all */ 496 + REG_WRITE(dpll_reg, dpll); 497 + REG_READ(dpll_reg); 498 + /* Wait for the clocks to stabilize. */ 499 + udelay(150); 500 + 501 + REG_WRITE(pipeconf_reg, pipeconf); 502 + REG_READ(pipeconf_reg); 503 + psb_intel_wait_for_vblank(dev); 504 + 505 + REG_WRITE(dspcntr_reg, dspcntr); 506 + psb_intel_wait_for_vblank(dev); 507 + 508 + oaktrail_crtc_mode_set_exit: 509 + gma_power_end(dev); 510 + return 0; 511 + } 512 + 513 + static bool oaktrail_crtc_mode_fixup(struct drm_crtc *crtc, 514 + struct drm_display_mode *mode, 515 + struct drm_display_mode *adjusted_mode) 516 + { 517 + return true; 518 + } 519 + 520 + int oaktrail_pipe_set_base(struct drm_crtc *crtc, 521 + int x, int y, struct drm_framebuffer *old_fb) 522 + { 523 + struct drm_device *dev = crtc->dev; 524 + /* struct drm_i915_master_private *master_priv; */ 525 + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); 526 + struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); 527 + int pipe = psb_intel_crtc->pipe; 528 + unsigned long start, offset; 529 + /* FIXME: check if we need this surely MRST is pipe 0 only */ 530 + int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE); 531 + int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); 532 + int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; 533 + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; 534 + u32 dspcntr; 535 + int ret = 0; 536 + 537 + /* no fb bound */ 538 + if (!crtc->fb) { 539 + dev_dbg(dev->dev, "No FB bound\n"); 540 + return 0; 541 + } 542 + 543 + if (!gma_power_begin(dev, true)) 544 + return 0; 545 + 546 + start = psbfb->gtt->offset; 547 + offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); 548 + 549 + REG_WRITE(dspstride, crtc->fb->pitch); 550 + 551 + dspcntr = REG_READ(dspcntr_reg); 552 + dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; 553 + 554 + switch (crtc->fb->bits_per_pixel) { 555 + case 8: 556 + dspcntr |= DISPPLANE_8BPP; 557 + break; 558 + case 16: 559 + if (crtc->fb->depth == 15) 560 + dspcntr |= DISPPLANE_15_16BPP; 561 + else 562 + dspcntr |= DISPPLANE_16BPP; 563 + break; 564 + case 24: 565 + case 32: 566 + dspcntr |= DISPPLANE_32BPP_NO_ALPHA; 567 + break; 568 + default: 569 + dev_err(dev->dev, "Unknown color depth\n"); 570 + ret = -EINVAL; 571 + goto pipe_set_base_exit; 572 + } 573 + REG_WRITE(dspcntr_reg, dspcntr); 574 + 575 + if (0 /* FIXMEAC - check what PSB needs */) { 576 + REG_WRITE(dspbase, offset); 577 + REG_READ(dspbase); 578 + REG_WRITE(dspsurf, start); 579 + REG_READ(dspsurf); 580 + } else { 581 + REG_WRITE(dspbase, start + offset); 582 + REG_READ(dspbase); 583 + } 584 + 585 + pipe_set_base_exit: 586 + gma_power_end(dev); 587 + return ret; 588 + } 589 + 590 + static void oaktrail_crtc_prepare(struct drm_crtc *crtc) 591 + { 592 + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 593 + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); 594 + } 595 + 596 + static void oaktrail_crtc_commit(struct drm_crtc *crtc) 597 + { 598 + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 599 + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); 600 + } 601 + 602 + const struct drm_crtc_helper_funcs oaktrail_helper_funcs = { 603 + .dpms = oaktrail_crtc_dpms, 604 + .mode_fixup = oaktrail_crtc_mode_fixup, 605 + .mode_set = oaktrail_crtc_mode_set, 606 + .mode_set_base = oaktrail_pipe_set_base, 607 + .prepare = oaktrail_crtc_prepare, 608 + .commit = oaktrail_crtc_commit, 609 + }; 610 +
+489
drivers/gpu/drm/gma500/oaktrail_device.c
··· 1 + /************************************************************************** 2 + * Copyright (c) 2011, Intel Corporation. 3 + * All Rights Reserved. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms and conditions of the GNU General Public License, 7 + * version 2, as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program; if not, write to the Free Software Foundation, Inc., 16 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 17 + * 18 + **************************************************************************/ 19 + 20 + #include <linux/backlight.h> 21 + #include <linux/module.h> 22 + #include <linux/dmi.h> 23 + #include <drm/drmP.h> 24 + #include <drm/drm.h> 25 + #include "psb_drm.h" 26 + #include "psb_drv.h" 27 + #include "psb_reg.h" 28 + #include "psb_intel_reg.h" 29 + #include <asm/mrst.h> 30 + #include <asm/intel_scu_ipc.h> 31 + #include "mid_bios.h" 32 + 33 + static int oaktrail_output_init(struct drm_device *dev) 34 + { 35 + struct drm_psb_private *dev_priv = dev->dev_private; 36 + if (dev_priv->iLVDS_enable) 37 + oaktrail_lvds_init(dev, &dev_priv->mode_dev); 38 + else 39 + dev_err(dev->dev, "DSI is not supported\n"); 40 + if (dev_priv->hdmi_priv) 41 + oaktrail_hdmi_init(dev, &dev_priv->mode_dev); 42 + return 0; 43 + } 44 + 45 + /* 46 + * Provide the low level interfaces for the Moorestown backlight 47 + */ 48 + 49 + #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 50 + 51 + #define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF 52 + #define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ 53 + #define BLC_PWM_FREQ_CALC_CONSTANT 32 54 + #define MHz 1000000 55 + #define BLC_ADJUSTMENT_MAX 100 56 + 57 + static struct backlight_device *oaktrail_backlight_device; 58 + static int oaktrail_brightness; 59 + 60 + static int oaktrail_set_brightness(struct backlight_device *bd) 61 + { 62 + struct drm_device *dev = bl_get_data(oaktrail_backlight_device); 63 + struct drm_psb_private *dev_priv = dev->dev_private; 64 + int level = bd->props.brightness; 65 + u32 blc_pwm_ctl; 66 + u32 max_pwm_blc; 67 + 68 + /* Percentage 1-100% being valid */ 69 + if (level < 1) 70 + level = 1; 71 + 72 + if (gma_power_begin(dev, 0)) { 73 + /* Calculate and set the brightness value */ 74 + max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16; 75 + blc_pwm_ctl = level * max_pwm_blc / 100; 76 + 77 + /* Adjust the backlight level with the percent in 78 + * dev_priv->blc_adj1; 79 + */ 80 + blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1; 81 + blc_pwm_ctl = blc_pwm_ctl / 100; 82 + 83 + /* Adjust the backlight level with the percent in 84 + * dev_priv->blc_adj2; 85 + */ 86 + blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2; 87 + blc_pwm_ctl = blc_pwm_ctl / 100; 88 + 89 + /* force PWM bit on */ 90 + REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2))); 91 + REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl); 92 + gma_power_end(dev); 93 + } 94 + oaktrail_brightness = level; 95 + return 0; 96 + } 97 + 98 + static int oaktrail_get_brightness(struct backlight_device *bd) 99 + { 100 + /* return locally cached var instead of HW read (due to DPST etc.) */ 101 + /* FIXME: ideally return actual value in case firmware fiddled with 102 + it */ 103 + return oaktrail_brightness; 104 + } 105 + 106 + static int device_backlight_init(struct drm_device *dev) 107 + { 108 + struct drm_psb_private *dev_priv = dev->dev_private; 109 + unsigned long core_clock; 110 + u16 bl_max_freq; 111 + uint32_t value; 112 + uint32_t blc_pwm_precision_factor; 113 + 114 + dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX; 115 + dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX; 116 + bl_max_freq = 256; 117 + /* this needs to be set elsewhere */ 118 + blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR; 119 + 120 + core_clock = dev_priv->core_freq; 121 + 122 + value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; 123 + value *= blc_pwm_precision_factor; 124 + value /= bl_max_freq; 125 + value /= blc_pwm_precision_factor; 126 + 127 + if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ) 128 + return -ERANGE; 129 + 130 + if (gma_power_begin(dev, false)) { 131 + REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2))); 132 + REG_WRITE(BLC_PWM_CTL, value | (value << 16)); 133 + gma_power_end(dev); 134 + } 135 + return 0; 136 + } 137 + 138 + static const struct backlight_ops oaktrail_ops = { 139 + .get_brightness = oaktrail_get_brightness, 140 + .update_status = oaktrail_set_brightness, 141 + }; 142 + 143 + int oaktrail_backlight_init(struct drm_device *dev) 144 + { 145 + struct drm_psb_private *dev_priv = dev->dev_private; 146 + int ret; 147 + struct backlight_properties props; 148 + 149 + memset(&props, 0, sizeof(struct backlight_properties)); 150 + props.max_brightness = 100; 151 + props.type = BACKLIGHT_PLATFORM; 152 + 153 + oaktrail_backlight_device = backlight_device_register("oaktrail-bl", 154 + NULL, (void *)dev, &oaktrail_ops, &props); 155 + 156 + if (IS_ERR(oaktrail_backlight_device)) 157 + return PTR_ERR(oaktrail_backlight_device); 158 + 159 + ret = device_backlight_init(dev); 160 + if (ret < 0) { 161 + backlight_device_unregister(oaktrail_backlight_device); 162 + return ret; 163 + } 164 + oaktrail_backlight_device->props.brightness = 100; 165 + oaktrail_backlight_device->props.max_brightness = 100; 166 + backlight_update_status(oaktrail_backlight_device); 167 + dev_priv->backlight_device = oaktrail_backlight_device; 168 + return 0; 169 + } 170 + 171 + #endif 172 + 173 + /* 174 + * Provide the Moorestown specific chip logic and low level methods 175 + * for power management 176 + */ 177 + 178 + static void oaktrail_init_pm(struct drm_device *dev) 179 + { 180 + } 181 + 182 + /** 183 + * oaktrail_save_display_registers - save registers lost on suspend 184 + * @dev: our DRM device 185 + * 186 + * Save the state we need in order to be able to restore the interface 187 + * upon resume from suspend 188 + */ 189 + static int oaktrail_save_display_registers(struct drm_device *dev) 190 + { 191 + struct drm_psb_private *dev_priv = dev->dev_private; 192 + int i; 193 + u32 pp_stat; 194 + 195 + /* Display arbitration control + watermarks */ 196 + dev_priv->saveDSPARB = PSB_RVDC32(DSPARB); 197 + dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1); 198 + dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2); 199 + dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3); 200 + dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4); 201 + dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5); 202 + dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6); 203 + dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT); 204 + 205 + /* Pipe & plane A info */ 206 + dev_priv->savePIPEACONF = PSB_RVDC32(PIPEACONF); 207 + dev_priv->savePIPEASRC = PSB_RVDC32(PIPEASRC); 208 + dev_priv->saveFPA0 = PSB_RVDC32(MRST_FPA0); 209 + dev_priv->saveFPA1 = PSB_RVDC32(MRST_FPA1); 210 + dev_priv->saveDPLL_A = PSB_RVDC32(MRST_DPLL_A); 211 + dev_priv->saveHTOTAL_A = PSB_RVDC32(HTOTAL_A); 212 + dev_priv->saveHBLANK_A = PSB_RVDC32(HBLANK_A); 213 + dev_priv->saveHSYNC_A = PSB_RVDC32(HSYNC_A); 214 + dev_priv->saveVTOTAL_A = PSB_RVDC32(VTOTAL_A); 215 + dev_priv->saveVBLANK_A = PSB_RVDC32(VBLANK_A); 216 + dev_priv->saveVSYNC_A = PSB_RVDC32(VSYNC_A); 217 + dev_priv->saveBCLRPAT_A = PSB_RVDC32(BCLRPAT_A); 218 + dev_priv->saveDSPACNTR = PSB_RVDC32(DSPACNTR); 219 + dev_priv->saveDSPASTRIDE = PSB_RVDC32(DSPASTRIDE); 220 + dev_priv->saveDSPAADDR = PSB_RVDC32(DSPABASE); 221 + dev_priv->saveDSPASURF = PSB_RVDC32(DSPASURF); 222 + dev_priv->saveDSPALINOFF = PSB_RVDC32(DSPALINOFF); 223 + dev_priv->saveDSPATILEOFF = PSB_RVDC32(DSPATILEOFF); 224 + 225 + /* Save cursor regs */ 226 + dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR); 227 + dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE); 228 + dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS); 229 + 230 + /* Save palette (gamma) */ 231 + for (i = 0; i < 256; i++) 232 + dev_priv->save_palette_a[i] = PSB_RVDC32(PALETTE_A + (i << 2)); 233 + 234 + if (dev_priv->hdmi_priv) 235 + oaktrail_hdmi_save(dev); 236 + 237 + /* Save performance state */ 238 + dev_priv->savePERF_MODE = PSB_RVDC32(MRST_PERF_MODE); 239 + 240 + /* LVDS state */ 241 + dev_priv->savePP_CONTROL = PSB_RVDC32(PP_CONTROL); 242 + dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS); 243 + dev_priv->savePFIT_AUTO_RATIOS = PSB_RVDC32(PFIT_AUTO_RATIOS); 244 + dev_priv->saveBLC_PWM_CTL = PSB_RVDC32(BLC_PWM_CTL); 245 + dev_priv->saveBLC_PWM_CTL2 = PSB_RVDC32(BLC_PWM_CTL2); 246 + dev_priv->saveLVDS = PSB_RVDC32(LVDS); 247 + dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL); 248 + dev_priv->savePP_ON_DELAYS = PSB_RVDC32(LVDSPP_ON); 249 + dev_priv->savePP_OFF_DELAYS = PSB_RVDC32(LVDSPP_OFF); 250 + dev_priv->savePP_DIVISOR = PSB_RVDC32(PP_CYCLE); 251 + 252 + /* HW overlay */ 253 + dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD); 254 + dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0); 255 + dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1); 256 + dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2); 257 + dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3); 258 + dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4); 259 + dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5); 260 + 261 + /* DPST registers */ 262 + dev_priv->saveHISTOGRAM_INT_CONTROL_REG = 263 + PSB_RVDC32(HISTOGRAM_INT_CONTROL); 264 + dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG = 265 + PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); 266 + dev_priv->savePWM_CONTROL_LOGIC = PSB_RVDC32(PWM_CONTROL_LOGIC); 267 + 268 + if (dev_priv->iLVDS_enable) { 269 + /* Shut down the panel */ 270 + PSB_WVDC32(0, PP_CONTROL); 271 + 272 + do { 273 + pp_stat = PSB_RVDC32(PP_STATUS); 274 + } while (pp_stat & 0x80000000); 275 + 276 + /* Turn off the plane */ 277 + PSB_WVDC32(0x58000000, DSPACNTR); 278 + /* Trigger the plane disable */ 279 + PSB_WVDC32(0, DSPASURF); 280 + 281 + /* Wait ~4 ticks */ 282 + msleep(4); 283 + 284 + /* Turn off pipe */ 285 + PSB_WVDC32(0x0, PIPEACONF); 286 + /* Wait ~8 ticks */ 287 + msleep(8); 288 + 289 + /* Turn off PLLs */ 290 + PSB_WVDC32(0, MRST_DPLL_A); 291 + } 292 + return 0; 293 + } 294 + 295 + /** 296 + * oaktrail_restore_display_registers - restore lost register state 297 + * @dev: our DRM device 298 + * 299 + * Restore register state that was lost during suspend and resume. 300 + */ 301 + static int oaktrail_restore_display_registers(struct drm_device *dev) 302 + { 303 + struct drm_psb_private *dev_priv = dev->dev_private; 304 + u32 pp_stat; 305 + int i; 306 + 307 + /* Display arbitration + watermarks */ 308 + PSB_WVDC32(dev_priv->saveDSPARB, DSPARB); 309 + PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1); 310 + PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2); 311 + PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3); 312 + PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4); 313 + PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5); 314 + PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6); 315 + PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT); 316 + 317 + /* Make sure VGA plane is off. it initializes to on after reset!*/ 318 + PSB_WVDC32(0x80000000, VGACNTRL); 319 + 320 + /* set the plls */ 321 + PSB_WVDC32(dev_priv->saveFPA0, MRST_FPA0); 322 + PSB_WVDC32(dev_priv->saveFPA1, MRST_FPA1); 323 + 324 + /* Actually enable it */ 325 + PSB_WVDC32(dev_priv->saveDPLL_A, MRST_DPLL_A); 326 + DRM_UDELAY(150); 327 + 328 + /* Restore mode */ 329 + PSB_WVDC32(dev_priv->saveHTOTAL_A, HTOTAL_A); 330 + PSB_WVDC32(dev_priv->saveHBLANK_A, HBLANK_A); 331 + PSB_WVDC32(dev_priv->saveHSYNC_A, HSYNC_A); 332 + PSB_WVDC32(dev_priv->saveVTOTAL_A, VTOTAL_A); 333 + PSB_WVDC32(dev_priv->saveVBLANK_A, VBLANK_A); 334 + PSB_WVDC32(dev_priv->saveVSYNC_A, VSYNC_A); 335 + PSB_WVDC32(dev_priv->savePIPEASRC, PIPEASRC); 336 + PSB_WVDC32(dev_priv->saveBCLRPAT_A, BCLRPAT_A); 337 + 338 + /* Restore performance mode*/ 339 + PSB_WVDC32(dev_priv->savePERF_MODE, MRST_PERF_MODE); 340 + 341 + /* Enable the pipe*/ 342 + if (dev_priv->iLVDS_enable) 343 + PSB_WVDC32(dev_priv->savePIPEACONF, PIPEACONF); 344 + 345 + /* Set up the plane*/ 346 + PSB_WVDC32(dev_priv->saveDSPALINOFF, DSPALINOFF); 347 + PSB_WVDC32(dev_priv->saveDSPASTRIDE, DSPASTRIDE); 348 + PSB_WVDC32(dev_priv->saveDSPATILEOFF, DSPATILEOFF); 349 + 350 + /* Enable the plane */ 351 + PSB_WVDC32(dev_priv->saveDSPACNTR, DSPACNTR); 352 + PSB_WVDC32(dev_priv->saveDSPASURF, DSPASURF); 353 + 354 + /* Enable Cursor A */ 355 + PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR); 356 + PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS); 357 + PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE); 358 + 359 + /* Restore palette (gamma) */ 360 + for (i = 0; i < 256; i++) 361 + PSB_WVDC32(dev_priv->save_palette_a[i], PALETTE_A + (i << 2)); 362 + 363 + if (dev_priv->hdmi_priv) 364 + oaktrail_hdmi_restore(dev); 365 + 366 + if (dev_priv->iLVDS_enable) { 367 + PSB_WVDC32(dev_priv->saveBLC_PWM_CTL2, BLC_PWM_CTL2); 368 + PSB_WVDC32(dev_priv->saveLVDS, LVDS); /*port 61180h*/ 369 + PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL); 370 + PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS); 371 + PSB_WVDC32(dev_priv->savePFIT_AUTO_RATIOS, PFIT_AUTO_RATIOS); 372 + PSB_WVDC32(dev_priv->saveBLC_PWM_CTL, BLC_PWM_CTL); 373 + PSB_WVDC32(dev_priv->savePP_ON_DELAYS, LVDSPP_ON); 374 + PSB_WVDC32(dev_priv->savePP_OFF_DELAYS, LVDSPP_OFF); 375 + PSB_WVDC32(dev_priv->savePP_DIVISOR, PP_CYCLE); 376 + PSB_WVDC32(dev_priv->savePP_CONTROL, PP_CONTROL); 377 + } 378 + 379 + /* Wait for cycle delay */ 380 + do { 381 + pp_stat = PSB_RVDC32(PP_STATUS); 382 + } while (pp_stat & 0x08000000); 383 + 384 + /* Wait for panel power up */ 385 + do { 386 + pp_stat = PSB_RVDC32(PP_STATUS); 387 + } while (pp_stat & 0x10000000); 388 + 389 + /* Restore HW overlay */ 390 + PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD); 391 + PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0); 392 + PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1); 393 + PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2); 394 + PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3); 395 + PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4); 396 + PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5); 397 + 398 + /* DPST registers */ 399 + PSB_WVDC32(dev_priv->saveHISTOGRAM_INT_CONTROL_REG, 400 + HISTOGRAM_INT_CONTROL); 401 + PSB_WVDC32(dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG, 402 + HISTOGRAM_LOGIC_CONTROL); 403 + PSB_WVDC32(dev_priv->savePWM_CONTROL_LOGIC, PWM_CONTROL_LOGIC); 404 + 405 + return 0; 406 + } 407 + 408 + /** 409 + * oaktrail_power_down - power down the display island 410 + * @dev: our DRM device 411 + * 412 + * Power down the display interface of our device 413 + */ 414 + static int oaktrail_power_down(struct drm_device *dev) 415 + { 416 + struct drm_psb_private *dev_priv = dev->dev_private; 417 + u32 pwr_mask ; 418 + u32 pwr_sts; 419 + 420 + pwr_mask = PSB_PWRGT_DISPLAY_MASK; 421 + outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC); 422 + 423 + while (true) { 424 + pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); 425 + if ((pwr_sts & pwr_mask) == pwr_mask) 426 + break; 427 + else 428 + udelay(10); 429 + } 430 + return 0; 431 + } 432 + 433 + /* 434 + * oaktrail_power_up 435 + * 436 + * Restore power to the specified island(s) (powergating) 437 + */ 438 + static int oaktrail_power_up(struct drm_device *dev) 439 + { 440 + struct drm_psb_private *dev_priv = dev->dev_private; 441 + u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK; 442 + u32 pwr_sts, pwr_cnt; 443 + 444 + pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC); 445 + pwr_cnt &= ~pwr_mask; 446 + outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC)); 447 + 448 + while (true) { 449 + pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); 450 + if ((pwr_sts & pwr_mask) == 0) 451 + break; 452 + else 453 + udelay(10); 454 + } 455 + return 0; 456 + } 457 + 458 + 459 + static void oaktrail_teardown(struct drm_device *dev) 460 + { 461 + oaktrail_hdmi_teardown(dev); 462 + } 463 + 464 + const struct psb_ops oaktrail_chip_ops = { 465 + .name = "Oaktrail", 466 + .accel_2d = 1, 467 + .pipes = 2, 468 + .crtcs = 2, 469 + .sgx_offset = MRST_SGX_OFFSET, 470 + 471 + .chip_setup = mid_chip_setup, 472 + .chip_teardown = oaktrail_teardown, 473 + .crtc_helper = &oaktrail_helper_funcs, 474 + .crtc_funcs = &psb_intel_crtc_funcs, 475 + 476 + .output_init = oaktrail_output_init, 477 + 478 + #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 479 + .backlight_init = oaktrail_backlight_init, 480 + #endif 481 + 482 + .init_pm = oaktrail_init_pm, 483 + .save_regs = oaktrail_save_display_registers, 484 + .restore_regs = oaktrail_restore_display_registers, 485 + .power_down = oaktrail_power_down, 486 + .power_up = oaktrail_power_up, 487 + 488 + .i2c_bus = 1, 489 + };
+852
drivers/gpu/drm/gma500/oaktrail_hdmi.c
··· 1 + /* 2 + * Copyright © 2010 Intel Corporation 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice (including the next 12 + * paragraph) shall be included in all copies or substantial portions of the 13 + * Software. 14 + * 15 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 + * DEALINGS IN THE SOFTWARE. 22 + * 23 + * Authors: 24 + * Li Peng <peng.li@intel.com> 25 + */ 26 + 27 + #include <drm/drmP.h> 28 + #include <drm/drm.h> 29 + #include "psb_intel_drv.h" 30 + #include "psb_intel_reg.h" 31 + #include "psb_drv.h" 32 + 33 + #define HDMI_READ(reg) readl(hdmi_dev->regs + (reg)) 34 + #define HDMI_WRITE(reg, val) writel(val, hdmi_dev->regs + (reg)) 35 + 36 + #define HDMI_HCR 0x1000 37 + #define HCR_ENABLE_HDCP (1 << 5) 38 + #define HCR_ENABLE_AUDIO (1 << 2) 39 + #define HCR_ENABLE_PIXEL (1 << 1) 40 + #define HCR_ENABLE_TMDS (1 << 0) 41 + 42 + #define HDMI_HICR 0x1004 43 + #define HDMI_HSR 0x1008 44 + #define HDMI_HISR 0x100C 45 + #define HDMI_DETECT_HDP (1 << 0) 46 + 47 + #define HDMI_VIDEO_REG 0x3000 48 + #define HDMI_UNIT_EN (1 << 7) 49 + #define HDMI_MODE_OUTPUT (1 << 0) 50 + #define HDMI_HBLANK_A 0x3100 51 + 52 + #define HDMI_AUDIO_CTRL 0x4000 53 + #define HDMI_ENABLE_AUDIO (1 << 0) 54 + 55 + #define PCH_HTOTAL_B 0x3100 56 + #define PCH_HBLANK_B 0x3104 57 + #define PCH_HSYNC_B 0x3108 58 + #define PCH_VTOTAL_B 0x310C 59 + #define PCH_VBLANK_B 0x3110 60 + #define PCH_VSYNC_B 0x3114 61 + #define PCH_PIPEBSRC 0x311C 62 + 63 + #define PCH_PIPEB_DSL 0x3800 64 + #define PCH_PIPEB_SLC 0x3804 65 + #define PCH_PIPEBCONF 0x3808 66 + #define PCH_PIPEBSTAT 0x3824 67 + 68 + #define CDVO_DFT 0x5000 69 + #define CDVO_SLEWRATE 0x5004 70 + #define CDVO_STRENGTH 0x5008 71 + #define CDVO_RCOMP 0x500C 72 + 73 + #define DPLL_CTRL 0x6000 74 + #define DPLL_PDIV_SHIFT 16 75 + #define DPLL_PDIV_MASK (0xf << 16) 76 + #define DPLL_PWRDN (1 << 4) 77 + #define DPLL_RESET (1 << 3) 78 + #define DPLL_FASTEN (1 << 2) 79 + #define DPLL_ENSTAT (1 << 1) 80 + #define DPLL_DITHEN (1 << 0) 81 + 82 + #define DPLL_DIV_CTRL 0x6004 83 + #define DPLL_CLKF_MASK 0xffffffc0 84 + #define DPLL_CLKR_MASK (0x3f) 85 + 86 + #define DPLL_CLK_ENABLE 0x6008 87 + #define DPLL_EN_DISP (1 << 31) 88 + #define DPLL_SEL_HDMI (1 << 8) 89 + #define DPLL_EN_HDMI (1 << 1) 90 + #define DPLL_EN_VGA (1 << 0) 91 + 92 + #define DPLL_ADJUST 0x600C 93 + #define DPLL_STATUS 0x6010 94 + #define DPLL_UPDATE 0x6014 95 + #define DPLL_DFT 0x6020 96 + 97 + struct intel_range { 98 + int min, max; 99 + }; 100 + 101 + struct oaktrail_hdmi_limit { 102 + struct intel_range vco, np, nr, nf; 103 + }; 104 + 105 + struct oaktrail_hdmi_clock { 106 + int np; 107 + int nr; 108 + int nf; 109 + int dot; 110 + }; 111 + 112 + #define VCO_MIN 320000 113 + #define VCO_MAX 1650000 114 + #define NP_MIN 1 115 + #define NP_MAX 15 116 + #define NR_MIN 1 117 + #define NR_MAX 64 118 + #define NF_MIN 2 119 + #define NF_MAX 4095 120 + 121 + static const struct oaktrail_hdmi_limit oaktrail_hdmi_limit = { 122 + .vco = { .min = VCO_MIN, .max = VCO_MAX }, 123 + .np = { .min = NP_MIN, .max = NP_MAX }, 124 + .nr = { .min = NR_MIN, .max = NR_MAX }, 125 + .nf = { .min = NF_MIN, .max = NF_MAX }, 126 + }; 127 + 128 + static void wait_for_vblank(struct drm_device *dev) 129 + { 130 + /* FIXME: Can we do this as a sleep ? */ 131 + /* Wait for 20ms, i.e. one cycle at 50hz. */ 132 + mdelay(20); 133 + } 134 + 135 + static void scu_busy_loop(void *scu_base) 136 + { 137 + u32 status = 0; 138 + u32 loop_count = 0; 139 + 140 + status = readl(scu_base + 0x04); 141 + while (status & 1) { 142 + udelay(1); /* scu processing time is in few u secods */ 143 + status = readl(scu_base + 0x04); 144 + loop_count++; 145 + /* break if scu doesn't reset busy bit after huge retry */ 146 + if (loop_count > 1000) { 147 + DRM_DEBUG_KMS("SCU IPC timed out"); 148 + return; 149 + } 150 + } 151 + } 152 + 153 + static void oaktrail_hdmi_reset(struct drm_device *dev) 154 + { 155 + void *base; 156 + /* FIXME: at least make these defines */ 157 + unsigned int scu_ipc_mmio = 0xff11c000; 158 + int scu_len = 1024; 159 + 160 + base = ioremap((resource_size_t)scu_ipc_mmio, scu_len); 161 + if (base == NULL) { 162 + DRM_ERROR("failed to map SCU mmio\n"); 163 + return; 164 + } 165 + 166 + /* scu ipc: assert hdmi controller reset */ 167 + writel(0xff11d118, base + 0x0c); 168 + writel(0x7fffffdf, base + 0x80); 169 + writel(0x42005, base + 0x0); 170 + scu_busy_loop(base); 171 + 172 + /* scu ipc: de-assert hdmi controller reset */ 173 + writel(0xff11d118, base + 0x0c); 174 + writel(0x7fffffff, base + 0x80); 175 + writel(0x42005, base + 0x0); 176 + scu_busy_loop(base); 177 + 178 + iounmap(base); 179 + } 180 + 181 + static void oaktrail_hdmi_audio_enable(struct drm_device *dev) 182 + { 183 + struct drm_psb_private *dev_priv = dev->dev_private; 184 + struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 185 + 186 + HDMI_WRITE(HDMI_HCR, 0x67); 187 + HDMI_READ(HDMI_HCR); 188 + 189 + HDMI_WRITE(0x51a8, 0x10); 190 + HDMI_READ(0x51a8); 191 + 192 + HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1); 193 + HDMI_READ(HDMI_AUDIO_CTRL); 194 + } 195 + 196 + static void oaktrail_hdmi_audio_disable(struct drm_device *dev) 197 + { 198 + struct drm_psb_private *dev_priv = dev->dev_private; 199 + struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 200 + 201 + HDMI_WRITE(0x51a8, 0x0); 202 + HDMI_READ(0x51a8); 203 + 204 + HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0); 205 + HDMI_READ(HDMI_AUDIO_CTRL); 206 + 207 + HDMI_WRITE(HDMI_HCR, 0x47); 208 + HDMI_READ(HDMI_HCR); 209 + } 210 + 211 + void oaktrail_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode) 212 + { 213 + struct drm_device *dev = crtc->dev; 214 + u32 temp; 215 + 216 + switch (mode) { 217 + case DRM_MODE_DPMS_OFF: 218 + /* Disable VGACNTRL */ 219 + REG_WRITE(VGACNTRL, 0x80000000); 220 + 221 + /* Disable plane */ 222 + temp = REG_READ(DSPBCNTR); 223 + if ((temp & DISPLAY_PLANE_ENABLE) != 0) { 224 + REG_WRITE(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE); 225 + REG_READ(DSPBCNTR); 226 + /* Flush the plane changes */ 227 + REG_WRITE(DSPBSURF, REG_READ(DSPBSURF)); 228 + REG_READ(DSPBSURF); 229 + } 230 + 231 + /* Disable pipe B */ 232 + temp = REG_READ(PIPEBCONF); 233 + if ((temp & PIPEACONF_ENABLE) != 0) { 234 + REG_WRITE(PIPEBCONF, temp & ~PIPEACONF_ENABLE); 235 + REG_READ(PIPEBCONF); 236 + } 237 + 238 + /* Disable LNW Pipes, etc */ 239 + temp = REG_READ(PCH_PIPEBCONF); 240 + if ((temp & PIPEACONF_ENABLE) != 0) { 241 + REG_WRITE(PCH_PIPEBCONF, temp & ~PIPEACONF_ENABLE); 242 + REG_READ(PCH_PIPEBCONF); 243 + } 244 + /* wait for pipe off */ 245 + udelay(150); 246 + /* Disable dpll */ 247 + temp = REG_READ(DPLL_CTRL); 248 + if ((temp & DPLL_PWRDN) == 0) { 249 + REG_WRITE(DPLL_CTRL, temp | (DPLL_PWRDN | DPLL_RESET)); 250 + REG_WRITE(DPLL_STATUS, 0x1); 251 + } 252 + /* wait for dpll off */ 253 + udelay(150); 254 + break; 255 + case DRM_MODE_DPMS_ON: 256 + case DRM_MODE_DPMS_STANDBY: 257 + case DRM_MODE_DPMS_SUSPEND: 258 + /* Enable dpll */ 259 + temp = REG_READ(DPLL_CTRL); 260 + if ((temp & DPLL_PWRDN) != 0) { 261 + REG_WRITE(DPLL_CTRL, temp & ~(DPLL_PWRDN | DPLL_RESET)); 262 + temp = REG_READ(DPLL_CLK_ENABLE); 263 + REG_WRITE(DPLL_CLK_ENABLE, temp | DPLL_EN_DISP | DPLL_SEL_HDMI | DPLL_EN_HDMI); 264 + REG_READ(DPLL_CLK_ENABLE); 265 + } 266 + /* wait for dpll warm up */ 267 + udelay(150); 268 + 269 + /* Enable pipe B */ 270 + temp = REG_READ(PIPEBCONF); 271 + if ((temp & PIPEACONF_ENABLE) == 0) { 272 + REG_WRITE(PIPEBCONF, temp | PIPEACONF_ENABLE); 273 + REG_READ(PIPEBCONF); 274 + } 275 + 276 + /* Enable LNW Pipe B */ 277 + temp = REG_READ(PCH_PIPEBCONF); 278 + if ((temp & PIPEACONF_ENABLE) == 0) { 279 + REG_WRITE(PCH_PIPEBCONF, temp | PIPEACONF_ENABLE); 280 + REG_READ(PCH_PIPEBCONF); 281 + } 282 + wait_for_vblank(dev); 283 + 284 + /* Enable plane */ 285 + temp = REG_READ(DSPBCNTR); 286 + if ((temp & DISPLAY_PLANE_ENABLE) == 0) { 287 + REG_WRITE(DSPBCNTR, temp | DISPLAY_PLANE_ENABLE); 288 + /* Flush the plane changes */ 289 + REG_WRITE(DSPBSURF, REG_READ(DSPBSURF)); 290 + REG_READ(DSPBSURF); 291 + } 292 + psb_intel_crtc_load_lut(crtc); 293 + } 294 + /* DSPARB */ 295 + REG_WRITE(DSPARB, 0x00003fbf); 296 + /* FW1 */ 297 + REG_WRITE(0x70034, 0x3f880a0a); 298 + /* FW2 */ 299 + REG_WRITE(0x70038, 0x0b060808); 300 + /* FW4 */ 301 + REG_WRITE(0x70050, 0x08030404); 302 + /* FW5 */ 303 + REG_WRITE(0x70054, 0x04040404); 304 + /* LNC Chicken Bits */ 305 + REG_WRITE(0x70400, 0x4000); 306 + } 307 + 308 + 309 + static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode) 310 + { 311 + static int dpms_mode = -1; 312 + 313 + struct drm_device *dev = encoder->dev; 314 + struct drm_psb_private *dev_priv = dev->dev_private; 315 + struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 316 + u32 temp; 317 + 318 + if (dpms_mode == mode) 319 + return; 320 + 321 + if (mode != DRM_MODE_DPMS_ON) 322 + temp = 0x0; 323 + else 324 + temp = 0x99; 325 + 326 + dpms_mode = mode; 327 + HDMI_WRITE(HDMI_VIDEO_REG, temp); 328 + } 329 + 330 + static unsigned int htotal_calculate(struct drm_display_mode *mode) 331 + { 332 + u32 htotal, new_crtc_htotal; 333 + 334 + htotal = (mode->crtc_hdisplay - 1) | ((mode->crtc_htotal - 1) << 16); 335 + 336 + /* 337 + * 1024 x 768 new_crtc_htotal = 0x1024; 338 + * 1280 x 1024 new_crtc_htotal = 0x0c34; 339 + */ 340 + new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock; 341 + 342 + return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16); 343 + } 344 + 345 + static void oaktrail_hdmi_find_dpll(struct drm_crtc *crtc, int target, 346 + int refclk, struct oaktrail_hdmi_clock *best_clock) 347 + { 348 + int np_min, np_max, nr_min, nr_max; 349 + int np, nr, nf; 350 + 351 + np_min = DIV_ROUND_UP(oaktrail_hdmi_limit.vco.min, target * 10); 352 + np_max = oaktrail_hdmi_limit.vco.max / (target * 10); 353 + if (np_min < oaktrail_hdmi_limit.np.min) 354 + np_min = oaktrail_hdmi_limit.np.min; 355 + if (np_max > oaktrail_hdmi_limit.np.max) 356 + np_max = oaktrail_hdmi_limit.np.max; 357 + 358 + nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max)); 359 + nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min)); 360 + if (nr_min < oaktrail_hdmi_limit.nr.min) 361 + nr_min = oaktrail_hdmi_limit.nr.min; 362 + if (nr_max > oaktrail_hdmi_limit.nr.max) 363 + nr_max = oaktrail_hdmi_limit.nr.max; 364 + 365 + np = DIV_ROUND_UP((refclk * 1000), (target * 10 * nr_max)); 366 + nr = DIV_ROUND_UP((refclk * 1000), (target * 10 * np)); 367 + nf = DIV_ROUND_CLOSEST((target * 10 * np * nr), refclk); 368 + DRM_DEBUG_KMS("np, nr, nf %d %d %d\n", np, nr, nf); 369 + 370 + /* 371 + * 1024 x 768 np = 1; nr = 0x26; nf = 0x0fd8000; 372 + * 1280 x 1024 np = 1; nr = 0x17; nf = 0x1034000; 373 + */ 374 + best_clock->np = np; 375 + best_clock->nr = nr - 1; 376 + best_clock->nf = (nf << 14); 377 + } 378 + 379 + int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc, 380 + struct drm_display_mode *mode, 381 + struct drm_display_mode *adjusted_mode, 382 + int x, int y, 383 + struct drm_framebuffer *old_fb) 384 + { 385 + struct drm_device *dev = crtc->dev; 386 + struct drm_psb_private *dev_priv = dev->dev_private; 387 + struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 388 + int pipe = 1; 389 + int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; 390 + int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; 391 + int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; 392 + int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; 393 + int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; 394 + int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; 395 + int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; 396 + int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; 397 + int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; 398 + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; 399 + int refclk; 400 + struct oaktrail_hdmi_clock clock; 401 + u32 dspcntr, pipeconf, dpll, temp; 402 + int dspcntr_reg = DSPBCNTR; 403 + 404 + /* Disable the VGA plane that we never use */ 405 + REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); 406 + 407 + /* XXX: Disable the panel fitter if it was on our pipe */ 408 + 409 + /* Disable dpll if necessary */ 410 + dpll = REG_READ(DPLL_CTRL); 411 + if ((dpll & DPLL_PWRDN) == 0) { 412 + REG_WRITE(DPLL_CTRL, dpll | (DPLL_PWRDN | DPLL_RESET)); 413 + REG_WRITE(DPLL_DIV_CTRL, 0x00000000); 414 + REG_WRITE(DPLL_STATUS, 0x1); 415 + } 416 + udelay(150); 417 + 418 + /* reset controller: FIXME - can we sort out the ioremap mess ? */ 419 + iounmap(hdmi_dev->regs); 420 + oaktrail_hdmi_reset(dev); 421 + 422 + /* program and enable dpll */ 423 + refclk = 25000; 424 + oaktrail_hdmi_find_dpll(crtc, adjusted_mode->clock, refclk, &clock); 425 + 426 + /* Setting DPLL */ 427 + dpll = REG_READ(DPLL_CTRL); 428 + dpll &= ~DPLL_PDIV_MASK; 429 + dpll &= ~(DPLL_PWRDN | DPLL_RESET); 430 + REG_WRITE(DPLL_CTRL, 0x00000008); 431 + REG_WRITE(DPLL_DIV_CTRL, ((clock.nf << 6) | clock.nr)); 432 + REG_WRITE(DPLL_ADJUST, ((clock.nf >> 14) - 1)); 433 + REG_WRITE(DPLL_CTRL, (dpll | (clock.np << DPLL_PDIV_SHIFT) | DPLL_ENSTAT | DPLL_DITHEN)); 434 + REG_WRITE(DPLL_UPDATE, 0x80000000); 435 + REG_WRITE(DPLL_CLK_ENABLE, 0x80050102); 436 + udelay(150); 437 + 438 + hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len); 439 + if (hdmi_dev->regs == NULL) { 440 + DRM_ERROR("failed to do hdmi mmio mapping\n"); 441 + return -ENOMEM; 442 + } 443 + 444 + /* configure HDMI */ 445 + HDMI_WRITE(0x1004, 0x1fd); 446 + HDMI_WRITE(0x2000, 0x1); 447 + HDMI_WRITE(0x2008, 0x0); 448 + HDMI_WRITE(0x3130, 0x8); 449 + HDMI_WRITE(0x101c, 0x1800810); 450 + 451 + temp = htotal_calculate(adjusted_mode); 452 + REG_WRITE(htot_reg, temp); 453 + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16)); 454 + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16)); 455 + REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16)); 456 + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16)); 457 + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16)); 458 + REG_WRITE(pipesrc_reg, 459 + ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); 460 + 461 + REG_WRITE(PCH_HTOTAL_B, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16)); 462 + REG_WRITE(PCH_HBLANK_B, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16)); 463 + REG_WRITE(PCH_HSYNC_B, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16)); 464 + REG_WRITE(PCH_VTOTAL_B, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16)); 465 + REG_WRITE(PCH_VBLANK_B, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16)); 466 + REG_WRITE(PCH_VSYNC_B, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16)); 467 + REG_WRITE(PCH_PIPEBSRC, 468 + ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); 469 + 470 + temp = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start; 471 + HDMI_WRITE(HDMI_HBLANK_A, ((adjusted_mode->crtc_hdisplay - 1) << 16) | temp); 472 + 473 + REG_WRITE(dspsize_reg, 474 + ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); 475 + REG_WRITE(dsppos_reg, 0); 476 + 477 + /* Flush the plane changes */ 478 + { 479 + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 480 + crtc_funcs->mode_set_base(crtc, x, y, old_fb); 481 + } 482 + 483 + /* Set up the display plane register */ 484 + dspcntr = REG_READ(dspcntr_reg); 485 + dspcntr |= DISPPLANE_GAMMA_ENABLE; 486 + dspcntr |= DISPPLANE_SEL_PIPE_B; 487 + dspcntr |= DISPLAY_PLANE_ENABLE; 488 + 489 + /* setup pipeconf */ 490 + pipeconf = REG_READ(pipeconf_reg); 491 + pipeconf |= PIPEACONF_ENABLE; 492 + 493 + REG_WRITE(pipeconf_reg, pipeconf); 494 + REG_READ(pipeconf_reg); 495 + 496 + REG_WRITE(PCH_PIPEBCONF, pipeconf); 497 + REG_READ(PCH_PIPEBCONF); 498 + wait_for_vblank(dev); 499 + 500 + REG_WRITE(dspcntr_reg, dspcntr); 501 + wait_for_vblank(dev); 502 + 503 + return 0; 504 + } 505 + 506 + static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, 507 + struct drm_display_mode *mode) 508 + { 509 + if (mode->clock > 165000) 510 + return MODE_CLOCK_HIGH; 511 + if (mode->clock < 20000) 512 + return MODE_CLOCK_LOW; 513 + 514 + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 515 + return MODE_NO_DBLESCAN; 516 + 517 + return MODE_OK; 518 + } 519 + 520 + static bool oaktrail_hdmi_mode_fixup(struct drm_encoder *encoder, 521 + struct drm_display_mode *mode, 522 + struct drm_display_mode *adjusted_mode) 523 + { 524 + return true; 525 + } 526 + 527 + static enum drm_connector_status 528 + oaktrail_hdmi_detect(struct drm_connector *connector, bool force) 529 + { 530 + enum drm_connector_status status; 531 + struct drm_device *dev = connector->dev; 532 + struct drm_psb_private *dev_priv = dev->dev_private; 533 + struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 534 + u32 temp; 535 + 536 + temp = HDMI_READ(HDMI_HSR); 537 + DRM_DEBUG_KMS("HDMI_HSR %x\n", temp); 538 + 539 + if ((temp & HDMI_DETECT_HDP) != 0) 540 + status = connector_status_connected; 541 + else 542 + status = connector_status_disconnected; 543 + 544 + return status; 545 + } 546 + 547 + static const unsigned char raw_edid[] = { 548 + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0, 549 + 0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78, 550 + 0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5, 551 + 0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01, 552 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0, 553 + 0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a, 554 + 0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35, 555 + 0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44, 556 + 0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20, 557 + 0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a, 558 + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d 559 + }; 560 + 561 + static int oaktrail_hdmi_get_modes(struct drm_connector *connector) 562 + { 563 + struct drm_device *dev = connector->dev; 564 + struct drm_psb_private *dev_priv = dev->dev_private; 565 + struct i2c_adapter *i2c_adap; 566 + struct edid *edid; 567 + struct drm_display_mode *mode, *t; 568 + int i = 0, ret = 0; 569 + 570 + i2c_adap = i2c_get_adapter(3); 571 + if (i2c_adap == NULL) { 572 + DRM_ERROR("No ddc adapter available!\n"); 573 + edid = (struct edid *)raw_edid; 574 + } else { 575 + edid = (struct edid *)raw_edid; 576 + /* FIXME ? edid = drm_get_edid(connector, i2c_adap); */ 577 + } 578 + 579 + if (edid) { 580 + drm_mode_connector_update_edid_property(connector, edid); 581 + ret = drm_add_edid_modes(connector, edid); 582 + connector->display_info.raw_edid = NULL; 583 + } 584 + 585 + /* 586 + * prune modes that require frame buffer bigger than stolen mem 587 + */ 588 + list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { 589 + if ((mode->hdisplay * mode->vdisplay * 4) >= dev_priv->vram_stolen_size) { 590 + i++; 591 + drm_mode_remove(connector, mode); 592 + } 593 + } 594 + return ret - i; 595 + } 596 + 597 + static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder, 598 + struct drm_display_mode *mode, 599 + struct drm_display_mode *adjusted_mode) 600 + { 601 + struct drm_device *dev = encoder->dev; 602 + 603 + oaktrail_hdmi_audio_enable(dev); 604 + return; 605 + } 606 + 607 + static void oaktrail_hdmi_destroy(struct drm_connector *connector) 608 + { 609 + return; 610 + } 611 + 612 + static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = { 613 + .dpms = oaktrail_hdmi_dpms, 614 + .mode_fixup = oaktrail_hdmi_mode_fixup, 615 + .prepare = psb_intel_encoder_prepare, 616 + .mode_set = oaktrail_hdmi_mode_set, 617 + .commit = psb_intel_encoder_commit, 618 + }; 619 + 620 + static const struct drm_connector_helper_funcs 621 + oaktrail_hdmi_connector_helper_funcs = { 622 + .get_modes = oaktrail_hdmi_get_modes, 623 + .mode_valid = oaktrail_hdmi_mode_valid, 624 + .best_encoder = psb_intel_best_encoder, 625 + }; 626 + 627 + static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = { 628 + .dpms = drm_helper_connector_dpms, 629 + .detect = oaktrail_hdmi_detect, 630 + .fill_modes = drm_helper_probe_single_connector_modes, 631 + .destroy = oaktrail_hdmi_destroy, 632 + }; 633 + 634 + static void oaktrail_hdmi_enc_destroy(struct drm_encoder *encoder) 635 + { 636 + drm_encoder_cleanup(encoder); 637 + } 638 + 639 + static const struct drm_encoder_funcs oaktrail_hdmi_enc_funcs = { 640 + .destroy = oaktrail_hdmi_enc_destroy, 641 + }; 642 + 643 + void oaktrail_hdmi_init(struct drm_device *dev, 644 + struct psb_intel_mode_device *mode_dev) 645 + { 646 + struct psb_intel_output *psb_intel_output; 647 + struct drm_connector *connector; 648 + struct drm_encoder *encoder; 649 + 650 + psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL); 651 + if (!psb_intel_output) 652 + return; 653 + 654 + psb_intel_output->mode_dev = mode_dev; 655 + connector = &psb_intel_output->base; 656 + encoder = &psb_intel_output->enc; 657 + drm_connector_init(dev, &psb_intel_output->base, 658 + &oaktrail_hdmi_connector_funcs, 659 + DRM_MODE_CONNECTOR_DVID); 660 + 661 + drm_encoder_init(dev, &psb_intel_output->enc, 662 + &oaktrail_hdmi_enc_funcs, 663 + DRM_MODE_ENCODER_TMDS); 664 + 665 + drm_mode_connector_attach_encoder(&psb_intel_output->base, 666 + &psb_intel_output->enc); 667 + 668 + psb_intel_output->type = INTEL_OUTPUT_HDMI; 669 + drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs); 670 + drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs); 671 + 672 + connector->display_info.subpixel_order = SubPixelHorizontalRGB; 673 + connector->interlace_allowed = false; 674 + connector->doublescan_allowed = false; 675 + drm_sysfs_connector_add(connector); 676 + 677 + return; 678 + } 679 + 680 + static DEFINE_PCI_DEVICE_TABLE(hdmi_ids) = { 681 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) }, 682 + {} 683 + }; 684 + 685 + void oaktrail_hdmi_setup(struct drm_device *dev) 686 + { 687 + struct drm_psb_private *dev_priv = dev->dev_private; 688 + struct pci_dev *pdev; 689 + struct oaktrail_hdmi_dev *hdmi_dev; 690 + int ret; 691 + 692 + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL); 693 + if (!pdev) 694 + return; 695 + 696 + hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL); 697 + if (!hdmi_dev) { 698 + dev_err(dev->dev, "failed to allocate memory\n"); 699 + goto out; 700 + } 701 + 702 + 703 + ret = pci_enable_device(pdev); 704 + if (ret) { 705 + dev_err(dev->dev, "failed to enable hdmi controller\n"); 706 + goto free; 707 + } 708 + 709 + hdmi_dev->mmio = pci_resource_start(pdev, 0); 710 + hdmi_dev->mmio_len = pci_resource_len(pdev, 0); 711 + hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len); 712 + if (!hdmi_dev->regs) { 713 + dev_err(dev->dev, "failed to map hdmi mmio\n"); 714 + goto free; 715 + } 716 + 717 + hdmi_dev->dev = pdev; 718 + pci_set_drvdata(pdev, hdmi_dev); 719 + 720 + /* Initialize i2c controller */ 721 + ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev); 722 + if (ret) 723 + dev_err(dev->dev, "HDMI I2C initialization failed\n"); 724 + 725 + dev_priv->hdmi_priv = hdmi_dev; 726 + oaktrail_hdmi_audio_disable(dev); 727 + return; 728 + 729 + free: 730 + kfree(hdmi_dev); 731 + out: 732 + return; 733 + } 734 + 735 + void oaktrail_hdmi_teardown(struct drm_device *dev) 736 + { 737 + struct drm_psb_private *dev_priv = dev->dev_private; 738 + struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 739 + struct pci_dev *pdev; 740 + 741 + if (hdmi_dev) { 742 + pdev = hdmi_dev->dev; 743 + pci_set_drvdata(pdev, NULL); 744 + oaktrail_hdmi_i2c_exit(pdev); 745 + iounmap(hdmi_dev->regs); 746 + kfree(hdmi_dev); 747 + pci_dev_put(pdev); 748 + } 749 + } 750 + 751 + /* save HDMI register state */ 752 + void oaktrail_hdmi_save(struct drm_device *dev) 753 + { 754 + struct drm_psb_private *dev_priv = dev->dev_private; 755 + struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 756 + int i; 757 + 758 + /* dpll */ 759 + hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL); 760 + hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL); 761 + hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST); 762 + hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE); 763 + hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE); 764 + 765 + /* pipe B */ 766 + dev_priv->savePIPEBCONF = PSB_RVDC32(PIPEBCONF); 767 + dev_priv->savePIPEBSRC = PSB_RVDC32(PIPEBSRC); 768 + dev_priv->saveHTOTAL_B = PSB_RVDC32(HTOTAL_B); 769 + dev_priv->saveHBLANK_B = PSB_RVDC32(HBLANK_B); 770 + dev_priv->saveHSYNC_B = PSB_RVDC32(HSYNC_B); 771 + dev_priv->saveVTOTAL_B = PSB_RVDC32(VTOTAL_B); 772 + dev_priv->saveVBLANK_B = PSB_RVDC32(VBLANK_B); 773 + dev_priv->saveVSYNC_B = PSB_RVDC32(VSYNC_B); 774 + 775 + hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF); 776 + hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC); 777 + hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B); 778 + hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B); 779 + hdmi_dev->savePCH_HSYNC_B = PSB_RVDC32(PCH_HSYNC_B); 780 + hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B); 781 + hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B); 782 + hdmi_dev->savePCH_VSYNC_B = PSB_RVDC32(PCH_VSYNC_B); 783 + 784 + /* plane */ 785 + dev_priv->saveDSPBCNTR = PSB_RVDC32(DSPBCNTR); 786 + dev_priv->saveDSPBSTRIDE = PSB_RVDC32(DSPBSTRIDE); 787 + dev_priv->saveDSPBADDR = PSB_RVDC32(DSPBBASE); 788 + dev_priv->saveDSPBSURF = PSB_RVDC32(DSPBSURF); 789 + dev_priv->saveDSPBLINOFF = PSB_RVDC32(DSPBLINOFF); 790 + dev_priv->saveDSPBTILEOFF = PSB_RVDC32(DSPBTILEOFF); 791 + 792 + /* cursor B */ 793 + dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR); 794 + dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE); 795 + dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS); 796 + 797 + /* save palette */ 798 + for (i = 0; i < 256; i++) 799 + dev_priv->save_palette_b[i] = PSB_RVDC32(PALETTE_B + (i << 2)); 800 + } 801 + 802 + /* restore HDMI register state */ 803 + void oaktrail_hdmi_restore(struct drm_device *dev) 804 + { 805 + struct drm_psb_private *dev_priv = dev->dev_private; 806 + struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 807 + int i; 808 + 809 + /* dpll */ 810 + PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL); 811 + PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL); 812 + PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST); 813 + PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE); 814 + PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE); 815 + DRM_UDELAY(150); 816 + 817 + /* pipe */ 818 + PSB_WVDC32(dev_priv->savePIPEBSRC, PIPEBSRC); 819 + PSB_WVDC32(dev_priv->saveHTOTAL_B, HTOTAL_B); 820 + PSB_WVDC32(dev_priv->saveHBLANK_B, HBLANK_B); 821 + PSB_WVDC32(dev_priv->saveHSYNC_B, HSYNC_B); 822 + PSB_WVDC32(dev_priv->saveVTOTAL_B, VTOTAL_B); 823 + PSB_WVDC32(dev_priv->saveVBLANK_B, VBLANK_B); 824 + PSB_WVDC32(dev_priv->saveVSYNC_B, VSYNC_B); 825 + 826 + PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC); 827 + PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B); 828 + PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B); 829 + PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B, PCH_HSYNC_B); 830 + PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B); 831 + PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B); 832 + PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B, PCH_VSYNC_B); 833 + 834 + PSB_WVDC32(dev_priv->savePIPEBCONF, PIPEBCONF); 835 + PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF); 836 + 837 + /* plane */ 838 + PSB_WVDC32(dev_priv->saveDSPBLINOFF, DSPBLINOFF); 839 + PSB_WVDC32(dev_priv->saveDSPBSTRIDE, DSPBSTRIDE); 840 + PSB_WVDC32(dev_priv->saveDSPBTILEOFF, DSPBTILEOFF); 841 + PSB_WVDC32(dev_priv->saveDSPBCNTR, DSPBCNTR); 842 + PSB_WVDC32(dev_priv->saveDSPBSURF, DSPBSURF); 843 + 844 + /* cursor B */ 845 + PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR); 846 + PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS); 847 + PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE); 848 + 849 + /* restore palette */ 850 + for (i = 0; i < 256; i++) 851 + PSB_WVDC32(dev_priv->save_palette_b[i], PALETTE_B + (i << 2)); 852 + }
+327
drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
··· 1 + /* 2 + * Copyright © 2010 Intel Corporation 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice (including the next 12 + * paragraph) shall be included in all copies or substantial portions of the 13 + * Software. 14 + * 15 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 + * DEALINGS IN THE SOFTWARE. 22 + * 23 + * Authors: 24 + * Li Peng <peng.li@intel.com> 25 + */ 26 + 27 + #include <linux/mutex.h> 28 + #include <linux/pci.h> 29 + #include <linux/i2c.h> 30 + #include <linux/interrupt.h> 31 + #include <linux/delay.h> 32 + #include "psb_drv.h" 33 + 34 + #define HDMI_READ(reg) readl(hdmi_dev->regs + (reg)) 35 + #define HDMI_WRITE(reg, val) writel(val, hdmi_dev->regs + (reg)) 36 + 37 + #define HDMI_HCR 0x1000 38 + #define HCR_DETECT_HDP (1 << 6) 39 + #define HCR_ENABLE_HDCP (1 << 5) 40 + #define HCR_ENABLE_AUDIO (1 << 2) 41 + #define HCR_ENABLE_PIXEL (1 << 1) 42 + #define HCR_ENABLE_TMDS (1 << 0) 43 + #define HDMI_HICR 0x1004 44 + #define HDMI_INTR_I2C_ERROR (1 << 4) 45 + #define HDMI_INTR_I2C_FULL (1 << 3) 46 + #define HDMI_INTR_I2C_DONE (1 << 2) 47 + #define HDMI_INTR_HPD (1 << 0) 48 + #define HDMI_HSR 0x1008 49 + #define HDMI_HISR 0x100C 50 + #define HDMI_HI2CRDB0 0x1200 51 + #define HDMI_HI2CHCR 0x1240 52 + #define HI2C_HDCP_WRITE (0 << 2) 53 + #define HI2C_HDCP_RI_READ (1 << 2) 54 + #define HI2C_HDCP_READ (2 << 2) 55 + #define HI2C_EDID_READ (3 << 2) 56 + #define HI2C_READ_CONTINUE (1 << 1) 57 + #define HI2C_ENABLE_TRANSACTION (1 << 0) 58 + 59 + #define HDMI_ICRH 0x1100 60 + #define HDMI_HI2CTDR0 0x1244 61 + #define HDMI_HI2CTDR1 0x1248 62 + 63 + #define I2C_STAT_INIT 0 64 + #define I2C_READ_DONE 1 65 + #define I2C_TRANSACTION_DONE 2 66 + 67 + struct hdmi_i2c_dev { 68 + struct i2c_adapter *adap; 69 + struct mutex i2c_lock; 70 + struct completion complete; 71 + int status; 72 + struct i2c_msg *msg; 73 + int buf_offset; 74 + }; 75 + 76 + static void hdmi_i2c_irq_enable(struct oaktrail_hdmi_dev *hdmi_dev) 77 + { 78 + u32 temp; 79 + 80 + temp = HDMI_READ(HDMI_HICR); 81 + temp |= (HDMI_INTR_I2C_ERROR | HDMI_INTR_I2C_FULL | HDMI_INTR_I2C_DONE); 82 + HDMI_WRITE(HDMI_HICR, temp); 83 + HDMI_READ(HDMI_HICR); 84 + } 85 + 86 + static void hdmi_i2c_irq_disable(struct oaktrail_hdmi_dev *hdmi_dev) 87 + { 88 + HDMI_WRITE(HDMI_HICR, 0x0); 89 + HDMI_READ(HDMI_HICR); 90 + } 91 + 92 + static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg) 93 + { 94 + struct oaktrail_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap); 95 + struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; 96 + u32 temp; 97 + 98 + i2c_dev->status = I2C_STAT_INIT; 99 + i2c_dev->msg = pmsg; 100 + i2c_dev->buf_offset = 0; 101 + INIT_COMPLETION(i2c_dev->complete); 102 + 103 + /* Enable I2C transaction */ 104 + temp = ((pmsg->len) << 20) | HI2C_EDID_READ | HI2C_ENABLE_TRANSACTION; 105 + HDMI_WRITE(HDMI_HI2CHCR, temp); 106 + HDMI_READ(HDMI_HI2CHCR); 107 + 108 + while (i2c_dev->status != I2C_TRANSACTION_DONE) 109 + wait_for_completion_interruptible_timeout(&i2c_dev->complete, 110 + 10 * HZ); 111 + 112 + return 0; 113 + } 114 + 115 + static int xfer_write(struct i2c_adapter *adap, struct i2c_msg *pmsg) 116 + { 117 + /* 118 + * XXX: i2c write seems isn't useful for EDID probe, don't do anything 119 + */ 120 + return 0; 121 + } 122 + 123 + static int oaktrail_hdmi_i2c_access(struct i2c_adapter *adap, 124 + struct i2c_msg *pmsg, 125 + int num) 126 + { 127 + struct oaktrail_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap); 128 + struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; 129 + int i, err = 0; 130 + 131 + mutex_lock(&i2c_dev->i2c_lock); 132 + 133 + /* Enable i2c unit */ 134 + HDMI_WRITE(HDMI_ICRH, 0x00008760); 135 + 136 + /* Enable irq */ 137 + hdmi_i2c_irq_enable(hdmi_dev); 138 + for (i = 0; i < num; i++) { 139 + if (pmsg->len && pmsg->buf) { 140 + if (pmsg->flags & I2C_M_RD) 141 + err = xfer_read(adap, pmsg); 142 + else 143 + err = xfer_write(adap, pmsg); 144 + } 145 + pmsg++; /* next message */ 146 + } 147 + 148 + /* Disable irq */ 149 + hdmi_i2c_irq_disable(hdmi_dev); 150 + 151 + mutex_unlock(&i2c_dev->i2c_lock); 152 + 153 + return i; 154 + } 155 + 156 + static u32 oaktrail_hdmi_i2c_func(struct i2c_adapter *adapter) 157 + { 158 + return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR; 159 + } 160 + 161 + static const struct i2c_algorithm oaktrail_hdmi_i2c_algorithm = { 162 + .master_xfer = oaktrail_hdmi_i2c_access, 163 + .functionality = oaktrail_hdmi_i2c_func, 164 + }; 165 + 166 + static struct i2c_adapter oaktrail_hdmi_i2c_adapter = { 167 + .name = "oaktrail_hdmi_i2c", 168 + .nr = 3, 169 + .owner = THIS_MODULE, 170 + .class = I2C_CLASS_DDC, 171 + .algo = &oaktrail_hdmi_i2c_algorithm, 172 + }; 173 + 174 + static void hdmi_i2c_read(struct oaktrail_hdmi_dev *hdmi_dev) 175 + { 176 + struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; 177 + struct i2c_msg *msg = i2c_dev->msg; 178 + u8 *buf = msg->buf; 179 + u32 temp; 180 + int i, offset; 181 + 182 + offset = i2c_dev->buf_offset; 183 + for (i = 0; i < 0x10; i++) { 184 + temp = HDMI_READ(HDMI_HI2CRDB0 + (i * 4)); 185 + memcpy(buf + (offset + i * 4), &temp, 4); 186 + } 187 + i2c_dev->buf_offset += (0x10 * 4); 188 + 189 + /* clearing read buffer full intr */ 190 + temp = HDMI_READ(HDMI_HISR); 191 + HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_FULL); 192 + HDMI_READ(HDMI_HISR); 193 + 194 + /* continue read transaction */ 195 + temp = HDMI_READ(HDMI_HI2CHCR); 196 + HDMI_WRITE(HDMI_HI2CHCR, temp | HI2C_READ_CONTINUE); 197 + HDMI_READ(HDMI_HI2CHCR); 198 + 199 + i2c_dev->status = I2C_READ_DONE; 200 + return; 201 + } 202 + 203 + static void hdmi_i2c_transaction_done(struct oaktrail_hdmi_dev *hdmi_dev) 204 + { 205 + struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; 206 + u32 temp; 207 + 208 + /* clear transaction done intr */ 209 + temp = HDMI_READ(HDMI_HISR); 210 + HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_DONE); 211 + HDMI_READ(HDMI_HISR); 212 + 213 + 214 + temp = HDMI_READ(HDMI_HI2CHCR); 215 + HDMI_WRITE(HDMI_HI2CHCR, temp & ~HI2C_ENABLE_TRANSACTION); 216 + HDMI_READ(HDMI_HI2CHCR); 217 + 218 + i2c_dev->status = I2C_TRANSACTION_DONE; 219 + return; 220 + } 221 + 222 + static irqreturn_t oaktrail_hdmi_i2c_handler(int this_irq, void *dev) 223 + { 224 + struct oaktrail_hdmi_dev *hdmi_dev = dev; 225 + struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; 226 + u32 stat; 227 + 228 + stat = HDMI_READ(HDMI_HISR); 229 + 230 + if (stat & HDMI_INTR_HPD) { 231 + HDMI_WRITE(HDMI_HISR, stat | HDMI_INTR_HPD); 232 + HDMI_READ(HDMI_HISR); 233 + } 234 + 235 + if (stat & HDMI_INTR_I2C_FULL) 236 + hdmi_i2c_read(hdmi_dev); 237 + 238 + if (stat & HDMI_INTR_I2C_DONE) 239 + hdmi_i2c_transaction_done(hdmi_dev); 240 + 241 + complete(&i2c_dev->complete); 242 + 243 + return IRQ_HANDLED; 244 + } 245 + 246 + /* 247 + * choose alternate function 2 of GPIO pin 52, 53, 248 + * which is used by HDMI I2C logic 249 + */ 250 + static void oaktrail_hdmi_i2c_gpio_fix(void) 251 + { 252 + void *base; 253 + unsigned int gpio_base = 0xff12c000; 254 + int gpio_len = 0x1000; 255 + u32 temp; 256 + 257 + base = ioremap((resource_size_t)gpio_base, gpio_len); 258 + if (base == NULL) { 259 + DRM_ERROR("gpio ioremap fail\n"); 260 + return; 261 + } 262 + 263 + temp = readl(base + 0x44); 264 + DRM_DEBUG_DRIVER("old gpio val %x\n", temp); 265 + writel((temp | 0x00000a00), (base + 0x44)); 266 + temp = readl(base + 0x44); 267 + DRM_DEBUG_DRIVER("new gpio val %x\n", temp); 268 + 269 + iounmap(base); 270 + } 271 + 272 + int oaktrail_hdmi_i2c_init(struct pci_dev *dev) 273 + { 274 + struct oaktrail_hdmi_dev *hdmi_dev; 275 + struct hdmi_i2c_dev *i2c_dev; 276 + int ret; 277 + 278 + hdmi_dev = pci_get_drvdata(dev); 279 + 280 + i2c_dev = kzalloc(sizeof(struct hdmi_i2c_dev), GFP_KERNEL); 281 + if (i2c_dev == NULL) { 282 + DRM_ERROR("Can't allocate interface\n"); 283 + ret = -ENOMEM; 284 + goto exit; 285 + } 286 + 287 + i2c_dev->adap = &oaktrail_hdmi_i2c_adapter; 288 + i2c_dev->status = I2C_STAT_INIT; 289 + init_completion(&i2c_dev->complete); 290 + mutex_init(&i2c_dev->i2c_lock); 291 + i2c_set_adapdata(&oaktrail_hdmi_i2c_adapter, hdmi_dev); 292 + hdmi_dev->i2c_dev = i2c_dev; 293 + 294 + /* Enable HDMI I2C function on gpio */ 295 + oaktrail_hdmi_i2c_gpio_fix(); 296 + 297 + /* request irq */ 298 + ret = request_irq(dev->irq, oaktrail_hdmi_i2c_handler, IRQF_SHARED, 299 + oaktrail_hdmi_i2c_adapter.name, hdmi_dev); 300 + if (ret) { 301 + DRM_ERROR("Failed to request IRQ for I2C controller\n"); 302 + goto err; 303 + } 304 + 305 + /* Adapter registration */ 306 + ret = i2c_add_numbered_adapter(&oaktrail_hdmi_i2c_adapter); 307 + return ret; 308 + 309 + err: 310 + kfree(i2c_dev); 311 + exit: 312 + return ret; 313 + } 314 + 315 + void oaktrail_hdmi_i2c_exit(struct pci_dev *dev) 316 + { 317 + struct oaktrail_hdmi_dev *hdmi_dev; 318 + struct hdmi_i2c_dev *i2c_dev; 319 + 320 + hdmi_dev = pci_get_drvdata(dev); 321 + if (i2c_del_adapter(&oaktrail_hdmi_i2c_adapter)) 322 + DRM_DEBUG_DRIVER("Failed to delete hdmi-i2c adapter\n"); 323 + 324 + i2c_dev = hdmi_dev->i2c_dev; 325 + kfree(i2c_dev); 326 + free_irq(dev->irq, hdmi_dev); 327 + }
+406
drivers/gpu/drm/gma500/oaktrail_lvds.c
··· 1 + /* 2 + * Copyright © 2006-2009 Intel Corporation 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + * 13 + * You should have received a copy of the GNU General Public License along with 14 + * this program; if not, write to the Free Software Foundation, Inc., 15 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 16 + * 17 + * Authors: 18 + * Eric Anholt <eric@anholt.net> 19 + * Dave Airlie <airlied@linux.ie> 20 + * Jesse Barnes <jesse.barnes@intel.com> 21 + */ 22 + 23 + #include <linux/i2c.h> 24 + #include <drm/drmP.h> 25 + #include <asm/mrst.h> 26 + 27 + #include "intel_bios.h" 28 + #include "psb_drv.h" 29 + #include "psb_intel_drv.h" 30 + #include "psb_intel_reg.h" 31 + #include "power.h" 32 + #include <linux/pm_runtime.h> 33 + 34 + /* The max/min PWM frequency in BPCR[31:17] - */ 35 + /* The smallest number is 1 (not 0) that can fit in the 36 + * 15-bit field of the and then*/ 37 + /* shifts to the left by one bit to get the actual 16-bit 38 + * value that the 15-bits correspond to.*/ 39 + #define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF 40 + #define BRIGHTNESS_MAX_LEVEL 100 41 + 42 + /** 43 + * Sets the power state for the panel. 44 + */ 45 + static void oaktrail_lvds_set_power(struct drm_device *dev, 46 + struct psb_intel_output *output, bool on) 47 + { 48 + u32 pp_status; 49 + struct drm_psb_private *dev_priv = dev->dev_private; 50 + 51 + if (!gma_power_begin(dev, true)) 52 + return; 53 + 54 + if (on) { 55 + REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | 56 + POWER_TARGET_ON); 57 + do { 58 + pp_status = REG_READ(PP_STATUS); 59 + } while ((pp_status & (PP_ON | PP_READY)) == PP_READY); 60 + dev_priv->is_lvds_on = true; 61 + if (dev_priv->ops->lvds_bl_power) 62 + dev_priv->ops->lvds_bl_power(dev, true); 63 + } else { 64 + if (dev_priv->ops->lvds_bl_power) 65 + dev_priv->ops->lvds_bl_power(dev, false); 66 + REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & 67 + ~POWER_TARGET_ON); 68 + do { 69 + pp_status = REG_READ(PP_STATUS); 70 + } while (pp_status & PP_ON); 71 + dev_priv->is_lvds_on = false; 72 + pm_request_idle(&dev->pdev->dev); 73 + } 74 + gma_power_end(dev); 75 + } 76 + 77 + static void oaktrail_lvds_dpms(struct drm_encoder *encoder, int mode) 78 + { 79 + struct drm_device *dev = encoder->dev; 80 + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); 81 + 82 + if (mode == DRM_MODE_DPMS_ON) 83 + oaktrail_lvds_set_power(dev, output, true); 84 + else 85 + oaktrail_lvds_set_power(dev, output, false); 86 + 87 + /* XXX: We never power down the LVDS pairs. */ 88 + } 89 + 90 + static void oaktrail_lvds_mode_set(struct drm_encoder *encoder, 91 + struct drm_display_mode *mode, 92 + struct drm_display_mode *adjusted_mode) 93 + { 94 + struct psb_intel_mode_device *mode_dev = 95 + enc_to_psb_intel_output(encoder)->mode_dev; 96 + struct drm_device *dev = encoder->dev; 97 + struct drm_psb_private *dev_priv = dev->dev_private; 98 + u32 lvds_port; 99 + uint64_t v = DRM_MODE_SCALE_FULLSCREEN; 100 + 101 + if (!gma_power_begin(dev, true)) 102 + return; 103 + 104 + /* 105 + * The LVDS pin pair will already have been turned on in the 106 + * psb_intel_crtc_mode_set since it has a large impact on the DPLL 107 + * settings. 108 + */ 109 + lvds_port = (REG_READ(LVDS) & 110 + (~LVDS_PIPEB_SELECT)) | 111 + LVDS_PORT_EN | 112 + LVDS_BORDER_EN; 113 + 114 + /* If the firmware says dither on Moorestown, or the BIOS does 115 + on Oaktrail then enable dithering */ 116 + if (mode_dev->panel_wants_dither || dev_priv->lvds_dither) 117 + lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE; 118 + 119 + REG_WRITE(LVDS, lvds_port); 120 + 121 + drm_connector_property_get_value( 122 + &enc_to_psb_intel_output(encoder)->base, 123 + dev->mode_config.scaling_mode_property, 124 + &v); 125 + 126 + if (v == DRM_MODE_SCALE_NO_SCALE) 127 + REG_WRITE(PFIT_CONTROL, 0); 128 + else if (v == DRM_MODE_SCALE_ASPECT) { 129 + if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) || 130 + (mode->hdisplay != adjusted_mode->crtc_hdisplay)) { 131 + if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) == 132 + (mode->hdisplay * adjusted_mode->crtc_vdisplay)) 133 + REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); 134 + else if ((adjusted_mode->crtc_hdisplay * 135 + mode->vdisplay) > (mode->hdisplay * 136 + adjusted_mode->crtc_vdisplay)) 137 + REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | 138 + PFIT_SCALING_MODE_PILLARBOX); 139 + else 140 + REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | 141 + PFIT_SCALING_MODE_LETTERBOX); 142 + } else 143 + REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); 144 + } else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/ 145 + REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); 146 + 147 + gma_power_end(dev); 148 + } 149 + 150 + static void oaktrail_lvds_prepare(struct drm_encoder *encoder) 151 + { 152 + struct drm_device *dev = encoder->dev; 153 + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); 154 + struct psb_intel_mode_device *mode_dev = output->mode_dev; 155 + 156 + if (!gma_power_begin(dev, true)) 157 + return; 158 + 159 + mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); 160 + mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL & 161 + BACKLIGHT_DUTY_CYCLE_MASK); 162 + oaktrail_lvds_set_power(dev, output, false); 163 + gma_power_end(dev); 164 + } 165 + 166 + static u32 oaktrail_lvds_get_max_backlight(struct drm_device *dev) 167 + { 168 + struct drm_psb_private *dev_priv = dev->dev_private; 169 + u32 ret; 170 + 171 + if (gma_power_begin(dev, false)) { 172 + ret = ((REG_READ(BLC_PWM_CTL) & 173 + BACKLIGHT_MODULATION_FREQ_MASK) >> 174 + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; 175 + 176 + gma_power_end(dev); 177 + } else 178 + ret = ((dev_priv->saveBLC_PWM_CTL & 179 + BACKLIGHT_MODULATION_FREQ_MASK) >> 180 + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; 181 + 182 + return ret; 183 + } 184 + 185 + static void oaktrail_lvds_commit(struct drm_encoder *encoder) 186 + { 187 + struct drm_device *dev = encoder->dev; 188 + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); 189 + struct psb_intel_mode_device *mode_dev = output->mode_dev; 190 + 191 + if (mode_dev->backlight_duty_cycle == 0) 192 + mode_dev->backlight_duty_cycle = 193 + oaktrail_lvds_get_max_backlight(dev); 194 + oaktrail_lvds_set_power(dev, output, true); 195 + } 196 + 197 + static const struct drm_encoder_helper_funcs oaktrail_lvds_helper_funcs = { 198 + .dpms = oaktrail_lvds_dpms, 199 + .mode_fixup = psb_intel_lvds_mode_fixup, 200 + .prepare = oaktrail_lvds_prepare, 201 + .mode_set = oaktrail_lvds_mode_set, 202 + .commit = oaktrail_lvds_commit, 203 + }; 204 + 205 + static struct drm_display_mode lvds_configuration_modes[] = { 206 + /* hard coded fixed mode for TPO LTPS LPJ040K001A */ 207 + { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 33264, 800, 836, 208 + 846, 1056, 0, 480, 489, 491, 525, 0, 0) }, 209 + /* hard coded fixed mode for LVDS 800x480 */ 210 + { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 30994, 800, 801, 211 + 802, 1024, 0, 480, 481, 482, 525, 0, 0) }, 212 + /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */ 213 + { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1072, 214 + 1104, 1184, 0, 600, 603, 604, 608, 0, 0) }, 215 + /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */ 216 + { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1104, 217 + 1136, 1184, 0, 600, 603, 604, 608, 0, 0) }, 218 + /* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */ 219 + { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 48885, 1024, 1124, 220 + 1204, 1312, 0, 600, 607, 610, 621, 0, 0) }, 221 + /* hard coded fixed mode for LVDS 1024x768 */ 222 + { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, 223 + 1184, 1344, 0, 768, 771, 777, 806, 0, 0) }, 224 + /* hard coded fixed mode for LVDS 1366x768 */ 225 + { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 77500, 1366, 1430, 226 + 1558, 1664, 0, 768, 769, 770, 776, 0, 0) }, 227 + }; 228 + 229 + /* Returns the panel fixed mode from configuration. */ 230 + 231 + static struct drm_display_mode * 232 + oaktrail_lvds_get_configuration_mode(struct drm_device *dev) 233 + { 234 + struct drm_display_mode *mode = NULL; 235 + struct drm_psb_private *dev_priv = dev->dev_private; 236 + struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD; 237 + 238 + if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/ 239 + mode = kzalloc(sizeof(*mode), GFP_KERNEL); 240 + if (!mode) 241 + return NULL; 242 + 243 + mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; 244 + mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; 245 + mode->hsync_start = mode->hdisplay + \ 246 + ((ti->hsync_offset_hi << 8) | \ 247 + ti->hsync_offset_lo); 248 + mode->hsync_end = mode->hsync_start + \ 249 + ((ti->hsync_pulse_width_hi << 8) | \ 250 + ti->hsync_pulse_width_lo); 251 + mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \ 252 + ti->hblank_lo); 253 + mode->vsync_start = \ 254 + mode->vdisplay + ((ti->vsync_offset_hi << 4) | \ 255 + ti->vsync_offset_lo); 256 + mode->vsync_end = \ 257 + mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \ 258 + ti->vsync_pulse_width_lo); 259 + mode->vtotal = mode->vdisplay + \ 260 + ((ti->vblank_hi << 8) | ti->vblank_lo); 261 + mode->clock = ti->pixel_clock * 10; 262 + #if 0 263 + printk(KERN_INFO "hdisplay is %d\n", mode->hdisplay); 264 + printk(KERN_INFO "vdisplay is %d\n", mode->vdisplay); 265 + printk(KERN_INFO "HSS is %d\n", mode->hsync_start); 266 + printk(KERN_INFO "HSE is %d\n", mode->hsync_end); 267 + printk(KERN_INFO "htotal is %d\n", mode->htotal); 268 + printk(KERN_INFO "VSS is %d\n", mode->vsync_start); 269 + printk(KERN_INFO "VSE is %d\n", mode->vsync_end); 270 + printk(KERN_INFO "vtotal is %d\n", mode->vtotal); 271 + printk(KERN_INFO "clock is %d\n", mode->clock); 272 + #endif 273 + } else 274 + mode = drm_mode_duplicate(dev, &lvds_configuration_modes[2]); 275 + 276 + drm_mode_set_name(mode); 277 + drm_mode_set_crtcinfo(mode, 0); 278 + 279 + return mode; 280 + } 281 + 282 + /** 283 + * oaktrail_lvds_init - setup LVDS connectors on this device 284 + * @dev: drm device 285 + * 286 + * Create the connector, register the LVDS DDC bus, and try to figure out what 287 + * modes we can display on the LVDS panel (if present). 288 + */ 289 + void oaktrail_lvds_init(struct drm_device *dev, 290 + struct psb_intel_mode_device *mode_dev) 291 + { 292 + struct psb_intel_output *psb_intel_output; 293 + struct drm_connector *connector; 294 + struct drm_encoder *encoder; 295 + struct drm_psb_private *dev_priv = 296 + (struct drm_psb_private *) dev->dev_private; 297 + struct edid *edid; 298 + int ret = 0; 299 + struct i2c_adapter *i2c_adap; 300 + struct drm_display_mode *scan; /* *modes, *bios_mode; */ 301 + 302 + psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL); 303 + if (!psb_intel_output) 304 + return; 305 + 306 + psb_intel_output->mode_dev = mode_dev; 307 + connector = &psb_intel_output->base; 308 + encoder = &psb_intel_output->enc; 309 + dev_priv->is_lvds_on = true; 310 + drm_connector_init(dev, &psb_intel_output->base, 311 + &psb_intel_lvds_connector_funcs, 312 + DRM_MODE_CONNECTOR_LVDS); 313 + 314 + drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs, 315 + DRM_MODE_ENCODER_LVDS); 316 + 317 + drm_mode_connector_attach_encoder(&psb_intel_output->base, 318 + &psb_intel_output->enc); 319 + psb_intel_output->type = INTEL_OUTPUT_LVDS; 320 + 321 + drm_encoder_helper_add(encoder, &oaktrail_lvds_helper_funcs); 322 + drm_connector_helper_add(connector, 323 + &psb_intel_lvds_connector_helper_funcs); 324 + connector->display_info.subpixel_order = SubPixelHorizontalRGB; 325 + connector->interlace_allowed = false; 326 + connector->doublescan_allowed = false; 327 + 328 + drm_connector_attach_property(connector, 329 + dev->mode_config.scaling_mode_property, 330 + DRM_MODE_SCALE_FULLSCREEN); 331 + drm_connector_attach_property(connector, 332 + dev_priv->backlight_property, 333 + BRIGHTNESS_MAX_LEVEL); 334 + 335 + mode_dev->panel_wants_dither = false; 336 + if (dev_priv->vbt_data.size != 0x00) 337 + mode_dev->panel_wants_dither = (dev_priv->gct_data. 338 + Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE); 339 + 340 + /* 341 + * LVDS discovery: 342 + * 1) check for EDID on DDC 343 + * 2) check for VBT data 344 + * 3) check to see if LVDS is already on 345 + * if none of the above, no panel 346 + * 4) make sure lid is open 347 + * if closed, act like it's not there for now 348 + */ 349 + 350 + i2c_adap = i2c_get_adapter(dev_priv->ops->i2c_bus); 351 + if (i2c_adap == NULL) 352 + dev_err(dev->dev, "No ddc adapter available!\n"); 353 + /* 354 + * Attempt to get the fixed panel mode from DDC. Assume that the 355 + * preferred mode is the right one. 356 + */ 357 + if (i2c_adap) { 358 + edid = drm_get_edid(connector, i2c_adap); 359 + if (edid) { 360 + drm_mode_connector_update_edid_property(connector, 361 + edid); 362 + ret = drm_add_edid_modes(connector, edid); 363 + kfree(edid); 364 + } 365 + 366 + list_for_each_entry(scan, &connector->probed_modes, head) { 367 + if (scan->type & DRM_MODE_TYPE_PREFERRED) { 368 + mode_dev->panel_fixed_mode = 369 + drm_mode_duplicate(dev, scan); 370 + goto out; /* FIXME: check for quirks */ 371 + } 372 + } 373 + } 374 + /* 375 + * If we didn't get EDID, try geting panel timing 376 + * from configuration data 377 + */ 378 + mode_dev->panel_fixed_mode = oaktrail_lvds_get_configuration_mode(dev); 379 + 380 + if (mode_dev->panel_fixed_mode) { 381 + mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; 382 + goto out; /* FIXME: check for quirks */ 383 + } 384 + 385 + /* If we still don't have a mode after all that, give up. */ 386 + if (!mode_dev->panel_fixed_mode) { 387 + dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n"); 388 + goto failed_find; 389 + } 390 + 391 + out: 392 + drm_sysfs_connector_add(connector); 393 + return; 394 + 395 + failed_find: 396 + dev_dbg(dev->dev, "No LVDS modes found, disabling.\n"); 397 + if (psb_intel_output->ddc_bus) 398 + psb_intel_i2c_destroy(psb_intel_output->ddc_bus); 399 + 400 + /* failed_ddc: */ 401 + 402 + drm_encoder_cleanup(encoder); 403 + drm_connector_cleanup(connector); 404 + kfree(connector); 405 + } 406 +