aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2011-11-03 14:22:26 -0400
committerDave Airlie <airlied@redhat.com>2011-11-16 06:27:12 -0500
commit1b082ccf5901108d3acd860a73d8c0442556c0bb (patch)
treed5b362913e21881a790490fe50228a13cb556be0
parent89c78134cc54dff016c83367912eb055637fa50c (diff)
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>
-rw-r--r--drivers/gpu/drm/gma500/oaktrail.h252
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_crtc.c610
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_device.c489
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_hdmi.c852
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c327
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_lvds.c406
6 files changed, 2936 insertions, 0 deletions
diff --git a/drivers/gpu/drm/gma500/oaktrail.h b/drivers/gpu/drm/gma500/oaktrail.h
new file mode 100644
index 000000000000..2da1f368f14e
--- /dev/null
+++ b/drivers/gpu/drm/gma500/oaktrail.h
@@ -0,0 +1,252 @@
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
22struct 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
30struct 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
63struct 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
87struct 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
116struct 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
146union 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
164struct 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
181struct 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
198struct 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
223struct 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
246extern void oaktrail_hdmi_setup(struct drm_device *dev);
247extern void oaktrail_hdmi_teardown(struct drm_device *dev);
248extern int oaktrail_hdmi_i2c_init(struct pci_dev *dev);
249extern void oaktrail_hdmi_i2c_exit(struct pci_dev *dev);
250extern void oaktrail_hdmi_save(struct drm_device *dev);
251extern void oaktrail_hdmi_restore(struct drm_device *dev);
252extern void oaktrail_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev);
diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c
new file mode 100644
index 000000000000..7f9c791fbe78
--- /dev/null
+++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c
@@ -0,0 +1,610 @@
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
29struct psb_intel_range_t {
30 int min, max;
31};
32
33struct oaktrail_limit_t {
34 struct psb_intel_range_t dot, m, p1;
35};
36
37struct 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
60static 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
79static 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
85static 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. */
113static void oaktrail_clock(int refclk, struct oaktrail_clock_t *clock)
114{
115 clock->dot = (refclk * clock->m) / (14 * clock->p1);
116}
117
118void 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 */
128static bool
129mrstFindBestPLL(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 */
162static 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 */
276static 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
288static 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
508oaktrail_crtc_mode_set_exit:
509 gma_power_end(dev);
510 return 0;
511}
512
513static 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
520int 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
585pipe_set_base_exit:
586 gma_power_end(dev);
587 return ret;
588}
589
590static 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
596static 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
602const 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
diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c
new file mode 100644
index 000000000000..41c418fa9aee
--- /dev/null
+++ b/drivers/gpu/drm/gma500/oaktrail_device.c
@@ -0,0 +1,489 @@
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
33static 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
57static struct backlight_device *oaktrail_backlight_device;
58static int oaktrail_brightness;
59
60static 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
98static 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
106static 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
138static const struct backlight_ops oaktrail_ops = {
139 .get_brightness = oaktrail_get_brightness,
140 .update_status = oaktrail_set_brightness,
141};
142
143int 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
178static 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 */
189static 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 */
301static 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 */
414static 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 */
438static 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
459static void oaktrail_teardown(struct drm_device *dev)
460{
461 oaktrail_hdmi_teardown(dev);
462}
463
464const 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};
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
new file mode 100644
index 000000000000..6f423c01c209
--- /dev/null
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
@@ -0,0 +1,852 @@
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
97struct intel_range {
98 int min, max;
99};
100
101struct oaktrail_hdmi_limit {
102 struct intel_range vco, np, nr, nf;
103};
104
105struct 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
121static 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
128static 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
135static 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
153static 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
181static 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
196static 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
211void 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
309static 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
330static 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
345static 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
379int 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
506static 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
520static 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
527static enum drm_connector_status
528oaktrail_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
547static 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
561static 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
597static 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
607static void oaktrail_hdmi_destroy(struct drm_connector *connector)
608{
609 return;
610}
611
612static 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
620static 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
627static 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
634static void oaktrail_hdmi_enc_destroy(struct drm_encoder *encoder)
635{
636 drm_encoder_cleanup(encoder);
637}
638
639static const struct drm_encoder_funcs oaktrail_hdmi_enc_funcs = {
640 .destroy = oaktrail_hdmi_enc_destroy,
641};
642
643void 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
680static DEFINE_PCI_DEVICE_TABLE(hdmi_ids) = {
681 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) },
682 {}
683};
684
685void 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
729free:
730 kfree(hdmi_dev);
731out:
732 return;
733}
734
735void 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 */
752void 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 */
803void 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}
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
new file mode 100644
index 000000000000..d454e6f615a8
--- /dev/null
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
@@ -0,0 +1,327 @@
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
67struct 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
76static 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
86static 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
92static 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
115static 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
123static 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
156static u32 oaktrail_hdmi_i2c_func(struct i2c_adapter *adapter)
157{
158 return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR;
159}
160
161static const struct i2c_algorithm oaktrail_hdmi_i2c_algorithm = {
162 .master_xfer = oaktrail_hdmi_i2c_access,
163 .functionality = oaktrail_hdmi_i2c_func,
164};
165
166static 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
174static 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
203static 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
222static 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 */
250static 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
272int 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
309err:
310 kfree(i2c_dev);
311exit:
312 return ret;
313}
314
315void 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}
diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c
new file mode 100644
index 000000000000..a552226a08ff
--- /dev/null
+++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c
@@ -0,0 +1,406 @@
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 */
45static 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
77static 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
90static 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
150static 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
166static 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
185static 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
197static 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
205static 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
231static struct drm_display_mode *
232oaktrail_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 */
289void 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
391out:
392 drm_sysfs_connector_add(connector);
393 return;
394
395failed_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