aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/gma500
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/gma500')
-rw-r--r--drivers/gpu/drm/gma500/Kconfig27
-rw-r--r--drivers/gpu/drm/gma500/Makefile40
-rw-r--r--drivers/gpu/drm/gma500/accel_2d.c364
-rw-r--r--drivers/gpu/drm/gma500/backlight.c49
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.c351
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.h36
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_crt.c333
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_display.c1508
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_hdmi.c394
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_lvds.c732
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c831
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.h47
-rw-r--r--drivers/gpu/drm/gma500/gem.c292
-rw-r--r--drivers/gpu/drm/gma500/gem_glue.c89
-rw-r--r--drivers/gpu/drm/gma500/gem_glue.h2
-rw-r--r--drivers/gpu/drm/gma500/gtt.c553
-rw-r--r--drivers/gpu/drm/gma500/gtt.h64
-rw-r--r--drivers/gpu/drm/gma500/intel_bios.c303
-rw-r--r--drivers/gpu/drm/gma500/intel_bios.h430
-rw-r--r--drivers/gpu/drm/gma500/intel_gmbus.c493
-rw-r--r--drivers/gpu/drm/gma500/intel_i2c.c169
-rw-r--r--drivers/gpu/drm/gma500/intel_opregion.c81
-rw-r--r--drivers/gpu/drm/gma500/mid_bios.c263
-rw-r--r--drivers/gpu/drm/gma500/mid_bios.h21
-rw-r--r--drivers/gpu/drm/gma500/mmu.c858
-rw-r--r--drivers/gpu/drm/gma500/oaktrail.h252
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_crtc.c604
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_device.c512
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_hdmi.c859
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c328
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_lvds.c449
-rw-r--r--drivers/gpu/drm/gma500/power.c316
-rw-r--r--drivers/gpu/drm/gma500/power.h67
-rw-r--r--drivers/gpu/drm/gma500/psb_device.c328
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c703
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h956
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_display.c1446
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_display.h28
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_drv.h289
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_lvds.c868
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_modes.c75
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_reg.h1309
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_sdvo.c2617
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_sdvo_regs.h723
-rw-r--r--drivers/gpu/drm/gma500/psb_irq.c564
-rw-r--r--drivers/gpu/drm/gma500/psb_irq.h45
-rw-r--r--drivers/gpu/drm/gma500/psb_lid.c88
-rw-r--r--drivers/gpu/drm/gma500/psb_reg.h582
48 files changed, 22338 insertions, 0 deletions
diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig
new file mode 100644
index 00000000000..754e14bdc80
--- /dev/null
+++ b/drivers/gpu/drm/gma500/Kconfig
@@ -0,0 +1,27 @@
1config DRM_GMA500
2 tristate "Intel GMA5/600 KMS Framebuffer"
3 depends on DRM && PCI && X86 && EXPERIMENTAL
4 select FB_CFB_COPYAREA
5 select FB_CFB_FILLRECT
6 select FB_CFB_IMAGEBLIT
7 select DRM_KMS_HELPER
8 select DRM_TTM
9 help
10 Say yes for an experimental 2D KMS framebuffer driver for the
11 Intel GMA500 ('Poulsbo') and other Intel IMG based graphics
12 devices.
13
14config DRM_GMA600
15 bool "Intel GMA600 support (Experimental)"
16 depends on DRM_GMA500
17 help
18 Say yes to include support for GMA600 (Intel Moorestown/Oaktrail)
19 platforms with LVDS ports. HDMI and MIPI are not currently
20 supported.
21
22config DRM_GMA3600
23 bool "Intel GMA3600/3650 support (Experimental)"
24 depends on DRM_GMA500
25 help
26 Say yes to include basic support for Intel GMA3600/3650 (Intel
27 Cedar Trail) platforms.
diff --git a/drivers/gpu/drm/gma500/Makefile b/drivers/gpu/drm/gma500/Makefile
new file mode 100644
index 00000000000..81c103be5e2
--- /dev/null
+++ b/drivers/gpu/drm/gma500/Makefile
@@ -0,0 +1,40 @@
1#
2# KMS driver for the GMA500
3#
4ccflags-y += -Iinclude/drm
5
6gma500_gfx-y += gem_glue.o \
7 accel_2d.o \
8 backlight.o \
9 framebuffer.o \
10 gem.o \
11 gtt.o \
12 intel_bios.o \
13 intel_i2c.o \
14 intel_gmbus.o \
15 intel_opregion.o \
16 mmu.o \
17 power.o \
18 psb_drv.o \
19 psb_intel_display.o \
20 psb_intel_lvds.o \
21 psb_intel_modes.o \
22 psb_intel_sdvo.o \
23 psb_lid.o \
24 psb_irq.o \
25 psb_device.o \
26 mid_bios.o
27
28gma500_gfx-$(CONFIG_DRM_GMA3600) += cdv_device.o \
29 cdv_intel_crt.o \
30 cdv_intel_display.o \
31 cdv_intel_hdmi.o \
32 cdv_intel_lvds.o
33
34gma500_gfx-$(CONFIG_DRM_GMA600) += oaktrail_device.o \
35 oaktrail_crtc.o \
36 oaktrail_lvds.o \
37 oaktrail_hdmi.o \
38 oaktrail_hdmi_i2c.o
39
40obj-$(CONFIG_DRM_GMA500) += gma500_gfx.o
diff --git a/drivers/gpu/drm/gma500/accel_2d.c b/drivers/gpu/drm/gma500/accel_2d.c
new file mode 100644
index 00000000000..d5ef1a5793c
--- /dev/null
+++ b/drivers/gpu/drm/gma500/accel_2d.c
@@ -0,0 +1,364 @@
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 * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
19 * develop this driver.
20 *
21 **************************************************************************/
22
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/errno.h>
26#include <linux/string.h>
27#include <linux/mm.h>
28#include <linux/tty.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31#include <linux/fb.h>
32#include <linux/init.h>
33#include <linux/console.h>
34
35#include <drm/drmP.h>
36#include <drm/drm.h>
37#include <drm/drm_crtc.h>
38
39#include "psb_drv.h"
40#include "psb_reg.h"
41#include "framebuffer.h"
42
43/**
44 * psb_spank - reset the 2D engine
45 * @dev_priv: our PSB DRM device
46 *
47 * Soft reset the graphics engine and then reload the necessary registers.
48 * We use this at initialisation time but it will become relevant for
49 * accelerated X later
50 */
51void psb_spank(struct drm_psb_private *dev_priv)
52{
53 PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET |
54 _PSB_CS_RESET_TA_RESET | _PSB_CS_RESET_USE_RESET |
55 _PSB_CS_RESET_ISP_RESET | _PSB_CS_RESET_TSP_RESET |
56 _PSB_CS_RESET_TWOD_RESET, PSB_CR_SOFT_RESET);
57 PSB_RSGX32(PSB_CR_SOFT_RESET);
58
59 msleep(1);
60
61 PSB_WSGX32(0, PSB_CR_SOFT_RESET);
62 wmb();
63 PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_CB_CTRL_CLEAR_FAULT,
64 PSB_CR_BIF_CTRL);
65 wmb();
66 (void) PSB_RSGX32(PSB_CR_BIF_CTRL);
67
68 msleep(1);
69 PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) & ~_PSB_CB_CTRL_CLEAR_FAULT,
70 PSB_CR_BIF_CTRL);
71 (void) PSB_RSGX32(PSB_CR_BIF_CTRL);
72 PSB_WSGX32(dev_priv->gtt.gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
73}
74
75/**
76 * psb2_2d_wait_available - wait for FIFO room
77 * @dev_priv: our DRM device
78 * @size: size (in dwords) of the command we want to issue
79 *
80 * Wait until there is room to load the FIFO with our data. If the
81 * device is not responding then reset it
82 */
83static int psb_2d_wait_available(struct drm_psb_private *dev_priv,
84 unsigned size)
85{
86 uint32_t avail = PSB_RSGX32(PSB_CR_2D_SOCIF);
87 unsigned long t = jiffies + HZ;
88
89 while (avail < size) {
90 avail = PSB_RSGX32(PSB_CR_2D_SOCIF);
91 if (time_after(jiffies, t)) {
92 psb_spank(dev_priv);
93 return -EIO;
94 }
95 }
96 return 0;
97}
98
99/**
100 * psb_2d_submit - submit a 2D command
101 * @dev_priv: our DRM device
102 * @cmdbuf: command to issue
103 * @size: length (in dwords)
104 *
105 * Issue one or more 2D commands to the accelerator. This needs to be
106 * serialized later when we add the GEM interfaces for acceleration
107 */
108static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
109 unsigned size)
110{
111 int ret = 0;
112 int i;
113 unsigned submit_size;
114 unsigned long flags;
115
116 spin_lock_irqsave(&dev_priv->lock_2d, flags);
117 while (size > 0) {
118 submit_size = (size < 0x60) ? size : 0x60;
119 size -= submit_size;
120 ret = psb_2d_wait_available(dev_priv, submit_size);
121 if (ret)
122 break;
123
124 submit_size <<= 2;
125
126 for (i = 0; i < submit_size; i += 4)
127 PSB_WSGX32(*cmdbuf++, PSB_SGX_2D_SLAVE_PORT + i);
128
129 (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4);
130 }
131 spin_unlock_irqrestore(&dev_priv->lock_2d, flags);
132 return ret;
133}
134
135
136/**
137 * psb_accel_2d_copy_direction - compute blit order
138 * @xdir: X direction of move
139 * @ydir: Y direction of move
140 *
141 * Compute the correct order setings to ensure that an overlapping blit
142 * correctly copies all the pixels.
143 */
144static u32 psb_accel_2d_copy_direction(int xdir, int ydir)
145{
146 if (xdir < 0)
147 return (ydir < 0) ? PSB_2D_COPYORDER_BR2TL :
148 PSB_2D_COPYORDER_TR2BL;
149 else
150 return (ydir < 0) ? PSB_2D_COPYORDER_BL2TR :
151 PSB_2D_COPYORDER_TL2BR;
152}
153
154/**
155 * psb_accel_2d_copy - accelerated 2D copy
156 * @dev_priv: our DRM device
157 * @src_offset in bytes
158 * @src_stride in bytes
159 * @src_format psb 2D format defines
160 * @dst_offset in bytes
161 * @dst_stride in bytes
162 * @dst_format psb 2D format defines
163 * @src_x offset in pixels
164 * @src_y offset in pixels
165 * @dst_x offset in pixels
166 * @dst_y offset in pixels
167 * @size_x of the copied area
168 * @size_y of the copied area
169 *
170 * Format and issue a 2D accelerated copy command.
171 */
172static int psb_accel_2d_copy(struct drm_psb_private *dev_priv,
173 uint32_t src_offset, uint32_t src_stride,
174 uint32_t src_format, uint32_t dst_offset,
175 uint32_t dst_stride, uint32_t dst_format,
176 uint16_t src_x, uint16_t src_y,
177 uint16_t dst_x, uint16_t dst_y,
178 uint16_t size_x, uint16_t size_y)
179{
180 uint32_t blit_cmd;
181 uint32_t buffer[10];
182 uint32_t *buf;
183 uint32_t direction;
184
185 buf = buffer;
186
187 direction =
188 psb_accel_2d_copy_direction(src_x - dst_x, src_y - dst_y);
189
190 if (direction == PSB_2D_COPYORDER_BR2TL ||
191 direction == PSB_2D_COPYORDER_TR2BL) {
192 src_x += size_x - 1;
193 dst_x += size_x - 1;
194 }
195 if (direction == PSB_2D_COPYORDER_BR2TL ||
196 direction == PSB_2D_COPYORDER_BL2TR) {
197 src_y += size_y - 1;
198 dst_y += size_y - 1;
199 }
200
201 blit_cmd =
202 PSB_2D_BLIT_BH |
203 PSB_2D_ROT_NONE |
204 PSB_2D_DSTCK_DISABLE |
205 PSB_2D_SRCCK_DISABLE |
206 PSB_2D_USE_PAT | PSB_2D_ROP3_SRCCOPY | direction;
207
208 *buf++ = PSB_2D_FENCE_BH;
209 *buf++ =
210 PSB_2D_DST_SURF_BH | dst_format | (dst_stride <<
211 PSB_2D_DST_STRIDE_SHIFT);
212 *buf++ = dst_offset;
213 *buf++ =
214 PSB_2D_SRC_SURF_BH | src_format | (src_stride <<
215 PSB_2D_SRC_STRIDE_SHIFT);
216 *buf++ = src_offset;
217 *buf++ =
218 PSB_2D_SRC_OFF_BH | (src_x << PSB_2D_SRCOFF_XSTART_SHIFT) |
219 (src_y << PSB_2D_SRCOFF_YSTART_SHIFT);
220 *buf++ = blit_cmd;
221 *buf++ =
222 (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y <<
223 PSB_2D_DST_YSTART_SHIFT);
224 *buf++ =
225 (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y <<
226 PSB_2D_DST_YSIZE_SHIFT);
227 *buf++ = PSB_2D_FLUSH_BH;
228
229 return psbfb_2d_submit(dev_priv, buffer, buf - buffer);
230}
231
232/**
233 * psbfb_copyarea_accel - copyarea acceleration for /dev/fb
234 * @info: our framebuffer
235 * @a: copyarea parameters from the framebuffer core
236 *
237 * Perform a 2D copy via the accelerator
238 */
239static void psbfb_copyarea_accel(struct fb_info *info,
240 const struct fb_copyarea *a)
241{
242 struct psb_fbdev *fbdev = info->par;
243 struct psb_framebuffer *psbfb = &fbdev->pfb;
244 struct drm_device *dev = psbfb->base.dev;
245 struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;
246 struct drm_psb_private *dev_priv = dev->dev_private;
247 uint32_t offset;
248 uint32_t stride;
249 uint32_t src_format;
250 uint32_t dst_format;
251
252 if (!fb)
253 return;
254
255 offset = psbfb->gtt->offset;
256 stride = fb->pitches[0];
257
258 switch (fb->depth) {
259 case 8:
260 src_format = PSB_2D_SRC_332RGB;
261 dst_format = PSB_2D_DST_332RGB;
262 break;
263 case 15:
264 src_format = PSB_2D_SRC_555RGB;
265 dst_format = PSB_2D_DST_555RGB;
266 break;
267 case 16:
268 src_format = PSB_2D_SRC_565RGB;
269 dst_format = PSB_2D_DST_565RGB;
270 break;
271 case 24:
272 case 32:
273 /* this is wrong but since we don't do blending its okay */
274 src_format = PSB_2D_SRC_8888ARGB;
275 dst_format = PSB_2D_DST_8888ARGB;
276 break;
277 default:
278 /* software fallback */
279 cfb_copyarea(info, a);
280 return;
281 }
282
283 if (!gma_power_begin(dev, false)) {
284 cfb_copyarea(info, a);
285 return;
286 }
287 psb_accel_2d_copy(dev_priv,
288 offset, stride, src_format,
289 offset, stride, dst_format,
290 a->sx, a->sy, a->dx, a->dy, a->width, a->height);
291 gma_power_end(dev);
292}
293
294/**
295 * psbfb_copyarea - 2D copy interface
296 * @info: our framebuffer
297 * @region: region to copy
298 *
299 * Copy an area of the framebuffer console either by the accelerator
300 * or directly using the cfb helpers according to the request
301 */
302void psbfb_copyarea(struct fb_info *info,
303 const struct fb_copyarea *region)
304{
305 if (unlikely(info->state != FBINFO_STATE_RUNNING))
306 return;
307
308 /* Avoid the 8 pixel erratum */
309 if (region->width == 8 || region->height == 8 ||
310 (info->flags & FBINFO_HWACCEL_DISABLED))
311 return cfb_copyarea(info, region);
312
313 psbfb_copyarea_accel(info, region);
314}
315
316/**
317 * psbfb_sync - synchronize 2D
318 * @info: our framebuffer
319 *
320 * Wait for the 2D engine to quiesce so that we can do CPU
321 * access to the framebuffer again
322 */
323int psbfb_sync(struct fb_info *info)
324{
325 struct psb_fbdev *fbdev = info->par;
326 struct psb_framebuffer *psbfb = &fbdev->pfb;
327 struct drm_device *dev = psbfb->base.dev;
328 struct drm_psb_private *dev_priv = dev->dev_private;
329 unsigned long _end = jiffies + DRM_HZ;
330 int busy = 0;
331 unsigned long flags;
332
333 spin_lock_irqsave(&dev_priv->lock_2d, flags);
334 /*
335 * First idle the 2D engine.
336 */
337
338 if ((PSB_RSGX32(PSB_CR_2D_SOCIF) == _PSB_C2_SOCIF_EMPTY) &&
339 ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & _PSB_C2B_STATUS_BUSY) == 0))
340 goto out;
341
342 do {
343 busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY);
344 cpu_relax();
345 } while (busy && !time_after_eq(jiffies, _end));
346
347 if (busy)
348 busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY);
349 if (busy)
350 goto out;
351
352 do {
353 busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) &
354 _PSB_C2B_STATUS_BUSY) != 0);
355 cpu_relax();
356 } while (busy && !time_after_eq(jiffies, _end));
357 if (busy)
358 busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) &
359 _PSB_C2B_STATUS_BUSY) != 0);
360
361out:
362 spin_unlock_irqrestore(&dev_priv->lock_2d, flags);
363 return (busy) ? -EBUSY : 0;
364}
diff --git a/drivers/gpu/drm/gma500/backlight.c b/drivers/gpu/drm/gma500/backlight.c
new file mode 100644
index 00000000000..20793951fca
--- /dev/null
+++ b/drivers/gpu/drm/gma500/backlight.c
@@ -0,0 +1,49 @@
1/*
2 * GMA500 Backlight Interface
3 *
4 * Copyright (c) 2009-2011, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Authors: Eric Knopp
20 *
21 */
22
23#include "psb_drv.h"
24#include "psb_intel_reg.h"
25#include "psb_intel_drv.h"
26#include "intel_bios.h"
27#include "power.h"
28
29int gma_backlight_init(struct drm_device *dev)
30{
31#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
32 struct drm_psb_private *dev_priv = dev->dev_private;
33 return dev_priv->ops->backlight_init(dev);
34#else
35 return 0;
36#endif
37}
38
39void gma_backlight_exit(struct drm_device *dev)
40{
41#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
42 struct drm_psb_private *dev_priv = dev->dev_private;
43 if (dev_priv->backlight_device) {
44 dev_priv->backlight_device->props.brightness = 0;
45 backlight_update_status(dev_priv->backlight_device);
46 backlight_device_unregister(dev_priv->backlight_device);
47 }
48#endif
49}
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c
new file mode 100644
index 00000000000..4a5b099c3bc
--- /dev/null
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -0,0 +1,351 @@
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 <drm/drmP.h>
22#include <drm/drm.h>
23#include "gma_drm.h"
24#include "psb_drv.h"
25#include "psb_reg.h"
26#include "psb_intel_reg.h"
27#include "intel_bios.h"
28#include "cdv_device.h"
29
30#define VGA_SR_INDEX 0x3c4
31#define VGA_SR_DATA 0x3c5
32
33static void cdv_disable_vga(struct drm_device *dev)
34{
35 u8 sr1;
36 u32 vga_reg;
37
38 vga_reg = VGACNTRL;
39
40 outb(1, VGA_SR_INDEX);
41 sr1 = inb(VGA_SR_DATA);
42 outb(sr1 | 1<<5, VGA_SR_DATA);
43 udelay(300);
44
45 REG_WRITE(vga_reg, VGA_DISP_DISABLE);
46 REG_READ(vga_reg);
47}
48
49static int cdv_output_init(struct drm_device *dev)
50{
51 struct drm_psb_private *dev_priv = dev->dev_private;
52 cdv_disable_vga(dev);
53
54 cdv_intel_crt_init(dev, &dev_priv->mode_dev);
55 cdv_intel_lvds_init(dev, &dev_priv->mode_dev);
56
57 /* These bits indicate HDMI not SDVO on CDV, but we don't yet support
58 the HDMI interface */
59 if (REG_READ(SDVOB) & SDVO_DETECTED)
60 cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB);
61 if (REG_READ(SDVOC) & SDVO_DETECTED)
62 cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOC);
63 return 0;
64}
65
66#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
67
68/*
69 * Poulsbo Backlight Interfaces
70 */
71
72#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
73#define BLC_PWM_FREQ_CALC_CONSTANT 32
74#define MHz 1000000
75
76#define PSB_BLC_PWM_PRECISION_FACTOR 10
77#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE
78#define PSB_BLC_MIN_PWM_REG_FREQ 0x2
79
80#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
81#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16)
82
83static int cdv_brightness;
84static struct backlight_device *cdv_backlight_device;
85
86static int cdv_get_brightness(struct backlight_device *bd)
87{
88 /* return locally cached var instead of HW read (due to DPST etc.) */
89 /* FIXME: ideally return actual value in case firmware fiddled with
90 it */
91 return cdv_brightness;
92}
93
94
95static int cdv_backlight_setup(struct drm_device *dev)
96{
97 struct drm_psb_private *dev_priv = dev->dev_private;
98 unsigned long core_clock;
99 /* u32 bl_max_freq; */
100 /* unsigned long value; */
101 u16 bl_max_freq;
102 uint32_t value;
103 uint32_t blc_pwm_precision_factor;
104
105 /* get bl_max_freq and pol from dev_priv*/
106 if (!dev_priv->lvds_bl) {
107 dev_err(dev->dev, "Has no valid LVDS backlight info\n");
108 return -ENOENT;
109 }
110 bl_max_freq = dev_priv->lvds_bl->freq;
111 blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
112
113 core_clock = dev_priv->core_freq;
114
115 value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
116 value *= blc_pwm_precision_factor;
117 value /= bl_max_freq;
118 value /= blc_pwm_precision_factor;
119
120 if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
121 value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
122 return -ERANGE;
123 else {
124 /* FIXME */
125 }
126 return 0;
127}
128
129static int cdv_set_brightness(struct backlight_device *bd)
130{
131 int level = bd->props.brightness;
132
133 /* Percentage 1-100% being valid */
134 if (level < 1)
135 level = 1;
136
137 /*cdv_intel_lvds_set_brightness(dev, level); FIXME */
138 cdv_brightness = level;
139 return 0;
140}
141
142static const struct backlight_ops cdv_ops = {
143 .get_brightness = cdv_get_brightness,
144 .update_status = cdv_set_brightness,
145};
146
147static int cdv_backlight_init(struct drm_device *dev)
148{
149 struct drm_psb_private *dev_priv = dev->dev_private;
150 int ret;
151 struct backlight_properties props;
152
153 memset(&props, 0, sizeof(struct backlight_properties));
154 props.max_brightness = 100;
155 props.type = BACKLIGHT_PLATFORM;
156
157 cdv_backlight_device = backlight_device_register("psb-bl",
158 NULL, (void *)dev, &cdv_ops, &props);
159 if (IS_ERR(cdv_backlight_device))
160 return PTR_ERR(cdv_backlight_device);
161
162 ret = cdv_backlight_setup(dev);
163 if (ret < 0) {
164 backlight_device_unregister(cdv_backlight_device);
165 cdv_backlight_device = NULL;
166 return ret;
167 }
168 cdv_backlight_device->props.brightness = 100;
169 cdv_backlight_device->props.max_brightness = 100;
170 backlight_update_status(cdv_backlight_device);
171 dev_priv->backlight_device = cdv_backlight_device;
172 return 0;
173}
174
175#endif
176
177/*
178 * Provide the Cedarview specific chip logic and low level methods
179 * for power management
180 *
181 * FIXME: we need to implement the apm/ospm base management bits
182 * for this and the MID devices.
183 */
184
185static inline u32 CDV_MSG_READ32(uint port, uint offset)
186{
187 int mcr = (0x10<<24) | (port << 16) | (offset << 8);
188 uint32_t ret_val = 0;
189 struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
190 pci_write_config_dword(pci_root, 0xD0, mcr);
191 pci_read_config_dword(pci_root, 0xD4, &ret_val);
192 pci_dev_put(pci_root);
193 return ret_val;
194}
195
196static inline void CDV_MSG_WRITE32(uint port, uint offset, u32 value)
197{
198 int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
199 struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
200 pci_write_config_dword(pci_root, 0xD4, value);
201 pci_write_config_dword(pci_root, 0xD0, mcr);
202 pci_dev_put(pci_root);
203}
204
205#define PSB_APM_CMD 0x0
206#define PSB_APM_STS 0x04
207#define PSB_PM_SSC 0x20
208#define PSB_PM_SSS 0x30
209#define PSB_PWRGT_GFX_MASK 0x3
210#define CDV_PWRGT_DISPLAY_CNTR 0x000fc00c
211#define CDV_PWRGT_DISPLAY_STS 0x000fc00c
212
213static void cdv_init_pm(struct drm_device *dev)
214{
215 struct drm_psb_private *dev_priv = dev->dev_private;
216 u32 pwr_cnt;
217 int i;
218
219 dev_priv->apm_base = CDV_MSG_READ32(PSB_PUNIT_PORT,
220 PSB_APMBA) & 0xFFFF;
221 dev_priv->ospm_base = CDV_MSG_READ32(PSB_PUNIT_PORT,
222 PSB_OSPMBA) & 0xFFFF;
223
224 /* Force power on for now */
225 pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD);
226 pwr_cnt &= ~PSB_PWRGT_GFX_MASK;
227
228 outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD);
229 for (i = 0; i < 5; i++) {
230 u32 pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS);
231 if ((pwr_sts & PSB_PWRGT_GFX_MASK) == 0)
232 break;
233 udelay(10);
234 }
235 pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
236 pwr_cnt &= ~CDV_PWRGT_DISPLAY_CNTR;
237 outl(pwr_cnt, dev_priv->ospm_base + PSB_PM_SSC);
238 for (i = 0; i < 5; i++) {
239 u32 pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
240 if ((pwr_sts & CDV_PWRGT_DISPLAY_STS) == 0)
241 break;
242 udelay(10);
243 }
244}
245
246/**
247 * cdv_save_display_registers - save registers lost on suspend
248 * @dev: our DRM device
249 *
250 * Save the state we need in order to be able to restore the interface
251 * upon resume from suspend
252 *
253 * FIXME: review
254 */
255static int cdv_save_display_registers(struct drm_device *dev)
256{
257 return 0;
258}
259
260/**
261 * cdv_restore_display_registers - restore lost register state
262 * @dev: our DRM device
263 *
264 * Restore register state that was lost during suspend and resume.
265 *
266 * FIXME: review
267 */
268static int cdv_restore_display_registers(struct drm_device *dev)
269{
270 return 0;
271}
272
273static int cdv_power_down(struct drm_device *dev)
274{
275 return 0;
276}
277
278static int cdv_power_up(struct drm_device *dev)
279{
280 return 0;
281}
282
283/* FIXME ? - shared with Poulsbo */
284static void cdv_get_core_freq(struct drm_device *dev)
285{
286 uint32_t clock;
287 struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
288 struct drm_psb_private *dev_priv = dev->dev_private;
289
290 pci_write_config_dword(pci_root, 0xD0, 0xD0050300);
291 pci_read_config_dword(pci_root, 0xD4, &clock);
292 pci_dev_put(pci_root);
293
294 switch (clock & 0x07) {
295 case 0:
296 dev_priv->core_freq = 100;
297 break;
298 case 1:
299 dev_priv->core_freq = 133;
300 break;
301 case 2:
302 dev_priv->core_freq = 150;
303 break;
304 case 3:
305 dev_priv->core_freq = 178;
306 break;
307 case 4:
308 dev_priv->core_freq = 200;
309 break;
310 case 5:
311 case 6:
312 case 7:
313 dev_priv->core_freq = 266;
314 default:
315 dev_priv->core_freq = 0;
316 }
317}
318
319static int cdv_chip_setup(struct drm_device *dev)
320{
321 cdv_get_core_freq(dev);
322 gma_intel_opregion_init(dev);
323 psb_intel_init_bios(dev);
324 return 0;
325}
326
327/* CDV is much like Poulsbo but has MID like SGX offsets and PM */
328
329const struct psb_ops cdv_chip_ops = {
330 .name = "GMA3600/3650",
331 .accel_2d = 0,
332 .pipes = 2,
333 .crtcs = 2,
334 .sgx_offset = MRST_SGX_OFFSET,
335 .chip_setup = cdv_chip_setup,
336
337 .crtc_helper = &cdv_intel_helper_funcs,
338 .crtc_funcs = &cdv_intel_crtc_funcs,
339
340 .output_init = cdv_output_init,
341
342#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
343 .backlight_init = cdv_backlight_init,
344#endif
345
346 .init_pm = cdv_init_pm,
347 .save_regs = cdv_save_display_registers,
348 .restore_regs = cdv_restore_display_registers,
349 .power_down = cdv_power_down,
350 .power_up = cdv_power_up,
351};
diff --git a/drivers/gpu/drm/gma500/cdv_device.h b/drivers/gpu/drm/gma500/cdv_device.h
new file mode 100644
index 00000000000..2a88b7beb55
--- /dev/null
+++ b/drivers/gpu/drm/gma500/cdv_device.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright © 2011 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
18extern const struct drm_crtc_helper_funcs cdv_intel_helper_funcs;
19extern const struct drm_crtc_funcs cdv_intel_crtc_funcs;
20extern void cdv_intel_crt_init(struct drm_device *dev,
21 struct psb_intel_mode_device *mode_dev);
22extern void cdv_intel_lvds_init(struct drm_device *dev,
23 struct psb_intel_mode_device *mode_dev);
24extern void cdv_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev,
25 int reg);
26extern struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev,
27 struct drm_crtc *crtc);
28
29extern inline void cdv_intel_wait_for_vblank(struct drm_device *dev)
30{
31 /* Wait for 20ms, i.e. one cycle at 50hz. */
32 /* FIXME: msleep ?? */
33 mdelay(20);
34}
35
36
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c
new file mode 100644
index 00000000000..6d0f10b7569
--- /dev/null
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -0,0 +1,333 @@
1/*
2 * Copyright © 2006-2007 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 * Eric Anholt <eric@anholt.net>
25 */
26
27#include <linux/i2c.h>
28#include <drm/drmP.h>
29
30#include "intel_bios.h"
31#include "psb_drv.h"
32#include "psb_intel_drv.h"
33#include "psb_intel_reg.h"
34#include "power.h"
35#include <linux/pm_runtime.h>
36
37
38static void cdv_intel_crt_dpms(struct drm_encoder *encoder, int mode)
39{
40 struct drm_device *dev = encoder->dev;
41 u32 temp, reg;
42 reg = ADPA;
43
44 temp = REG_READ(reg);
45 temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
46 temp &= ~ADPA_DAC_ENABLE;
47
48 switch (mode) {
49 case DRM_MODE_DPMS_ON:
50 temp |= ADPA_DAC_ENABLE;
51 break;
52 case DRM_MODE_DPMS_STANDBY:
53 temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE;
54 break;
55 case DRM_MODE_DPMS_SUSPEND:
56 temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE;
57 break;
58 case DRM_MODE_DPMS_OFF:
59 temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
60 break;
61 }
62
63 REG_WRITE(reg, temp);
64}
65
66static int cdv_intel_crt_mode_valid(struct drm_connector *connector,
67 struct drm_display_mode *mode)
68{
69 int max_clock = 0;
70 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
71 return MODE_NO_DBLESCAN;
72
73 /* The lowest clock for CDV is 20000KHz */
74 if (mode->clock < 20000)
75 return MODE_CLOCK_LOW;
76
77 /* The max clock for CDV is 355 instead of 400 */
78 max_clock = 355000;
79 if (mode->clock > max_clock)
80 return MODE_CLOCK_HIGH;
81
82 if (mode->hdisplay > 1680 || mode->vdisplay > 1050)
83 return MODE_PANEL;
84
85 return MODE_OK;
86}
87
88static bool cdv_intel_crt_mode_fixup(struct drm_encoder *encoder,
89 struct drm_display_mode *mode,
90 struct drm_display_mode *adjusted_mode)
91{
92 return true;
93}
94
95static void cdv_intel_crt_mode_set(struct drm_encoder *encoder,
96 struct drm_display_mode *mode,
97 struct drm_display_mode *adjusted_mode)
98{
99
100 struct drm_device *dev = encoder->dev;
101 struct drm_crtc *crtc = encoder->crtc;
102 struct psb_intel_crtc *psb_intel_crtc =
103 to_psb_intel_crtc(crtc);
104 int dpll_md_reg;
105 u32 adpa, dpll_md;
106 u32 adpa_reg;
107
108 if (psb_intel_crtc->pipe == 0)
109 dpll_md_reg = DPLL_A_MD;
110 else
111 dpll_md_reg = DPLL_B_MD;
112
113 adpa_reg = ADPA;
114
115 /*
116 * Disable separate mode multiplier used when cloning SDVO to CRT
117 * XXX this needs to be adjusted when we really are cloning
118 */
119 {
120 dpll_md = REG_READ(dpll_md_reg);
121 REG_WRITE(dpll_md_reg,
122 dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
123 }
124
125 adpa = 0;
126 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
127 adpa |= ADPA_HSYNC_ACTIVE_HIGH;
128 if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
129 adpa |= ADPA_VSYNC_ACTIVE_HIGH;
130
131 if (psb_intel_crtc->pipe == 0)
132 adpa |= ADPA_PIPE_A_SELECT;
133 else
134 adpa |= ADPA_PIPE_B_SELECT;
135
136 REG_WRITE(adpa_reg, adpa);
137}
138
139
140/**
141 * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
142 *
143 * \return true if CRT is connected.
144 * \return false if CRT is disconnected.
145 */
146static bool cdv_intel_crt_detect_hotplug(struct drm_connector *connector,
147 bool force)
148{
149 struct drm_device *dev = connector->dev;
150 u32 hotplug_en;
151 int i, tries = 0, ret = false;
152 u32 adpa_orig;
153
154 /* disable the DAC when doing the hotplug detection */
155
156 adpa_orig = REG_READ(ADPA);
157
158 REG_WRITE(ADPA, adpa_orig & ~(ADPA_DAC_ENABLE));
159
160 /*
161 * On a CDV thep, CRT detect sequence need to be done twice
162 * to get a reliable result.
163 */
164 tries = 2;
165
166 hotplug_en = REG_READ(PORT_HOTPLUG_EN);
167 hotplug_en &= ~(CRT_HOTPLUG_DETECT_MASK);
168 hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
169
170 hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
171 hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
172
173 for (i = 0; i < tries ; i++) {
174 unsigned long timeout;
175 /* turn on the FORCE_DETECT */
176 REG_WRITE(PORT_HOTPLUG_EN, hotplug_en);
177 timeout = jiffies + msecs_to_jiffies(1000);
178 /* wait for FORCE_DETECT to go off */
179 do {
180 if (!(REG_READ(PORT_HOTPLUG_EN) &
181 CRT_HOTPLUG_FORCE_DETECT))
182 break;
183 msleep(1);
184 } while (time_after(timeout, jiffies));
185 }
186
187 if ((REG_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) !=
188 CRT_HOTPLUG_MONITOR_NONE)
189 ret = true;
190
191 /* Restore the saved ADPA */
192 REG_WRITE(ADPA, adpa_orig);
193 return ret;
194}
195
196static enum drm_connector_status cdv_intel_crt_detect(
197 struct drm_connector *connector, bool force)
198{
199 if (cdv_intel_crt_detect_hotplug(connector, force))
200 return connector_status_connected;
201 else
202 return connector_status_disconnected;
203}
204
205static void cdv_intel_crt_destroy(struct drm_connector *connector)
206{
207 struct psb_intel_encoder *psb_intel_encoder =
208 psb_intel_attached_encoder(connector);
209
210 psb_intel_i2c_destroy(psb_intel_encoder->ddc_bus);
211 drm_sysfs_connector_remove(connector);
212 drm_connector_cleanup(connector);
213 kfree(connector);
214}
215
216static int cdv_intel_crt_get_modes(struct drm_connector *connector)
217{
218 struct psb_intel_encoder *psb_intel_encoder =
219 psb_intel_attached_encoder(connector);
220 return psb_intel_ddc_get_modes(connector, &psb_intel_encoder->ddc_bus->adapter);
221}
222
223static int cdv_intel_crt_set_property(struct drm_connector *connector,
224 struct drm_property *property,
225 uint64_t value)
226{
227 return 0;
228}
229
230/*
231 * Routines for controlling stuff on the analog port
232 */
233
234static const struct drm_encoder_helper_funcs cdv_intel_crt_helper_funcs = {
235 .dpms = cdv_intel_crt_dpms,
236 .mode_fixup = cdv_intel_crt_mode_fixup,
237 .prepare = psb_intel_encoder_prepare,
238 .commit = psb_intel_encoder_commit,
239 .mode_set = cdv_intel_crt_mode_set,
240};
241
242static const struct drm_connector_funcs cdv_intel_crt_connector_funcs = {
243 .dpms = drm_helper_connector_dpms,
244 .detect = cdv_intel_crt_detect,
245 .fill_modes = drm_helper_probe_single_connector_modes,
246 .destroy = cdv_intel_crt_destroy,
247 .set_property = cdv_intel_crt_set_property,
248};
249
250static const struct drm_connector_helper_funcs
251 cdv_intel_crt_connector_helper_funcs = {
252 .mode_valid = cdv_intel_crt_mode_valid,
253 .get_modes = cdv_intel_crt_get_modes,
254 .best_encoder = psb_intel_best_encoder,
255};
256
257static void cdv_intel_crt_enc_destroy(struct drm_encoder *encoder)
258{
259 drm_encoder_cleanup(encoder);
260}
261
262static const struct drm_encoder_funcs cdv_intel_crt_enc_funcs = {
263 .destroy = cdv_intel_crt_enc_destroy,
264};
265
266void cdv_intel_crt_init(struct drm_device *dev,
267 struct psb_intel_mode_device *mode_dev)
268{
269
270 struct psb_intel_connector *psb_intel_connector;
271 struct psb_intel_encoder *psb_intel_encoder;
272 struct drm_connector *connector;
273 struct drm_encoder *encoder;
274
275 u32 i2c_reg;
276
277 psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL);
278 if (!psb_intel_encoder)
279 return;
280
281 psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL);
282 if (!psb_intel_connector)
283 goto failed_connector;
284
285 connector = &psb_intel_connector->base;
286 drm_connector_init(dev, connector,
287 &cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
288
289 encoder = &psb_intel_encoder->base;
290 drm_encoder_init(dev, encoder,
291 &cdv_intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC);
292
293 psb_intel_connector_attach_encoder(psb_intel_connector,
294 psb_intel_encoder);
295
296 /* Set up the DDC bus. */
297 i2c_reg = GPIOA;
298 /* Remove the following code for CDV */
299 /*
300 if (dev_priv->crt_ddc_bus != 0)
301 i2c_reg = dev_priv->crt_ddc_bus;
302 }*/
303 psb_intel_encoder->ddc_bus = psb_intel_i2c_create(dev,
304 i2c_reg, "CRTDDC_A");
305 if (!psb_intel_encoder->ddc_bus) {
306 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
307 "failed.\n");
308 goto failed_ddc;
309 }
310
311 psb_intel_encoder->type = INTEL_OUTPUT_ANALOG;
312 /*
313 psb_intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT);
314 psb_intel_output->crtc_mask = (1 << 0) | (1 << 1);
315 */
316 connector->interlace_allowed = 0;
317 connector->doublescan_allowed = 0;
318
319 drm_encoder_helper_add(encoder, &cdv_intel_crt_helper_funcs);
320 drm_connector_helper_add(connector,
321 &cdv_intel_crt_connector_helper_funcs);
322
323 drm_sysfs_connector_add(connector);
324
325 return;
326failed_ddc:
327 drm_encoder_cleanup(&psb_intel_encoder->base);
328 drm_connector_cleanup(&psb_intel_connector->base);
329 kfree(psb_intel_connector);
330failed_connector:
331 kfree(psb_intel_encoder);
332 return;
333}
diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c
new file mode 100644
index 00000000000..18d11525095
--- /dev/null
+++ b/drivers/gpu/drm/gma500/cdv_intel_display.c
@@ -0,0 +1,1508 @@
1/*
2 * Copyright © 2006-2011 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 */
20
21#include <linux/i2c.h>
22#include <linux/pm_runtime.h>
23
24#include <drm/drmP.h>
25#include "framebuffer.h"
26#include "psb_drv.h"
27#include "psb_intel_drv.h"
28#include "psb_intel_reg.h"
29#include "psb_intel_display.h"
30#include "power.h"
31#include "cdv_device.h"
32
33
34struct cdv_intel_range_t {
35 int min, max;
36};
37
38struct cdv_intel_p2_t {
39 int dot_limit;
40 int p2_slow, p2_fast;
41};
42
43struct cdv_intel_clock_t {
44 /* given values */
45 int n;
46 int m1, m2;
47 int p1, p2;
48 /* derived values */
49 int dot;
50 int vco;
51 int m;
52 int p;
53};
54
55#define INTEL_P2_NUM 2
56
57struct cdv_intel_limit_t {
58 struct cdv_intel_range_t dot, vco, n, m, m1, m2, p, p1;
59 struct cdv_intel_p2_t p2;
60};
61
62#define CDV_LIMIT_SINGLE_LVDS_96 0
63#define CDV_LIMIT_SINGLE_LVDS_100 1
64#define CDV_LIMIT_DAC_HDMI_27 2
65#define CDV_LIMIT_DAC_HDMI_96 3
66
67static const struct cdv_intel_limit_t cdv_intel_limits[] = {
68 { /* CDV_SIGNLE_LVDS_96MHz */
69 .dot = {.min = 20000, .max = 115500},
70 .vco = {.min = 1800000, .max = 3600000},
71 .n = {.min = 2, .max = 6},
72 .m = {.min = 60, .max = 160},
73 .m1 = {.min = 0, .max = 0},
74 .m2 = {.min = 58, .max = 158},
75 .p = {.min = 28, .max = 140},
76 .p1 = {.min = 2, .max = 10},
77 .p2 = {.dot_limit = 200000,
78 .p2_slow = 14, .p2_fast = 14},
79 },
80 { /* CDV_SINGLE_LVDS_100MHz */
81 .dot = {.min = 20000, .max = 115500},
82 .vco = {.min = 1800000, .max = 3600000},
83 .n = {.min = 2, .max = 6},
84 .m = {.min = 60, .max = 160},
85 .m1 = {.min = 0, .max = 0},
86 .m2 = {.min = 58, .max = 158},
87 .p = {.min = 28, .max = 140},
88 .p1 = {.min = 2, .max = 10},
89 /* The single-channel range is 25-112Mhz, and dual-channel
90 * is 80-224Mhz. Prefer single channel as much as possible.
91 */
92 .p2 = {.dot_limit = 200000, .p2_slow = 14, .p2_fast = 14},
93 },
94 { /* CDV_DAC_HDMI_27MHz */
95 .dot = {.min = 20000, .max = 400000},
96 .vco = {.min = 1809000, .max = 3564000},
97 .n = {.min = 1, .max = 1},
98 .m = {.min = 67, .max = 132},
99 .m1 = {.min = 0, .max = 0},
100 .m2 = {.min = 65, .max = 130},
101 .p = {.min = 5, .max = 90},
102 .p1 = {.min = 1, .max = 9},
103 .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
104 },
105 { /* CDV_DAC_HDMI_96MHz */
106 .dot = {.min = 20000, .max = 400000},
107 .vco = {.min = 1800000, .max = 3600000},
108 .n = {.min = 2, .max = 6},
109 .m = {.min = 60, .max = 160},
110 .m1 = {.min = 0, .max = 0},
111 .m2 = {.min = 58, .max = 158},
112 .p = {.min = 5, .max = 100},
113 .p1 = {.min = 1, .max = 10},
114 .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
115 },
116};
117
118#define _wait_for(COND, MS, W) ({ \
119 unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \
120 int ret__ = 0; \
121 while (!(COND)) { \
122 if (time_after(jiffies, timeout__)) { \
123 ret__ = -ETIMEDOUT; \
124 break; \
125 } \
126 if (W && !in_dbg_master()) \
127 msleep(W); \
128 } \
129 ret__; \
130})
131
132#define wait_for(COND, MS) _wait_for(COND, MS, 1)
133
134
135static int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val)
136{
137 int ret;
138
139 ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
140 if (ret) {
141 DRM_ERROR("timeout waiting for SB to idle before read\n");
142 return ret;
143 }
144
145 REG_WRITE(SB_ADDR, reg);
146 REG_WRITE(SB_PCKT,
147 SET_FIELD(SB_OPCODE_READ, SB_OPCODE) |
148 SET_FIELD(SB_DEST_DPLL, SB_DEST) |
149 SET_FIELD(0xf, SB_BYTE_ENABLE));
150
151 ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
152 if (ret) {
153 DRM_ERROR("timeout waiting for SB to idle after read\n");
154 return ret;
155 }
156
157 *val = REG_READ(SB_DATA);
158
159 return 0;
160}
161
162static int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val)
163{
164 int ret;
165 static bool dpio_debug = true;
166 u32 temp;
167
168 if (dpio_debug) {
169 if (cdv_sb_read(dev, reg, &temp) == 0)
170 DRM_DEBUG_KMS("0x%08x: 0x%08x (before)\n", reg, temp);
171 DRM_DEBUG_KMS("0x%08x: 0x%08x\n", reg, val);
172 }
173
174 ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
175 if (ret) {
176 DRM_ERROR("timeout waiting for SB to idle before write\n");
177 return ret;
178 }
179
180 REG_WRITE(SB_ADDR, reg);
181 REG_WRITE(SB_DATA, val);
182 REG_WRITE(SB_PCKT,
183 SET_FIELD(SB_OPCODE_WRITE, SB_OPCODE) |
184 SET_FIELD(SB_DEST_DPLL, SB_DEST) |
185 SET_FIELD(0xf, SB_BYTE_ENABLE));
186
187 ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
188 if (ret) {
189 DRM_ERROR("timeout waiting for SB to idle after write\n");
190 return ret;
191 }
192
193 if (dpio_debug) {
194 if (cdv_sb_read(dev, reg, &temp) == 0)
195 DRM_DEBUG_KMS("0x%08x: 0x%08x (after)\n", reg, temp);
196 }
197
198 return 0;
199}
200
201/* Reset the DPIO configuration register. The BIOS does this at every
202 * mode set.
203 */
204static void cdv_sb_reset(struct drm_device *dev)
205{
206
207 REG_WRITE(DPIO_CFG, 0);
208 REG_READ(DPIO_CFG);
209 REG_WRITE(DPIO_CFG, DPIO_MODE_SELECT_0 | DPIO_CMN_RESET_N);
210}
211
212/* Unlike most Intel display engines, on Cedarview the DPLL registers
213 * are behind this sideband bus. They must be programmed while the
214 * DPLL reference clock is on in the DPLL control register, but before
215 * the DPLL is enabled in the DPLL control register.
216 */
217static int
218cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
219 struct cdv_intel_clock_t *clock)
220{
221 struct psb_intel_crtc *psb_crtc =
222 to_psb_intel_crtc(crtc);
223 int pipe = psb_crtc->pipe;
224 u32 m, n_vco, p;
225 int ret = 0;
226 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
227 u32 ref_value;
228
229 cdv_sb_reset(dev);
230
231 if ((REG_READ(dpll_reg) & DPLL_SYNCLOCK_ENABLE) == 0) {
232 DRM_ERROR("Attempting to set DPLL with refclk disabled\n");
233 return -EBUSY;
234 }
235
236 /* Follow the BIOS and write the REF/SFR Register. Hardcoded value */
237 ref_value = 0x68A701;
238
239 cdv_sb_write(dev, SB_REF_SFR(pipe), ref_value);
240
241 /* We don't know what the other fields of these regs are, so
242 * leave them in place.
243 */
244 ret = cdv_sb_read(dev, SB_M(pipe), &m);
245 if (ret)
246 return ret;
247 m &= ~SB_M_DIVIDER_MASK;
248 m |= ((clock->m2) << SB_M_DIVIDER_SHIFT);
249 ret = cdv_sb_write(dev, SB_M(pipe), m);
250 if (ret)
251 return ret;
252
253 ret = cdv_sb_read(dev, SB_N_VCO(pipe), &n_vco);
254 if (ret)
255 return ret;
256
257 /* Follow the BIOS to program the N_DIVIDER REG */
258 n_vco &= 0xFFFF;
259 n_vco |= 0x107;
260 n_vco &= ~(SB_N_VCO_SEL_MASK |
261 SB_N_DIVIDER_MASK |
262 SB_N_CB_TUNE_MASK);
263
264 n_vco |= ((clock->n) << SB_N_DIVIDER_SHIFT);
265
266 if (clock->vco < 2250000) {
267 n_vco |= (2 << SB_N_CB_TUNE_SHIFT);
268 n_vco |= (0 << SB_N_VCO_SEL_SHIFT);
269 } else if (clock->vco < 2750000) {
270 n_vco |= (1 << SB_N_CB_TUNE_SHIFT);
271 n_vco |= (1 << SB_N_VCO_SEL_SHIFT);
272 } else if (clock->vco < 3300000) {
273 n_vco |= (0 << SB_N_CB_TUNE_SHIFT);
274 n_vco |= (2 << SB_N_VCO_SEL_SHIFT);
275 } else {
276 n_vco |= (0 << SB_N_CB_TUNE_SHIFT);
277 n_vco |= (3 << SB_N_VCO_SEL_SHIFT);
278 }
279
280 ret = cdv_sb_write(dev, SB_N_VCO(pipe), n_vco);
281 if (ret)
282 return ret;
283
284 ret = cdv_sb_read(dev, SB_P(pipe), &p);
285 if (ret)
286 return ret;
287 p &= ~(SB_P2_DIVIDER_MASK | SB_P1_DIVIDER_MASK);
288 p |= SET_FIELD(clock->p1, SB_P1_DIVIDER);
289 switch (clock->p2) {
290 case 5:
291 p |= SET_FIELD(SB_P2_5, SB_P2_DIVIDER);
292 break;
293 case 10:
294 p |= SET_FIELD(SB_P2_10, SB_P2_DIVIDER);
295 break;
296 case 14:
297 p |= SET_FIELD(SB_P2_14, SB_P2_DIVIDER);
298 break;
299 case 7:
300 p |= SET_FIELD(SB_P2_7, SB_P2_DIVIDER);
301 break;
302 default:
303 DRM_ERROR("Bad P2 clock: %d\n", clock->p2);
304 return -EINVAL;
305 }
306 ret = cdv_sb_write(dev, SB_P(pipe), p);
307 if (ret)
308 return ret;
309
310 /* always Program the Lane Register for the Pipe A*/
311 if (pipe == 0) {
312 /* Program the Lane0/1 for HDMI B */
313 u32 lane_reg, lane_value;
314
315 lane_reg = PSB_LANE0;
316 cdv_sb_read(dev, lane_reg, &lane_value);
317 lane_value &= ~(LANE_PLL_MASK);
318 lane_value |= LANE_PLL_ENABLE;
319 cdv_sb_write(dev, lane_reg, lane_value);
320
321 lane_reg = PSB_LANE1;
322 cdv_sb_read(dev, lane_reg, &lane_value);
323 lane_value &= ~(LANE_PLL_MASK);
324 lane_value |= LANE_PLL_ENABLE;
325 cdv_sb_write(dev, lane_reg, lane_value);
326
327 /* Program the Lane2/3 for HDMI C */
328 lane_reg = PSB_LANE2;
329 cdv_sb_read(dev, lane_reg, &lane_value);
330 lane_value &= ~(LANE_PLL_MASK);
331 lane_value |= LANE_PLL_ENABLE;
332 cdv_sb_write(dev, lane_reg, lane_value);
333
334 lane_reg = PSB_LANE3;
335 cdv_sb_read(dev, lane_reg, &lane_value);
336 lane_value &= ~(LANE_PLL_MASK);
337 lane_value |= LANE_PLL_ENABLE;
338 cdv_sb_write(dev, lane_reg, lane_value);
339 }
340
341 return 0;
342}
343
344/*
345 * Returns whether any encoder on the specified pipe is of the specified type
346 */
347bool cdv_intel_pipe_has_type(struct drm_crtc *crtc, int type)
348{
349 struct drm_device *dev = crtc->dev;
350 struct drm_mode_config *mode_config = &dev->mode_config;
351 struct drm_connector *l_entry;
352
353 list_for_each_entry(l_entry, &mode_config->connector_list, head) {
354 if (l_entry->encoder && l_entry->encoder->crtc == crtc) {
355 struct psb_intel_encoder *psb_intel_encoder =
356 psb_intel_attached_encoder(l_entry);
357 if (psb_intel_encoder->type == type)
358 return true;
359 }
360 }
361 return false;
362}
363
364static const struct cdv_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc,
365 int refclk)
366{
367 const struct cdv_intel_limit_t *limit;
368 if (cdv_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
369 /*
370 * Now only single-channel LVDS is supported on CDV. If it is
371 * incorrect, please add the dual-channel LVDS.
372 */
373 if (refclk == 96000)
374 limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96];
375 else
376 limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100];
377 } else {
378 if (refclk == 27000)
379 limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_27];
380 else
381 limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_96];
382 }
383 return limit;
384}
385
386/* m1 is reserved as 0 in CDV, n is a ring counter */
387static void cdv_intel_clock(struct drm_device *dev,
388 int refclk, struct cdv_intel_clock_t *clock)
389{
390 clock->m = clock->m2 + 2;
391 clock->p = clock->p1 * clock->p2;
392 clock->vco = (refclk * clock->m) / clock->n;
393 clock->dot = clock->vco / clock->p;
394}
395
396
397#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; }
398static bool cdv_intel_PLL_is_valid(struct drm_crtc *crtc,
399 const struct cdv_intel_limit_t *limit,
400 struct cdv_intel_clock_t *clock)
401{
402 if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
403 INTELPllInvalid("p1 out of range\n");
404 if (clock->p < limit->p.min || limit->p.max < clock->p)
405 INTELPllInvalid("p out of range\n");
406 /* unnecessary to check the range of m(m1/M2)/n again */
407 if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
408 INTELPllInvalid("vco out of range\n");
409 /* XXX: We may need to be checking "Dot clock"
410 * depending on the multiplier, connector, etc.,
411 * rather than just a single range.
412 */
413 if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
414 INTELPllInvalid("dot out of range\n");
415
416 return true;
417}
418
419static bool cdv_intel_find_best_PLL(struct drm_crtc *crtc, int target,
420 int refclk,
421 struct cdv_intel_clock_t *best_clock)
422{
423 struct drm_device *dev = crtc->dev;
424 struct cdv_intel_clock_t clock;
425 const struct cdv_intel_limit_t *limit = cdv_intel_limit(crtc, refclk);
426 int err = target;
427
428
429 if (cdv_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
430 (REG_READ(LVDS) & LVDS_PORT_EN) != 0) {
431 /*
432 * For LVDS, if the panel is on, just rely on its current
433 * settings for dual-channel. We haven't figured out how to
434 * reliably set up different single/dual channel state, if we
435 * even can.
436 */
437 if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
438 LVDS_CLKB_POWER_UP)
439 clock.p2 = limit->p2.p2_fast;
440 else
441 clock.p2 = limit->p2.p2_slow;
442 } else {
443 if (target < limit->p2.dot_limit)
444 clock.p2 = limit->p2.p2_slow;
445 else
446 clock.p2 = limit->p2.p2_fast;
447 }
448
449 memset(best_clock, 0, sizeof(*best_clock));
450 clock.m1 = 0;
451 /* m1 is reserved as 0 in CDV, n is a ring counter.
452 So skip the m1 loop */
453 for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) {
454 for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max;
455 clock.m2++) {
456 for (clock.p1 = limit->p1.min;
457 clock.p1 <= limit->p1.max;
458 clock.p1++) {
459 int this_err;
460
461 cdv_intel_clock(dev, refclk, &clock);
462
463 if (!cdv_intel_PLL_is_valid(crtc,
464 limit, &clock))
465 continue;
466
467 this_err = abs(clock.dot - target);
468 if (this_err < err) {
469 *best_clock = clock;
470 err = this_err;
471 }
472 }
473 }
474 }
475
476 return err != target;
477}
478
479int cdv_intel_pipe_set_base(struct drm_crtc *crtc,
480 int x, int y, struct drm_framebuffer *old_fb)
481{
482 struct drm_device *dev = crtc->dev;
483 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
484 struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
485 int pipe = psb_intel_crtc->pipe;
486 unsigned long start, offset;
487 int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
488 int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
489 int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
490 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
491 u32 dspcntr;
492 int ret = 0;
493
494 if (!gma_power_begin(dev, true))
495 return 0;
496
497 /* no fb bound */
498 if (!crtc->fb) {
499 dev_err(dev->dev, "No FB bound\n");
500 goto psb_intel_pipe_cleaner;
501 }
502
503
504 /* We are displaying this buffer, make sure it is actually loaded
505 into the GTT */
506 ret = psb_gtt_pin(psbfb->gtt);
507 if (ret < 0)
508 goto psb_intel_pipe_set_base_exit;
509 start = psbfb->gtt->offset;
510 offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
511
512 REG_WRITE(dspstride, crtc->fb->pitches[0]);
513
514 dspcntr = REG_READ(dspcntr_reg);
515 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
516
517 switch (crtc->fb->bits_per_pixel) {
518 case 8:
519 dspcntr |= DISPPLANE_8BPP;
520 break;
521 case 16:
522 if (crtc->fb->depth == 15)
523 dspcntr |= DISPPLANE_15_16BPP;
524 else
525 dspcntr |= DISPPLANE_16BPP;
526 break;
527 case 24:
528 case 32:
529 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
530 break;
531 default:
532 dev_err(dev->dev, "Unknown color depth\n");
533 ret = -EINVAL;
534 goto psb_intel_pipe_set_base_exit;
535 }
536 REG_WRITE(dspcntr_reg, dspcntr);
537
538 dev_dbg(dev->dev,
539 "Writing base %08lX %08lX %d %d\n", start, offset, x, y);
540
541 REG_WRITE(dspbase, offset);
542 REG_READ(dspbase);
543 REG_WRITE(dspsurf, start);
544 REG_READ(dspsurf);
545
546psb_intel_pipe_cleaner:
547 /* If there was a previous display we can now unpin it */
548 if (old_fb)
549 psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
550
551psb_intel_pipe_set_base_exit:
552 gma_power_end(dev);
553 return ret;
554}
555
556/**
557 * Sets the power management mode of the pipe and plane.
558 *
559 * This code should probably grow support for turning the cursor off and back
560 * on appropriately at the same time as we're turning the pipe off/on.
561 */
562static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
563{
564 struct drm_device *dev = crtc->dev;
565 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
566 int pipe = psb_intel_crtc->pipe;
567 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
568 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
569 int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
570 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
571 u32 temp;
572 bool enabled;
573
574 /* XXX: When our outputs are all unaware of DPMS modes other than off
575 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
576 */
577 switch (mode) {
578 case DRM_MODE_DPMS_ON:
579 case DRM_MODE_DPMS_STANDBY:
580 case DRM_MODE_DPMS_SUSPEND:
581 /* Enable the DPLL */
582 temp = REG_READ(dpll_reg);
583 if ((temp & DPLL_VCO_ENABLE) == 0) {
584 REG_WRITE(dpll_reg, temp);
585 REG_READ(dpll_reg);
586 /* Wait for the clocks to stabilize. */
587 udelay(150);
588 REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
589 REG_READ(dpll_reg);
590 /* Wait for the clocks to stabilize. */
591 udelay(150);
592 REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
593 REG_READ(dpll_reg);
594 /* Wait for the clocks to stabilize. */
595 udelay(150);
596 }
597
598 /* Jim Bish - switch plan and pipe per scott */
599 /* Enable the plane */
600 temp = REG_READ(dspcntr_reg);
601 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
602 REG_WRITE(dspcntr_reg,
603 temp | DISPLAY_PLANE_ENABLE);
604 /* Flush the plane changes */
605 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
606 }
607
608 udelay(150);
609
610 /* Enable the pipe */
611 temp = REG_READ(pipeconf_reg);
612 if ((temp & PIPEACONF_ENABLE) == 0)
613 REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
614
615 psb_intel_crtc_load_lut(crtc);
616
617 /* Give the overlay scaler a chance to enable
618 * if it's on this pipe */
619 /* psb_intel_crtc_dpms_video(crtc, true); TODO */
620 break;
621 case DRM_MODE_DPMS_OFF:
622 /* Give the overlay scaler a chance to disable
623 * if it's on this pipe */
624 /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
625
626 /* Disable the VGA plane that we never use */
627 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
628
629 /* Jim Bish - changed pipe/plane here as well. */
630
631 /* Wait for vblank for the disable to take effect */
632 cdv_intel_wait_for_vblank(dev);
633
634 /* Next, disable display pipes */
635 temp = REG_READ(pipeconf_reg);
636 if ((temp & PIPEACONF_ENABLE) != 0) {
637 REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
638 REG_READ(pipeconf_reg);
639 }
640
641 /* Wait for vblank for the disable to take effect. */
642 cdv_intel_wait_for_vblank(dev);
643
644 udelay(150);
645
646 /* Disable display plane */
647 temp = REG_READ(dspcntr_reg);
648 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
649 REG_WRITE(dspcntr_reg,
650 temp & ~DISPLAY_PLANE_ENABLE);
651 /* Flush the plane changes */
652 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
653 REG_READ(dspbase_reg);
654 }
655
656 temp = REG_READ(dpll_reg);
657 if ((temp & DPLL_VCO_ENABLE) != 0) {
658 REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
659 REG_READ(dpll_reg);
660 }
661
662 /* Wait for the clocks to turn off. */
663 udelay(150);
664 break;
665 }
666 enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
667 /*Set FIFO Watermarks*/
668 REG_WRITE(DSPARB, 0x3F3E);
669}
670
671static void cdv_intel_crtc_prepare(struct drm_crtc *crtc)
672{
673 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
674 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
675}
676
677static void cdv_intel_crtc_commit(struct drm_crtc *crtc)
678{
679 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
680 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
681}
682
683void cdv_intel_encoder_prepare(struct drm_encoder *encoder)
684{
685 struct drm_encoder_helper_funcs *encoder_funcs =
686 encoder->helper_private;
687 /* lvds has its own version of prepare see cdv_intel_lvds_prepare */
688 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
689}
690
691void cdv_intel_encoder_commit(struct drm_encoder *encoder)
692{
693 struct drm_encoder_helper_funcs *encoder_funcs =
694 encoder->helper_private;
695 /* lvds has its own version of commit see cdv_intel_lvds_commit */
696 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
697}
698
699static bool cdv_intel_crtc_mode_fixup(struct drm_crtc *crtc,
700 struct drm_display_mode *mode,
701 struct drm_display_mode *adjusted_mode)
702{
703 return true;
704}
705
706
707/**
708 * Return the pipe currently connected to the panel fitter,
709 * or -1 if the panel fitter is not present or not in use
710 */
711static int cdv_intel_panel_fitter_pipe(struct drm_device *dev)
712{
713 u32 pfit_control;
714
715 pfit_control = REG_READ(PFIT_CONTROL);
716
717 /* See if the panel fitter is in use */
718 if ((pfit_control & PFIT_ENABLE) == 0)
719 return -1;
720 return (pfit_control >> 29) & 0x3;
721}
722
723static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
724 struct drm_display_mode *mode,
725 struct drm_display_mode *adjusted_mode,
726 int x, int y,
727 struct drm_framebuffer *old_fb)
728{
729 struct drm_device *dev = crtc->dev;
730 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
731 int pipe = psb_intel_crtc->pipe;
732 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
733 int dpll_md_reg = (psb_intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
734 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
735 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
736 int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
737 int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
738 int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
739 int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
740 int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
741 int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
742 int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
743 int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
744 int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
745 int refclk;
746 struct cdv_intel_clock_t clock;
747 u32 dpll = 0, dspcntr, pipeconf;
748 bool ok, is_sdvo = false, is_dvo = false;
749 bool is_crt = false, is_lvds = false, is_tv = false;
750 bool is_hdmi = false;
751 struct drm_mode_config *mode_config = &dev->mode_config;
752 struct drm_connector *connector;
753
754 list_for_each_entry(connector, &mode_config->connector_list, head) {
755 struct psb_intel_encoder *psb_intel_encoder =
756 psb_intel_attached_encoder(connector);
757
758 if (!connector->encoder
759 || connector->encoder->crtc != crtc)
760 continue;
761
762 switch (psb_intel_encoder->type) {
763 case INTEL_OUTPUT_LVDS:
764 is_lvds = true;
765 break;
766 case INTEL_OUTPUT_SDVO:
767 is_sdvo = true;
768 break;
769 case INTEL_OUTPUT_DVO:
770 is_dvo = true;
771 break;
772 case INTEL_OUTPUT_TVOUT:
773 is_tv = true;
774 break;
775 case INTEL_OUTPUT_ANALOG:
776 is_crt = true;
777 break;
778 case INTEL_OUTPUT_HDMI:
779 is_hdmi = true;
780 break;
781 }
782 }
783
784 refclk = 96000;
785
786 /* Hack selection about ref clk for CRT */
787 /* Select 27MHz as the reference clk for HDMI */
788 if (is_crt || is_hdmi)
789 refclk = 27000;
790
791 drm_mode_debug_printmodeline(adjusted_mode);
792
793 ok = cdv_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk,
794 &clock);
795 if (!ok) {
796 dev_err(dev->dev, "Couldn't find PLL settings for mode!\n");
797 return 0;
798 }
799
800 dpll = DPLL_VGA_MODE_DIS;
801 if (is_tv) {
802 /* XXX: just matching BIOS for now */
803/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
804 dpll |= 3;
805 }
806 dpll |= PLL_REF_INPUT_DREFCLK;
807
808 dpll |= DPLL_SYNCLOCK_ENABLE;
809 dpll |= DPLL_VGA_MODE_DIS;
810 if (is_lvds)
811 dpll |= DPLLB_MODE_LVDS;
812 else
813 dpll |= DPLLB_MODE_DAC_SERIAL;
814 /* dpll |= (2 << 11); */
815
816 /* setup pipeconf */
817 pipeconf = REG_READ(pipeconf_reg);
818
819 /* Set up the display plane register */
820 dspcntr = DISPPLANE_GAMMA_ENABLE;
821
822 if (pipe == 0)
823 dspcntr |= DISPPLANE_SEL_PIPE_A;
824 else
825 dspcntr |= DISPPLANE_SEL_PIPE_B;
826
827 dspcntr |= DISPLAY_PLANE_ENABLE;
828 pipeconf |= PIPEACONF_ENABLE;
829
830 REG_WRITE(dpll_reg, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE);
831 REG_READ(dpll_reg);
832
833 cdv_dpll_set_clock_cdv(dev, crtc, &clock);
834
835 udelay(150);
836
837
838 /* The LVDS pin pair needs to be on before the DPLLs are enabled.
839 * This is an exception to the general rule that mode_set doesn't turn
840 * things on.
841 */
842 if (is_lvds) {
843 u32 lvds = REG_READ(LVDS);
844
845 lvds |=
846 LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP |
847 LVDS_PIPEB_SELECT;
848 /* Set the B0-B3 data pairs corresponding to
849 * whether we're going to
850 * set the DPLLs for dual-channel mode or not.
851 */
852 if (clock.p2 == 7)
853 lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
854 else
855 lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
856
857 /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
858 * appropriately here, but we need to look more
859 * thoroughly into how panels behave in the two modes.
860 */
861
862 REG_WRITE(LVDS, lvds);
863 REG_READ(LVDS);
864 }
865
866 dpll |= DPLL_VCO_ENABLE;
867
868 /* Disable the panel fitter if it was on our pipe */
869 if (cdv_intel_panel_fitter_pipe(dev) == pipe)
870 REG_WRITE(PFIT_CONTROL, 0);
871
872 DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
873 drm_mode_debug_printmodeline(mode);
874
875 REG_WRITE(dpll_reg,
876 (REG_READ(dpll_reg) & ~DPLL_LOCK) | DPLL_VCO_ENABLE);
877 REG_READ(dpll_reg);
878 /* Wait for the clocks to stabilize. */
879 udelay(150); /* 42 usec w/o calibration, 110 with. rounded up. */
880
881 if (!(REG_READ(dpll_reg) & DPLL_LOCK)) {
882 dev_err(dev->dev, "Failed to get DPLL lock\n");
883 return -EBUSY;
884 }
885
886 {
887 int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
888 REG_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
889 }
890
891 REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
892 ((adjusted_mode->crtc_htotal - 1) << 16));
893 REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
894 ((adjusted_mode->crtc_hblank_end - 1) << 16));
895 REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
896 ((adjusted_mode->crtc_hsync_end - 1) << 16));
897 REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
898 ((adjusted_mode->crtc_vtotal - 1) << 16));
899 REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
900 ((adjusted_mode->crtc_vblank_end - 1) << 16));
901 REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
902 ((adjusted_mode->crtc_vsync_end - 1) << 16));
903 /* pipesrc and dspsize control the size that is scaled from,
904 * which should always be the user's requested size.
905 */
906 REG_WRITE(dspsize_reg,
907 ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
908 REG_WRITE(dsppos_reg, 0);
909 REG_WRITE(pipesrc_reg,
910 ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
911 REG_WRITE(pipeconf_reg, pipeconf);
912 REG_READ(pipeconf_reg);
913
914 cdv_intel_wait_for_vblank(dev);
915
916 REG_WRITE(dspcntr_reg, dspcntr);
917
918 /* Flush the plane changes */
919 {
920 struct drm_crtc_helper_funcs *crtc_funcs =
921 crtc->helper_private;
922 crtc_funcs->mode_set_base(crtc, x, y, old_fb);
923 }
924
925 cdv_intel_wait_for_vblank(dev);
926
927 return 0;
928}
929
930/** Loads the palette/gamma unit for the CRTC with the prepared values */
931void cdv_intel_crtc_load_lut(struct drm_crtc *crtc)
932{
933 struct drm_device *dev = crtc->dev;
934 struct drm_psb_private *dev_priv =
935 (struct drm_psb_private *)dev->dev_private;
936 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
937 int palreg = PALETTE_A;
938 int i;
939
940 /* The clocks have to be on to load the palette. */
941 if (!crtc->enabled)
942 return;
943
944 switch (psb_intel_crtc->pipe) {
945 case 0:
946 break;
947 case 1:
948 palreg = PALETTE_B;
949 break;
950 case 2:
951 palreg = PALETTE_C;
952 break;
953 default:
954 dev_err(dev->dev, "Illegal Pipe Number.\n");
955 return;
956 }
957
958 if (gma_power_begin(dev, false)) {
959 for (i = 0; i < 256; i++) {
960 REG_WRITE(palreg + 4 * i,
961 ((psb_intel_crtc->lut_r[i] +
962 psb_intel_crtc->lut_adj[i]) << 16) |
963 ((psb_intel_crtc->lut_g[i] +
964 psb_intel_crtc->lut_adj[i]) << 8) |
965 (psb_intel_crtc->lut_b[i] +
966 psb_intel_crtc->lut_adj[i]));
967 }
968 gma_power_end(dev);
969 } else {
970 for (i = 0; i < 256; i++) {
971 dev_priv->save_palette_a[i] =
972 ((psb_intel_crtc->lut_r[i] +
973 psb_intel_crtc->lut_adj[i]) << 16) |
974 ((psb_intel_crtc->lut_g[i] +
975 psb_intel_crtc->lut_adj[i]) << 8) |
976 (psb_intel_crtc->lut_b[i] +
977 psb_intel_crtc->lut_adj[i]);
978 }
979
980 }
981}
982
983/**
984 * Save HW states of giving crtc
985 */
986static void cdv_intel_crtc_save(struct drm_crtc *crtc)
987{
988 struct drm_device *dev = crtc->dev;
989 /* struct drm_psb_private *dev_priv =
990 (struct drm_psb_private *)dev->dev_private; */
991 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
992 struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
993 int pipeA = (psb_intel_crtc->pipe == 0);
994 uint32_t paletteReg;
995 int i;
996
997 if (!crtc_state) {
998 dev_dbg(dev->dev, "No CRTC state found\n");
999 return;
1000 }
1001
1002 crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR);
1003 crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF);
1004 crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC);
1005 crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0);
1006 crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1);
1007 crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B);
1008 crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B);
1009 crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B);
1010 crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B);
1011 crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B);
1012 crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B);
1013 crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B);
1014 crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE);
1015
1016 /*NOTE: DSPSIZE DSPPOS only for psb*/
1017 crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE);
1018 crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS);
1019
1020 crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE);
1021
1022 DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
1023 crtc_state->saveDSPCNTR,
1024 crtc_state->savePIPECONF,
1025 crtc_state->savePIPESRC,
1026 crtc_state->saveFP0,
1027 crtc_state->saveFP1,
1028 crtc_state->saveDPLL,
1029 crtc_state->saveHTOTAL,
1030 crtc_state->saveHBLANK,
1031 crtc_state->saveHSYNC,
1032 crtc_state->saveVTOTAL,
1033 crtc_state->saveVBLANK,
1034 crtc_state->saveVSYNC,
1035 crtc_state->saveDSPSTRIDE,
1036 crtc_state->saveDSPSIZE,
1037 crtc_state->saveDSPPOS,
1038 crtc_state->saveDSPBASE
1039 );
1040
1041 paletteReg = pipeA ? PALETTE_A : PALETTE_B;
1042 for (i = 0; i < 256; ++i)
1043 crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2));
1044}
1045
1046/**
1047 * Restore HW states of giving crtc
1048 */
1049static void cdv_intel_crtc_restore(struct drm_crtc *crtc)
1050{
1051 struct drm_device *dev = crtc->dev;
1052 /* struct drm_psb_private * dev_priv =
1053 (struct drm_psb_private *)dev->dev_private; */
1054 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1055 struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
1056 /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */
1057 int pipeA = (psb_intel_crtc->pipe == 0);
1058 uint32_t paletteReg;
1059 int i;
1060
1061 if (!crtc_state) {
1062 dev_dbg(dev->dev, "No crtc state\n");
1063 return;
1064 }
1065
1066 DRM_DEBUG(
1067 "current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
1068 REG_READ(pipeA ? DSPACNTR : DSPBCNTR),
1069 REG_READ(pipeA ? PIPEACONF : PIPEBCONF),
1070 REG_READ(pipeA ? PIPEASRC : PIPEBSRC),
1071 REG_READ(pipeA ? FPA0 : FPB0),
1072 REG_READ(pipeA ? FPA1 : FPB1),
1073 REG_READ(pipeA ? DPLL_A : DPLL_B),
1074 REG_READ(pipeA ? HTOTAL_A : HTOTAL_B),
1075 REG_READ(pipeA ? HBLANK_A : HBLANK_B),
1076 REG_READ(pipeA ? HSYNC_A : HSYNC_B),
1077 REG_READ(pipeA ? VTOTAL_A : VTOTAL_B),
1078 REG_READ(pipeA ? VBLANK_A : VBLANK_B),
1079 REG_READ(pipeA ? VSYNC_A : VSYNC_B),
1080 REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE),
1081 REG_READ(pipeA ? DSPASIZE : DSPBSIZE),
1082 REG_READ(pipeA ? DSPAPOS : DSPBPOS),
1083 REG_READ(pipeA ? DSPABASE : DSPBBASE)
1084 );
1085
1086 DRM_DEBUG(
1087 "saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
1088 crtc_state->saveDSPCNTR,
1089 crtc_state->savePIPECONF,
1090 crtc_state->savePIPESRC,
1091 crtc_state->saveFP0,
1092 crtc_state->saveFP1,
1093 crtc_state->saveDPLL,
1094 crtc_state->saveHTOTAL,
1095 crtc_state->saveHBLANK,
1096 crtc_state->saveHSYNC,
1097 crtc_state->saveVTOTAL,
1098 crtc_state->saveVBLANK,
1099 crtc_state->saveVSYNC,
1100 crtc_state->saveDSPSTRIDE,
1101 crtc_state->saveDSPSIZE,
1102 crtc_state->saveDSPPOS,
1103 crtc_state->saveDSPBASE
1104 );
1105
1106
1107 if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) {
1108 REG_WRITE(pipeA ? DPLL_A : DPLL_B,
1109 crtc_state->saveDPLL & ~DPLL_VCO_ENABLE);
1110 REG_READ(pipeA ? DPLL_A : DPLL_B);
1111 DRM_DEBUG("write dpll: %x\n",
1112 REG_READ(pipeA ? DPLL_A : DPLL_B));
1113 udelay(150);
1114 }
1115
1116 REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0);
1117 REG_READ(pipeA ? FPA0 : FPB0);
1118
1119 REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1);
1120 REG_READ(pipeA ? FPA1 : FPB1);
1121
1122 REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL);
1123 REG_READ(pipeA ? DPLL_A : DPLL_B);
1124 udelay(150);
1125
1126 REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL);
1127 REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK);
1128 REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC);
1129 REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL);
1130 REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK);
1131 REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC);
1132 REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE);
1133
1134 REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE);
1135 REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS);
1136
1137 REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC);
1138 REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
1139 REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF);
1140
1141 cdv_intel_wait_for_vblank(dev);
1142
1143 REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR);
1144 REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
1145
1146 cdv_intel_wait_for_vblank(dev);
1147
1148 paletteReg = pipeA ? PALETTE_A : PALETTE_B;
1149 for (i = 0; i < 256; ++i)
1150 REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]);
1151}
1152
1153static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
1154 struct drm_file *file_priv,
1155 uint32_t handle,
1156 uint32_t width, uint32_t height)
1157{
1158 struct drm_device *dev = crtc->dev;
1159 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1160 int pipe = psb_intel_crtc->pipe;
1161 uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
1162 uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
1163 uint32_t temp;
1164 size_t addr = 0;
1165 struct gtt_range *gt;
1166 struct drm_gem_object *obj;
1167 int ret;
1168
1169 /* if we want to turn of the cursor ignore width and height */
1170 if (!handle) {
1171 /* turn off the cursor */
1172 temp = CURSOR_MODE_DISABLE;
1173
1174 if (gma_power_begin(dev, false)) {
1175 REG_WRITE(control, temp);
1176 REG_WRITE(base, 0);
1177 gma_power_end(dev);
1178 }
1179
1180 /* unpin the old GEM object */
1181 if (psb_intel_crtc->cursor_obj) {
1182 gt = container_of(psb_intel_crtc->cursor_obj,
1183 struct gtt_range, gem);
1184 psb_gtt_unpin(gt);
1185 drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
1186 psb_intel_crtc->cursor_obj = NULL;
1187 }
1188
1189 return 0;
1190 }
1191
1192 /* Currently we only support 64x64 cursors */
1193 if (width != 64 || height != 64) {
1194 dev_dbg(dev->dev, "we currently only support 64x64 cursors\n");
1195 return -EINVAL;
1196 }
1197
1198 obj = drm_gem_object_lookup(dev, file_priv, handle);
1199 if (!obj)
1200 return -ENOENT;
1201
1202 if (obj->size < width * height * 4) {
1203 dev_dbg(dev->dev, "buffer is to small\n");
1204 return -ENOMEM;
1205 }
1206
1207 gt = container_of(obj, struct gtt_range, gem);
1208
1209 /* Pin the memory into the GTT */
1210 ret = psb_gtt_pin(gt);
1211 if (ret) {
1212 dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
1213 return ret;
1214 }
1215
1216 addr = gt->offset; /* Or resource.start ??? */
1217
1218 psb_intel_crtc->cursor_addr = addr;
1219
1220 temp = 0;
1221 /* set the pipe for the cursor */
1222 temp |= (pipe << 28);
1223 temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
1224
1225 if (gma_power_begin(dev, false)) {
1226 REG_WRITE(control, temp);
1227 REG_WRITE(base, addr);
1228 gma_power_end(dev);
1229 }
1230
1231 /* unpin the old GEM object */
1232 if (psb_intel_crtc->cursor_obj) {
1233 gt = container_of(psb_intel_crtc->cursor_obj,
1234 struct gtt_range, gem);
1235 psb_gtt_unpin(gt);
1236 drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
1237 psb_intel_crtc->cursor_obj = obj;
1238 }
1239 return 0;
1240}
1241
1242static int cdv_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
1243{
1244 struct drm_device *dev = crtc->dev;
1245 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1246 int pipe = psb_intel_crtc->pipe;
1247 uint32_t temp = 0;
1248 uint32_t adder;
1249
1250
1251 if (x < 0) {
1252 temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
1253 x = -x;
1254 }
1255 if (y < 0) {
1256 temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
1257 y = -y;
1258 }
1259
1260 temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
1261 temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
1262
1263 adder = psb_intel_crtc->cursor_addr;
1264
1265 if (gma_power_begin(dev, false)) {
1266 REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
1267 REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
1268 gma_power_end(dev);
1269 }
1270 return 0;
1271}
1272
1273static void cdv_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
1274 u16 *green, u16 *blue, uint32_t start, uint32_t size)
1275{
1276 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1277 int i;
1278 int end = (start + size > 256) ? 256 : start + size;
1279
1280 for (i = start; i < end; i++) {
1281 psb_intel_crtc->lut_r[i] = red[i] >> 8;
1282 psb_intel_crtc->lut_g[i] = green[i] >> 8;
1283 psb_intel_crtc->lut_b[i] = blue[i] >> 8;
1284 }
1285
1286 cdv_intel_crtc_load_lut(crtc);
1287}
1288
1289static int cdv_crtc_set_config(struct drm_mode_set *set)
1290{
1291 int ret = 0;
1292 struct drm_device *dev = set->crtc->dev;
1293 struct drm_psb_private *dev_priv = dev->dev_private;
1294
1295 if (!dev_priv->rpm_enabled)
1296 return drm_crtc_helper_set_config(set);
1297
1298 pm_runtime_forbid(&dev->pdev->dev);
1299
1300 ret = drm_crtc_helper_set_config(set);
1301
1302 pm_runtime_allow(&dev->pdev->dev);
1303
1304 return ret;
1305}
1306
1307/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
1308
1309/* FIXME: why are we using this, should it be cdv_ in this tree ? */
1310
1311static void i8xx_clock(int refclk, struct cdv_intel_clock_t *clock)
1312{
1313 clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
1314 clock->p = clock->p1 * clock->p2;
1315 clock->vco = refclk * clock->m / (clock->n + 2);
1316 clock->dot = clock->vco / clock->p;
1317}
1318
1319/* Returns the clock of the currently programmed mode of the given pipe. */
1320static int cdv_intel_crtc_clock_get(struct drm_device *dev,
1321 struct drm_crtc *crtc)
1322{
1323 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1324 int pipe = psb_intel_crtc->pipe;
1325 u32 dpll;
1326 u32 fp;
1327 struct cdv_intel_clock_t clock;
1328 bool is_lvds;
1329 struct drm_psb_private *dev_priv = dev->dev_private;
1330
1331 if (gma_power_begin(dev, false)) {
1332 dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B);
1333 if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
1334 fp = REG_READ((pipe == 0) ? FPA0 : FPB0);
1335 else
1336 fp = REG_READ((pipe == 0) ? FPA1 : FPB1);
1337 is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN);
1338 gma_power_end(dev);
1339 } else {
1340 dpll = (pipe == 0) ?
1341 dev_priv->saveDPLL_A : dev_priv->saveDPLL_B;
1342
1343 if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
1344 fp = (pipe == 0) ?
1345 dev_priv->saveFPA0 :
1346 dev_priv->saveFPB0;
1347 else
1348 fp = (pipe == 0) ?
1349 dev_priv->saveFPA1 :
1350 dev_priv->saveFPB1;
1351
1352 is_lvds = (pipe == 1) && (dev_priv->saveLVDS & LVDS_PORT_EN);
1353 }
1354
1355 clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
1356 clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
1357 clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
1358
1359 if (is_lvds) {
1360 clock.p1 =
1361 ffs((dpll &
1362 DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
1363 DPLL_FPA01_P1_POST_DIV_SHIFT);
1364 if (clock.p1 == 0) {
1365 clock.p1 = 4;
1366 dev_err(dev->dev, "PLL %d\n", dpll);
1367 }
1368 clock.p2 = 14;
1369
1370 if ((dpll & PLL_REF_INPUT_MASK) ==
1371 PLLB_REF_INPUT_SPREADSPECTRUMIN) {
1372 /* XXX: might not be 66MHz */
1373 i8xx_clock(66000, &clock);
1374 } else
1375 i8xx_clock(48000, &clock);
1376 } else {
1377 if (dpll & PLL_P1_DIVIDE_BY_TWO)
1378 clock.p1 = 2;
1379 else {
1380 clock.p1 =
1381 ((dpll &
1382 DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
1383 DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
1384 }
1385 if (dpll & PLL_P2_DIVIDE_BY_4)
1386 clock.p2 = 4;
1387 else
1388 clock.p2 = 2;
1389
1390 i8xx_clock(48000, &clock);
1391 }
1392
1393 /* XXX: It would be nice to validate the clocks, but we can't reuse
1394 * i830PllIsValid() because it relies on the xf86_config connector
1395 * configuration being accurate, which it isn't necessarily.
1396 */
1397
1398 return clock.dot;
1399}
1400
1401/** Returns the currently programmed mode of the given pipe. */
1402struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev,
1403 struct drm_crtc *crtc)
1404{
1405 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1406 int pipe = psb_intel_crtc->pipe;
1407 struct drm_display_mode *mode;
1408 int htot;
1409 int hsync;
1410 int vtot;
1411 int vsync;
1412 struct drm_psb_private *dev_priv = dev->dev_private;
1413
1414 if (gma_power_begin(dev, false)) {
1415 htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
1416 hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
1417 vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
1418 vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
1419 gma_power_end(dev);
1420 } else {
1421 htot = (pipe == 0) ?
1422 dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B;
1423 hsync = (pipe == 0) ?
1424 dev_priv->saveHSYNC_A : dev_priv->saveHSYNC_B;
1425 vtot = (pipe == 0) ?
1426 dev_priv->saveVTOTAL_A : dev_priv->saveVTOTAL_B;
1427 vsync = (pipe == 0) ?
1428 dev_priv->saveVSYNC_A : dev_priv->saveVSYNC_B;
1429 }
1430
1431 mode = kzalloc(sizeof(*mode), GFP_KERNEL);
1432 if (!mode)
1433 return NULL;
1434
1435 mode->clock = cdv_intel_crtc_clock_get(dev, crtc);
1436 mode->hdisplay = (htot & 0xffff) + 1;
1437 mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
1438 mode->hsync_start = (hsync & 0xffff) + 1;
1439 mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
1440 mode->vdisplay = (vtot & 0xffff) + 1;
1441 mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
1442 mode->vsync_start = (vsync & 0xffff) + 1;
1443 mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
1444
1445 drm_mode_set_name(mode);
1446 drm_mode_set_crtcinfo(mode, 0);
1447
1448 return mode;
1449}
1450
1451static void cdv_intel_crtc_destroy(struct drm_crtc *crtc)
1452{
1453 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1454
1455 kfree(psb_intel_crtc->crtc_state);
1456 drm_crtc_cleanup(crtc);
1457 kfree(psb_intel_crtc);
1458}
1459
1460const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
1461 .dpms = cdv_intel_crtc_dpms,
1462 .mode_fixup = cdv_intel_crtc_mode_fixup,
1463 .mode_set = cdv_intel_crtc_mode_set,
1464 .mode_set_base = cdv_intel_pipe_set_base,
1465 .prepare = cdv_intel_crtc_prepare,
1466 .commit = cdv_intel_crtc_commit,
1467};
1468
1469const struct drm_crtc_funcs cdv_intel_crtc_funcs = {
1470 .save = cdv_intel_crtc_save,
1471 .restore = cdv_intel_crtc_restore,
1472 .cursor_set = cdv_intel_crtc_cursor_set,
1473 .cursor_move = cdv_intel_crtc_cursor_move,
1474 .gamma_set = cdv_intel_crtc_gamma_set,
1475 .set_config = cdv_crtc_set_config,
1476 .destroy = cdv_intel_crtc_destroy,
1477};
1478
1479/*
1480 * Set the default value of cursor control and base register
1481 * to zero. This is a workaround for h/w defect on oaktrail
1482 */
1483void cdv_intel_cursor_init(struct drm_device *dev, int pipe)
1484{
1485 uint32_t control;
1486 uint32_t base;
1487
1488 switch (pipe) {
1489 case 0:
1490 control = CURACNTR;
1491 base = CURABASE;
1492 break;
1493 case 1:
1494 control = CURBCNTR;
1495 base = CURBBASE;
1496 break;
1497 case 2:
1498 control = CURCCNTR;
1499 base = CURCBASE;
1500 break;
1501 default:
1502 return;
1503 }
1504
1505 REG_WRITE(control, 0);
1506 REG_WRITE(base, 0);
1507}
1508
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
new file mode 100644
index 00000000000..50d7cfb5166
--- /dev/null
+++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
@@ -0,0 +1,394 @@
1/*
2 * Copyright © 2006-2011 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 * jim liu <jim.liu@intel.com>
25 *
26 * FIXME:
27 * We should probably make this generic and share it with Medfield
28 */
29
30#include <drm/drmP.h>
31#include <drm/drm.h>
32#include <drm/drm_crtc.h>
33#include <drm/drm_edid.h>
34#include "psb_intel_drv.h"
35#include "psb_drv.h"
36#include "psb_intel_reg.h"
37#include <linux/pm_runtime.h>
38
39/* hdmi control bits */
40#define HDMI_NULL_PACKETS_DURING_VSYNC (1 << 9)
41#define HDMI_BORDER_ENABLE (1 << 7)
42#define HDMI_AUDIO_ENABLE (1 << 6)
43#define HDMI_VSYNC_ACTIVE_HIGH (1 << 4)
44#define HDMI_HSYNC_ACTIVE_HIGH (1 << 3)
45/* hdmi-b control bits */
46#define HDMIB_PIPE_B_SELECT (1 << 30)
47
48
49struct mid_intel_hdmi_priv {
50 u32 hdmi_reg;
51 u32 save_HDMIB;
52 bool has_hdmi_sink;
53 bool has_hdmi_audio;
54 /* Should set this when detect hotplug */
55 bool hdmi_device_connected;
56 struct mdfld_hdmi_i2c *i2c_bus;
57 struct i2c_adapter *hdmi_i2c_adapter; /* for control functions */
58 struct drm_device *dev;
59};
60
61static void cdv_hdmi_mode_set(struct drm_encoder *encoder,
62 struct drm_display_mode *mode,
63 struct drm_display_mode *adjusted_mode)
64{
65 struct drm_device *dev = encoder->dev;
66 struct psb_intel_encoder *psb_intel_encoder = to_psb_intel_encoder(encoder);
67 struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
68 u32 hdmib;
69 struct drm_crtc *crtc = encoder->crtc;
70 struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc);
71
72 hdmib = (2 << 10);
73
74 if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
75 hdmib |= HDMI_VSYNC_ACTIVE_HIGH;
76 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
77 hdmib |= HDMI_HSYNC_ACTIVE_HIGH;
78
79 if (intel_crtc->pipe == 1)
80 hdmib |= HDMIB_PIPE_B_SELECT;
81
82 if (hdmi_priv->has_hdmi_audio) {
83 hdmib |= HDMI_AUDIO_ENABLE;
84 hdmib |= HDMI_NULL_PACKETS_DURING_VSYNC;
85 }
86
87 REG_WRITE(hdmi_priv->hdmi_reg, hdmib);
88 REG_READ(hdmi_priv->hdmi_reg);
89}
90
91static bool cdv_hdmi_mode_fixup(struct drm_encoder *encoder,
92 struct drm_display_mode *mode,
93 struct drm_display_mode *adjusted_mode)
94{
95 return true;
96}
97
98static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode)
99{
100 struct drm_device *dev = encoder->dev;
101 struct psb_intel_encoder *psb_intel_encoder =
102 to_psb_intel_encoder(encoder);
103 struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
104 u32 hdmib;
105
106 hdmib = REG_READ(hdmi_priv->hdmi_reg);
107
108 if (mode != DRM_MODE_DPMS_ON)
109 REG_WRITE(hdmi_priv->hdmi_reg, hdmib & ~HDMIB_PORT_EN);
110 else
111 REG_WRITE(hdmi_priv->hdmi_reg, hdmib | HDMIB_PORT_EN);
112 REG_READ(hdmi_priv->hdmi_reg);
113}
114
115static void cdv_hdmi_save(struct drm_connector *connector)
116{
117 struct drm_device *dev = connector->dev;
118 struct psb_intel_encoder *psb_intel_encoder =
119 psb_intel_attached_encoder(connector);
120 struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
121
122 hdmi_priv->save_HDMIB = REG_READ(hdmi_priv->hdmi_reg);
123}
124
125static void cdv_hdmi_restore(struct drm_connector *connector)
126{
127 struct drm_device *dev = connector->dev;
128 struct psb_intel_encoder *psb_intel_encoder =
129 psb_intel_attached_encoder(connector);
130 struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
131
132 REG_WRITE(hdmi_priv->hdmi_reg, hdmi_priv->save_HDMIB);
133 REG_READ(hdmi_priv->hdmi_reg);
134}
135
136static enum drm_connector_status cdv_hdmi_detect(
137 struct drm_connector *connector, bool force)
138{
139 struct psb_intel_encoder *psb_intel_encoder =
140 psb_intel_attached_encoder(connector);
141 struct psb_intel_connector *psb_intel_connector =
142 to_psb_intel_connector(connector);
143 struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
144 struct edid *edid = NULL;
145 enum drm_connector_status status = connector_status_disconnected;
146
147 edid = drm_get_edid(connector, &psb_intel_encoder->i2c_bus->adapter);
148
149 hdmi_priv->has_hdmi_sink = false;
150 hdmi_priv->has_hdmi_audio = false;
151 if (edid) {
152 if (edid->input & DRM_EDID_INPUT_DIGITAL) {
153 status = connector_status_connected;
154 hdmi_priv->has_hdmi_sink =
155 drm_detect_hdmi_monitor(edid);
156 hdmi_priv->has_hdmi_audio =
157 drm_detect_monitor_audio(edid);
158 }
159
160 psb_intel_connector->base.display_info.raw_edid = NULL;
161 kfree(edid);
162 }
163 return status;
164}
165
166static int cdv_hdmi_set_property(struct drm_connector *connector,
167 struct drm_property *property,
168 uint64_t value)
169{
170 struct drm_encoder *encoder = connector->encoder;
171
172 if (!strcmp(property->name, "scaling mode") && encoder) {
173 struct psb_intel_crtc *crtc = to_psb_intel_crtc(encoder->crtc);
174 bool centre;
175 uint64_t curValue;
176
177 if (!crtc)
178 return -1;
179
180 switch (value) {
181 case DRM_MODE_SCALE_FULLSCREEN:
182 break;
183 case DRM_MODE_SCALE_NO_SCALE:
184 break;
185 case DRM_MODE_SCALE_ASPECT:
186 break;
187 default:
188 return -1;
189 }
190
191 if (drm_connector_property_get_value(connector,
192 property, &curValue))
193 return -1;
194
195 if (curValue == value)
196 return 0;
197
198 if (drm_connector_property_set_value(connector,
199 property, value))
200 return -1;
201
202 centre = (curValue == DRM_MODE_SCALE_NO_SCALE) ||
203 (value == DRM_MODE_SCALE_NO_SCALE);
204
205 if (crtc->saved_mode.hdisplay != 0 &&
206 crtc->saved_mode.vdisplay != 0) {
207 if (centre) {
208 if (!drm_crtc_helper_set_mode(encoder->crtc, &crtc->saved_mode,
209 encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb))
210 return -1;
211 } else {
212 struct drm_encoder_helper_funcs *helpers
213 = encoder->helper_private;
214 helpers->mode_set(encoder, &crtc->saved_mode,
215 &crtc->saved_adjusted_mode);
216 }
217 }
218 }
219 return 0;
220}
221
222/*
223 * Return the list of HDMI DDC modes if available.
224 */
225static int cdv_hdmi_get_modes(struct drm_connector *connector)
226{
227 struct psb_intel_encoder *psb_intel_encoder =
228 psb_intel_attached_encoder(connector);
229 struct edid *edid = NULL;
230 int ret = 0;
231
232 edid = drm_get_edid(connector, &psb_intel_encoder->i2c_bus->adapter);
233 if (edid) {
234 drm_mode_connector_update_edid_property(connector, edid);
235 ret = drm_add_edid_modes(connector, edid);
236 kfree(edid);
237 }
238 return ret;
239}
240
241static int cdv_hdmi_mode_valid(struct drm_connector *connector,
242 struct drm_display_mode *mode)
243{
244
245 if (mode->clock > 165000)
246 return MODE_CLOCK_HIGH;
247 if (mode->clock < 20000)
248 return MODE_CLOCK_HIGH;
249
250 /* just in case */
251 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
252 return MODE_NO_DBLESCAN;
253
254 /* just in case */
255 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
256 return MODE_NO_INTERLACE;
257
258 /*
259 * FIXME: for now we limit the size to 1680x1050 on CDV, otherwise it
260 * will go beyond the stolen memory size allocated to the framebuffer
261 */
262 if (mode->hdisplay > 1680)
263 return MODE_PANEL;
264 if (mode->vdisplay > 1050)
265 return MODE_PANEL;
266 return MODE_OK;
267}
268
269static void cdv_hdmi_destroy(struct drm_connector *connector)
270{
271 struct psb_intel_encoder *psb_intel_encoder =
272 psb_intel_attached_encoder(connector);
273
274 if (psb_intel_encoder->i2c_bus)
275 psb_intel_i2c_destroy(psb_intel_encoder->i2c_bus);
276 drm_sysfs_connector_remove(connector);
277 drm_connector_cleanup(connector);
278 kfree(connector);
279}
280
281static const struct drm_encoder_helper_funcs cdv_hdmi_helper_funcs = {
282 .dpms = cdv_hdmi_dpms,
283 .mode_fixup = cdv_hdmi_mode_fixup,
284 .prepare = psb_intel_encoder_prepare,
285 .mode_set = cdv_hdmi_mode_set,
286 .commit = psb_intel_encoder_commit,
287};
288
289static const struct drm_connector_helper_funcs
290 cdv_hdmi_connector_helper_funcs = {
291 .get_modes = cdv_hdmi_get_modes,
292 .mode_valid = cdv_hdmi_mode_valid,
293 .best_encoder = psb_intel_best_encoder,
294};
295
296static const struct drm_connector_funcs cdv_hdmi_connector_funcs = {
297 .dpms = drm_helper_connector_dpms,
298 .save = cdv_hdmi_save,
299 .restore = cdv_hdmi_restore,
300 .detect = cdv_hdmi_detect,
301 .fill_modes = drm_helper_probe_single_connector_modes,
302 .set_property = cdv_hdmi_set_property,
303 .destroy = cdv_hdmi_destroy,
304};
305
306void cdv_hdmi_init(struct drm_device *dev,
307 struct psb_intel_mode_device *mode_dev, int reg)
308{
309 struct psb_intel_encoder *psb_intel_encoder;
310 struct psb_intel_connector *psb_intel_connector;
311 struct drm_connector *connector;
312 struct drm_encoder *encoder;
313 struct mid_intel_hdmi_priv *hdmi_priv;
314 int ddc_bus;
315
316 psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder),
317 GFP_KERNEL);
318
319 if (!psb_intel_encoder)
320 return;
321
322 psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector),
323 GFP_KERNEL);
324
325 if (!psb_intel_connector)
326 goto err_connector;
327
328 hdmi_priv = kzalloc(sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL);
329
330 if (!hdmi_priv)
331 goto err_priv;
332
333 connector = &psb_intel_connector->base;
334 encoder = &psb_intel_encoder->base;
335 drm_connector_init(dev, connector,
336 &cdv_hdmi_connector_funcs,
337 DRM_MODE_CONNECTOR_DVID);
338
339 drm_encoder_init(dev, encoder, &psb_intel_lvds_enc_funcs,
340 DRM_MODE_ENCODER_TMDS);
341
342 psb_intel_connector_attach_encoder(psb_intel_connector,
343 psb_intel_encoder);
344 psb_intel_encoder->type = INTEL_OUTPUT_HDMI;
345 hdmi_priv->hdmi_reg = reg;
346 hdmi_priv->has_hdmi_sink = false;
347 psb_intel_encoder->dev_priv = hdmi_priv;
348
349 drm_encoder_helper_add(encoder, &cdv_hdmi_helper_funcs);
350 drm_connector_helper_add(connector,
351 &cdv_hdmi_connector_helper_funcs);
352 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
353 connector->interlace_allowed = false;
354 connector->doublescan_allowed = false;
355
356 drm_connector_attach_property(connector,
357 dev->mode_config.scaling_mode_property,
358 DRM_MODE_SCALE_FULLSCREEN);
359
360 switch (reg) {
361 case SDVOB:
362 ddc_bus = GPIOE;
363 break;
364 case SDVOC:
365 ddc_bus = GPIOD;
366 break;
367 default:
368 DRM_ERROR("unknown reg 0x%x for HDMI\n", reg);
369 goto failed_ddc;
370 break;
371 }
372
373 psb_intel_encoder->i2c_bus = psb_intel_i2c_create(dev,
374 ddc_bus, (reg == SDVOB) ? "HDMIB" : "HDMIC");
375
376 if (!psb_intel_encoder->i2c_bus) {
377 dev_err(dev->dev, "No ddc adapter available!\n");
378 goto failed_ddc;
379 }
380
381 hdmi_priv->hdmi_i2c_adapter =
382 &(psb_intel_encoder->i2c_bus->adapter);
383 hdmi_priv->dev = dev;
384 drm_sysfs_connector_add(connector);
385 return;
386
387failed_ddc:
388 drm_encoder_cleanup(encoder);
389 drm_connector_cleanup(connector);
390err_priv:
391 kfree(psb_intel_connector);
392err_connector:
393 kfree(psb_intel_encoder);
394}
diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
new file mode 100644
index 00000000000..50e744be985
--- /dev/null
+++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -0,0 +1,732 @@
1/*
2 * Copyright © 2006-2011 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 <linux/dmi.h>
25#include <drm/drmP.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#include "cdv_device.h"
34
35/**
36 * LVDS I2C backlight control macros
37 */
38#define BRIGHTNESS_MAX_LEVEL 100
39#define BRIGHTNESS_MASK 0xFF
40#define BLC_I2C_TYPE 0x01
41#define BLC_PWM_TYPT 0x02
42
43#define BLC_POLARITY_NORMAL 0
44#define BLC_POLARITY_INVERSE 1
45
46#define PSB_BLC_MAX_PWM_REG_FREQ (0xFFFE)
47#define PSB_BLC_MIN_PWM_REG_FREQ (0x2)
48#define PSB_BLC_PWM_PRECISION_FACTOR (10)
49#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16)
50#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
51
52struct cdv_intel_lvds_priv {
53 /**
54 * Saved LVDO output states
55 */
56 uint32_t savePP_ON;
57 uint32_t savePP_OFF;
58 uint32_t saveLVDS;
59 uint32_t savePP_CONTROL;
60 uint32_t savePP_CYCLE;
61 uint32_t savePFIT_CONTROL;
62 uint32_t savePFIT_PGM_RATIOS;
63 uint32_t saveBLC_PWM_CTL;
64};
65
66/*
67 * Returns the maximum level of the backlight duty cycle field.
68 */
69static u32 cdv_intel_lvds_get_max_backlight(struct drm_device *dev)
70{
71 struct drm_psb_private *dev_priv = dev->dev_private;
72 u32 retval;
73
74 if (gma_power_begin(dev, false)) {
75 retval = ((REG_READ(BLC_PWM_CTL) &
76 BACKLIGHT_MODULATION_FREQ_MASK) >>
77 BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
78
79 gma_power_end(dev);
80 } else
81 retval = ((dev_priv->saveBLC_PWM_CTL &
82 BACKLIGHT_MODULATION_FREQ_MASK) >>
83 BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
84
85 return retval;
86}
87
88/*
89 * Set LVDS backlight level by I2C command
90 */
91static int cdv_lvds_i2c_set_brightness(struct drm_device *dev,
92 unsigned int level)
93{
94 struct drm_psb_private *dev_priv = dev->dev_private;
95 struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus;
96 u8 out_buf[2];
97 unsigned int blc_i2c_brightness;
98
99 struct i2c_msg msgs[] = {
100 {
101 .addr = lvds_i2c_bus->slave_addr,
102 .flags = 0,
103 .len = 2,
104 .buf = out_buf,
105 }
106 };
107
108 blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level *
109 BRIGHTNESS_MASK /
110 BRIGHTNESS_MAX_LEVEL);
111
112 if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
113 blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness;
114
115 out_buf[0] = dev_priv->lvds_bl->brightnesscmd;
116 out_buf[1] = (u8)blc_i2c_brightness;
117
118 if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1)
119 return 0;
120
121 DRM_ERROR("I2C transfer error\n");
122 return -1;
123}
124
125
126static int cdv_lvds_pwm_set_brightness(struct drm_device *dev, int level)
127{
128 struct drm_psb_private *dev_priv = dev->dev_private;
129
130 u32 max_pwm_blc;
131 u32 blc_pwm_duty_cycle;
132
133 max_pwm_blc = cdv_intel_lvds_get_max_backlight(dev);
134
135 /*BLC_PWM_CTL Should be initiated while backlight device init*/
136 BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0);
137
138 blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL;
139
140 if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
141 blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle;
142
143 blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
144 REG_WRITE(BLC_PWM_CTL,
145 (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
146 (blc_pwm_duty_cycle));
147
148 return 0;
149}
150
151/*
152 * Set LVDS backlight level either by I2C or PWM
153 */
154void cdv_intel_lvds_set_brightness(struct drm_device *dev, int level)
155{
156 struct drm_psb_private *dev_priv = dev->dev_private;
157
158 if (!dev_priv->lvds_bl) {
159 DRM_ERROR("NO LVDS Backlight Info\n");
160 return;
161 }
162
163 if (dev_priv->lvds_bl->type == BLC_I2C_TYPE)
164 cdv_lvds_i2c_set_brightness(dev, level);
165 else
166 cdv_lvds_pwm_set_brightness(dev, level);
167}
168
169/**
170 * Sets the backlight level.
171 *
172 * level backlight level, from 0 to cdv_intel_lvds_get_max_backlight().
173 */
174static void cdv_intel_lvds_set_backlight(struct drm_device *dev, int level)
175{
176 struct drm_psb_private *dev_priv = dev->dev_private;
177 u32 blc_pwm_ctl;
178
179 if (gma_power_begin(dev, false)) {
180 blc_pwm_ctl =
181 REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
182 REG_WRITE(BLC_PWM_CTL,
183 (blc_pwm_ctl |
184 (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
185 gma_power_end(dev);
186 } else {
187 blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
188 ~BACKLIGHT_DUTY_CYCLE_MASK;
189 dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
190 (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
191 }
192}
193
194/**
195 * Sets the power state for the panel.
196 */
197static void cdv_intel_lvds_set_power(struct drm_device *dev,
198 struct drm_encoder *encoder, bool on)
199{
200 struct drm_psb_private *dev_priv = dev->dev_private;
201 u32 pp_status;
202
203 if (!gma_power_begin(dev, true))
204 return;
205
206 if (on) {
207 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
208 POWER_TARGET_ON);
209 do {
210 pp_status = REG_READ(PP_STATUS);
211 } while ((pp_status & PP_ON) == 0);
212
213 cdv_intel_lvds_set_backlight(dev,
214 dev_priv->mode_dev.backlight_duty_cycle);
215 } else {
216 cdv_intel_lvds_set_backlight(dev, 0);
217
218 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
219 ~POWER_TARGET_ON);
220 do {
221 pp_status = REG_READ(PP_STATUS);
222 } while (pp_status & PP_ON);
223 }
224 gma_power_end(dev);
225}
226
227static void cdv_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
228{
229 struct drm_device *dev = encoder->dev;
230 if (mode == DRM_MODE_DPMS_ON)
231 cdv_intel_lvds_set_power(dev, encoder, true);
232 else
233 cdv_intel_lvds_set_power(dev, encoder, false);
234 /* XXX: We never power down the LVDS pairs. */
235}
236
237static void cdv_intel_lvds_save(struct drm_connector *connector)
238{
239}
240
241static void cdv_intel_lvds_restore(struct drm_connector *connector)
242{
243}
244
245int cdv_intel_lvds_mode_valid(struct drm_connector *connector,
246 struct drm_display_mode *mode)
247{
248 struct drm_device *dev = connector->dev;
249 struct drm_psb_private *dev_priv = dev->dev_private;
250 struct drm_display_mode *fixed_mode =
251 dev_priv->mode_dev.panel_fixed_mode;
252
253 /* just in case */
254 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
255 return MODE_NO_DBLESCAN;
256
257 /* just in case */
258 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
259 return MODE_NO_INTERLACE;
260
261 if (fixed_mode) {
262 if (mode->hdisplay > fixed_mode->hdisplay)
263 return MODE_PANEL;
264 if (mode->vdisplay > fixed_mode->vdisplay)
265 return MODE_PANEL;
266 }
267 return MODE_OK;
268}
269
270bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder,
271 struct drm_display_mode *mode,
272 struct drm_display_mode *adjusted_mode)
273{
274 struct drm_device *dev = encoder->dev;
275 struct drm_psb_private *dev_priv = dev->dev_private;
276 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
277 struct drm_encoder *tmp_encoder;
278 struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;
279
280 /* Should never happen!! */
281 list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
282 head) {
283 if (tmp_encoder != encoder
284 && tmp_encoder->crtc == encoder->crtc) {
285 printk(KERN_ERR "Can't enable LVDS and another "
286 "encoder on the same pipe\n");
287 return false;
288 }
289 }
290
291 /*
292 * If we have timings from the BIOS for the panel, put them in
293 * to the adjusted mode. The CRTC will be set up for this mode,
294 * with the panel scaling set up to source from the H/VDisplay
295 * of the original mode.
296 */
297 if (panel_fixed_mode != NULL) {
298 adjusted_mode->hdisplay = panel_fixed_mode->hdisplay;
299 adjusted_mode->hsync_start = panel_fixed_mode->hsync_start;
300 adjusted_mode->hsync_end = panel_fixed_mode->hsync_end;
301 adjusted_mode->htotal = panel_fixed_mode->htotal;
302 adjusted_mode->vdisplay = panel_fixed_mode->vdisplay;
303 adjusted_mode->vsync_start = panel_fixed_mode->vsync_start;
304 adjusted_mode->vsync_end = panel_fixed_mode->vsync_end;
305 adjusted_mode->vtotal = panel_fixed_mode->vtotal;
306 adjusted_mode->clock = panel_fixed_mode->clock;
307 drm_mode_set_crtcinfo(adjusted_mode,
308 CRTC_INTERLACE_HALVE_V);
309 }
310
311 /*
312 * XXX: It would be nice to support lower refresh rates on the
313 * panels to reduce power consumption, and perhaps match the
314 * user's requested refresh rate.
315 */
316
317 return true;
318}
319
320static void cdv_intel_lvds_prepare(struct drm_encoder *encoder)
321{
322 struct drm_device *dev = encoder->dev;
323 struct drm_psb_private *dev_priv = dev->dev_private;
324 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
325
326 if (!gma_power_begin(dev, true))
327 return;
328
329 mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
330 mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
331 BACKLIGHT_DUTY_CYCLE_MASK);
332
333 cdv_intel_lvds_set_power(dev, encoder, false);
334
335 gma_power_end(dev);
336}
337
338static void cdv_intel_lvds_commit(struct drm_encoder *encoder)
339{
340 struct drm_device *dev = encoder->dev;
341 struct drm_psb_private *dev_priv = dev->dev_private;
342 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
343
344 if (mode_dev->backlight_duty_cycle == 0)
345 mode_dev->backlight_duty_cycle =
346 cdv_intel_lvds_get_max_backlight(dev);
347
348 cdv_intel_lvds_set_power(dev, encoder, true);
349}
350
351static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder,
352 struct drm_display_mode *mode,
353 struct drm_display_mode *adjusted_mode)
354{
355 struct drm_device *dev = encoder->dev;
356 struct drm_psb_private *dev_priv = dev->dev_private;
357 u32 pfit_control;
358
359 /*
360 * The LVDS pin pair will already have been turned on in the
361 * cdv_intel_crtc_mode_set since it has a large impact on the DPLL
362 * settings.
363 */
364
365 /*
366 * Enable automatic panel scaling so that non-native modes fill the
367 * screen. Should be enabled before the pipe is enabled, according to
368 * register description and PRM.
369 */
370 if (mode->hdisplay != adjusted_mode->hdisplay ||
371 mode->vdisplay != adjusted_mode->vdisplay)
372 pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
373 HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
374 HORIZ_INTERP_BILINEAR);
375 else
376 pfit_control = 0;
377
378 if (dev_priv->lvds_dither)
379 pfit_control |= PANEL_8TO6_DITHER_ENABLE;
380
381 REG_WRITE(PFIT_CONTROL, pfit_control);
382}
383
384/**
385 * Detect the LVDS connection.
386 *
387 * This always returns CONNECTOR_STATUS_CONNECTED.
388 * This connector should only have
389 * been set up if the LVDS was actually connected anyway.
390 */
391static enum drm_connector_status cdv_intel_lvds_detect(
392 struct drm_connector *connector, bool force)
393{
394 return connector_status_connected;
395}
396
397/**
398 * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
399 */
400static int cdv_intel_lvds_get_modes(struct drm_connector *connector)
401{
402 struct drm_device *dev = connector->dev;
403 struct drm_psb_private *dev_priv = dev->dev_private;
404 struct psb_intel_encoder *psb_intel_encoder =
405 psb_intel_attached_encoder(connector);
406 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
407 int ret;
408
409 ret = psb_intel_ddc_get_modes(connector, &psb_intel_encoder->i2c_bus->adapter);
410
411 if (ret)
412 return ret;
413
414 /* Didn't get an EDID, so
415 * Set wide sync ranges so we get all modes
416 * handed to valid_mode for checking
417 */
418 connector->display_info.min_vfreq = 0;
419 connector->display_info.max_vfreq = 200;
420 connector->display_info.min_hfreq = 0;
421 connector->display_info.max_hfreq = 200;
422 if (mode_dev->panel_fixed_mode != NULL) {
423 struct drm_display_mode *mode =
424 drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
425 drm_mode_probed_add(connector, mode);
426 return 1;
427 }
428
429 return 0;
430}
431
432/**
433 * cdv_intel_lvds_destroy - unregister and free LVDS structures
434 * @connector: connector to free
435 *
436 * Unregister the DDC bus for this connector then free the driver private
437 * structure.
438 */
439void cdv_intel_lvds_destroy(struct drm_connector *connector)
440{
441 struct psb_intel_encoder *psb_intel_encoder =
442 psb_intel_attached_encoder(connector);
443
444 if (psb_intel_encoder->i2c_bus)
445 psb_intel_i2c_destroy(psb_intel_encoder->i2c_bus);
446 drm_sysfs_connector_remove(connector);
447 drm_connector_cleanup(connector);
448 kfree(connector);
449}
450
451int cdv_intel_lvds_set_property(struct drm_connector *connector,
452 struct drm_property *property,
453 uint64_t value)
454{
455 struct drm_encoder *encoder = connector->encoder;
456
457 if (!strcmp(property->name, "scaling mode") && encoder) {
458 struct psb_intel_crtc *crtc =
459 to_psb_intel_crtc(encoder->crtc);
460 uint64_t curValue;
461
462 if (!crtc)
463 return -1;
464
465 switch (value) {
466 case DRM_MODE_SCALE_FULLSCREEN:
467 break;
468 case DRM_MODE_SCALE_NO_SCALE:
469 break;
470 case DRM_MODE_SCALE_ASPECT:
471 break;
472 default:
473 return -1;
474 }
475
476 if (drm_connector_property_get_value(connector,
477 property,
478 &curValue))
479 return -1;
480
481 if (curValue == value)
482 return 0;
483
484 if (drm_connector_property_set_value(connector,
485 property,
486 value))
487 return -1;
488
489 if (crtc->saved_mode.hdisplay != 0 &&
490 crtc->saved_mode.vdisplay != 0) {
491 if (!drm_crtc_helper_set_mode(encoder->crtc,
492 &crtc->saved_mode,
493 encoder->crtc->x,
494 encoder->crtc->y,
495 encoder->crtc->fb))
496 return -1;
497 }
498 } else if (!strcmp(property->name, "backlight") && encoder) {
499 if (drm_connector_property_set_value(connector,
500 property,
501 value))
502 return -1;
503 else {
504#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
505 struct drm_psb_private *dev_priv =
506 encoder->dev->dev_private;
507 struct backlight_device *bd =
508 dev_priv->backlight_device;
509 bd->props.brightness = value;
510 backlight_update_status(bd);
511#endif
512 }
513 } else if (!strcmp(property->name, "DPMS") && encoder) {
514 struct drm_encoder_helper_funcs *helpers =
515 encoder->helper_private;
516 helpers->dpms(encoder, value);
517 }
518 return 0;
519}
520
521static const struct drm_encoder_helper_funcs
522 cdv_intel_lvds_helper_funcs = {
523 .dpms = cdv_intel_lvds_encoder_dpms,
524 .mode_fixup = cdv_intel_lvds_mode_fixup,
525 .prepare = cdv_intel_lvds_prepare,
526 .mode_set = cdv_intel_lvds_mode_set,
527 .commit = cdv_intel_lvds_commit,
528};
529
530static const struct drm_connector_helper_funcs
531 cdv_intel_lvds_connector_helper_funcs = {
532 .get_modes = cdv_intel_lvds_get_modes,
533 .mode_valid = cdv_intel_lvds_mode_valid,
534 .best_encoder = psb_intel_best_encoder,
535};
536
537static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = {
538 .dpms = drm_helper_connector_dpms,
539 .save = cdv_intel_lvds_save,
540 .restore = cdv_intel_lvds_restore,
541 .detect = cdv_intel_lvds_detect,
542 .fill_modes = drm_helper_probe_single_connector_modes,
543 .set_property = cdv_intel_lvds_set_property,
544 .destroy = cdv_intel_lvds_destroy,
545};
546
547
548static void cdv_intel_lvds_enc_destroy(struct drm_encoder *encoder)
549{
550 drm_encoder_cleanup(encoder);
551}
552
553const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = {
554 .destroy = cdv_intel_lvds_enc_destroy,
555};
556
557/**
558 * cdv_intel_lvds_init - setup LVDS connectors on this device
559 * @dev: drm device
560 *
561 * Create the connector, register the LVDS DDC bus, and try to figure out what
562 * modes we can display on the LVDS panel (if present).
563 */
564void cdv_intel_lvds_init(struct drm_device *dev,
565 struct psb_intel_mode_device *mode_dev)
566{
567 struct psb_intel_encoder *psb_intel_encoder;
568 struct psb_intel_connector *psb_intel_connector;
569 struct cdv_intel_lvds_priv *lvds_priv;
570 struct drm_connector *connector;
571 struct drm_encoder *encoder;
572 struct drm_display_mode *scan;
573 struct drm_crtc *crtc;
574 struct drm_psb_private *dev_priv = dev->dev_private;
575 u32 lvds;
576 int pipe;
577
578 psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder),
579 GFP_KERNEL);
580 if (!psb_intel_encoder)
581 return;
582
583 psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector),
584 GFP_KERNEL);
585 if (!psb_intel_connector)
586 goto failed_connector;
587
588 lvds_priv = kzalloc(sizeof(struct cdv_intel_lvds_priv), GFP_KERNEL);
589 if (!lvds_priv)
590 goto failed_lvds_priv;
591
592 psb_intel_encoder->dev_priv = lvds_priv;
593
594 connector = &psb_intel_connector->base;
595 encoder = &psb_intel_encoder->base;
596
597
598 drm_connector_init(dev, connector,
599 &cdv_intel_lvds_connector_funcs,
600 DRM_MODE_CONNECTOR_LVDS);
601
602 drm_encoder_init(dev, encoder,
603 &cdv_intel_lvds_enc_funcs,
604 DRM_MODE_ENCODER_LVDS);
605
606
607 psb_intel_connector_attach_encoder(psb_intel_connector,
608 psb_intel_encoder);
609 psb_intel_encoder->type = INTEL_OUTPUT_LVDS;
610
611 drm_encoder_helper_add(encoder, &cdv_intel_lvds_helper_funcs);
612 drm_connector_helper_add(connector,
613 &cdv_intel_lvds_connector_helper_funcs);
614 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
615 connector->interlace_allowed = false;
616 connector->doublescan_allowed = false;
617
618 /*Attach connector properties*/
619 drm_connector_attach_property(connector,
620 dev->mode_config.scaling_mode_property,
621 DRM_MODE_SCALE_FULLSCREEN);
622 drm_connector_attach_property(connector,
623 dev_priv->backlight_property,
624 BRIGHTNESS_MAX_LEVEL);
625
626 /**
627 * Set up I2C bus
628 * FIXME: distroy i2c_bus when exit
629 */
630 psb_intel_encoder->i2c_bus = psb_intel_i2c_create(dev,
631 GPIOB,
632 "LVDSBLC_B");
633 if (!psb_intel_encoder->i2c_bus) {
634 dev_printk(KERN_ERR,
635 &dev->pdev->dev, "I2C bus registration failed.\n");
636 goto failed_blc_i2c;
637 }
638 psb_intel_encoder->i2c_bus->slave_addr = 0x2C;
639 dev_priv->lvds_i2c_bus = psb_intel_encoder->i2c_bus;
640
641 /*
642 * LVDS discovery:
643 * 1) check for EDID on DDC
644 * 2) check for VBT data
645 * 3) check to see if LVDS is already on
646 * if none of the above, no panel
647 * 4) make sure lid is open
648 * if closed, act like it's not there for now
649 */
650
651 /* Set up the DDC bus. */
652 psb_intel_encoder->ddc_bus = psb_intel_i2c_create(dev,
653 GPIOC,
654 "LVDSDDC_C");
655 if (!psb_intel_encoder->ddc_bus) {
656 dev_printk(KERN_ERR, &dev->pdev->dev,
657 "DDC bus registration " "failed.\n");
658 goto failed_ddc;
659 }
660
661 /*
662 * Attempt to get the fixed panel mode from DDC. Assume that the
663 * preferred mode is the right one.
664 */
665 psb_intel_ddc_get_modes(connector,
666 &psb_intel_encoder->ddc_bus->adapter);
667 list_for_each_entry(scan, &connector->probed_modes, head) {
668 if (scan->type & DRM_MODE_TYPE_PREFERRED) {
669 mode_dev->panel_fixed_mode =
670 drm_mode_duplicate(dev, scan);
671 goto out; /* FIXME: check for quirks */
672 }
673 }
674
675 /* Failed to get EDID, what about VBT? do we need this?*/
676 if (dev_priv->lfp_lvds_vbt_mode) {
677 mode_dev->panel_fixed_mode =
678 drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
679 if (mode_dev->panel_fixed_mode) {
680 mode_dev->panel_fixed_mode->type |=
681 DRM_MODE_TYPE_PREFERRED;
682 goto out; /* FIXME: check for quirks */
683 }
684 }
685 /*
686 * If we didn't get EDID, try checking if the panel is already turned
687 * on. If so, assume that whatever is currently programmed is the
688 * correct mode.
689 */
690 lvds = REG_READ(LVDS);
691 pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
692 crtc = psb_intel_get_crtc_from_pipe(dev, pipe);
693
694 if (crtc && (lvds & LVDS_PORT_EN)) {
695 mode_dev->panel_fixed_mode =
696 cdv_intel_crtc_mode_get(dev, crtc);
697 if (mode_dev->panel_fixed_mode) {
698 mode_dev->panel_fixed_mode->type |=
699 DRM_MODE_TYPE_PREFERRED;
700 goto out; /* FIXME: check for quirks */
701 }
702 }
703
704 /* If we still don't have a mode after all that, give up. */
705 if (!mode_dev->panel_fixed_mode) {
706 DRM_DEBUG
707 ("Found no modes on the lvds, ignoring the LVDS\n");
708 goto failed_find;
709 }
710
711out:
712 drm_sysfs_connector_add(connector);
713 return;
714
715failed_find:
716 printk(KERN_ERR "Failed find\n");
717 if (psb_intel_encoder->ddc_bus)
718 psb_intel_i2c_destroy(psb_intel_encoder->ddc_bus);
719failed_ddc:
720 printk(KERN_ERR "Failed DDC\n");
721 if (psb_intel_encoder->i2c_bus)
722 psb_intel_i2c_destroy(psb_intel_encoder->i2c_bus);
723failed_blc_i2c:
724 printk(KERN_ERR "Failed BLC\n");
725 drm_encoder_cleanup(encoder);
726 drm_connector_cleanup(connector);
727 kfree(lvds_priv);
728failed_lvds_priv:
729 kfree(psb_intel_connector);
730failed_connector:
731 kfree(psb_intel_encoder);
732}
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
new file mode 100644
index 00000000000..791c0ef1a65
--- /dev/null
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -0,0 +1,831 @@
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#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/errno.h>
23#include <linux/string.h>
24#include <linux/mm.h>
25#include <linux/tty.h>
26#include <linux/slab.h>
27#include <linux/delay.h>
28#include <linux/fb.h>
29#include <linux/init.h>
30#include <linux/console.h>
31
32#include <drm/drmP.h>
33#include <drm/drm.h>
34#include <drm/drm_crtc.h>
35#include <drm/drm_fb_helper.h>
36
37#include "psb_drv.h"
38#include "psb_intel_reg.h"
39#include "psb_intel_drv.h"
40#include "framebuffer.h"
41#include "gtt.h"
42
43static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb);
44static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
45 struct drm_file *file_priv,
46 unsigned int *handle);
47
48static const struct drm_framebuffer_funcs psb_fb_funcs = {
49 .destroy = psb_user_framebuffer_destroy,
50 .create_handle = psb_user_framebuffer_create_handle,
51};
52
53#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
54
55static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
56 unsigned blue, unsigned transp,
57 struct fb_info *info)
58{
59 struct psb_fbdev *fbdev = info->par;
60 struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;
61 uint32_t v;
62
63 if (!fb)
64 return -ENOMEM;
65
66 if (regno > 255)
67 return 1;
68
69 red = CMAP_TOHW(red, info->var.red.length);
70 blue = CMAP_TOHW(blue, info->var.blue.length);
71 green = CMAP_TOHW(green, info->var.green.length);
72 transp = CMAP_TOHW(transp, info->var.transp.length);
73
74 v = (red << info->var.red.offset) |
75 (green << info->var.green.offset) |
76 (blue << info->var.blue.offset) |
77 (transp << info->var.transp.offset);
78
79 if (regno < 16) {
80 switch (fb->bits_per_pixel) {
81 case 16:
82 ((uint32_t *) info->pseudo_palette)[regno] = v;
83 break;
84 case 24:
85 case 32:
86 ((uint32_t *) info->pseudo_palette)[regno] = v;
87 break;
88 }
89 }
90
91 return 0;
92}
93
94static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info)
95{
96 struct psb_fbdev *fbdev = info->par;
97 struct psb_framebuffer *psbfb = &fbdev->pfb;
98 struct drm_device *dev = psbfb->base.dev;
99
100 /*
101 * We have to poke our nose in here. The core fb code assumes
102 * panning is part of the hardware that can be invoked before
103 * the actual fb is mapped. In our case that isn't quite true.
104 */
105 if (psbfb->gtt->npage) {
106 /* GTT roll shifts in 4K pages, we need to shift the right
107 number of pages */
108 int pages = info->fix.line_length >> 12;
109 psb_gtt_roll(dev, psbfb->gtt, var->yoffset * pages);
110 }
111 return 0;
112}
113
114void psbfb_suspend(struct drm_device *dev)
115{
116 struct drm_framebuffer *fb = 0;
117 struct psb_framebuffer *psbfb = to_psb_fb(fb);
118
119 console_lock();
120 mutex_lock(&dev->mode_config.mutex);
121 list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
122 struct fb_info *info = psbfb->fbdev;
123 fb_set_suspend(info, 1);
124 drm_fb_helper_blank(FB_BLANK_POWERDOWN, info);
125 }
126 mutex_unlock(&dev->mode_config.mutex);
127 console_unlock();
128}
129
130void psbfb_resume(struct drm_device *dev)
131{
132 struct drm_framebuffer *fb = 0;
133 struct psb_framebuffer *psbfb = to_psb_fb(fb);
134
135 console_lock();
136 mutex_lock(&dev->mode_config.mutex);
137 list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
138 struct fb_info *info = psbfb->fbdev;
139 fb_set_suspend(info, 0);
140 drm_fb_helper_blank(FB_BLANK_UNBLANK, info);
141 }
142 mutex_unlock(&dev->mode_config.mutex);
143 console_unlock();
144 drm_helper_disable_unused_functions(dev);
145}
146
147static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
148{
149 struct psb_framebuffer *psbfb = vma->vm_private_data;
150 struct drm_device *dev = psbfb->base.dev;
151 struct drm_psb_private *dev_priv = dev->dev_private;
152 int page_num;
153 int i;
154 unsigned long address;
155 int ret;
156 unsigned long pfn;
157 /* FIXME: assumes fb at stolen base which may not be true */
158 unsigned long phys_addr = (unsigned long)dev_priv->stolen_base;
159
160 page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
161 address = (unsigned long)vmf->virtual_address;
162
163 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
164
165 for (i = 0; i < page_num; i++) {
166 pfn = (phys_addr >> PAGE_SHIFT);
167
168 ret = vm_insert_mixed(vma, address, pfn);
169 if (unlikely((ret == -EBUSY) || (ret != 0 && i > 0)))
170 break;
171 else if (unlikely(ret != 0)) {
172 ret = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
173 return ret;
174 }
175 address += PAGE_SIZE;
176 phys_addr += PAGE_SIZE;
177 }
178 return VM_FAULT_NOPAGE;
179}
180
181static void psbfb_vm_open(struct vm_area_struct *vma)
182{
183}
184
185static void psbfb_vm_close(struct vm_area_struct *vma)
186{
187}
188
189static struct vm_operations_struct psbfb_vm_ops = {
190 .fault = psbfb_vm_fault,
191 .open = psbfb_vm_open,
192 .close = psbfb_vm_close
193};
194
195static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
196{
197 struct psb_fbdev *fbdev = info->par;
198 struct psb_framebuffer *psbfb = &fbdev->pfb;
199
200 if (vma->vm_pgoff != 0)
201 return -EINVAL;
202 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
203 return -EINVAL;
204
205 if (!psbfb->addr_space)
206 psbfb->addr_space = vma->vm_file->f_mapping;
207 /*
208 * If this is a GEM object then info->screen_base is the virtual
209 * kernel remapping of the object. FIXME: Review if this is
210 * suitable for our mmap work
211 */
212 vma->vm_ops = &psbfb_vm_ops;
213 vma->vm_private_data = (void *)psbfb;
214 vma->vm_flags |= VM_RESERVED | VM_IO |
215 VM_MIXEDMAP | VM_DONTEXPAND;
216 return 0;
217}
218
219static int psbfb_ioctl(struct fb_info *info, unsigned int cmd,
220 unsigned long arg)
221{
222 return -ENOTTY;
223}
224
225static struct fb_ops psbfb_ops = {
226 .owner = THIS_MODULE,
227 .fb_check_var = drm_fb_helper_check_var,
228 .fb_set_par = drm_fb_helper_set_par,
229 .fb_blank = drm_fb_helper_blank,
230 .fb_setcolreg = psbfb_setcolreg,
231 .fb_fillrect = cfb_fillrect,
232 .fb_copyarea = psbfb_copyarea,
233 .fb_imageblit = cfb_imageblit,
234 .fb_mmap = psbfb_mmap,
235 .fb_sync = psbfb_sync,
236 .fb_ioctl = psbfb_ioctl,
237};
238
239static struct fb_ops psbfb_roll_ops = {
240 .owner = THIS_MODULE,
241 .fb_check_var = drm_fb_helper_check_var,
242 .fb_set_par = drm_fb_helper_set_par,
243 .fb_blank = drm_fb_helper_blank,
244 .fb_setcolreg = psbfb_setcolreg,
245 .fb_fillrect = cfb_fillrect,
246 .fb_copyarea = cfb_copyarea,
247 .fb_imageblit = cfb_imageblit,
248 .fb_pan_display = psbfb_pan,
249 .fb_mmap = psbfb_mmap,
250 .fb_sync = psbfb_sync,
251 .fb_ioctl = psbfb_ioctl,
252};
253
254static struct fb_ops psbfb_unaccel_ops = {
255 .owner = THIS_MODULE,
256 .fb_check_var = drm_fb_helper_check_var,
257 .fb_set_par = drm_fb_helper_set_par,
258 .fb_blank = drm_fb_helper_blank,
259 .fb_setcolreg = psbfb_setcolreg,
260 .fb_fillrect = cfb_fillrect,
261 .fb_copyarea = cfb_copyarea,
262 .fb_imageblit = cfb_imageblit,
263 .fb_mmap = psbfb_mmap,
264 .fb_ioctl = psbfb_ioctl,
265};
266
267/**
268 * psb_framebuffer_init - initialize a framebuffer
269 * @dev: our DRM device
270 * @fb: framebuffer to set up
271 * @mode_cmd: mode description
272 * @gt: backing object
273 *
274 * Configure and fill in the boilerplate for our frame buffer. Return
275 * 0 on success or an error code if we fail.
276 */
277static int psb_framebuffer_init(struct drm_device *dev,
278 struct psb_framebuffer *fb,
279 struct drm_mode_fb_cmd2 *mode_cmd,
280 struct gtt_range *gt)
281{
282 u32 bpp, depth;
283 int ret;
284
285 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
286
287 if (mode_cmd->pitches[0] & 63)
288 return -EINVAL;
289 switch (bpp) {
290 case 8:
291 case 16:
292 case 24:
293 case 32:
294 break;
295 default:
296 return -EINVAL;
297 }
298 ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
299 if (ret) {
300 dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
301 return ret;
302 }
303 drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
304 fb->gtt = gt;
305 return 0;
306}
307
308/**
309 * psb_framebuffer_create - create a framebuffer backed by gt
310 * @dev: our DRM device
311 * @mode_cmd: the description of the requested mode
312 * @gt: the backing object
313 *
314 * Create a framebuffer object backed by the gt, and fill in the
315 * boilerplate required
316 *
317 * TODO: review object references
318 */
319
320static struct drm_framebuffer *psb_framebuffer_create
321 (struct drm_device *dev,
322 struct drm_mode_fb_cmd2 *mode_cmd,
323 struct gtt_range *gt)
324{
325 struct psb_framebuffer *fb;
326 int ret;
327
328 fb = kzalloc(sizeof(*fb), GFP_KERNEL);
329 if (!fb)
330 return ERR_PTR(-ENOMEM);
331
332 ret = psb_framebuffer_init(dev, fb, mode_cmd, gt);
333 if (ret) {
334 kfree(fb);
335 return ERR_PTR(ret);
336 }
337 return &fb->base;
338}
339
340/**
341 * psbfb_alloc - allocate frame buffer memory
342 * @dev: the DRM device
343 * @aligned_size: space needed
344 * @force: fall back to GEM buffers if need be
345 *
346 * Allocate the frame buffer. In the usual case we get a GTT range that
347 * is stolen memory backed and life is simple. If there isn't sufficient
348 * we fail as we don't have the virtual mapping space to really vmap it
349 * and the kernel console code can't handle non linear framebuffers.
350 *
351 * Re-address this as and if the framebuffer layer grows this ability.
352 */
353static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
354{
355 struct gtt_range *backing;
356 /* Begin by trying to use stolen memory backing */
357 backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1);
358 if (backing) {
359 if (drm_gem_private_object_init(dev,
360 &backing->gem, aligned_size) == 0)
361 return backing;
362 psb_gtt_free_range(dev, backing);
363 }
364 return NULL;
365}
366
367/**
368 * psbfb_create - create a framebuffer
369 * @fbdev: the framebuffer device
370 * @sizes: specification of the layout
371 *
372 * Create a framebuffer to the specifications provided
373 */
374static int psbfb_create(struct psb_fbdev *fbdev,
375 struct drm_fb_helper_surface_size *sizes)
376{
377 struct drm_device *dev = fbdev->psb_fb_helper.dev;
378 struct drm_psb_private *dev_priv = dev->dev_private;
379 struct fb_info *info;
380 struct drm_framebuffer *fb;
381 struct psb_framebuffer *psbfb = &fbdev->pfb;
382 struct drm_mode_fb_cmd2 mode_cmd;
383 struct device *device = &dev->pdev->dev;
384 int size;
385 int ret;
386 struct gtt_range *backing;
387 u32 bpp, depth;
388 int gtt_roll = 0;
389 int pitch_lines = 0;
390
391 mode_cmd.width = sizes->surface_width;
392 mode_cmd.height = sizes->surface_height;
393 bpp = sizes->surface_bpp;
394
395 /* No 24bit packed */
396 if (bpp == 24)
397 bpp = 32;
398
399 do {
400 /*
401 * Acceleration via the GTT requires pitch to be
402 * power of two aligned. Preferably page but less
403 * is ok with some fonts
404 */
405 mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 7) / 8), 4096 >> pitch_lines);
406 depth = sizes->surface_depth;
407
408 size = mode_cmd.pitches[0] * mode_cmd.height;
409 size = ALIGN(size, PAGE_SIZE);
410
411 /* Allocate the fb in the GTT with stolen page backing */
412 backing = psbfb_alloc(dev, size);
413
414 if (pitch_lines)
415 pitch_lines *= 2;
416 else
417 pitch_lines = 1;
418 gtt_roll++;
419 } while (backing == NULL && pitch_lines <= 16);
420
421 /* The final pitch we accepted if we succeeded */
422 pitch_lines /= 2;
423
424 if (backing == NULL) {
425 /*
426 * We couldn't get the space we wanted, fall back to the
427 * display engine requirement instead. The HW requires
428 * the pitch to be 64 byte aligned
429 */
430
431 gtt_roll = 0; /* Don't use GTT accelerated scrolling */
432 pitch_lines = 64;
433
434 mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 7) / 8), 64);
435
436 size = mode_cmd.pitches[0] * mode_cmd.height;
437 size = ALIGN(size, PAGE_SIZE);
438
439 /* Allocate the framebuffer in the GTT with stolen page backing */
440 backing = psbfb_alloc(dev, size);
441 if (backing == NULL)
442 return -ENOMEM;
443 }
444
445 mutex_lock(&dev->struct_mutex);
446
447 info = framebuffer_alloc(0, device);
448 if (!info) {
449 ret = -ENOMEM;
450 goto out_err1;
451 }
452 info->par = fbdev;
453
454 mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
455
456 ret = psb_framebuffer_init(dev, psbfb, &mode_cmd, backing);
457 if (ret)
458 goto out_unref;
459
460 fb = &psbfb->base;
461 psbfb->fbdev = info;
462
463 fbdev->psb_fb_helper.fb = fb;
464 fbdev->psb_fb_helper.fbdev = info;
465
466 strcpy(info->fix.id, "psbfb");
467
468 info->flags = FBINFO_DEFAULT;
469 if (dev_priv->ops->accel_2d && pitch_lines > 8) /* 2D engine */
470 info->fbops = &psbfb_ops;
471 else if (gtt_roll) { /* GTT rolling seems best */
472 info->fbops = &psbfb_roll_ops;
473 info->flags |= FBINFO_HWACCEL_YPAN;
474 } else /* Software */
475 info->fbops = &psbfb_unaccel_ops;
476
477 ret = fb_alloc_cmap(&info->cmap, 256, 0);
478 if (ret) {
479 ret = -ENOMEM;
480 goto out_unref;
481 }
482
483 info->fix.smem_start = dev->mode_config.fb_base;
484 info->fix.smem_len = size;
485 info->fix.ywrapstep = gtt_roll;
486 info->fix.ypanstep = 0;
487
488 /* Accessed stolen memory directly */
489 info->screen_base = (char *)dev_priv->vram_addr +
490 backing->offset;
491 info->screen_size = size;
492
493 if (dev_priv->gtt.stolen_size) {
494 info->apertures = alloc_apertures(1);
495 if (!info->apertures) {
496 ret = -ENOMEM;
497 goto out_unref;
498 }
499 info->apertures->ranges[0].base = dev->mode_config.fb_base;
500 info->apertures->ranges[0].size = dev_priv->gtt.stolen_size;
501 }
502
503 drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
504 drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper,
505 sizes->fb_width, sizes->fb_height);
506
507 info->fix.mmio_start = pci_resource_start(dev->pdev, 0);
508 info->fix.mmio_len = pci_resource_len(dev->pdev, 0);
509
510 info->pixmap.size = 64 * 1024;
511 info->pixmap.buf_align = 8;
512 info->pixmap.access_align = 32;
513 info->pixmap.flags = FB_PIXMAP_SYSTEM;
514 info->pixmap.scan_align = 1;
515
516 dev_info(dev->dev, "allocated %dx%d fb\n",
517 psbfb->base.width, psbfb->base.height);
518
519 mutex_unlock(&dev->struct_mutex);
520 return 0;
521out_unref:
522 if (backing->stolen)
523 psb_gtt_free_range(dev, backing);
524 else
525 drm_gem_object_unreference(&backing->gem);
526out_err1:
527 mutex_unlock(&dev->struct_mutex);
528 psb_gtt_free_range(dev, backing);
529 return ret;
530}
531
532/**
533 * psb_user_framebuffer_create - create framebuffer
534 * @dev: our DRM device
535 * @filp: client file
536 * @cmd: mode request
537 *
538 * Create a new framebuffer backed by a userspace GEM object
539 */
540static struct drm_framebuffer *psb_user_framebuffer_create
541 (struct drm_device *dev, struct drm_file *filp,
542 struct drm_mode_fb_cmd2 *cmd)
543{
544 struct gtt_range *r;
545 struct drm_gem_object *obj;
546
547 /*
548 * Find the GEM object and thus the gtt range object that is
549 * to back this space
550 */
551 obj = drm_gem_object_lookup(dev, filp, cmd->handles[0]);
552 if (obj == NULL)
553 return ERR_PTR(-ENOENT);
554
555 /* Let the core code do all the work */
556 r = container_of(obj, struct gtt_range, gem);
557 return psb_framebuffer_create(dev, cmd, r);
558}
559
560static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
561 u16 blue, int regno)
562{
563}
564
565static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red,
566 u16 *green, u16 *blue, int regno)
567{
568}
569
570static int psbfb_probe(struct drm_fb_helper *helper,
571 struct drm_fb_helper_surface_size *sizes)
572{
573 struct psb_fbdev *psb_fbdev = (struct psb_fbdev *)helper;
574 int new_fb = 0;
575 int ret;
576
577 if (!helper->fb) {
578 ret = psbfb_create(psb_fbdev, sizes);
579 if (ret)
580 return ret;
581 new_fb = 1;
582 }
583 return new_fb;
584}
585
586struct drm_fb_helper_funcs psb_fb_helper_funcs = {
587 .gamma_set = psbfb_gamma_set,
588 .gamma_get = psbfb_gamma_get,
589 .fb_probe = psbfb_probe,
590};
591
592int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
593{
594 struct fb_info *info;
595 struct psb_framebuffer *psbfb = &fbdev->pfb;
596
597 if (fbdev->psb_fb_helper.fbdev) {
598 info = fbdev->psb_fb_helper.fbdev;
599 unregister_framebuffer(info);
600 if (info->cmap.len)
601 fb_dealloc_cmap(&info->cmap);
602 framebuffer_release(info);
603 }
604 drm_fb_helper_fini(&fbdev->psb_fb_helper);
605 drm_framebuffer_cleanup(&psbfb->base);
606
607 if (psbfb->gtt)
608 drm_gem_object_unreference(&psbfb->gtt->gem);
609 return 0;
610}
611
612int psb_fbdev_init(struct drm_device *dev)
613{
614 struct psb_fbdev *fbdev;
615 struct drm_psb_private *dev_priv = dev->dev_private;
616
617 fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL);
618 if (!fbdev) {
619 dev_err(dev->dev, "no memory\n");
620 return -ENOMEM;
621 }
622
623 dev_priv->fbdev = fbdev;
624 fbdev->psb_fb_helper.funcs = &psb_fb_helper_funcs;
625
626 drm_fb_helper_init(dev, &fbdev->psb_fb_helper, dev_priv->ops->crtcs,
627 INTELFB_CONN_LIMIT);
628
629 drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper);
630 drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32);
631 return 0;
632}
633
634void psb_fbdev_fini(struct drm_device *dev)
635{
636 struct drm_psb_private *dev_priv = dev->dev_private;
637
638 if (!dev_priv->fbdev)
639 return;
640
641 psb_fbdev_destroy(dev, dev_priv->fbdev);
642 kfree(dev_priv->fbdev);
643 dev_priv->fbdev = NULL;
644}
645
646static void psbfb_output_poll_changed(struct drm_device *dev)
647{
648 struct drm_psb_private *dev_priv = dev->dev_private;
649 struct psb_fbdev *fbdev = (struct psb_fbdev *)dev_priv->fbdev;
650 drm_fb_helper_hotplug_event(&fbdev->psb_fb_helper);
651}
652
653/**
654 * psb_user_framebuffer_create_handle - add hamdle to a framebuffer
655 * @fb: framebuffer
656 * @file_priv: our DRM file
657 * @handle: returned handle
658 *
659 * Our framebuffer object is a GTT range which also contains a GEM
660 * object. We need to turn it into a handle for userspace. GEM will do
661 * the work for us
662 */
663static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
664 struct drm_file *file_priv,
665 unsigned int *handle)
666{
667 struct psb_framebuffer *psbfb = to_psb_fb(fb);
668 struct gtt_range *r = psbfb->gtt;
669 return drm_gem_handle_create(file_priv, &r->gem, handle);
670}
671
672/**
673 * psb_user_framebuffer_destroy - destruct user created fb
674 * @fb: framebuffer
675 *
676 * User framebuffers are backed by GEM objects so all we have to do is
677 * clean up a bit and drop the reference, GEM will handle the fallout
678 */
679static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
680{
681 struct psb_framebuffer *psbfb = to_psb_fb(fb);
682 struct gtt_range *r = psbfb->gtt;
683 struct drm_device *dev = fb->dev;
684 struct drm_psb_private *dev_priv = dev->dev_private;
685 struct psb_fbdev *fbdev = dev_priv->fbdev;
686 struct drm_crtc *crtc;
687 int reset = 0;
688
689 /* Should never get stolen memory for a user fb */
690 WARN_ON(r->stolen);
691
692 /* Check if we are erroneously live */
693 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
694 if (crtc->fb == fb)
695 reset = 1;
696
697 if (reset)
698 /*
699 * Now force a sane response before we permit the DRM CRTC
700 * layer to do stupid things like blank the display. Instead
701 * we reset this framebuffer as if the user had forced a reset.
702 * We must do this before the cleanup so that the DRM layer
703 * doesn't get a chance to stick its oar in where it isn't
704 * wanted.
705 */
706 drm_fb_helper_restore_fbdev_mode(&fbdev->psb_fb_helper);
707
708 /* Let DRM do its clean up */
709 drm_framebuffer_cleanup(fb);
710 /* We are no longer using the resource in GEM */
711 drm_gem_object_unreference_unlocked(&r->gem);
712 kfree(fb);
713}
714
715static const struct drm_mode_config_funcs psb_mode_funcs = {
716 .fb_create = psb_user_framebuffer_create,
717 .output_poll_changed = psbfb_output_poll_changed,
718};
719
720static int psb_create_backlight_property(struct drm_device *dev)
721{
722 struct drm_psb_private *dev_priv = dev->dev_private;
723 struct drm_property *backlight;
724
725 if (dev_priv->backlight_property)
726 return 0;
727
728 backlight = drm_property_create(dev, DRM_MODE_PROP_RANGE,
729 "backlight", 2);
730 backlight->values[0] = 0;
731 backlight->values[1] = 100;
732
733 dev_priv->backlight_property = backlight;
734
735 return 0;
736}
737
738static void psb_setup_outputs(struct drm_device *dev)
739{
740 struct drm_psb_private *dev_priv = dev->dev_private;
741 struct drm_connector *connector;
742
743 drm_mode_create_scaling_mode_property(dev);
744 psb_create_backlight_property(dev);
745
746 dev_priv->ops->output_init(dev);
747
748 list_for_each_entry(connector, &dev->mode_config.connector_list,
749 head) {
750 struct psb_intel_encoder *psb_intel_encoder =
751 psb_intel_attached_encoder(connector);
752 struct drm_encoder *encoder = &psb_intel_encoder->base;
753 int crtc_mask = 0, clone_mask = 0;
754
755 /* valid crtcs */
756 switch (psb_intel_encoder->type) {
757 case INTEL_OUTPUT_ANALOG:
758 crtc_mask = (1 << 0);
759 clone_mask = (1 << INTEL_OUTPUT_ANALOG);
760 break;
761 case INTEL_OUTPUT_SDVO:
762 crtc_mask = ((1 << 0) | (1 << 1));
763 clone_mask = (1 << INTEL_OUTPUT_SDVO);
764 break;
765 case INTEL_OUTPUT_LVDS:
766 if (IS_MRST(dev))
767 crtc_mask = (1 << 0);
768 else
769 crtc_mask = (1 << 1);
770 clone_mask = (1 << INTEL_OUTPUT_LVDS);
771 break;
772 case INTEL_OUTPUT_MIPI:
773 crtc_mask = (1 << 0);
774 clone_mask = (1 << INTEL_OUTPUT_MIPI);
775 break;
776 case INTEL_OUTPUT_MIPI2:
777 crtc_mask = (1 << 2);
778 clone_mask = (1 << INTEL_OUTPUT_MIPI2);
779 break;
780 case INTEL_OUTPUT_HDMI:
781 if (IS_MFLD(dev))
782 crtc_mask = (1 << 1);
783 else
784 crtc_mask = (1 << 0);
785 clone_mask = (1 << INTEL_OUTPUT_HDMI);
786 break;
787 }
788 encoder->possible_crtcs = crtc_mask;
789 encoder->possible_clones =
790 psb_intel_connector_clones(dev, clone_mask);
791 }
792}
793
794void psb_modeset_init(struct drm_device *dev)
795{
796 struct drm_psb_private *dev_priv = dev->dev_private;
797 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
798 int i;
799
800 drm_mode_config_init(dev);
801
802 dev->mode_config.min_width = 0;
803 dev->mode_config.min_height = 0;
804
805 dev->mode_config.funcs = (void *) &psb_mode_funcs;
806
807 /* set memory base */
808 /* Oaktrail and Poulsbo should use BAR 2*/
809 pci_read_config_dword(dev->pdev, PSB_BSM, (u32 *)
810 &(dev->mode_config.fb_base));
811
812 /* num pipes is 2 for PSB but 1 for Mrst */
813 for (i = 0; i < dev_priv->num_pipe; i++)
814 psb_intel_crtc_init(dev, i, mode_dev);
815
816 dev->mode_config.max_width = 2048;
817 dev->mode_config.max_height = 2048;
818
819 psb_setup_outputs(dev);
820}
821
822void psb_modeset_cleanup(struct drm_device *dev)
823{
824 mutex_lock(&dev->struct_mutex);
825
826 drm_kms_helper_poll_fini(dev);
827 psb_fbdev_fini(dev);
828 drm_mode_config_cleanup(dev);
829
830 mutex_unlock(&dev->struct_mutex);
831}
diff --git a/drivers/gpu/drm/gma500/framebuffer.h b/drivers/gpu/drm/gma500/framebuffer.h
new file mode 100644
index 00000000000..989558a9e6e
--- /dev/null
+++ b/drivers/gpu/drm/gma500/framebuffer.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2008-2011, 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 *
20 */
21
22#ifndef _FRAMEBUFFER_H_
23#define _FRAMEBUFFER_H_
24
25#include <drm/drmP.h>
26#include <drm/drm_fb_helper.h>
27
28#include "psb_drv.h"
29
30struct psb_framebuffer {
31 struct drm_framebuffer base;
32 struct address_space *addr_space;
33 struct fb_info *fbdev;
34 struct gtt_range *gtt;
35};
36
37struct psb_fbdev {
38 struct drm_fb_helper psb_fb_helper;
39 struct psb_framebuffer pfb;
40};
41
42#define to_psb_fb(x) container_of(x, struct psb_framebuffer, base)
43
44extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask);
45
46#endif
47
diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
new file mode 100644
index 00000000000..9fbb86868e2
--- /dev/null
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -0,0 +1,292 @@
1/*
2 * psb GEM interface
3 *
4 * Copyright (c) 2011, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Authors: Alan Cox
20 *
21 * TODO:
22 * - we need to work out if the MMU is relevant (eg for
23 * accelerated operations on a GEM object)
24 */
25
26#include <drm/drmP.h>
27#include <drm/drm.h>
28#include "gma_drm.h"
29#include "psb_drv.h"
30
31int psb_gem_init_object(struct drm_gem_object *obj)
32{
33 return -EINVAL;
34}
35
36void psb_gem_free_object(struct drm_gem_object *obj)
37{
38 struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
39 drm_gem_object_release_wrap(obj);
40 /* This must occur last as it frees up the memory of the GEM object */
41 psb_gtt_free_range(obj->dev, gtt);
42}
43
44int psb_gem_get_aperture(struct drm_device *dev, void *data,
45 struct drm_file *file)
46{
47 return -EINVAL;
48}
49
50/**
51 * psb_gem_dumb_map_gtt - buffer mapping for dumb interface
52 * @file: our drm client file
53 * @dev: drm device
54 * @handle: GEM handle to the object (from dumb_create)
55 *
56 * Do the necessary setup to allow the mapping of the frame buffer
57 * into user memory. We don't have to do much here at the moment.
58 */
59int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
60 uint32_t handle, uint64_t *offset)
61{
62 int ret = 0;
63 struct drm_gem_object *obj;
64
65 if (!(dev->driver->driver_features & DRIVER_GEM))
66 return -ENODEV;
67
68 mutex_lock(&dev->struct_mutex);
69
70 /* GEM does all our handle to object mapping */
71 obj = drm_gem_object_lookup(dev, file, handle);
72 if (obj == NULL) {
73 ret = -ENOENT;
74 goto unlock;
75 }
76 /* What validation is needed here ? */
77
78 /* Make it mmapable */
79 if (!obj->map_list.map) {
80 ret = gem_create_mmap_offset(obj);
81 if (ret)
82 goto out;
83 }
84 /* GEM should really work out the hash offsets for us */
85 *offset = (u64)obj->map_list.hash.key << PAGE_SHIFT;
86out:
87 drm_gem_object_unreference(obj);
88unlock:
89 mutex_unlock(&dev->struct_mutex);
90 return ret;
91}
92
93/**
94 * psb_gem_create - create a mappable object
95 * @file: the DRM file of the client
96 * @dev: our device
97 * @size: the size requested
98 * @handlep: returned handle (opaque number)
99 *
100 * Create a GEM object, fill in the boilerplate and attach a handle to
101 * it so that userspace can speak about it. This does the core work
102 * for the various methods that do/will create GEM objects for things
103 */
104static int psb_gem_create(struct drm_file *file,
105 struct drm_device *dev, uint64_t size, uint32_t *handlep)
106{
107 struct gtt_range *r;
108 int ret;
109 u32 handle;
110
111 size = roundup(size, PAGE_SIZE);
112
113 /* Allocate our object - for now a direct gtt range which is not
114 stolen memory backed */
115 r = psb_gtt_alloc_range(dev, size, "gem", 0);
116 if (r == NULL) {
117 dev_err(dev->dev, "no memory for %lld byte GEM object\n", size);
118 return -ENOSPC;
119 }
120 /* Initialize the extra goodies GEM needs to do all the hard work */
121 if (drm_gem_object_init(dev, &r->gem, size) != 0) {
122 psb_gtt_free_range(dev, r);
123 /* GEM doesn't give an error code so use -ENOMEM */
124 dev_err(dev->dev, "GEM init failed for %lld\n", size);
125 return -ENOMEM;
126 }
127 /* Give the object a handle so we can carry it more easily */
128 ret = drm_gem_handle_create(file, &r->gem, &handle);
129 if (ret) {
130 dev_err(dev->dev, "GEM handle failed for %p, %lld\n",
131 &r->gem, size);
132 drm_gem_object_release(&r->gem);
133 psb_gtt_free_range(dev, r);
134 return ret;
135 }
136 /* We have the initial and handle reference but need only one now */
137 drm_gem_object_unreference(&r->gem);
138 *handlep = handle;
139 return 0;
140}
141
142/**
143 * psb_gem_dumb_create - create a dumb buffer
144 * @drm_file: our client file
145 * @dev: our device
146 * @args: the requested arguments copied from userspace
147 *
148 * Allocate a buffer suitable for use for a frame buffer of the
149 * form described by user space. Give userspace a handle by which
150 * to reference it.
151 */
152int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
153 struct drm_mode_create_dumb *args)
154{
155 args->pitch = ALIGN(args->width * ((args->bpp + 7) / 8), 64);
156 args->size = args->pitch * args->height;
157 return psb_gem_create(file, dev, args->size, &args->handle);
158}
159
160/**
161 * psb_gem_dumb_destroy - destroy a dumb buffer
162 * @file: client file
163 * @dev: our DRM device
164 * @handle: the object handle
165 *
166 * Destroy a handle that was created via psb_gem_dumb_create, at least
167 * we hope it was created that way. i915 seems to assume the caller
168 * does the checking but that might be worth review ! FIXME
169 */
170int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
171 uint32_t handle)
172{
173 /* No special work needed, drop the reference and see what falls out */
174 return drm_gem_handle_delete(file, handle);
175}
176
177/**
178 * psb_gem_fault - pagefault handler for GEM objects
179 * @vma: the VMA of the GEM object
180 * @vmf: fault detail
181 *
182 * Invoked when a fault occurs on an mmap of a GEM managed area. GEM
183 * does most of the work for us including the actual map/unmap calls
184 * but we need to do the actual page work.
185 *
186 * This code eventually needs to handle faulting objects in and out
187 * of the GTT and repacking it when we run out of space. We can put
188 * that off for now and for our simple uses
189 *
190 * The VMA was set up by GEM. In doing so it also ensured that the
191 * vma->vm_private_data points to the GEM object that is backing this
192 * mapping.
193 */
194int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
195{
196 struct drm_gem_object *obj;
197 struct gtt_range *r;
198 int ret;
199 unsigned long pfn;
200 pgoff_t page_offset;
201 struct drm_device *dev;
202 struct drm_psb_private *dev_priv;
203
204 obj = vma->vm_private_data; /* GEM object */
205 dev = obj->dev;
206 dev_priv = dev->dev_private;
207
208 r = container_of(obj, struct gtt_range, gem); /* Get the gtt range */
209
210 /* Make sure we don't parallel update on a fault, nor move or remove
211 something from beneath our feet */
212 mutex_lock(&dev->struct_mutex);
213
214 /* For now the mmap pins the object and it stays pinned. As things
215 stand that will do us no harm */
216 if (r->mmapping == 0) {
217 ret = psb_gtt_pin(r);
218 if (ret < 0) {
219 dev_err(dev->dev, "gma500: pin failed: %d\n", ret);
220 goto fail;
221 }
222 r->mmapping = 1;
223 }
224
225 /* Page relative to the VMA start - we must calculate this ourselves
226 because vmf->pgoff is the fake GEM offset */
227 page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
228 >> PAGE_SHIFT;
229
230 /* CPU view of the page, don't go via the GART for CPU writes */
231 if (r->stolen)
232 pfn = (dev_priv->stolen_base + r->offset) >> PAGE_SHIFT;
233 else
234 pfn = page_to_pfn(r->pages[page_offset]);
235 ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
236
237fail:
238 mutex_unlock(&dev->struct_mutex);
239 switch (ret) {
240 case 0:
241 case -ERESTARTSYS:
242 case -EINTR:
243 return VM_FAULT_NOPAGE;
244 case -ENOMEM:
245 return VM_FAULT_OOM;
246 default:
247 return VM_FAULT_SIGBUS;
248 }
249}
250
251static int psb_gem_create_stolen(struct drm_file *file, struct drm_device *dev,
252 int size, u32 *handle)
253{
254 struct gtt_range *gtt = psb_gtt_alloc_range(dev, size, "gem", 1);
255 if (gtt == NULL)
256 return -ENOMEM;
257 if (drm_gem_private_object_init(dev, &gtt->gem, size) != 0)
258 goto free_gtt;
259 if (drm_gem_handle_create(file, &gtt->gem, handle) == 0)
260 return 0;
261free_gtt:
262 psb_gtt_free_range(dev, gtt);
263 return -ENOMEM;
264}
265
266/*
267 * GEM interfaces for our specific client
268 */
269int psb_gem_create_ioctl(struct drm_device *dev, void *data,
270 struct drm_file *file)
271{
272 struct drm_psb_gem_create *args = data;
273 int ret;
274 if (args->flags & GMA_GEM_CREATE_STOLEN) {
275 ret = psb_gem_create_stolen(file, dev, args->size,
276 &args->handle);
277 if (ret == 0)
278 return 0;
279 /* Fall throguh */
280 args->flags &= ~GMA_GEM_CREATE_STOLEN;
281 }
282 return psb_gem_create(file, dev, args->size, &args->handle);
283}
284
285int psb_gem_mmap_ioctl(struct drm_device *dev, void *data,
286 struct drm_file *file)
287{
288 struct drm_psb_gem_mmap *args = data;
289 return dev->driver->dumb_map_offset(file, dev,
290 args->handle, &args->offset);
291}
292
diff --git a/drivers/gpu/drm/gma500/gem_glue.c b/drivers/gpu/drm/gma500/gem_glue.c
new file mode 100644
index 00000000000..daac1212065
--- /dev/null
+++ b/drivers/gpu/drm/gma500/gem_glue.c
@@ -0,0 +1,89 @@
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 <drm/drmP.h>
21#include <drm/drm.h>
22
23void drm_gem_object_release_wrap(struct drm_gem_object *obj)
24{
25 /* Remove the list map if one is present */
26 if (obj->map_list.map) {
27 struct drm_gem_mm *mm = obj->dev->mm_private;
28 struct drm_map_list *list = &obj->map_list;
29 drm_ht_remove_item(&mm->offset_hash, &list->hash);
30 drm_mm_put_block(list->file_offset_node);
31 kfree(list->map);
32 list->map = NULL;
33 }
34 drm_gem_object_release(obj);
35}
36
37/**
38 * gem_create_mmap_offset - invent an mmap offset
39 * @obj: our object
40 *
41 * Standard implementation of offset generation for mmap as is
42 * duplicated in several drivers. This belongs in GEM.
43 */
44int gem_create_mmap_offset(struct drm_gem_object *obj)
45{
46 struct drm_device *dev = obj->dev;
47 struct drm_gem_mm *mm = dev->mm_private;
48 struct drm_map_list *list;
49 struct drm_local_map *map;
50 int ret;
51
52 list = &obj->map_list;
53 list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
54 if (list->map == NULL)
55 return -ENOMEM;
56 map = list->map;
57 map->type = _DRM_GEM;
58 map->size = obj->size;
59 map->handle = obj;
60
61 list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
62 obj->size / PAGE_SIZE, 0, 0);
63 if (!list->file_offset_node) {
64 dev_err(dev->dev, "failed to allocate offset for bo %d\n",
65 obj->name);
66 ret = -ENOSPC;
67 goto free_it;
68 }
69 list->file_offset_node = drm_mm_get_block(list->file_offset_node,
70 obj->size / PAGE_SIZE, 0);
71 if (!list->file_offset_node) {
72 ret = -ENOMEM;
73 goto free_it;
74 }
75 list->hash.key = list->file_offset_node->start;
76 ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
77 if (ret) {
78 dev_err(dev->dev, "failed to add to map hash\n");
79 goto free_mm;
80 }
81 return 0;
82
83free_mm:
84 drm_mm_put_block(list->file_offset_node);
85free_it:
86 kfree(list->map);
87 list->map = NULL;
88 return ret;
89}
diff --git a/drivers/gpu/drm/gma500/gem_glue.h b/drivers/gpu/drm/gma500/gem_glue.h
new file mode 100644
index 00000000000..ce5ce30f74d
--- /dev/null
+++ b/drivers/gpu/drm/gma500/gem_glue.h
@@ -0,0 +1,2 @@
1extern void drm_gem_object_release_wrap(struct drm_gem_object *obj);
2extern int gem_create_mmap_offset(struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
new file mode 100644
index 00000000000..e770bd190a5
--- /dev/null
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -0,0 +1,553 @@
1/*
2 * Copyright (c) 2007, 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 * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
19 * Alan Cox <alan@linux.intel.com>
20 */
21
22#include <drm/drmP.h>
23#include "psb_drv.h"
24
25
26/*
27 * GTT resource allocator - manage page mappings in GTT space
28 */
29
30/**
31 * psb_gtt_mask_pte - generate GTT pte entry
32 * @pfn: page number to encode
33 * @type: type of memory in the GTT
34 *
35 * Set the GTT entry for the appropriate memory type.
36 */
37static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
38{
39 uint32_t mask = PSB_PTE_VALID;
40
41 if (type & PSB_MMU_CACHED_MEMORY)
42 mask |= PSB_PTE_CACHED;
43 if (type & PSB_MMU_RO_MEMORY)
44 mask |= PSB_PTE_RO;
45 if (type & PSB_MMU_WO_MEMORY)
46 mask |= PSB_PTE_WO;
47
48 return (pfn << PAGE_SHIFT) | mask;
49}
50
51/**
52 * psb_gtt_entry - find the GTT entries for a gtt_range
53 * @dev: our DRM device
54 * @r: our GTT range
55 *
56 * Given a gtt_range object return the GTT offset of the page table
57 * entries for this gtt_range
58 */
59u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
60{
61 struct drm_psb_private *dev_priv = dev->dev_private;
62 unsigned long offset;
63
64 offset = r->resource.start - dev_priv->gtt_mem->start;
65
66 return dev_priv->gtt_map + (offset >> PAGE_SHIFT);
67}
68
69/**
70 * psb_gtt_insert - put an object into the GTT
71 * @dev: our DRM device
72 * @r: our GTT range
73 *
74 * Take our preallocated GTT range and insert the GEM object into
75 * the GTT. This is protected via the gtt mutex which the caller
76 * must hold.
77 */
78static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
79{
80 u32 *gtt_slot, pte;
81 struct page **pages;
82 int i;
83
84 if (r->pages == NULL) {
85 WARN_ON(1);
86 return -EINVAL;
87 }
88
89 WARN_ON(r->stolen); /* refcount these maybe ? */
90
91 gtt_slot = psb_gtt_entry(dev, r);
92 pages = r->pages;
93
94 /* Make sure changes are visible to the GPU */
95 set_pages_array_uc(pages, r->npage);
96
97 /* Write our page entries into the GTT itself */
98 for (i = r->roll; i < r->npage; i++) {
99 pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
100 iowrite32(pte, gtt_slot++);
101 }
102 for (i = 0; i < r->roll; i++) {
103 pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
104 iowrite32(pte, gtt_slot++);
105 }
106 /* Make sure all the entries are set before we return */
107 ioread32(gtt_slot - 1);
108
109 return 0;
110}
111
112/**
113 * psb_gtt_remove - remove an object from the GTT
114 * @dev: our DRM device
115 * @r: our GTT range
116 *
117 * Remove a preallocated GTT range from the GTT. Overwrite all the
118 * page table entries with the dummy page. This is protected via the gtt
119 * mutex which the caller must hold.
120 */
121static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
122{
123 struct drm_psb_private *dev_priv = dev->dev_private;
124 u32 *gtt_slot, pte;
125 int i;
126
127 WARN_ON(r->stolen);
128
129 gtt_slot = psb_gtt_entry(dev, r);
130 pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);
131
132 for (i = 0; i < r->npage; i++)
133 iowrite32(pte, gtt_slot++);
134 ioread32(gtt_slot - 1);
135 set_pages_array_wb(r->pages, r->npage);
136}
137
138/**
139 * psb_gtt_roll - set scrolling position
140 * @dev: our DRM device
141 * @r: the gtt mapping we are using
142 * @roll: roll offset
143 *
144 * Roll an existing pinned mapping by moving the pages through the GTT.
145 * This allows us to implement hardware scrolling on the consoles without
146 * a 2D engine
147 */
148void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll)
149{
150 u32 *gtt_slot, pte;
151 int i;
152
153 if (roll >= r->npage) {
154 WARN_ON(1);
155 return;
156 }
157
158 r->roll = roll;
159
160 /* Not currently in the GTT - no worry we will write the mapping at
161 the right position when it gets pinned */
162 if (!r->stolen && !r->in_gart)
163 return;
164
165 gtt_slot = psb_gtt_entry(dev, r);
166
167 for (i = r->roll; i < r->npage; i++) {
168 pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
169 iowrite32(pte, gtt_slot++);
170 }
171 for (i = 0; i < r->roll; i++) {
172 pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
173 iowrite32(pte, gtt_slot++);
174 }
175 ioread32(gtt_slot - 1);
176}
177
178/**
179 * psb_gtt_attach_pages - attach and pin GEM pages
180 * @gt: the gtt range
181 *
182 * Pin and build an in kernel list of the pages that back our GEM object.
183 * While we hold this the pages cannot be swapped out. This is protected
184 * via the gtt mutex which the caller must hold.
185 */
186static int psb_gtt_attach_pages(struct gtt_range *gt)
187{
188 struct inode *inode;
189 struct address_space *mapping;
190 int i;
191 struct page *p;
192 int pages = gt->gem.size / PAGE_SIZE;
193
194 WARN_ON(gt->pages);
195
196 /* This is the shared memory object that backs the GEM resource */
197 inode = gt->gem.filp->f_path.dentry->d_inode;
198 mapping = inode->i_mapping;
199
200 gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL);
201 if (gt->pages == NULL)
202 return -ENOMEM;
203 gt->npage = pages;
204
205 for (i = 0; i < pages; i++) {
206 /* FIXME: needs updating as per mail from Hugh Dickins */
207 p = read_cache_page_gfp(mapping, i,
208 __GFP_COLD | GFP_KERNEL);
209 if (IS_ERR(p))
210 goto err;
211 gt->pages[i] = p;
212 }
213 return 0;
214
215err:
216 while (i--)
217 page_cache_release(gt->pages[i]);
218 kfree(gt->pages);
219 gt->pages = NULL;
220 return PTR_ERR(p);
221}
222
223/**
224 * psb_gtt_detach_pages - attach and pin GEM pages
225 * @gt: the gtt range
226 *
227 * Undo the effect of psb_gtt_attach_pages. At this point the pages
228 * must have been removed from the GTT as they could now be paged out
229 * and move bus address. This is protected via the gtt mutex which the
230 * caller must hold.
231 */
232static void psb_gtt_detach_pages(struct gtt_range *gt)
233{
234 int i;
235 for (i = 0; i < gt->npage; i++) {
236 /* FIXME: do we need to force dirty */
237 set_page_dirty(gt->pages[i]);
238 page_cache_release(gt->pages[i]);
239 }
240 kfree(gt->pages);
241 gt->pages = NULL;
242}
243
244/**
245 * psb_gtt_pin - pin pages into the GTT
246 * @gt: range to pin
247 *
248 * Pin a set of pages into the GTT. The pins are refcounted so that
249 * multiple pins need multiple unpins to undo.
250 *
251 * Non GEM backed objects treat this as a no-op as they are always GTT
252 * backed objects.
253 */
254int psb_gtt_pin(struct gtt_range *gt)
255{
256 int ret = 0;
257 struct drm_device *dev = gt->gem.dev;
258 struct drm_psb_private *dev_priv = dev->dev_private;
259
260 mutex_lock(&dev_priv->gtt_mutex);
261
262 if (gt->in_gart == 0 && gt->stolen == 0) {
263 ret = psb_gtt_attach_pages(gt);
264 if (ret < 0)
265 goto out;
266 ret = psb_gtt_insert(dev, gt);
267 if (ret < 0) {
268 psb_gtt_detach_pages(gt);
269 goto out;
270 }
271 }
272 gt->in_gart++;
273out:
274 mutex_unlock(&dev_priv->gtt_mutex);
275 return ret;
276}
277
278/**
279 * psb_gtt_unpin - Drop a GTT pin requirement
280 * @gt: range to pin
281 *
282 * Undoes the effect of psb_gtt_pin. On the last drop the GEM object
283 * will be removed from the GTT which will also drop the page references
284 * and allow the VM to clean up or page stuff.
285 *
286 * Non GEM backed objects treat this as a no-op as they are always GTT
287 * backed objects.
288 */
289void psb_gtt_unpin(struct gtt_range *gt)
290{
291 struct drm_device *dev = gt->gem.dev;
292 struct drm_psb_private *dev_priv = dev->dev_private;
293
294 mutex_lock(&dev_priv->gtt_mutex);
295
296 WARN_ON(!gt->in_gart);
297
298 gt->in_gart--;
299 if (gt->in_gart == 0 && gt->stolen == 0) {
300 psb_gtt_remove(dev, gt);
301 psb_gtt_detach_pages(gt);
302 }
303 mutex_unlock(&dev_priv->gtt_mutex);
304}
305
306/*
307 * GTT resource allocator - allocate and manage GTT address space
308 */
309
310/**
311 * psb_gtt_alloc_range - allocate GTT address space
312 * @dev: Our DRM device
313 * @len: length (bytes) of address space required
314 * @name: resource name
315 * @backed: resource should be backed by stolen pages
316 *
317 * Ask the kernel core to find us a suitable range of addresses
318 * to use for a GTT mapping.
319 *
320 * Returns a gtt_range structure describing the object, or NULL on
321 * error. On successful return the resource is both allocated and marked
322 * as in use.
323 */
324struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
325 const char *name, int backed)
326{
327 struct drm_psb_private *dev_priv = dev->dev_private;
328 struct gtt_range *gt;
329 struct resource *r = dev_priv->gtt_mem;
330 int ret;
331 unsigned long start, end;
332
333 if (backed) {
334 /* The start of the GTT is the stolen pages */
335 start = r->start;
336 end = r->start + dev_priv->gtt.stolen_size - 1;
337 } else {
338 /* The rest we will use for GEM backed objects */
339 start = r->start + dev_priv->gtt.stolen_size;
340 end = r->end;
341 }
342
343 gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL);
344 if (gt == NULL)
345 return NULL;
346 gt->resource.name = name;
347 gt->stolen = backed;
348 gt->in_gart = backed;
349 gt->roll = 0;
350 /* Ensure this is set for non GEM objects */
351 gt->gem.dev = dev;
352 ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,
353 len, start, end, PAGE_SIZE, NULL, NULL);
354 if (ret == 0) {
355 gt->offset = gt->resource.start - r->start;
356 return gt;
357 }
358 kfree(gt);
359 return NULL;
360}
361
362/**
363 * psb_gtt_free_range - release GTT address space
364 * @dev: our DRM device
365 * @gt: a mapping created with psb_gtt_alloc_range
366 *
367 * Release a resource that was allocated with psb_gtt_alloc_range. If the
368 * object has been pinned by mmap users we clean this up here currently.
369 */
370void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
371{
372 /* Undo the mmap pin if we are destroying the object */
373 if (gt->mmapping) {
374 psb_gtt_unpin(gt);
375 gt->mmapping = 0;
376 }
377 WARN_ON(gt->in_gart && !gt->stolen);
378 release_resource(&gt->resource);
379 kfree(gt);
380}
381
382void psb_gtt_alloc(struct drm_device *dev)
383{
384 struct drm_psb_private *dev_priv = dev->dev_private;
385 init_rwsem(&dev_priv->gtt.sem);
386}
387
388void psb_gtt_takedown(struct drm_device *dev)
389{
390 struct drm_psb_private *dev_priv = dev->dev_private;
391
392 if (dev_priv->gtt_map) {
393 iounmap(dev_priv->gtt_map);
394 dev_priv->gtt_map = NULL;
395 }
396 if (dev_priv->gtt_initialized) {
397 pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
398 dev_priv->gmch_ctrl);
399 PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
400 (void) PSB_RVDC32(PSB_PGETBL_CTL);
401 }
402 if (dev_priv->vram_addr)
403 iounmap(dev_priv->gtt_map);
404}
405
406int psb_gtt_init(struct drm_device *dev, int resume)
407{
408 struct drm_psb_private *dev_priv = dev->dev_private;
409 unsigned gtt_pages;
410 unsigned long stolen_size, vram_stolen_size;
411 unsigned i, num_pages;
412 unsigned pfn_base;
413 uint32_t vram_pages;
414 uint32_t dvmt_mode = 0;
415 struct psb_gtt *pg;
416
417 int ret = 0;
418 uint32_t pte;
419
420 mutex_init(&dev_priv->gtt_mutex);
421
422 psb_gtt_alloc(dev);
423 pg = &dev_priv->gtt;
424
425 /* Enable the GTT */
426 pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
427 pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
428 dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
429
430 dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
431 PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
432 (void) PSB_RVDC32(PSB_PGETBL_CTL);
433
434 /* The root resource we allocate address space from */
435 dev_priv->gtt_initialized = 1;
436
437 pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
438
439 /*
440 * The video mmu has a hw bug when accessing 0x0D0000000.
441 * Make gatt start at 0x0e000,0000. This doesn't actually
442 * matter for us but may do if the video acceleration ever
443 * gets opened up.
444 */
445 pg->mmu_gatt_start = 0xE0000000;
446
447 pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
448 gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE)
449 >> PAGE_SHIFT;
450 /* Some CDV firmware doesn't report this currently. In which case the
451 system has 64 gtt pages */
452 if (pg->gtt_start == 0 || gtt_pages == 0) {
453 dev_err(dev->dev, "GTT PCI BAR not initialized.\n");
454 gtt_pages = 64;
455 pg->gtt_start = dev_priv->pge_ctl;
456 }
457
458 pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
459 pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
460 >> PAGE_SHIFT;
461 dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE];
462
463 if (pg->gatt_pages == 0 || pg->gatt_start == 0) {
464 static struct resource fudge; /* Preferably peppermint */
465 /* This can occur on CDV SDV systems. Fudge it in this case.
466 We really don't care what imaginary space is being allocated
467 at this point */
468 dev_err(dev->dev, "GATT PCI BAR not initialized.\n");
469 pg->gatt_start = 0x40000000;
470 pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT;
471 /* This is a little confusing but in fact the GTT is providing
472 a view from the GPU into memory and not vice versa. As such
473 this is really allocating space that is not the same as the
474 CPU address space on CDV */
475 fudge.start = 0x40000000;
476 fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1;
477 fudge.name = "fudge";
478 fudge.flags = IORESOURCE_MEM;
479 dev_priv->gtt_mem = &fudge;
480 }
481
482 pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base);
483 vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base
484 - PAGE_SIZE;
485
486 stolen_size = vram_stolen_size;
487
488 printk(KERN_INFO "Stolen memory information\n");
489 printk(KERN_INFO " base in RAM: 0x%x\n", dev_priv->stolen_base);
490 printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
491 vram_stolen_size/1024);
492 dvmt_mode = (dev_priv->gmch_ctrl >> 4) & 0x7;
493 printk(KERN_INFO " the correct size should be: %dM(dvmt mode=%d)\n",
494 (dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode);
495
496 if (resume && (gtt_pages != pg->gtt_pages) &&
497 (stolen_size != pg->stolen_size)) {
498 dev_err(dev->dev, "GTT resume error.\n");
499 ret = -EINVAL;
500 goto out_err;
501 }
502
503 pg->gtt_pages = gtt_pages;
504 pg->stolen_size = stolen_size;
505 dev_priv->vram_stolen_size = vram_stolen_size;
506
507 /*
508 * Map the GTT and the stolen memory area
509 */
510 dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start,
511 gtt_pages << PAGE_SHIFT);
512 if (!dev_priv->gtt_map) {
513 dev_err(dev->dev, "Failure to map gtt.\n");
514 ret = -ENOMEM;
515 goto out_err;
516 }
517
518 dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size);
519 if (!dev_priv->vram_addr) {
520 dev_err(dev->dev, "Failure to map stolen base.\n");
521 ret = -ENOMEM;
522 goto out_err;
523 }
524
525 /*
526 * Insert vram stolen pages into the GTT
527 */
528
529 pfn_base = dev_priv->stolen_base >> PAGE_SHIFT;
530 vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT;
531 printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
532 num_pages, pfn_base << PAGE_SHIFT, 0);
533 for (i = 0; i < num_pages; ++i) {
534 pte = psb_gtt_mask_pte(pfn_base + i, 0);
535 iowrite32(pte, dev_priv->gtt_map + i);
536 }
537
538 /*
539 * Init rest of GTT to the scratch page to avoid accidents or scribbles
540 */
541
542 pfn_base = page_to_pfn(dev_priv->scratch_page);
543 pte = psb_gtt_mask_pte(pfn_base, 0);
544 for (; i < gtt_pages; ++i)
545 iowrite32(pte, dev_priv->gtt_map + i);
546
547 (void) ioread32(dev_priv->gtt_map + i - 1);
548 return 0;
549
550out_err:
551 psb_gtt_takedown(dev);
552 return ret;
553}
diff --git a/drivers/gpu/drm/gma500/gtt.h b/drivers/gpu/drm/gma500/gtt.h
new file mode 100644
index 00000000000..aa1742387f5
--- /dev/null
+++ b/drivers/gpu/drm/gma500/gtt.h
@@ -0,0 +1,64 @@
1/**************************************************************************
2 * Copyright (c) 2007-2008, 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#ifndef _PSB_GTT_H_
21#define _PSB_GTT_H_
22
23#include <drm/drmP.h>
24
25/* This wants cleaning up with respect to the psb_dev and un-needed stuff */
26struct psb_gtt {
27 uint32_t gatt_start;
28 uint32_t mmu_gatt_start;
29 uint32_t gtt_start;
30 uint32_t gtt_phys_start;
31 unsigned gtt_pages;
32 unsigned gatt_pages;
33 unsigned long stolen_size;
34 unsigned long vram_stolen_size;
35 struct rw_semaphore sem;
36};
37
38/* Exported functions */
39extern int psb_gtt_init(struct drm_device *dev, int resume);
40extern void psb_gtt_takedown(struct drm_device *dev);
41
42/* Each gtt_range describes an allocation in the GTT area */
43struct gtt_range {
44 struct resource resource; /* Resource for our allocation */
45 u32 offset; /* GTT offset of our object */
46 struct drm_gem_object gem; /* GEM high level stuff */
47 int in_gart; /* Currently in the GART (ref ct) */
48 bool stolen; /* Backed from stolen RAM */
49 bool mmapping; /* Is mmappable */
50 struct page **pages; /* Backing pages if present */
51 int npage; /* Number of backing pages */
52 int roll; /* Roll applied to the GTT entries */
53};
54
55extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
56 const char *name, int backed);
57extern void psb_gtt_kref_put(struct gtt_range *gt);
58extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt);
59extern int psb_gtt_pin(struct gtt_range *gt);
60extern void psb_gtt_unpin(struct gtt_range *gt);
61extern void psb_gtt_roll(struct drm_device *dev,
62 struct gtt_range *gt, int roll);
63
64#endif
diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c
new file mode 100644
index 00000000000..d4d0c5b8bf9
--- /dev/null
+++ b/drivers/gpu/drm/gma500/intel_bios.c
@@ -0,0 +1,303 @@
1/*
2 * Copyright (c) 2006 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 *
20 */
21#include <drm/drmP.h>
22#include <drm/drm.h>
23#include "gma_drm.h"
24#include "psb_drv.h"
25#include "psb_intel_drv.h"
26#include "psb_intel_reg.h"
27#include "intel_bios.h"
28
29
30static void *find_section(struct bdb_header *bdb, int section_id)
31{
32 u8 *base = (u8 *)bdb;
33 int index = 0;
34 u16 total, current_size;
35 u8 current_id;
36
37 /* skip to first section */
38 index += bdb->header_size;
39 total = bdb->bdb_size;
40
41 /* walk the sections looking for section_id */
42 while (index < total) {
43 current_id = *(base + index);
44 index++;
45 current_size = *((u16 *)(base + index));
46 index += 2;
47 if (current_id == section_id)
48 return base + index;
49 index += current_size;
50 }
51
52 return NULL;
53}
54
55static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
56 struct lvds_dvo_timing *dvo_timing)
57{
58 panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
59 dvo_timing->hactive_lo;
60 panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
61 ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
62 panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
63 dvo_timing->hsync_pulse_width;
64 panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
65 ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
66
67 panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
68 dvo_timing->vactive_lo;
69 panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
70 dvo_timing->vsync_off;
71 panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
72 dvo_timing->vsync_pulse_width;
73 panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
74 ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
75 panel_fixed_mode->clock = dvo_timing->clock * 10;
76 panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
77
78 /* Some VBTs have bogus h/vtotal values */
79 if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
80 panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
81 if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
82 panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
83
84 drm_mode_set_name(panel_fixed_mode);
85}
86
87static void parse_backlight_data(struct drm_psb_private *dev_priv,
88 struct bdb_header *bdb)
89{
90 struct bdb_lvds_backlight *vbt_lvds_bl = NULL;
91 struct bdb_lvds_backlight *lvds_bl;
92 u8 p_type = 0;
93 void *bl_start = NULL;
94 struct bdb_lvds_options *lvds_opts
95 = find_section(bdb, BDB_LVDS_OPTIONS);
96
97 dev_priv->lvds_bl = NULL;
98
99 if (lvds_opts)
100 p_type = lvds_opts->panel_type;
101 else
102 return;
103
104 bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT);
105 vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type;
106
107 lvds_bl = kzalloc(sizeof(*vbt_lvds_bl), GFP_KERNEL);
108 if (!lvds_bl) {
109 dev_err(dev_priv->dev->dev, "out of memory for backlight data\n");
110 return;
111 }
112 memcpy(lvds_bl, vbt_lvds_bl, sizeof(*vbt_lvds_bl));
113 dev_priv->lvds_bl = lvds_bl;
114}
115
116/* Try to find integrated panel data */
117static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,
118 struct bdb_header *bdb)
119{
120 struct bdb_lvds_options *lvds_options;
121 struct bdb_lvds_lfp_data *lvds_lfp_data;
122 struct bdb_lvds_lfp_data_entry *entry;
123 struct lvds_dvo_timing *dvo_timing;
124 struct drm_display_mode *panel_fixed_mode;
125
126 /* Defaults if we can't find VBT info */
127 dev_priv->lvds_dither = 0;
128 dev_priv->lvds_vbt = 0;
129
130 lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
131 if (!lvds_options)
132 return;
133
134 dev_priv->lvds_dither = lvds_options->pixel_dither;
135 if (lvds_options->panel_type == 0xff)
136 return;
137
138 lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
139 if (!lvds_lfp_data)
140 return;
141
142
143 entry = &lvds_lfp_data->data[lvds_options->panel_type];
144 dvo_timing = &entry->dvo_timing;
145
146 panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode),
147 GFP_KERNEL);
148 if (panel_fixed_mode == NULL) {
149 dev_err(dev_priv->dev->dev, "out of memory for fixed panel mode\n");
150 return;
151 }
152
153 dev_priv->lvds_vbt = 1;
154 fill_detail_timing_data(panel_fixed_mode, dvo_timing);
155
156 if (panel_fixed_mode->htotal > 0 && panel_fixed_mode->vtotal > 0) {
157 dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
158 drm_mode_debug_printmodeline(panel_fixed_mode);
159 } else {
160 dev_dbg(dev_priv->dev->dev, "ignoring invalid LVDS VBT\n");
161 dev_priv->lvds_vbt = 0;
162 kfree(panel_fixed_mode);
163 }
164 return;
165}
166
167/* Try to find sdvo panel data */
168static void parse_sdvo_panel_data(struct drm_psb_private *dev_priv,
169 struct bdb_header *bdb)
170{
171 struct bdb_sdvo_lvds_options *sdvo_lvds_options;
172 struct lvds_dvo_timing *dvo_timing;
173 struct drm_display_mode *panel_fixed_mode;
174
175 dev_priv->sdvo_lvds_vbt_mode = NULL;
176
177 sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
178 if (!sdvo_lvds_options)
179 return;
180
181 dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
182 if (!dvo_timing)
183 return;
184
185 panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
186
187 if (!panel_fixed_mode)
188 return;
189
190 fill_detail_timing_data(panel_fixed_mode,
191 dvo_timing + sdvo_lvds_options->panel_type);
192
193 dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;
194
195 return;
196}
197
198static void parse_general_features(struct drm_psb_private *dev_priv,
199 struct bdb_header *bdb)
200{
201 struct bdb_general_features *general;
202
203 /* Set sensible defaults in case we can't find the general block */
204 dev_priv->int_tv_support = 1;
205 dev_priv->int_crt_support = 1;
206
207 general = find_section(bdb, BDB_GENERAL_FEATURES);
208 if (general) {
209 dev_priv->int_tv_support = general->int_tv_support;
210 dev_priv->int_crt_support = general->int_crt_support;
211 dev_priv->lvds_use_ssc = general->enable_ssc;
212
213 if (dev_priv->lvds_use_ssc) {
214 dev_priv->lvds_ssc_freq
215 = general->ssc_freq ? 100 : 96;
216 }
217 }
218}
219
220/**
221 * psb_intel_init_bios - initialize VBIOS settings & find VBT
222 * @dev: DRM device
223 *
224 * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers
225 * to appropriate values.
226 *
227 * VBT existence is a sanity check that is relied on by other i830_bios.c code.
228 * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may
229 * feed an updated VBT back through that, compared to what we'll fetch using
230 * this method of groping around in the BIOS data.
231 *
232 * Returns 0 on success, nonzero on failure.
233 */
234bool psb_intel_init_bios(struct drm_device *dev)
235{
236 struct drm_psb_private *dev_priv = dev->dev_private;
237 struct pci_dev *pdev = dev->pdev;
238 struct vbt_header *vbt = NULL;
239 struct bdb_header *bdb;
240 u8 __iomem *bios;
241 size_t size;
242 int i;
243
244 bios = pci_map_rom(pdev, &size);
245 if (!bios)
246 return -1;
247
248 /* Scour memory looking for the VBT signature */
249 for (i = 0; i + 4 < size; i++) {
250 if (!memcmp(bios + i, "$VBT", 4)) {
251 vbt = (struct vbt_header *)(bios + i);
252 break;
253 }
254 }
255
256 if (!vbt) {
257 dev_err(dev->dev, "VBT signature missing\n");
258 pci_unmap_rom(pdev, bios);
259 return -1;
260 }
261
262 bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset);
263
264 /* Grab useful general definitions */
265 parse_general_features(dev_priv, bdb);
266 parse_lfp_panel_data(dev_priv, bdb);
267 parse_sdvo_panel_data(dev_priv, bdb);
268 parse_backlight_data(dev_priv, bdb);
269
270 pci_unmap_rom(pdev, bios);
271
272 return 0;
273}
274
275/**
276 * Destroy and free VBT data
277 */
278void psb_intel_destroy_bios(struct drm_device *dev)
279{
280 struct drm_psb_private *dev_priv = dev->dev_private;
281 struct drm_display_mode *sdvo_lvds_vbt_mode =
282 dev_priv->sdvo_lvds_vbt_mode;
283 struct drm_display_mode *lfp_lvds_vbt_mode =
284 dev_priv->lfp_lvds_vbt_mode;
285 struct bdb_lvds_backlight *lvds_bl =
286 dev_priv->lvds_bl;
287
288 /*free sdvo panel mode*/
289 if (sdvo_lvds_vbt_mode) {
290 dev_priv->sdvo_lvds_vbt_mode = NULL;
291 kfree(sdvo_lvds_vbt_mode);
292 }
293
294 if (lfp_lvds_vbt_mode) {
295 dev_priv->lfp_lvds_vbt_mode = NULL;
296 kfree(lfp_lvds_vbt_mode);
297 }
298
299 if (lvds_bl) {
300 dev_priv->lvds_bl = NULL;
301 kfree(lvds_bl);
302 }
303}
diff --git a/drivers/gpu/drm/gma500/intel_bios.h b/drivers/gpu/drm/gma500/intel_bios.h
new file mode 100644
index 00000000000..70f1bf01818
--- /dev/null
+++ b/drivers/gpu/drm/gma500/intel_bios.h
@@ -0,0 +1,430 @@
1/*
2 * Copyright (c) 2006 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 *
20 */
21
22#ifndef _I830_BIOS_H_
23#define _I830_BIOS_H_
24
25#include <drm/drmP.h>
26
27struct vbt_header {
28 u8 signature[20]; /**< Always starts with 'VBT$' */
29 u16 version; /**< decimal */
30 u16 header_size; /**< in bytes */
31 u16 vbt_size; /**< in bytes */
32 u8 vbt_checksum;
33 u8 reserved0;
34 u32 bdb_offset; /**< from beginning of VBT */
35 u32 aim_offset[4]; /**< from beginning of VBT */
36} __attribute__((packed));
37
38
39struct bdb_header {
40 u8 signature[16]; /**< Always 'BIOS_DATA_BLOCK' */
41 u16 version; /**< decimal */
42 u16 header_size; /**< in bytes */
43 u16 bdb_size; /**< in bytes */
44};
45
46/* strictly speaking, this is a "skip" block, but it has interesting info */
47struct vbios_data {
48 u8 type; /* 0 == desktop, 1 == mobile */
49 u8 relstage;
50 u8 chipset;
51 u8 lvds_present:1;
52 u8 tv_present:1;
53 u8 rsvd2:6; /* finish byte */
54 u8 rsvd3[4];
55 u8 signon[155];
56 u8 copyright[61];
57 u16 code_segment;
58 u8 dos_boot_mode;
59 u8 bandwidth_percent;
60 u8 rsvd4; /* popup memory size */
61 u8 resize_pci_bios;
62 u8 rsvd5; /* is crt already on ddc2 */
63} __attribute__((packed));
64
65/*
66 * There are several types of BIOS data blocks (BDBs), each block has
67 * an ID and size in the first 3 bytes (ID in first, size in next 2).
68 * Known types are listed below.
69 */
70#define BDB_GENERAL_FEATURES 1
71#define BDB_GENERAL_DEFINITIONS 2
72#define BDB_OLD_TOGGLE_LIST 3
73#define BDB_MODE_SUPPORT_LIST 4
74#define BDB_GENERIC_MODE_TABLE 5
75#define BDB_EXT_MMIO_REGS 6
76#define BDB_SWF_IO 7
77#define BDB_SWF_MMIO 8
78#define BDB_DOT_CLOCK_TABLE 9
79#define BDB_MODE_REMOVAL_TABLE 10
80#define BDB_CHILD_DEVICE_TABLE 11
81#define BDB_DRIVER_FEATURES 12
82#define BDB_DRIVER_PERSISTENCE 13
83#define BDB_EXT_TABLE_PTRS 14
84#define BDB_DOT_CLOCK_OVERRIDE 15
85#define BDB_DISPLAY_SELECT 16
86/* 17 rsvd */
87#define BDB_DRIVER_ROTATION 18
88#define BDB_DISPLAY_REMOVE 19
89#define BDB_OEM_CUSTOM 20
90#define BDB_EFP_LIST 21 /* workarounds for VGA hsync/vsync */
91#define BDB_SDVO_LVDS_OPTIONS 22
92#define BDB_SDVO_PANEL_DTDS 23
93#define BDB_SDVO_LVDS_PNP_IDS 24
94#define BDB_SDVO_LVDS_POWER_SEQ 25
95#define BDB_TV_OPTIONS 26
96#define BDB_LVDS_OPTIONS 40
97#define BDB_LVDS_LFP_DATA_PTRS 41
98#define BDB_LVDS_LFP_DATA 42
99#define BDB_LVDS_BACKLIGHT 43
100#define BDB_LVDS_POWER 44
101#define BDB_SKIP 254 /* VBIOS private block, ignore */
102
103struct bdb_general_features {
104 /* bits 1 */
105 u8 panel_fitting:2;
106 u8 flexaim:1;
107 u8 msg_enable:1;
108 u8 clear_screen:3;
109 u8 color_flip:1;
110
111 /* bits 2 */
112 u8 download_ext_vbt:1;
113 u8 enable_ssc:1;
114 u8 ssc_freq:1;
115 u8 enable_lfp_on_override:1;
116 u8 disable_ssc_ddt:1;
117 u8 rsvd8:3; /* finish byte */
118
119 /* bits 3 */
120 u8 disable_smooth_vision:1;
121 u8 single_dvi:1;
122 u8 rsvd9:6; /* finish byte */
123
124 /* bits 4 */
125 u8 legacy_monitor_detect;
126
127 /* bits 5 */
128 u8 int_crt_support:1;
129 u8 int_tv_support:1;
130 u8 rsvd11:6; /* finish byte */
131} __attribute__((packed));
132
133struct bdb_general_definitions {
134 /* DDC GPIO */
135 u8 crt_ddc_gmbus_pin;
136
137 /* DPMS bits */
138 u8 dpms_acpi:1;
139 u8 skip_boot_crt_detect:1;
140 u8 dpms_aim:1;
141 u8 rsvd1:5; /* finish byte */
142
143 /* boot device bits */
144 u8 boot_display[2];
145 u8 child_dev_size;
146
147 /* device info */
148 u8 tv_or_lvds_info[33];
149 u8 dev1[33];
150 u8 dev2[33];
151 u8 dev3[33];
152 u8 dev4[33];
153 /* may be another device block here on some platforms */
154};
155
156struct bdb_lvds_options {
157 u8 panel_type;
158 u8 rsvd1;
159 /* LVDS capabilities, stored in a dword */
160 u8 pfit_mode:2;
161 u8 pfit_text_mode_enhanced:1;
162 u8 pfit_gfx_mode_enhanced:1;
163 u8 pfit_ratio_auto:1;
164 u8 pixel_dither:1;
165 u8 lvds_edid:1;
166 u8 rsvd2:1;
167 u8 rsvd4;
168} __attribute__((packed));
169
170struct bdb_lvds_backlight {
171 u8 type:2;
172 u8 pol:1;
173 u8 gpio:3;
174 u8 gmbus:2;
175 u16 freq;
176 u8 minbrightness;
177 u8 i2caddr;
178 u8 brightnesscmd;
179 /*FIXME: more...*/
180} __attribute__((packed));
181
182/* LFP pointer table contains entries to the struct below */
183struct bdb_lvds_lfp_data_ptr {
184 u16 fp_timing_offset; /* offsets are from start of bdb */
185 u8 fp_table_size;
186 u16 dvo_timing_offset;
187 u8 dvo_table_size;
188 u16 panel_pnp_id_offset;
189 u8 pnp_table_size;
190} __attribute__((packed));
191
192struct bdb_lvds_lfp_data_ptrs {
193 u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
194 struct bdb_lvds_lfp_data_ptr ptr[16];
195} __attribute__((packed));
196
197/* LFP data has 3 blocks per entry */
198struct lvds_fp_timing {
199 u16 x_res;
200 u16 y_res;
201 u32 lvds_reg;
202 u32 lvds_reg_val;
203 u32 pp_on_reg;
204 u32 pp_on_reg_val;
205 u32 pp_off_reg;
206 u32 pp_off_reg_val;
207 u32 pp_cycle_reg;
208 u32 pp_cycle_reg_val;
209 u32 pfit_reg;
210 u32 pfit_reg_val;
211 u16 terminator;
212} __attribute__((packed));
213
214struct lvds_dvo_timing {
215 u16 clock; /**< In 10khz */
216 u8 hactive_lo;
217 u8 hblank_lo;
218 u8 hblank_hi:4;
219 u8 hactive_hi:4;
220 u8 vactive_lo;
221 u8 vblank_lo;
222 u8 vblank_hi:4;
223 u8 vactive_hi:4;
224 u8 hsync_off_lo;
225 u8 hsync_pulse_width;
226 u8 vsync_pulse_width:4;
227 u8 vsync_off:4;
228 u8 rsvd0:6;
229 u8 hsync_off_hi:2;
230 u8 h_image;
231 u8 v_image;
232 u8 max_hv;
233 u8 h_border;
234 u8 v_border;
235 u8 rsvd1:3;
236 u8 digital:2;
237 u8 vsync_positive:1;
238 u8 hsync_positive:1;
239 u8 rsvd2:1;
240} __attribute__((packed));
241
242struct lvds_pnp_id {
243 u16 mfg_name;
244 u16 product_code;
245 u32 serial;
246 u8 mfg_week;
247 u8 mfg_year;
248} __attribute__((packed));
249
250struct bdb_lvds_lfp_data_entry {
251 struct lvds_fp_timing fp_timing;
252 struct lvds_dvo_timing dvo_timing;
253 struct lvds_pnp_id pnp_id;
254} __attribute__((packed));
255
256struct bdb_lvds_lfp_data {
257 struct bdb_lvds_lfp_data_entry data[16];
258} __attribute__((packed));
259
260struct aimdb_header {
261 char signature[16];
262 char oem_device[20];
263 u16 aimdb_version;
264 u16 aimdb_header_size;
265 u16 aimdb_size;
266} __attribute__((packed));
267
268struct aimdb_block {
269 u8 aimdb_id;
270 u16 aimdb_size;
271} __attribute__((packed));
272
273struct vch_panel_data {
274 u16 fp_timing_offset;
275 u8 fp_timing_size;
276 u16 dvo_timing_offset;
277 u8 dvo_timing_size;
278 u16 text_fitting_offset;
279 u8 text_fitting_size;
280 u16 graphics_fitting_offset;
281 u8 graphics_fitting_size;
282} __attribute__((packed));
283
284struct vch_bdb_22 {
285 struct aimdb_block aimdb_block;
286 struct vch_panel_data panels[16];
287} __attribute__((packed));
288
289struct bdb_sdvo_lvds_options {
290 u8 panel_backlight;
291 u8 h40_set_panel_type;
292 u8 panel_type;
293 u8 ssc_clk_freq;
294 u16 als_low_trip;
295 u16 als_high_trip;
296 u8 sclalarcoeff_tab_row_num;
297 u8 sclalarcoeff_tab_row_size;
298 u8 coefficient[8];
299 u8 panel_misc_bits_1;
300 u8 panel_misc_bits_2;
301 u8 panel_misc_bits_3;
302 u8 panel_misc_bits_4;
303} __attribute__((packed));
304
305
306extern bool psb_intel_init_bios(struct drm_device *dev);
307extern void psb_intel_destroy_bios(struct drm_device *dev);
308
309/*
310 * Driver<->VBIOS interaction occurs through scratch bits in
311 * GR18 & SWF*.
312 */
313
314/* GR18 bits are set on display switch and hotkey events */
315#define GR18_DRIVER_SWITCH_EN (1<<7) /* 0: VBIOS control, 1: driver control */
316#define GR18_HOTKEY_MASK 0x78 /* See also SWF4 15:0 */
317#define GR18_HK_NONE (0x0<<3)
318#define GR18_HK_LFP_STRETCH (0x1<<3)
319#define GR18_HK_TOGGLE_DISP (0x2<<3)
320#define GR18_HK_DISP_SWITCH (0x4<<3) /* see SWF14 15:0 for what to enable */
321#define GR18_HK_POPUP_DISABLED (0x6<<3)
322#define GR18_HK_POPUP_ENABLED (0x7<<3)
323#define GR18_HK_PFIT (0x8<<3)
324#define GR18_HK_APM_CHANGE (0xa<<3)
325#define GR18_HK_MULTIPLE (0xc<<3)
326#define GR18_USER_INT_EN (1<<2)
327#define GR18_A0000_FLUSH_EN (1<<1)
328#define GR18_SMM_EN (1<<0)
329
330/* Set by driver, cleared by VBIOS */
331#define SWF00_YRES_SHIFT 16
332#define SWF00_XRES_SHIFT 0
333#define SWF00_RES_MASK 0xffff
334
335/* Set by VBIOS at boot time and driver at runtime */
336#define SWF01_TV2_FORMAT_SHIFT 8
337#define SWF01_TV1_FORMAT_SHIFT 0
338#define SWF01_TV_FORMAT_MASK 0xffff
339
340#define SWF10_VBIOS_BLC_I2C_EN (1<<29)
341#define SWF10_GTT_OVERRIDE_EN (1<<28)
342#define SWF10_LFP_DPMS_OVR (1<<27) /* override DPMS on display switch */
343#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24)
344#define SWF10_OLD_TOGGLE 0x0
345#define SWF10_TOGGLE_LIST_1 0x1
346#define SWF10_TOGGLE_LIST_2 0x2
347#define SWF10_TOGGLE_LIST_3 0x3
348#define SWF10_TOGGLE_LIST_4 0x4
349#define SWF10_PANNING_EN (1<<23)
350#define SWF10_DRIVER_LOADED (1<<22)
351#define SWF10_EXTENDED_DESKTOP (1<<21)
352#define SWF10_EXCLUSIVE_MODE (1<<20)
353#define SWF10_OVERLAY_EN (1<<19)
354#define SWF10_PLANEB_HOLDOFF (1<<18)
355#define SWF10_PLANEA_HOLDOFF (1<<17)
356#define SWF10_VGA_HOLDOFF (1<<16)
357#define SWF10_ACTIVE_DISP_MASK 0xffff
358#define SWF10_PIPEB_LFP2 (1<<15)
359#define SWF10_PIPEB_EFP2 (1<<14)
360#define SWF10_PIPEB_TV2 (1<<13)
361#define SWF10_PIPEB_CRT2 (1<<12)
362#define SWF10_PIPEB_LFP (1<<11)
363#define SWF10_PIPEB_EFP (1<<10)
364#define SWF10_PIPEB_TV (1<<9)
365#define SWF10_PIPEB_CRT (1<<8)
366#define SWF10_PIPEA_LFP2 (1<<7)
367#define SWF10_PIPEA_EFP2 (1<<6)
368#define SWF10_PIPEA_TV2 (1<<5)
369#define SWF10_PIPEA_CRT2 (1<<4)
370#define SWF10_PIPEA_LFP (1<<3)
371#define SWF10_PIPEA_EFP (1<<2)
372#define SWF10_PIPEA_TV (1<<1)
373#define SWF10_PIPEA_CRT (1<<0)
374
375#define SWF11_MEMORY_SIZE_SHIFT 16
376#define SWF11_SV_TEST_EN (1<<15)
377#define SWF11_IS_AGP (1<<14)
378#define SWF11_DISPLAY_HOLDOFF (1<<13)
379#define SWF11_DPMS_REDUCED (1<<12)
380#define SWF11_IS_VBE_MODE (1<<11)
381#define SWF11_PIPEB_ACCESS (1<<10) /* 0 here means pipe a */
382#define SWF11_DPMS_MASK 0x07
383#define SWF11_DPMS_OFF (1<<2)
384#define SWF11_DPMS_SUSPEND (1<<1)
385#define SWF11_DPMS_STANDBY (1<<0)
386#define SWF11_DPMS_ON 0
387
388#define SWF14_GFX_PFIT_EN (1<<31)
389#define SWF14_TEXT_PFIT_EN (1<<30)
390#define SWF14_LID_STATUS_CLOSED (1<<29) /* 0 here means open */
391#define SWF14_POPUP_EN (1<<28)
392#define SWF14_DISPLAY_HOLDOFF (1<<27)
393#define SWF14_DISP_DETECT_EN (1<<26)
394#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */
395#define SWF14_DRIVER_STATUS (1<<24)
396#define SWF14_OS_TYPE_WIN9X (1<<23)
397#define SWF14_OS_TYPE_WINNT (1<<22)
398/* 21:19 rsvd */
399#define SWF14_PM_TYPE_MASK 0x00070000
400#define SWF14_PM_ACPI_VIDEO (0x4 << 16)
401#define SWF14_PM_ACPI (0x3 << 16)
402#define SWF14_PM_APM_12 (0x2 << 16)
403#define SWF14_PM_APM_11 (0x1 << 16)
404#define SWF14_HK_REQUEST_MASK 0x0000ffff /* see GR18 6:3 for event type */
405 /* if GR18 indicates a display switch */
406#define SWF14_DS_PIPEB_LFP2_EN (1<<15)
407#define SWF14_DS_PIPEB_EFP2_EN (1<<14)
408#define SWF14_DS_PIPEB_TV2_EN (1<<13)
409#define SWF14_DS_PIPEB_CRT2_EN (1<<12)
410#define SWF14_DS_PIPEB_LFP_EN (1<<11)
411#define SWF14_DS_PIPEB_EFP_EN (1<<10)
412#define SWF14_DS_PIPEB_TV_EN (1<<9)
413#define SWF14_DS_PIPEB_CRT_EN (1<<8)
414#define SWF14_DS_PIPEA_LFP2_EN (1<<7)
415#define SWF14_DS_PIPEA_EFP2_EN (1<<6)
416#define SWF14_DS_PIPEA_TV2_EN (1<<5)
417#define SWF14_DS_PIPEA_CRT2_EN (1<<4)
418#define SWF14_DS_PIPEA_LFP_EN (1<<3)
419#define SWF14_DS_PIPEA_EFP_EN (1<<2)
420#define SWF14_DS_PIPEA_TV_EN (1<<1)
421#define SWF14_DS_PIPEA_CRT_EN (1<<0)
422 /* if GR18 indicates a panel fitting request */
423#define SWF14_PFIT_EN (1<<0) /* 0 means disable */
424 /* if GR18 indicates an APM change request */
425#define SWF14_APM_HIBERNATE 0x4
426#define SWF14_APM_SUSPEND 0x3
427#define SWF14_APM_STANDBY 0x1
428#define SWF14_APM_RESTORE 0x0
429
430#endif /* _I830_BIOS_H_ */
diff --git a/drivers/gpu/drm/gma500/intel_gmbus.c b/drivers/gpu/drm/gma500/intel_gmbus.c
new file mode 100644
index 00000000000..147584ac8d0
--- /dev/null
+++ b/drivers/gpu/drm/gma500/intel_gmbus.c
@@ -0,0 +1,493 @@
1/*
2 * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
3 * Copyright © 2006-2008,2010 Intel Corporation
4 * Jesse Barnes <jesse.barnes@intel.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Eric Anholt <eric@anholt.net>
27 * Chris Wilson <chris@chris-wilson.co.uk>
28 */
29#include <linux/module.h>
30#include <linux/i2c.h>
31#include <linux/i2c-algo-bit.h>
32#include "drmP.h"
33#include "drm.h"
34#include "psb_intel_drv.h"
35#include "gma_drm.h"
36#include "psb_drv.h"
37#include "psb_intel_reg.h"
38
39#define _wait_for(COND, MS, W) ({ \
40 unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \
41 int ret__ = 0; \
42 while (! (COND)) { \
43 if (time_after(jiffies, timeout__)) { \
44 ret__ = -ETIMEDOUT; \
45 break; \
46 } \
47 if (W && !(in_atomic() || in_dbg_master())) msleep(W); \
48 } \
49 ret__; \
50})
51
52#define wait_for(COND, MS) _wait_for(COND, MS, 1)
53#define wait_for_atomic(COND, MS) _wait_for(COND, MS, 0)
54
55/* Intel GPIO access functions */
56
57#define I2C_RISEFALL_TIME 20
58
59static inline struct intel_gmbus *
60to_intel_gmbus(struct i2c_adapter *i2c)
61{
62 return container_of(i2c, struct intel_gmbus, adapter);
63}
64
65struct intel_gpio {
66 struct i2c_adapter adapter;
67 struct i2c_algo_bit_data algo;
68 struct drm_psb_private *dev_priv;
69 u32 reg;
70};
71
72void
73gma_intel_i2c_reset(struct drm_device *dev)
74{
75 REG_WRITE(GMBUS0, 0);
76}
77
78static void intel_i2c_quirk_set(struct drm_psb_private *dev_priv, bool enable)
79{
80 /* When using bit bashing for I2C, this bit needs to be set to 1 */
81 /* FIXME: We are never Pineview, right?
82
83 u32 val;
84
85 if (!IS_PINEVIEW(dev_priv->dev))
86 return;
87
88 val = REG_READ(DSPCLK_GATE_D);
89 if (enable)
90 val |= DPCUNIT_CLOCK_GATE_DISABLE;
91 else
92 val &= ~DPCUNIT_CLOCK_GATE_DISABLE;
93 REG_WRITE(DSPCLK_GATE_D, val);
94
95 return;
96 */
97}
98
99static u32 get_reserved(struct intel_gpio *gpio)
100{
101 struct drm_psb_private *dev_priv = gpio->dev_priv;
102 struct drm_device *dev = dev_priv->dev;
103 u32 reserved = 0;
104
105 /* On most chips, these bits must be preserved in software. */
106 reserved = REG_READ(gpio->reg) &
107 (GPIO_DATA_PULLUP_DISABLE |
108 GPIO_CLOCK_PULLUP_DISABLE);
109
110 return reserved;
111}
112
113static int get_clock(void *data)
114{
115 struct intel_gpio *gpio = data;
116 struct drm_psb_private *dev_priv = gpio->dev_priv;
117 struct drm_device *dev = dev_priv->dev;
118 u32 reserved = get_reserved(gpio);
119 REG_WRITE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK);
120 REG_WRITE(gpio->reg, reserved);
121 return (REG_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0;
122}
123
124static int get_data(void *data)
125{
126 struct intel_gpio *gpio = data;
127 struct drm_psb_private *dev_priv = gpio->dev_priv;
128 struct drm_device *dev = dev_priv->dev;
129 u32 reserved = get_reserved(gpio);
130 REG_WRITE(gpio->reg, reserved | GPIO_DATA_DIR_MASK);
131 REG_WRITE(gpio->reg, reserved);
132 return (REG_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0;
133}
134
135static void set_clock(void *data, int state_high)
136{
137 struct intel_gpio *gpio = data;
138 struct drm_psb_private *dev_priv = gpio->dev_priv;
139 struct drm_device *dev = dev_priv->dev;
140 u32 reserved = get_reserved(gpio);
141 u32 clock_bits;
142
143 if (state_high)
144 clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
145 else
146 clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
147 GPIO_CLOCK_VAL_MASK;
148
149 REG_WRITE(gpio->reg, reserved | clock_bits);
150 REG_READ(gpio->reg); /* Posting */
151}
152
153static void set_data(void *data, int state_high)
154{
155 struct intel_gpio *gpio = data;
156 struct drm_psb_private *dev_priv = gpio->dev_priv;
157 struct drm_device *dev = dev_priv->dev;
158 u32 reserved = get_reserved(gpio);
159 u32 data_bits;
160
161 if (state_high)
162 data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
163 else
164 data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
165 GPIO_DATA_VAL_MASK;
166
167 REG_WRITE(gpio->reg, reserved | data_bits);
168 REG_READ(gpio->reg);
169}
170
171static struct i2c_adapter *
172intel_gpio_create(struct drm_psb_private *dev_priv, u32 pin)
173{
174 static const int map_pin_to_reg[] = {
175 0,
176 GPIOB,
177 GPIOA,
178 GPIOC,
179 GPIOD,
180 GPIOE,
181 0,
182 GPIOF,
183 };
184 struct intel_gpio *gpio;
185
186 if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin])
187 return NULL;
188
189 gpio = kzalloc(sizeof(struct intel_gpio), GFP_KERNEL);
190 if (gpio == NULL)
191 return NULL;
192
193 gpio->reg = map_pin_to_reg[pin];
194 gpio->dev_priv = dev_priv;
195
196 snprintf(gpio->adapter.name, sizeof(gpio->adapter.name),
197 "gma500 GPIO%c", "?BACDE?F"[pin]);
198 gpio->adapter.owner = THIS_MODULE;
199 gpio->adapter.algo_data = &gpio->algo;
200 gpio->adapter.dev.parent = &dev_priv->dev->pdev->dev;
201 gpio->algo.setsda = set_data;
202 gpio->algo.setscl = set_clock;
203 gpio->algo.getsda = get_data;
204 gpio->algo.getscl = get_clock;
205 gpio->algo.udelay = I2C_RISEFALL_TIME;
206 gpio->algo.timeout = usecs_to_jiffies(2200);
207 gpio->algo.data = gpio;
208
209 if (i2c_bit_add_bus(&gpio->adapter))
210 goto out_free;
211
212 return &gpio->adapter;
213
214out_free:
215 kfree(gpio);
216 return NULL;
217}
218
219static int
220intel_i2c_quirk_xfer(struct drm_psb_private *dev_priv,
221 struct i2c_adapter *adapter,
222 struct i2c_msg *msgs,
223 int num)
224{
225 struct intel_gpio *gpio = container_of(adapter,
226 struct intel_gpio,
227 adapter);
228 int ret;
229
230 gma_intel_i2c_reset(dev_priv->dev);
231
232 intel_i2c_quirk_set(dev_priv, true);
233 set_data(gpio, 1);
234 set_clock(gpio, 1);
235 udelay(I2C_RISEFALL_TIME);
236
237 ret = adapter->algo->master_xfer(adapter, msgs, num);
238
239 set_data(gpio, 1);
240 set_clock(gpio, 1);
241 intel_i2c_quirk_set(dev_priv, false);
242
243 return ret;
244}
245
246static int
247gmbus_xfer(struct i2c_adapter *adapter,
248 struct i2c_msg *msgs,
249 int num)
250{
251 struct intel_gmbus *bus = container_of(adapter,
252 struct intel_gmbus,
253 adapter);
254 struct drm_psb_private *dev_priv = adapter->algo_data;
255 struct drm_device *dev = dev_priv->dev;
256 int i, reg_offset;
257
258 if (bus->force_bit)
259 return intel_i2c_quirk_xfer(dev_priv,
260 bus->force_bit, msgs, num);
261
262 reg_offset = 0;
263
264 REG_WRITE(GMBUS0 + reg_offset, bus->reg0);
265
266 for (i = 0; i < num; i++) {
267 u16 len = msgs[i].len;
268 u8 *buf = msgs[i].buf;
269
270 if (msgs[i].flags & I2C_M_RD) {
271 REG_WRITE(GMBUS1 + reg_offset,
272 GMBUS_CYCLE_WAIT | (i + 1 == num ? GMBUS_CYCLE_STOP : 0) |
273 (len << GMBUS_BYTE_COUNT_SHIFT) |
274 (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) |
275 GMBUS_SLAVE_READ | GMBUS_SW_RDY);
276 REG_READ(GMBUS2+reg_offset);
277 do {
278 u32 val, loop = 0;
279
280 if (wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50))
281 goto timeout;
282 if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
283 goto clear_err;
284
285 val = REG_READ(GMBUS3 + reg_offset);
286 do {
287 *buf++ = val & 0xff;
288 val >>= 8;
289 } while (--len && ++loop < 4);
290 } while (len);
291 } else {
292 u32 val, loop;
293
294 val = loop = 0;
295 do {
296 val |= *buf++ << (8 * loop);
297 } while (--len && ++loop < 4);
298
299 REG_WRITE(GMBUS3 + reg_offset, val);
300 REG_WRITE(GMBUS1 + reg_offset,
301 (i + 1 == num ? GMBUS_CYCLE_STOP : GMBUS_CYCLE_WAIT) |
302 (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) |
303 (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) |
304 GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
305 REG_READ(GMBUS2+reg_offset);
306
307 while (len) {
308 if (wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50))
309 goto timeout;
310 if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
311 goto clear_err;
312
313 val = loop = 0;
314 do {
315 val |= *buf++ << (8 * loop);
316 } while (--len && ++loop < 4);
317
318 REG_WRITE(GMBUS3 + reg_offset, val);
319 REG_READ(GMBUS2+reg_offset);
320 }
321 }
322
323 if (i + 1 < num && wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50))
324 goto timeout;
325 if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
326 goto clear_err;
327 }
328
329 goto done;
330
331clear_err:
332 /* Toggle the Software Clear Interrupt bit. This has the effect
333 * of resetting the GMBUS controller and so clearing the
334 * BUS_ERROR raised by the slave's NAK.
335 */
336 REG_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT);
337 REG_WRITE(GMBUS1 + reg_offset, 0);
338
339done:
340 /* Mark the GMBUS interface as disabled. We will re-enable it at the
341 * start of the next xfer, till then let it sleep.
342 */
343 REG_WRITE(GMBUS0 + reg_offset, 0);
344 return i;
345
346timeout:
347 DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d [%s]\n",
348 bus->reg0 & 0xff, bus->adapter.name);
349 REG_WRITE(GMBUS0 + reg_offset, 0);
350
351 /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */
352 bus->force_bit = intel_gpio_create(dev_priv, bus->reg0 & 0xff);
353 if (!bus->force_bit)
354 return -ENOMEM;
355
356 return intel_i2c_quirk_xfer(dev_priv, bus->force_bit, msgs, num);
357}
358
359static u32 gmbus_func(struct i2c_adapter *adapter)
360{
361 struct intel_gmbus *bus = container_of(adapter,
362 struct intel_gmbus,
363 adapter);
364
365 if (bus->force_bit)
366 bus->force_bit->algo->functionality(bus->force_bit);
367
368 return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
369 /* I2C_FUNC_10BIT_ADDR | */
370 I2C_FUNC_SMBUS_READ_BLOCK_DATA |
371 I2C_FUNC_SMBUS_BLOCK_PROC_CALL);
372}
373
374static const struct i2c_algorithm gmbus_algorithm = {
375 .master_xfer = gmbus_xfer,
376 .functionality = gmbus_func
377};
378
379/**
380 * intel_gmbus_setup - instantiate all Intel i2c GMBuses
381 * @dev: DRM device
382 */
383int gma_intel_setup_gmbus(struct drm_device *dev)
384{
385 static const char *names[GMBUS_NUM_PORTS] = {
386 "disabled",
387 "ssc",
388 "vga",
389 "panel",
390 "dpc",
391 "dpb",
392 "reserved",
393 "dpd",
394 };
395 struct drm_psb_private *dev_priv = dev->dev_private;
396 int ret, i;
397
398 dev_priv->gmbus = kcalloc(sizeof(struct intel_gmbus), GMBUS_NUM_PORTS,
399 GFP_KERNEL);
400 if (dev_priv->gmbus == NULL)
401 return -ENOMEM;
402
403 for (i = 0; i < GMBUS_NUM_PORTS; i++) {
404 struct intel_gmbus *bus = &dev_priv->gmbus[i];
405
406 bus->adapter.owner = THIS_MODULE;
407 bus->adapter.class = I2C_CLASS_DDC;
408 snprintf(bus->adapter.name,
409 sizeof(bus->adapter.name),
410 "gma500 gmbus %s",
411 names[i]);
412
413 bus->adapter.dev.parent = &dev->pdev->dev;
414 bus->adapter.algo_data = dev_priv;
415
416 bus->adapter.algo = &gmbus_algorithm;
417 ret = i2c_add_adapter(&bus->adapter);
418 if (ret)
419 goto err;
420
421 /* By default use a conservative clock rate */
422 bus->reg0 = i | GMBUS_RATE_100KHZ;
423
424 /* XXX force bit banging until GMBUS is fully debugged */
425 bus->force_bit = intel_gpio_create(dev_priv, i);
426 }
427
428 gma_intel_i2c_reset(dev_priv->dev);
429
430 return 0;
431
432err:
433 while (--i) {
434 struct intel_gmbus *bus = &dev_priv->gmbus[i];
435 i2c_del_adapter(&bus->adapter);
436 }
437 kfree(dev_priv->gmbus);
438 dev_priv->gmbus = NULL;
439 return ret;
440}
441
442void gma_intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed)
443{
444 struct intel_gmbus *bus = to_intel_gmbus(adapter);
445
446 /* speed:
447 * 0x0 = 100 KHz
448 * 0x1 = 50 KHz
449 * 0x2 = 400 KHz
450 * 0x3 = 1000 Khz
451 */
452 bus->reg0 = (bus->reg0 & ~(0x3 << 8)) | (speed << 8);
453}
454
455void gma_intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit)
456{
457 struct intel_gmbus *bus = to_intel_gmbus(adapter);
458
459 if (force_bit) {
460 if (bus->force_bit == NULL) {
461 struct drm_psb_private *dev_priv = adapter->algo_data;
462 bus->force_bit = intel_gpio_create(dev_priv,
463 bus->reg0 & 0xff);
464 }
465 } else {
466 if (bus->force_bit) {
467 i2c_del_adapter(bus->force_bit);
468 kfree(bus->force_bit);
469 bus->force_bit = NULL;
470 }
471 }
472}
473
474void gma_intel_teardown_gmbus(struct drm_device *dev)
475{
476 struct drm_psb_private *dev_priv = dev->dev_private;
477 int i;
478
479 if (dev_priv->gmbus == NULL)
480 return;
481
482 for (i = 0; i < GMBUS_NUM_PORTS; i++) {
483 struct intel_gmbus *bus = &dev_priv->gmbus[i];
484 if (bus->force_bit) {
485 i2c_del_adapter(bus->force_bit);
486 kfree(bus->force_bit);
487 }
488 i2c_del_adapter(&bus->adapter);
489 }
490
491 kfree(dev_priv->gmbus);
492 dev_priv->gmbus = NULL;
493}
diff --git a/drivers/gpu/drm/gma500/intel_i2c.c b/drivers/gpu/drm/gma500/intel_i2c.c
new file mode 100644
index 00000000000..98a28c20955
--- /dev/null
+++ b/drivers/gpu/drm/gma500/intel_i2c.c
@@ -0,0 +1,169 @@
1/*
2 * Copyright © 2006-2007 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 */
20#include <linux/export.h>
21#include <linux/i2c.h>
22#include <linux/i2c-algo-bit.h>
23
24#include "psb_drv.h"
25#include "psb_intel_reg.h"
26
27/*
28 * Intel GPIO access functions
29 */
30
31#define I2C_RISEFALL_TIME 20
32
33static int get_clock(void *data)
34{
35 struct psb_intel_i2c_chan *chan = data;
36 struct drm_device *dev = chan->drm_dev;
37 u32 val;
38
39 val = REG_READ(chan->reg);
40 return (val & GPIO_CLOCK_VAL_IN) != 0;
41}
42
43static int get_data(void *data)
44{
45 struct psb_intel_i2c_chan *chan = data;
46 struct drm_device *dev = chan->drm_dev;
47 u32 val;
48
49 val = REG_READ(chan->reg);
50 return (val & GPIO_DATA_VAL_IN) != 0;
51}
52
53static void set_clock(void *data, int state_high)
54{
55 struct psb_intel_i2c_chan *chan = data;
56 struct drm_device *dev = chan->drm_dev;
57 u32 reserved = 0, clock_bits;
58
59 /* On most chips, these bits must be preserved in software. */
60 reserved =
61 REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
62 GPIO_CLOCK_PULLUP_DISABLE);
63
64 if (state_high)
65 clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
66 else
67 clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
68 GPIO_CLOCK_VAL_MASK;
69 REG_WRITE(chan->reg, reserved | clock_bits);
70 udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
71}
72
73static void set_data(void *data, int state_high)
74{
75 struct psb_intel_i2c_chan *chan = data;
76 struct drm_device *dev = chan->drm_dev;
77 u32 reserved = 0, data_bits;
78
79 /* On most chips, these bits must be preserved in software. */
80 reserved =
81 REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
82 GPIO_CLOCK_PULLUP_DISABLE);
83
84 if (state_high)
85 data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
86 else
87 data_bits =
88 GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
89 GPIO_DATA_VAL_MASK;
90
91 REG_WRITE(chan->reg, reserved | data_bits);
92 udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
93}
94
95/**
96 * psb_intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
97 * @dev: DRM device
98 * @output: driver specific output device
99 * @reg: GPIO reg to use
100 * @name: name for this bus
101 *
102 * Creates and registers a new i2c bus with the Linux i2c layer, for use
103 * in output probing and control (e.g. DDC or SDVO control functions).
104 *
105 * Possible values for @reg include:
106 * %GPIOA
107 * %GPIOB
108 * %GPIOC
109 * %GPIOD
110 * %GPIOE
111 * %GPIOF
112 * %GPIOG
113 * %GPIOH
114 * see PRM for details on how these different busses are used.
115 */
116struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev,
117 const u32 reg, const char *name)
118{
119 struct psb_intel_i2c_chan *chan;
120
121 chan = kzalloc(sizeof(struct psb_intel_i2c_chan), GFP_KERNEL);
122 if (!chan)
123 goto out_free;
124
125 chan->drm_dev = dev;
126 chan->reg = reg;
127 snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name);
128 chan->adapter.owner = THIS_MODULE;
129 chan->adapter.algo_data = &chan->algo;
130 chan->adapter.dev.parent = &dev->pdev->dev;
131 chan->algo.setsda = set_data;
132 chan->algo.setscl = set_clock;
133 chan->algo.getsda = get_data;
134 chan->algo.getscl = get_clock;
135 chan->algo.udelay = 20;
136 chan->algo.timeout = usecs_to_jiffies(2200);
137 chan->algo.data = chan;
138
139 i2c_set_adapdata(&chan->adapter, chan);
140
141 if (i2c_bit_add_bus(&chan->adapter))
142 goto out_free;
143
144 /* JJJ: raise SCL and SDA? */
145 set_data(chan, 1);
146 set_clock(chan, 1);
147 udelay(20);
148
149 return chan;
150
151out_free:
152 kfree(chan);
153 return NULL;
154}
155
156/**
157 * psb_intel_i2c_destroy - unregister and free i2c bus resources
158 * @output: channel to free
159 *
160 * Unregister the adapter from the i2c layer, then free the structure.
161 */
162void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan)
163{
164 if (!chan)
165 return;
166
167 i2c_del_adapter(&chan->adapter);
168 kfree(chan);
169}
diff --git a/drivers/gpu/drm/gma500/intel_opregion.c b/drivers/gpu/drm/gma500/intel_opregion.c
new file mode 100644
index 00000000000..d946bc1b17b
--- /dev/null
+++ b/drivers/gpu/drm/gma500/intel_opregion.c
@@ -0,0 +1,81 @@
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 * FIXME: resolve with the i915 version
24 */
25
26#include "psb_drv.h"
27
28struct opregion_header {
29 u8 signature[16];
30 u32 size;
31 u32 opregion_ver;
32 u8 bios_ver[32];
33 u8 vbios_ver[16];
34 u8 driver_ver[16];
35 u32 mboxes;
36 u8 reserved[164];
37} __packed;
38
39struct opregion_apci {
40 /*FIXME: add it later*/
41} __packed;
42
43struct opregion_swsci {
44 /*FIXME: add it later*/
45} __packed;
46
47struct opregion_acpi {
48 /*FIXME: add it later*/
49} __packed;
50
51int gma_intel_opregion_init(struct drm_device *dev)
52{
53 struct drm_psb_private *dev_priv = dev->dev_private;
54 u32 opregion_phy;
55 void *base;
56 u32 *lid_state;
57
58 dev_priv->lid_state = NULL;
59
60 pci_read_config_dword(dev->pdev, 0xfc, &opregion_phy);
61 if (opregion_phy == 0)
62 return -ENOTSUPP;
63
64 base = ioremap(opregion_phy, 8*1024);
65 if (!base)
66 return -ENOMEM;
67
68 lid_state = base + 0x01ac;
69
70 dev_priv->lid_state = lid_state;
71 dev_priv->lid_last_state = readl(lid_state);
72 return 0;
73}
74
75int gma_intel_opregion_exit(struct drm_device *dev)
76{
77 struct drm_psb_private *dev_priv = dev->dev_private;
78 if (dev_priv->lid_state)
79 iounmap(dev_priv->lid_state);
80 return 0;
81}
diff --git a/drivers/gpu/drm/gma500/mid_bios.c b/drivers/gpu/drm/gma500/mid_bios.c
new file mode 100644
index 00000000000..5eee9ad80da
--- /dev/null
+++ b/drivers/gpu/drm/gma500/mid_bios.c
@@ -0,0 +1,263 @@
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/* TODO
21 * - Split functions by vbt type
22 * - Make them all take drm_device
23 * - Check ioremap failures
24 */
25
26#include <drm/drmP.h>
27#include <drm/drm.h>
28#include "gma_drm.h"
29#include "psb_drv.h"
30#include "mid_bios.h"
31
32static void mid_get_fuse_settings(struct drm_device *dev)
33{
34 struct drm_psb_private *dev_priv = dev->dev_private;
35 struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
36 uint32_t fuse_value = 0;
37 uint32_t fuse_value_tmp = 0;
38
39#define FB_REG06 0xD0810600
40#define FB_MIPI_DISABLE (1 << 11)
41#define FB_REG09 0xD0810900
42#define FB_REG09 0xD0810900
43#define FB_SKU_MASK 0x7000
44#define FB_SKU_SHIFT 12
45#define FB_SKU_100 0
46#define FB_SKU_100L 1
47#define FB_SKU_83 2
48 if (pci_root == NULL) {
49 WARN_ON(1);
50 return;
51 }
52
53
54 pci_write_config_dword(pci_root, 0xD0, FB_REG06);
55 pci_read_config_dword(pci_root, 0xD4, &fuse_value);
56
57 /* FB_MIPI_DISABLE doesn't mean LVDS on with Medfield */
58 if (IS_MRST(dev))
59 dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE;
60
61 DRM_INFO("internal display is %s\n",
62 dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display");
63
64 /* Prevent runtime suspend at start*/
65 if (dev_priv->iLVDS_enable) {
66 dev_priv->is_lvds_on = true;
67 dev_priv->is_mipi_on = false;
68 } else {
69 dev_priv->is_mipi_on = true;
70 dev_priv->is_lvds_on = false;
71 }
72
73 dev_priv->video_device_fuse = fuse_value;
74
75 pci_write_config_dword(pci_root, 0xD0, FB_REG09);
76 pci_read_config_dword(pci_root, 0xD4, &fuse_value);
77
78 dev_dbg(dev->dev, "SKU values is 0x%x.\n", fuse_value);
79 fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT;
80
81 dev_priv->fuse_reg_value = fuse_value;
82
83 switch (fuse_value_tmp) {
84 case FB_SKU_100:
85 dev_priv->core_freq = 200;
86 break;
87 case FB_SKU_100L:
88 dev_priv->core_freq = 100;
89 break;
90 case FB_SKU_83:
91 dev_priv->core_freq = 166;
92 break;
93 default:
94 dev_warn(dev->dev, "Invalid SKU values, SKU value = 0x%08x\n",
95 fuse_value_tmp);
96 dev_priv->core_freq = 0;
97 }
98 dev_dbg(dev->dev, "LNC core clk is %dMHz.\n", dev_priv->core_freq);
99 pci_dev_put(pci_root);
100}
101
102/*
103 * Get the revison ID, B0:D2:F0;0x08
104 */
105static void mid_get_pci_revID(struct drm_psb_private *dev_priv)
106{
107 uint32_t platform_rev_id = 0;
108 struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
109
110 if (pci_gfx_root == NULL) {
111 WARN_ON(1);
112 return;
113 }
114 pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id);
115 dev_priv->platform_rev_id = (uint8_t) platform_rev_id;
116 pci_dev_put(pci_gfx_root);
117 dev_dbg(dev_priv->dev->dev, "platform_rev_id is %x\n",
118 dev_priv->platform_rev_id);
119}
120
121static void mid_get_vbt_data(struct drm_psb_private *dev_priv)
122{
123 struct drm_device *dev = dev_priv->dev;
124 struct oaktrail_vbt *vbt = &dev_priv->vbt_data;
125 u32 addr;
126 u16 new_size;
127 u8 *vbt_virtual;
128 u8 bpi;
129 u8 number_desc = 0;
130 struct oaktrail_timing_info *dp_ti = &dev_priv->gct_data.DTD;
131 struct gct_r10_timing_info ti;
132 void *pGCT;
133 struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
134
135 /* Get the address of the platform config vbt, B0:D2:F0;0xFC */
136 pci_read_config_dword(pci_gfx_root, 0xFC, &addr);
137 pci_dev_put(pci_gfx_root);
138
139 dev_dbg(dev->dev, "drm platform config address is %x\n", addr);
140
141 /* check for platform config address == 0. */
142 /* this means fw doesn't support vbt */
143
144 if (addr == 0) {
145 vbt->size = 0;
146 return;
147 }
148
149 /* get the virtual address of the vbt */
150 vbt_virtual = ioremap(addr, sizeof(*vbt));
151 if (vbt_virtual == NULL) {
152 vbt->size = 0;
153 return;
154 }
155
156 memcpy(vbt, vbt_virtual, sizeof(*vbt));
157 iounmap(vbt_virtual); /* Free virtual address space */
158
159 /* No matching signature don't process the data */
160 if (memcmp(vbt->signature, "$GCT", 4)) {
161 vbt->size = 0;
162 return;
163 }
164
165 dev_dbg(dev->dev, "GCT revision is %x\n", vbt->revision);
166
167 switch (vbt->revision) {
168 case 0:
169 vbt->oaktrail_gct = ioremap(addr + sizeof(*vbt) - 4,
170 vbt->size - sizeof(*vbt) + 4);
171 pGCT = vbt->oaktrail_gct;
172 bpi = ((struct oaktrail_gct_v1 *)pGCT)->PD.BootPanelIndex;
173 dev_priv->gct_data.bpi = bpi;
174 dev_priv->gct_data.pt =
175 ((struct oaktrail_gct_v1 *)pGCT)->PD.PanelType;
176 memcpy(&dev_priv->gct_data.DTD,
177 &((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].DTD,
178 sizeof(struct oaktrail_timing_info));
179 dev_priv->gct_data.Panel_Port_Control =
180 ((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control;
181 dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
182 ((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
183 break;
184 case 1:
185 vbt->oaktrail_gct = ioremap(addr + sizeof(*vbt) - 4,
186 vbt->size - sizeof(*vbt) + 4);
187 pGCT = vbt->oaktrail_gct;
188 bpi = ((struct oaktrail_gct_v2 *)pGCT)->PD.BootPanelIndex;
189 dev_priv->gct_data.bpi = bpi;
190 dev_priv->gct_data.pt =
191 ((struct oaktrail_gct_v2 *)pGCT)->PD.PanelType;
192 memcpy(&dev_priv->gct_data.DTD,
193 &((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].DTD,
194 sizeof(struct oaktrail_timing_info));
195 dev_priv->gct_data.Panel_Port_Control =
196 ((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control;
197 dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
198 ((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
199 break;
200 case 0x10:
201 /*header definition changed from rev 01 (v2) to rev 10h. */
202 /*so, some values have changed location*/
203 new_size = vbt->checksum; /*checksum contains lo size byte*/
204 /*LSB of oaktrail_gct contains hi size byte*/
205 new_size |= ((0xff & (unsigned int)(long)vbt->oaktrail_gct)) << 8;
206
207 vbt->checksum = vbt->size; /*size contains the checksum*/
208 if (new_size > 0xff)
209 vbt->size = 0xff; /*restrict size to 255*/
210 else
211 vbt->size = new_size;
212
213 /* number of descriptors defined in the GCT */
214 number_desc = ((0xff00 & (unsigned int)(long)vbt->oaktrail_gct)) >> 8;
215 bpi = ((0xff0000 & (unsigned int)(long)vbt->oaktrail_gct)) >> 16;
216 vbt->oaktrail_gct = ioremap(addr + GCT_R10_HEADER_SIZE,
217 GCT_R10_DISPLAY_DESC_SIZE * number_desc);
218 pGCT = vbt->oaktrail_gct;
219 pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE);
220 dev_priv->gct_data.bpi = bpi; /*save boot panel id*/
221
222 /*copy the GCT display timings into a temp structure*/
223 memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info));
224
225 /*now copy the temp struct into the dev_priv->gct_data*/
226 dp_ti->pixel_clock = ti.pixel_clock;
227 dp_ti->hactive_hi = ti.hactive_hi;
228 dp_ti->hactive_lo = ti.hactive_lo;
229 dp_ti->hblank_hi = ti.hblank_hi;
230 dp_ti->hblank_lo = ti.hblank_lo;
231 dp_ti->hsync_offset_hi = ti.hsync_offset_hi;
232 dp_ti->hsync_offset_lo = ti.hsync_offset_lo;
233 dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi;
234 dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo;
235 dp_ti->vactive_hi = ti.vactive_hi;
236 dp_ti->vactive_lo = ti.vactive_lo;
237 dp_ti->vblank_hi = ti.vblank_hi;
238 dp_ti->vblank_lo = ti.vblank_lo;
239 dp_ti->vsync_offset_hi = ti.vsync_offset_hi;
240 dp_ti->vsync_offset_lo = ti.vsync_offset_lo;
241 dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi;
242 dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo;
243
244 /* Move the MIPI_Display_Descriptor data from GCT to dev priv */
245 dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
246 *((u8 *)pGCT + 0x0d);
247 dev_priv->gct_data.Panel_MIPI_Display_Descriptor |=
248 (*((u8 *)pGCT + 0x0e)) << 8;
249 break;
250 default:
251 dev_err(dev->dev, "Unknown revision of GCT!\n");
252 vbt->size = 0;
253 }
254}
255
256int mid_chip_setup(struct drm_device *dev)
257{
258 struct drm_psb_private *dev_priv = dev->dev_private;
259 mid_get_fuse_settings(dev);
260 mid_get_vbt_data(dev_priv);
261 mid_get_pci_revID(dev_priv);
262 return 0;
263}
diff --git a/drivers/gpu/drm/gma500/mid_bios.h b/drivers/gpu/drm/gma500/mid_bios.h
new file mode 100644
index 00000000000..00e7d564b7e
--- /dev/null
+++ b/drivers/gpu/drm/gma500/mid_bios.h
@@ -0,0 +1,21 @@
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
20extern int mid_chip_setup(struct drm_device *dev);
21
diff --git a/drivers/gpu/drm/gma500/mmu.c b/drivers/gpu/drm/gma500/mmu.c
new file mode 100644
index 00000000000..c904d73b1de
--- /dev/null
+++ b/drivers/gpu/drm/gma500/mmu.c
@@ -0,0 +1,858 @@
1/**************************************************************************
2 * Copyright (c) 2007, 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 <drm/drmP.h>
19#include "psb_drv.h"
20#include "psb_reg.h"
21
22/*
23 * Code for the SGX MMU:
24 */
25
26/*
27 * clflush on one processor only:
28 * clflush should apparently flush the cache line on all processors in an
29 * SMP system.
30 */
31
32/*
33 * kmap atomic:
34 * The usage of the slots must be completely encapsulated within a spinlock, and
35 * no other functions that may be using the locks for other purposed may be
36 * called from within the locked region.
37 * Since the slots are per processor, this will guarantee that we are the only
38 * user.
39 */
40
41/*
42 * TODO: Inserting ptes from an interrupt handler:
43 * This may be desirable for some SGX functionality where the GPU can fault in
44 * needed pages. For that, we need to make an atomic insert_pages function, that
45 * may fail.
46 * If it fails, the caller need to insert the page using a workqueue function,
47 * but on average it should be fast.
48 */
49
50struct psb_mmu_driver {
51 /* protects driver- and pd structures. Always take in read mode
52 * before taking the page table spinlock.
53 */
54 struct rw_semaphore sem;
55
56 /* protects page tables, directory tables and pt tables.
57 * and pt structures.
58 */
59 spinlock_t lock;
60
61 atomic_t needs_tlbflush;
62
63 uint8_t __iomem *register_map;
64 struct psb_mmu_pd *default_pd;
65 /*uint32_t bif_ctrl;*/
66 int has_clflush;
67 int clflush_add;
68 unsigned long clflush_mask;
69
70 struct drm_psb_private *dev_priv;
71};
72
73struct psb_mmu_pd;
74
75struct psb_mmu_pt {
76 struct psb_mmu_pd *pd;
77 uint32_t index;
78 uint32_t count;
79 struct page *p;
80 uint32_t *v;
81};
82
83struct psb_mmu_pd {
84 struct psb_mmu_driver *driver;
85 int hw_context;
86 struct psb_mmu_pt **tables;
87 struct page *p;
88 struct page *dummy_pt;
89 struct page *dummy_page;
90 uint32_t pd_mask;
91 uint32_t invalid_pde;
92 uint32_t invalid_pte;
93};
94
95static inline uint32_t psb_mmu_pt_index(uint32_t offset)
96{
97 return (offset >> PSB_PTE_SHIFT) & 0x3FF;
98}
99
100static inline uint32_t psb_mmu_pd_index(uint32_t offset)
101{
102 return offset >> PSB_PDE_SHIFT;
103}
104
105static inline void psb_clflush(void *addr)
106{
107 __asm__ __volatile__("clflush (%0)\n" : : "r"(addr) : "memory");
108}
109
110static inline void psb_mmu_clflush(struct psb_mmu_driver *driver,
111 void *addr)
112{
113 if (!driver->has_clflush)
114 return;
115
116 mb();
117 psb_clflush(addr);
118 mb();
119}
120
121static void psb_page_clflush(struct psb_mmu_driver *driver, struct page* page)
122{
123 uint32_t clflush_add = driver->clflush_add >> PAGE_SHIFT;
124 uint32_t clflush_count = PAGE_SIZE / clflush_add;
125 int i;
126 uint8_t *clf;
127
128 clf = kmap_atomic(page, KM_USER0);
129 mb();
130 for (i = 0; i < clflush_count; ++i) {
131 psb_clflush(clf);
132 clf += clflush_add;
133 }
134 mb();
135 kunmap_atomic(clf, KM_USER0);
136}
137
138static void psb_pages_clflush(struct psb_mmu_driver *driver,
139 struct page *page[], unsigned long num_pages)
140{
141 int i;
142
143 if (!driver->has_clflush)
144 return ;
145
146 for (i = 0; i < num_pages; i++)
147 psb_page_clflush(driver, *page++);
148}
149
150static void psb_mmu_flush_pd_locked(struct psb_mmu_driver *driver,
151 int force)
152{
153 atomic_set(&driver->needs_tlbflush, 0);
154}
155
156static void psb_mmu_flush_pd(struct psb_mmu_driver *driver, int force)
157{
158 down_write(&driver->sem);
159 psb_mmu_flush_pd_locked(driver, force);
160 up_write(&driver->sem);
161}
162
163void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot)
164{
165 if (rc_prot)
166 down_write(&driver->sem);
167 if (rc_prot)
168 up_write(&driver->sem);
169}
170
171void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context)
172{
173 /*ttm_tt_cache_flush(&pd->p, 1);*/
174 psb_pages_clflush(pd->driver, &pd->p, 1);
175 down_write(&pd->driver->sem);
176 wmb();
177 psb_mmu_flush_pd_locked(pd->driver, 1);
178 pd->hw_context = hw_context;
179 up_write(&pd->driver->sem);
180
181}
182
183static inline unsigned long psb_pd_addr_end(unsigned long addr,
184 unsigned long end)
185{
186
187 addr = (addr + PSB_PDE_MASK + 1) & ~PSB_PDE_MASK;
188 return (addr < end) ? addr : end;
189}
190
191static inline uint32_t psb_mmu_mask_pte(uint32_t pfn, int type)
192{
193 uint32_t mask = PSB_PTE_VALID;
194
195 if (type & PSB_MMU_CACHED_MEMORY)
196 mask |= PSB_PTE_CACHED;
197 if (type & PSB_MMU_RO_MEMORY)
198 mask |= PSB_PTE_RO;
199 if (type & PSB_MMU_WO_MEMORY)
200 mask |= PSB_PTE_WO;
201
202 return (pfn << PAGE_SHIFT) | mask;
203}
204
205struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver,
206 int trap_pagefaults, int invalid_type)
207{
208 struct psb_mmu_pd *pd = kmalloc(sizeof(*pd), GFP_KERNEL);
209 uint32_t *v;
210 int i;
211
212 if (!pd)
213 return NULL;
214
215 pd->p = alloc_page(GFP_DMA32);
216 if (!pd->p)
217 goto out_err1;
218 pd->dummy_pt = alloc_page(GFP_DMA32);
219 if (!pd->dummy_pt)
220 goto out_err2;
221 pd->dummy_page = alloc_page(GFP_DMA32);
222 if (!pd->dummy_page)
223 goto out_err3;
224
225 if (!trap_pagefaults) {
226 pd->invalid_pde =
227 psb_mmu_mask_pte(page_to_pfn(pd->dummy_pt),
228 invalid_type);
229 pd->invalid_pte =
230 psb_mmu_mask_pte(page_to_pfn(pd->dummy_page),
231 invalid_type);
232 } else {
233 pd->invalid_pde = 0;
234 pd->invalid_pte = 0;
235 }
236
237 v = kmap(pd->dummy_pt);
238 for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
239 v[i] = pd->invalid_pte;
240
241 kunmap(pd->dummy_pt);
242
243 v = kmap(pd->p);
244 for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
245 v[i] = pd->invalid_pde;
246
247 kunmap(pd->p);
248
249 clear_page(kmap(pd->dummy_page));
250 kunmap(pd->dummy_page);
251
252 pd->tables = vmalloc_user(sizeof(struct psb_mmu_pt *) * 1024);
253 if (!pd->tables)
254 goto out_err4;
255
256 pd->hw_context = -1;
257 pd->pd_mask = PSB_PTE_VALID;
258 pd->driver = driver;
259
260 return pd;
261
262out_err4:
263 __free_page(pd->dummy_page);
264out_err3:
265 __free_page(pd->dummy_pt);
266out_err2:
267 __free_page(pd->p);
268out_err1:
269 kfree(pd);
270 return NULL;
271}
272
273void psb_mmu_free_pt(struct psb_mmu_pt *pt)
274{
275 __free_page(pt->p);
276 kfree(pt);
277}
278
279void psb_mmu_free_pagedir(struct psb_mmu_pd *pd)
280{
281 struct psb_mmu_driver *driver = pd->driver;
282 struct psb_mmu_pt *pt;
283 int i;
284
285 down_write(&driver->sem);
286 if (pd->hw_context != -1)
287 psb_mmu_flush_pd_locked(driver, 1);
288
289 /* Should take the spinlock here, but we don't need to do that
290 since we have the semaphore in write mode. */
291
292 for (i = 0; i < 1024; ++i) {
293 pt = pd->tables[i];
294 if (pt)
295 psb_mmu_free_pt(pt);
296 }
297
298 vfree(pd->tables);
299 __free_page(pd->dummy_page);
300 __free_page(pd->dummy_pt);
301 __free_page(pd->p);
302 kfree(pd);
303 up_write(&driver->sem);
304}
305
306static struct psb_mmu_pt *psb_mmu_alloc_pt(struct psb_mmu_pd *pd)
307{
308 struct psb_mmu_pt *pt = kmalloc(sizeof(*pt), GFP_KERNEL);
309 void *v;
310 uint32_t clflush_add = pd->driver->clflush_add >> PAGE_SHIFT;
311 uint32_t clflush_count = PAGE_SIZE / clflush_add;
312 spinlock_t *lock = &pd->driver->lock;
313 uint8_t *clf;
314 uint32_t *ptes;
315 int i;
316
317 if (!pt)
318 return NULL;
319
320 pt->p = alloc_page(GFP_DMA32);
321 if (!pt->p) {
322 kfree(pt);
323 return NULL;
324 }
325
326 spin_lock(lock);
327
328 v = kmap_atomic(pt->p, KM_USER0);
329 clf = (uint8_t *) v;
330 ptes = (uint32_t *) v;
331 for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
332 *ptes++ = pd->invalid_pte;
333
334
335 if (pd->driver->has_clflush && pd->hw_context != -1) {
336 mb();
337 for (i = 0; i < clflush_count; ++i) {
338 psb_clflush(clf);
339 clf += clflush_add;
340 }
341 mb();
342 }
343
344 kunmap_atomic(v, KM_USER0);
345 spin_unlock(lock);
346
347 pt->count = 0;
348 pt->pd = pd;
349 pt->index = 0;
350
351 return pt;
352}
353
354struct psb_mmu_pt *psb_mmu_pt_alloc_map_lock(struct psb_mmu_pd *pd,
355 unsigned long addr)
356{
357 uint32_t index = psb_mmu_pd_index(addr);
358 struct psb_mmu_pt *pt;
359 uint32_t *v;
360 spinlock_t *lock = &pd->driver->lock;
361
362 spin_lock(lock);
363 pt = pd->tables[index];
364 while (!pt) {
365 spin_unlock(lock);
366 pt = psb_mmu_alloc_pt(pd);
367 if (!pt)
368 return NULL;
369 spin_lock(lock);
370
371 if (pd->tables[index]) {
372 spin_unlock(lock);
373 psb_mmu_free_pt(pt);
374 spin_lock(lock);
375 pt = pd->tables[index];
376 continue;
377 }
378
379 v = kmap_atomic(pd->p, KM_USER0);
380 pd->tables[index] = pt;
381 v[index] = (page_to_pfn(pt->p) << 12) | pd->pd_mask;
382 pt->index = index;
383 kunmap_atomic((void *) v, KM_USER0);
384
385 if (pd->hw_context != -1) {
386 psb_mmu_clflush(pd->driver, (void *) &v[index]);
387 atomic_set(&pd->driver->needs_tlbflush, 1);
388 }
389 }
390 pt->v = kmap_atomic(pt->p, KM_USER0);
391 return pt;
392}
393
394static struct psb_mmu_pt *psb_mmu_pt_map_lock(struct psb_mmu_pd *pd,
395 unsigned long addr)
396{
397 uint32_t index = psb_mmu_pd_index(addr);
398 struct psb_mmu_pt *pt;
399 spinlock_t *lock = &pd->driver->lock;
400
401 spin_lock(lock);
402 pt = pd->tables[index];
403 if (!pt) {
404 spin_unlock(lock);
405 return NULL;
406 }
407 pt->v = kmap_atomic(pt->p, KM_USER0);
408 return pt;
409}
410
411static void psb_mmu_pt_unmap_unlock(struct psb_mmu_pt *pt)
412{
413 struct psb_mmu_pd *pd = pt->pd;
414 uint32_t *v;
415
416 kunmap_atomic(pt->v, KM_USER0);
417 if (pt->count == 0) {
418 v = kmap_atomic(pd->p, KM_USER0);
419 v[pt->index] = pd->invalid_pde;
420 pd->tables[pt->index] = NULL;
421
422 if (pd->hw_context != -1) {
423 psb_mmu_clflush(pd->driver,
424 (void *) &v[pt->index]);
425 atomic_set(&pd->driver->needs_tlbflush, 1);
426 }
427 kunmap_atomic(pt->v, KM_USER0);
428 spin_unlock(&pd->driver->lock);
429 psb_mmu_free_pt(pt);
430 return;
431 }
432 spin_unlock(&pd->driver->lock);
433}
434
435static inline void psb_mmu_set_pte(struct psb_mmu_pt *pt,
436 unsigned long addr, uint32_t pte)
437{
438 pt->v[psb_mmu_pt_index(addr)] = pte;
439}
440
441static inline void psb_mmu_invalidate_pte(struct psb_mmu_pt *pt,
442 unsigned long addr)
443{
444 pt->v[psb_mmu_pt_index(addr)] = pt->pd->invalid_pte;
445}
446
447
448void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd,
449 uint32_t mmu_offset, uint32_t gtt_start,
450 uint32_t gtt_pages)
451{
452 uint32_t *v;
453 uint32_t start = psb_mmu_pd_index(mmu_offset);
454 struct psb_mmu_driver *driver = pd->driver;
455 int num_pages = gtt_pages;
456
457 down_read(&driver->sem);
458 spin_lock(&driver->lock);
459
460 v = kmap_atomic(pd->p, KM_USER0);
461 v += start;
462
463 while (gtt_pages--) {
464 *v++ = gtt_start | pd->pd_mask;
465 gtt_start += PAGE_SIZE;
466 }
467
468 /*ttm_tt_cache_flush(&pd->p, num_pages);*/
469 psb_pages_clflush(pd->driver, &pd->p, num_pages);
470 kunmap_atomic(v, KM_USER0);
471 spin_unlock(&driver->lock);
472
473 if (pd->hw_context != -1)
474 atomic_set(&pd->driver->needs_tlbflush, 1);
475
476 up_read(&pd->driver->sem);
477 psb_mmu_flush_pd(pd->driver, 0);
478}
479
480struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver *driver)
481{
482 struct psb_mmu_pd *pd;
483
484 /* down_read(&driver->sem); */
485 pd = driver->default_pd;
486 /* up_read(&driver->sem); */
487
488 return pd;
489}
490
491/* Returns the physical address of the PD shared by sgx/msvdx */
492uint32_t psb_get_default_pd_addr(struct psb_mmu_driver *driver)
493{
494 struct psb_mmu_pd *pd;
495
496 pd = psb_mmu_get_default_pd(driver);
497 return page_to_pfn(pd->p) << PAGE_SHIFT;
498}
499
500void psb_mmu_driver_takedown(struct psb_mmu_driver *driver)
501{
502 psb_mmu_free_pagedir(driver->default_pd);
503 kfree(driver);
504}
505
506struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
507 int trap_pagefaults,
508 int invalid_type,
509 struct drm_psb_private *dev_priv)
510{
511 struct psb_mmu_driver *driver;
512
513 driver = kmalloc(sizeof(*driver), GFP_KERNEL);
514
515 if (!driver)
516 return NULL;
517 driver->dev_priv = dev_priv;
518
519 driver->default_pd = psb_mmu_alloc_pd(driver, trap_pagefaults,
520 invalid_type);
521 if (!driver->default_pd)
522 goto out_err1;
523
524 spin_lock_init(&driver->lock);
525 init_rwsem(&driver->sem);
526 down_write(&driver->sem);
527 driver->register_map = registers;
528 atomic_set(&driver->needs_tlbflush, 1);
529
530 driver->has_clflush = 0;
531
532 if (boot_cpu_has(X86_FEATURE_CLFLSH)) {
533 uint32_t tfms, misc, cap0, cap4, clflush_size;
534
535 /*
536 * clflush size is determined at kernel setup for x86_64
537 * but not for i386. We have to do it here.
538 */
539
540 cpuid(0x00000001, &tfms, &misc, &cap0, &cap4);
541 clflush_size = ((misc >> 8) & 0xff) * 8;
542 driver->has_clflush = 1;
543 driver->clflush_add =
544 PAGE_SIZE * clflush_size / sizeof(uint32_t);
545 driver->clflush_mask = driver->clflush_add - 1;
546 driver->clflush_mask = ~driver->clflush_mask;
547 }
548
549 up_write(&driver->sem);
550 return driver;
551
552out_err1:
553 kfree(driver);
554 return NULL;
555}
556
557static void psb_mmu_flush_ptes(struct psb_mmu_pd *pd,
558 unsigned long address, uint32_t num_pages,
559 uint32_t desired_tile_stride,
560 uint32_t hw_tile_stride)
561{
562 struct psb_mmu_pt *pt;
563 uint32_t rows = 1;
564 uint32_t i;
565 unsigned long addr;
566 unsigned long end;
567 unsigned long next;
568 unsigned long add;
569 unsigned long row_add;
570 unsigned long clflush_add = pd->driver->clflush_add;
571 unsigned long clflush_mask = pd->driver->clflush_mask;
572
573 if (!pd->driver->has_clflush) {
574 /*ttm_tt_cache_flush(&pd->p, num_pages);*/
575 psb_pages_clflush(pd->driver, &pd->p, num_pages);
576 return;
577 }
578
579 if (hw_tile_stride)
580 rows = num_pages / desired_tile_stride;
581 else
582 desired_tile_stride = num_pages;
583
584 add = desired_tile_stride << PAGE_SHIFT;
585 row_add = hw_tile_stride << PAGE_SHIFT;
586 mb();
587 for (i = 0; i < rows; ++i) {
588
589 addr = address;
590 end = addr + add;
591
592 do {
593 next = psb_pd_addr_end(addr, end);
594 pt = psb_mmu_pt_map_lock(pd, addr);
595 if (!pt)
596 continue;
597 do {
598 psb_clflush(&pt->v
599 [psb_mmu_pt_index(addr)]);
600 } while (addr +=
601 clflush_add,
602 (addr & clflush_mask) < next);
603
604 psb_mmu_pt_unmap_unlock(pt);
605 } while (addr = next, next != end);
606 address += row_add;
607 }
608 mb();
609}
610
611void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd,
612 unsigned long address, uint32_t num_pages)
613{
614 struct psb_mmu_pt *pt;
615 unsigned long addr;
616 unsigned long end;
617 unsigned long next;
618 unsigned long f_address = address;
619
620 down_read(&pd->driver->sem);
621
622 addr = address;
623 end = addr + (num_pages << PAGE_SHIFT);
624
625 do {
626 next = psb_pd_addr_end(addr, end);
627 pt = psb_mmu_pt_alloc_map_lock(pd, addr);
628 if (!pt)
629 goto out;
630 do {
631 psb_mmu_invalidate_pte(pt, addr);
632 --pt->count;
633 } while (addr += PAGE_SIZE, addr < next);
634 psb_mmu_pt_unmap_unlock(pt);
635
636 } while (addr = next, next != end);
637
638out:
639 if (pd->hw_context != -1)
640 psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
641
642 up_read(&pd->driver->sem);
643
644 if (pd->hw_context != -1)
645 psb_mmu_flush(pd->driver, 0);
646
647 return;
648}
649
650void psb_mmu_remove_pages(struct psb_mmu_pd *pd, unsigned long address,
651 uint32_t num_pages, uint32_t desired_tile_stride,
652 uint32_t hw_tile_stride)
653{
654 struct psb_mmu_pt *pt;
655 uint32_t rows = 1;
656 uint32_t i;
657 unsigned long addr;
658 unsigned long end;
659 unsigned long next;
660 unsigned long add;
661 unsigned long row_add;
662 unsigned long f_address = address;
663
664 if (hw_tile_stride)
665 rows = num_pages / desired_tile_stride;
666 else
667 desired_tile_stride = num_pages;
668
669 add = desired_tile_stride << PAGE_SHIFT;
670 row_add = hw_tile_stride << PAGE_SHIFT;
671
672 /* down_read(&pd->driver->sem); */
673
674 /* Make sure we only need to flush this processor's cache */
675
676 for (i = 0; i < rows; ++i) {
677
678 addr = address;
679 end = addr + add;
680
681 do {
682 next = psb_pd_addr_end(addr, end);
683 pt = psb_mmu_pt_map_lock(pd, addr);
684 if (!pt)
685 continue;
686 do {
687 psb_mmu_invalidate_pte(pt, addr);
688 --pt->count;
689
690 } while (addr += PAGE_SIZE, addr < next);
691 psb_mmu_pt_unmap_unlock(pt);
692
693 } while (addr = next, next != end);
694 address += row_add;
695 }
696 if (pd->hw_context != -1)
697 psb_mmu_flush_ptes(pd, f_address, num_pages,
698 desired_tile_stride, hw_tile_stride);
699
700 /* up_read(&pd->driver->sem); */
701
702 if (pd->hw_context != -1)
703 psb_mmu_flush(pd->driver, 0);
704}
705
706int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, uint32_t start_pfn,
707 unsigned long address, uint32_t num_pages,
708 int type)
709{
710 struct psb_mmu_pt *pt;
711 uint32_t pte;
712 unsigned long addr;
713 unsigned long end;
714 unsigned long next;
715 unsigned long f_address = address;
716 int ret = 0;
717
718 down_read(&pd->driver->sem);
719
720 addr = address;
721 end = addr + (num_pages << PAGE_SHIFT);
722
723 do {
724 next = psb_pd_addr_end(addr, end);
725 pt = psb_mmu_pt_alloc_map_lock(pd, addr);
726 if (!pt) {
727 ret = -ENOMEM;
728 goto out;
729 }
730 do {
731 pte = psb_mmu_mask_pte(start_pfn++, type);
732 psb_mmu_set_pte(pt, addr, pte);
733 pt->count++;
734 } while (addr += PAGE_SIZE, addr < next);
735 psb_mmu_pt_unmap_unlock(pt);
736
737 } while (addr = next, next != end);
738
739out:
740 if (pd->hw_context != -1)
741 psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
742
743 up_read(&pd->driver->sem);
744
745 if (pd->hw_context != -1)
746 psb_mmu_flush(pd->driver, 1);
747
748 return ret;
749}
750
751int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages,
752 unsigned long address, uint32_t num_pages,
753 uint32_t desired_tile_stride,
754 uint32_t hw_tile_stride, int type)
755{
756 struct psb_mmu_pt *pt;
757 uint32_t rows = 1;
758 uint32_t i;
759 uint32_t pte;
760 unsigned long addr;
761 unsigned long end;
762 unsigned long next;
763 unsigned long add;
764 unsigned long row_add;
765 unsigned long f_address = address;
766 int ret = 0;
767
768 if (hw_tile_stride) {
769 if (num_pages % desired_tile_stride != 0)
770 return -EINVAL;
771 rows = num_pages / desired_tile_stride;
772 } else {
773 desired_tile_stride = num_pages;
774 }
775
776 add = desired_tile_stride << PAGE_SHIFT;
777 row_add = hw_tile_stride << PAGE_SHIFT;
778
779 down_read(&pd->driver->sem);
780
781 for (i = 0; i < rows; ++i) {
782
783 addr = address;
784 end = addr + add;
785
786 do {
787 next = psb_pd_addr_end(addr, end);
788 pt = psb_mmu_pt_alloc_map_lock(pd, addr);
789 if (!pt) {
790 ret = -ENOMEM;
791 goto out;
792 }
793 do {
794 pte =
795 psb_mmu_mask_pte(page_to_pfn(*pages++),
796 type);
797 psb_mmu_set_pte(pt, addr, pte);
798 pt->count++;
799 } while (addr += PAGE_SIZE, addr < next);
800 psb_mmu_pt_unmap_unlock(pt);
801
802 } while (addr = next, next != end);
803
804 address += row_add;
805 }
806out:
807 if (pd->hw_context != -1)
808 psb_mmu_flush_ptes(pd, f_address, num_pages,
809 desired_tile_stride, hw_tile_stride);
810
811 up_read(&pd->driver->sem);
812
813 if (pd->hw_context != -1)
814 psb_mmu_flush(pd->driver, 1);
815
816 return ret;
817}
818
819int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
820 unsigned long *pfn)
821{
822 int ret;
823 struct psb_mmu_pt *pt;
824 uint32_t tmp;
825 spinlock_t *lock = &pd->driver->lock;
826
827 down_read(&pd->driver->sem);
828 pt = psb_mmu_pt_map_lock(pd, virtual);
829 if (!pt) {
830 uint32_t *v;
831
832 spin_lock(lock);
833 v = kmap_atomic(pd->p, KM_USER0);
834 tmp = v[psb_mmu_pd_index(virtual)];
835 kunmap_atomic(v, KM_USER0);
836 spin_unlock(lock);
837
838 if (tmp != pd->invalid_pde || !(tmp & PSB_PTE_VALID) ||
839 !(pd->invalid_pte & PSB_PTE_VALID)) {
840 ret = -EINVAL;
841 goto out;
842 }
843 ret = 0;
844 *pfn = pd->invalid_pte >> PAGE_SHIFT;
845 goto out;
846 }
847 tmp = pt->v[psb_mmu_pt_index(virtual)];
848 if (!(tmp & PSB_PTE_VALID)) {
849 ret = -EINVAL;
850 } else {
851 ret = 0;
852 *pfn = tmp >> PAGE_SHIFT;
853 }
854 psb_mmu_pt_unmap_unlock(pt);
855out:
856 up_read(&pd->driver->sem);
857 return ret;
858}
diff --git a/drivers/gpu/drm/gma500/oaktrail.h b/drivers/gpu/drm/gma500/oaktrail.h
new file mode 100644
index 00000000000..2da1f368f14
--- /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 00000000000..9d12a3ee160
--- /dev/null
+++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c
@@ -0,0 +1,604 @@
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_encoder *psb_intel_encoder = NULL;
317 uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
318 struct drm_connector *connector;
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(connector, &mode_config->connector_list, head) {
331 if (!connector->encoder || connector->encoder->crtc != crtc)
332 continue;
333
334 psb_intel_encoder = psb_intel_attached_encoder(connector);
335
336 switch (psb_intel_encoder->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_encoder)
367 drm_connector_property_get_value(connector,
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 psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
525 struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
526 int pipe = psb_intel_crtc->pipe;
527 unsigned long start, offset;
528
529 int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE);
530 int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
531 int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
532 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
533 u32 dspcntr;
534 int ret = 0;
535
536 /* no fb bound */
537 if (!crtc->fb) {
538 dev_dbg(dev->dev, "No FB bound\n");
539 return 0;
540 }
541
542 if (!gma_power_begin(dev, true))
543 return 0;
544
545 start = psbfb->gtt->offset;
546 offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
547
548 REG_WRITE(dspstride, crtc->fb->pitches[0]);
549
550 dspcntr = REG_READ(dspcntr_reg);
551 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
552
553 switch (crtc->fb->bits_per_pixel) {
554 case 8:
555 dspcntr |= DISPPLANE_8BPP;
556 break;
557 case 16:
558 if (crtc->fb->depth == 15)
559 dspcntr |= DISPPLANE_15_16BPP;
560 else
561 dspcntr |= DISPPLANE_16BPP;
562 break;
563 case 24:
564 case 32:
565 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
566 break;
567 default:
568 dev_err(dev->dev, "Unknown color depth\n");
569 ret = -EINVAL;
570 goto pipe_set_base_exit;
571 }
572 REG_WRITE(dspcntr_reg, dspcntr);
573
574 REG_WRITE(dspbase, offset);
575 REG_READ(dspbase);
576 REG_WRITE(dspsurf, start);
577 REG_READ(dspsurf);
578
579pipe_set_base_exit:
580 gma_power_end(dev);
581 return ret;
582}
583
584static void oaktrail_crtc_prepare(struct drm_crtc *crtc)
585{
586 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
587 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
588}
589
590static void oaktrail_crtc_commit(struct drm_crtc *crtc)
591{
592 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
593 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
594}
595
596const struct drm_crtc_helper_funcs oaktrail_helper_funcs = {
597 .dpms = oaktrail_crtc_dpms,
598 .mode_fixup = oaktrail_crtc_mode_fixup,
599 .mode_set = oaktrail_crtc_mode_set,
600 .mode_set_base = oaktrail_pipe_set_base,
601 .prepare = oaktrail_crtc_prepare,
602 .commit = oaktrail_crtc_commit,
603};
604
diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c
new file mode 100644
index 00000000000..63aea2f010d
--- /dev/null
+++ b/drivers/gpu/drm/gma500/oaktrail_device.c
@@ -0,0 +1,512 @@
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 "gma_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#include "intel_bios.h"
33
34static int oaktrail_output_init(struct drm_device *dev)
35{
36 struct drm_psb_private *dev_priv = dev->dev_private;
37 if (dev_priv->iLVDS_enable)
38 oaktrail_lvds_init(dev, &dev_priv->mode_dev);
39 else
40 dev_err(dev->dev, "DSI is not supported\n");
41 if (dev_priv->hdmi_priv)
42 oaktrail_hdmi_init(dev, &dev_priv->mode_dev);
43 return 0;
44}
45
46/*
47 * Provide the low level interfaces for the Moorestown backlight
48 */
49
50#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
51
52#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF
53#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
54#define BLC_PWM_FREQ_CALC_CONSTANT 32
55#define MHz 1000000
56#define BLC_ADJUSTMENT_MAX 100
57
58static struct backlight_device *oaktrail_backlight_device;
59static int oaktrail_brightness;
60
61static int oaktrail_set_brightness(struct backlight_device *bd)
62{
63 struct drm_device *dev = bl_get_data(oaktrail_backlight_device);
64 struct drm_psb_private *dev_priv = dev->dev_private;
65 int level = bd->props.brightness;
66 u32 blc_pwm_ctl;
67 u32 max_pwm_blc;
68
69 /* Percentage 1-100% being valid */
70 if (level < 1)
71 level = 1;
72
73 if (gma_power_begin(dev, 0)) {
74 /* Calculate and set the brightness value */
75 max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16;
76 blc_pwm_ctl = level * max_pwm_blc / 100;
77
78 /* Adjust the backlight level with the percent in
79 * dev_priv->blc_adj1;
80 */
81 blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1;
82 blc_pwm_ctl = blc_pwm_ctl / 100;
83
84 /* Adjust the backlight level with the percent in
85 * dev_priv->blc_adj2;
86 */
87 blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2;
88 blc_pwm_ctl = blc_pwm_ctl / 100;
89
90 /* force PWM bit on */
91 REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2)));
92 REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl);
93 gma_power_end(dev);
94 }
95 oaktrail_brightness = level;
96 return 0;
97}
98
99static int oaktrail_get_brightness(struct backlight_device *bd)
100{
101 /* return locally cached var instead of HW read (due to DPST etc.) */
102 /* FIXME: ideally return actual value in case firmware fiddled with
103 it */
104 return oaktrail_brightness;
105}
106
107static int device_backlight_init(struct drm_device *dev)
108{
109 struct drm_psb_private *dev_priv = dev->dev_private;
110 unsigned long core_clock;
111 u16 bl_max_freq;
112 uint32_t value;
113 uint32_t blc_pwm_precision_factor;
114
115 dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
116 dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
117 bl_max_freq = 256;
118 /* this needs to be set elsewhere */
119 blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR;
120
121 core_clock = dev_priv->core_freq;
122
123 value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
124 value *= blc_pwm_precision_factor;
125 value /= bl_max_freq;
126 value /= blc_pwm_precision_factor;
127
128 if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ)
129 return -ERANGE;
130
131 if (gma_power_begin(dev, false)) {
132 REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2)));
133 REG_WRITE(BLC_PWM_CTL, value | (value << 16));
134 gma_power_end(dev);
135 }
136 return 0;
137}
138
139static const struct backlight_ops oaktrail_ops = {
140 .get_brightness = oaktrail_get_brightness,
141 .update_status = oaktrail_set_brightness,
142};
143
144int oaktrail_backlight_init(struct drm_device *dev)
145{
146 struct drm_psb_private *dev_priv = dev->dev_private;
147 int ret;
148 struct backlight_properties props;
149
150 memset(&props, 0, sizeof(struct backlight_properties));
151 props.max_brightness = 100;
152 props.type = BACKLIGHT_PLATFORM;
153
154 oaktrail_backlight_device = backlight_device_register("oaktrail-bl",
155 NULL, (void *)dev, &oaktrail_ops, &props);
156
157 if (IS_ERR(oaktrail_backlight_device))
158 return PTR_ERR(oaktrail_backlight_device);
159
160 ret = device_backlight_init(dev);
161 if (ret < 0) {
162 backlight_device_unregister(oaktrail_backlight_device);
163 return ret;
164 }
165 oaktrail_backlight_device->props.brightness = 100;
166 oaktrail_backlight_device->props.max_brightness = 100;
167 backlight_update_status(oaktrail_backlight_device);
168 dev_priv->backlight_device = oaktrail_backlight_device;
169 return 0;
170}
171
172#endif
173
174/*
175 * Provide the Moorestown specific chip logic and low level methods
176 * for power management
177 */
178
179static void oaktrail_init_pm(struct drm_device *dev)
180{
181}
182
183/**
184 * oaktrail_save_display_registers - save registers lost on suspend
185 * @dev: our DRM device
186 *
187 * Save the state we need in order to be able to restore the interface
188 * upon resume from suspend
189 */
190static int oaktrail_save_display_registers(struct drm_device *dev)
191{
192 struct drm_psb_private *dev_priv = dev->dev_private;
193 int i;
194 u32 pp_stat;
195
196 /* Display arbitration control + watermarks */
197 dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
198 dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1);
199 dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2);
200 dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3);
201 dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4);
202 dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5);
203 dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
204 dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
205
206 /* Pipe & plane A info */
207 dev_priv->savePIPEACONF = PSB_RVDC32(PIPEACONF);
208 dev_priv->savePIPEASRC = PSB_RVDC32(PIPEASRC);
209 dev_priv->saveFPA0 = PSB_RVDC32(MRST_FPA0);
210 dev_priv->saveFPA1 = PSB_RVDC32(MRST_FPA1);
211 dev_priv->saveDPLL_A = PSB_RVDC32(MRST_DPLL_A);
212 dev_priv->saveHTOTAL_A = PSB_RVDC32(HTOTAL_A);
213 dev_priv->saveHBLANK_A = PSB_RVDC32(HBLANK_A);
214 dev_priv->saveHSYNC_A = PSB_RVDC32(HSYNC_A);
215 dev_priv->saveVTOTAL_A = PSB_RVDC32(VTOTAL_A);
216 dev_priv->saveVBLANK_A = PSB_RVDC32(VBLANK_A);
217 dev_priv->saveVSYNC_A = PSB_RVDC32(VSYNC_A);
218 dev_priv->saveBCLRPAT_A = PSB_RVDC32(BCLRPAT_A);
219 dev_priv->saveDSPACNTR = PSB_RVDC32(DSPACNTR);
220 dev_priv->saveDSPASTRIDE = PSB_RVDC32(DSPASTRIDE);
221 dev_priv->saveDSPAADDR = PSB_RVDC32(DSPABASE);
222 dev_priv->saveDSPASURF = PSB_RVDC32(DSPASURF);
223 dev_priv->saveDSPALINOFF = PSB_RVDC32(DSPALINOFF);
224 dev_priv->saveDSPATILEOFF = PSB_RVDC32(DSPATILEOFF);
225
226 /* Save cursor regs */
227 dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
228 dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
229 dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);
230
231 /* Save palette (gamma) */
232 for (i = 0; i < 256; i++)
233 dev_priv->save_palette_a[i] = PSB_RVDC32(PALETTE_A + (i << 2));
234
235 if (dev_priv->hdmi_priv)
236 oaktrail_hdmi_save(dev);
237
238 /* Save performance state */
239 dev_priv->savePERF_MODE = PSB_RVDC32(MRST_PERF_MODE);
240
241 /* LVDS state */
242 dev_priv->savePP_CONTROL = PSB_RVDC32(PP_CONTROL);
243 dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
244 dev_priv->savePFIT_AUTO_RATIOS = PSB_RVDC32(PFIT_AUTO_RATIOS);
245 dev_priv->saveBLC_PWM_CTL = PSB_RVDC32(BLC_PWM_CTL);
246 dev_priv->saveBLC_PWM_CTL2 = PSB_RVDC32(BLC_PWM_CTL2);
247 dev_priv->saveLVDS = PSB_RVDC32(LVDS);
248 dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
249 dev_priv->savePP_ON_DELAYS = PSB_RVDC32(LVDSPP_ON);
250 dev_priv->savePP_OFF_DELAYS = PSB_RVDC32(LVDSPP_OFF);
251 dev_priv->savePP_DIVISOR = PSB_RVDC32(PP_CYCLE);
252
253 /* HW overlay */
254 dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD);
255 dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0);
256 dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1);
257 dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2);
258 dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3);
259 dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4);
260 dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
261
262 /* DPST registers */
263 dev_priv->saveHISTOGRAM_INT_CONTROL_REG =
264 PSB_RVDC32(HISTOGRAM_INT_CONTROL);
265 dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG =
266 PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
267 dev_priv->savePWM_CONTROL_LOGIC = PSB_RVDC32(PWM_CONTROL_LOGIC);
268
269 if (dev_priv->iLVDS_enable) {
270 /* Shut down the panel */
271 PSB_WVDC32(0, PP_CONTROL);
272
273 do {
274 pp_stat = PSB_RVDC32(PP_STATUS);
275 } while (pp_stat & 0x80000000);
276
277 /* Turn off the plane */
278 PSB_WVDC32(0x58000000, DSPACNTR);
279 /* Trigger the plane disable */
280 PSB_WVDC32(0, DSPASURF);
281
282 /* Wait ~4 ticks */
283 msleep(4);
284
285 /* Turn off pipe */
286 PSB_WVDC32(0x0, PIPEACONF);
287 /* Wait ~8 ticks */
288 msleep(8);
289
290 /* Turn off PLLs */
291 PSB_WVDC32(0, MRST_DPLL_A);
292 }
293 return 0;
294}
295
296/**
297 * oaktrail_restore_display_registers - restore lost register state
298 * @dev: our DRM device
299 *
300 * Restore register state that was lost during suspend and resume.
301 */
302static int oaktrail_restore_display_registers(struct drm_device *dev)
303{
304 struct drm_psb_private *dev_priv = dev->dev_private;
305 u32 pp_stat;
306 int i;
307
308 /* Display arbitration + watermarks */
309 PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
310 PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1);
311 PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2);
312 PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3);
313 PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4);
314 PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5);
315 PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6);
316 PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT);
317
318 /* Make sure VGA plane is off. it initializes to on after reset!*/
319 PSB_WVDC32(0x80000000, VGACNTRL);
320
321 /* set the plls */
322 PSB_WVDC32(dev_priv->saveFPA0, MRST_FPA0);
323 PSB_WVDC32(dev_priv->saveFPA1, MRST_FPA1);
324
325 /* Actually enable it */
326 PSB_WVDC32(dev_priv->saveDPLL_A, MRST_DPLL_A);
327 DRM_UDELAY(150);
328
329 /* Restore mode */
330 PSB_WVDC32(dev_priv->saveHTOTAL_A, HTOTAL_A);
331 PSB_WVDC32(dev_priv->saveHBLANK_A, HBLANK_A);
332 PSB_WVDC32(dev_priv->saveHSYNC_A, HSYNC_A);
333 PSB_WVDC32(dev_priv->saveVTOTAL_A, VTOTAL_A);
334 PSB_WVDC32(dev_priv->saveVBLANK_A, VBLANK_A);
335 PSB_WVDC32(dev_priv->saveVSYNC_A, VSYNC_A);
336 PSB_WVDC32(dev_priv->savePIPEASRC, PIPEASRC);
337 PSB_WVDC32(dev_priv->saveBCLRPAT_A, BCLRPAT_A);
338
339 /* Restore performance mode*/
340 PSB_WVDC32(dev_priv->savePERF_MODE, MRST_PERF_MODE);
341
342 /* Enable the pipe*/
343 if (dev_priv->iLVDS_enable)
344 PSB_WVDC32(dev_priv->savePIPEACONF, PIPEACONF);
345
346 /* Set up the plane*/
347 PSB_WVDC32(dev_priv->saveDSPALINOFF, DSPALINOFF);
348 PSB_WVDC32(dev_priv->saveDSPASTRIDE, DSPASTRIDE);
349 PSB_WVDC32(dev_priv->saveDSPATILEOFF, DSPATILEOFF);
350
351 /* Enable the plane */
352 PSB_WVDC32(dev_priv->saveDSPACNTR, DSPACNTR);
353 PSB_WVDC32(dev_priv->saveDSPASURF, DSPASURF);
354
355 /* Enable Cursor A */
356 PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
357 PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
358 PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);
359
360 /* Restore palette (gamma) */
361 for (i = 0; i < 256; i++)
362 PSB_WVDC32(dev_priv->save_palette_a[i], PALETTE_A + (i << 2));
363
364 if (dev_priv->hdmi_priv)
365 oaktrail_hdmi_restore(dev);
366
367 if (dev_priv->iLVDS_enable) {
368 PSB_WVDC32(dev_priv->saveBLC_PWM_CTL2, BLC_PWM_CTL2);
369 PSB_WVDC32(dev_priv->saveLVDS, LVDS); /*port 61180h*/
370 PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
371 PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
372 PSB_WVDC32(dev_priv->savePFIT_AUTO_RATIOS, PFIT_AUTO_RATIOS);
373 PSB_WVDC32(dev_priv->saveBLC_PWM_CTL, BLC_PWM_CTL);
374 PSB_WVDC32(dev_priv->savePP_ON_DELAYS, LVDSPP_ON);
375 PSB_WVDC32(dev_priv->savePP_OFF_DELAYS, LVDSPP_OFF);
376 PSB_WVDC32(dev_priv->savePP_DIVISOR, PP_CYCLE);
377 PSB_WVDC32(dev_priv->savePP_CONTROL, PP_CONTROL);
378 }
379
380 /* Wait for cycle delay */
381 do {
382 pp_stat = PSB_RVDC32(PP_STATUS);
383 } while (pp_stat & 0x08000000);
384
385 /* Wait for panel power up */
386 do {
387 pp_stat = PSB_RVDC32(PP_STATUS);
388 } while (pp_stat & 0x10000000);
389
390 /* Restore HW overlay */
391 PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD);
392 PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0);
393 PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1);
394 PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2);
395 PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3);
396 PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4);
397 PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
398
399 /* DPST registers */
400 PSB_WVDC32(dev_priv->saveHISTOGRAM_INT_CONTROL_REG,
401 HISTOGRAM_INT_CONTROL);
402 PSB_WVDC32(dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG,
403 HISTOGRAM_LOGIC_CONTROL);
404 PSB_WVDC32(dev_priv->savePWM_CONTROL_LOGIC, PWM_CONTROL_LOGIC);
405
406 return 0;
407}
408
409/**
410 * oaktrail_power_down - power down the display island
411 * @dev: our DRM device
412 *
413 * Power down the display interface of our device
414 */
415static int oaktrail_power_down(struct drm_device *dev)
416{
417 struct drm_psb_private *dev_priv = dev->dev_private;
418 u32 pwr_mask ;
419 u32 pwr_sts;
420
421 pwr_mask = PSB_PWRGT_DISPLAY_MASK;
422 outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC);
423
424 while (true) {
425 pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
426 if ((pwr_sts & pwr_mask) == pwr_mask)
427 break;
428 else
429 udelay(10);
430 }
431 return 0;
432}
433
434/*
435 * oaktrail_power_up
436 *
437 * Restore power to the specified island(s) (powergating)
438 */
439static int oaktrail_power_up(struct drm_device *dev)
440{
441 struct drm_psb_private *dev_priv = dev->dev_private;
442 u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK;
443 u32 pwr_sts, pwr_cnt;
444
445 pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
446 pwr_cnt &= ~pwr_mask;
447 outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC));
448
449 while (true) {
450 pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
451 if ((pwr_sts & pwr_mask) == 0)
452 break;
453 else
454 udelay(10);
455 }
456 return 0;
457}
458
459
460static int oaktrail_chip_setup(struct drm_device *dev)
461{
462 struct drm_psb_private *dev_priv = dev->dev_private;
463 struct oaktrail_vbt *vbt = &dev_priv->vbt_data;
464 int ret;
465
466 ret = mid_chip_setup(dev);
467 if (ret < 0)
468 return ret;
469 if (vbt->size == 0) {
470 /* Now pull the BIOS data */
471 gma_intel_opregion_init(dev);
472 psb_intel_init_bios(dev);
473 }
474 return 0;
475}
476
477static void oaktrail_teardown(struct drm_device *dev)
478{
479 struct drm_psb_private *dev_priv = dev->dev_private;
480 struct oaktrail_vbt *vbt = &dev_priv->vbt_data;
481
482 oaktrail_hdmi_teardown(dev);
483 if (vbt->size == 0)
484 psb_intel_destroy_bios(dev);
485}
486
487const struct psb_ops oaktrail_chip_ops = {
488 .name = "Oaktrail",
489 .accel_2d = 1,
490 .pipes = 2,
491 .crtcs = 2,
492 .sgx_offset = MRST_SGX_OFFSET,
493
494 .chip_setup = oaktrail_chip_setup,
495 .chip_teardown = oaktrail_teardown,
496 .crtc_helper = &oaktrail_helper_funcs,
497 .crtc_funcs = &psb_intel_crtc_funcs,
498
499 .output_init = oaktrail_output_init,
500
501#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
502 .backlight_init = oaktrail_backlight_init,
503#endif
504
505 .init_pm = oaktrail_init_pm,
506 .save_regs = oaktrail_save_display_registers,
507 .restore_regs = oaktrail_restore_display_registers,
508 .power_down = oaktrail_power_down,
509 .power_up = oaktrail_power_up,
510
511 .i2c_bus = 1,
512};
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
new file mode 100644
index 00000000000..36878a60080
--- /dev/null
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
@@ -0,0 +1,859 @@
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_encoder *psb_intel_encoder;
647 struct psb_intel_connector *psb_intel_connector;
648 struct drm_connector *connector;
649 struct drm_encoder *encoder;
650
651 psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL);
652 if (!psb_intel_encoder)
653 return;
654
655 psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL);
656 if (!psb_intel_connector)
657 goto failed_connector;
658
659 connector = &psb_intel_connector->base;
660 encoder = &psb_intel_encoder->base;
661 drm_connector_init(dev, connector,
662 &oaktrail_hdmi_connector_funcs,
663 DRM_MODE_CONNECTOR_DVID);
664
665 drm_encoder_init(dev, encoder,
666 &oaktrail_hdmi_enc_funcs,
667 DRM_MODE_ENCODER_TMDS);
668
669 psb_intel_connector_attach_encoder(psb_intel_connector,
670 psb_intel_encoder);
671
672 psb_intel_encoder->type = INTEL_OUTPUT_HDMI;
673 drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs);
674 drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs);
675
676 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
677 connector->interlace_allowed = false;
678 connector->doublescan_allowed = false;
679 drm_sysfs_connector_add(connector);
680
681 return;
682
683failed_connector:
684 kfree(psb_intel_encoder);
685}
686
687static DEFINE_PCI_DEVICE_TABLE(hdmi_ids) = {
688 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) },
689 {}
690};
691
692void oaktrail_hdmi_setup(struct drm_device *dev)
693{
694 struct drm_psb_private *dev_priv = dev->dev_private;
695 struct pci_dev *pdev;
696 struct oaktrail_hdmi_dev *hdmi_dev;
697 int ret;
698
699 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
700 if (!pdev)
701 return;
702
703 hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL);
704 if (!hdmi_dev) {
705 dev_err(dev->dev, "failed to allocate memory\n");
706 goto out;
707 }
708
709
710 ret = pci_enable_device(pdev);
711 if (ret) {
712 dev_err(dev->dev, "failed to enable hdmi controller\n");
713 goto free;
714 }
715
716 hdmi_dev->mmio = pci_resource_start(pdev, 0);
717 hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
718 hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
719 if (!hdmi_dev->regs) {
720 dev_err(dev->dev, "failed to map hdmi mmio\n");
721 goto free;
722 }
723
724 hdmi_dev->dev = pdev;
725 pci_set_drvdata(pdev, hdmi_dev);
726
727 /* Initialize i2c controller */
728 ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev);
729 if (ret)
730 dev_err(dev->dev, "HDMI I2C initialization failed\n");
731
732 dev_priv->hdmi_priv = hdmi_dev;
733 oaktrail_hdmi_audio_disable(dev);
734 return;
735
736free:
737 kfree(hdmi_dev);
738out:
739 return;
740}
741
742void oaktrail_hdmi_teardown(struct drm_device *dev)
743{
744 struct drm_psb_private *dev_priv = dev->dev_private;
745 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
746 struct pci_dev *pdev;
747
748 if (hdmi_dev) {
749 pdev = hdmi_dev->dev;
750 pci_set_drvdata(pdev, NULL);
751 oaktrail_hdmi_i2c_exit(pdev);
752 iounmap(hdmi_dev->regs);
753 kfree(hdmi_dev);
754 pci_dev_put(pdev);
755 }
756}
757
758/* save HDMI register state */
759void oaktrail_hdmi_save(struct drm_device *dev)
760{
761 struct drm_psb_private *dev_priv = dev->dev_private;
762 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
763 int i;
764
765 /* dpll */
766 hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
767 hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL);
768 hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST);
769 hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE);
770 hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE);
771
772 /* pipe B */
773 dev_priv->savePIPEBCONF = PSB_RVDC32(PIPEBCONF);
774 dev_priv->savePIPEBSRC = PSB_RVDC32(PIPEBSRC);
775 dev_priv->saveHTOTAL_B = PSB_RVDC32(HTOTAL_B);
776 dev_priv->saveHBLANK_B = PSB_RVDC32(HBLANK_B);
777 dev_priv->saveHSYNC_B = PSB_RVDC32(HSYNC_B);
778 dev_priv->saveVTOTAL_B = PSB_RVDC32(VTOTAL_B);
779 dev_priv->saveVBLANK_B = PSB_RVDC32(VBLANK_B);
780 dev_priv->saveVSYNC_B = PSB_RVDC32(VSYNC_B);
781
782 hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF);
783 hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC);
784 hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B);
785 hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B);
786 hdmi_dev->savePCH_HSYNC_B = PSB_RVDC32(PCH_HSYNC_B);
787 hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B);
788 hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B);
789 hdmi_dev->savePCH_VSYNC_B = PSB_RVDC32(PCH_VSYNC_B);
790
791 /* plane */
792 dev_priv->saveDSPBCNTR = PSB_RVDC32(DSPBCNTR);
793 dev_priv->saveDSPBSTRIDE = PSB_RVDC32(DSPBSTRIDE);
794 dev_priv->saveDSPBADDR = PSB_RVDC32(DSPBBASE);
795 dev_priv->saveDSPBSURF = PSB_RVDC32(DSPBSURF);
796 dev_priv->saveDSPBLINOFF = PSB_RVDC32(DSPBLINOFF);
797 dev_priv->saveDSPBTILEOFF = PSB_RVDC32(DSPBTILEOFF);
798
799 /* cursor B */
800 dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
801 dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
802 dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
803
804 /* save palette */
805 for (i = 0; i < 256; i++)
806 dev_priv->save_palette_b[i] = PSB_RVDC32(PALETTE_B + (i << 2));
807}
808
809/* restore HDMI register state */
810void oaktrail_hdmi_restore(struct drm_device *dev)
811{
812 struct drm_psb_private *dev_priv = dev->dev_private;
813 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
814 int i;
815
816 /* dpll */
817 PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
818 PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL);
819 PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
820 PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
821 PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
822 DRM_UDELAY(150);
823
824 /* pipe */
825 PSB_WVDC32(dev_priv->savePIPEBSRC, PIPEBSRC);
826 PSB_WVDC32(dev_priv->saveHTOTAL_B, HTOTAL_B);
827 PSB_WVDC32(dev_priv->saveHBLANK_B, HBLANK_B);
828 PSB_WVDC32(dev_priv->saveHSYNC_B, HSYNC_B);
829 PSB_WVDC32(dev_priv->saveVTOTAL_B, VTOTAL_B);
830 PSB_WVDC32(dev_priv->saveVBLANK_B, VBLANK_B);
831 PSB_WVDC32(dev_priv->saveVSYNC_B, VSYNC_B);
832
833 PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC);
834 PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B);
835 PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B);
836 PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B, PCH_HSYNC_B);
837 PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B);
838 PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B);
839 PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B, PCH_VSYNC_B);
840
841 PSB_WVDC32(dev_priv->savePIPEBCONF, PIPEBCONF);
842 PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
843
844 /* plane */
845 PSB_WVDC32(dev_priv->saveDSPBLINOFF, DSPBLINOFF);
846 PSB_WVDC32(dev_priv->saveDSPBSTRIDE, DSPBSTRIDE);
847 PSB_WVDC32(dev_priv->saveDSPBTILEOFF, DSPBTILEOFF);
848 PSB_WVDC32(dev_priv->saveDSPBCNTR, DSPBCNTR);
849 PSB_WVDC32(dev_priv->saveDSPBSURF, DSPBSURF);
850
851 /* cursor B */
852 PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR);
853 PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS);
854 PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE);
855
856 /* restore palette */
857 for (i = 0; i < 256; i++)
858 PSB_WVDC32(dev_priv->save_palette_b[i], PALETTE_B + (i << 2));
859}
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 00000000000..705440874ac
--- /dev/null
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
@@ -0,0 +1,328 @@
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/export.h>
28#include <linux/mutex.h>
29#include <linux/pci.h>
30#include <linux/i2c.h>
31#include <linux/interrupt.h>
32#include <linux/delay.h>
33#include "psb_drv.h"
34
35#define HDMI_READ(reg) readl(hdmi_dev->regs + (reg))
36#define HDMI_WRITE(reg, val) writel(val, hdmi_dev->regs + (reg))
37
38#define HDMI_HCR 0x1000
39#define HCR_DETECT_HDP (1 << 6)
40#define HCR_ENABLE_HDCP (1 << 5)
41#define HCR_ENABLE_AUDIO (1 << 2)
42#define HCR_ENABLE_PIXEL (1 << 1)
43#define HCR_ENABLE_TMDS (1 << 0)
44#define HDMI_HICR 0x1004
45#define HDMI_INTR_I2C_ERROR (1 << 4)
46#define HDMI_INTR_I2C_FULL (1 << 3)
47#define HDMI_INTR_I2C_DONE (1 << 2)
48#define HDMI_INTR_HPD (1 << 0)
49#define HDMI_HSR 0x1008
50#define HDMI_HISR 0x100C
51#define HDMI_HI2CRDB0 0x1200
52#define HDMI_HI2CHCR 0x1240
53#define HI2C_HDCP_WRITE (0 << 2)
54#define HI2C_HDCP_RI_READ (1 << 2)
55#define HI2C_HDCP_READ (2 << 2)
56#define HI2C_EDID_READ (3 << 2)
57#define HI2C_READ_CONTINUE (1 << 1)
58#define HI2C_ENABLE_TRANSACTION (1 << 0)
59
60#define HDMI_ICRH 0x1100
61#define HDMI_HI2CTDR0 0x1244
62#define HDMI_HI2CTDR1 0x1248
63
64#define I2C_STAT_INIT 0
65#define I2C_READ_DONE 1
66#define I2C_TRANSACTION_DONE 2
67
68struct hdmi_i2c_dev {
69 struct i2c_adapter *adap;
70 struct mutex i2c_lock;
71 struct completion complete;
72 int status;
73 struct i2c_msg *msg;
74 int buf_offset;
75};
76
77static void hdmi_i2c_irq_enable(struct oaktrail_hdmi_dev *hdmi_dev)
78{
79 u32 temp;
80
81 temp = HDMI_READ(HDMI_HICR);
82 temp |= (HDMI_INTR_I2C_ERROR | HDMI_INTR_I2C_FULL | HDMI_INTR_I2C_DONE);
83 HDMI_WRITE(HDMI_HICR, temp);
84 HDMI_READ(HDMI_HICR);
85}
86
87static void hdmi_i2c_irq_disable(struct oaktrail_hdmi_dev *hdmi_dev)
88{
89 HDMI_WRITE(HDMI_HICR, 0x0);
90 HDMI_READ(HDMI_HICR);
91}
92
93static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg)
94{
95 struct oaktrail_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap);
96 struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
97 u32 temp;
98
99 i2c_dev->status = I2C_STAT_INIT;
100 i2c_dev->msg = pmsg;
101 i2c_dev->buf_offset = 0;
102 INIT_COMPLETION(i2c_dev->complete);
103
104 /* Enable I2C transaction */
105 temp = ((pmsg->len) << 20) | HI2C_EDID_READ | HI2C_ENABLE_TRANSACTION;
106 HDMI_WRITE(HDMI_HI2CHCR, temp);
107 HDMI_READ(HDMI_HI2CHCR);
108
109 while (i2c_dev->status != I2C_TRANSACTION_DONE)
110 wait_for_completion_interruptible_timeout(&i2c_dev->complete,
111 10 * HZ);
112
113 return 0;
114}
115
116static int xfer_write(struct i2c_adapter *adap, struct i2c_msg *pmsg)
117{
118 /*
119 * XXX: i2c write seems isn't useful for EDID probe, don't do anything
120 */
121 return 0;
122}
123
124static int oaktrail_hdmi_i2c_access(struct i2c_adapter *adap,
125 struct i2c_msg *pmsg,
126 int num)
127{
128 struct oaktrail_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap);
129 struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
130 int i, err = 0;
131
132 mutex_lock(&i2c_dev->i2c_lock);
133
134 /* Enable i2c unit */
135 HDMI_WRITE(HDMI_ICRH, 0x00008760);
136
137 /* Enable irq */
138 hdmi_i2c_irq_enable(hdmi_dev);
139 for (i = 0; i < num; i++) {
140 if (pmsg->len && pmsg->buf) {
141 if (pmsg->flags & I2C_M_RD)
142 err = xfer_read(adap, pmsg);
143 else
144 err = xfer_write(adap, pmsg);
145 }
146 pmsg++; /* next message */
147 }
148
149 /* Disable irq */
150 hdmi_i2c_irq_disable(hdmi_dev);
151
152 mutex_unlock(&i2c_dev->i2c_lock);
153
154 return i;
155}
156
157static u32 oaktrail_hdmi_i2c_func(struct i2c_adapter *adapter)
158{
159 return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR;
160}
161
162static const struct i2c_algorithm oaktrail_hdmi_i2c_algorithm = {
163 .master_xfer = oaktrail_hdmi_i2c_access,
164 .functionality = oaktrail_hdmi_i2c_func,
165};
166
167static struct i2c_adapter oaktrail_hdmi_i2c_adapter = {
168 .name = "oaktrail_hdmi_i2c",
169 .nr = 3,
170 .owner = THIS_MODULE,
171 .class = I2C_CLASS_DDC,
172 .algo = &oaktrail_hdmi_i2c_algorithm,
173};
174
175static void hdmi_i2c_read(struct oaktrail_hdmi_dev *hdmi_dev)
176{
177 struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
178 struct i2c_msg *msg = i2c_dev->msg;
179 u8 *buf = msg->buf;
180 u32 temp;
181 int i, offset;
182
183 offset = i2c_dev->buf_offset;
184 for (i = 0; i < 0x10; i++) {
185 temp = HDMI_READ(HDMI_HI2CRDB0 + (i * 4));
186 memcpy(buf + (offset + i * 4), &temp, 4);
187 }
188 i2c_dev->buf_offset += (0x10 * 4);
189
190 /* clearing read buffer full intr */
191 temp = HDMI_READ(HDMI_HISR);
192 HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_FULL);
193 HDMI_READ(HDMI_HISR);
194
195 /* continue read transaction */
196 temp = HDMI_READ(HDMI_HI2CHCR);
197 HDMI_WRITE(HDMI_HI2CHCR, temp | HI2C_READ_CONTINUE);
198 HDMI_READ(HDMI_HI2CHCR);
199
200 i2c_dev->status = I2C_READ_DONE;
201 return;
202}
203
204static void hdmi_i2c_transaction_done(struct oaktrail_hdmi_dev *hdmi_dev)
205{
206 struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
207 u32 temp;
208
209 /* clear transaction done intr */
210 temp = HDMI_READ(HDMI_HISR);
211 HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_DONE);
212 HDMI_READ(HDMI_HISR);
213
214
215 temp = HDMI_READ(HDMI_HI2CHCR);
216 HDMI_WRITE(HDMI_HI2CHCR, temp & ~HI2C_ENABLE_TRANSACTION);
217 HDMI_READ(HDMI_HI2CHCR);
218
219 i2c_dev->status = I2C_TRANSACTION_DONE;
220 return;
221}
222
223static irqreturn_t oaktrail_hdmi_i2c_handler(int this_irq, void *dev)
224{
225 struct oaktrail_hdmi_dev *hdmi_dev = dev;
226 struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
227 u32 stat;
228
229 stat = HDMI_READ(HDMI_HISR);
230
231 if (stat & HDMI_INTR_HPD) {
232 HDMI_WRITE(HDMI_HISR, stat | HDMI_INTR_HPD);
233 HDMI_READ(HDMI_HISR);
234 }
235
236 if (stat & HDMI_INTR_I2C_FULL)
237 hdmi_i2c_read(hdmi_dev);
238
239 if (stat & HDMI_INTR_I2C_DONE)
240 hdmi_i2c_transaction_done(hdmi_dev);
241
242 complete(&i2c_dev->complete);
243
244 return IRQ_HANDLED;
245}
246
247/*
248 * choose alternate function 2 of GPIO pin 52, 53,
249 * which is used by HDMI I2C logic
250 */
251static void oaktrail_hdmi_i2c_gpio_fix(void)
252{
253 void *base;
254 unsigned int gpio_base = 0xff12c000;
255 int gpio_len = 0x1000;
256 u32 temp;
257
258 base = ioremap((resource_size_t)gpio_base, gpio_len);
259 if (base == NULL) {
260 DRM_ERROR("gpio ioremap fail\n");
261 return;
262 }
263
264 temp = readl(base + 0x44);
265 DRM_DEBUG_DRIVER("old gpio val %x\n", temp);
266 writel((temp | 0x00000a00), (base + 0x44));
267 temp = readl(base + 0x44);
268 DRM_DEBUG_DRIVER("new gpio val %x\n", temp);
269
270 iounmap(base);
271}
272
273int oaktrail_hdmi_i2c_init(struct pci_dev *dev)
274{
275 struct oaktrail_hdmi_dev *hdmi_dev;
276 struct hdmi_i2c_dev *i2c_dev;
277 int ret;
278
279 hdmi_dev = pci_get_drvdata(dev);
280
281 i2c_dev = kzalloc(sizeof(struct hdmi_i2c_dev), GFP_KERNEL);
282 if (i2c_dev == NULL) {
283 DRM_ERROR("Can't allocate interface\n");
284 ret = -ENOMEM;
285 goto exit;
286 }
287
288 i2c_dev->adap = &oaktrail_hdmi_i2c_adapter;
289 i2c_dev->status = I2C_STAT_INIT;
290 init_completion(&i2c_dev->complete);
291 mutex_init(&i2c_dev->i2c_lock);
292 i2c_set_adapdata(&oaktrail_hdmi_i2c_adapter, hdmi_dev);
293 hdmi_dev->i2c_dev = i2c_dev;
294
295 /* Enable HDMI I2C function on gpio */
296 oaktrail_hdmi_i2c_gpio_fix();
297
298 /* request irq */
299 ret = request_irq(dev->irq, oaktrail_hdmi_i2c_handler, IRQF_SHARED,
300 oaktrail_hdmi_i2c_adapter.name, hdmi_dev);
301 if (ret) {
302 DRM_ERROR("Failed to request IRQ for I2C controller\n");
303 goto err;
304 }
305
306 /* Adapter registration */
307 ret = i2c_add_numbered_adapter(&oaktrail_hdmi_i2c_adapter);
308 return ret;
309
310err:
311 kfree(i2c_dev);
312exit:
313 return ret;
314}
315
316void oaktrail_hdmi_i2c_exit(struct pci_dev *dev)
317{
318 struct oaktrail_hdmi_dev *hdmi_dev;
319 struct hdmi_i2c_dev *i2c_dev;
320
321 hdmi_dev = pci_get_drvdata(dev);
322 if (i2c_del_adapter(&oaktrail_hdmi_i2c_adapter))
323 DRM_DEBUG_DRIVER("Failed to delete hdmi-i2c adapter\n");
324
325 i2c_dev = hdmi_dev->i2c_dev;
326 kfree(i2c_dev);
327 free_irq(dev->irq, hdmi_dev);
328}
diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c
new file mode 100644
index 00000000000..238bbe10530
--- /dev/null
+++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c
@@ -0,0 +1,449 @@
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_encoder *psb_intel_encoder,
47 bool on)
48{
49 u32 pp_status;
50 struct drm_psb_private *dev_priv = dev->dev_private;
51
52 if (!gma_power_begin(dev, true))
53 return;
54
55 if (on) {
56 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
57 POWER_TARGET_ON);
58 do {
59 pp_status = REG_READ(PP_STATUS);
60 } while ((pp_status & (PP_ON | PP_READY)) == PP_READY);
61 dev_priv->is_lvds_on = true;
62 if (dev_priv->ops->lvds_bl_power)
63 dev_priv->ops->lvds_bl_power(dev, true);
64 } else {
65 if (dev_priv->ops->lvds_bl_power)
66 dev_priv->ops->lvds_bl_power(dev, false);
67 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
68 ~POWER_TARGET_ON);
69 do {
70 pp_status = REG_READ(PP_STATUS);
71 } while (pp_status & PP_ON);
72 dev_priv->is_lvds_on = false;
73 pm_request_idle(&dev->pdev->dev);
74 }
75 gma_power_end(dev);
76}
77
78static void oaktrail_lvds_dpms(struct drm_encoder *encoder, int mode)
79{
80 struct drm_device *dev = encoder->dev;
81 struct psb_intel_encoder *psb_intel_encoder =
82 to_psb_intel_encoder(encoder);
83
84 if (mode == DRM_MODE_DPMS_ON)
85 oaktrail_lvds_set_power(dev, psb_intel_encoder, true);
86 else
87 oaktrail_lvds_set_power(dev, psb_intel_encoder, false);
88
89 /* XXX: We never power down the LVDS pairs. */
90}
91
92static void oaktrail_lvds_mode_set(struct drm_encoder *encoder,
93 struct drm_display_mode *mode,
94 struct drm_display_mode *adjusted_mode)
95{
96 struct drm_device *dev = encoder->dev;
97 struct drm_psb_private *dev_priv = dev->dev_private;
98 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
99 struct drm_mode_config *mode_config = &dev->mode_config;
100 struct drm_connector *connector = NULL;
101 struct drm_crtc *crtc = encoder->crtc;
102 u32 lvds_port;
103 uint64_t v = DRM_MODE_SCALE_FULLSCREEN;
104
105 if (!gma_power_begin(dev, true))
106 return;
107
108 /*
109 * The LVDS pin pair will already have been turned on in the
110 * psb_intel_crtc_mode_set since it has a large impact on the DPLL
111 * settings.
112 */
113 lvds_port = (REG_READ(LVDS) &
114 (~LVDS_PIPEB_SELECT)) |
115 LVDS_PORT_EN |
116 LVDS_BORDER_EN;
117
118 /* If the firmware says dither on Moorestown, or the BIOS does
119 on Oaktrail then enable dithering */
120 if (mode_dev->panel_wants_dither || dev_priv->lvds_dither)
121 lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE;
122
123 REG_WRITE(LVDS, lvds_port);
124
125 /* Find the connector we're trying to set up */
126 list_for_each_entry(connector, &mode_config->connector_list, head) {
127 if (!connector->encoder || connector->encoder->crtc != crtc)
128 continue;
129 }
130
131 if (!connector) {
132 DRM_ERROR("Couldn't find connector when setting mode");
133 return;
134 }
135
136 drm_connector_property_get_value(
137 connector,
138 dev->mode_config.scaling_mode_property,
139 &v);
140
141 if (v == DRM_MODE_SCALE_NO_SCALE)
142 REG_WRITE(PFIT_CONTROL, 0);
143 else if (v == DRM_MODE_SCALE_ASPECT) {
144 if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) ||
145 (mode->hdisplay != adjusted_mode->crtc_hdisplay)) {
146 if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) ==
147 (mode->hdisplay * adjusted_mode->crtc_vdisplay))
148 REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
149 else if ((adjusted_mode->crtc_hdisplay *
150 mode->vdisplay) > (mode->hdisplay *
151 adjusted_mode->crtc_vdisplay))
152 REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
153 PFIT_SCALING_MODE_PILLARBOX);
154 else
155 REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
156 PFIT_SCALING_MODE_LETTERBOX);
157 } else
158 REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
159 } else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/
160 REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
161
162 gma_power_end(dev);
163}
164
165static void oaktrail_lvds_prepare(struct drm_encoder *encoder)
166{
167 struct drm_device *dev = encoder->dev;
168 struct drm_psb_private *dev_priv = dev->dev_private;
169 struct psb_intel_encoder *psb_intel_encoder =
170 to_psb_intel_encoder(encoder);
171 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
172
173 if (!gma_power_begin(dev, true))
174 return;
175
176 mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
177 mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
178 BACKLIGHT_DUTY_CYCLE_MASK);
179 oaktrail_lvds_set_power(dev, psb_intel_encoder, false);
180 gma_power_end(dev);
181}
182
183static u32 oaktrail_lvds_get_max_backlight(struct drm_device *dev)
184{
185 struct drm_psb_private *dev_priv = dev->dev_private;
186 u32 ret;
187
188 if (gma_power_begin(dev, false)) {
189 ret = ((REG_READ(BLC_PWM_CTL) &
190 BACKLIGHT_MODULATION_FREQ_MASK) >>
191 BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
192
193 gma_power_end(dev);
194 } else
195 ret = ((dev_priv->saveBLC_PWM_CTL &
196 BACKLIGHT_MODULATION_FREQ_MASK) >>
197 BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
198
199 return ret;
200}
201
202static void oaktrail_lvds_commit(struct drm_encoder *encoder)
203{
204 struct drm_device *dev = encoder->dev;
205 struct drm_psb_private *dev_priv = dev->dev_private;
206 struct psb_intel_encoder *psb_intel_encoder =
207 to_psb_intel_encoder(encoder);
208 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
209
210 if (mode_dev->backlight_duty_cycle == 0)
211 mode_dev->backlight_duty_cycle =
212 oaktrail_lvds_get_max_backlight(dev);
213 oaktrail_lvds_set_power(dev, psb_intel_encoder, true);
214}
215
216static const struct drm_encoder_helper_funcs oaktrail_lvds_helper_funcs = {
217 .dpms = oaktrail_lvds_dpms,
218 .mode_fixup = psb_intel_lvds_mode_fixup,
219 .prepare = oaktrail_lvds_prepare,
220 .mode_set = oaktrail_lvds_mode_set,
221 .commit = oaktrail_lvds_commit,
222};
223
224static struct drm_display_mode lvds_configuration_modes[] = {
225 /* hard coded fixed mode for TPO LTPS LPJ040K001A */
226 { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 33264, 800, 836,
227 846, 1056, 0, 480, 489, 491, 525, 0, 0) },
228 /* hard coded fixed mode for LVDS 800x480 */
229 { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 30994, 800, 801,
230 802, 1024, 0, 480, 481, 482, 525, 0, 0) },
231 /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
232 { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1072,
233 1104, 1184, 0, 600, 603, 604, 608, 0, 0) },
234 /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
235 { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1104,
236 1136, 1184, 0, 600, 603, 604, 608, 0, 0) },
237 /* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */
238 { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 48885, 1024, 1124,
239 1204, 1312, 0, 600, 607, 610, 621, 0, 0) },
240 /* hard coded fixed mode for LVDS 1024x768 */
241 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
242 1184, 1344, 0, 768, 771, 777, 806, 0, 0) },
243 /* hard coded fixed mode for LVDS 1366x768 */
244 { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 77500, 1366, 1430,
245 1558, 1664, 0, 768, 769, 770, 776, 0, 0) },
246};
247
248/* Returns the panel fixed mode from configuration. */
249
250static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev,
251 struct psb_intel_mode_device *mode_dev)
252{
253 struct drm_display_mode *mode = NULL;
254 struct drm_psb_private *dev_priv = dev->dev_private;
255 struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD;
256
257 mode_dev->panel_fixed_mode = NULL;
258
259 /* Use the firmware provided data on Moorestown */
260 if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/
261 mode = kzalloc(sizeof(*mode), GFP_KERNEL);
262 if (!mode)
263 return;
264
265 mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
266 mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
267 mode->hsync_start = mode->hdisplay + \
268 ((ti->hsync_offset_hi << 8) | \
269 ti->hsync_offset_lo);
270 mode->hsync_end = mode->hsync_start + \
271 ((ti->hsync_pulse_width_hi << 8) | \
272 ti->hsync_pulse_width_lo);
273 mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
274 ti->hblank_lo);
275 mode->vsync_start = \
276 mode->vdisplay + ((ti->vsync_offset_hi << 4) | \
277 ti->vsync_offset_lo);
278 mode->vsync_end = \
279 mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \
280 ti->vsync_pulse_width_lo);
281 mode->vtotal = mode->vdisplay + \
282 ((ti->vblank_hi << 8) | ti->vblank_lo);
283 mode->clock = ti->pixel_clock * 10;
284#if 0
285 printk(KERN_INFO "hdisplay is %d\n", mode->hdisplay);
286 printk(KERN_INFO "vdisplay is %d\n", mode->vdisplay);
287 printk(KERN_INFO "HSS is %d\n", mode->hsync_start);
288 printk(KERN_INFO "HSE is %d\n", mode->hsync_end);
289 printk(KERN_INFO "htotal is %d\n", mode->htotal);
290 printk(KERN_INFO "VSS is %d\n", mode->vsync_start);
291 printk(KERN_INFO "VSE is %d\n", mode->vsync_end);
292 printk(KERN_INFO "vtotal is %d\n", mode->vtotal);
293 printk(KERN_INFO "clock is %d\n", mode->clock);
294#endif
295 mode_dev->panel_fixed_mode = mode;
296 }
297
298 /* Use the BIOS VBT mode if available */
299 if (mode_dev->panel_fixed_mode == NULL && mode_dev->vbt_mode)
300 mode_dev->panel_fixed_mode = drm_mode_duplicate(dev,
301 mode_dev->vbt_mode);
302
303 /* Then try the LVDS VBT mode */
304 if (mode_dev->panel_fixed_mode == NULL)
305 if (dev_priv->lfp_lvds_vbt_mode)
306 mode_dev->panel_fixed_mode =
307 drm_mode_duplicate(dev,
308 dev_priv->lfp_lvds_vbt_mode);
309 /* Then guess */
310 if (mode_dev->panel_fixed_mode == NULL)
311 mode_dev->panel_fixed_mode
312 = drm_mode_duplicate(dev, &lvds_configuration_modes[2]);
313
314 drm_mode_set_name(mode_dev->panel_fixed_mode);
315 drm_mode_set_crtcinfo(mode_dev->panel_fixed_mode, 0);
316}
317
318/**
319 * oaktrail_lvds_init - setup LVDS connectors on this device
320 * @dev: drm device
321 *
322 * Create the connector, register the LVDS DDC bus, and try to figure out what
323 * modes we can display on the LVDS panel (if present).
324 */
325void oaktrail_lvds_init(struct drm_device *dev,
326 struct psb_intel_mode_device *mode_dev)
327{
328 struct psb_intel_encoder *psb_intel_encoder;
329 struct psb_intel_connector *psb_intel_connector;
330 struct drm_connector *connector;
331 struct drm_encoder *encoder;
332 struct drm_psb_private *dev_priv = dev->dev_private;
333 struct edid *edid;
334 int ret = 0;
335 struct i2c_adapter *i2c_adap;
336 struct drm_display_mode *scan; /* *modes, *bios_mode; */
337
338 psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL);
339 if (!psb_intel_encoder)
340 return;
341
342 psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL);
343 if (!psb_intel_connector)
344 goto failed_connector;
345
346 connector = &psb_intel_connector->base;
347 encoder = &psb_intel_encoder->base;
348 dev_priv->is_lvds_on = true;
349 drm_connector_init(dev, connector,
350 &psb_intel_lvds_connector_funcs,
351 DRM_MODE_CONNECTOR_LVDS);
352
353 drm_encoder_init(dev, encoder, &psb_intel_lvds_enc_funcs,
354 DRM_MODE_ENCODER_LVDS);
355
356 psb_intel_connector_attach_encoder(psb_intel_connector,
357 psb_intel_encoder);
358 psb_intel_encoder->type = INTEL_OUTPUT_LVDS;
359
360 drm_encoder_helper_add(encoder, &oaktrail_lvds_helper_funcs);
361 drm_connector_helper_add(connector,
362 &psb_intel_lvds_connector_helper_funcs);
363 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
364 connector->interlace_allowed = false;
365 connector->doublescan_allowed = false;
366
367 drm_connector_attach_property(connector,
368 dev->mode_config.scaling_mode_property,
369 DRM_MODE_SCALE_FULLSCREEN);
370 drm_connector_attach_property(connector,
371 dev_priv->backlight_property,
372 BRIGHTNESS_MAX_LEVEL);
373
374 mode_dev->panel_wants_dither = false;
375 if (dev_priv->vbt_data.size != 0x00)
376 mode_dev->panel_wants_dither = (dev_priv->gct_data.
377 Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE);
378 if (dev_priv->lvds_dither)
379 mode_dev->panel_wants_dither = 1;
380
381 /*
382 * LVDS discovery:
383 * 1) check for EDID on DDC
384 * 2) check for VBT data
385 * 3) check to see if LVDS is already on
386 * if none of the above, no panel
387 * 4) make sure lid is open
388 * if closed, act like it's not there for now
389 */
390
391 i2c_adap = i2c_get_adapter(dev_priv->ops->i2c_bus);
392 if (i2c_adap == NULL)
393 dev_err(dev->dev, "No ddc adapter available!\n");
394 /*
395 * Attempt to get the fixed panel mode from DDC. Assume that the
396 * preferred mode is the right one.
397 */
398 if (i2c_adap) {
399 edid = drm_get_edid(connector, i2c_adap);
400 if (edid) {
401 drm_mode_connector_update_edid_property(connector,
402 edid);
403 ret = drm_add_edid_modes(connector, edid);
404 kfree(edid);
405 }
406
407 list_for_each_entry(scan, &connector->probed_modes, head) {
408 if (scan->type & DRM_MODE_TYPE_PREFERRED) {
409 mode_dev->panel_fixed_mode =
410 drm_mode_duplicate(dev, scan);
411 goto out; /* FIXME: check for quirks */
412 }
413 }
414 }
415 /*
416 * If we didn't get EDID, try geting panel timing
417 * from configuration data
418 */
419 oaktrail_lvds_get_configuration_mode(dev, mode_dev);
420
421 if (mode_dev->panel_fixed_mode) {
422 mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
423 goto out; /* FIXME: check for quirks */
424 }
425
426 /* If we still don't have a mode after all that, give up. */
427 if (!mode_dev->panel_fixed_mode) {
428 dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n");
429 goto failed_find;
430 }
431
432out:
433 drm_sysfs_connector_add(connector);
434 return;
435
436failed_find:
437 dev_dbg(dev->dev, "No LVDS modes found, disabling.\n");
438 if (psb_intel_encoder->ddc_bus)
439 psb_intel_i2c_destroy(psb_intel_encoder->ddc_bus);
440
441/* failed_ddc: */
442
443 drm_encoder_cleanup(encoder);
444 drm_connector_cleanup(connector);
445 kfree(psb_intel_connector);
446failed_connector:
447 kfree(psb_intel_encoder);
448}
449
diff --git a/drivers/gpu/drm/gma500/power.c b/drivers/gpu/drm/gma500/power.c
new file mode 100644
index 00000000000..94025693bae
--- /dev/null
+++ b/drivers/gpu/drm/gma500/power.c
@@ -0,0 +1,316 @@
1/**************************************************************************
2 * Copyright (c) 2009-2011, Intel Corporation.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 * Authors:
25 * Benjamin Defnet <benjamin.r.defnet@intel.com>
26 * Rajesh Poornachandran <rajesh.poornachandran@intel.com>
27 * Massively reworked
28 * Alan Cox <alan@linux.intel.com>
29 */
30
31#include "power.h"
32#include "psb_drv.h"
33#include "psb_reg.h"
34#include "psb_intel_reg.h"
35#include <linux/mutex.h>
36#include <linux/pm_runtime.h>
37
38static struct mutex power_mutex; /* Serialize power ops */
39static spinlock_t power_ctrl_lock; /* Serialize power claim */
40
41/**
42 * gma_power_init - initialise power manager
43 * @dev: our device
44 *
45 * Set up for power management tracking of our hardware.
46 */
47void gma_power_init(struct drm_device *dev)
48{
49 struct drm_psb_private *dev_priv = dev->dev_private;
50
51 /* FIXME: Move APM/OSPM base into relevant device code */
52 dev_priv->apm_base = dev_priv->apm_reg & 0xffff;
53 dev_priv->ospm_base &= 0xffff;
54
55 dev_priv->display_power = true; /* We start active */
56 dev_priv->display_count = 0; /* Currently no users */
57 dev_priv->suspended = false; /* And not suspended */
58 spin_lock_init(&power_ctrl_lock);
59 mutex_init(&power_mutex);
60
61 dev_priv->ops->init_pm(dev);
62}
63
64/**
65 * gma_power_uninit - end power manager
66 * @dev: device to end for
67 *
68 * Undo the effects of gma_power_init
69 */
70void gma_power_uninit(struct drm_device *dev)
71{
72 pm_runtime_disable(&dev->pdev->dev);
73 pm_runtime_set_suspended(&dev->pdev->dev);
74}
75
76/**
77 * gma_suspend_display - suspend the display logic
78 * @dev: our DRM device
79 *
80 * Suspend the display logic of the graphics interface
81 */
82static void gma_suspend_display(struct drm_device *dev)
83{
84 struct drm_psb_private *dev_priv = dev->dev_private;
85
86 if (dev_priv->suspended)
87 return;
88 dev_priv->ops->save_regs(dev);
89 dev_priv->ops->power_down(dev);
90 dev_priv->display_power = false;
91}
92
93/**
94 * gma_resume_display - resume display side logic
95 *
96 * Resume the display hardware restoring state and enabling
97 * as necessary.
98 */
99static void gma_resume_display(struct pci_dev *pdev)
100{
101 struct drm_device *dev = pci_get_drvdata(pdev);
102 struct drm_psb_private *dev_priv = dev->dev_private;
103
104 if (dev_priv->suspended == false)
105 return;
106
107 /* turn on the display power island */
108 dev_priv->ops->power_up(dev);
109 dev_priv->suspended = false;
110 dev_priv->display_power = true;
111
112 PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
113 pci_write_config_word(pdev, PSB_GMCH_CTRL,
114 dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
115 dev_priv->ops->restore_regs(dev);
116}
117
118/**
119 * gma_suspend_pci - suspend PCI side
120 * @pdev: PCI device
121 *
122 * Perform the suspend processing on our PCI device state
123 */
124static void gma_suspend_pci(struct pci_dev *pdev)
125{
126 struct drm_device *dev = pci_get_drvdata(pdev);
127 struct drm_psb_private *dev_priv = dev->dev_private;
128 int bsm, vbt;
129
130 if (dev_priv->suspended)
131 return;
132
133 pci_save_state(pdev);
134 pci_read_config_dword(pdev, 0x5C, &bsm);
135 dev_priv->saveBSM = bsm;
136 pci_read_config_dword(pdev, 0xFC, &vbt);
137 dev_priv->saveVBT = vbt;
138 pci_read_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, &dev_priv->msi_addr);
139 pci_read_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, &dev_priv->msi_data);
140
141 pci_disable_device(pdev);
142 pci_set_power_state(pdev, PCI_D3hot);
143
144 dev_priv->suspended = true;
145}
146
147/**
148 * gma_resume_pci - resume helper
149 * @dev: our PCI device
150 *
151 * Perform the resume processing on our PCI device state - rewrite
152 * register state and re-enable the PCI device
153 */
154static bool gma_resume_pci(struct pci_dev *pdev)
155{
156 struct drm_device *dev = pci_get_drvdata(pdev);
157 struct drm_psb_private *dev_priv = dev->dev_private;
158 int ret;
159
160 if (!dev_priv->suspended)
161 return true;
162
163 pci_set_power_state(pdev, PCI_D0);
164 pci_restore_state(pdev);
165 pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM);
166 pci_write_config_dword(pdev, 0xFC, dev_priv->saveVBT);
167 /* restoring MSI address and data in PCIx space */
168 pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr);
169 pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data);
170 ret = pci_enable_device(pdev);
171
172 if (ret != 0)
173 dev_err(&pdev->dev, "pci_enable failed: %d\n", ret);
174 else
175 dev_priv->suspended = false;
176 return !dev_priv->suspended;
177}
178
179/**
180 * gma_power_suspend - bus callback for suspend
181 * @pdev: our PCI device
182 * @state: suspend type
183 *
184 * Called back by the PCI layer during a suspend of the system. We
185 * perform the necessary shut down steps and save enough state that
186 * we can undo this when resume is called.
187 */
188int gma_power_suspend(struct device *_dev)
189{
190 struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev);
191 struct drm_device *dev = pci_get_drvdata(pdev);
192 struct drm_psb_private *dev_priv = dev->dev_private;
193
194 mutex_lock(&power_mutex);
195 if (!dev_priv->suspended) {
196 if (dev_priv->display_count) {
197 mutex_unlock(&power_mutex);
198 return -EBUSY;
199 }
200 psb_irq_uninstall(dev);
201 gma_suspend_display(dev);
202 gma_suspend_pci(pdev);
203 }
204 mutex_unlock(&power_mutex);
205 return 0;
206}
207
208/**
209 * gma_power_resume - resume power
210 * @pdev: PCI device
211 *
212 * Resume the PCI side of the graphics and then the displays
213 */
214int gma_power_resume(struct device *_dev)
215{
216 struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev);
217 struct drm_device *dev = pci_get_drvdata(pdev);
218
219 mutex_lock(&power_mutex);
220 gma_resume_pci(pdev);
221 gma_resume_display(pdev);
222 psb_irq_preinstall(dev);
223 psb_irq_postinstall(dev);
224 mutex_unlock(&power_mutex);
225 return 0;
226}
227
228/**
229 * gma_power_is_on - returne true if power is on
230 * @dev: our DRM device
231 *
232 * Returns true if the display island power is on at this moment
233 */
234bool gma_power_is_on(struct drm_device *dev)
235{
236 struct drm_psb_private *dev_priv = dev->dev_private;
237 return dev_priv->display_power;
238}
239
240/**
241 * gma_power_begin - begin requiring power
242 * @dev: our DRM device
243 * @force_on: true to force power on
244 *
245 * Begin an action that requires the display power island is enabled.
246 * We refcount the islands.
247 */
248bool gma_power_begin(struct drm_device *dev, bool force_on)
249{
250 struct drm_psb_private *dev_priv = dev->dev_private;
251 int ret;
252 unsigned long flags;
253
254 spin_lock_irqsave(&power_ctrl_lock, flags);
255 /* Power already on ? */
256 if (dev_priv->display_power) {
257 dev_priv->display_count++;
258 pm_runtime_get(&dev->pdev->dev);
259 spin_unlock_irqrestore(&power_ctrl_lock, flags);
260 return true;
261 }
262 if (force_on == false)
263 goto out_false;
264
265 /* Ok power up needed */
266 ret = gma_resume_pci(dev->pdev);
267 if (ret == 0) {
268 psb_irq_preinstall(dev);
269 psb_irq_postinstall(dev);
270 pm_runtime_get(&dev->pdev->dev);
271 dev_priv->display_count++;
272 spin_unlock_irqrestore(&power_ctrl_lock, flags);
273 return true;
274 }
275out_false:
276 spin_unlock_irqrestore(&power_ctrl_lock, flags);
277 return false;
278}
279
280/**
281 * gma_power_end - end use of power
282 * @dev: Our DRM device
283 *
284 * Indicate that one of our gma_power_begin() requested periods when
285 * the diplay island power is needed has completed.
286 */
287void gma_power_end(struct drm_device *dev)
288{
289 struct drm_psb_private *dev_priv = dev->dev_private;
290 unsigned long flags;
291 spin_lock_irqsave(&power_ctrl_lock, flags);
292 dev_priv->display_count--;
293 WARN_ON(dev_priv->display_count < 0);
294 spin_unlock_irqrestore(&power_ctrl_lock, flags);
295 pm_runtime_put(&dev->pdev->dev);
296}
297
298int psb_runtime_suspend(struct device *dev)
299{
300 return gma_power_suspend(dev);
301}
302
303int psb_runtime_resume(struct device *dev)
304{
305 return gma_power_resume(dev);;
306}
307
308int psb_runtime_idle(struct device *dev)
309{
310 struct drm_device *drmdev = pci_get_drvdata(to_pci_dev(dev));
311 struct drm_psb_private *dev_priv = drmdev->dev_private;
312 if (dev_priv->display_count)
313 return 0;
314 else
315 return 1;
316}
diff --git a/drivers/gpu/drm/gma500/power.h b/drivers/gpu/drm/gma500/power.h
new file mode 100644
index 00000000000..1969d2ecb32
--- /dev/null
+++ b/drivers/gpu/drm/gma500/power.h
@@ -0,0 +1,67 @@
1/**************************************************************************
2 * Copyright (c) 2009-2011, Intel Corporation.
3 * All Rights Reserved.
4
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 * Authors:
25 * Benjamin Defnet <benjamin.r.defnet@intel.com>
26 * Rajesh Poornachandran <rajesh.poornachandran@intel.com>
27 * Massively reworked
28 * Alan Cox <alan@linux.intel.com>
29 */
30#ifndef _PSB_POWERMGMT_H_
31#define _PSB_POWERMGMT_H_
32
33#include <linux/pci.h>
34#include <drm/drmP.h>
35
36void gma_power_init(struct drm_device *dev);
37void gma_power_uninit(struct drm_device *dev);
38
39/*
40 * The kernel bus power management will call these functions
41 */
42int gma_power_suspend(struct device *dev);
43int gma_power_resume(struct device *dev);
44
45/*
46 * These are the functions the driver should use to wrap all hw access
47 * (i.e. register reads and writes)
48 */
49bool gma_power_begin(struct drm_device *dev, bool force);
50void gma_power_end(struct drm_device *dev);
51
52/*
53 * Use this function to do an instantaneous check for if the hw is on.
54 * Only use this in cases where you know the mutex is already held such
55 * as in irq install/uninstall and you need to
56 * prevent a deadlock situation. Otherwise use gma_power_begin().
57 */
58bool gma_power_is_on(struct drm_device *dev);
59
60/*
61 * GFX-Runtime PM callbacks
62 */
63int psb_runtime_suspend(struct device *dev);
64int psb_runtime_resume(struct device *dev);
65int psb_runtime_idle(struct device *dev);
66
67#endif /*_PSB_POWERMGMT_H_*/
diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c
new file mode 100644
index 00000000000..e5f5906172b
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_device.c
@@ -0,0 +1,328 @@
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 <drm/drmP.h>
22#include <drm/drm.h>
23#include "gma_drm.h"
24#include "psb_drv.h"
25#include "psb_reg.h"
26#include "psb_intel_reg.h"
27#include "intel_bios.h"
28
29
30static int psb_output_init(struct drm_device *dev)
31{
32 struct drm_psb_private *dev_priv = dev->dev_private;
33 psb_intel_lvds_init(dev, &dev_priv->mode_dev);
34 psb_intel_sdvo_init(dev, SDVOB);
35 return 0;
36}
37
38#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
39
40/*
41 * Poulsbo Backlight Interfaces
42 */
43
44#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
45#define BLC_PWM_FREQ_CALC_CONSTANT 32
46#define MHz 1000000
47
48#define PSB_BLC_PWM_PRECISION_FACTOR 10
49#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE
50#define PSB_BLC_MIN_PWM_REG_FREQ 0x2
51
52#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
53#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16)
54
55static int psb_brightness;
56static struct backlight_device *psb_backlight_device;
57
58static int psb_get_brightness(struct backlight_device *bd)
59{
60 /* return locally cached var instead of HW read (due to DPST etc.) */
61 /* FIXME: ideally return actual value in case firmware fiddled with
62 it */
63 return psb_brightness;
64}
65
66
67static int psb_backlight_setup(struct drm_device *dev)
68{
69 struct drm_psb_private *dev_priv = dev->dev_private;
70 unsigned long core_clock;
71 /* u32 bl_max_freq; */
72 /* unsigned long value; */
73 u16 bl_max_freq;
74 uint32_t value;
75 uint32_t blc_pwm_precision_factor;
76
77 /* get bl_max_freq and pol from dev_priv*/
78 if (!dev_priv->lvds_bl) {
79 dev_err(dev->dev, "Has no valid LVDS backlight info\n");
80 return -ENOENT;
81 }
82 bl_max_freq = dev_priv->lvds_bl->freq;
83 blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
84
85 core_clock = dev_priv->core_freq;
86
87 value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
88 value *= blc_pwm_precision_factor;
89 value /= bl_max_freq;
90 value /= blc_pwm_precision_factor;
91
92 if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
93 value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
94 return -ERANGE;
95 else {
96 value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
97 REG_WRITE(BLC_PWM_CTL,
98 (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | (value));
99 }
100 return 0;
101}
102
103static int psb_set_brightness(struct backlight_device *bd)
104{
105 struct drm_device *dev = bl_get_data(psb_backlight_device);
106 int level = bd->props.brightness;
107
108 /* Percentage 1-100% being valid */
109 if (level < 1)
110 level = 1;
111
112 psb_intel_lvds_set_brightness(dev, level);
113 psb_brightness = level;
114 return 0;
115}
116
117static const struct backlight_ops psb_ops = {
118 .get_brightness = psb_get_brightness,
119 .update_status = psb_set_brightness,
120};
121
122static int psb_backlight_init(struct drm_device *dev)
123{
124 struct drm_psb_private *dev_priv = dev->dev_private;
125 int ret;
126 struct backlight_properties props;
127
128 memset(&props, 0, sizeof(struct backlight_properties));
129 props.max_brightness = 100;
130 props.type = BACKLIGHT_PLATFORM;
131
132 psb_backlight_device = backlight_device_register("psb-bl",
133 NULL, (void *)dev, &psb_ops, &props);
134 if (IS_ERR(psb_backlight_device))
135 return PTR_ERR(psb_backlight_device);
136
137 ret = psb_backlight_setup(dev);
138 if (ret < 0) {
139 backlight_device_unregister(psb_backlight_device);
140 psb_backlight_device = NULL;
141 return ret;
142 }
143 psb_backlight_device->props.brightness = 100;
144 psb_backlight_device->props.max_brightness = 100;
145 backlight_update_status(psb_backlight_device);
146 dev_priv->backlight_device = psb_backlight_device;
147 return 0;
148}
149
150#endif
151
152/*
153 * Provide the Poulsbo specific chip logic and low level methods
154 * for power management
155 */
156
157static void psb_init_pm(struct drm_device *dev)
158{
159 struct drm_psb_private *dev_priv = dev->dev_private;
160
161 u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL);
162 gating &= ~3; /* Disable 2D clock gating */
163 gating |= 1;
164 PSB_WSGX32(gating, PSB_CR_CLKGATECTL);
165 PSB_RSGX32(PSB_CR_CLKGATECTL);
166}
167
168/**
169 * psb_save_display_registers - save registers lost on suspend
170 * @dev: our DRM device
171 *
172 * Save the state we need in order to be able to restore the interface
173 * upon resume from suspend
174 */
175static int psb_save_display_registers(struct drm_device *dev)
176{
177 struct drm_psb_private *dev_priv = dev->dev_private;
178 struct drm_crtc *crtc;
179 struct drm_connector *connector;
180
181 /* Display arbitration control + watermarks */
182 dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
183 dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1);
184 dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2);
185 dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3);
186 dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4);
187 dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5);
188 dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
189 dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
190
191 /* Save crtc and output state */
192 mutex_lock(&dev->mode_config.mutex);
193 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
194 if (drm_helper_crtc_in_use(crtc))
195 crtc->funcs->save(crtc);
196 }
197
198 list_for_each_entry(connector, &dev->mode_config.connector_list, head)
199 connector->funcs->save(connector);
200
201 mutex_unlock(&dev->mode_config.mutex);
202 return 0;
203}
204
205/**
206 * psb_restore_display_registers - restore lost register state
207 * @dev: our DRM device
208 *
209 * Restore register state that was lost during suspend and resume.
210 */
211static int psb_restore_display_registers(struct drm_device *dev)
212{
213 struct drm_psb_private *dev_priv = dev->dev_private;
214 struct drm_crtc *crtc;
215 struct drm_connector *connector;
216
217 /* Display arbitration + watermarks */
218 PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
219 PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1);
220 PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2);
221 PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3);
222 PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4);
223 PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5);
224 PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6);
225 PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT);
226
227 /*make sure VGA plane is off. it initializes to on after reset!*/
228 PSB_WVDC32(0x80000000, VGACNTRL);
229
230 mutex_lock(&dev->mode_config.mutex);
231 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
232 if (drm_helper_crtc_in_use(crtc))
233 crtc->funcs->restore(crtc);
234
235 list_for_each_entry(connector, &dev->mode_config.connector_list, head)
236 connector->funcs->restore(connector);
237
238 mutex_unlock(&dev->mode_config.mutex);
239 return 0;
240}
241
242static int psb_power_down(struct drm_device *dev)
243{
244 return 0;
245}
246
247static int psb_power_up(struct drm_device *dev)
248{
249 return 0;
250}
251
252static void psb_get_core_freq(struct drm_device *dev)
253{
254 uint32_t clock;
255 struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
256 struct drm_psb_private *dev_priv = dev->dev_private;
257
258 /*pci_write_config_dword(pci_root, 0xD4, 0x00C32004);*/
259 /*pci_write_config_dword(pci_root, 0xD0, 0xE0033000);*/
260
261 pci_write_config_dword(pci_root, 0xD0, 0xD0050300);
262 pci_read_config_dword(pci_root, 0xD4, &clock);
263 pci_dev_put(pci_root);
264
265 switch (clock & 0x07) {
266 case 0:
267 dev_priv->core_freq = 100;
268 break;
269 case 1:
270 dev_priv->core_freq = 133;
271 break;
272 case 2:
273 dev_priv->core_freq = 150;
274 break;
275 case 3:
276 dev_priv->core_freq = 178;
277 break;
278 case 4:
279 dev_priv->core_freq = 200;
280 break;
281 case 5:
282 case 6:
283 case 7:
284 dev_priv->core_freq = 266;
285 default:
286 dev_priv->core_freq = 0;
287 }
288}
289
290static int psb_chip_setup(struct drm_device *dev)
291{
292 psb_get_core_freq(dev);
293 gma_intel_setup_gmbus(dev);
294 gma_intel_opregion_init(dev);
295 psb_intel_init_bios(dev);
296 return 0;
297}
298
299static void psb_chip_teardown(struct drm_device *dev)
300{
301 gma_intel_teardown_gmbus(dev);
302}
303
304const struct psb_ops psb_chip_ops = {
305 .name = "Poulsbo",
306 .accel_2d = 1,
307 .pipes = 2,
308 .crtcs = 2,
309 .sgx_offset = PSB_SGX_OFFSET,
310 .chip_setup = psb_chip_setup,
311 .chip_teardown = psb_chip_teardown,
312
313 .crtc_helper = &psb_intel_helper_funcs,
314 .crtc_funcs = &psb_intel_crtc_funcs,
315
316 .output_init = psb_output_init,
317
318#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
319 .backlight_init = psb_backlight_init,
320#endif
321
322 .init_pm = psb_init_pm,
323 .save_regs = psb_save_display_registers,
324 .restore_regs = psb_restore_display_registers,
325 .power_down = psb_power_down,
326 .power_up = psb_power_up,
327};
328
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
new file mode 100644
index 00000000000..f14768f2b36
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -0,0 +1,703 @@
1/**************************************************************************
2 * Copyright (c) 2007-2011, Intel Corporation.
3 * All Rights Reserved.
4 * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX., USA.
5 * All Rights Reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 **************************************************************************/
21
22#include <drm/drmP.h>
23#include <drm/drm.h>
24#include "gma_drm.h"
25#include "psb_drv.h"
26#include "framebuffer.h"
27#include "psb_reg.h"
28#include "psb_intel_reg.h"
29#include "intel_bios.h"
30#include "mid_bios.h"
31#include <drm/drm_pciids.h>
32#include "power.h"
33#include <linux/cpu.h>
34#include <linux/notifier.h>
35#include <linux/spinlock.h>
36#include <linux/pm_runtime.h>
37#include <acpi/video.h>
38#include <linux/module.h>
39
40static int drm_psb_trap_pagefaults;
41
42static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
43
44MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults");
45module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600);
46
47
48static DEFINE_PCI_DEVICE_TABLE(pciidlist) = {
49 { 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops },
50 { 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops },
51#if defined(CONFIG_DRM_GMA600)
52 { 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
53 { 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
54 { 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
55 { 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
56 { 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
57 { 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
58 { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
59 { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
60 /* Atom E620 */
61 { 0x8086, 0x4108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops},
62#endif
63#if defined(CONFIG_DRM_GMA3600)
64 { 0x8086, 0x0be0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
65 { 0x8086, 0x0be1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
66 { 0x8086, 0x0be2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
67 { 0x8086, 0x0be3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
68 { 0x8086, 0x0be4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
69 { 0x8086, 0x0be5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
70 { 0x8086, 0x0be6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
71 { 0x8086, 0x0be7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
72#endif
73 { 0, 0, 0}
74};
75MODULE_DEVICE_TABLE(pci, pciidlist);
76
77/*
78 * Standard IOCTLs.
79 */
80
81#define DRM_IOCTL_PSB_ADB \
82 DRM_IOWR(DRM_GMA_ADB + DRM_COMMAND_BASE, uint32_t)
83#define DRM_IOCTL_PSB_MODE_OPERATION \
84 DRM_IOWR(DRM_GMA_MODE_OPERATION + DRM_COMMAND_BASE, \
85 struct drm_psb_mode_operation_arg)
86#define DRM_IOCTL_PSB_STOLEN_MEMORY \
87 DRM_IOWR(DRM_GMA_STOLEN_MEMORY + DRM_COMMAND_BASE, \
88 struct drm_psb_stolen_memory_arg)
89#define DRM_IOCTL_PSB_GAMMA \
90 DRM_IOWR(DRM_GMA_GAMMA + DRM_COMMAND_BASE, \
91 struct drm_psb_dpst_lut_arg)
92#define DRM_IOCTL_PSB_DPST_BL \
93 DRM_IOWR(DRM_GMA_DPST_BL + DRM_COMMAND_BASE, \
94 uint32_t)
95#define DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID \
96 DRM_IOWR(DRM_GMA_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \
97 struct drm_psb_get_pipe_from_crtc_id_arg)
98#define DRM_IOCTL_PSB_GEM_CREATE \
99 DRM_IOWR(DRM_GMA_GEM_CREATE + DRM_COMMAND_BASE, \
100 struct drm_psb_gem_create)
101#define DRM_IOCTL_PSB_GEM_MMAP \
102 DRM_IOWR(DRM_GMA_GEM_MMAP + DRM_COMMAND_BASE, \
103 struct drm_psb_gem_mmap)
104
105static int psb_adb_ioctl(struct drm_device *dev, void *data,
106 struct drm_file *file_priv);
107static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
108 struct drm_file *file_priv);
109static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
110 struct drm_file *file_priv);
111static int psb_gamma_ioctl(struct drm_device *dev, void *data,
112 struct drm_file *file_priv);
113static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
114 struct drm_file *file_priv);
115
116#define PSB_IOCTL_DEF(ioctl, func, flags) \
117 [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func}
118
119static struct drm_ioctl_desc psb_ioctls[] = {
120 PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH),
121 PSB_IOCTL_DEF(DRM_IOCTL_PSB_MODE_OPERATION, psb_mode_operation_ioctl,
122 DRM_AUTH),
123 PSB_IOCTL_DEF(DRM_IOCTL_PSB_STOLEN_MEMORY, psb_stolen_memory_ioctl,
124 DRM_AUTH),
125 PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH),
126 PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH),
127 PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID,
128 psb_intel_get_pipe_from_crtc_id, 0),
129 PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_CREATE, psb_gem_create_ioctl,
130 DRM_UNLOCKED | DRM_AUTH),
131 PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_MMAP, psb_gem_mmap_ioctl,
132 DRM_UNLOCKED | DRM_AUTH),
133};
134
135static void psb_lastclose(struct drm_device *dev)
136{
137 return;
138}
139
140static void psb_do_takedown(struct drm_device *dev)
141{
142}
143
144static int psb_do_init(struct drm_device *dev)
145{
146 struct drm_psb_private *dev_priv = dev->dev_private;
147 struct psb_gtt *pg = &dev_priv->gtt;
148
149 uint32_t stolen_gtt;
150
151 int ret = -ENOMEM;
152
153 if (pg->mmu_gatt_start & 0x0FFFFFFF) {
154 dev_err(dev->dev, "Gatt must be 256M aligned. This is a bug.\n");
155 ret = -EINVAL;
156 goto out_err;
157 }
158
159
160 stolen_gtt = (pg->stolen_size >> PAGE_SHIFT) * 4;
161 stolen_gtt = (stolen_gtt + PAGE_SIZE - 1) >> PAGE_SHIFT;
162 stolen_gtt =
163 (stolen_gtt < pg->gtt_pages) ? stolen_gtt : pg->gtt_pages;
164
165 dev_priv->gatt_free_offset = pg->mmu_gatt_start +
166 (stolen_gtt << PAGE_SHIFT) * 1024;
167
168 if (1 || drm_debug) {
169 uint32_t core_id = PSB_RSGX32(PSB_CR_CORE_ID);
170 uint32_t core_rev = PSB_RSGX32(PSB_CR_CORE_REVISION);
171 DRM_INFO("SGX core id = 0x%08x\n", core_id);
172 DRM_INFO("SGX core rev major = 0x%02x, minor = 0x%02x\n",
173 (core_rev & _PSB_CC_REVISION_MAJOR_MASK) >>
174 _PSB_CC_REVISION_MAJOR_SHIFT,
175 (core_rev & _PSB_CC_REVISION_MINOR_MASK) >>
176 _PSB_CC_REVISION_MINOR_SHIFT);
177 DRM_INFO
178 ("SGX core rev maintenance = 0x%02x, designer = 0x%02x\n",
179 (core_rev & _PSB_CC_REVISION_MAINTENANCE_MASK) >>
180 _PSB_CC_REVISION_MAINTENANCE_SHIFT,
181 (core_rev & _PSB_CC_REVISION_DESIGNER_MASK) >>
182 _PSB_CC_REVISION_DESIGNER_SHIFT);
183 }
184
185
186 spin_lock_init(&dev_priv->irqmask_lock);
187 spin_lock_init(&dev_priv->lock_2d);
188
189 PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
190 PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1);
191 PSB_RSGX32(PSB_CR_BIF_BANK1);
192 PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK,
193 PSB_CR_BIF_CTRL);
194 psb_spank(dev_priv);
195
196 /* mmu_gatt ?? */
197 PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
198 return 0;
199out_err:
200 psb_do_takedown(dev);
201 return ret;
202}
203
204static int psb_driver_unload(struct drm_device *dev)
205{
206 struct drm_psb_private *dev_priv = dev->dev_private;
207
208 /* Kill vblank etc here */
209
210 gma_backlight_exit(dev);
211
212 psb_modeset_cleanup(dev);
213
214 if (dev_priv) {
215 psb_lid_timer_takedown(dev_priv);
216 gma_intel_opregion_exit(dev);
217
218 if (dev_priv->ops->chip_teardown)
219 dev_priv->ops->chip_teardown(dev);
220 psb_do_takedown(dev);
221
222
223 if (dev_priv->pf_pd) {
224 psb_mmu_free_pagedir(dev_priv->pf_pd);
225 dev_priv->pf_pd = NULL;
226 }
227 if (dev_priv->mmu) {
228 struct psb_gtt *pg = &dev_priv->gtt;
229
230 down_read(&pg->sem);
231 psb_mmu_remove_pfn_sequence(
232 psb_mmu_get_default_pd
233 (dev_priv->mmu),
234 pg->mmu_gatt_start,
235 dev_priv->vram_stolen_size >> PAGE_SHIFT);
236 up_read(&pg->sem);
237 psb_mmu_driver_takedown(dev_priv->mmu);
238 dev_priv->mmu = NULL;
239 }
240 psb_gtt_takedown(dev);
241 if (dev_priv->scratch_page) {
242 __free_page(dev_priv->scratch_page);
243 dev_priv->scratch_page = NULL;
244 }
245 if (dev_priv->vdc_reg) {
246 iounmap(dev_priv->vdc_reg);
247 dev_priv->vdc_reg = NULL;
248 }
249 if (dev_priv->sgx_reg) {
250 iounmap(dev_priv->sgx_reg);
251 dev_priv->sgx_reg = NULL;
252 }
253
254 kfree(dev_priv);
255 dev->dev_private = NULL;
256
257 /*destroy VBT data*/
258 psb_intel_destroy_bios(dev);
259 }
260
261 gma_power_uninit(dev);
262
263 return 0;
264}
265
266
267static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
268{
269 struct drm_psb_private *dev_priv;
270 unsigned long resource_start;
271 struct psb_gtt *pg;
272 unsigned long irqflags;
273 int ret = -ENOMEM;
274 uint32_t tt_pages;
275 struct drm_connector *connector;
276 struct psb_intel_encoder *psb_intel_encoder;
277
278 dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
279 if (dev_priv == NULL)
280 return -ENOMEM;
281
282 dev_priv->ops = (struct psb_ops *)chipset;
283 dev_priv->dev = dev;
284 dev->dev_private = (void *) dev_priv;
285
286 if (!IS_PSB(dev)) {
287 if (pci_enable_msi(dev->pdev))
288 dev_warn(dev->dev, "Enabling MSI failed!\n");
289 }
290
291 dev_priv->num_pipe = dev_priv->ops->pipes;
292
293 resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE);
294
295 dev_priv->vdc_reg =
296 ioremap(resource_start + PSB_VDC_OFFSET, PSB_VDC_SIZE);
297 if (!dev_priv->vdc_reg)
298 goto out_err;
299
300 dev_priv->sgx_reg = ioremap(resource_start + dev_priv->ops->sgx_offset,
301 PSB_SGX_SIZE);
302 if (!dev_priv->sgx_reg)
303 goto out_err;
304
305 ret = dev_priv->ops->chip_setup(dev);
306 if (ret)
307 goto out_err;
308
309 /* Init OSPM support */
310 gma_power_init(dev);
311
312 ret = -ENOMEM;
313
314 dev_priv->scratch_page = alloc_page(GFP_DMA32 | __GFP_ZERO);
315 if (!dev_priv->scratch_page)
316 goto out_err;
317
318 set_pages_uc(dev_priv->scratch_page, 1);
319
320 ret = psb_gtt_init(dev, 0);
321 if (ret)
322 goto out_err;
323
324 dev_priv->mmu = psb_mmu_driver_init((void *)0,
325 drm_psb_trap_pagefaults, 0,
326 dev_priv);
327 if (!dev_priv->mmu)
328 goto out_err;
329
330 pg = &dev_priv->gtt;
331
332 tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
333 (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
334
335
336 dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0);
337 if (!dev_priv->pf_pd)
338 goto out_err;
339
340 psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0);
341 psb_mmu_set_pd_context(dev_priv->pf_pd, 1);
342
343 ret = psb_do_init(dev);
344 if (ret)
345 return ret;
346
347 PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE);
348 PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE);
349
350/* igd_opregion_init(&dev_priv->opregion_dev); */
351 acpi_video_register();
352 if (dev_priv->lid_state)
353 psb_lid_timer_init(dev_priv);
354
355 ret = drm_vblank_init(dev, dev_priv->num_pipe);
356 if (ret)
357 goto out_err;
358
359 /*
360 * Install interrupt handlers prior to powering off SGX or else we will
361 * crash.
362 */
363 dev_priv->vdc_irq_mask = 0;
364 dev_priv->pipestat[0] = 0;
365 dev_priv->pipestat[1] = 0;
366 dev_priv->pipestat[2] = 0;
367 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
368 PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
369 PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);
370 PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
371 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
372 if (IS_PSB(dev) && drm_core_check_feature(dev, DRIVER_MODESET))
373 drm_irq_install(dev);
374
375 dev->vblank_disable_allowed = 1;
376
377 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
378
379 dev->driver->get_vblank_counter = psb_get_vblank_counter;
380
381 psb_modeset_init(dev);
382 psb_fbdev_init(dev);
383 drm_kms_helper_poll_init(dev);
384
385 /* Only add backlight support if we have LVDS output */
386 list_for_each_entry(connector, &dev->mode_config.connector_list,
387 head) {
388 psb_intel_encoder = psb_intel_attached_encoder(connector);
389
390 switch (psb_intel_encoder->type) {
391 case INTEL_OUTPUT_LVDS:
392 case INTEL_OUTPUT_MIPI:
393 ret = gma_backlight_init(dev);
394 break;
395 }
396 }
397
398 if (ret)
399 return ret;
400#if 0
401 /*enable runtime pm at last*/
402 pm_runtime_enable(&dev->pdev->dev);
403 pm_runtime_set_active(&dev->pdev->dev);
404#endif
405 /*Intel drm driver load is done, continue doing pvr load*/
406 return 0;
407out_err:
408 psb_driver_unload(dev);
409 return ret;
410}
411
412int psb_driver_device_is_agp(struct drm_device *dev)
413{
414 return 0;
415}
416
417static inline void get_brightness(struct backlight_device *bd)
418{
419#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
420 if (bd) {
421 bd->props.brightness = bd->ops->get_brightness(bd);
422 backlight_update_status(bd);
423 }
424#endif
425}
426
427static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
428 struct drm_file *file_priv)
429{
430 struct drm_psb_private *dev_priv = psb_priv(dev);
431 uint32_t *arg = data;
432
433 dev_priv->blc_adj2 = *arg;
434 get_brightness(dev_priv->backlight_device);
435 return 0;
436}
437
438static int psb_adb_ioctl(struct drm_device *dev, void *data,
439 struct drm_file *file_priv)
440{
441 struct drm_psb_private *dev_priv = psb_priv(dev);
442 uint32_t *arg = data;
443
444 dev_priv->blc_adj1 = *arg;
445 get_brightness(dev_priv->backlight_device);
446 return 0;
447}
448
449static int psb_gamma_ioctl(struct drm_device *dev, void *data,
450 struct drm_file *file_priv)
451{
452 struct drm_psb_dpst_lut_arg *lut_arg = data;
453 struct drm_mode_object *obj;
454 struct drm_crtc *crtc;
455 struct drm_connector *connector;
456 struct psb_intel_crtc *psb_intel_crtc;
457 int i = 0;
458 int32_t obj_id;
459
460 obj_id = lut_arg->output_id;
461 obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR);
462 if (!obj) {
463 dev_dbg(dev->dev, "Invalid Connector object.\n");
464 return -EINVAL;
465 }
466
467 connector = obj_to_connector(obj);
468 crtc = connector->encoder->crtc;
469 psb_intel_crtc = to_psb_intel_crtc(crtc);
470
471 for (i = 0; i < 256; i++)
472 psb_intel_crtc->lut_adj[i] = lut_arg->lut[i];
473
474 psb_intel_crtc_load_lut(crtc);
475
476 return 0;
477}
478
479static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
480 struct drm_file *file_priv)
481{
482 uint32_t obj_id;
483 uint16_t op;
484 struct drm_mode_modeinfo *umode;
485 struct drm_display_mode *mode = NULL;
486 struct drm_psb_mode_operation_arg *arg;
487 struct drm_mode_object *obj;
488 struct drm_connector *connector;
489 struct drm_connector_helper_funcs *connector_funcs;
490 int ret = 0;
491 int resp = MODE_OK;
492
493 arg = (struct drm_psb_mode_operation_arg *)data;
494 obj_id = arg->obj_id;
495 op = arg->operation;
496
497 switch (op) {
498 case PSB_MODE_OPERATION_MODE_VALID:
499 umode = &arg->mode;
500
501 mutex_lock(&dev->mode_config.mutex);
502
503 obj = drm_mode_object_find(dev, obj_id,
504 DRM_MODE_OBJECT_CONNECTOR);
505 if (!obj) {
506 ret = -EINVAL;
507 goto mode_op_out;
508 }
509
510 connector = obj_to_connector(obj);
511
512 mode = drm_mode_create(dev);
513 if (!mode) {
514 ret = -ENOMEM;
515 goto mode_op_out;
516 }
517
518 /* drm_crtc_convert_umode(mode, umode); */
519 {
520 mode->clock = umode->clock;
521 mode->hdisplay = umode->hdisplay;
522 mode->hsync_start = umode->hsync_start;
523 mode->hsync_end = umode->hsync_end;
524 mode->htotal = umode->htotal;
525 mode->hskew = umode->hskew;
526 mode->vdisplay = umode->vdisplay;
527 mode->vsync_start = umode->vsync_start;
528 mode->vsync_end = umode->vsync_end;
529 mode->vtotal = umode->vtotal;
530 mode->vscan = umode->vscan;
531 mode->vrefresh = umode->vrefresh;
532 mode->flags = umode->flags;
533 mode->type = umode->type;
534 strncpy(mode->name, umode->name, DRM_DISPLAY_MODE_LEN);
535 mode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
536 }
537
538 connector_funcs = (struct drm_connector_helper_funcs *)
539 connector->helper_private;
540
541 if (connector_funcs->mode_valid) {
542 resp = connector_funcs->mode_valid(connector, mode);
543 arg->data = resp;
544 }
545
546 /*do some clean up work*/
547 if (mode)
548 drm_mode_destroy(dev, mode);
549mode_op_out:
550 mutex_unlock(&dev->mode_config.mutex);
551 return ret;
552
553 default:
554 dev_dbg(dev->dev, "Unsupported psb mode operation\n");
555 return -EOPNOTSUPP;
556 }
557
558 return 0;
559}
560
561static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
562 struct drm_file *file_priv)
563{
564 struct drm_psb_private *dev_priv = psb_priv(dev);
565 struct drm_psb_stolen_memory_arg *arg = data;
566
567 arg->base = dev_priv->stolen_base;
568 arg->size = dev_priv->vram_stolen_size;
569
570 return 0;
571}
572
573static int psb_driver_open(struct drm_device *dev, struct drm_file *priv)
574{
575 return 0;
576}
577
578static void psb_driver_close(struct drm_device *dev, struct drm_file *priv)
579{
580}
581
582static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd,
583 unsigned long arg)
584{
585 struct drm_file *file_priv = filp->private_data;
586 struct drm_device *dev = file_priv->minor->dev;
587 struct drm_psb_private *dev_priv = dev->dev_private;
588 static unsigned int runtime_allowed;
589
590 if (runtime_allowed == 1 && dev_priv->is_lvds_on) {
591 runtime_allowed++;
592 pm_runtime_allow(&dev->pdev->dev);
593 dev_priv->rpm_enabled = 1;
594 }
595 return drm_ioctl(filp, cmd, arg);
596 /* FIXME: do we need to wrap the other side of this */
597}
598
599
600/* When a client dies:
601 * - Check for and clean up flipped page state
602 */
603void psb_driver_preclose(struct drm_device *dev, struct drm_file *priv)
604{
605}
606
607static void psb_remove(struct pci_dev *pdev)
608{
609 struct drm_device *dev = pci_get_drvdata(pdev);
610 drm_put_dev(dev);
611}
612
613static const struct dev_pm_ops psb_pm_ops = {
614 .resume = gma_power_resume,
615 .suspend = gma_power_suspend,
616 .runtime_suspend = psb_runtime_suspend,
617 .runtime_resume = psb_runtime_resume,
618 .runtime_idle = psb_runtime_idle,
619};
620
621static struct vm_operations_struct psb_gem_vm_ops = {
622 .fault = psb_gem_fault,
623 .open = drm_gem_vm_open,
624 .close = drm_gem_vm_close,
625};
626
627static const struct file_operations psb_gem_fops = {
628 .owner = THIS_MODULE,
629 .open = drm_open,
630 .release = drm_release,
631 .unlocked_ioctl = psb_unlocked_ioctl,
632 .mmap = drm_gem_mmap,
633 .poll = drm_poll,
634 .fasync = drm_fasync,
635 .read = drm_read,
636};
637
638static struct drm_driver driver = {
639 .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \
640 DRIVER_IRQ_VBL | DRIVER_MODESET | DRIVER_GEM ,
641 .load = psb_driver_load,
642 .unload = psb_driver_unload,
643
644 .ioctls = psb_ioctls,
645 .num_ioctls = DRM_ARRAY_SIZE(psb_ioctls),
646 .device_is_agp = psb_driver_device_is_agp,
647 .irq_preinstall = psb_irq_preinstall,
648 .irq_postinstall = psb_irq_postinstall,
649 .irq_uninstall = psb_irq_uninstall,
650 .irq_handler = psb_irq_handler,
651 .enable_vblank = psb_enable_vblank,
652 .disable_vblank = psb_disable_vblank,
653 .get_vblank_counter = psb_get_vblank_counter,
654 .lastclose = psb_lastclose,
655 .open = psb_driver_open,
656 .preclose = psb_driver_preclose,
657 .postclose = psb_driver_close,
658 .reclaim_buffers = drm_core_reclaim_buffers,
659
660 .gem_init_object = psb_gem_init_object,
661 .gem_free_object = psb_gem_free_object,
662 .gem_vm_ops = &psb_gem_vm_ops,
663 .dumb_create = psb_gem_dumb_create,
664 .dumb_map_offset = psb_gem_dumb_map_gtt,
665 .dumb_destroy = psb_gem_dumb_destroy,
666 .fops = &psb_gem_fops,
667 .name = DRIVER_NAME,
668 .desc = DRIVER_DESC,
669 .date = PSB_DRM_DRIVER_DATE,
670 .major = PSB_DRM_DRIVER_MAJOR,
671 .minor = PSB_DRM_DRIVER_MINOR,
672 .patchlevel = PSB_DRM_DRIVER_PATCHLEVEL
673};
674
675static struct pci_driver psb_pci_driver = {
676 .name = DRIVER_NAME,
677 .id_table = pciidlist,
678 .probe = psb_probe,
679 .remove = psb_remove,
680 .driver.pm = &psb_pm_ops,
681};
682
683static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
684{
685 return drm_get_pci_dev(pdev, ent, &driver);
686}
687
688static int __init psb_init(void)
689{
690 return drm_pci_init(&driver, &psb_pci_driver);
691}
692
693static void __exit psb_exit(void)
694{
695 drm_pci_exit(&driver, &psb_pci_driver);
696}
697
698late_initcall(psb_init);
699module_exit(psb_exit);
700
701MODULE_AUTHOR("Alan Cox <alan@linux.intel.com> and others");
702MODULE_DESCRIPTION(DRIVER_DESC);
703MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
new file mode 100644
index 00000000000..eb1568a0da9
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -0,0 +1,956 @@
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#ifndef _PSB_DRV_H_
21#define _PSB_DRV_H_
22
23#include <linux/kref.h>
24
25#include <drm/drmP.h>
26#include "drm_global.h"
27#include "gem_glue.h"
28#include "gma_drm.h"
29#include "psb_reg.h"
30#include "psb_intel_drv.h"
31#include "gtt.h"
32#include "power.h"
33#include "oaktrail.h"
34
35/* Append new drm mode definition here, align with libdrm definition */
36#define DRM_MODE_SCALE_NO_SCALE 2
37
38enum {
39 CHIP_PSB_8108 = 0, /* Poulsbo */
40 CHIP_PSB_8109 = 1, /* Poulsbo */
41 CHIP_MRST_4100 = 2, /* Moorestown/Oaktrail */
42 CHIP_MFLD_0130 = 3, /* Medfield */
43};
44
45#define IS_PSB(dev) (((dev)->pci_device & 0xfffe) == 0x8108)
46#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100)
47#define IS_MFLD(dev) (((dev)->pci_device & 0xfff8) == 0x0130)
48
49/*
50 * Driver definitions
51 */
52
53#define DRIVER_NAME "gma500"
54#define DRIVER_DESC "DRM driver for the Intel GMA500"
55
56#define PSB_DRM_DRIVER_DATE "2011-06-06"
57#define PSB_DRM_DRIVER_MAJOR 1
58#define PSB_DRM_DRIVER_MINOR 0
59#define PSB_DRM_DRIVER_PATCHLEVEL 0
60
61/*
62 * Hardware offsets
63 */
64#define PSB_VDC_OFFSET 0x00000000
65#define PSB_VDC_SIZE 0x000080000
66#define MRST_MMIO_SIZE 0x0000C0000
67#define MDFLD_MMIO_SIZE 0x000100000
68#define PSB_SGX_SIZE 0x8000
69#define PSB_SGX_OFFSET 0x00040000
70#define MRST_SGX_OFFSET 0x00080000
71/*
72 * PCI resource identifiers
73 */
74#define PSB_MMIO_RESOURCE 0
75#define PSB_GATT_RESOURCE 2
76#define PSB_GTT_RESOURCE 3
77/*
78 * PCI configuration
79 */
80#define PSB_GMCH_CTRL 0x52
81#define PSB_BSM 0x5C
82#define _PSB_GMCH_ENABLED 0x4
83#define PSB_PGETBL_CTL 0x2020
84#define _PSB_PGETBL_ENABLED 0x00000001
85#define PSB_SGX_2D_SLAVE_PORT 0x4000
86
87/* To get rid of */
88#define PSB_TT_PRIV0_LIMIT (256*1024*1024)
89#define PSB_TT_PRIV0_PLIMIT (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT)
90
91/*
92 * SGX side MMU definitions (these can probably go)
93 */
94
95/*
96 * Flags for external memory type field.
97 */
98#define PSB_MMU_CACHED_MEMORY 0x0001 /* Bind to MMU only */
99#define PSB_MMU_RO_MEMORY 0x0002 /* MMU RO memory */
100#define PSB_MMU_WO_MEMORY 0x0004 /* MMU WO memory */
101/*
102 * PTE's and PDE's
103 */
104#define PSB_PDE_MASK 0x003FFFFF
105#define PSB_PDE_SHIFT 22
106#define PSB_PTE_SHIFT 12
107/*
108 * Cache control
109 */
110#define PSB_PTE_VALID 0x0001 /* PTE / PDE valid */
111#define PSB_PTE_WO 0x0002 /* Write only */
112#define PSB_PTE_RO 0x0004 /* Read only */
113#define PSB_PTE_CACHED 0x0008 /* CPU cache coherent */
114
115/*
116 * VDC registers and bits
117 */
118#define PSB_MSVDX_CLOCKGATING 0x2064
119#define PSB_TOPAZ_CLOCKGATING 0x2068
120#define PSB_HWSTAM 0x2098
121#define PSB_INSTPM 0x20C0
122#define PSB_INT_IDENTITY_R 0x20A4
123#define _MDFLD_PIPEC_EVENT_FLAG (1<<2)
124#define _MDFLD_PIPEC_VBLANK_FLAG (1<<3)
125#define _PSB_DPST_PIPEB_FLAG (1<<4)
126#define _MDFLD_PIPEB_EVENT_FLAG (1<<4)
127#define _PSB_VSYNC_PIPEB_FLAG (1<<5)
128#define _PSB_DPST_PIPEA_FLAG (1<<6)
129#define _PSB_PIPEA_EVENT_FLAG (1<<6)
130#define _PSB_VSYNC_PIPEA_FLAG (1<<7)
131#define _MDFLD_MIPIA_FLAG (1<<16)
132#define _MDFLD_MIPIC_FLAG (1<<17)
133#define _PSB_IRQ_SGX_FLAG (1<<18)
134#define _PSB_IRQ_MSVDX_FLAG (1<<19)
135#define _LNC_IRQ_TOPAZ_FLAG (1<<20)
136
137#define _PSB_PIPE_EVENT_FLAG (_PSB_VSYNC_PIPEA_FLAG | \
138 _PSB_VSYNC_PIPEB_FLAG)
139
140/* This flag includes all the display IRQ bits excepts the vblank irqs. */
141#define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | \
142 _MDFLD_PIPEB_EVENT_FLAG | \
143 _PSB_PIPEA_EVENT_FLAG | \
144 _PSB_VSYNC_PIPEA_FLAG | \
145 _MDFLD_MIPIA_FLAG | \
146 _MDFLD_MIPIC_FLAG)
147#define PSB_INT_IDENTITY_R 0x20A4
148#define PSB_INT_MASK_R 0x20A8
149#define PSB_INT_ENABLE_R 0x20A0
150
151#define _PSB_MMU_ER_MASK 0x0001FF00
152#define _PSB_MMU_ER_HOST (1 << 16)
153#define GPIOA 0x5010
154#define GPIOB 0x5014
155#define GPIOC 0x5018
156#define GPIOD 0x501c
157#define GPIOE 0x5020
158#define GPIOF 0x5024
159#define GPIOG 0x5028
160#define GPIOH 0x502c
161#define GPIO_CLOCK_DIR_MASK (1 << 0)
162#define GPIO_CLOCK_DIR_IN (0 << 1)
163#define GPIO_CLOCK_DIR_OUT (1 << 1)
164#define GPIO_CLOCK_VAL_MASK (1 << 2)
165#define GPIO_CLOCK_VAL_OUT (1 << 3)
166#define GPIO_CLOCK_VAL_IN (1 << 4)
167#define GPIO_CLOCK_PULLUP_DISABLE (1 << 5)
168#define GPIO_DATA_DIR_MASK (1 << 8)
169#define GPIO_DATA_DIR_IN (0 << 9)
170#define GPIO_DATA_DIR_OUT (1 << 9)
171#define GPIO_DATA_VAL_MASK (1 << 10)
172#define GPIO_DATA_VAL_OUT (1 << 11)
173#define GPIO_DATA_VAL_IN (1 << 12)
174#define GPIO_DATA_PULLUP_DISABLE (1 << 13)
175
176#define VCLK_DIVISOR_VGA0 0x6000
177#define VCLK_DIVISOR_VGA1 0x6004
178#define VCLK_POST_DIV 0x6010
179
180#define PSB_COMM_2D (PSB_ENGINE_2D << 4)
181#define PSB_COMM_3D (PSB_ENGINE_3D << 4)
182#define PSB_COMM_TA (PSB_ENGINE_TA << 4)
183#define PSB_COMM_HP (PSB_ENGINE_HP << 4)
184#define PSB_COMM_USER_IRQ (1024 >> 2)
185#define PSB_COMM_USER_IRQ_LOST (PSB_COMM_USER_IRQ + 1)
186#define PSB_COMM_FW (2048 >> 2)
187
188#define PSB_UIRQ_VISTEST 1
189#define PSB_UIRQ_OOM_REPLY 2
190#define PSB_UIRQ_FIRE_TA_REPLY 3
191#define PSB_UIRQ_FIRE_RASTER_REPLY 4
192
193#define PSB_2D_SIZE (256*1024*1024)
194#define PSB_MAX_RELOC_PAGES 1024
195
196#define PSB_LOW_REG_OFFS 0x0204
197#define PSB_HIGH_REG_OFFS 0x0600
198
199#define PSB_NUM_VBLANKS 2
200
201
202#define PSB_2D_SIZE (256*1024*1024)
203#define PSB_MAX_RELOC_PAGES 1024
204
205#define PSB_LOW_REG_OFFS 0x0204
206#define PSB_HIGH_REG_OFFS 0x0600
207
208#define PSB_NUM_VBLANKS 2
209#define PSB_WATCHDOG_DELAY (DRM_HZ * 2)
210#define PSB_LID_DELAY (DRM_HZ / 10)
211
212#define MDFLD_PNW_B0 0x04
213#define MDFLD_PNW_C0 0x08
214
215#define MDFLD_DSR_2D_3D_0 (1 << 0)
216#define MDFLD_DSR_2D_3D_2 (1 << 1)
217#define MDFLD_DSR_CURSOR_0 (1 << 2)
218#define MDFLD_DSR_CURSOR_2 (1 << 3)
219#define MDFLD_DSR_OVERLAY_0 (1 << 4)
220#define MDFLD_DSR_OVERLAY_2 (1 << 5)
221#define MDFLD_DSR_MIPI_CONTROL (1 << 6)
222#define MDFLD_DSR_DAMAGE_MASK_0 ((1 << 0) | (1 << 2) | (1 << 4))
223#define MDFLD_DSR_DAMAGE_MASK_2 ((1 << 1) | (1 << 3) | (1 << 5))
224#define MDFLD_DSR_2D_3D (MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2)
225
226#define MDFLD_DSR_RR 45
227#define MDFLD_DPU_ENABLE (1 << 31)
228#define MDFLD_DSR_FULLSCREEN (1 << 30)
229#define MDFLD_DSR_DELAY (DRM_HZ / MDFLD_DSR_RR)
230
231#define PSB_PWR_STATE_ON 1
232#define PSB_PWR_STATE_OFF 2
233
234#define PSB_PMPOLICY_NOPM 0
235#define PSB_PMPOLICY_CLOCKGATING 1
236#define PSB_PMPOLICY_POWERDOWN 2
237
238#define PSB_PMSTATE_POWERUP 0
239#define PSB_PMSTATE_CLOCKGATED 1
240#define PSB_PMSTATE_POWERDOWN 2
241#define PSB_PCIx_MSI_ADDR_LOC 0x94
242#define PSB_PCIx_MSI_DATA_LOC 0x98
243
244/* Medfield crystal settings */
245#define KSEL_CRYSTAL_19 1
246#define KSEL_BYPASS_19 5
247#define KSEL_BYPASS_25 6
248#define KSEL_BYPASS_83_100 7
249
250struct opregion_header;
251struct opregion_acpi;
252struct opregion_swsci;
253struct opregion_asle;
254
255struct psb_intel_opregion {
256 struct opregion_header *header;
257 struct opregion_acpi *acpi;
258 struct opregion_swsci *swsci;
259 struct opregion_asle *asle;
260 int enabled;
261};
262
263struct sdvo_device_mapping {
264 u8 initialized;
265 u8 dvo_port;
266 u8 slave_addr;
267 u8 dvo_wiring;
268 u8 i2c_pin;
269 u8 i2c_speed;
270 u8 ddc_pin;
271};
272
273struct intel_gmbus {
274 struct i2c_adapter adapter;
275 struct i2c_adapter *force_bit;
276 u32 reg0;
277};
278
279struct psb_ops;
280
281#define PSB_NUM_PIPE 3
282
283struct drm_psb_private {
284 struct drm_device *dev;
285 const struct psb_ops *ops;
286
287 struct psb_gtt gtt;
288
289 /* GTT Memory manager */
290 struct psb_gtt_mm *gtt_mm;
291 struct page *scratch_page;
292 u32 *gtt_map;
293 uint32_t stolen_base;
294 void *vram_addr;
295 unsigned long vram_stolen_size;
296 int gtt_initialized;
297 u16 gmch_ctrl; /* Saved GTT setup */
298 u32 pge_ctl;
299
300 struct mutex gtt_mutex;
301 struct resource *gtt_mem; /* Our PCI resource */
302
303 struct psb_mmu_driver *mmu;
304 struct psb_mmu_pd *pf_pd;
305
306 /*
307 * Register base
308 */
309
310 uint8_t *sgx_reg;
311 uint8_t *vdc_reg;
312 uint32_t gatt_free_offset;
313
314 /*
315 * Fencing / irq.
316 */
317
318 uint32_t vdc_irq_mask;
319 uint32_t pipestat[PSB_NUM_PIPE];
320
321 spinlock_t irqmask_lock;
322
323 /*
324 * Power
325 */
326
327 bool suspended;
328 bool display_power;
329 int display_count;
330
331 /*
332 * Modesetting
333 */
334 struct psb_intel_mode_device mode_dev;
335
336 struct drm_crtc *plane_to_crtc_mapping[PSB_NUM_PIPE];
337 struct drm_crtc *pipe_to_crtc_mapping[PSB_NUM_PIPE];
338 uint32_t num_pipe;
339
340 /*
341 * OSPM info (Power management base) (can go ?)
342 */
343 uint32_t ospm_base;
344
345 /*
346 * Sizes info
347 */
348
349 u32 fuse_reg_value;
350 u32 video_device_fuse;
351
352 /* PCI revision ID for B0:D2:F0 */
353 uint8_t platform_rev_id;
354
355 /* gmbus */
356 struct intel_gmbus *gmbus;
357
358 /* Used by SDVO */
359 int crt_ddc_pin;
360 /* FIXME: The mappings should be parsed from bios but for now we can
361 pretend there are no mappings available */
362 struct sdvo_device_mapping sdvo_mappings[2];
363 u32 hotplug_supported_mask;
364 struct drm_property *broadcast_rgb_property;
365 struct drm_property *force_audio_property;
366
367 /*
368 * LVDS info
369 */
370 int backlight_duty_cycle; /* restore backlight to this value */
371 bool panel_wants_dither;
372 struct drm_display_mode *panel_fixed_mode;
373 struct drm_display_mode *lfp_lvds_vbt_mode;
374 struct drm_display_mode *sdvo_lvds_vbt_mode;
375
376 struct bdb_lvds_backlight *lvds_bl; /* LVDS backlight info from VBT */
377 struct psb_intel_i2c_chan *lvds_i2c_bus; /* FIXME: Remove this? */
378
379 /* Feature bits from the VBIOS */
380 unsigned int int_tv_support:1;
381 unsigned int lvds_dither:1;
382 unsigned int lvds_vbt:1;
383 unsigned int int_crt_support:1;
384 unsigned int lvds_use_ssc:1;
385 int lvds_ssc_freq;
386 bool is_lvds_on;
387 bool is_mipi_on;
388 u32 mipi_ctrl_display;
389
390 unsigned int core_freq;
391 uint32_t iLVDS_enable;
392
393 /* Runtime PM state */
394 int rpm_enabled;
395
396 /* MID specific */
397 struct oaktrail_vbt vbt_data;
398 struct oaktrail_gct_data gct_data;
399
400 /* MIPI Panel type etc */
401 int panel_id;
402 bool dual_mipi; /* dual display - DPI & DBI */
403 bool dpi_panel_on; /* The DPI panel power is on */
404 bool dpi_panel_on2; /* The DPI panel power is on */
405 bool dbi_panel_on; /* The DBI panel power is on */
406 bool dbi_panel_on2; /* The DBI panel power is on */
407 u32 dsr_fb_update; /* DSR FB update counter */
408
409 /* Moorestown HDMI state */
410 struct oaktrail_hdmi_dev *hdmi_priv;
411
412 /* Moorestown pipe config register value cache */
413 uint32_t pipeconf;
414 uint32_t pipeconf1;
415 uint32_t pipeconf2;
416
417 /* Moorestown plane control register value cache */
418 uint32_t dspcntr;
419 uint32_t dspcntr1;
420 uint32_t dspcntr2;
421
422 /* Moorestown MM backlight cache */
423 uint8_t saveBKLTCNT;
424 uint8_t saveBKLTREQ;
425 uint8_t saveBKLTBRTL;
426
427 /*
428 * Register state
429 */
430 uint32_t saveDSPACNTR;
431 uint32_t saveDSPBCNTR;
432 uint32_t savePIPEACONF;
433 uint32_t savePIPEBCONF;
434 uint32_t savePIPEASRC;
435 uint32_t savePIPEBSRC;
436 uint32_t saveFPA0;
437 uint32_t saveFPA1;
438 uint32_t saveDPLL_A;
439 uint32_t saveDPLL_A_MD;
440 uint32_t saveHTOTAL_A;
441 uint32_t saveHBLANK_A;
442 uint32_t saveHSYNC_A;
443 uint32_t saveVTOTAL_A;
444 uint32_t saveVBLANK_A;
445 uint32_t saveVSYNC_A;
446 uint32_t saveDSPASTRIDE;
447 uint32_t saveDSPASIZE;
448 uint32_t saveDSPAPOS;
449 uint32_t saveDSPABASE;
450 uint32_t saveDSPASURF;
451 uint32_t saveDSPASTATUS;
452 uint32_t saveFPB0;
453 uint32_t saveFPB1;
454 uint32_t saveDPLL_B;
455 uint32_t saveDPLL_B_MD;
456 uint32_t saveHTOTAL_B;
457 uint32_t saveHBLANK_B;
458 uint32_t saveHSYNC_B;
459 uint32_t saveVTOTAL_B;
460 uint32_t saveVBLANK_B;
461 uint32_t saveVSYNC_B;
462 uint32_t saveDSPBSTRIDE;
463 uint32_t saveDSPBSIZE;
464 uint32_t saveDSPBPOS;
465 uint32_t saveDSPBBASE;
466 uint32_t saveDSPBSURF;
467 uint32_t saveDSPBSTATUS;
468 uint32_t saveVCLK_DIVISOR_VGA0;
469 uint32_t saveVCLK_DIVISOR_VGA1;
470 uint32_t saveVCLK_POST_DIV;
471 uint32_t saveVGACNTRL;
472 uint32_t saveADPA;
473 uint32_t saveLVDS;
474 uint32_t saveDVOA;
475 uint32_t saveDVOB;
476 uint32_t saveDVOC;
477 uint32_t savePP_ON;
478 uint32_t savePP_OFF;
479 uint32_t savePP_CONTROL;
480 uint32_t savePP_CYCLE;
481 uint32_t savePFIT_CONTROL;
482 uint32_t savePaletteA[256];
483 uint32_t savePaletteB[256];
484 uint32_t saveBLC_PWM_CTL2;
485 uint32_t saveBLC_PWM_CTL;
486 uint32_t saveCLOCKGATING;
487 uint32_t saveDSPARB;
488 uint32_t saveDSPATILEOFF;
489 uint32_t saveDSPBTILEOFF;
490 uint32_t saveDSPAADDR;
491 uint32_t saveDSPBADDR;
492 uint32_t savePFIT_AUTO_RATIOS;
493 uint32_t savePFIT_PGM_RATIOS;
494 uint32_t savePP_ON_DELAYS;
495 uint32_t savePP_OFF_DELAYS;
496 uint32_t savePP_DIVISOR;
497 uint32_t saveBSM;
498 uint32_t saveVBT;
499 uint32_t saveBCLRPAT_A;
500 uint32_t saveBCLRPAT_B;
501 uint32_t saveDSPALINOFF;
502 uint32_t saveDSPBLINOFF;
503 uint32_t savePERF_MODE;
504 uint32_t saveDSPFW1;
505 uint32_t saveDSPFW2;
506 uint32_t saveDSPFW3;
507 uint32_t saveDSPFW4;
508 uint32_t saveDSPFW5;
509 uint32_t saveDSPFW6;
510 uint32_t saveCHICKENBIT;
511 uint32_t saveDSPACURSOR_CTRL;
512 uint32_t saveDSPBCURSOR_CTRL;
513 uint32_t saveDSPACURSOR_BASE;
514 uint32_t saveDSPBCURSOR_BASE;
515 uint32_t saveDSPACURSOR_POS;
516 uint32_t saveDSPBCURSOR_POS;
517 uint32_t save_palette_a[256];
518 uint32_t save_palette_b[256];
519 uint32_t saveOV_OVADD;
520 uint32_t saveOV_OGAMC0;
521 uint32_t saveOV_OGAMC1;
522 uint32_t saveOV_OGAMC2;
523 uint32_t saveOV_OGAMC3;
524 uint32_t saveOV_OGAMC4;
525 uint32_t saveOV_OGAMC5;
526 uint32_t saveOVC_OVADD;
527 uint32_t saveOVC_OGAMC0;
528 uint32_t saveOVC_OGAMC1;
529 uint32_t saveOVC_OGAMC2;
530 uint32_t saveOVC_OGAMC3;
531 uint32_t saveOVC_OGAMC4;
532 uint32_t saveOVC_OGAMC5;
533
534 /* MSI reg save */
535 uint32_t msi_addr;
536 uint32_t msi_data;
537
538 /* Medfield specific register save state */
539 uint32_t saveHDMIPHYMISCCTL;
540 uint32_t saveHDMIB_CONTROL;
541 uint32_t saveDSPCCNTR;
542 uint32_t savePIPECCONF;
543 uint32_t savePIPECSRC;
544 uint32_t saveHTOTAL_C;
545 uint32_t saveHBLANK_C;
546 uint32_t saveHSYNC_C;
547 uint32_t saveVTOTAL_C;
548 uint32_t saveVBLANK_C;
549 uint32_t saveVSYNC_C;
550 uint32_t saveDSPCSTRIDE;
551 uint32_t saveDSPCSIZE;
552 uint32_t saveDSPCPOS;
553 uint32_t saveDSPCSURF;
554 uint32_t saveDSPCSTATUS;
555 uint32_t saveDSPCLINOFF;
556 uint32_t saveDSPCTILEOFF;
557 uint32_t saveDSPCCURSOR_CTRL;
558 uint32_t saveDSPCCURSOR_BASE;
559 uint32_t saveDSPCCURSOR_POS;
560 uint32_t save_palette_c[256];
561 uint32_t saveOV_OVADD_C;
562 uint32_t saveOV_OGAMC0_C;
563 uint32_t saveOV_OGAMC1_C;
564 uint32_t saveOV_OGAMC2_C;
565 uint32_t saveOV_OGAMC3_C;
566 uint32_t saveOV_OGAMC4_C;
567 uint32_t saveOV_OGAMC5_C;
568
569 /* DSI register save */
570 uint32_t saveDEVICE_READY_REG;
571 uint32_t saveINTR_EN_REG;
572 uint32_t saveDSI_FUNC_PRG_REG;
573 uint32_t saveHS_TX_TIMEOUT_REG;
574 uint32_t saveLP_RX_TIMEOUT_REG;
575 uint32_t saveTURN_AROUND_TIMEOUT_REG;
576 uint32_t saveDEVICE_RESET_REG;
577 uint32_t saveDPI_RESOLUTION_REG;
578 uint32_t saveHORIZ_SYNC_PAD_COUNT_REG;
579 uint32_t saveHORIZ_BACK_PORCH_COUNT_REG;
580 uint32_t saveHORIZ_FRONT_PORCH_COUNT_REG;
581 uint32_t saveHORIZ_ACTIVE_AREA_COUNT_REG;
582 uint32_t saveVERT_SYNC_PAD_COUNT_REG;
583 uint32_t saveVERT_BACK_PORCH_COUNT_REG;
584 uint32_t saveVERT_FRONT_PORCH_COUNT_REG;
585 uint32_t saveHIGH_LOW_SWITCH_COUNT_REG;
586 uint32_t saveINIT_COUNT_REG;
587 uint32_t saveMAX_RET_PAK_REG;
588 uint32_t saveVIDEO_FMT_REG;
589 uint32_t saveEOT_DISABLE_REG;
590 uint32_t saveLP_BYTECLK_REG;
591 uint32_t saveHS_LS_DBI_ENABLE_REG;
592 uint32_t saveTXCLKESC_REG;
593 uint32_t saveDPHY_PARAM_REG;
594 uint32_t saveMIPI_CONTROL_REG;
595 uint32_t saveMIPI;
596 uint32_t saveMIPI_C;
597
598 /* DPST register save */
599 uint32_t saveHISTOGRAM_INT_CONTROL_REG;
600 uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG;
601 uint32_t savePWM_CONTROL_LOGIC;
602
603 /*
604 * DSI info.
605 */
606 void * dbi_dsr_info;
607 void * dbi_dpu_info;
608 void * dsi_configs[2];
609 /*
610 * LID-Switch
611 */
612 spinlock_t lid_lock;
613 struct timer_list lid_timer;
614 struct psb_intel_opregion opregion;
615 u32 *lid_state;
616 u32 lid_last_state;
617
618 /*
619 * Watchdog
620 */
621
622 uint32_t apm_reg;
623 uint16_t apm_base;
624
625 /*
626 * Used for modifying backlight from
627 * xrandr -- consider removing and using HAL instead
628 */
629 struct backlight_device *backlight_device;
630 struct drm_property *backlight_property;
631 uint32_t blc_adj1;
632 uint32_t blc_adj2;
633
634 void *fbdev;
635
636 /* 2D acceleration */
637 spinlock_t lock_2d;
638};
639
640
641/*
642 * Operations for each board type
643 */
644
645struct psb_ops {
646 const char *name;
647 unsigned int accel_2d:1;
648 int pipes; /* Number of output pipes */
649 int crtcs; /* Number of CRTCs */
650 int sgx_offset; /* Base offset of SGX device */
651
652 /* Sub functions */
653 struct drm_crtc_helper_funcs const *crtc_helper;
654 struct drm_crtc_funcs const *crtc_funcs;
655
656 /* Setup hooks */
657 int (*chip_setup)(struct drm_device *dev);
658 void (*chip_teardown)(struct drm_device *dev);
659
660 /* Display management hooks */
661 int (*output_init)(struct drm_device *dev);
662 /* Power management hooks */
663 void (*init_pm)(struct drm_device *dev);
664 int (*save_regs)(struct drm_device *dev);
665 int (*restore_regs)(struct drm_device *dev);
666 int (*power_up)(struct drm_device *dev);
667 int (*power_down)(struct drm_device *dev);
668
669 void (*lvds_bl_power)(struct drm_device *dev, bool on);
670#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
671 /* Backlight */
672 int (*backlight_init)(struct drm_device *dev);
673#endif
674 int i2c_bus; /* I2C bus identifier for Moorestown */
675};
676
677
678
679struct psb_mmu_driver;
680
681extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int);
682extern int drm_pick_crtcs(struct drm_device *dev);
683
684static inline struct drm_psb_private *psb_priv(struct drm_device *dev)
685{
686 return (struct drm_psb_private *) dev->dev_private;
687}
688
689/*
690 * MMU stuff.
691 */
692
693extern struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
694 int trap_pagefaults,
695 int invalid_type,
696 struct drm_psb_private *dev_priv);
697extern void psb_mmu_driver_takedown(struct psb_mmu_driver *driver);
698extern struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver
699 *driver);
700extern void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, uint32_t mmu_offset,
701 uint32_t gtt_start, uint32_t gtt_pages);
702extern struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver,
703 int trap_pagefaults,
704 int invalid_type);
705extern void psb_mmu_free_pagedir(struct psb_mmu_pd *pd);
706extern void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot);
707extern void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd,
708 unsigned long address,
709 uint32_t num_pages);
710extern int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd,
711 uint32_t start_pfn,
712 unsigned long address,
713 uint32_t num_pages, int type);
714extern int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
715 unsigned long *pfn);
716
717/*
718 * Enable / disable MMU for different requestors.
719 */
720
721
722extern void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context);
723extern int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages,
724 unsigned long address, uint32_t num_pages,
725 uint32_t desired_tile_stride,
726 uint32_t hw_tile_stride, int type);
727extern void psb_mmu_remove_pages(struct psb_mmu_pd *pd,
728 unsigned long address, uint32_t num_pages,
729 uint32_t desired_tile_stride,
730 uint32_t hw_tile_stride);
731/*
732 *psb_irq.c
733 */
734
735extern irqreturn_t psb_irq_handler(DRM_IRQ_ARGS);
736extern int psb_irq_enable_dpst(struct drm_device *dev);
737extern int psb_irq_disable_dpst(struct drm_device *dev);
738extern void psb_irq_preinstall(struct drm_device *dev);
739extern int psb_irq_postinstall(struct drm_device *dev);
740extern void psb_irq_uninstall(struct drm_device *dev);
741extern void psb_irq_turn_on_dpst(struct drm_device *dev);
742extern void psb_irq_turn_off_dpst(struct drm_device *dev);
743
744extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands);
745extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
746extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence);
747extern int psb_enable_vblank(struct drm_device *dev, int crtc);
748extern void psb_disable_vblank(struct drm_device *dev, int crtc);
749void
750psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask);
751
752void
753psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask);
754
755extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc);
756
757/*
758 * intel_opregion.c
759 */
760extern int gma_intel_opregion_init(struct drm_device *dev);
761extern int gma_intel_opregion_exit(struct drm_device *dev);
762
763/*
764 * framebuffer.c
765 */
766extern int psbfb_probed(struct drm_device *dev);
767extern int psbfb_remove(struct drm_device *dev,
768 struct drm_framebuffer *fb);
769/*
770 * accel_2d.c
771 */
772extern void psbfb_copyarea(struct fb_info *info,
773 const struct fb_copyarea *region);
774extern int psbfb_sync(struct fb_info *info);
775extern void psb_spank(struct drm_psb_private *dev_priv);
776
777/*
778 * psb_reset.c
779 */
780
781extern void psb_lid_timer_init(struct drm_psb_private *dev_priv);
782extern void psb_lid_timer_takedown(struct drm_psb_private *dev_priv);
783extern void psb_print_pagefault(struct drm_psb_private *dev_priv);
784
785/* modesetting */
786extern void psb_modeset_init(struct drm_device *dev);
787extern void psb_modeset_cleanup(struct drm_device *dev);
788extern int psb_fbdev_init(struct drm_device *dev);
789
790/* backlight.c */
791int gma_backlight_init(struct drm_device *dev);
792void gma_backlight_exit(struct drm_device *dev);
793
794/* oaktrail_crtc.c */
795extern const struct drm_crtc_helper_funcs oaktrail_helper_funcs;
796
797/* oaktrail_lvds.c */
798extern void oaktrail_lvds_init(struct drm_device *dev,
799 struct psb_intel_mode_device *mode_dev);
800
801/* psb_intel_display.c */
802extern const struct drm_crtc_helper_funcs psb_intel_helper_funcs;
803extern const struct drm_crtc_funcs psb_intel_crtc_funcs;
804
805/* psb_intel_lvds.c */
806extern const struct drm_connector_helper_funcs
807 psb_intel_lvds_connector_helper_funcs;
808extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs;
809
810/* gem.c */
811extern int psb_gem_init_object(struct drm_gem_object *obj);
812extern void psb_gem_free_object(struct drm_gem_object *obj);
813extern int psb_gem_get_aperture(struct drm_device *dev, void *data,
814 struct drm_file *file);
815extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
816 struct drm_mode_create_dumb *args);
817extern int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
818 uint32_t handle);
819extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
820 uint32_t handle, uint64_t *offset);
821extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
822extern int psb_gem_create_ioctl(struct drm_device *dev, void *data,
823 struct drm_file *file);
824extern int psb_gem_mmap_ioctl(struct drm_device *dev, void *data,
825 struct drm_file *file);
826
827/* psb_device.c */
828extern const struct psb_ops psb_chip_ops;
829
830/* oaktrail_device.c */
831extern const struct psb_ops oaktrail_chip_ops;
832
833/* cdv_device.c */
834extern const struct psb_ops cdv_chip_ops;
835
836/*
837 * Debug print bits setting
838 */
839#define PSB_D_GENERAL (1 << 0)
840#define PSB_D_INIT (1 << 1)
841#define PSB_D_IRQ (1 << 2)
842#define PSB_D_ENTRY (1 << 3)
843/* debug the get H/V BP/FP count */
844#define PSB_D_HV (1 << 4)
845#define PSB_D_DBI_BF (1 << 5)
846#define PSB_D_PM (1 << 6)
847#define PSB_D_RENDER (1 << 7)
848#define PSB_D_REG (1 << 8)
849#define PSB_D_MSVDX (1 << 9)
850#define PSB_D_TOPAZ (1 << 10)
851
852extern int drm_psb_no_fb;
853extern int drm_idle_check_interval;
854
855/*
856 * Utilities
857 */
858
859static inline u32 MRST_MSG_READ32(uint port, uint offset)
860{
861 int mcr = (0xD0<<24) | (port << 16) | (offset << 8);
862 uint32_t ret_val = 0;
863 struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
864 pci_write_config_dword(pci_root, 0xD0, mcr);
865 pci_read_config_dword(pci_root, 0xD4, &ret_val);
866 pci_dev_put(pci_root);
867 return ret_val;
868}
869static inline void MRST_MSG_WRITE32(uint port, uint offset, u32 value)
870{
871 int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0;
872 struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
873 pci_write_config_dword(pci_root, 0xD4, value);
874 pci_write_config_dword(pci_root, 0xD0, mcr);
875 pci_dev_put(pci_root);
876}
877static inline u32 MDFLD_MSG_READ32(uint port, uint offset)
878{
879 int mcr = (0x10<<24) | (port << 16) | (offset << 8);
880 uint32_t ret_val = 0;
881 struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
882 pci_write_config_dword(pci_root, 0xD0, mcr);
883 pci_read_config_dword(pci_root, 0xD4, &ret_val);
884 pci_dev_put(pci_root);
885 return ret_val;
886}
887static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value)
888{
889 int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
890 struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
891 pci_write_config_dword(pci_root, 0xD4, value);
892 pci_write_config_dword(pci_root, 0xD0, mcr);
893 pci_dev_put(pci_root);
894}
895
896static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg)
897{
898 struct drm_psb_private *dev_priv = dev->dev_private;
899 return ioread32(dev_priv->vdc_reg + reg);
900}
901
902#define REG_READ(reg) REGISTER_READ(dev, (reg))
903
904static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg,
905 uint32_t val)
906{
907 struct drm_psb_private *dev_priv = dev->dev_private;
908 iowrite32((val), dev_priv->vdc_reg + (reg));
909}
910
911#define REG_WRITE(reg, val) REGISTER_WRITE(dev, (reg), (val))
912
913static inline void REGISTER_WRITE16(struct drm_device *dev,
914 uint32_t reg, uint32_t val)
915{
916 struct drm_psb_private *dev_priv = dev->dev_private;
917 iowrite16((val), dev_priv->vdc_reg + (reg));
918}
919
920#define REG_WRITE16(reg, val) REGISTER_WRITE16(dev, (reg), (val))
921
922static inline void REGISTER_WRITE8(struct drm_device *dev,
923 uint32_t reg, uint32_t val)
924{
925 struct drm_psb_private *dev_priv = dev->dev_private;
926 iowrite8((val), dev_priv->vdc_reg + (reg));
927}
928
929#define REG_WRITE8(reg, val) REGISTER_WRITE8(dev, (reg), (val))
930
931#define PSB_WVDC32(_val, _offs) iowrite32(_val, dev_priv->vdc_reg + (_offs))
932#define PSB_RVDC32(_offs) ioread32(dev_priv->vdc_reg + (_offs))
933
934/* #define TRAP_SGX_PM_FAULT 1 */
935#ifdef TRAP_SGX_PM_FAULT
936#define PSB_RSGX32(_offs) \
937({ \
938 if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) { \
939 printk(KERN_ERR \
940 "access sgx when it's off!! (READ) %s, %d\n", \
941 __FILE__, __LINE__); \
942 melay(1000); \
943 } \
944 ioread32(dev_priv->sgx_reg + (_offs)); \
945})
946#else
947#define PSB_RSGX32(_offs) ioread32(dev_priv->sgx_reg + (_offs))
948#endif
949#define PSB_WSGX32(_val, _offs) iowrite32(_val, dev_priv->sgx_reg + (_offs))
950
951#define MSVDX_REG_DUMP 0
952
953#define PSB_WMSVDX32(_val, _offs) iowrite32(_val, dev_priv->msvdx_reg + (_offs))
954#define PSB_RMSVDX32(_offs) ioread32(dev_priv->msvdx_reg + (_offs))
955
956#endif
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c
new file mode 100644
index 00000000000..49e983508d5
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_intel_display.c
@@ -0,0 +1,1446 @@
1/*
2 * Copyright © 2006-2011 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 */
20
21#include <linux/i2c.h>
22#include <linux/pm_runtime.h>
23
24#include <drm/drmP.h>
25#include "framebuffer.h"
26#include "psb_drv.h"
27#include "psb_intel_drv.h"
28#include "psb_intel_reg.h"
29#include "psb_intel_display.h"
30#include "power.h"
31
32struct psb_intel_clock_t {
33 /* given values */
34 int n;
35 int m1, m2;
36 int p1, p2;
37 /* derived values */
38 int dot;
39 int vco;
40 int m;
41 int p;
42};
43
44struct psb_intel_range_t {
45 int min, max;
46};
47
48struct psb_intel_p2_t {
49 int dot_limit;
50 int p2_slow, p2_fast;
51};
52
53#define INTEL_P2_NUM 2
54
55struct psb_intel_limit_t {
56 struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1;
57 struct psb_intel_p2_t p2;
58};
59
60#define I8XX_DOT_MIN 25000
61#define I8XX_DOT_MAX 350000
62#define I8XX_VCO_MIN 930000
63#define I8XX_VCO_MAX 1400000
64#define I8XX_N_MIN 3
65#define I8XX_N_MAX 16
66#define I8XX_M_MIN 96
67#define I8XX_M_MAX 140
68#define I8XX_M1_MIN 18
69#define I8XX_M1_MAX 26
70#define I8XX_M2_MIN 6
71#define I8XX_M2_MAX 16
72#define I8XX_P_MIN 4
73#define I8XX_P_MAX 128
74#define I8XX_P1_MIN 2
75#define I8XX_P1_MAX 33
76#define I8XX_P1_LVDS_MIN 1
77#define I8XX_P1_LVDS_MAX 6
78#define I8XX_P2_SLOW 4
79#define I8XX_P2_FAST 2
80#define I8XX_P2_LVDS_SLOW 14
81#define I8XX_P2_LVDS_FAST 14 /* No fast option */
82#define I8XX_P2_SLOW_LIMIT 165000
83
84#define I9XX_DOT_MIN 20000
85#define I9XX_DOT_MAX 400000
86#define I9XX_VCO_MIN 1400000
87#define I9XX_VCO_MAX 2800000
88#define I9XX_N_MIN 3
89#define I9XX_N_MAX 8
90#define I9XX_M_MIN 70
91#define I9XX_M_MAX 120
92#define I9XX_M1_MIN 10
93#define I9XX_M1_MAX 20
94#define I9XX_M2_MIN 5
95#define I9XX_M2_MAX 9
96#define I9XX_P_SDVO_DAC_MIN 5
97#define I9XX_P_SDVO_DAC_MAX 80
98#define I9XX_P_LVDS_MIN 7
99#define I9XX_P_LVDS_MAX 98
100#define I9XX_P1_MIN 1
101#define I9XX_P1_MAX 8
102#define I9XX_P2_SDVO_DAC_SLOW 10
103#define I9XX_P2_SDVO_DAC_FAST 5
104#define I9XX_P2_SDVO_DAC_SLOW_LIMIT 200000
105#define I9XX_P2_LVDS_SLOW 14
106#define I9XX_P2_LVDS_FAST 7
107#define I9XX_P2_LVDS_SLOW_LIMIT 112000
108
109#define INTEL_LIMIT_I8XX_DVO_DAC 0
110#define INTEL_LIMIT_I8XX_LVDS 1
111#define INTEL_LIMIT_I9XX_SDVO_DAC 2
112#define INTEL_LIMIT_I9XX_LVDS 3
113
114static const struct psb_intel_limit_t psb_intel_limits[] = {
115 { /* INTEL_LIMIT_I8XX_DVO_DAC */
116 .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
117 .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
118 .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
119 .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
120 .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
121 .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
122 .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
123 .p1 = {.min = I8XX_P1_MIN, .max = I8XX_P1_MAX},
124 .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
125 .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST},
126 },
127 { /* INTEL_LIMIT_I8XX_LVDS */
128 .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
129 .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
130 .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
131 .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
132 .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
133 .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
134 .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
135 .p1 = {.min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX},
136 .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
137 .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST},
138 },
139 { /* INTEL_LIMIT_I9XX_SDVO_DAC */
140 .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
141 .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX},
142 .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX},
143 .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX},
144 .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX},
145 .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX},
146 .p = {.min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX},
147 .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX},
148 .p2 = {.dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
149 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast =
150 I9XX_P2_SDVO_DAC_FAST},
151 },
152 { /* INTEL_LIMIT_I9XX_LVDS */
153 .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
154 .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX},
155 .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX},
156 .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX},
157 .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX},
158 .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX},
159 .p = {.min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX},
160 .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX},
161 /* The single-channel range is 25-112Mhz, and dual-channel
162 * is 80-224Mhz. Prefer single channel as much as possible.
163 */
164 .p2 = {.dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
165 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST},
166 },
167};
168
169static const struct psb_intel_limit_t *psb_intel_limit(struct drm_crtc *crtc)
170{
171 const struct psb_intel_limit_t *limit;
172
173 if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
174 limit = &psb_intel_limits[INTEL_LIMIT_I9XX_LVDS];
175 else
176 limit = &psb_intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
177 return limit;
178}
179
180/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
181
182static void i8xx_clock(int refclk, struct psb_intel_clock_t *clock)
183{
184 clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
185 clock->p = clock->p1 * clock->p2;
186 clock->vco = refclk * clock->m / (clock->n + 2);
187 clock->dot = clock->vco / clock->p;
188}
189
190/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */
191
192static void i9xx_clock(int refclk, struct psb_intel_clock_t *clock)
193{
194 clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
195 clock->p = clock->p1 * clock->p2;
196 clock->vco = refclk * clock->m / (clock->n + 2);
197 clock->dot = clock->vco / clock->p;
198}
199
200static void psb_intel_clock(struct drm_device *dev, int refclk,
201 struct psb_intel_clock_t *clock)
202{
203 return i9xx_clock(refclk, clock);
204}
205
206/**
207 * Returns whether any output on the specified pipe is of the specified type
208 */
209bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type)
210{
211 struct drm_device *dev = crtc->dev;
212 struct drm_mode_config *mode_config = &dev->mode_config;
213 struct drm_connector *l_entry;
214
215 list_for_each_entry(l_entry, &mode_config->connector_list, head) {
216 if (l_entry->encoder && l_entry->encoder->crtc == crtc) {
217 struct psb_intel_encoder *psb_intel_encoder =
218 psb_intel_attached_encoder(l_entry);
219 if (psb_intel_encoder->type == type)
220 return true;
221 }
222 }
223 return false;
224}
225
226#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; }
227/**
228 * Returns whether the given set of divisors are valid for a given refclk with
229 * the given connectors.
230 */
231
232static bool psb_intel_PLL_is_valid(struct drm_crtc *crtc,
233 struct psb_intel_clock_t *clock)
234{
235 const struct psb_intel_limit_t *limit = psb_intel_limit(crtc);
236
237 if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
238 INTELPllInvalid("p1 out of range\n");
239 if (clock->p < limit->p.min || limit->p.max < clock->p)
240 INTELPllInvalid("p out of range\n");
241 if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
242 INTELPllInvalid("m2 out of range\n");
243 if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
244 INTELPllInvalid("m1 out of range\n");
245 if (clock->m1 <= clock->m2)
246 INTELPllInvalid("m1 <= m2\n");
247 if (clock->m < limit->m.min || limit->m.max < clock->m)
248 INTELPllInvalid("m out of range\n");
249 if (clock->n < limit->n.min || limit->n.max < clock->n)
250 INTELPllInvalid("n out of range\n");
251 if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
252 INTELPllInvalid("vco out of range\n");
253 /* XXX: We may need to be checking "Dot clock"
254 * depending on the multiplier, connector, etc.,
255 * rather than just a single range.
256 */
257 if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
258 INTELPllInvalid("dot out of range\n");
259
260 return true;
261}
262
263/**
264 * Returns a set of divisors for the desired target clock with the given
265 * refclk, or FALSE. The returned values represent the clock equation:
266 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
267 */
268static bool psb_intel_find_best_PLL(struct drm_crtc *crtc, int target,
269 int refclk,
270 struct psb_intel_clock_t *best_clock)
271{
272 struct drm_device *dev = crtc->dev;
273 struct psb_intel_clock_t clock;
274 const struct psb_intel_limit_t *limit = psb_intel_limit(crtc);
275 int err = target;
276
277 if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
278 (REG_READ(LVDS) & LVDS_PORT_EN) != 0) {
279 /*
280 * For LVDS, if the panel is on, just rely on its current
281 * settings for dual-channel. We haven't figured out how to
282 * reliably set up different single/dual channel state, if we
283 * even can.
284 */
285 if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
286 LVDS_CLKB_POWER_UP)
287 clock.p2 = limit->p2.p2_fast;
288 else
289 clock.p2 = limit->p2.p2_slow;
290 } else {
291 if (target < limit->p2.dot_limit)
292 clock.p2 = limit->p2.p2_slow;
293 else
294 clock.p2 = limit->p2.p2_fast;
295 }
296
297 memset(best_clock, 0, sizeof(*best_clock));
298
299 for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
300 clock.m1++) {
301 for (clock.m2 = limit->m2.min;
302 clock.m2 < clock.m1 && clock.m2 <= limit->m2.max;
303 clock.m2++) {
304 for (clock.n = limit->n.min;
305 clock.n <= limit->n.max; clock.n++) {
306 for (clock.p1 = limit->p1.min;
307 clock.p1 <= limit->p1.max;
308 clock.p1++) {
309 int this_err;
310
311 psb_intel_clock(dev, refclk, &clock);
312
313 if (!psb_intel_PLL_is_valid
314 (crtc, &clock))
315 continue;
316
317 this_err = abs(clock.dot - target);
318 if (this_err < err) {
319 *best_clock = clock;
320 err = this_err;
321 }
322 }
323 }
324 }
325 }
326
327 return err != target;
328}
329
330void psb_intel_wait_for_vblank(struct drm_device *dev)
331{
332 /* Wait for 20ms, i.e. one cycle at 50hz. */
333 mdelay(20);
334}
335
336int psb_intel_pipe_set_base(struct drm_crtc *crtc,
337 int x, int y, struct drm_framebuffer *old_fb)
338{
339 struct drm_device *dev = crtc->dev;
340 /* struct drm_i915_master_private *master_priv; */
341 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
342 struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
343 int pipe = psb_intel_crtc->pipe;
344 unsigned long start, offset;
345 int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
346 int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
347 int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
348 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
349 u32 dspcntr;
350 int ret = 0;
351
352 if (!gma_power_begin(dev, true))
353 return 0;
354
355 /* no fb bound */
356 if (!crtc->fb) {
357 dev_dbg(dev->dev, "No FB bound\n");
358 goto psb_intel_pipe_cleaner;
359 }
360
361 /* We are displaying this buffer, make sure it is actually loaded
362 into the GTT */
363 ret = psb_gtt_pin(psbfb->gtt);
364 if (ret < 0)
365 goto psb_intel_pipe_set_base_exit;
366 start = psbfb->gtt->offset;
367
368 offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
369
370 REG_WRITE(dspstride, crtc->fb->pitches[0]);
371
372 dspcntr = REG_READ(dspcntr_reg);
373 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
374
375 switch (crtc->fb->bits_per_pixel) {
376 case 8:
377 dspcntr |= DISPPLANE_8BPP;
378 break;
379 case 16:
380 if (crtc->fb->depth == 15)
381 dspcntr |= DISPPLANE_15_16BPP;
382 else
383 dspcntr |= DISPPLANE_16BPP;
384 break;
385 case 24:
386 case 32:
387 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
388 break;
389 default:
390 dev_err(dev->dev, "Unknown color depth\n");
391 ret = -EINVAL;
392 psb_gtt_unpin(psbfb->gtt);
393 goto psb_intel_pipe_set_base_exit;
394 }
395 REG_WRITE(dspcntr_reg, dspcntr);
396
397
398 if (0 /* FIXMEAC - check what PSB needs */) {
399 REG_WRITE(dspbase, offset);
400 REG_READ(dspbase);
401 REG_WRITE(dspsurf, start);
402 REG_READ(dspsurf);
403 } else {
404 REG_WRITE(dspbase, start + offset);
405 REG_READ(dspbase);
406 }
407
408psb_intel_pipe_cleaner:
409 /* If there was a previous display we can now unpin it */
410 if (old_fb)
411 psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
412
413psb_intel_pipe_set_base_exit:
414 gma_power_end(dev);
415 return ret;
416}
417
418/**
419 * Sets the power management mode of the pipe and plane.
420 *
421 * This code should probably grow support for turning the cursor off and back
422 * on appropriately at the same time as we're turning the pipe off/on.
423 */
424static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
425{
426 struct drm_device *dev = crtc->dev;
427 /* struct drm_i915_master_private *master_priv; */
428 /* struct drm_i915_private *dev_priv = dev->dev_private; */
429 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
430 int pipe = psb_intel_crtc->pipe;
431 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
432 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
433 int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
434 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
435 u32 temp;
436 bool enabled;
437
438 /* XXX: When our outputs are all unaware of DPMS modes other than off
439 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
440 */
441 switch (mode) {
442 case DRM_MODE_DPMS_ON:
443 case DRM_MODE_DPMS_STANDBY:
444 case DRM_MODE_DPMS_SUSPEND:
445 /* Enable the DPLL */
446 temp = REG_READ(dpll_reg);
447 if ((temp & DPLL_VCO_ENABLE) == 0) {
448 REG_WRITE(dpll_reg, temp);
449 REG_READ(dpll_reg);
450 /* Wait for the clocks to stabilize. */
451 udelay(150);
452 REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
453 REG_READ(dpll_reg);
454 /* Wait for the clocks to stabilize. */
455 udelay(150);
456 REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
457 REG_READ(dpll_reg);
458 /* Wait for the clocks to stabilize. */
459 udelay(150);
460 }
461
462 /* Enable the pipe */
463 temp = REG_READ(pipeconf_reg);
464 if ((temp & PIPEACONF_ENABLE) == 0)
465 REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
466
467 /* Enable the plane */
468 temp = REG_READ(dspcntr_reg);
469 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
470 REG_WRITE(dspcntr_reg,
471 temp | DISPLAY_PLANE_ENABLE);
472 /* Flush the plane changes */
473 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
474 }
475
476 psb_intel_crtc_load_lut(crtc);
477
478 /* Give the overlay scaler a chance to enable
479 * if it's on this pipe */
480 /* psb_intel_crtc_dpms_video(crtc, true); TODO */
481 break;
482 case DRM_MODE_DPMS_OFF:
483 /* Give the overlay scaler a chance to disable
484 * if it's on this pipe */
485 /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
486
487 /* Disable the VGA plane that we never use */
488 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
489
490 /* Disable display plane */
491 temp = REG_READ(dspcntr_reg);
492 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
493 REG_WRITE(dspcntr_reg,
494 temp & ~DISPLAY_PLANE_ENABLE);
495 /* Flush the plane changes */
496 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
497 REG_READ(dspbase_reg);
498 }
499
500 /* Next, disable display pipes */
501 temp = REG_READ(pipeconf_reg);
502 if ((temp & PIPEACONF_ENABLE) != 0) {
503 REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
504 REG_READ(pipeconf_reg);
505 }
506
507 /* Wait for vblank for the disable to take effect. */
508 psb_intel_wait_for_vblank(dev);
509
510 temp = REG_READ(dpll_reg);
511 if ((temp & DPLL_VCO_ENABLE) != 0) {
512 REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
513 REG_READ(dpll_reg);
514 }
515
516 /* Wait for the clocks to turn off. */
517 udelay(150);
518 break;
519 }
520
521 enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
522
523 /*Set FIFO Watermarks*/
524 REG_WRITE(DSPARB, 0x3F3E);
525}
526
527static void psb_intel_crtc_prepare(struct drm_crtc *crtc)
528{
529 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
530 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
531}
532
533static void psb_intel_crtc_commit(struct drm_crtc *crtc)
534{
535 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
536 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
537}
538
539void psb_intel_encoder_prepare(struct drm_encoder *encoder)
540{
541 struct drm_encoder_helper_funcs *encoder_funcs =
542 encoder->helper_private;
543 /* lvds has its own version of prepare see psb_intel_lvds_prepare */
544 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
545}
546
547void psb_intel_encoder_commit(struct drm_encoder *encoder)
548{
549 struct drm_encoder_helper_funcs *encoder_funcs =
550 encoder->helper_private;
551 /* lvds has its own version of commit see psb_intel_lvds_commit */
552 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
553}
554
555void psb_intel_encoder_destroy(struct drm_encoder *encoder)
556{
557 struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder);
558
559 drm_encoder_cleanup(encoder);
560 kfree(intel_encoder);
561}
562
563static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc,
564 struct drm_display_mode *mode,
565 struct drm_display_mode *adjusted_mode)
566{
567 return true;
568}
569
570
571/**
572 * Return the pipe currently connected to the panel fitter,
573 * or -1 if the panel fitter is not present or not in use
574 */
575static int psb_intel_panel_fitter_pipe(struct drm_device *dev)
576{
577 u32 pfit_control;
578
579 pfit_control = REG_READ(PFIT_CONTROL);
580
581 /* See if the panel fitter is in use */
582 if ((pfit_control & PFIT_ENABLE) == 0)
583 return -1;
584 /* Must be on PIPE 1 for PSB */
585 return 1;
586}
587
588static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
589 struct drm_display_mode *mode,
590 struct drm_display_mode *adjusted_mode,
591 int x, int y,
592 struct drm_framebuffer *old_fb)
593{
594 struct drm_device *dev = crtc->dev;
595 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
596 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
597 int pipe = psb_intel_crtc->pipe;
598 int fp_reg = (pipe == 0) ? FPA0 : FPB0;
599 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
600 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
601 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
602 int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
603 int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
604 int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
605 int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
606 int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
607 int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
608 int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
609 int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
610 int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
611 int refclk;
612 struct psb_intel_clock_t clock;
613 u32 dpll = 0, fp = 0, dspcntr, pipeconf;
614 bool ok, is_sdvo = false, is_dvo = false;
615 bool is_crt = false, is_lvds = false, is_tv = false;
616 struct drm_mode_config *mode_config = &dev->mode_config;
617 struct drm_connector *connector;
618
619 /* No scan out no play */
620 if (crtc->fb == NULL) {
621 crtc_funcs->mode_set_base(crtc, x, y, old_fb);
622 return 0;
623 }
624
625 list_for_each_entry(connector, &mode_config->connector_list, head) {
626 struct psb_intel_encoder *psb_intel_encoder =
627 psb_intel_attached_encoder(connector);
628
629 if (!connector->encoder
630 || connector->encoder->crtc != crtc)
631 continue;
632
633 switch (psb_intel_encoder->type) {
634 case INTEL_OUTPUT_LVDS:
635 is_lvds = true;
636 break;
637 case INTEL_OUTPUT_SDVO:
638 is_sdvo = true;
639 break;
640 case INTEL_OUTPUT_DVO:
641 is_dvo = true;
642 break;
643 case INTEL_OUTPUT_TVOUT:
644 is_tv = true;
645 break;
646 case INTEL_OUTPUT_ANALOG:
647 is_crt = true;
648 break;
649 }
650 }
651
652 refclk = 96000;
653
654 ok = psb_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk,
655 &clock);
656 if (!ok) {
657 dev_err(dev->dev, "Couldn't find PLL settings for mode!\n");
658 return 0;
659 }
660
661 fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
662
663 dpll = DPLL_VGA_MODE_DIS;
664 if (is_lvds) {
665 dpll |= DPLLB_MODE_LVDS;
666 dpll |= DPLL_DVO_HIGH_SPEED;
667 } else
668 dpll |= DPLLB_MODE_DAC_SERIAL;
669 if (is_sdvo) {
670 int sdvo_pixel_multiply =
671 adjusted_mode->clock / mode->clock;
672 dpll |= DPLL_DVO_HIGH_SPEED;
673 dpll |=
674 (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
675 }
676
677 /* compute bitmask from p1 value */
678 dpll |= (1 << (clock.p1 - 1)) << 16;
679 switch (clock.p2) {
680 case 5:
681 dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
682 break;
683 case 7:
684 dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
685 break;
686 case 10:
687 dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
688 break;
689 case 14:
690 dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
691 break;
692 }
693
694 if (is_tv) {
695 /* XXX: just matching BIOS for now */
696/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
697 dpll |= 3;
698 }
699 dpll |= PLL_REF_INPUT_DREFCLK;
700
701 /* setup pipeconf */
702 pipeconf = REG_READ(pipeconf_reg);
703
704 /* Set up the display plane register */
705 dspcntr = DISPPLANE_GAMMA_ENABLE;
706
707 if (pipe == 0)
708 dspcntr |= DISPPLANE_SEL_PIPE_A;
709 else
710 dspcntr |= DISPPLANE_SEL_PIPE_B;
711
712 dspcntr |= DISPLAY_PLANE_ENABLE;
713 pipeconf |= PIPEACONF_ENABLE;
714 dpll |= DPLL_VCO_ENABLE;
715
716
717 /* Disable the panel fitter if it was on our pipe */
718 if (psb_intel_panel_fitter_pipe(dev) == pipe)
719 REG_WRITE(PFIT_CONTROL, 0);
720
721 drm_mode_debug_printmodeline(mode);
722
723 if (dpll & DPLL_VCO_ENABLE) {
724 REG_WRITE(fp_reg, fp);
725 REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
726 REG_READ(dpll_reg);
727 udelay(150);
728 }
729
730 /* The LVDS pin pair needs to be on before the DPLLs are enabled.
731 * This is an exception to the general rule that mode_set doesn't turn
732 * things on.
733 */
734 if (is_lvds) {
735 u32 lvds = REG_READ(LVDS);
736
737 lvds &= ~LVDS_PIPEB_SELECT;
738 if (pipe == 1)
739 lvds |= LVDS_PIPEB_SELECT;
740
741 lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
742 /* Set the B0-B3 data pairs corresponding to
743 * whether we're going to
744 * set the DPLLs for dual-channel mode or not.
745 */
746 lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
747 if (clock.p2 == 7)
748 lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
749
750 /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
751 * appropriately here, but we need to look more
752 * thoroughly into how panels behave in the two modes.
753 */
754
755 REG_WRITE(LVDS, lvds);
756 REG_READ(LVDS);
757 }
758
759 REG_WRITE(fp_reg, fp);
760 REG_WRITE(dpll_reg, dpll);
761 REG_READ(dpll_reg);
762 /* Wait for the clocks to stabilize. */
763 udelay(150);
764
765 /* write it again -- the BIOS does, after all */
766 REG_WRITE(dpll_reg, dpll);
767
768 REG_READ(dpll_reg);
769 /* Wait for the clocks to stabilize. */
770 udelay(150);
771
772 REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
773 ((adjusted_mode->crtc_htotal - 1) << 16));
774 REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
775 ((adjusted_mode->crtc_hblank_end - 1) << 16));
776 REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
777 ((adjusted_mode->crtc_hsync_end - 1) << 16));
778 REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
779 ((adjusted_mode->crtc_vtotal - 1) << 16));
780 REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
781 ((adjusted_mode->crtc_vblank_end - 1) << 16));
782 REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
783 ((adjusted_mode->crtc_vsync_end - 1) << 16));
784 /* pipesrc and dspsize control the size that is scaled from,
785 * which should always be the user's requested size.
786 */
787 REG_WRITE(dspsize_reg,
788 ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
789 REG_WRITE(dsppos_reg, 0);
790 REG_WRITE(pipesrc_reg,
791 ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
792 REG_WRITE(pipeconf_reg, pipeconf);
793 REG_READ(pipeconf_reg);
794
795 psb_intel_wait_for_vblank(dev);
796
797 REG_WRITE(dspcntr_reg, dspcntr);
798
799 /* Flush the plane changes */
800 crtc_funcs->mode_set_base(crtc, x, y, old_fb);
801
802 psb_intel_wait_for_vblank(dev);
803
804 return 0;
805}
806
807/** Loads the palette/gamma unit for the CRTC with the prepared values */
808void psb_intel_crtc_load_lut(struct drm_crtc *crtc)
809{
810 struct drm_device *dev = crtc->dev;
811 struct drm_psb_private *dev_priv =
812 (struct drm_psb_private *)dev->dev_private;
813 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
814 int palreg = PALETTE_A;
815 int i;
816
817 /* The clocks have to be on to load the palette. */
818 if (!crtc->enabled)
819 return;
820
821 switch (psb_intel_crtc->pipe) {
822 case 0:
823 break;
824 case 1:
825 palreg = PALETTE_B;
826 break;
827 case 2:
828 palreg = PALETTE_C;
829 break;
830 default:
831 dev_err(dev->dev, "Illegal Pipe Number.\n");
832 return;
833 }
834
835 if (gma_power_begin(dev, false)) {
836 for (i = 0; i < 256; i++) {
837 REG_WRITE(palreg + 4 * i,
838 ((psb_intel_crtc->lut_r[i] +
839 psb_intel_crtc->lut_adj[i]) << 16) |
840 ((psb_intel_crtc->lut_g[i] +
841 psb_intel_crtc->lut_adj[i]) << 8) |
842 (psb_intel_crtc->lut_b[i] +
843 psb_intel_crtc->lut_adj[i]));
844 }
845 gma_power_end(dev);
846 } else {
847 for (i = 0; i < 256; i++) {
848 dev_priv->save_palette_a[i] =
849 ((psb_intel_crtc->lut_r[i] +
850 psb_intel_crtc->lut_adj[i]) << 16) |
851 ((psb_intel_crtc->lut_g[i] +
852 psb_intel_crtc->lut_adj[i]) << 8) |
853 (psb_intel_crtc->lut_b[i] +
854 psb_intel_crtc->lut_adj[i]);
855 }
856
857 }
858}
859
860/**
861 * Save HW states of giving crtc
862 */
863static void psb_intel_crtc_save(struct drm_crtc *crtc)
864{
865 struct drm_device *dev = crtc->dev;
866 /* struct drm_psb_private *dev_priv =
867 (struct drm_psb_private *)dev->dev_private; */
868 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
869 struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
870 int pipeA = (psb_intel_crtc->pipe == 0);
871 uint32_t paletteReg;
872 int i;
873
874 if (!crtc_state) {
875 dev_err(dev->dev, "No CRTC state found\n");
876 return;
877 }
878
879 crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR);
880 crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF);
881 crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC);
882 crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0);
883 crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1);
884 crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B);
885 crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B);
886 crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B);
887 crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B);
888 crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B);
889 crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B);
890 crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B);
891 crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE);
892
893 /*NOTE: DSPSIZE DSPPOS only for psb*/
894 crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE);
895 crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS);
896
897 crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE);
898
899 paletteReg = pipeA ? PALETTE_A : PALETTE_B;
900 for (i = 0; i < 256; ++i)
901 crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2));
902}
903
904/**
905 * Restore HW states of giving crtc
906 */
907static void psb_intel_crtc_restore(struct drm_crtc *crtc)
908{
909 struct drm_device *dev = crtc->dev;
910 /* struct drm_psb_private * dev_priv =
911 (struct drm_psb_private *)dev->dev_private; */
912 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
913 struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
914 /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */
915 int pipeA = (psb_intel_crtc->pipe == 0);
916 uint32_t paletteReg;
917 int i;
918
919 if (!crtc_state) {
920 dev_err(dev->dev, "No crtc state\n");
921 return;
922 }
923
924 if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) {
925 REG_WRITE(pipeA ? DPLL_A : DPLL_B,
926 crtc_state->saveDPLL & ~DPLL_VCO_ENABLE);
927 REG_READ(pipeA ? DPLL_A : DPLL_B);
928 udelay(150);
929 }
930
931 REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0);
932 REG_READ(pipeA ? FPA0 : FPB0);
933
934 REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1);
935 REG_READ(pipeA ? FPA1 : FPB1);
936
937 REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL);
938 REG_READ(pipeA ? DPLL_A : DPLL_B);
939 udelay(150);
940
941 REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL);
942 REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK);
943 REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC);
944 REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL);
945 REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK);
946 REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC);
947 REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE);
948
949 REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE);
950 REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS);
951
952 REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC);
953 REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
954 REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF);
955
956 psb_intel_wait_for_vblank(dev);
957
958 REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR);
959 REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
960
961 psb_intel_wait_for_vblank(dev);
962
963 paletteReg = pipeA ? PALETTE_A : PALETTE_B;
964 for (i = 0; i < 256; ++i)
965 REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]);
966}
967
968static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
969 struct drm_file *file_priv,
970 uint32_t handle,
971 uint32_t width, uint32_t height)
972{
973 struct drm_device *dev = crtc->dev;
974 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
975 int pipe = psb_intel_crtc->pipe;
976 uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
977 uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
978 uint32_t temp;
979 size_t addr = 0;
980 struct gtt_range *gt;
981 struct drm_gem_object *obj;
982 int ret;
983
984 /* if we want to turn of the cursor ignore width and height */
985 if (!handle) {
986 /* turn off the cursor */
987 temp = CURSOR_MODE_DISABLE;
988
989 if (gma_power_begin(dev, false)) {
990 REG_WRITE(control, temp);
991 REG_WRITE(base, 0);
992 gma_power_end(dev);
993 }
994
995 /* Unpin the old GEM object */
996 if (psb_intel_crtc->cursor_obj) {
997 gt = container_of(psb_intel_crtc->cursor_obj,
998 struct gtt_range, gem);
999 psb_gtt_unpin(gt);
1000 drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
1001 psb_intel_crtc->cursor_obj = NULL;
1002 }
1003
1004 return 0;
1005 }
1006
1007 /* Currently we only support 64x64 cursors */
1008 if (width != 64 || height != 64) {
1009 dev_dbg(dev->dev, "we currently only support 64x64 cursors\n");
1010 return -EINVAL;
1011 }
1012
1013 obj = drm_gem_object_lookup(dev, file_priv, handle);
1014 if (!obj)
1015 return -ENOENT;
1016
1017 if (obj->size < width * height * 4) {
1018 dev_dbg(dev->dev, "buffer is to small\n");
1019 return -ENOMEM;
1020 }
1021
1022 gt = container_of(obj, struct gtt_range, gem);
1023
1024 /* Pin the memory into the GTT */
1025 ret = psb_gtt_pin(gt);
1026 if (ret) {
1027 dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
1028 return ret;
1029 }
1030
1031
1032 addr = gt->offset; /* Or resource.start ??? */
1033
1034 psb_intel_crtc->cursor_addr = addr;
1035
1036 temp = 0;
1037 /* set the pipe for the cursor */
1038 temp |= (pipe << 28);
1039 temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
1040
1041 if (gma_power_begin(dev, false)) {
1042 REG_WRITE(control, temp);
1043 REG_WRITE(base, addr);
1044 gma_power_end(dev);
1045 }
1046
1047 /* unpin the old bo */
1048 if (psb_intel_crtc->cursor_obj) {
1049 gt = container_of(psb_intel_crtc->cursor_obj,
1050 struct gtt_range, gem);
1051 psb_gtt_unpin(gt);
1052 drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
1053 psb_intel_crtc->cursor_obj = obj;
1054 }
1055 return 0;
1056}
1057
1058static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
1059{
1060 struct drm_device *dev = crtc->dev;
1061 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1062 int pipe = psb_intel_crtc->pipe;
1063 uint32_t temp = 0;
1064 uint32_t addr;
1065
1066
1067 if (x < 0) {
1068 temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
1069 x = -x;
1070 }
1071 if (y < 0) {
1072 temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
1073 y = -y;
1074 }
1075
1076 temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
1077 temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
1078
1079 addr = psb_intel_crtc->cursor_addr;
1080
1081 if (gma_power_begin(dev, false)) {
1082 REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
1083 REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, addr);
1084 gma_power_end(dev);
1085 }
1086 return 0;
1087}
1088
1089void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
1090 u16 *green, u16 *blue, uint32_t type, uint32_t size)
1091{
1092 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1093 int i;
1094
1095 if (size != 256)
1096 return;
1097
1098 for (i = 0; i < 256; i++) {
1099 psb_intel_crtc->lut_r[i] = red[i] >> 8;
1100 psb_intel_crtc->lut_g[i] = green[i] >> 8;
1101 psb_intel_crtc->lut_b[i] = blue[i] >> 8;
1102 }
1103
1104 psb_intel_crtc_load_lut(crtc);
1105}
1106
1107static int psb_crtc_set_config(struct drm_mode_set *set)
1108{
1109 int ret;
1110 struct drm_device *dev = set->crtc->dev;
1111 struct drm_psb_private *dev_priv = dev->dev_private;
1112
1113 if (!dev_priv->rpm_enabled)
1114 return drm_crtc_helper_set_config(set);
1115
1116 pm_runtime_forbid(&dev->pdev->dev);
1117 ret = drm_crtc_helper_set_config(set);
1118 pm_runtime_allow(&dev->pdev->dev);
1119 return ret;
1120}
1121
1122/* Returns the clock of the currently programmed mode of the given pipe. */
1123static int psb_intel_crtc_clock_get(struct drm_device *dev,
1124 struct drm_crtc *crtc)
1125{
1126 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1127 int pipe = psb_intel_crtc->pipe;
1128 u32 dpll;
1129 u32 fp;
1130 struct psb_intel_clock_t clock;
1131 bool is_lvds;
1132 struct drm_psb_private *dev_priv = dev->dev_private;
1133
1134 if (gma_power_begin(dev, false)) {
1135 dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B);
1136 if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
1137 fp = REG_READ((pipe == 0) ? FPA0 : FPB0);
1138 else
1139 fp = REG_READ((pipe == 0) ? FPA1 : FPB1);
1140 is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN);
1141 gma_power_end(dev);
1142 } else {
1143 dpll = (pipe == 0) ?
1144 dev_priv->saveDPLL_A : dev_priv->saveDPLL_B;
1145
1146 if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
1147 fp = (pipe == 0) ?
1148 dev_priv->saveFPA0 :
1149 dev_priv->saveFPB0;
1150 else
1151 fp = (pipe == 0) ?
1152 dev_priv->saveFPA1 :
1153 dev_priv->saveFPB1;
1154
1155 is_lvds = (pipe == 1) && (dev_priv->saveLVDS & LVDS_PORT_EN);
1156 }
1157
1158 clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
1159 clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
1160 clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
1161
1162 if (is_lvds) {
1163 clock.p1 =
1164 ffs((dpll &
1165 DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
1166 DPLL_FPA01_P1_POST_DIV_SHIFT);
1167 clock.p2 = 14;
1168
1169 if ((dpll & PLL_REF_INPUT_MASK) ==
1170 PLLB_REF_INPUT_SPREADSPECTRUMIN) {
1171 /* XXX: might not be 66MHz */
1172 i8xx_clock(66000, &clock);
1173 } else
1174 i8xx_clock(48000, &clock);
1175 } else {
1176 if (dpll & PLL_P1_DIVIDE_BY_TWO)
1177 clock.p1 = 2;
1178 else {
1179 clock.p1 =
1180 ((dpll &
1181 DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
1182 DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
1183 }
1184 if (dpll & PLL_P2_DIVIDE_BY_4)
1185 clock.p2 = 4;
1186 else
1187 clock.p2 = 2;
1188
1189 i8xx_clock(48000, &clock);
1190 }
1191
1192 /* XXX: It would be nice to validate the clocks, but we can't reuse
1193 * i830PllIsValid() because it relies on the xf86_config connector
1194 * configuration being accurate, which it isn't necessarily.
1195 */
1196
1197 return clock.dot;
1198}
1199
1200/** Returns the currently programmed mode of the given pipe. */
1201struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
1202 struct drm_crtc *crtc)
1203{
1204 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1205 int pipe = psb_intel_crtc->pipe;
1206 struct drm_display_mode *mode;
1207 int htot;
1208 int hsync;
1209 int vtot;
1210 int vsync;
1211 struct drm_psb_private *dev_priv = dev->dev_private;
1212
1213 if (gma_power_begin(dev, false)) {
1214 htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
1215 hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
1216 vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
1217 vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
1218 gma_power_end(dev);
1219 } else {
1220 htot = (pipe == 0) ?
1221 dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B;
1222 hsync = (pipe == 0) ?
1223 dev_priv->saveHSYNC_A : dev_priv->saveHSYNC_B;
1224 vtot = (pipe == 0) ?
1225 dev_priv->saveVTOTAL_A : dev_priv->saveVTOTAL_B;
1226 vsync = (pipe == 0) ?
1227 dev_priv->saveVSYNC_A : dev_priv->saveVSYNC_B;
1228 }
1229
1230 mode = kzalloc(sizeof(*mode), GFP_KERNEL);
1231 if (!mode)
1232 return NULL;
1233
1234 mode->clock = psb_intel_crtc_clock_get(dev, crtc);
1235 mode->hdisplay = (htot & 0xffff) + 1;
1236 mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
1237 mode->hsync_start = (hsync & 0xffff) + 1;
1238 mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
1239 mode->vdisplay = (vtot & 0xffff) + 1;
1240 mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
1241 mode->vsync_start = (vsync & 0xffff) + 1;
1242 mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
1243
1244 drm_mode_set_name(mode);
1245 drm_mode_set_crtcinfo(mode, 0);
1246
1247 return mode;
1248}
1249
1250void psb_intel_crtc_destroy(struct drm_crtc *crtc)
1251{
1252 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1253 struct gtt_range *gt;
1254
1255 /* Unpin the old GEM object */
1256 if (psb_intel_crtc->cursor_obj) {
1257 gt = container_of(psb_intel_crtc->cursor_obj,
1258 struct gtt_range, gem);
1259 psb_gtt_unpin(gt);
1260 drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
1261 psb_intel_crtc->cursor_obj = NULL;
1262 }
1263 kfree(psb_intel_crtc->crtc_state);
1264 drm_crtc_cleanup(crtc);
1265 kfree(psb_intel_crtc);
1266}
1267
1268const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
1269 .dpms = psb_intel_crtc_dpms,
1270 .mode_fixup = psb_intel_crtc_mode_fixup,
1271 .mode_set = psb_intel_crtc_mode_set,
1272 .mode_set_base = psb_intel_pipe_set_base,
1273 .prepare = psb_intel_crtc_prepare,
1274 .commit = psb_intel_crtc_commit,
1275};
1276
1277const struct drm_crtc_funcs psb_intel_crtc_funcs = {
1278 .save = psb_intel_crtc_save,
1279 .restore = psb_intel_crtc_restore,
1280 .cursor_set = psb_intel_crtc_cursor_set,
1281 .cursor_move = psb_intel_crtc_cursor_move,
1282 .gamma_set = psb_intel_crtc_gamma_set,
1283 .set_config = psb_crtc_set_config,
1284 .destroy = psb_intel_crtc_destroy,
1285};
1286
1287/*
1288 * Set the default value of cursor control and base register
1289 * to zero. This is a workaround for h/w defect on Oaktrail
1290 */
1291static void psb_intel_cursor_init(struct drm_device *dev, int pipe)
1292{
1293 u32 control[3] = { CURACNTR, CURBCNTR, CURCCNTR };
1294 u32 base[3] = { CURABASE, CURBBASE, CURCBASE };
1295
1296 REG_WRITE(control[pipe], 0);
1297 REG_WRITE(base[pipe], 0);
1298}
1299
1300void psb_intel_crtc_init(struct drm_device *dev, int pipe,
1301 struct psb_intel_mode_device *mode_dev)
1302{
1303 struct drm_psb_private *dev_priv = dev->dev_private;
1304 struct psb_intel_crtc *psb_intel_crtc;
1305 int i;
1306 uint16_t *r_base, *g_base, *b_base;
1307
1308 /* We allocate a extra array of drm_connector pointers
1309 * for fbdev after the crtc */
1310 psb_intel_crtc =
1311 kzalloc(sizeof(struct psb_intel_crtc) +
1312 (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)),
1313 GFP_KERNEL);
1314 if (psb_intel_crtc == NULL)
1315 return;
1316
1317 psb_intel_crtc->crtc_state =
1318 kzalloc(sizeof(struct psb_intel_crtc_state), GFP_KERNEL);
1319 if (!psb_intel_crtc->crtc_state) {
1320 dev_err(dev->dev, "Crtc state error: No memory\n");
1321 kfree(psb_intel_crtc);
1322 return;
1323 }
1324
1325 /* Set the CRTC operations from the chip specific data */
1326 drm_crtc_init(dev, &psb_intel_crtc->base, dev_priv->ops->crtc_funcs);
1327
1328 drm_mode_crtc_set_gamma_size(&psb_intel_crtc->base, 256);
1329 psb_intel_crtc->pipe = pipe;
1330 psb_intel_crtc->plane = pipe;
1331
1332 r_base = psb_intel_crtc->base.gamma_store;
1333 g_base = r_base + 256;
1334 b_base = g_base + 256;
1335 for (i = 0; i < 256; i++) {
1336 psb_intel_crtc->lut_r[i] = i;
1337 psb_intel_crtc->lut_g[i] = i;
1338 psb_intel_crtc->lut_b[i] = i;
1339 r_base[i] = i << 8;
1340 g_base[i] = i << 8;
1341 b_base[i] = i << 8;
1342
1343 psb_intel_crtc->lut_adj[i] = 0;
1344 }
1345
1346 psb_intel_crtc->mode_dev = mode_dev;
1347 psb_intel_crtc->cursor_addr = 0;
1348
1349 drm_crtc_helper_add(&psb_intel_crtc->base,
1350 dev_priv->ops->crtc_helper);
1351
1352 /* Setup the array of drm_connector pointer array */
1353 psb_intel_crtc->mode_set.crtc = &psb_intel_crtc->base;
1354 BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
1355 dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] != NULL);
1356 dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] =
1357 &psb_intel_crtc->base;
1358 dev_priv->pipe_to_crtc_mapping[psb_intel_crtc->pipe] =
1359 &psb_intel_crtc->base;
1360 psb_intel_crtc->mode_set.connectors =
1361 (struct drm_connector **) (psb_intel_crtc + 1);
1362 psb_intel_crtc->mode_set.num_connectors = 0;
1363 psb_intel_cursor_init(dev, pipe);
1364}
1365
1366int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
1367 struct drm_file *file_priv)
1368{
1369 struct drm_psb_private *dev_priv = dev->dev_private;
1370 struct drm_psb_get_pipe_from_crtc_id_arg *pipe_from_crtc_id = data;
1371 struct drm_mode_object *drmmode_obj;
1372 struct psb_intel_crtc *crtc;
1373
1374 if (!dev_priv) {
1375 dev_err(dev->dev, "called with no initialization\n");
1376 return -EINVAL;
1377 }
1378
1379 drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id,
1380 DRM_MODE_OBJECT_CRTC);
1381
1382 if (!drmmode_obj) {
1383 dev_err(dev->dev, "no such CRTC id\n");
1384 return -EINVAL;
1385 }
1386
1387 crtc = to_psb_intel_crtc(obj_to_crtc(drmmode_obj));
1388 pipe_from_crtc_id->pipe = crtc->pipe;
1389
1390 return 0;
1391}
1392
1393struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
1394{
1395 struct drm_crtc *crtc = NULL;
1396
1397 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1398 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
1399 if (psb_intel_crtc->pipe == pipe)
1400 break;
1401 }
1402 return crtc;
1403}
1404
1405int psb_intel_connector_clones(struct drm_device *dev, int type_mask)
1406{
1407 int index_mask = 0;
1408 struct drm_connector *connector;
1409 int entry = 0;
1410
1411 list_for_each_entry(connector, &dev->mode_config.connector_list,
1412 head) {
1413 struct psb_intel_encoder *psb_intel_encoder =
1414 psb_intel_attached_encoder(connector);
1415 if (type_mask & (1 << psb_intel_encoder->type))
1416 index_mask |= (1 << entry);
1417 entry++;
1418 }
1419 return index_mask;
1420}
1421
1422
1423void psb_intel_modeset_cleanup(struct drm_device *dev)
1424{
1425 drm_mode_config_cleanup(dev);
1426}
1427
1428
1429/* current intel driver doesn't take advantage of encoders
1430 always give back the encoder for the connector
1431*/
1432struct drm_encoder *psb_intel_best_encoder(struct drm_connector *connector)
1433{
1434 struct psb_intel_encoder *psb_intel_encoder =
1435 psb_intel_attached_encoder(connector);
1436
1437 return &psb_intel_encoder->base;
1438}
1439
1440void psb_intel_connector_attach_encoder(struct psb_intel_connector *connector,
1441 struct psb_intel_encoder *encoder)
1442{
1443 connector->encoder = encoder;
1444 drm_mode_connector_attach_encoder(&connector->base,
1445 &encoder->base);
1446}
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.h b/drivers/gpu/drm/gma500/psb_intel_display.h
new file mode 100644
index 00000000000..535b49a5e40
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_intel_display.h
@@ -0,0 +1,28 @@
1/* copyright (c) 2008, Intel Corporation
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms and conditions of the GNU General Public License,
5 * version 2, as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope it will be useful, but WITHOUT
8 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
10 * more details.
11 *
12 * You should have received a copy of the GNU General Public License along with
13 * this program; if not, write to the Free Software Foundation, Inc.,
14 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
15 *
16 * Authors:
17 * Eric Anholt <eric@anholt.net>
18 */
19
20#ifndef _INTEL_DISPLAY_H_
21#define _INTEL_DISPLAY_H_
22
23bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type);
24void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
25 u16 *green, u16 *blue, uint32_t type, uint32_t size);
26void psb_intel_crtc_destroy(struct drm_crtc *crtc);
27
28#endif
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h
new file mode 100644
index 00000000000..f40535e5668
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_intel_drv.h
@@ -0,0 +1,289 @@
1/*
2 * Copyright (c) 2009-2011, 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
19#ifndef __INTEL_DRV_H__
20#define __INTEL_DRV_H__
21
22#include <linux/i2c.h>
23#include <linux/i2c-algo-bit.h>
24#include <drm/drm_crtc.h>
25#include <drm/drm_crtc_helper.h>
26#include <linux/gpio.h>
27
28/*
29 * Display related stuff
30 */
31
32/* store information about an Ixxx DVO */
33/* The i830->i865 use multiple DVOs with multiple i2cs */
34/* the i915, i945 have a single sDVO i2c bus - which is different */
35#define MAX_OUTPUTS 6
36/* maximum connectors per crtcs in the mode set */
37#define INTELFB_CONN_LIMIT 4
38
39#define INTEL_I2C_BUS_DVO 1
40#define INTEL_I2C_BUS_SDVO 2
41
42/* Intel Pipe Clone Bit */
43#define INTEL_HDMIB_CLONE_BIT 1
44#define INTEL_HDMIC_CLONE_BIT 2
45#define INTEL_HDMID_CLONE_BIT 3
46#define INTEL_HDMIE_CLONE_BIT 4
47#define INTEL_HDMIF_CLONE_BIT 5
48#define INTEL_SDVO_NON_TV_CLONE_BIT 6
49#define INTEL_SDVO_TV_CLONE_BIT 7
50#define INTEL_SDVO_LVDS_CLONE_BIT 8
51#define INTEL_ANALOG_CLONE_BIT 9
52#define INTEL_TV_CLONE_BIT 10
53#define INTEL_DP_B_CLONE_BIT 11
54#define INTEL_DP_C_CLONE_BIT 12
55#define INTEL_DP_D_CLONE_BIT 13
56#define INTEL_LVDS_CLONE_BIT 14
57#define INTEL_DVO_TMDS_CLONE_BIT 15
58#define INTEL_DVO_LVDS_CLONE_BIT 16
59#define INTEL_EDP_CLONE_BIT 17
60
61/* these are outputs from the chip - integrated only
62 * external chips are via DVO or SDVO output */
63#define INTEL_OUTPUT_UNUSED 0
64#define INTEL_OUTPUT_ANALOG 1
65#define INTEL_OUTPUT_DVO 2
66#define INTEL_OUTPUT_SDVO 3
67#define INTEL_OUTPUT_LVDS 4
68#define INTEL_OUTPUT_TVOUT 5
69#define INTEL_OUTPUT_HDMI 6
70#define INTEL_OUTPUT_MIPI 7
71#define INTEL_OUTPUT_MIPI2 8
72
73#define INTEL_DVO_CHIP_NONE 0
74#define INTEL_DVO_CHIP_LVDS 1
75#define INTEL_DVO_CHIP_TMDS 2
76#define INTEL_DVO_CHIP_TVOUT 4
77
78#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
79#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
80
81static inline void
82psb_intel_mode_set_pixel_multiplier(struct drm_display_mode *mode,
83 int multiplier)
84{
85 mode->clock *= multiplier;
86 mode->private_flags |= multiplier;
87}
88
89static inline int
90psb_intel_mode_get_pixel_multiplier(const struct drm_display_mode *mode)
91{
92 return (mode->private_flags & INTEL_MODE_PIXEL_MULTIPLIER_MASK)
93 >> INTEL_MODE_PIXEL_MULTIPLIER_SHIFT;
94}
95
96
97/*
98 * Hold information useally put on the device driver privates here,
99 * since it needs to be shared across multiple of devices drivers privates.
100 */
101struct psb_intel_mode_device {
102
103 /*
104 * Abstracted memory manager operations
105 */
106 size_t(*bo_offset) (struct drm_device *dev, void *bo);
107
108 /*
109 * Cursor (Can go ?)
110 */
111 int cursor_needs_physical;
112
113 /*
114 * LVDS info
115 */
116 int backlight_duty_cycle; /* restore backlight to this value */
117 bool panel_wants_dither;
118 struct drm_display_mode *panel_fixed_mode;
119 struct drm_display_mode *panel_fixed_mode2;
120 struct drm_display_mode *vbt_mode; /* if any */
121
122 uint32_t saveBLC_PWM_CTL;
123};
124
125struct psb_intel_i2c_chan {
126 /* for getting at dev. private (mmio etc.) */
127 struct drm_device *drm_dev;
128 u32 reg; /* GPIO reg */
129 struct i2c_adapter adapter;
130 struct i2c_algo_bit_data algo;
131 u8 slave_addr;
132};
133
134struct psb_intel_encoder {
135 struct drm_encoder base;
136 int type;
137 bool needs_tv_clock;
138 void (*hot_plug)(struct psb_intel_encoder *);
139 int crtc_mask;
140 int clone_mask;
141 void *dev_priv; /* For sdvo_priv, lvds_priv, etc... */
142
143 /* FIXME: Either make SDVO and LVDS store it's i2c here or give CDV it's
144 own set of output privates */
145 struct psb_intel_i2c_chan *i2c_bus;
146 struct psb_intel_i2c_chan *ddc_bus;
147};
148
149struct psb_intel_connector {
150 struct drm_connector base;
151 struct psb_intel_encoder *encoder;
152};
153
154struct psb_intel_crtc_state {
155 uint32_t saveDSPCNTR;
156 uint32_t savePIPECONF;
157 uint32_t savePIPESRC;
158 uint32_t saveDPLL;
159 uint32_t saveFP0;
160 uint32_t saveFP1;
161 uint32_t saveHTOTAL;
162 uint32_t saveHBLANK;
163 uint32_t saveHSYNC;
164 uint32_t saveVTOTAL;
165 uint32_t saveVBLANK;
166 uint32_t saveVSYNC;
167 uint32_t saveDSPSTRIDE;
168 uint32_t saveDSPSIZE;
169 uint32_t saveDSPPOS;
170 uint32_t saveDSPBASE;
171 uint32_t savePalette[256];
172};
173
174struct psb_intel_crtc {
175 struct drm_crtc base;
176 int pipe;
177 int plane;
178 uint32_t cursor_addr;
179 u8 lut_r[256], lut_g[256], lut_b[256];
180 u8 lut_adj[256];
181 struct psb_intel_framebuffer *fbdev_fb;
182 /* a mode_set for fbdev users on this crtc */
183 struct drm_mode_set mode_set;
184
185 /* GEM object that holds our cursor */
186 struct drm_gem_object *cursor_obj;
187
188 struct drm_display_mode saved_mode;
189 struct drm_display_mode saved_adjusted_mode;
190
191 struct psb_intel_mode_device *mode_dev;
192
193 /*crtc mode setting flags*/
194 u32 mode_flags;
195
196 /* Saved Crtc HW states */
197 struct psb_intel_crtc_state *crtc_state;
198};
199
200#define to_psb_intel_crtc(x) \
201 container_of(x, struct psb_intel_crtc, base)
202#define to_psb_intel_connector(x) \
203 container_of(x, struct psb_intel_connector, base)
204#define to_psb_intel_encoder(x) \
205 container_of(x, struct psb_intel_encoder, base)
206#define to_psb_intel_framebuffer(x) \
207 container_of(x, struct psb_intel_framebuffer, base)
208
209struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev,
210 const u32 reg, const char *name);
211void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan);
212int psb_intel_ddc_get_modes(struct drm_connector *connector,
213 struct i2c_adapter *adapter);
214extern bool psb_intel_ddc_probe(struct i2c_adapter *adapter);
215
216extern void psb_intel_crtc_init(struct drm_device *dev, int pipe,
217 struct psb_intel_mode_device *mode_dev);
218extern void psb_intel_crt_init(struct drm_device *dev);
219extern bool psb_intel_sdvo_init(struct drm_device *dev, int output_device);
220extern void psb_intel_dvo_init(struct drm_device *dev);
221extern void psb_intel_tv_init(struct drm_device *dev);
222extern void psb_intel_lvds_init(struct drm_device *dev,
223 struct psb_intel_mode_device *mode_dev);
224extern void psb_intel_lvds_set_brightness(struct drm_device *dev, int level);
225extern void oaktrail_lvds_init(struct drm_device *dev,
226 struct psb_intel_mode_device *mode_dev);
227extern void oaktrail_wait_for_INTR_PKT_SENT(struct drm_device *dev);
228extern void oaktrail_dsi_init(struct drm_device *dev,
229 struct psb_intel_mode_device *mode_dev);
230extern void mid_dsi_init(struct drm_device *dev,
231 struct psb_intel_mode_device *mode_dev, int dsi_num);
232
233extern void psb_intel_crtc_load_lut(struct drm_crtc *crtc);
234extern void psb_intel_encoder_prepare(struct drm_encoder *encoder);
235extern void psb_intel_encoder_commit(struct drm_encoder *encoder);
236extern void psb_intel_encoder_destroy(struct drm_encoder *encoder);
237
238static inline struct psb_intel_encoder *psb_intel_attached_encoder(
239 struct drm_connector *connector)
240{
241 return to_psb_intel_connector(connector)->encoder;
242}
243
244extern void psb_intel_connector_attach_encoder(
245 struct psb_intel_connector *connector,
246 struct psb_intel_encoder *encoder);
247
248extern struct drm_encoder *psb_intel_best_encoder(struct drm_connector
249 *connector);
250
251extern struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
252 struct drm_crtc *crtc);
253extern void psb_intel_wait_for_vblank(struct drm_device *dev);
254extern int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
255 struct drm_file *file_priv);
256extern struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev,
257 int pipe);
258extern struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev,
259 int sdvoB);
260extern int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector);
261extern void psb_intel_sdvo_set_hotplug(struct drm_connector *connector,
262 int enable);
263extern int intelfb_probe(struct drm_device *dev);
264extern int intelfb_remove(struct drm_device *dev,
265 struct drm_framebuffer *fb);
266extern struct drm_framebuffer *psb_intel_framebuffer_create(struct drm_device
267 *dev, struct
268 drm_mode_fb_cmd
269 *mode_cmd,
270 void *mm_private);
271extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
272 struct drm_display_mode *mode,
273 struct drm_display_mode *adjusted_mode);
274extern int psb_intel_lvds_mode_valid(struct drm_connector *connector,
275 struct drm_display_mode *mode);
276extern int psb_intel_lvds_set_property(struct drm_connector *connector,
277 struct drm_property *property,
278 uint64_t value);
279extern void psb_intel_lvds_destroy(struct drm_connector *connector);
280extern const struct drm_encoder_funcs psb_intel_lvds_enc_funcs;
281
282/* intel_gmbus.c */
283extern void gma_intel_i2c_reset(struct drm_device *dev);
284extern int gma_intel_setup_gmbus(struct drm_device *dev);
285extern void gma_intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed);
286extern void gma_intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit);
287extern void gma_intel_teardown_gmbus(struct drm_device *dev);
288
289#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c
new file mode 100644
index 00000000000..a25e4ca5e91
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c
@@ -0,0 +1,868 @@
1/*
2 * Copyright © 2006-2007 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
26#include "intel_bios.h"
27#include "psb_drv.h"
28#include "psb_intel_drv.h"
29#include "psb_intel_reg.h"
30#include "power.h"
31#include <linux/pm_runtime.h>
32
33/*
34 * LVDS I2C backlight control macros
35 */
36#define BRIGHTNESS_MAX_LEVEL 100
37#define BRIGHTNESS_MASK 0xFF
38#define BLC_I2C_TYPE 0x01
39#define BLC_PWM_TYPT 0x02
40
41#define BLC_POLARITY_NORMAL 0
42#define BLC_POLARITY_INVERSE 1
43
44#define PSB_BLC_MAX_PWM_REG_FREQ (0xFFFE)
45#define PSB_BLC_MIN_PWM_REG_FREQ (0x2)
46#define PSB_BLC_PWM_PRECISION_FACTOR (10)
47#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16)
48#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
49
50struct psb_intel_lvds_priv {
51 /*
52 * Saved LVDO output states
53 */
54 uint32_t savePP_ON;
55 uint32_t savePP_OFF;
56 uint32_t saveLVDS;
57 uint32_t savePP_CONTROL;
58 uint32_t savePP_CYCLE;
59 uint32_t savePFIT_CONTROL;
60 uint32_t savePFIT_PGM_RATIOS;
61 uint32_t saveBLC_PWM_CTL;
62
63 struct psb_intel_i2c_chan *i2c_bus;
64 struct psb_intel_i2c_chan *ddc_bus;
65};
66
67
68/*
69 * Returns the maximum level of the backlight duty cycle field.
70 */
71static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev)
72{
73 struct drm_psb_private *dev_priv = dev->dev_private;
74 u32 ret;
75
76 if (gma_power_begin(dev, false)) {
77 ret = REG_READ(BLC_PWM_CTL);
78 gma_power_end(dev);
79 } else /* Powered off, use the saved value */
80 ret = dev_priv->saveBLC_PWM_CTL;
81
82 /* Top 15bits hold the frequency mask */
83 ret = (ret & BACKLIGHT_MODULATION_FREQ_MASK) >>
84 BACKLIGHT_MODULATION_FREQ_SHIFT;
85
86 ret *= 2; /* Return a 16bit range as needed for setting */
87 if (ret == 0)
88 dev_err(dev->dev, "BL bug: Reg %08x save %08X\n",
89 REG_READ(BLC_PWM_CTL), dev_priv->saveBLC_PWM_CTL);
90 return ret;
91}
92
93/*
94 * Set LVDS backlight level by I2C command
95 *
96 * FIXME: at some point we need to both track this for PM and also
97 * disable runtime pm on MRST if the brightness is nil (ie blanked)
98 */
99static int psb_lvds_i2c_set_brightness(struct drm_device *dev,
100 unsigned int level)
101{
102 struct drm_psb_private *dev_priv =
103 (struct drm_psb_private *)dev->dev_private;
104
105 struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus;
106 u8 out_buf[2];
107 unsigned int blc_i2c_brightness;
108
109 struct i2c_msg msgs[] = {
110 {
111 .addr = lvds_i2c_bus->slave_addr,
112 .flags = 0,
113 .len = 2,
114 .buf = out_buf,
115 }
116 };
117
118 blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level *
119 BRIGHTNESS_MASK /
120 BRIGHTNESS_MAX_LEVEL);
121
122 if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
123 blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness;
124
125 out_buf[0] = dev_priv->lvds_bl->brightnesscmd;
126 out_buf[1] = (u8)blc_i2c_brightness;
127
128 if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) {
129 dev_dbg(dev->dev, "I2C set brightness.(command, value) (%d, %d)\n",
130 dev_priv->lvds_bl->brightnesscmd,
131 blc_i2c_brightness);
132 return 0;
133 }
134
135 dev_err(dev->dev, "I2C transfer error\n");
136 return -1;
137}
138
139
140static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level)
141{
142 struct drm_psb_private *dev_priv =
143 (struct drm_psb_private *)dev->dev_private;
144
145 u32 max_pwm_blc;
146 u32 blc_pwm_duty_cycle;
147
148 max_pwm_blc = psb_intel_lvds_get_max_backlight(dev);
149
150 /*BLC_PWM_CTL Should be initiated while backlight device init*/
151 BUG_ON(max_pwm_blc == 0);
152
153 blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL;
154
155 if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
156 blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle;
157
158 blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
159 REG_WRITE(BLC_PWM_CTL,
160 (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
161 (blc_pwm_duty_cycle));
162
163 dev_info(dev->dev, "Backlight lvds set brightness %08x\n",
164 (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
165 (blc_pwm_duty_cycle));
166
167 return 0;
168}
169
170/*
171 * Set LVDS backlight level either by I2C or PWM
172 */
173void psb_intel_lvds_set_brightness(struct drm_device *dev, int level)
174{
175 struct drm_psb_private *dev_priv = dev->dev_private;
176
177 dev_dbg(dev->dev, "backlight level is %d\n", level);
178
179 if (!dev_priv->lvds_bl) {
180 dev_err(dev->dev, "NO LVDS backlight info\n");
181 return;
182 }
183
184 if (dev_priv->lvds_bl->type == BLC_I2C_TYPE)
185 psb_lvds_i2c_set_brightness(dev, level);
186 else
187 psb_lvds_pwm_set_brightness(dev, level);
188}
189
190/*
191 * Sets the backlight level.
192 *
193 * level: backlight level, from 0 to psb_intel_lvds_get_max_backlight().
194 */
195static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level)
196{
197 struct drm_psb_private *dev_priv = dev->dev_private;
198 u32 blc_pwm_ctl;
199
200 if (gma_power_begin(dev, false)) {
201 blc_pwm_ctl = REG_READ(BLC_PWM_CTL);
202 blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
203 REG_WRITE(BLC_PWM_CTL,
204 (blc_pwm_ctl |
205 (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
206 dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
207 (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
208 gma_power_end(dev);
209 } else {
210 blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
211 ~BACKLIGHT_DUTY_CYCLE_MASK;
212 dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
213 (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
214 }
215}
216
217/*
218 * Sets the power state for the panel.
219 */
220static void psb_intel_lvds_set_power(struct drm_device *dev, bool on)
221{
222 struct drm_psb_private *dev_priv = dev->dev_private;
223 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
224 u32 pp_status;
225
226 if (!gma_power_begin(dev, true)) {
227 dev_err(dev->dev, "set power, chip off!\n");
228 return;
229 }
230
231 if (on) {
232 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
233 POWER_TARGET_ON);
234 do {
235 pp_status = REG_READ(PP_STATUS);
236 } while ((pp_status & PP_ON) == 0);
237
238 psb_intel_lvds_set_backlight(dev,
239 mode_dev->backlight_duty_cycle);
240 } else {
241 psb_intel_lvds_set_backlight(dev, 0);
242
243 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
244 ~POWER_TARGET_ON);
245 do {
246 pp_status = REG_READ(PP_STATUS);
247 } while (pp_status & PP_ON);
248 }
249
250 gma_power_end(dev);
251}
252
253static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
254{
255 struct drm_device *dev = encoder->dev;
256
257 if (mode == DRM_MODE_DPMS_ON)
258 psb_intel_lvds_set_power(dev, true);
259 else
260 psb_intel_lvds_set_power(dev, false);
261
262 /* XXX: We never power down the LVDS pairs. */
263}
264
265static void psb_intel_lvds_save(struct drm_connector *connector)
266{
267 struct drm_device *dev = connector->dev;
268 struct drm_psb_private *dev_priv =
269 (struct drm_psb_private *)dev->dev_private;
270 struct psb_intel_encoder *psb_intel_encoder =
271 psb_intel_attached_encoder(connector);
272 struct psb_intel_lvds_priv *lvds_priv =
273 (struct psb_intel_lvds_priv *)psb_intel_encoder->dev_priv;
274
275 lvds_priv->savePP_ON = REG_READ(LVDSPP_ON);
276 lvds_priv->savePP_OFF = REG_READ(LVDSPP_OFF);
277 lvds_priv->saveLVDS = REG_READ(LVDS);
278 lvds_priv->savePP_CONTROL = REG_READ(PP_CONTROL);
279 lvds_priv->savePP_CYCLE = REG_READ(PP_CYCLE);
280 /*lvds_priv->savePP_DIVISOR = REG_READ(PP_DIVISOR);*/
281 lvds_priv->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
282 lvds_priv->savePFIT_CONTROL = REG_READ(PFIT_CONTROL);
283 lvds_priv->savePFIT_PGM_RATIOS = REG_READ(PFIT_PGM_RATIOS);
284
285 /*TODO: move backlight_duty_cycle to psb_intel_lvds_priv*/
286 dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
287 BACKLIGHT_DUTY_CYCLE_MASK);
288
289 /*
290 * If the light is off at server startup,
291 * just make it full brightness
292 */
293 if (dev_priv->backlight_duty_cycle == 0)
294 dev_priv->backlight_duty_cycle =
295 psb_intel_lvds_get_max_backlight(dev);
296
297 dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
298 lvds_priv->savePP_ON,
299 lvds_priv->savePP_OFF,
300 lvds_priv->saveLVDS,
301 lvds_priv->savePP_CONTROL,
302 lvds_priv->savePP_CYCLE,
303 lvds_priv->saveBLC_PWM_CTL);
304}
305
306static void psb_intel_lvds_restore(struct drm_connector *connector)
307{
308 struct drm_device *dev = connector->dev;
309 u32 pp_status;
310 struct psb_intel_encoder *psb_intel_encoder =
311 psb_intel_attached_encoder(connector);
312 struct psb_intel_lvds_priv *lvds_priv =
313 (struct psb_intel_lvds_priv *)psb_intel_encoder->dev_priv;
314
315 dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
316 lvds_priv->savePP_ON,
317 lvds_priv->savePP_OFF,
318 lvds_priv->saveLVDS,
319 lvds_priv->savePP_CONTROL,
320 lvds_priv->savePP_CYCLE,
321 lvds_priv->saveBLC_PWM_CTL);
322
323 REG_WRITE(BLC_PWM_CTL, lvds_priv->saveBLC_PWM_CTL);
324 REG_WRITE(PFIT_CONTROL, lvds_priv->savePFIT_CONTROL);
325 REG_WRITE(PFIT_PGM_RATIOS, lvds_priv->savePFIT_PGM_RATIOS);
326 REG_WRITE(LVDSPP_ON, lvds_priv->savePP_ON);
327 REG_WRITE(LVDSPP_OFF, lvds_priv->savePP_OFF);
328 /*REG_WRITE(PP_DIVISOR, lvds_priv->savePP_DIVISOR);*/
329 REG_WRITE(PP_CYCLE, lvds_priv->savePP_CYCLE);
330 REG_WRITE(PP_CONTROL, lvds_priv->savePP_CONTROL);
331 REG_WRITE(LVDS, lvds_priv->saveLVDS);
332
333 if (lvds_priv->savePP_CONTROL & POWER_TARGET_ON) {
334 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
335 POWER_TARGET_ON);
336 do {
337 pp_status = REG_READ(PP_STATUS);
338 } while ((pp_status & PP_ON) == 0);
339 } else {
340 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
341 ~POWER_TARGET_ON);
342 do {
343 pp_status = REG_READ(PP_STATUS);
344 } while (pp_status & PP_ON);
345 }
346}
347
348int psb_intel_lvds_mode_valid(struct drm_connector *connector,
349 struct drm_display_mode *mode)
350{
351 struct drm_psb_private *dev_priv = connector->dev->dev_private;
352 struct psb_intel_encoder *psb_intel_encoder =
353 psb_intel_attached_encoder(connector);
354 struct drm_display_mode *fixed_mode =
355 dev_priv->mode_dev.panel_fixed_mode;
356
357 if (psb_intel_encoder->type == INTEL_OUTPUT_MIPI2)
358 fixed_mode = dev_priv->mode_dev.panel_fixed_mode2;
359
360 /* just in case */
361 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
362 return MODE_NO_DBLESCAN;
363
364 /* just in case */
365 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
366 return MODE_NO_INTERLACE;
367
368 if (fixed_mode) {
369 if (mode->hdisplay > fixed_mode->hdisplay)
370 return MODE_PANEL;
371 if (mode->vdisplay > fixed_mode->vdisplay)
372 return MODE_PANEL;
373 }
374 return MODE_OK;
375}
376
377bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
378 struct drm_display_mode *mode,
379 struct drm_display_mode *adjusted_mode)
380{
381 struct drm_device *dev = encoder->dev;
382 struct drm_psb_private *dev_priv = dev->dev_private;
383 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
384 struct psb_intel_crtc *psb_intel_crtc =
385 to_psb_intel_crtc(encoder->crtc);
386 struct drm_encoder *tmp_encoder;
387 struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;
388 struct psb_intel_encoder *psb_intel_encoder =
389 to_psb_intel_encoder(encoder);
390
391 if (psb_intel_encoder->type == INTEL_OUTPUT_MIPI2)
392 panel_fixed_mode = mode_dev->panel_fixed_mode2;
393
394 /* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */
395 if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) {
396 printk(KERN_ERR "Can't support LVDS on pipe A\n");
397 return false;
398 }
399 if (IS_MRST(dev) && psb_intel_crtc->pipe != 0) {
400 printk(KERN_ERR "Must use PIPE A\n");
401 return false;
402 }
403 /* Should never happen!! */
404 list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
405 head) {
406 if (tmp_encoder != encoder
407 && tmp_encoder->crtc == encoder->crtc) {
408 printk(KERN_ERR "Can't enable LVDS and another "
409 "encoder on the same pipe\n");
410 return false;
411 }
412 }
413
414 /*
415 * If we have timings from the BIOS for the panel, put them in
416 * to the adjusted mode. The CRTC will be set up for this mode,
417 * with the panel scaling set up to source from the H/VDisplay
418 * of the original mode.
419 */
420 if (panel_fixed_mode != NULL) {
421 adjusted_mode->hdisplay = panel_fixed_mode->hdisplay;
422 adjusted_mode->hsync_start = panel_fixed_mode->hsync_start;
423 adjusted_mode->hsync_end = panel_fixed_mode->hsync_end;
424 adjusted_mode->htotal = panel_fixed_mode->htotal;
425 adjusted_mode->vdisplay = panel_fixed_mode->vdisplay;
426 adjusted_mode->vsync_start = panel_fixed_mode->vsync_start;
427 adjusted_mode->vsync_end = panel_fixed_mode->vsync_end;
428 adjusted_mode->vtotal = panel_fixed_mode->vtotal;
429 adjusted_mode->clock = panel_fixed_mode->clock;
430 drm_mode_set_crtcinfo(adjusted_mode,
431 CRTC_INTERLACE_HALVE_V);
432 }
433
434 /*
435 * XXX: It would be nice to support lower refresh rates on the
436 * panels to reduce power consumption, and perhaps match the
437 * user's requested refresh rate.
438 */
439
440 return true;
441}
442
443static void psb_intel_lvds_prepare(struct drm_encoder *encoder)
444{
445 struct drm_device *dev = encoder->dev;
446 struct drm_psb_private *dev_priv = dev->dev_private;
447 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
448
449 if (!gma_power_begin(dev, true))
450 return;
451
452 mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
453 mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
454 BACKLIGHT_DUTY_CYCLE_MASK);
455
456 psb_intel_lvds_set_power(dev, false);
457
458 gma_power_end(dev);
459}
460
461static void psb_intel_lvds_commit(struct drm_encoder *encoder)
462{
463 struct drm_device *dev = encoder->dev;
464 struct drm_psb_private *dev_priv = dev->dev_private;
465 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
466
467 if (mode_dev->backlight_duty_cycle == 0)
468 mode_dev->backlight_duty_cycle =
469 psb_intel_lvds_get_max_backlight(dev);
470
471 psb_intel_lvds_set_power(dev, true);
472}
473
474static void psb_intel_lvds_mode_set(struct drm_encoder *encoder,
475 struct drm_display_mode *mode,
476 struct drm_display_mode *adjusted_mode)
477{
478 struct drm_device *dev = encoder->dev;
479 struct drm_psb_private *dev_priv = dev->dev_private;
480 u32 pfit_control;
481
482 /*
483 * The LVDS pin pair will already have been turned on in the
484 * psb_intel_crtc_mode_set since it has a large impact on the DPLL
485 * settings.
486 */
487
488 /*
489 * Enable automatic panel scaling so that non-native modes fill the
490 * screen. Should be enabled before the pipe is enabled, according to
491 * register description and PRM.
492 */
493 if (mode->hdisplay != adjusted_mode->hdisplay ||
494 mode->vdisplay != adjusted_mode->vdisplay)
495 pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
496 HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
497 HORIZ_INTERP_BILINEAR);
498 else
499 pfit_control = 0;
500
501 if (dev_priv->lvds_dither)
502 pfit_control |= PANEL_8TO6_DITHER_ENABLE;
503
504 REG_WRITE(PFIT_CONTROL, pfit_control);
505}
506
507/*
508 * Detect the LVDS connection.
509 *
510 * This always returns CONNECTOR_STATUS_CONNECTED.
511 * This connector should only have
512 * been set up if the LVDS was actually connected anyway.
513 */
514static enum drm_connector_status psb_intel_lvds_detect(struct drm_connector
515 *connector, bool force)
516{
517 return connector_status_connected;
518}
519
520/*
521 * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
522 */
523static int psb_intel_lvds_get_modes(struct drm_connector *connector)
524{
525 struct drm_device *dev = connector->dev;
526 struct drm_psb_private *dev_priv = dev->dev_private;
527 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
528 struct psb_intel_encoder *psb_intel_encoder =
529 psb_intel_attached_encoder(connector);
530 struct psb_intel_lvds_priv *lvds_priv = psb_intel_encoder->dev_priv;
531 int ret = 0;
532
533 if (!IS_MRST(dev))
534 ret = psb_intel_ddc_get_modes(connector, &lvds_priv->i2c_bus->adapter);
535
536 if (ret)
537 return ret;
538
539 /* Didn't get an EDID, so
540 * Set wide sync ranges so we get all modes
541 * handed to valid_mode for checking
542 */
543 connector->display_info.min_vfreq = 0;
544 connector->display_info.max_vfreq = 200;
545 connector->display_info.min_hfreq = 0;
546 connector->display_info.max_hfreq = 200;
547
548 if (mode_dev->panel_fixed_mode != NULL) {
549 struct drm_display_mode *mode =
550 drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
551 drm_mode_probed_add(connector, mode);
552 return 1;
553 }
554
555 return 0;
556}
557
558/**
559 * psb_intel_lvds_destroy - unregister and free LVDS structures
560 * @connector: connector to free
561 *
562 * Unregister the DDC bus for this connector then free the driver private
563 * structure.
564 */
565void psb_intel_lvds_destroy(struct drm_connector *connector)
566{
567 struct psb_intel_encoder *psb_intel_encoder =
568 psb_intel_attached_encoder(connector);
569 struct psb_intel_lvds_priv *lvds_priv = psb_intel_encoder->dev_priv;
570
571 if (lvds_priv->ddc_bus)
572 psb_intel_i2c_destroy(lvds_priv->ddc_bus);
573 drm_sysfs_connector_remove(connector);
574 drm_connector_cleanup(connector);
575 kfree(connector);
576}
577
578int psb_intel_lvds_set_property(struct drm_connector *connector,
579 struct drm_property *property,
580 uint64_t value)
581{
582 struct drm_encoder *encoder = connector->encoder;
583
584 if (!encoder)
585 return -1;
586
587 if (!strcmp(property->name, "scaling mode")) {
588 struct psb_intel_crtc *crtc =
589 to_psb_intel_crtc(encoder->crtc);
590 uint64_t curval;
591
592 if (!crtc)
593 goto set_prop_error;
594
595 switch (value) {
596 case DRM_MODE_SCALE_FULLSCREEN:
597 break;
598 case DRM_MODE_SCALE_NO_SCALE:
599 break;
600 case DRM_MODE_SCALE_ASPECT:
601 break;
602 default:
603 goto set_prop_error;
604 }
605
606 if (drm_connector_property_get_value(connector,
607 property,
608 &curval))
609 goto set_prop_error;
610
611 if (curval == value)
612 goto set_prop_done;
613
614 if (drm_connector_property_set_value(connector,
615 property,
616 value))
617 goto set_prop_error;
618
619 if (crtc->saved_mode.hdisplay != 0 &&
620 crtc->saved_mode.vdisplay != 0) {
621 if (!drm_crtc_helper_set_mode(encoder->crtc,
622 &crtc->saved_mode,
623 encoder->crtc->x,
624 encoder->crtc->y,
625 encoder->crtc->fb))
626 goto set_prop_error;
627 }
628 } else if (!strcmp(property->name, "backlight")) {
629 if (drm_connector_property_set_value(connector,
630 property,
631 value))
632 goto set_prop_error;
633 else {
634#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
635 struct drm_psb_private *devp =
636 encoder->dev->dev_private;
637 struct backlight_device *bd = devp->backlight_device;
638 if (bd) {
639 bd->props.brightness = value;
640 backlight_update_status(bd);
641 }
642#endif
643 }
644 } else if (!strcmp(property->name, "DPMS")) {
645 struct drm_encoder_helper_funcs *hfuncs
646 = encoder->helper_private;
647 hfuncs->dpms(encoder, value);
648 }
649
650set_prop_done:
651 return 0;
652set_prop_error:
653 return -1;
654}
655
656static const struct drm_encoder_helper_funcs psb_intel_lvds_helper_funcs = {
657 .dpms = psb_intel_lvds_encoder_dpms,
658 .mode_fixup = psb_intel_lvds_mode_fixup,
659 .prepare = psb_intel_lvds_prepare,
660 .mode_set = psb_intel_lvds_mode_set,
661 .commit = psb_intel_lvds_commit,
662};
663
664const struct drm_connector_helper_funcs
665 psb_intel_lvds_connector_helper_funcs = {
666 .get_modes = psb_intel_lvds_get_modes,
667 .mode_valid = psb_intel_lvds_mode_valid,
668 .best_encoder = psb_intel_best_encoder,
669};
670
671const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
672 .dpms = drm_helper_connector_dpms,
673 .save = psb_intel_lvds_save,
674 .restore = psb_intel_lvds_restore,
675 .detect = psb_intel_lvds_detect,
676 .fill_modes = drm_helper_probe_single_connector_modes,
677 .set_property = psb_intel_lvds_set_property,
678 .destroy = psb_intel_lvds_destroy,
679};
680
681
682static void psb_intel_lvds_enc_destroy(struct drm_encoder *encoder)
683{
684 drm_encoder_cleanup(encoder);
685}
686
687const struct drm_encoder_funcs psb_intel_lvds_enc_funcs = {
688 .destroy = psb_intel_lvds_enc_destroy,
689};
690
691
692
693/**
694 * psb_intel_lvds_init - setup LVDS connectors on this device
695 * @dev: drm device
696 *
697 * Create the connector, register the LVDS DDC bus, and try to figure out what
698 * modes we can display on the LVDS panel (if present).
699 */
700void psb_intel_lvds_init(struct drm_device *dev,
701 struct psb_intel_mode_device *mode_dev)
702{
703 struct psb_intel_encoder *psb_intel_encoder;
704 struct psb_intel_connector *psb_intel_connector;
705 struct psb_intel_lvds_priv *lvds_priv;
706 struct drm_connector *connector;
707 struct drm_encoder *encoder;
708 struct drm_display_mode *scan; /* *modes, *bios_mode; */
709 struct drm_crtc *crtc;
710 struct drm_psb_private *dev_priv = dev->dev_private;
711 u32 lvds;
712 int pipe;
713
714 psb_intel_encoder =
715 kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL);
716
717 if (!psb_intel_encoder) {
718 dev_err(dev->dev, "psb_intel_encoder allocation error\n");
719 return;
720 }
721
722 psb_intel_connector =
723 kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL);
724
725 if (!psb_intel_connector) {
726 kfree(psb_intel_encoder);
727 dev_err(dev->dev, "psb_intel_connector allocation error\n");
728 }
729
730 lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL);
731 if (!lvds_priv) {
732 dev_err(dev->dev, "LVDS private allocation error\n");
733 goto failed_connector;
734 }
735
736 psb_intel_encoder->dev_priv = lvds_priv;
737
738 connector = &psb_intel_connector->base;
739 encoder = &psb_intel_encoder->base;
740 drm_connector_init(dev, connector,
741 &psb_intel_lvds_connector_funcs,
742 DRM_MODE_CONNECTOR_LVDS);
743
744 drm_encoder_init(dev, encoder,
745 &psb_intel_lvds_enc_funcs,
746 DRM_MODE_ENCODER_LVDS);
747
748 psb_intel_connector_attach_encoder(psb_intel_connector,
749 psb_intel_encoder);
750 psb_intel_encoder->type = INTEL_OUTPUT_LVDS;
751
752 drm_encoder_helper_add(encoder, &psb_intel_lvds_helper_funcs);
753 drm_connector_helper_add(connector,
754 &psb_intel_lvds_connector_helper_funcs);
755 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
756 connector->interlace_allowed = false;
757 connector->doublescan_allowed = false;
758
759 /*Attach connector properties*/
760 drm_connector_attach_property(connector,
761 dev->mode_config.scaling_mode_property,
762 DRM_MODE_SCALE_FULLSCREEN);
763 drm_connector_attach_property(connector,
764 dev_priv->backlight_property,
765 BRIGHTNESS_MAX_LEVEL);
766
767 /*
768 * Set up I2C bus
769 * FIXME: distroy i2c_bus when exit
770 */
771 lvds_priv->i2c_bus = psb_intel_i2c_create(dev, GPIOB, "LVDSBLC_B");
772 if (!lvds_priv->i2c_bus) {
773 dev_printk(KERN_ERR,
774 &dev->pdev->dev, "I2C bus registration failed.\n");
775 goto failed_blc_i2c;
776 }
777 lvds_priv->i2c_bus->slave_addr = 0x2C;
778 dev_priv->lvds_i2c_bus = lvds_priv->i2c_bus;
779
780 /*
781 * LVDS discovery:
782 * 1) check for EDID on DDC
783 * 2) check for VBT data
784 * 3) check to see if LVDS is already on
785 * if none of the above, no panel
786 * 4) make sure lid is open
787 * if closed, act like it's not there for now
788 */
789
790 /* Set up the DDC bus. */
791 lvds_priv->ddc_bus = psb_intel_i2c_create(dev, GPIOC, "LVDSDDC_C");
792 if (!lvds_priv->ddc_bus) {
793 dev_printk(KERN_ERR, &dev->pdev->dev,
794 "DDC bus registration " "failed.\n");
795 goto failed_ddc;
796 }
797
798 /*
799 * Attempt to get the fixed panel mode from DDC. Assume that the
800 * preferred mode is the right one.
801 */
802 psb_intel_ddc_get_modes(connector, &lvds_priv->ddc_bus->adapter);
803 list_for_each_entry(scan, &connector->probed_modes, head) {
804 if (scan->type & DRM_MODE_TYPE_PREFERRED) {
805 mode_dev->panel_fixed_mode =
806 drm_mode_duplicate(dev, scan);
807 goto out; /* FIXME: check for quirks */
808 }
809 }
810
811 /* Failed to get EDID, what about VBT? do we need this? */
812 if (mode_dev->vbt_mode)
813 mode_dev->panel_fixed_mode =
814 drm_mode_duplicate(dev, mode_dev->vbt_mode);
815
816 if (!mode_dev->panel_fixed_mode)
817 if (dev_priv->lfp_lvds_vbt_mode)
818 mode_dev->panel_fixed_mode =
819 drm_mode_duplicate(dev,
820 dev_priv->lfp_lvds_vbt_mode);
821
822 /*
823 * If we didn't get EDID, try checking if the panel is already turned
824 * on. If so, assume that whatever is currently programmed is the
825 * correct mode.
826 */
827 lvds = REG_READ(LVDS);
828 pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
829 crtc = psb_intel_get_crtc_from_pipe(dev, pipe);
830
831 if (crtc && (lvds & LVDS_PORT_EN)) {
832 mode_dev->panel_fixed_mode =
833 psb_intel_crtc_mode_get(dev, crtc);
834 if (mode_dev->panel_fixed_mode) {
835 mode_dev->panel_fixed_mode->type |=
836 DRM_MODE_TYPE_PREFERRED;
837 goto out; /* FIXME: check for quirks */
838 }
839 }
840
841 /* If we still don't have a mode after all that, give up. */
842 if (!mode_dev->panel_fixed_mode) {
843 dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n");
844 goto failed_find;
845 }
846
847 /*
848 * Blacklist machines with BIOSes that list an LVDS panel without
849 * actually having one.
850 */
851out:
852 drm_sysfs_connector_add(connector);
853 return;
854
855failed_find:
856 if (lvds_priv->ddc_bus)
857 psb_intel_i2c_destroy(lvds_priv->ddc_bus);
858failed_ddc:
859 if (lvds_priv->i2c_bus)
860 psb_intel_i2c_destroy(lvds_priv->i2c_bus);
861failed_blc_i2c:
862 drm_encoder_cleanup(encoder);
863 drm_connector_cleanup(connector);
864failed_connector:
865 if (psb_intel_connector)
866 kfree(psb_intel_connector);
867}
868
diff --git a/drivers/gpu/drm/gma500/psb_intel_modes.c b/drivers/gpu/drm/gma500/psb_intel_modes.c
new file mode 100644
index 00000000000..4fca0d6feeb
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_intel_modes.c
@@ -0,0 +1,75 @@
1/*
2 * Copyright (c) 2007 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 * Authers: Jesse Barnes <jesse.barnes@intel.com>
18 */
19
20#include <linux/i2c.h>
21#include <linux/fb.h>
22#include <drm/drmP.h>
23#include "psb_intel_drv.h"
24
25/**
26 * psb_intel_ddc_probe
27 *
28 */
29bool psb_intel_ddc_probe(struct i2c_adapter *adapter)
30{
31 u8 out_buf[] = { 0x0, 0x0 };
32 u8 buf[2];
33 int ret;
34 struct i2c_msg msgs[] = {
35 {
36 .addr = 0x50,
37 .flags = 0,
38 .len = 1,
39 .buf = out_buf,
40 },
41 {
42 .addr = 0x50,
43 .flags = I2C_M_RD,
44 .len = 1,
45 .buf = buf,
46 }
47 };
48
49 ret = i2c_transfer(adapter, msgs, 2);
50 if (ret == 2)
51 return true;
52
53 return false;
54}
55
56/**
57 * psb_intel_ddc_get_modes - get modelist from monitor
58 * @connector: DRM connector device to use
59 *
60 * Fetch the EDID information from @connector using the DDC bus.
61 */
62int psb_intel_ddc_get_modes(struct drm_connector *connector,
63 struct i2c_adapter *adapter)
64{
65 struct edid *edid;
66 int ret = 0;
67
68 edid = drm_get_edid(connector, adapter);
69 if (edid) {
70 drm_mode_connector_update_edid_property(connector, edid);
71 ret = drm_add_edid_modes(connector, edid);
72 kfree(edid);
73 }
74 return ret;
75}
diff --git a/drivers/gpu/drm/gma500/psb_intel_reg.h b/drivers/gpu/drm/gma500/psb_intel_reg.h
new file mode 100644
index 00000000000..fcc0af03d68
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_intel_reg.h
@@ -0,0 +1,1309 @@
1/*
2 * Copyright (c) 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#ifndef __PSB_INTEL_REG_H__
18#define __PSB_INTEL_REG_H__
19
20/*
21 * GPIO regs
22 */
23#define GPIOA 0x5010
24#define GPIOB 0x5014
25#define GPIOC 0x5018
26#define GPIOD 0x501c
27#define GPIOE 0x5020
28#define GPIOF 0x5024
29#define GPIOG 0x5028
30#define GPIOH 0x502c
31# define GPIO_CLOCK_DIR_MASK (1 << 0)
32# define GPIO_CLOCK_DIR_IN (0 << 1)
33# define GPIO_CLOCK_DIR_OUT (1 << 1)
34# define GPIO_CLOCK_VAL_MASK (1 << 2)
35# define GPIO_CLOCK_VAL_OUT (1 << 3)
36# define GPIO_CLOCK_VAL_IN (1 << 4)
37# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5)
38# define GPIO_DATA_DIR_MASK (1 << 8)
39# define GPIO_DATA_DIR_IN (0 << 9)
40# define GPIO_DATA_DIR_OUT (1 << 9)
41# define GPIO_DATA_VAL_MASK (1 << 10)
42# define GPIO_DATA_VAL_OUT (1 << 11)
43# define GPIO_DATA_VAL_IN (1 << 12)
44# define GPIO_DATA_PULLUP_DISABLE (1 << 13)
45
46#define GMBUS0 0x5100 /* clock/port select */
47#define GMBUS_RATE_100KHZ (0<<8)
48#define GMBUS_RATE_50KHZ (1<<8)
49#define GMBUS_RATE_400KHZ (2<<8) /* reserved on Pineview */
50#define GMBUS_RATE_1MHZ (3<<8) /* reserved on Pineview */
51#define GMBUS_HOLD_EXT (1<<7) /* 300ns hold time, rsvd on Pineview */
52#define GMBUS_PORT_DISABLED 0
53#define GMBUS_PORT_SSC 1
54#define GMBUS_PORT_VGADDC 2
55#define GMBUS_PORT_PANEL 3
56#define GMBUS_PORT_DPC 4 /* HDMIC */
57#define GMBUS_PORT_DPB 5 /* SDVO, HDMIB */
58 /* 6 reserved */
59#define GMBUS_PORT_DPD 7 /* HDMID */
60#define GMBUS_NUM_PORTS 8
61#define GMBUS1 0x5104 /* command/status */
62#define GMBUS_SW_CLR_INT (1<<31)
63#define GMBUS_SW_RDY (1<<30)
64#define GMBUS_ENT (1<<29) /* enable timeout */
65#define GMBUS_CYCLE_NONE (0<<25)
66#define GMBUS_CYCLE_WAIT (1<<25)
67#define GMBUS_CYCLE_INDEX (2<<25)
68#define GMBUS_CYCLE_STOP (4<<25)
69#define GMBUS_BYTE_COUNT_SHIFT 16
70#define GMBUS_SLAVE_INDEX_SHIFT 8
71#define GMBUS_SLAVE_ADDR_SHIFT 1
72#define GMBUS_SLAVE_READ (1<<0)
73#define GMBUS_SLAVE_WRITE (0<<0)
74#define GMBUS2 0x5108 /* status */
75#define GMBUS_INUSE (1<<15)
76#define GMBUS_HW_WAIT_PHASE (1<<14)
77#define GMBUS_STALL_TIMEOUT (1<<13)
78#define GMBUS_INT (1<<12)
79#define GMBUS_HW_RDY (1<<11)
80#define GMBUS_SATOER (1<<10)
81#define GMBUS_ACTIVE (1<<9)
82#define GMBUS3 0x510c /* data buffer bytes 3-0 */
83#define GMBUS4 0x5110 /* interrupt mask (Pineview+) */
84#define GMBUS_SLAVE_TIMEOUT_EN (1<<4)
85#define GMBUS_NAK_EN (1<<3)
86#define GMBUS_IDLE_EN (1<<2)
87#define GMBUS_HW_WAIT_EN (1<<1)
88#define GMBUS_HW_RDY_EN (1<<0)
89#define GMBUS5 0x5120 /* byte index */
90#define GMBUS_2BYTE_INDEX_EN (1<<31)
91
92#define BLC_PWM_CTL 0x61254
93#define BLC_PWM_CTL2 0x61250
94#define BLC_PWM_CTL_C 0x62254
95#define BLC_PWM_CTL2_C 0x62250
96#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
97/*
98 * This is the most significant 15 bits of the number of backlight cycles in a
99 * complete cycle of the modulated backlight control.
100 *
101 * The actual value is this field multiplied by two.
102 */
103#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
104#define BLM_LEGACY_MODE (1 << 16)
105/*
106 * This is the number of cycles out of the backlight modulation cycle for which
107 * the backlight is on.
108 *
109 * This field must be no greater than the number of cycles in the complete
110 * backlight modulation cycle.
111 */
112#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
113#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
114
115#define I915_GCFGC 0xf0
116#define I915_LOW_FREQUENCY_ENABLE (1 << 7)
117#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
118#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4)
119#define I915_DISPLAY_CLOCK_MASK (7 << 4)
120
121#define I855_HPLLCC 0xc0
122#define I855_CLOCK_CONTROL_MASK (3 << 0)
123#define I855_CLOCK_133_200 (0 << 0)
124#define I855_CLOCK_100_200 (1 << 0)
125#define I855_CLOCK_100_133 (2 << 0)
126#define I855_CLOCK_166_250 (3 << 0)
127
128/* I830 CRTC registers */
129#define HTOTAL_A 0x60000
130#define HBLANK_A 0x60004
131#define HSYNC_A 0x60008
132#define VTOTAL_A 0x6000c
133#define VBLANK_A 0x60010
134#define VSYNC_A 0x60014
135#define PIPEASRC 0x6001c
136#define BCLRPAT_A 0x60020
137#define VSYNCSHIFT_A 0x60028
138
139#define HTOTAL_B 0x61000
140#define HBLANK_B 0x61004
141#define HSYNC_B 0x61008
142#define VTOTAL_B 0x6100c
143#define VBLANK_B 0x61010
144#define VSYNC_B 0x61014
145#define PIPEBSRC 0x6101c
146#define BCLRPAT_B 0x61020
147#define VSYNCSHIFT_B 0x61028
148
149#define HTOTAL_C 0x62000
150#define HBLANK_C 0x62004
151#define HSYNC_C 0x62008
152#define VTOTAL_C 0x6200c
153#define VBLANK_C 0x62010
154#define VSYNC_C 0x62014
155#define PIPECSRC 0x6201c
156#define BCLRPAT_C 0x62020
157#define VSYNCSHIFT_C 0x62028
158
159#define PP_STATUS 0x61200
160# define PP_ON (1 << 31)
161/*
162 * Indicates that all dependencies of the panel are on:
163 *
164 * - PLL enabled
165 * - pipe enabled
166 * - LVDS/DVOB/DVOC on
167 */
168#define PP_READY (1 << 30)
169#define PP_SEQUENCE_NONE (0 << 28)
170#define PP_SEQUENCE_ON (1 << 28)
171#define PP_SEQUENCE_OFF (2 << 28)
172#define PP_SEQUENCE_MASK 0x30000000
173#define PP_CONTROL 0x61204
174#define POWER_TARGET_ON (1 << 0)
175
176#define LVDSPP_ON 0x61208
177#define LVDSPP_OFF 0x6120c
178#define PP_CYCLE 0x61210
179
180#define PFIT_CONTROL 0x61230
181#define PFIT_ENABLE (1 << 31)
182#define PFIT_PIPE_MASK (3 << 29)
183#define PFIT_PIPE_SHIFT 29
184#define PFIT_SCALING_MODE_PILLARBOX (1 << 27)
185#define PFIT_SCALING_MODE_LETTERBOX (3 << 26)
186#define VERT_INTERP_DISABLE (0 << 10)
187#define VERT_INTERP_BILINEAR (1 << 10)
188#define VERT_INTERP_MASK (3 << 10)
189#define VERT_AUTO_SCALE (1 << 9)
190#define HORIZ_INTERP_DISABLE (0 << 6)
191#define HORIZ_INTERP_BILINEAR (1 << 6)
192#define HORIZ_INTERP_MASK (3 << 6)
193#define HORIZ_AUTO_SCALE (1 << 5)
194#define PANEL_8TO6_DITHER_ENABLE (1 << 3)
195
196#define PFIT_PGM_RATIOS 0x61234
197#define PFIT_VERT_SCALE_MASK 0xfff00000
198#define PFIT_HORIZ_SCALE_MASK 0x0000fff0
199
200#define PFIT_AUTO_RATIOS 0x61238
201
202#define DPLL_A 0x06014
203#define DPLL_B 0x06018
204#define DPLL_VCO_ENABLE (1 << 31)
205#define DPLL_DVO_HIGH_SPEED (1 << 30)
206#define DPLL_SYNCLOCK_ENABLE (1 << 29)
207#define DPLL_VGA_MODE_DIS (1 << 28)
208#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
209#define DPLLB_MODE_LVDS (2 << 26) /* i915 */
210#define DPLL_MODE_MASK (3 << 26)
211#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
212#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
213#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
214#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
215#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
216#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
217#define DPLL_LOCK (1 << 15) /* CDV */
218
219/*
220 * The i830 generation, in DAC/serial mode, defines p1 as two plus this
221 * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
222 */
223# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
224/*
225 * The i830 generation, in LVDS mode, defines P1 as the bit number set within
226 * this field (only one bit may be set).
227 */
228#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
229#define DPLL_FPA01_P1_POST_DIV_SHIFT 16
230#define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required
231 * in DVO non-gang */
232# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
233#define PLL_REF_INPUT_DREFCLK (0 << 13)
234#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
235#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO
236 * TVCLKIN */
237#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
238#define PLL_REF_INPUT_MASK (3 << 13)
239#define PLL_LOAD_PULSE_PHASE_SHIFT 9
240/*
241 * Parallel to Serial Load Pulse phase selection.
242 * Selects the phase for the 10X DPLL clock for the PCIe
243 * digital display port. The range is 4 to 13; 10 or more
244 * is just a flip delay. The default is 6
245 */
246#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
247#define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
248
249/*
250 * SDVO multiplier for 945G/GM. Not used on 965.
251 *
252 * DPLL_MD_UDI_MULTIPLIER_MASK
253 */
254#define SDVO_MULTIPLIER_MASK 0x000000ff
255#define SDVO_MULTIPLIER_SHIFT_HIRES 4
256#define SDVO_MULTIPLIER_SHIFT_VGA 0
257
258/*
259 * PLL_MD
260 */
261/* Pipe A SDVO/UDI clock multiplier/divider register for G965. */
262#define DPLL_A_MD 0x0601c
263/* Pipe B SDVO/UDI clock multiplier/divider register for G965. */
264#define DPLL_B_MD 0x06020
265/*
266 * UDI pixel divider, controlling how many pixels are stuffed into a packet.
267 *
268 * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
269 */
270#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
271#define DPLL_MD_UDI_DIVIDER_SHIFT 24
272/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
273#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
274#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
275/*
276 * SDVO/UDI pixel multiplier.
277 *
278 * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
279 * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
280 * modes, the bus rate would be below the limits, so SDVO allows for stuffing
281 * dummy bytes in the datastream at an increased clock rate, with both sides of
282 * the link knowing how many bytes are fill.
283 *
284 * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
285 * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
286 * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
287 * through an SDVO command.
288 *
289 * This register field has values of multiplication factor minus 1, with
290 * a maximum multiplier of 5 for SDVO.
291 */
292#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
293#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
294/*
295 * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
296 * This best be set to the default value (3) or the CRT won't work. No,
297 * I don't entirely understand what this does...
298 */
299#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
300#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
301
302#define DPLL_TEST 0x606c
303#define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
304#define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
305#define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
306#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
307#define DPLLB_TEST_N_BYPASS (1 << 19)
308#define DPLLB_TEST_M_BYPASS (1 << 18)
309#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
310#define DPLLA_TEST_N_BYPASS (1 << 3)
311#define DPLLA_TEST_M_BYPASS (1 << 2)
312#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
313
314#define ADPA 0x61100
315#define ADPA_DAC_ENABLE (1 << 31)
316#define ADPA_DAC_DISABLE 0
317#define ADPA_PIPE_SELECT_MASK (1 << 30)
318#define ADPA_PIPE_A_SELECT 0
319#define ADPA_PIPE_B_SELECT (1 << 30)
320#define ADPA_USE_VGA_HVPOLARITY (1 << 15)
321#define ADPA_SETS_HVPOLARITY 0
322#define ADPA_VSYNC_CNTL_DISABLE (1 << 11)
323#define ADPA_VSYNC_CNTL_ENABLE 0
324#define ADPA_HSYNC_CNTL_DISABLE (1 << 10)
325#define ADPA_HSYNC_CNTL_ENABLE 0
326#define ADPA_VSYNC_ACTIVE_HIGH (1 << 4)
327#define ADPA_VSYNC_ACTIVE_LOW 0
328#define ADPA_HSYNC_ACTIVE_HIGH (1 << 3)
329#define ADPA_HSYNC_ACTIVE_LOW 0
330
331#define FPA0 0x06040
332#define FPA1 0x06044
333#define FPB0 0x06048
334#define FPB1 0x0604c
335#define FP_N_DIV_MASK 0x003f0000
336#define FP_N_DIV_SHIFT 16
337#define FP_M1_DIV_MASK 0x00003f00
338#define FP_M1_DIV_SHIFT 8
339#define FP_M2_DIV_MASK 0x0000003f
340#define FP_M2_DIV_SHIFT 0
341
342#define PORT_HOTPLUG_EN 0x61110
343#define SDVOB_HOTPLUG_INT_EN (1 << 26)
344#define SDVOC_HOTPLUG_INT_EN (1 << 25)
345#define TV_HOTPLUG_INT_EN (1 << 18)
346#define CRT_HOTPLUG_INT_EN (1 << 9)
347#define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
348/* CDV.. */
349#define CRT_HOTPLUG_ACTIVATION_PERIOD_64 (1 << 8)
350#define CRT_HOTPLUG_DAC_ON_TIME_2M (0 << 7)
351#define CRT_HOTPLUG_DAC_ON_TIME_4M (1 << 7)
352#define CRT_HOTPLUG_VOLTAGE_COMPARE_40 (0 << 5)
353#define CRT_HOTPLUG_VOLTAGE_COMPARE_50 (1 << 5)
354#define CRT_HOTPLUG_VOLTAGE_COMPARE_60 (2 << 5)
355#define CRT_HOTPLUG_VOLTAGE_COMPARE_70 (3 << 5)
356#define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK (3 << 5)
357#define CRT_HOTPLUG_DETECT_DELAY_1G (0 << 4)
358#define CRT_HOTPLUG_DETECT_DELAY_2G (1 << 4)
359#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2)
360#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2)
361#define CRT_HOTPLUG_DETECT_MASK 0x000000F8
362
363#define PORT_HOTPLUG_STAT 0x61114
364#define CRT_HOTPLUG_INT_STATUS (1 << 11)
365#define TV_HOTPLUG_INT_STATUS (1 << 10)
366#define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
367#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
368#define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
369#define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
370#define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
371#define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
372
373#define SDVOB 0x61140
374#define SDVOC 0x61160
375#define SDVO_ENABLE (1 << 31)
376#define SDVO_PIPE_B_SELECT (1 << 30)
377#define SDVO_STALL_SELECT (1 << 29)
378#define SDVO_INTERRUPT_ENABLE (1 << 26)
379#define SDVO_COLOR_RANGE_16_235 (1 << 8)
380#define SDVO_AUDIO_ENABLE (1 << 6)
381
382/**
383 * 915G/GM SDVO pixel multiplier.
384 *
385 * Programmed value is multiplier - 1, up to 5x.
386 *
387 * DPLL_MD_UDI_MULTIPLIER_MASK
388 */
389#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
390#define SDVO_PORT_MULTIPLY_SHIFT 23
391#define SDVO_PHASE_SELECT_MASK (15 << 19)
392#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
393#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
394#define SDVOC_GANG_MODE (1 << 16)
395#define SDVO_BORDER_ENABLE (1 << 7)
396#define SDVOB_PCIE_CONCURRENCY (1 << 3)
397#define SDVO_DETECTED (1 << 2)
398/* Bits to be preserved when writing */
399#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14))
400#define SDVOC_PRESERVE_MASK (1 << 17)
401
402/*
403 * This register controls the LVDS output enable, pipe selection, and data
404 * format selection.
405 *
406 * All of the clock/data pairs are force powered down by power sequencing.
407 */
408#define LVDS 0x61180
409/*
410 * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
411 * the DPLL semantics change when the LVDS is assigned to that pipe.
412 */
413#define LVDS_PORT_EN (1 << 31)
414/* Selects pipe B for LVDS data. Must be set on pre-965. */
415#define LVDS_PIPEB_SELECT (1 << 30)
416
417/* Turns on border drawing to allow centered display. */
418#define LVDS_BORDER_EN (1 << 15)
419
420/*
421 * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
422 * pixel.
423 */
424#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
425#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
426#define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
427/*
428 * Controls the A3 data pair, which contains the additional LSBs for 24 bit
429 * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
430 * on.
431 */
432#define LVDS_A3_POWER_MASK (3 << 6)
433#define LVDS_A3_POWER_DOWN (0 << 6)
434#define LVDS_A3_POWER_UP (3 << 6)
435/*
436 * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
437 * is set.
438 */
439#define LVDS_CLKB_POWER_MASK (3 << 4)
440#define LVDS_CLKB_POWER_DOWN (0 << 4)
441#define LVDS_CLKB_POWER_UP (3 << 4)
442/*
443 * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
444 * setting for whether we are in dual-channel mode. The B3 pair will
445 * additionally only be powered up when LVDS_A3_POWER_UP is set.
446 */
447#define LVDS_B0B3_POWER_MASK (3 << 2)
448#define LVDS_B0B3_POWER_DOWN (0 << 2)
449#define LVDS_B0B3_POWER_UP (3 << 2)
450
451#define PIPEACONF 0x70008
452#define PIPEACONF_ENABLE (1 << 31)
453#define PIPEACONF_DISABLE 0
454#define PIPEACONF_DOUBLE_WIDE (1 << 30)
455#define PIPECONF_ACTIVE (1 << 30)
456#define I965_PIPECONF_ACTIVE (1 << 30)
457#define PIPECONF_DSIPLL_LOCK (1 << 29)
458#define PIPEACONF_SINGLE_WIDE 0
459#define PIPEACONF_PIPE_UNLOCKED 0
460#define PIPEACONF_DSR (1 << 26)
461#define PIPEACONF_PIPE_LOCKED (1 << 25)
462#define PIPEACONF_PALETTE 0
463#define PIPECONF_FORCE_BORDER (1 << 25)
464#define PIPEACONF_GAMMA (1 << 24)
465#define PIPECONF_PROGRESSIVE (0 << 21)
466#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
467#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
468#define PIPECONF_PLANE_OFF (1 << 19)
469#define PIPECONF_CURSOR_OFF (1 << 18)
470
471#define PIPEBCONF 0x71008
472#define PIPEBCONF_ENABLE (1 << 31)
473#define PIPEBCONF_DISABLE 0
474#define PIPEBCONF_DOUBLE_WIDE (1 << 30)
475#define PIPEBCONF_DISABLE 0
476#define PIPEBCONF_GAMMA (1 << 24)
477#define PIPEBCONF_PALETTE 0
478
479#define PIPECCONF 0x72008
480
481#define PIPEBGCMAXRED 0x71010
482#define PIPEBGCMAXGREEN 0x71014
483#define PIPEBGCMAXBLUE 0x71018
484
485#define PIPEASTAT 0x70024
486#define PIPEBSTAT 0x71024
487#define PIPECSTAT 0x72024
488#define PIPE_VBLANK_INTERRUPT_STATUS (1UL << 1)
489#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL << 2)
490#define PIPE_VBLANK_CLEAR (1 << 1)
491#define PIPE_VBLANK_STATUS (1 << 1)
492#define PIPE_TE_STATUS (1UL << 6)
493#define PIPE_DPST_EVENT_STATUS (1UL << 7)
494#define PIPE_VSYNC_CLEAR (1UL << 9)
495#define PIPE_VSYNC_STATUS (1UL << 9)
496#define PIPE_HDMI_AUDIO_UNDERRUN_STATUS (1UL << 10)
497#define PIPE_HDMI_AUDIO_BUFFER_DONE_STATUS (1UL << 11)
498#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL << 17)
499#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL << 18)
500#define PIPE_TE_ENABLE (1UL << 22)
501#define PIPE_DPST_EVENT_ENABLE (1UL << 23)
502#define PIPE_VSYNC_ENABL (1UL << 25)
503#define PIPE_HDMI_AUDIO_UNDERRUN (1UL << 26)
504#define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL << 27)
505#define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | \
506 PIPE_HDMI_AUDIO_BUFFER_DONE)
507#define PIPE_EVENT_MASK ((1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)|(1 << 22)|(1 << 21)|(1 << 20)|(1 << 16))
508#define PIPE_VBLANK_MASK ((1 << 25)|(1 << 24)|(1 << 18)|(1 << 17))
509#define HISTOGRAM_INT_CONTROL 0x61268
510#define HISTOGRAM_BIN_DATA 0X61264
511#define HISTOGRAM_LOGIC_CONTROL 0x61260
512#define PWM_CONTROL_LOGIC 0x61250
513#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL << 10)
514#define HISTOGRAM_INTERRUPT_ENABLE (1UL << 31)
515#define HISTOGRAM_LOGIC_ENABLE (1UL << 31)
516#define PWM_LOGIC_ENABLE (1UL << 31)
517#define PWM_PHASEIN_ENABLE (1UL << 25)
518#define PWM_PHASEIN_INT_ENABLE (1UL << 24)
519#define PWM_PHASEIN_VB_COUNT 0x00001f00
520#define PWM_PHASEIN_INC 0x0000001f
521#define HISTOGRAM_INT_CTRL_CLEAR (1UL << 30)
522#define DPST_YUV_LUMA_MODE 0
523
524struct dpst_ie_histogram_control {
525 union {
526 uint32_t data;
527 struct {
528 uint32_t bin_reg_index:7;
529 uint32_t reserved:4;
530 uint32_t bin_reg_func_select:1;
531 uint32_t sync_to_phase_in:1;
532 uint32_t alt_enhancement_mode:2;
533 uint32_t reserved1:1;
534 uint32_t sync_to_phase_in_count:8;
535 uint32_t histogram_mode_select:1;
536 uint32_t reserved2:4;
537 uint32_t ie_pipe_assignment:1;
538 uint32_t ie_mode_table_enabled:1;
539 uint32_t ie_histogram_enable:1;
540 };
541 };
542};
543
544struct dpst_guardband {
545 union {
546 uint32_t data;
547 struct {
548 uint32_t guardband:22;
549 uint32_t guardband_interrupt_delay:8;
550 uint32_t interrupt_status:1;
551 uint32_t interrupt_enable:1;
552 };
553 };
554};
555
556#define PIPEAFRAMEHIGH 0x70040
557#define PIPEAFRAMEPIXEL 0x70044
558#define PIPEBFRAMEHIGH 0x71040
559#define PIPEBFRAMEPIXEL 0x71044
560#define PIPECFRAMEHIGH 0x72040
561#define PIPECFRAMEPIXEL 0x72044
562#define PIPE_FRAME_HIGH_MASK 0x0000ffff
563#define PIPE_FRAME_HIGH_SHIFT 0
564#define PIPE_FRAME_LOW_MASK 0xff000000
565#define PIPE_FRAME_LOW_SHIFT 24
566#define PIPE_PIXEL_MASK 0x00ffffff
567#define PIPE_PIXEL_SHIFT 0
568
569#define DSPARB 0x70030
570#define DSPFW1 0x70034
571#define DSPFW2 0x70038
572#define DSPFW3 0x7003c
573#define DSPFW4 0x70050
574#define DSPFW5 0x70054
575#define DSPFW6 0x70058
576#define DSPCHICKENBIT 0x70400
577#define DSPACNTR 0x70180
578#define DSPBCNTR 0x71180
579#define DSPCCNTR 0x72180
580#define DISPLAY_PLANE_ENABLE (1 << 31)
581#define DISPLAY_PLANE_DISABLE 0
582#define DISPPLANE_GAMMA_ENABLE (1 << 30)
583#define DISPPLANE_GAMMA_DISABLE 0
584#define DISPPLANE_PIXFORMAT_MASK (0xf << 26)
585#define DISPPLANE_8BPP (0x2 << 26)
586#define DISPPLANE_15_16BPP (0x4 << 26)
587#define DISPPLANE_16BPP (0x5 << 26)
588#define DISPPLANE_32BPP_NO_ALPHA (0x6 << 26)
589#define DISPPLANE_32BPP (0x7 << 26)
590#define DISPPLANE_STEREO_ENABLE (1 << 25)
591#define DISPPLANE_STEREO_DISABLE 0
592#define DISPPLANE_SEL_PIPE_MASK (1 << 24)
593#define DISPPLANE_SEL_PIPE_POS 24
594#define DISPPLANE_SEL_PIPE_A 0
595#define DISPPLANE_SEL_PIPE_B (1 << 24)
596#define DISPPLANE_SRC_KEY_ENABLE (1 << 22)
597#define DISPPLANE_SRC_KEY_DISABLE 0
598#define DISPPLANE_LINE_DOUBLE (1 << 20)
599#define DISPPLANE_NO_LINE_DOUBLE 0
600#define DISPPLANE_STEREO_POLARITY_FIRST 0
601#define DISPPLANE_STEREO_POLARITY_SECOND (1 << 18)
602/* plane B only */
603#define DISPPLANE_ALPHA_TRANS_ENABLE (1 << 15)
604#define DISPPLANE_ALPHA_TRANS_DISABLE 0
605#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0
606#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
607#define DISPPLANE_BOTTOM (4)
608
609#define DSPABASE 0x70184
610#define DSPALINOFF 0x70184
611#define DSPASTRIDE 0x70188
612
613#define DSPBBASE 0x71184
614#define DSPBLINOFF 0X71184
615#define DSPBADDR DSPBBASE
616#define DSPBSTRIDE 0x71188
617
618#define DSPCBASE 0x72184
619#define DSPCLINOFF 0x72184
620#define DSPCSTRIDE 0x72188
621
622#define DSPAKEYVAL 0x70194
623#define DSPAKEYMASK 0x70198
624
625#define DSPAPOS 0x7018C /* reserved */
626#define DSPASIZE 0x70190
627#define DSPBPOS 0x7118C
628#define DSPBSIZE 0x71190
629#define DSPCPOS 0x7218C
630#define DSPCSIZE 0x72190
631
632#define DSPASURF 0x7019C
633#define DSPATILEOFF 0x701A4
634
635#define DSPBSURF 0x7119C
636#define DSPBTILEOFF 0x711A4
637
638#define DSPCSURF 0x7219C
639#define DSPCTILEOFF 0x721A4
640#define DSPCKEYMAXVAL 0x721A0
641#define DSPCKEYMINVAL 0x72194
642#define DSPCKEYMSK 0x72198
643
644#define VGACNTRL 0x71400
645#define VGA_DISP_DISABLE (1 << 31)
646#define VGA_2X_MODE (1 << 30)
647#define VGA_PIPE_B_SELECT (1 << 29)
648
649/*
650 * Overlay registers
651 */
652#define OV_C_OFFSET 0x08000
653#define OV_OVADD 0x30000
654#define OV_DOVASTA 0x30008
655# define OV_PIPE_SELECT ((1 << 6)|(1 << 7))
656# define OV_PIPE_SELECT_POS 6
657# define OV_PIPE_A 0
658# define OV_PIPE_C 1
659#define OV_OGAMC5 0x30010
660#define OV_OGAMC4 0x30014
661#define OV_OGAMC3 0x30018
662#define OV_OGAMC2 0x3001C
663#define OV_OGAMC1 0x30020
664#define OV_OGAMC0 0x30024
665#define OVC_OVADD 0x38000
666#define OVC_DOVCSTA 0x38008
667#define OVC_OGAMC5 0x38010
668#define OVC_OGAMC4 0x38014
669#define OVC_OGAMC3 0x38018
670#define OVC_OGAMC2 0x3801C
671#define OVC_OGAMC1 0x38020
672#define OVC_OGAMC0 0x38024
673
674/*
675 * Some BIOS scratch area registers. The 845 (and 830?) store the amount
676 * of video memory available to the BIOS in SWF1.
677 */
678#define SWF0 0x71410
679#define SWF1 0x71414
680#define SWF2 0x71418
681#define SWF3 0x7141c
682#define SWF4 0x71420
683#define SWF5 0x71424
684#define SWF6 0x71428
685
686/*
687 * 855 scratch registers.
688 */
689#define SWF00 0x70410
690#define SWF01 0x70414
691#define SWF02 0x70418
692#define SWF03 0x7041c
693#define SWF04 0x70420
694#define SWF05 0x70424
695#define SWF06 0x70428
696
697#define SWF10 SWF0
698#define SWF11 SWF1
699#define SWF12 SWF2
700#define SWF13 SWF3
701#define SWF14 SWF4
702#define SWF15 SWF5
703#define SWF16 SWF6
704
705#define SWF30 0x72414
706#define SWF31 0x72418
707#define SWF32 0x7241c
708
709
710/*
711 * Palette registers
712 */
713#define PALETTE_A 0x0a000
714#define PALETTE_B 0x0a800
715#define PALETTE_C 0x0ac00
716
717/* Cursor A & B regs */
718#define CURACNTR 0x70080
719#define CURSOR_MODE_DISABLE 0x00
720#define CURSOR_MODE_64_32B_AX 0x07
721#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
722#define MCURSOR_GAMMA_ENABLE (1 << 26)
723#define CURABASE 0x70084
724#define CURAPOS 0x70088
725#define CURSOR_POS_MASK 0x007FF
726#define CURSOR_POS_SIGN 0x8000
727#define CURSOR_X_SHIFT 0
728#define CURSOR_Y_SHIFT 16
729#define CURBCNTR 0x700c0
730#define CURBBASE 0x700c4
731#define CURBPOS 0x700c8
732#define CURCCNTR 0x700e0
733#define CURCBASE 0x700e4
734#define CURCPOS 0x700e8
735
736/*
737 * Interrupt Registers
738 */
739#define IER 0x020a0
740#define IIR 0x020a4
741#define IMR 0x020a8
742#define ISR 0x020ac
743
744/*
745 * MOORESTOWN delta registers
746 */
747#define MRST_DPLL_A 0x0f014
748#define MDFLD_DPLL_B 0x0f018
749#define MDFLD_INPUT_REF_SEL (1 << 14)
750#define MDFLD_VCO_SEL (1 << 16)
751#define DPLLA_MODE_LVDS (2 << 26) /* mrst */
752#define MDFLD_PLL_LATCHEN (1 << 28)
753#define MDFLD_PWR_GATE_EN (1 << 30)
754#define MDFLD_P1_MASK (0x1FF << 17)
755#define MRST_FPA0 0x0f040
756#define MRST_FPA1 0x0f044
757#define MDFLD_DPLL_DIV0 0x0f048
758#define MDFLD_DPLL_DIV1 0x0f04c
759#define MRST_PERF_MODE 0x020f4
760
761/*
762 * MEDFIELD HDMI registers
763 */
764#define HDMIPHYMISCCTL 0x61134
765#define HDMI_PHY_POWER_DOWN 0x7f
766#define HDMIB_CONTROL 0x61140
767#define HDMIB_PORT_EN (1 << 31)
768#define HDMIB_PIPE_B_SELECT (1 << 30)
769#define HDMIB_NULL_PACKET (1 << 9)
770#define HDMIB_HDCP_PORT (1 << 5)
771
772/* #define LVDS 0x61180 */
773#define MRST_PANEL_8TO6_DITHER_ENABLE (1 << 25)
774#define MRST_PANEL_24_DOT_1_FORMAT (1 << 24)
775#define LVDS_A3_POWER_UP_0_OUTPUT (1 << 6)
776
777#define MIPI 0x61190
778#define MIPI_C 0x62190
779#define MIPI_PORT_EN (1 << 31)
780/* Turns on border drawing to allow centered display. */
781#define SEL_FLOPPED_HSTX (1 << 23)
782#define PASS_FROM_SPHY_TO_AFE (1 << 16)
783#define MIPI_BORDER_EN (1 << 15)
784#define MIPIA_3LANE_MIPIC_1LANE 0x1
785#define MIPIA_2LANE_MIPIC_2LANE 0x2
786#define TE_TRIGGER_DSI_PROTOCOL (1 << 2)
787#define TE_TRIGGER_GPIO_PIN (1 << 3)
788#define MIPI_TE_COUNT 0x61194
789
790/* #define PP_CONTROL 0x61204 */
791#define POWER_DOWN_ON_RESET (1 << 1)
792
793/* #define PFIT_CONTROL 0x61230 */
794#define PFIT_PIPE_SELECT (3 << 29)
795#define PFIT_PIPE_SELECT_SHIFT (29)
796
797/* #define BLC_PWM_CTL 0x61254 */
798#define MRST_BACKLIGHT_MODULATION_FREQ_SHIFT (16)
799#define MRST_BACKLIGHT_MODULATION_FREQ_MASK (0xffff << 16)
800
801/* #define PIPEACONF 0x70008 */
802#define PIPEACONF_PIPE_STATE (1 << 30)
803/* #define DSPACNTR 0x70180 */
804
805#define MRST_DSPABASE 0x7019c
806#define MRST_DSPBBASE 0x7119c
807#define MDFLD_DSPCBASE 0x7219c
808
809/*
810 * Moorestown registers.
811 */
812
813/*
814 * MIPI IP registers
815 */
816#define MIPIC_REG_OFFSET 0x800
817
818#define DEVICE_READY_REG 0xb000
819#define LP_OUTPUT_HOLD (1 << 16)
820#define EXIT_ULPS_DEV_READY 0x3
821#define LP_OUTPUT_HOLD_RELEASE 0x810000
822# define ENTERING_ULPS (2 << 1)
823# define EXITING_ULPS (1 << 1)
824# define ULPS_MASK (3 << 1)
825# define BUS_POSSESSION (1 << 3)
826#define INTR_STAT_REG 0xb004
827#define RX_SOT_ERROR (1 << 0)
828#define RX_SOT_SYNC_ERROR (1 << 1)
829#define RX_ESCAPE_MODE_ENTRY_ERROR (1 << 3)
830#define RX_LP_TX_SYNC_ERROR (1 << 4)
831#define RX_HS_RECEIVE_TIMEOUT_ERROR (1 << 5)
832#define RX_FALSE_CONTROL_ERROR (1 << 6)
833#define RX_ECC_SINGLE_BIT_ERROR (1 << 7)
834#define RX_ECC_MULTI_BIT_ERROR (1 << 8)
835#define RX_CHECKSUM_ERROR (1 << 9)
836#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 10)
837#define RX_DSI_VC_ID_INVALID (1 << 11)
838#define TX_FALSE_CONTROL_ERROR (1 << 12)
839#define TX_ECC_SINGLE_BIT_ERROR (1 << 13)
840#define TX_ECC_MULTI_BIT_ERROR (1 << 14)
841#define TX_CHECKSUM_ERROR (1 << 15)
842#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 16)
843#define TX_DSI_VC_ID_INVALID (1 << 17)
844#define HIGH_CONTENTION (1 << 18)
845#define LOW_CONTENTION (1 << 19)
846#define DPI_FIFO_UNDER_RUN (1 << 20)
847#define HS_TX_TIMEOUT (1 << 21)
848#define LP_RX_TIMEOUT (1 << 22)
849#define TURN_AROUND_ACK_TIMEOUT (1 << 23)
850#define ACK_WITH_NO_ERROR (1 << 24)
851#define HS_GENERIC_WR_FIFO_FULL (1 << 27)
852#define LP_GENERIC_WR_FIFO_FULL (1 << 28)
853#define SPL_PKT_SENT (1 << 30)
854#define INTR_EN_REG 0xb008
855#define DSI_FUNC_PRG_REG 0xb00c
856#define DPI_CHANNEL_NUMBER_POS 0x03
857#define DBI_CHANNEL_NUMBER_POS 0x05
858#define FMT_DPI_POS 0x07
859#define FMT_DBI_POS 0x0A
860#define DBI_DATA_WIDTH_POS 0x0D
861
862/* DPI PIXEL FORMATS */
863#define RGB_565_FMT 0x01 /* RGB 565 FORMAT */
864#define RGB_666_FMT 0x02 /* RGB 666 FORMAT */
865#define LRGB_666_FMT 0x03 /* RGB LOOSELY PACKED
866 * 666 FORMAT
867 */
868#define RGB_888_FMT 0x04 /* RGB 888 FORMAT */
869#define VIRTUAL_CHANNEL_NUMBER_0 0x00 /* Virtual channel 0 */
870#define VIRTUAL_CHANNEL_NUMBER_1 0x01 /* Virtual channel 1 */
871#define VIRTUAL_CHANNEL_NUMBER_2 0x02 /* Virtual channel 2 */
872#define VIRTUAL_CHANNEL_NUMBER_3 0x03 /* Virtual channel 3 */
873
874#define DBI_NOT_SUPPORTED 0x00 /* command mode
875 * is not supported
876 */
877#define DBI_DATA_WIDTH_16BIT 0x01 /* 16 bit data */
878#define DBI_DATA_WIDTH_9BIT 0x02 /* 9 bit data */
879#define DBI_DATA_WIDTH_8BIT 0x03 /* 8 bit data */
880#define DBI_DATA_WIDTH_OPT1 0x04 /* option 1 */
881#define DBI_DATA_WIDTH_OPT2 0x05 /* option 2 */
882
883#define HS_TX_TIMEOUT_REG 0xb010
884#define LP_RX_TIMEOUT_REG 0xb014
885#define TURN_AROUND_TIMEOUT_REG 0xb018
886#define DEVICE_RESET_REG 0xb01C
887#define DPI_RESOLUTION_REG 0xb020
888#define RES_V_POS 0x10
889#define DBI_RESOLUTION_REG 0xb024 /* Reserved for MDFLD */
890#define HORIZ_SYNC_PAD_COUNT_REG 0xb028
891#define HORIZ_BACK_PORCH_COUNT_REG 0xb02C
892#define HORIZ_FRONT_PORCH_COUNT_REG 0xb030
893#define HORIZ_ACTIVE_AREA_COUNT_REG 0xb034
894#define VERT_SYNC_PAD_COUNT_REG 0xb038
895#define VERT_BACK_PORCH_COUNT_REG 0xb03c
896#define VERT_FRONT_PORCH_COUNT_REG 0xb040
897#define HIGH_LOW_SWITCH_COUNT_REG 0xb044
898#define DPI_CONTROL_REG 0xb048
899#define DPI_SHUT_DOWN (1 << 0)
900#define DPI_TURN_ON (1 << 1)
901#define DPI_COLOR_MODE_ON (1 << 2)
902#define DPI_COLOR_MODE_OFF (1 << 3)
903#define DPI_BACK_LIGHT_ON (1 << 4)
904#define DPI_BACK_LIGHT_OFF (1 << 5)
905#define DPI_LP (1 << 6)
906#define DPI_DATA_REG 0xb04c
907#define DPI_BACK_LIGHT_ON_DATA 0x07
908#define DPI_BACK_LIGHT_OFF_DATA 0x17
909#define INIT_COUNT_REG 0xb050
910#define MAX_RET_PAK_REG 0xb054
911#define VIDEO_FMT_REG 0xb058
912#define COMPLETE_LAST_PCKT (1 << 2)
913#define EOT_DISABLE_REG 0xb05c
914#define ENABLE_CLOCK_STOPPING (1 << 1)
915#define LP_BYTECLK_REG 0xb060
916#define LP_GEN_DATA_REG 0xb064
917#define HS_GEN_DATA_REG 0xb068
918#define LP_GEN_CTRL_REG 0xb06C
919#define HS_GEN_CTRL_REG 0xb070
920#define DCS_CHANNEL_NUMBER_POS 0x6
921#define MCS_COMMANDS_POS 0x8
922#define WORD_COUNTS_POS 0x8
923#define MCS_PARAMETER_POS 0x10
924#define GEN_FIFO_STAT_REG 0xb074
925#define HS_DATA_FIFO_FULL (1 << 0)
926#define HS_DATA_FIFO_HALF_EMPTY (1 << 1)
927#define HS_DATA_FIFO_EMPTY (1 << 2)
928#define LP_DATA_FIFO_FULL (1 << 8)
929#define LP_DATA_FIFO_HALF_EMPTY (1 << 9)
930#define LP_DATA_FIFO_EMPTY (1 << 10)
931#define HS_CTRL_FIFO_FULL (1 << 16)
932#define HS_CTRL_FIFO_HALF_EMPTY (1 << 17)
933#define HS_CTRL_FIFO_EMPTY (1 << 18)
934#define LP_CTRL_FIFO_FULL (1 << 24)
935#define LP_CTRL_FIFO_HALF_EMPTY (1 << 25)
936#define LP_CTRL_FIFO_EMPTY (1 << 26)
937#define DBI_FIFO_EMPTY (1 << 27)
938#define DPI_FIFO_EMPTY (1 << 28)
939#define HS_LS_DBI_ENABLE_REG 0xb078
940#define TXCLKESC_REG 0xb07c
941#define DPHY_PARAM_REG 0xb080
942#define DBI_BW_CTRL_REG 0xb084
943#define CLK_LANE_SWT_REG 0xb088
944
945/*
946 * MIPI Adapter registers
947 */
948#define MIPI_CONTROL_REG 0xb104
949#define MIPI_2X_CLOCK_BITS ((1 << 0) | (1 << 1))
950#define MIPI_DATA_ADDRESS_REG 0xb108
951#define MIPI_DATA_LENGTH_REG 0xb10C
952#define MIPI_COMMAND_ADDRESS_REG 0xb110
953#define MIPI_COMMAND_LENGTH_REG 0xb114
954#define MIPI_READ_DATA_RETURN_REG0 0xb118
955#define MIPI_READ_DATA_RETURN_REG1 0xb11C
956#define MIPI_READ_DATA_RETURN_REG2 0xb120
957#define MIPI_READ_DATA_RETURN_REG3 0xb124
958#define MIPI_READ_DATA_RETURN_REG4 0xb128
959#define MIPI_READ_DATA_RETURN_REG5 0xb12C
960#define MIPI_READ_DATA_RETURN_REG6 0xb130
961#define MIPI_READ_DATA_RETURN_REG7 0xb134
962#define MIPI_READ_DATA_VALID_REG 0xb138
963
964/* DBI COMMANDS */
965#define soft_reset 0x01
966/*
967 * The display module performs a software reset.
968 * Registers are written with their SW Reset default values.
969 */
970#define get_power_mode 0x0a
971/*
972 * The display module returns the current power mode
973 */
974#define get_address_mode 0x0b
975/*
976 * The display module returns the current status.
977 */
978#define get_pixel_format 0x0c
979/*
980 * This command gets the pixel format for the RGB image data
981 * used by the interface.
982 */
983#define get_display_mode 0x0d
984/*
985 * The display module returns the Display Image Mode status.
986 */
987#define get_signal_mode 0x0e
988/*
989 * The display module returns the Display Signal Mode.
990 */
991#define get_diagnostic_result 0x0f
992/*
993 * The display module returns the self-diagnostic results following
994 * a Sleep Out command.
995 */
996#define enter_sleep_mode 0x10
997/*
998 * This command causes the display module to enter the Sleep mode.
999 * In this mode, all unnecessary blocks inside the display module are
1000 * disabled except interface communication. This is the lowest power
1001 * mode the display module supports.
1002 */
1003#define exit_sleep_mode 0x11
1004/*
1005 * This command causes the display module to exit Sleep mode.
1006 * All blocks inside the display module are enabled.
1007 */
1008#define enter_partial_mode 0x12
1009/*
1010 * This command causes the display module to enter the Partial Display
1011 * Mode. The Partial Display Mode window is described by the
1012 * set_partial_area command.
1013 */
1014#define enter_normal_mode 0x13
1015/*
1016 * This command causes the display module to enter the Normal mode.
1017 * Normal Mode is defined as Partial Display mode and Scroll mode are off
1018 */
1019#define exit_invert_mode 0x20
1020/*
1021 * This command causes the display module to stop inverting the image
1022 * data on the display device. The frame memory contents remain unchanged.
1023 * No status bits are changed.
1024 */
1025#define enter_invert_mode 0x21
1026/*
1027 * This command causes the display module to invert the image data only on
1028 * the display device. The frame memory contents remain unchanged.
1029 * No status bits are changed.
1030 */
1031#define set_gamma_curve 0x26
1032/*
1033 * This command selects the desired gamma curve for the display device.
1034 * Four fixed gamma curves are defined in section DCS spec.
1035 */
1036#define set_display_off 0x28
1037/* ************************************************************************* *\
1038This command causes the display module to stop displaying the image data
1039on the display device. The frame memory contents remain unchanged.
1040No status bits are changed.
1041\* ************************************************************************* */
1042#define set_display_on 0x29
1043/* ************************************************************************* *\
1044This command causes the display module to start displaying the image data
1045on the display device. The frame memory contents remain unchanged.
1046No status bits are changed.
1047\* ************************************************************************* */
1048#define set_column_address 0x2a
1049/*
1050 * This command defines the column extent of the frame memory accessed by
1051 * the hostprocessor with the read_memory_continue and
1052 * write_memory_continue commands.
1053 * No status bits are changed.
1054 */
1055#define set_page_addr 0x2b
1056/*
1057 * This command defines the page extent of the frame memory accessed by
1058 * the host processor with the write_memory_continue and
1059 * read_memory_continue command.
1060 * No status bits are changed.
1061 */
1062#define write_mem_start 0x2c
1063/*
1064 * This command transfers image data from the host processor to the
1065 * display modules frame memory starting at the pixel location specified
1066 * by preceding set_column_address and set_page_address commands.
1067 */
1068#define set_partial_area 0x30
1069/*
1070 * This command defines the Partial Display mode s display area.
1071 * There are two parameters associated with this command, the first
1072 * defines the Start Row (SR) and the second the End Row (ER). SR and ER
1073 * refer to the Frame Memory Line Pointer.
1074 */
1075#define set_scroll_area 0x33
1076/*
1077 * This command defines the display modules Vertical Scrolling Area.
1078 */
1079#define set_tear_off 0x34
1080/*
1081 * This command turns off the display modules Tearing Effect output
1082 * signal on the TE signal line.
1083 */
1084#define set_tear_on 0x35
1085/*
1086 * This command turns on the display modules Tearing Effect output signal
1087 * on the TE signal line.
1088 */
1089#define set_address_mode 0x36
1090/*
1091 * This command sets the data order for transfers from the host processor
1092 * to display modules frame memory,bits B[7:5] and B3, and from the
1093 * display modules frame memory to the display device, bits B[2:0] and B4.
1094 */
1095#define set_scroll_start 0x37
1096/*
1097 * This command sets the start of the vertical scrolling area in the frame
1098 * memory. The vertical scrolling area is fully defined when this command
1099 * is used with the set_scroll_area command The set_scroll_start command
1100 * has one parameter, the Vertical Scroll Pointer. The VSP defines the
1101 * line in the frame memory that is written to the display device as the
1102 * first line of the vertical scroll area.
1103 */
1104#define exit_idle_mode 0x38
1105/*
1106 * This command causes the display module to exit Idle mode.
1107 */
1108#define enter_idle_mode 0x39
1109/*
1110 * This command causes the display module to enter Idle Mode.
1111 * In Idle Mode, color expression is reduced. Colors are shown on the
1112 * display device using the MSB of each of the R, G and B color
1113 * components in the frame memory
1114 */
1115#define set_pixel_format 0x3a
1116/*
1117 * This command sets the pixel format for the RGB image data used by the
1118 * interface.
1119 * Bits D[6:4] DPI Pixel Format Definition
1120 * Bits D[2:0] DBI Pixel Format Definition
1121 * Bits D7 and D3 are not used.
1122 */
1123#define DCS_PIXEL_FORMAT_3bpp 0x1
1124#define DCS_PIXEL_FORMAT_8bpp 0x2
1125#define DCS_PIXEL_FORMAT_12bpp 0x3
1126#define DCS_PIXEL_FORMAT_16bpp 0x5
1127#define DCS_PIXEL_FORMAT_18bpp 0x6
1128#define DCS_PIXEL_FORMAT_24bpp 0x7
1129
1130#define write_mem_cont 0x3c
1131
1132/*
1133 * This command transfers image data from the host processor to the
1134 * display module's frame memory continuing from the pixel location
1135 * following the previous write_memory_continue or write_memory_start
1136 * command.
1137 */
1138#define set_tear_scanline 0x44
1139/*
1140 * This command turns on the display modules Tearing Effect output signal
1141 * on the TE signal line when the display module reaches line N.
1142 */
1143#define get_scanline 0x45
1144/*
1145 * The display module returns the current scanline, N, used to update the
1146 * display device. The total number of scanlines on a display device is
1147 * defined as VSYNC + VBP + VACT + VFP.The first scanline is defined as
1148 * the first line of V Sync and is denoted as Line 0.
1149 * When in Sleep Mode, the value returned by get_scanline is undefined.
1150 */
1151
1152/* MCS or Generic COMMANDS */
1153/* MCS/generic data type */
1154#define GEN_SHORT_WRITE_0 0x03 /* generic short write, no parameters */
1155#define GEN_SHORT_WRITE_1 0x13 /* generic short write, 1 parameters */
1156#define GEN_SHORT_WRITE_2 0x23 /* generic short write, 2 parameters */
1157#define GEN_READ_0 0x04 /* generic read, no parameters */
1158#define GEN_READ_1 0x14 /* generic read, 1 parameters */
1159#define GEN_READ_2 0x24 /* generic read, 2 parameters */
1160#define GEN_LONG_WRITE 0x29 /* generic long write */
1161#define MCS_SHORT_WRITE_0 0x05 /* MCS short write, no parameters */
1162#define MCS_SHORT_WRITE_1 0x15 /* MCS short write, 1 parameters */
1163#define MCS_READ 0x06 /* MCS read, no parameters */
1164#define MCS_LONG_WRITE 0x39 /* MCS long write */
1165/* MCS/generic commands */
1166/* TPO MCS */
1167#define write_display_profile 0x50
1168#define write_display_brightness 0x51
1169#define write_ctrl_display 0x53
1170#define write_ctrl_cabc 0x55
1171 #define UI_IMAGE 0x01
1172 #define STILL_IMAGE 0x02
1173 #define MOVING_IMAGE 0x03
1174#define write_hysteresis 0x57
1175#define write_gamma_setting 0x58
1176#define write_cabc_min_bright 0x5e
1177#define write_kbbc_profile 0x60
1178/* TMD MCS */
1179#define tmd_write_display_brightness 0x8c
1180
1181/*
1182 * This command is used to control ambient light, panel backlight
1183 * brightness and gamma settings.
1184 */
1185#define BRIGHT_CNTL_BLOCK_ON (1 << 5)
1186#define AMBIENT_LIGHT_SENSE_ON (1 << 4)
1187#define DISPLAY_DIMMING_ON (1 << 3)
1188#define BACKLIGHT_ON (1 << 2)
1189#define DISPLAY_BRIGHTNESS_AUTO (1 << 1)
1190#define GAMMA_AUTO (1 << 0)
1191
1192/* DCS Interface Pixel Formats */
1193#define DCS_PIXEL_FORMAT_3BPP 0x1
1194#define DCS_PIXEL_FORMAT_8BPP 0x2
1195#define DCS_PIXEL_FORMAT_12BPP 0x3
1196#define DCS_PIXEL_FORMAT_16BPP 0x5
1197#define DCS_PIXEL_FORMAT_18BPP 0x6
1198#define DCS_PIXEL_FORMAT_24BPP 0x7
1199/* ONE PARAMETER READ DATA */
1200#define addr_mode_data 0xfc
1201#define diag_res_data 0x00
1202#define disp_mode_data 0x23
1203#define pxl_fmt_data 0x77
1204#define pwr_mode_data 0x74
1205#define sig_mode_data 0x00
1206/* TWO PARAMETERS READ DATA */
1207#define scanline_data1 0xff
1208#define scanline_data2 0xff
1209#define NON_BURST_MODE_SYNC_PULSE 0x01 /* Non Burst Mode
1210 * with Sync Pulse
1211 */
1212#define NON_BURST_MODE_SYNC_EVENTS 0x02 /* Non Burst Mode
1213 * with Sync events
1214 */
1215#define BURST_MODE 0x03 /* Burst Mode */
1216#define DBI_COMMAND_BUFFER_SIZE 0x240 /* 0x32 */ /* 0x120 */
1217 /* Allocate at least
1218 * 0x100 Byte with 32
1219 * byte alignment
1220 */
1221#define DBI_DATA_BUFFER_SIZE 0x120 /* Allocate at least
1222 * 0x100 Byte with 32
1223 * byte alignment
1224 */
1225#define DBI_CB_TIME_OUT 0xFFFF
1226
1227#define GEN_FB_TIME_OUT 2000
1228
1229#define SKU_83 0x01
1230#define SKU_100 0x02
1231#define SKU_100L 0x04
1232#define SKU_BYPASS 0x08
1233
1234/* Some handy macros for playing with bitfields. */
1235#define PSB_MASK(high, low) (((1<<((high)-(low)+1))-1)<<(low))
1236#define SET_FIELD(value, field) (((value) << field ## _SHIFT) & field ## _MASK)
1237#define GET_FIELD(word, field) (((word) & field ## _MASK) >> field ## _SHIFT)
1238
1239#define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a)))
1240
1241/* PCI config space */
1242
1243#define SB_PCKT 0x02100 /* cedarview */
1244# define SB_OPCODE_MASK PSB_MASK(31, 16)
1245# define SB_OPCODE_SHIFT 16
1246# define SB_OPCODE_READ 0
1247# define SB_OPCODE_WRITE 1
1248# define SB_DEST_MASK PSB_MASK(15, 8)
1249# define SB_DEST_SHIFT 8
1250# define SB_DEST_DPLL 0x88
1251# define SB_BYTE_ENABLE_MASK PSB_MASK(7, 4)
1252# define SB_BYTE_ENABLE_SHIFT 4
1253# define SB_BUSY (1 << 0)
1254
1255
1256/* 32-bit value read/written from the DPIO reg. */
1257#define SB_DATA 0x02104 /* cedarview */
1258/* 32-bit address of the DPIO reg to be read/written. */
1259#define SB_ADDR 0x02108 /* cedarview */
1260#define DPIO_CFG 0x02110 /* cedarview */
1261# define DPIO_MODE_SELECT_1 (1 << 3)
1262# define DPIO_MODE_SELECT_0 (1 << 2)
1263# define DPIO_SFR_BYPASS (1 << 1)
1264/* reset is active low */
1265# define DPIO_CMN_RESET_N (1 << 0)
1266
1267/* Cedarview sideband registers */
1268#define _SB_M_A 0x8008
1269#define _SB_M_B 0x8028
1270#define SB_M(pipe) _PIPE(pipe, _SB_M_A, _SB_M_B)
1271# define SB_M_DIVIDER_MASK (0xFF << 24)
1272# define SB_M_DIVIDER_SHIFT 24
1273
1274#define _SB_N_VCO_A 0x8014
1275#define _SB_N_VCO_B 0x8034
1276#define SB_N_VCO(pipe) _PIPE(pipe, _SB_N_VCO_A, _SB_N_VCO_B)
1277#define SB_N_VCO_SEL_MASK PSB_MASK(31, 30)
1278#define SB_N_VCO_SEL_SHIFT 30
1279#define SB_N_DIVIDER_MASK PSB_MASK(29, 26)
1280#define SB_N_DIVIDER_SHIFT 26
1281#define SB_N_CB_TUNE_MASK PSB_MASK(25, 24)
1282#define SB_N_CB_TUNE_SHIFT 24
1283
1284#define _SB_REF_A 0x8018
1285#define _SB_REF_B 0x8038
1286#define SB_REF_SFR(pipe) _PIPE(pipe, _SB_REF_A, _SB_REF_B)
1287
1288#define _SB_P_A 0x801c
1289#define _SB_P_B 0x803c
1290#define SB_P(pipe) _PIPE(pipe, _SB_P_A, _SB_P_B)
1291#define SB_P2_DIVIDER_MASK PSB_MASK(31, 30)
1292#define SB_P2_DIVIDER_SHIFT 30
1293#define SB_P2_10 0 /* HDMI, DP, DAC */
1294#define SB_P2_5 1 /* DAC */
1295#define SB_P2_14 2 /* LVDS single */
1296#define SB_P2_7 3 /* LVDS double */
1297#define SB_P1_DIVIDER_MASK PSB_MASK(15, 12)
1298#define SB_P1_DIVIDER_SHIFT 12
1299
1300#define PSB_LANE0 0x120
1301#define PSB_LANE1 0x220
1302#define PSB_LANE2 0x2320
1303#define PSB_LANE3 0x2420
1304
1305#define LANE_PLL_MASK (0x7 << 20)
1306#define LANE_PLL_ENABLE (0x3 << 20)
1307
1308
1309#endif
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
new file mode 100644
index 00000000000..4882b29119e
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
@@ -0,0 +1,2617 @@
1/*
2 * Copyright 2006 Dave Airlie <airlied@linux.ie>
3 * Copyright © 2006-2007 Intel Corporation
4 * Jesse Barnes <jesse.barnes@intel.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Eric Anholt <eric@anholt.net>
27 */
28#include <linux/module.h>
29#include <linux/i2c.h>
30#include <linux/slab.h>
31#include <linux/delay.h>
32#include "drmP.h"
33#include "drm.h"
34#include "drm_crtc.h"
35#include "drm_edid.h"
36#include "psb_intel_drv.h"
37#include "gma_drm.h"
38#include "psb_drv.h"
39#include "psb_intel_sdvo_regs.h"
40#include "psb_intel_reg.h"
41
42#define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)
43#define SDVO_RGB_MASK (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)
44#define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)
45#define SDVO_TV_MASK (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_SVID0)
46
47#define SDVO_OUTPUT_MASK (SDVO_TMDS_MASK | SDVO_RGB_MASK | SDVO_LVDS_MASK |\
48 SDVO_TV_MASK)
49
50#define IS_TV(c) (c->output_flag & SDVO_TV_MASK)
51#define IS_TMDS(c) (c->output_flag & SDVO_TMDS_MASK)
52#define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK)
53#define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK))
54
55
56static const char *tv_format_names[] = {
57 "NTSC_M" , "NTSC_J" , "NTSC_443",
58 "PAL_B" , "PAL_D" , "PAL_G" ,
59 "PAL_H" , "PAL_I" , "PAL_M" ,
60 "PAL_N" , "PAL_NC" , "PAL_60" ,
61 "SECAM_B" , "SECAM_D" , "SECAM_G" ,
62 "SECAM_K" , "SECAM_K1", "SECAM_L" ,
63 "SECAM_60"
64};
65
66#define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names))
67
68struct psb_intel_sdvo {
69 struct psb_intel_encoder base;
70
71 struct i2c_adapter *i2c;
72 u8 slave_addr;
73
74 struct i2c_adapter ddc;
75
76 /* Register for the SDVO device: SDVOB or SDVOC */
77 int sdvo_reg;
78
79 /* Active outputs controlled by this SDVO output */
80 uint16_t controlled_output;
81
82 /*
83 * Capabilities of the SDVO device returned by
84 * i830_sdvo_get_capabilities()
85 */
86 struct psb_intel_sdvo_caps caps;
87
88 /* Pixel clock limitations reported by the SDVO device, in kHz */
89 int pixel_clock_min, pixel_clock_max;
90
91 /*
92 * For multiple function SDVO device,
93 * this is for current attached outputs.
94 */
95 uint16_t attached_output;
96
97 /**
98 * This is used to select the color range of RBG outputs in HDMI mode.
99 * It is only valid when using TMDS encoding and 8 bit per color mode.
100 */
101 uint32_t color_range;
102
103 /**
104 * This is set if we're going to treat the device as TV-out.
105 *
106 * While we have these nice friendly flags for output types that ought
107 * to decide this for us, the S-Video output on our HDMI+S-Video card
108 * shows up as RGB1 (VGA).
109 */
110 bool is_tv;
111
112 /* This is for current tv format name */
113 int tv_format_index;
114
115 /**
116 * This is set if we treat the device as HDMI, instead of DVI.
117 */
118 bool is_hdmi;
119 bool has_hdmi_monitor;
120 bool has_hdmi_audio;
121
122 /**
123 * This is set if we detect output of sdvo device as LVDS and
124 * have a valid fixed mode to use with the panel.
125 */
126 bool is_lvds;
127
128 /**
129 * This is sdvo fixed pannel mode pointer
130 */
131 struct drm_display_mode *sdvo_lvds_fixed_mode;
132
133 /* DDC bus used by this SDVO encoder */
134 uint8_t ddc_bus;
135
136 /* Input timings for adjusted_mode */
137 struct psb_intel_sdvo_dtd input_dtd;
138};
139
140struct psb_intel_sdvo_connector {
141 struct psb_intel_connector base;
142
143 /* Mark the type of connector */
144 uint16_t output_flag;
145
146 int force_audio;
147
148 /* This contains all current supported TV format */
149 u8 tv_format_supported[TV_FORMAT_NUM];
150 int format_supported_num;
151 struct drm_property *tv_format;
152
153 /* add the property for the SDVO-TV */
154 struct drm_property *left;
155 struct drm_property *right;
156 struct drm_property *top;
157 struct drm_property *bottom;
158 struct drm_property *hpos;
159 struct drm_property *vpos;
160 struct drm_property *contrast;
161 struct drm_property *saturation;
162 struct drm_property *hue;
163 struct drm_property *sharpness;
164 struct drm_property *flicker_filter;
165 struct drm_property *flicker_filter_adaptive;
166 struct drm_property *flicker_filter_2d;
167 struct drm_property *tv_chroma_filter;
168 struct drm_property *tv_luma_filter;
169 struct drm_property *dot_crawl;
170
171 /* add the property for the SDVO-TV/LVDS */
172 struct drm_property *brightness;
173
174 /* Add variable to record current setting for the above property */
175 u32 left_margin, right_margin, top_margin, bottom_margin;
176
177 /* this is to get the range of margin.*/
178 u32 max_hscan, max_vscan;
179 u32 max_hpos, cur_hpos;
180 u32 max_vpos, cur_vpos;
181 u32 cur_brightness, max_brightness;
182 u32 cur_contrast, max_contrast;
183 u32 cur_saturation, max_saturation;
184 u32 cur_hue, max_hue;
185 u32 cur_sharpness, max_sharpness;
186 u32 cur_flicker_filter, max_flicker_filter;
187 u32 cur_flicker_filter_adaptive, max_flicker_filter_adaptive;
188 u32 cur_flicker_filter_2d, max_flicker_filter_2d;
189 u32 cur_tv_chroma_filter, max_tv_chroma_filter;
190 u32 cur_tv_luma_filter, max_tv_luma_filter;
191 u32 cur_dot_crawl, max_dot_crawl;
192};
193
194static struct psb_intel_sdvo *to_psb_intel_sdvo(struct drm_encoder *encoder)
195{
196 return container_of(encoder, struct psb_intel_sdvo, base.base);
197}
198
199static struct psb_intel_sdvo *intel_attached_sdvo(struct drm_connector *connector)
200{
201 return container_of(psb_intel_attached_encoder(connector),
202 struct psb_intel_sdvo, base);
203}
204
205static struct psb_intel_sdvo_connector *to_psb_intel_sdvo_connector(struct drm_connector *connector)
206{
207 return container_of(to_psb_intel_connector(connector), struct psb_intel_sdvo_connector, base);
208}
209
210static bool
211psb_intel_sdvo_output_setup(struct psb_intel_sdvo *psb_intel_sdvo, uint16_t flags);
212static bool
213psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_sdvo,
214 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector,
215 int type);
216static bool
217psb_intel_sdvo_create_enhance_property(struct psb_intel_sdvo *psb_intel_sdvo,
218 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector);
219
220/**
221 * Writes the SDVOB or SDVOC with the given value, but always writes both
222 * SDVOB and SDVOC to work around apparent hardware issues (according to
223 * comments in the BIOS).
224 */
225static void psb_intel_sdvo_write_sdvox(struct psb_intel_sdvo *psb_intel_sdvo, u32 val)
226{
227 struct drm_device *dev = psb_intel_sdvo->base.base.dev;
228 u32 bval = val, cval = val;
229 int i;
230
231 if (psb_intel_sdvo->sdvo_reg == SDVOB) {
232 cval = REG_READ(SDVOC);
233 } else {
234 bval = REG_READ(SDVOB);
235 }
236 /*
237 * Write the registers twice for luck. Sometimes,
238 * writing them only once doesn't appear to 'stick'.
239 * The BIOS does this too. Yay, magic
240 */
241 for (i = 0; i < 2; i++)
242 {
243 REG_WRITE(SDVOB, bval);
244 REG_READ(SDVOB);
245 REG_WRITE(SDVOC, cval);
246 REG_READ(SDVOC);
247 }
248}
249
250static bool psb_intel_sdvo_read_byte(struct psb_intel_sdvo *psb_intel_sdvo, u8 addr, u8 *ch)
251{
252 struct i2c_msg msgs[] = {
253 {
254 .addr = psb_intel_sdvo->slave_addr,
255 .flags = 0,
256 .len = 1,
257 .buf = &addr,
258 },
259 {
260 .addr = psb_intel_sdvo->slave_addr,
261 .flags = I2C_M_RD,
262 .len = 1,
263 .buf = ch,
264 }
265 };
266 int ret;
267
268 if ((ret = i2c_transfer(psb_intel_sdvo->i2c, msgs, 2)) == 2)
269 return true;
270
271 DRM_DEBUG_KMS("i2c transfer returned %d\n", ret);
272 return false;
273}
274
275#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
276/** Mapping of command numbers to names, for debug output */
277static const struct _sdvo_cmd_name {
278 u8 cmd;
279 const char *name;
280} sdvo_cmd_names[] = {
281 SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
282 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
283 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV),
284 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS),
285 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS),
286 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS),
287 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP),
288 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP),
289 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS),
290 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
291 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
292 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
293 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE),
294 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
295 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
296 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
297 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2),
298 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
299 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2),
300 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
301 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1),
302 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2),
303 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1),
304 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2),
305 SDVO_CMD_NAME_ENTRY(SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING),
306 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1),
307 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2),
308 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE),
309 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE),
310 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS),
311 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT),
312 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT),
313 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
314 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
315 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
316 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_POWER_STATES),
317 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POWER_STATE),
318 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE),
319 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DISPLAY_POWER_STATE),
320 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
321 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT),
322 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT),
323 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS),
324
325 /* Add the op code for SDVO enhancements */
326 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HPOS),
327 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HPOS),
328 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HPOS),
329 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_VPOS),
330 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_VPOS),
331 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_VPOS),
332 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION),
333 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION),
334 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION),
335 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HUE),
336 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HUE),
337 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HUE),
338 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_CONTRAST),
339 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CONTRAST),
340 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTRAST),
341 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_BRIGHTNESS),
342 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_BRIGHTNESS),
343 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_BRIGHTNESS),
344 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_H),
345 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_H),
346 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_H),
347 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V),
348 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V),
349 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V),
350 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER),
351 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER),
352 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER),
353 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE),
354 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE),
355 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE),
356 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_2D),
357 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_2D),
358 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_2D),
359 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SHARPNESS),
360 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SHARPNESS),
361 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SHARPNESS),
362 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DOT_CRAWL),
363 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DOT_CRAWL),
364 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_CHROMA_FILTER),
365 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_CHROMA_FILTER),
366 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_CHROMA_FILTER),
367 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_LUMA_FILTER),
368 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_LUMA_FILTER),
369 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_LUMA_FILTER),
370
371 /* HDMI op code */
372 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE),
373 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE),
374 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODE),
375 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_PIXEL_REPLI),
376 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI),
377 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP),
378 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_COLORIMETRY),
379 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY),
380 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER),
381 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_AUDIO_STAT),
382 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT),
383 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX),
384 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX),
385 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO),
386 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT),
387 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_AV_SPLIT),
388 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE),
389 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE),
390 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA),
391 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA),
392};
393
394#define IS_SDVOB(reg) (reg == SDVOB)
395#define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC")
396
397static void psb_intel_sdvo_debug_write(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd,
398 const void *args, int args_len)
399{
400 int i;
401
402 DRM_DEBUG_KMS("%s: W: %02X ",
403 SDVO_NAME(psb_intel_sdvo), cmd);
404 for (i = 0; i < args_len; i++)
405 DRM_LOG_KMS("%02X ", ((u8 *)args)[i]);
406 for (; i < 8; i++)
407 DRM_LOG_KMS(" ");
408 for (i = 0; i < ARRAY_SIZE(sdvo_cmd_names); i++) {
409 if (cmd == sdvo_cmd_names[i].cmd) {
410 DRM_LOG_KMS("(%s)", sdvo_cmd_names[i].name);
411 break;
412 }
413 }
414 if (i == ARRAY_SIZE(sdvo_cmd_names))
415 DRM_LOG_KMS("(%02X)", cmd);
416 DRM_LOG_KMS("\n");
417}
418
419static const char *cmd_status_names[] = {
420 "Power on",
421 "Success",
422 "Not supported",
423 "Invalid arg",
424 "Pending",
425 "Target not specified",
426 "Scaling not supported"
427};
428
429static bool psb_intel_sdvo_write_cmd(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd,
430 const void *args, int args_len)
431{
432 u8 buf[args_len*2 + 2], status;
433 struct i2c_msg msgs[args_len + 3];
434 int i, ret;
435
436 psb_intel_sdvo_debug_write(psb_intel_sdvo, cmd, args, args_len);
437
438 for (i = 0; i < args_len; i++) {
439 msgs[i].addr = psb_intel_sdvo->slave_addr;
440 msgs[i].flags = 0;
441 msgs[i].len = 2;
442 msgs[i].buf = buf + 2 *i;
443 buf[2*i + 0] = SDVO_I2C_ARG_0 - i;
444 buf[2*i + 1] = ((u8*)args)[i];
445 }
446 msgs[i].addr = psb_intel_sdvo->slave_addr;
447 msgs[i].flags = 0;
448 msgs[i].len = 2;
449 msgs[i].buf = buf + 2*i;
450 buf[2*i + 0] = SDVO_I2C_OPCODE;
451 buf[2*i + 1] = cmd;
452
453 /* the following two are to read the response */
454 status = SDVO_I2C_CMD_STATUS;
455 msgs[i+1].addr = psb_intel_sdvo->slave_addr;
456 msgs[i+1].flags = 0;
457 msgs[i+1].len = 1;
458 msgs[i+1].buf = &status;
459
460 msgs[i+2].addr = psb_intel_sdvo->slave_addr;
461 msgs[i+2].flags = I2C_M_RD;
462 msgs[i+2].len = 1;
463 msgs[i+2].buf = &status;
464
465 ret = i2c_transfer(psb_intel_sdvo->i2c, msgs, i+3);
466 if (ret < 0) {
467 DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
468 return false;
469 }
470 if (ret != i+3) {
471 /* failure in I2C transfer */
472 DRM_DEBUG_KMS("I2c transfer returned %d/%d\n", ret, i+3);
473 return false;
474 }
475
476 return true;
477}
478
479static bool psb_intel_sdvo_read_response(struct psb_intel_sdvo *psb_intel_sdvo,
480 void *response, int response_len)
481{
482 u8 retry = 5;
483 u8 status;
484 int i;
485
486 DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(psb_intel_sdvo));
487
488 /*
489 * The documentation states that all commands will be
490 * processed within 15µs, and that we need only poll
491 * the status byte a maximum of 3 times in order for the
492 * command to be complete.
493 *
494 * Check 5 times in case the hardware failed to read the docs.
495 */
496 if (!psb_intel_sdvo_read_byte(psb_intel_sdvo,
497 SDVO_I2C_CMD_STATUS,
498 &status))
499 goto log_fail;
500
501 while (status == SDVO_CMD_STATUS_PENDING && retry--) {
502 udelay(15);
503 if (!psb_intel_sdvo_read_byte(psb_intel_sdvo,
504 SDVO_I2C_CMD_STATUS,
505 &status))
506 goto log_fail;
507 }
508
509 if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
510 DRM_LOG_KMS("(%s)", cmd_status_names[status]);
511 else
512 DRM_LOG_KMS("(??? %d)", status);
513
514 if (status != SDVO_CMD_STATUS_SUCCESS)
515 goto log_fail;
516
517 /* Read the command response */
518 for (i = 0; i < response_len; i++) {
519 if (!psb_intel_sdvo_read_byte(psb_intel_sdvo,
520 SDVO_I2C_RETURN_0 + i,
521 &((u8 *)response)[i]))
522 goto log_fail;
523 DRM_LOG_KMS(" %02X", ((u8 *)response)[i]);
524 }
525 DRM_LOG_KMS("\n");
526 return true;
527
528log_fail:
529 DRM_LOG_KMS("... failed\n");
530 return false;
531}
532
533static int psb_intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
534{
535 if (mode->clock >= 100000)
536 return 1;
537 else if (mode->clock >= 50000)
538 return 2;
539 else
540 return 4;
541}
542
543static bool psb_intel_sdvo_set_control_bus_switch(struct psb_intel_sdvo *psb_intel_sdvo,
544 u8 ddc_bus)
545{
546 /* This must be the immediately preceding write before the i2c xfer */
547 return psb_intel_sdvo_write_cmd(psb_intel_sdvo,
548 SDVO_CMD_SET_CONTROL_BUS_SWITCH,
549 &ddc_bus, 1);
550}
551
552static bool psb_intel_sdvo_set_value(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd, const void *data, int len)
553{
554 if (!psb_intel_sdvo_write_cmd(psb_intel_sdvo, cmd, data, len))
555 return false;
556
557 return psb_intel_sdvo_read_response(psb_intel_sdvo, NULL, 0);
558}
559
560static bool
561psb_intel_sdvo_get_value(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd, void *value, int len)
562{
563 if (!psb_intel_sdvo_write_cmd(psb_intel_sdvo, cmd, NULL, 0))
564 return false;
565
566 return psb_intel_sdvo_read_response(psb_intel_sdvo, value, len);
567}
568
569static bool psb_intel_sdvo_set_target_input(struct psb_intel_sdvo *psb_intel_sdvo)
570{
571 struct psb_intel_sdvo_set_target_input_args targets = {0};
572 return psb_intel_sdvo_set_value(psb_intel_sdvo,
573 SDVO_CMD_SET_TARGET_INPUT,
574 &targets, sizeof(targets));
575}
576
577/**
578 * Return whether each input is trained.
579 *
580 * This function is making an assumption about the layout of the response,
581 * which should be checked against the docs.
582 */
583static bool psb_intel_sdvo_get_trained_inputs(struct psb_intel_sdvo *psb_intel_sdvo, bool *input_1, bool *input_2)
584{
585 struct psb_intel_sdvo_get_trained_inputs_response response;
586
587 BUILD_BUG_ON(sizeof(response) != 1);
588 if (!psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS,
589 &response, sizeof(response)))
590 return false;
591
592 *input_1 = response.input0_trained;
593 *input_2 = response.input1_trained;
594 return true;
595}
596
597static bool psb_intel_sdvo_set_active_outputs(struct psb_intel_sdvo *psb_intel_sdvo,
598 u16 outputs)
599{
600 return psb_intel_sdvo_set_value(psb_intel_sdvo,
601 SDVO_CMD_SET_ACTIVE_OUTPUTS,
602 &outputs, sizeof(outputs));
603}
604
605static bool psb_intel_sdvo_set_encoder_power_state(struct psb_intel_sdvo *psb_intel_sdvo,
606 int mode)
607{
608 u8 state = SDVO_ENCODER_STATE_ON;
609
610 switch (mode) {
611 case DRM_MODE_DPMS_ON:
612 state = SDVO_ENCODER_STATE_ON;
613 break;
614 case DRM_MODE_DPMS_STANDBY:
615 state = SDVO_ENCODER_STATE_STANDBY;
616 break;
617 case DRM_MODE_DPMS_SUSPEND:
618 state = SDVO_ENCODER_STATE_SUSPEND;
619 break;
620 case DRM_MODE_DPMS_OFF:
621 state = SDVO_ENCODER_STATE_OFF;
622 break;
623 }
624
625 return psb_intel_sdvo_set_value(psb_intel_sdvo,
626 SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state));
627}
628
629static bool psb_intel_sdvo_get_input_pixel_clock_range(struct psb_intel_sdvo *psb_intel_sdvo,
630 int *clock_min,
631 int *clock_max)
632{
633 struct psb_intel_sdvo_pixel_clock_range clocks;
634
635 BUILD_BUG_ON(sizeof(clocks) != 4);
636 if (!psb_intel_sdvo_get_value(psb_intel_sdvo,
637 SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
638 &clocks, sizeof(clocks)))
639 return false;
640
641 /* Convert the values from units of 10 kHz to kHz. */
642 *clock_min = clocks.min * 10;
643 *clock_max = clocks.max * 10;
644 return true;
645}
646
647static bool psb_intel_sdvo_set_target_output(struct psb_intel_sdvo *psb_intel_sdvo,
648 u16 outputs)
649{
650 return psb_intel_sdvo_set_value(psb_intel_sdvo,
651 SDVO_CMD_SET_TARGET_OUTPUT,
652 &outputs, sizeof(outputs));
653}
654
655static bool psb_intel_sdvo_set_timing(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd,
656 struct psb_intel_sdvo_dtd *dtd)
657{
658 return psb_intel_sdvo_set_value(psb_intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) &&
659 psb_intel_sdvo_set_value(psb_intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
660}
661
662static bool psb_intel_sdvo_set_input_timing(struct psb_intel_sdvo *psb_intel_sdvo,
663 struct psb_intel_sdvo_dtd *dtd)
664{
665 return psb_intel_sdvo_set_timing(psb_intel_sdvo,
666 SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
667}
668
669static bool psb_intel_sdvo_set_output_timing(struct psb_intel_sdvo *psb_intel_sdvo,
670 struct psb_intel_sdvo_dtd *dtd)
671{
672 return psb_intel_sdvo_set_timing(psb_intel_sdvo,
673 SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
674}
675
676static bool
677psb_intel_sdvo_create_preferred_input_timing(struct psb_intel_sdvo *psb_intel_sdvo,
678 uint16_t clock,
679 uint16_t width,
680 uint16_t height)
681{
682 struct psb_intel_sdvo_preferred_input_timing_args args;
683
684 memset(&args, 0, sizeof(args));
685 args.clock = clock;
686 args.width = width;
687 args.height = height;
688 args.interlace = 0;
689
690 if (psb_intel_sdvo->is_lvds &&
691 (psb_intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width ||
692 psb_intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height))
693 args.scaled = 1;
694
695 return psb_intel_sdvo_set_value(psb_intel_sdvo,
696 SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
697 &args, sizeof(args));
698}
699
700static bool psb_intel_sdvo_get_preferred_input_timing(struct psb_intel_sdvo *psb_intel_sdvo,
701 struct psb_intel_sdvo_dtd *dtd)
702{
703 BUILD_BUG_ON(sizeof(dtd->part1) != 8);
704 BUILD_BUG_ON(sizeof(dtd->part2) != 8);
705 return psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
706 &dtd->part1, sizeof(dtd->part1)) &&
707 psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
708 &dtd->part2, sizeof(dtd->part2));
709}
710
711static bool psb_intel_sdvo_set_clock_rate_mult(struct psb_intel_sdvo *psb_intel_sdvo, u8 val)
712{
713 return psb_intel_sdvo_set_value(psb_intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
714}
715
716static void psb_intel_sdvo_get_dtd_from_mode(struct psb_intel_sdvo_dtd *dtd,
717 const struct drm_display_mode *mode)
718{
719 uint16_t width, height;
720 uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
721 uint16_t h_sync_offset, v_sync_offset;
722
723 width = mode->crtc_hdisplay;
724 height = mode->crtc_vdisplay;
725
726 /* do some mode translations */
727 h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
728 h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
729
730 v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
731 v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
732
733 h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
734 v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
735
736 dtd->part1.clock = mode->clock / 10;
737 dtd->part1.h_active = width & 0xff;
738 dtd->part1.h_blank = h_blank_len & 0xff;
739 dtd->part1.h_high = (((width >> 8) & 0xf) << 4) |
740 ((h_blank_len >> 8) & 0xf);
741 dtd->part1.v_active = height & 0xff;
742 dtd->part1.v_blank = v_blank_len & 0xff;
743 dtd->part1.v_high = (((height >> 8) & 0xf) << 4) |
744 ((v_blank_len >> 8) & 0xf);
745
746 dtd->part2.h_sync_off = h_sync_offset & 0xff;
747 dtd->part2.h_sync_width = h_sync_len & 0xff;
748 dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
749 (v_sync_len & 0xf);
750 dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) |
751 ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) |
752 ((v_sync_len & 0x30) >> 4);
753
754 dtd->part2.dtd_flags = 0x18;
755 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
756 dtd->part2.dtd_flags |= 0x2;
757 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
758 dtd->part2.dtd_flags |= 0x4;
759
760 dtd->part2.sdvo_flags = 0;
761 dtd->part2.v_sync_off_high = v_sync_offset & 0xc0;
762 dtd->part2.reserved = 0;
763}
764
765static void psb_intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
766 const struct psb_intel_sdvo_dtd *dtd)
767{
768 mode->hdisplay = dtd->part1.h_active;
769 mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
770 mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off;
771 mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2;
772 mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width;
773 mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4;
774 mode->htotal = mode->hdisplay + dtd->part1.h_blank;
775 mode->htotal += (dtd->part1.h_high & 0xf) << 8;
776
777 mode->vdisplay = dtd->part1.v_active;
778 mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8;
779 mode->vsync_start = mode->vdisplay;
780 mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf;
781 mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2;
782 mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0;
783 mode->vsync_end = mode->vsync_start +
784 (dtd->part2.v_sync_off_width & 0xf);
785 mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4;
786 mode->vtotal = mode->vdisplay + dtd->part1.v_blank;
787 mode->vtotal += (dtd->part1.v_high & 0xf) << 8;
788
789 mode->clock = dtd->part1.clock * 10;
790
791 mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
792 if (dtd->part2.dtd_flags & 0x2)
793 mode->flags |= DRM_MODE_FLAG_PHSYNC;
794 if (dtd->part2.dtd_flags & 0x4)
795 mode->flags |= DRM_MODE_FLAG_PVSYNC;
796}
797
798static bool psb_intel_sdvo_check_supp_encode(struct psb_intel_sdvo *psb_intel_sdvo)
799{
800 struct psb_intel_sdvo_encode encode;
801
802 BUILD_BUG_ON(sizeof(encode) != 2);
803 return psb_intel_sdvo_get_value(psb_intel_sdvo,
804 SDVO_CMD_GET_SUPP_ENCODE,
805 &encode, sizeof(encode));
806}
807
808static bool psb_intel_sdvo_set_encode(struct psb_intel_sdvo *psb_intel_sdvo,
809 uint8_t mode)
810{
811 return psb_intel_sdvo_set_value(psb_intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1);
812}
813
814static bool psb_intel_sdvo_set_colorimetry(struct psb_intel_sdvo *psb_intel_sdvo,
815 uint8_t mode)
816{
817 return psb_intel_sdvo_set_value(psb_intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
818}
819
820#if 0
821static void psb_intel_sdvo_dump_hdmi_buf(struct psb_intel_sdvo *psb_intel_sdvo)
822{
823 int i, j;
824 uint8_t set_buf_index[2];
825 uint8_t av_split;
826 uint8_t buf_size;
827 uint8_t buf[48];
828 uint8_t *pos;
829
830 psb_intel_sdvo_get_value(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, &av_split, 1);
831
832 for (i = 0; i <= av_split; i++) {
833 set_buf_index[0] = i; set_buf_index[1] = 0;
834 psb_intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX,
835 set_buf_index, 2);
836 psb_intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
837 psb_intel_sdvo_read_response(encoder, &buf_size, 1);
838
839 pos = buf;
840 for (j = 0; j <= buf_size; j += 8) {
841 psb_intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA,
842 NULL, 0);
843 psb_intel_sdvo_read_response(encoder, pos, 8);
844 pos += 8;
845 }
846 }
847}
848#endif
849
850static bool psb_intel_sdvo_set_avi_infoframe(struct psb_intel_sdvo *psb_intel_sdvo)
851{
852 DRM_INFO("HDMI is not supported yet");
853
854 return false;
855#if 0
856 struct dip_infoframe avi_if = {
857 .type = DIP_TYPE_AVI,
858 .ver = DIP_VERSION_AVI,
859 .len = DIP_LEN_AVI,
860 };
861 uint8_t tx_rate = SDVO_HBUF_TX_VSYNC;
862 uint8_t set_buf_index[2] = { 1, 0 };
863 uint64_t *data = (uint64_t *)&avi_if;
864 unsigned i;
865
866 intel_dip_infoframe_csum(&avi_if);
867
868 if (!psb_intel_sdvo_set_value(psb_intel_sdvo,
869 SDVO_CMD_SET_HBUF_INDEX,
870 set_buf_index, 2))
871 return false;
872
873 for (i = 0; i < sizeof(avi_if); i += 8) {
874 if (!psb_intel_sdvo_set_value(psb_intel_sdvo,
875 SDVO_CMD_SET_HBUF_DATA,
876 data, 8))
877 return false;
878 data++;
879 }
880
881 return psb_intel_sdvo_set_value(psb_intel_sdvo,
882 SDVO_CMD_SET_HBUF_TXRATE,
883 &tx_rate, 1);
884#endif
885}
886
887static bool psb_intel_sdvo_set_tv_format(struct psb_intel_sdvo *psb_intel_sdvo)
888{
889 struct psb_intel_sdvo_tv_format format;
890 uint32_t format_map;
891
892 format_map = 1 << psb_intel_sdvo->tv_format_index;
893 memset(&format, 0, sizeof(format));
894 memcpy(&format, &format_map, min(sizeof(format), sizeof(format_map)));
895
896 BUILD_BUG_ON(sizeof(format) != 6);
897 return psb_intel_sdvo_set_value(psb_intel_sdvo,
898 SDVO_CMD_SET_TV_FORMAT,
899 &format, sizeof(format));
900}
901
902static bool
903psb_intel_sdvo_set_output_timings_from_mode(struct psb_intel_sdvo *psb_intel_sdvo,
904 struct drm_display_mode *mode)
905{
906 struct psb_intel_sdvo_dtd output_dtd;
907
908 if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo,
909 psb_intel_sdvo->attached_output))
910 return false;
911
912 psb_intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
913 if (!psb_intel_sdvo_set_output_timing(psb_intel_sdvo, &output_dtd))
914 return false;
915
916 return true;
917}
918
919static bool
920psb_intel_sdvo_set_input_timings_for_mode(struct psb_intel_sdvo *psb_intel_sdvo,
921 struct drm_display_mode *mode,
922 struct drm_display_mode *adjusted_mode)
923{
924 /* Reset the input timing to the screen. Assume always input 0. */
925 if (!psb_intel_sdvo_set_target_input(psb_intel_sdvo))
926 return false;
927
928 if (!psb_intel_sdvo_create_preferred_input_timing(psb_intel_sdvo,
929 mode->clock / 10,
930 mode->hdisplay,
931 mode->vdisplay))
932 return false;
933
934 if (!psb_intel_sdvo_get_preferred_input_timing(psb_intel_sdvo,
935 &psb_intel_sdvo->input_dtd))
936 return false;
937
938 psb_intel_sdvo_get_mode_from_dtd(adjusted_mode, &psb_intel_sdvo->input_dtd);
939
940 drm_mode_set_crtcinfo(adjusted_mode, 0);
941 return true;
942}
943
944static bool psb_intel_sdvo_mode_fixup(struct drm_encoder *encoder,
945 struct drm_display_mode *mode,
946 struct drm_display_mode *adjusted_mode)
947{
948 struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder);
949 int multiplier;
950
951 /* We need to construct preferred input timings based on our
952 * output timings. To do that, we have to set the output
953 * timings, even though this isn't really the right place in
954 * the sequence to do it. Oh well.
955 */
956 if (psb_intel_sdvo->is_tv) {
957 if (!psb_intel_sdvo_set_output_timings_from_mode(psb_intel_sdvo, mode))
958 return false;
959
960 (void) psb_intel_sdvo_set_input_timings_for_mode(psb_intel_sdvo,
961 mode,
962 adjusted_mode);
963 } else if (psb_intel_sdvo->is_lvds) {
964 if (!psb_intel_sdvo_set_output_timings_from_mode(psb_intel_sdvo,
965 psb_intel_sdvo->sdvo_lvds_fixed_mode))
966 return false;
967
968 (void) psb_intel_sdvo_set_input_timings_for_mode(psb_intel_sdvo,
969 mode,
970 adjusted_mode);
971 }
972
973 /* Make the CRTC code factor in the SDVO pixel multiplier. The
974 * SDVO device will factor out the multiplier during mode_set.
975 */
976 multiplier = psb_intel_sdvo_get_pixel_multiplier(adjusted_mode);
977 psb_intel_mode_set_pixel_multiplier(adjusted_mode, multiplier);
978
979 return true;
980}
981
982static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder,
983 struct drm_display_mode *mode,
984 struct drm_display_mode *adjusted_mode)
985{
986 struct drm_device *dev = encoder->dev;
987 struct drm_crtc *crtc = encoder->crtc;
988 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
989 struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder);
990 u32 sdvox;
991 struct psb_intel_sdvo_in_out_map in_out;
992 struct psb_intel_sdvo_dtd input_dtd;
993 int pixel_multiplier = psb_intel_mode_get_pixel_multiplier(adjusted_mode);
994 int rate;
995
996 if (!mode)
997 return;
998
999 /* First, set the input mapping for the first input to our controlled
1000 * output. This is only correct if we're a single-input device, in
1001 * which case the first input is the output from the appropriate SDVO
1002 * channel on the motherboard. In a two-input device, the first input
1003 * will be SDVOB and the second SDVOC.
1004 */
1005 in_out.in0 = psb_intel_sdvo->attached_output;
1006 in_out.in1 = 0;
1007
1008 psb_intel_sdvo_set_value(psb_intel_sdvo,
1009 SDVO_CMD_SET_IN_OUT_MAP,
1010 &in_out, sizeof(in_out));
1011
1012 /* Set the output timings to the screen */
1013 if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo,
1014 psb_intel_sdvo->attached_output))
1015 return;
1016
1017 /* We have tried to get input timing in mode_fixup, and filled into
1018 * adjusted_mode.
1019 */
1020 if (psb_intel_sdvo->is_tv || psb_intel_sdvo->is_lvds) {
1021 input_dtd = psb_intel_sdvo->input_dtd;
1022 } else {
1023 /* Set the output timing to the screen */
1024 if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo,
1025 psb_intel_sdvo->attached_output))
1026 return;
1027
1028 psb_intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
1029 (void) psb_intel_sdvo_set_output_timing(psb_intel_sdvo, &input_dtd);
1030 }
1031
1032 /* Set the input timing to the screen. Assume always input 0. */
1033 if (!psb_intel_sdvo_set_target_input(psb_intel_sdvo))
1034 return;
1035
1036 if (psb_intel_sdvo->has_hdmi_monitor) {
1037 psb_intel_sdvo_set_encode(psb_intel_sdvo, SDVO_ENCODE_HDMI);
1038 psb_intel_sdvo_set_colorimetry(psb_intel_sdvo,
1039 SDVO_COLORIMETRY_RGB256);
1040 psb_intel_sdvo_set_avi_infoframe(psb_intel_sdvo);
1041 } else
1042 psb_intel_sdvo_set_encode(psb_intel_sdvo, SDVO_ENCODE_DVI);
1043
1044 if (psb_intel_sdvo->is_tv &&
1045 !psb_intel_sdvo_set_tv_format(psb_intel_sdvo))
1046 return;
1047
1048 (void) psb_intel_sdvo_set_input_timing(psb_intel_sdvo, &input_dtd);
1049
1050 switch (pixel_multiplier) {
1051 default:
1052 case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;
1053 case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break;
1054 case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break;
1055 }
1056 if (!psb_intel_sdvo_set_clock_rate_mult(psb_intel_sdvo, rate))
1057 return;
1058
1059 /* Set the SDVO control regs. */
1060 sdvox = REG_READ(psb_intel_sdvo->sdvo_reg);
1061 switch (psb_intel_sdvo->sdvo_reg) {
1062 case SDVOB:
1063 sdvox &= SDVOB_PRESERVE_MASK;
1064 break;
1065 case SDVOC:
1066 sdvox &= SDVOC_PRESERVE_MASK;
1067 break;
1068 }
1069 sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
1070
1071 if (psb_intel_crtc->pipe == 1)
1072 sdvox |= SDVO_PIPE_B_SELECT;
1073 if (psb_intel_sdvo->has_hdmi_audio)
1074 sdvox |= SDVO_AUDIO_ENABLE;
1075
1076 /* FIXME: Check if this is needed for PSB
1077 sdvox |= (pixel_multiplier - 1) << SDVO_PORT_MULTIPLY_SHIFT;
1078 */
1079
1080 if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL)
1081 sdvox |= SDVO_STALL_SELECT;
1082 psb_intel_sdvo_write_sdvox(psb_intel_sdvo, sdvox);
1083}
1084
1085static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
1086{
1087 struct drm_device *dev = encoder->dev;
1088 struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder);
1089 u32 temp;
1090
1091 switch (mode) {
1092 case DRM_MODE_DPMS_ON:
1093 DRM_DEBUG("DPMS_ON");
1094 break;
1095 case DRM_MODE_DPMS_OFF:
1096 DRM_DEBUG("DPMS_OFF");
1097 break;
1098 default:
1099 DRM_DEBUG("DPMS: %d", mode);
1100 }
1101
1102 if (mode != DRM_MODE_DPMS_ON) {
1103 psb_intel_sdvo_set_active_outputs(psb_intel_sdvo, 0);
1104 if (0)
1105 psb_intel_sdvo_set_encoder_power_state(psb_intel_sdvo, mode);
1106
1107 if (mode == DRM_MODE_DPMS_OFF) {
1108 temp = REG_READ(psb_intel_sdvo->sdvo_reg);
1109 if ((temp & SDVO_ENABLE) != 0) {
1110 psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp & ~SDVO_ENABLE);
1111 }
1112 }
1113 } else {
1114 bool input1, input2;
1115 int i;
1116 u8 status;
1117
1118 temp = REG_READ(psb_intel_sdvo->sdvo_reg);
1119 if ((temp & SDVO_ENABLE) == 0)
1120 psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp | SDVO_ENABLE);
1121 for (i = 0; i < 2; i++)
1122 psb_intel_wait_for_vblank(dev);
1123
1124 status = psb_intel_sdvo_get_trained_inputs(psb_intel_sdvo, &input1, &input2);
1125 /* Warn if the device reported failure to sync.
1126 * A lot of SDVO devices fail to notify of sync, but it's
1127 * a given it the status is a success, we succeeded.
1128 */
1129 if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
1130 DRM_DEBUG_KMS("First %s output reported failure to "
1131 "sync\n", SDVO_NAME(psb_intel_sdvo));
1132 }
1133
1134 if (0)
1135 psb_intel_sdvo_set_encoder_power_state(psb_intel_sdvo, mode);
1136 psb_intel_sdvo_set_active_outputs(psb_intel_sdvo, psb_intel_sdvo->attached_output);
1137 }
1138 return;
1139}
1140
1141static int psb_intel_sdvo_mode_valid(struct drm_connector *connector,
1142 struct drm_display_mode *mode)
1143{
1144 struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector);
1145
1146 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
1147 return MODE_NO_DBLESCAN;
1148
1149 if (psb_intel_sdvo->pixel_clock_min > mode->clock)
1150 return MODE_CLOCK_LOW;
1151
1152 if (psb_intel_sdvo->pixel_clock_max < mode->clock)
1153 return MODE_CLOCK_HIGH;
1154
1155 if (psb_intel_sdvo->is_lvds) {
1156 if (mode->hdisplay > psb_intel_sdvo->sdvo_lvds_fixed_mode->hdisplay)
1157 return MODE_PANEL;
1158
1159 if (mode->vdisplay > psb_intel_sdvo->sdvo_lvds_fixed_mode->vdisplay)
1160 return MODE_PANEL;
1161 }
1162
1163 return MODE_OK;
1164}
1165
1166static bool psb_intel_sdvo_get_capabilities(struct psb_intel_sdvo *psb_intel_sdvo, struct psb_intel_sdvo_caps *caps)
1167{
1168 BUILD_BUG_ON(sizeof(*caps) != 8);
1169 if (!psb_intel_sdvo_get_value(psb_intel_sdvo,
1170 SDVO_CMD_GET_DEVICE_CAPS,
1171 caps, sizeof(*caps)))
1172 return false;
1173
1174 DRM_DEBUG_KMS("SDVO capabilities:\n"
1175 " vendor_id: %d\n"
1176 " device_id: %d\n"
1177 " device_rev_id: %d\n"
1178 " sdvo_version_major: %d\n"
1179 " sdvo_version_minor: %d\n"
1180 " sdvo_inputs_mask: %d\n"
1181 " smooth_scaling: %d\n"
1182 " sharp_scaling: %d\n"
1183 " up_scaling: %d\n"
1184 " down_scaling: %d\n"
1185 " stall_support: %d\n"
1186 " output_flags: %d\n",
1187 caps->vendor_id,
1188 caps->device_id,
1189 caps->device_rev_id,
1190 caps->sdvo_version_major,
1191 caps->sdvo_version_minor,
1192 caps->sdvo_inputs_mask,
1193 caps->smooth_scaling,
1194 caps->sharp_scaling,
1195 caps->up_scaling,
1196 caps->down_scaling,
1197 caps->stall_support,
1198 caps->output_flags);
1199
1200 return true;
1201}
1202
1203/* No use! */
1204#if 0
1205struct drm_connector* psb_intel_sdvo_find(struct drm_device *dev, int sdvoB)
1206{
1207 struct drm_connector *connector = NULL;
1208 struct psb_intel_sdvo *iout = NULL;
1209 struct psb_intel_sdvo *sdvo;
1210
1211 /* find the sdvo connector */
1212 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1213 iout = to_psb_intel_sdvo(connector);
1214
1215 if (iout->type != INTEL_OUTPUT_SDVO)
1216 continue;
1217
1218 sdvo = iout->dev_priv;
1219
1220 if (sdvo->sdvo_reg == SDVOB && sdvoB)
1221 return connector;
1222
1223 if (sdvo->sdvo_reg == SDVOC && !sdvoB)
1224 return connector;
1225
1226 }
1227
1228 return NULL;
1229}
1230
1231int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector)
1232{
1233 u8 response[2];
1234 u8 status;
1235 struct psb_intel_sdvo *psb_intel_sdvo;
1236 DRM_DEBUG_KMS("\n");
1237
1238 if (!connector)
1239 return 0;
1240
1241 psb_intel_sdvo = to_psb_intel_sdvo(connector);
1242
1243 return psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT,
1244 &response, 2) && response[0];
1245}
1246
1247void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
1248{
1249 u8 response[2];
1250 u8 status;
1251 struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(connector);
1252
1253 psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
1254 psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2);
1255
1256 if (on) {
1257 psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
1258 status = psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2);
1259
1260 psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
1261 } else {
1262 response[0] = 0;
1263 response[1] = 0;
1264 psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
1265 }
1266
1267 psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
1268 psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2);
1269}
1270#endif
1271
1272static bool
1273psb_intel_sdvo_multifunc_encoder(struct psb_intel_sdvo *psb_intel_sdvo)
1274{
1275 /* Is there more than one type of output? */
1276 int caps = psb_intel_sdvo->caps.output_flags & 0xf;
1277 return caps & -caps;
1278}
1279
1280static struct edid *
1281psb_intel_sdvo_get_edid(struct drm_connector *connector)
1282{
1283 struct psb_intel_sdvo *sdvo = intel_attached_sdvo(connector);
1284 return drm_get_edid(connector, &sdvo->ddc);
1285}
1286
1287/* Mac mini hack -- use the same DDC as the analog connector */
1288static struct edid *
1289psb_intel_sdvo_get_analog_edid(struct drm_connector *connector)
1290{
1291 struct drm_psb_private *dev_priv = connector->dev->dev_private;
1292
1293 return drm_get_edid(connector,
1294 &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
1295 return NULL;
1296}
1297
1298enum drm_connector_status
1299psb_intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
1300{
1301 struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector);
1302 enum drm_connector_status status;
1303 struct edid *edid;
1304
1305 edid = psb_intel_sdvo_get_edid(connector);
1306
1307 if (edid == NULL && psb_intel_sdvo_multifunc_encoder(psb_intel_sdvo)) {
1308 u8 ddc, saved_ddc = psb_intel_sdvo->ddc_bus;
1309
1310 /*
1311 * Don't use the 1 as the argument of DDC bus switch to get
1312 * the EDID. It is used for SDVO SPD ROM.
1313 */
1314 for (ddc = psb_intel_sdvo->ddc_bus >> 1; ddc > 1; ddc >>= 1) {
1315 psb_intel_sdvo->ddc_bus = ddc;
1316 edid = psb_intel_sdvo_get_edid(connector);
1317 if (edid)
1318 break;
1319 }
1320 /*
1321 * If we found the EDID on the other bus,
1322 * assume that is the correct DDC bus.
1323 */
1324 if (edid == NULL)
1325 psb_intel_sdvo->ddc_bus = saved_ddc;
1326 }
1327
1328 /*
1329 * When there is no edid and no monitor is connected with VGA
1330 * port, try to use the CRT ddc to read the EDID for DVI-connector.
1331 */
1332 if (edid == NULL)
1333 edid = psb_intel_sdvo_get_analog_edid(connector);
1334
1335 status = connector_status_unknown;
1336 if (edid != NULL) {
1337 /* DDC bus is shared, match EDID to connector type */
1338 if (edid->input & DRM_EDID_INPUT_DIGITAL) {
1339 status = connector_status_connected;
1340 if (psb_intel_sdvo->is_hdmi) {
1341 psb_intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid);
1342 psb_intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid);
1343 }
1344 } else
1345 status = connector_status_disconnected;
1346 connector->display_info.raw_edid = NULL;
1347 kfree(edid);
1348 }
1349
1350 if (status == connector_status_connected) {
1351 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector);
1352 if (psb_intel_sdvo_connector->force_audio)
1353 psb_intel_sdvo->has_hdmi_audio = psb_intel_sdvo_connector->force_audio > 0;
1354 }
1355
1356 return status;
1357}
1358
1359static enum drm_connector_status
1360psb_intel_sdvo_detect(struct drm_connector *connector, bool force)
1361{
1362 uint16_t response;
1363 struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector);
1364 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector);
1365 enum drm_connector_status ret;
1366
1367 if (!psb_intel_sdvo_write_cmd(psb_intel_sdvo,
1368 SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0))
1369 return connector_status_unknown;
1370
1371 /* add 30ms delay when the output type might be TV */
1372 if (psb_intel_sdvo->caps.output_flags &
1373 (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_CVBS0))
1374 mdelay(30);
1375
1376 if (!psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2))
1377 return connector_status_unknown;
1378
1379 DRM_DEBUG_KMS("SDVO response %d %d [%x]\n",
1380 response & 0xff, response >> 8,
1381 psb_intel_sdvo_connector->output_flag);
1382
1383 if (response == 0)
1384 return connector_status_disconnected;
1385
1386 psb_intel_sdvo->attached_output = response;
1387
1388 psb_intel_sdvo->has_hdmi_monitor = false;
1389 psb_intel_sdvo->has_hdmi_audio = false;
1390
1391 if ((psb_intel_sdvo_connector->output_flag & response) == 0)
1392 ret = connector_status_disconnected;
1393 else if (IS_TMDS(psb_intel_sdvo_connector))
1394 ret = psb_intel_sdvo_hdmi_sink_detect(connector);
1395 else {
1396 struct edid *edid;
1397
1398 /* if we have an edid check it matches the connection */
1399 edid = psb_intel_sdvo_get_edid(connector);
1400 if (edid == NULL)
1401 edid = psb_intel_sdvo_get_analog_edid(connector);
1402 if (edid != NULL) {
1403 if (edid->input & DRM_EDID_INPUT_DIGITAL)
1404 ret = connector_status_disconnected;
1405 else
1406 ret = connector_status_connected;
1407 connector->display_info.raw_edid = NULL;
1408 kfree(edid);
1409 } else
1410 ret = connector_status_connected;
1411 }
1412
1413 /* May update encoder flag for like clock for SDVO TV, etc.*/
1414 if (ret == connector_status_connected) {
1415 psb_intel_sdvo->is_tv = false;
1416 psb_intel_sdvo->is_lvds = false;
1417 psb_intel_sdvo->base.needs_tv_clock = false;
1418
1419 if (response & SDVO_TV_MASK) {
1420 psb_intel_sdvo->is_tv = true;
1421 psb_intel_sdvo->base.needs_tv_clock = true;
1422 }
1423 if (response & SDVO_LVDS_MASK)
1424 psb_intel_sdvo->is_lvds = psb_intel_sdvo->sdvo_lvds_fixed_mode != NULL;
1425 }
1426
1427 return ret;
1428}
1429
1430static void psb_intel_sdvo_get_ddc_modes(struct drm_connector *connector)
1431{
1432 struct edid *edid;
1433
1434 /* set the bus switch and get the modes */
1435 edid = psb_intel_sdvo_get_edid(connector);
1436
1437 /*
1438 * Mac mini hack. On this device, the DVI-I connector shares one DDC
1439 * link between analog and digital outputs. So, if the regular SDVO
1440 * DDC fails, check to see if the analog output is disconnected, in
1441 * which case we'll look there for the digital DDC data.
1442 */
1443 if (edid == NULL)
1444 edid = psb_intel_sdvo_get_analog_edid(connector);
1445
1446 if (edid != NULL) {
1447 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector);
1448 bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL);
1449 bool connector_is_digital = !!IS_TMDS(psb_intel_sdvo_connector);
1450
1451 if (connector_is_digital == monitor_is_digital) {
1452 drm_mode_connector_update_edid_property(connector, edid);
1453 drm_add_edid_modes(connector, edid);
1454 }
1455
1456 connector->display_info.raw_edid = NULL;
1457 kfree(edid);
1458 }
1459}
1460
1461/*
1462 * Set of SDVO TV modes.
1463 * Note! This is in reply order (see loop in get_tv_modes).
1464 * XXX: all 60Hz refresh?
1465 */
1466static const struct drm_display_mode sdvo_tv_modes[] = {
1467 { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815, 320, 321, 384,
1468 416, 0, 200, 201, 232, 233, 0,
1469 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1470 { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814, 320, 321, 384,
1471 416, 0, 240, 241, 272, 273, 0,
1472 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1473 { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910, 400, 401, 464,
1474 496, 0, 300, 301, 332, 333, 0,
1475 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1476 { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913, 640, 641, 704,
1477 736, 0, 350, 351, 382, 383, 0,
1478 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1479 { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121, 640, 641, 704,
1480 736, 0, 400, 401, 432, 433, 0,
1481 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1482 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 22654, 640, 641, 704,
1483 736, 0, 480, 481, 512, 513, 0,
1484 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1485 { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624, 704, 705, 768,
1486 800, 0, 480, 481, 512, 513, 0,
1487 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1488 { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232, 704, 705, 768,
1489 800, 0, 576, 577, 608, 609, 0,
1490 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1491 { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751, 720, 721, 784,
1492 816, 0, 350, 351, 382, 383, 0,
1493 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1494 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199, 720, 721, 784,
1495 816, 0, 400, 401, 432, 433, 0,
1496 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1497 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116, 720, 721, 784,
1498 816, 0, 480, 481, 512, 513, 0,
1499 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1500 { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054, 720, 721, 784,
1501 816, 0, 540, 541, 572, 573, 0,
1502 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1503 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816, 720, 721, 784,
1504 816, 0, 576, 577, 608, 609, 0,
1505 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1506 { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570, 768, 769, 832,
1507 864, 0, 576, 577, 608, 609, 0,
1508 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1509 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030, 800, 801, 864,
1510 896, 0, 600, 601, 632, 633, 0,
1511 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1512 { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581, 832, 833, 896,
1513 928, 0, 624, 625, 656, 657, 0,
1514 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1515 { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707, 920, 921, 984,
1516 1016, 0, 766, 767, 798, 799, 0,
1517 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1518 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827, 1024, 1025, 1088,
1519 1120, 0, 768, 769, 800, 801, 0,
1520 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1521 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265, 1280, 1281, 1344,
1522 1376, 0, 1024, 1025, 1056, 1057, 0,
1523 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1524};
1525
1526static void psb_intel_sdvo_get_tv_modes(struct drm_connector *connector)
1527{
1528 struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector);
1529 struct psb_intel_sdvo_sdtv_resolution_request tv_res;
1530 uint32_t reply = 0, format_map = 0;
1531 int i;
1532
1533 /* Read the list of supported input resolutions for the selected TV
1534 * format.
1535 */
1536 format_map = 1 << psb_intel_sdvo->tv_format_index;
1537 memcpy(&tv_res, &format_map,
1538 min(sizeof(format_map), sizeof(struct psb_intel_sdvo_sdtv_resolution_request)));
1539
1540 if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo, psb_intel_sdvo->attached_output))
1541 return;
1542
1543 BUILD_BUG_ON(sizeof(tv_res) != 3);
1544 if (!psb_intel_sdvo_write_cmd(psb_intel_sdvo,
1545 SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
1546 &tv_res, sizeof(tv_res)))
1547 return;
1548 if (!psb_intel_sdvo_read_response(psb_intel_sdvo, &reply, 3))
1549 return;
1550
1551 for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++)
1552 if (reply & (1 << i)) {
1553 struct drm_display_mode *nmode;
1554 nmode = drm_mode_duplicate(connector->dev,
1555 &sdvo_tv_modes[i]);
1556 if (nmode)
1557 drm_mode_probed_add(connector, nmode);
1558 }
1559}
1560
1561static void psb_intel_sdvo_get_lvds_modes(struct drm_connector *connector)
1562{
1563 struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector);
1564 struct drm_psb_private *dev_priv = connector->dev->dev_private;
1565 struct drm_display_mode *newmode;
1566
1567 /*
1568 * Attempt to get the mode list from DDC.
1569 * Assume that the preferred modes are
1570 * arranged in priority order.
1571 */
1572 psb_intel_ddc_get_modes(connector, psb_intel_sdvo->i2c);
1573 if (list_empty(&connector->probed_modes) == false)
1574 goto end;
1575
1576 /* Fetch modes from VBT */
1577 if (dev_priv->sdvo_lvds_vbt_mode != NULL) {
1578 newmode = drm_mode_duplicate(connector->dev,
1579 dev_priv->sdvo_lvds_vbt_mode);
1580 if (newmode != NULL) {
1581 /* Guarantee the mode is preferred */
1582 newmode->type = (DRM_MODE_TYPE_PREFERRED |
1583 DRM_MODE_TYPE_DRIVER);
1584 drm_mode_probed_add(connector, newmode);
1585 }
1586 }
1587
1588end:
1589 list_for_each_entry(newmode, &connector->probed_modes, head) {
1590 if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
1591 psb_intel_sdvo->sdvo_lvds_fixed_mode =
1592 drm_mode_duplicate(connector->dev, newmode);
1593
1594 drm_mode_set_crtcinfo(psb_intel_sdvo->sdvo_lvds_fixed_mode,
1595 0);
1596
1597 psb_intel_sdvo->is_lvds = true;
1598 break;
1599 }
1600 }
1601
1602}
1603
1604static int psb_intel_sdvo_get_modes(struct drm_connector *connector)
1605{
1606 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector);
1607
1608 if (IS_TV(psb_intel_sdvo_connector))
1609 psb_intel_sdvo_get_tv_modes(connector);
1610 else if (IS_LVDS(psb_intel_sdvo_connector))
1611 psb_intel_sdvo_get_lvds_modes(connector);
1612 else
1613 psb_intel_sdvo_get_ddc_modes(connector);
1614
1615 return !list_empty(&connector->probed_modes);
1616}
1617
1618static void
1619psb_intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
1620{
1621 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector);
1622 struct drm_device *dev = connector->dev;
1623
1624 if (psb_intel_sdvo_connector->left)
1625 drm_property_destroy(dev, psb_intel_sdvo_connector->left);
1626 if (psb_intel_sdvo_connector->right)
1627 drm_property_destroy(dev, psb_intel_sdvo_connector->right);
1628 if (psb_intel_sdvo_connector->top)
1629 drm_property_destroy(dev, psb_intel_sdvo_connector->top);
1630 if (psb_intel_sdvo_connector->bottom)
1631 drm_property_destroy(dev, psb_intel_sdvo_connector->bottom);
1632 if (psb_intel_sdvo_connector->hpos)
1633 drm_property_destroy(dev, psb_intel_sdvo_connector->hpos);
1634 if (psb_intel_sdvo_connector->vpos)
1635 drm_property_destroy(dev, psb_intel_sdvo_connector->vpos);
1636 if (psb_intel_sdvo_connector->saturation)
1637 drm_property_destroy(dev, psb_intel_sdvo_connector->saturation);
1638 if (psb_intel_sdvo_connector->contrast)
1639 drm_property_destroy(dev, psb_intel_sdvo_connector->contrast);
1640 if (psb_intel_sdvo_connector->hue)
1641 drm_property_destroy(dev, psb_intel_sdvo_connector->hue);
1642 if (psb_intel_sdvo_connector->sharpness)
1643 drm_property_destroy(dev, psb_intel_sdvo_connector->sharpness);
1644 if (psb_intel_sdvo_connector->flicker_filter)
1645 drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter);
1646 if (psb_intel_sdvo_connector->flicker_filter_2d)
1647 drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter_2d);
1648 if (psb_intel_sdvo_connector->flicker_filter_adaptive)
1649 drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter_adaptive);
1650 if (psb_intel_sdvo_connector->tv_luma_filter)
1651 drm_property_destroy(dev, psb_intel_sdvo_connector->tv_luma_filter);
1652 if (psb_intel_sdvo_connector->tv_chroma_filter)
1653 drm_property_destroy(dev, psb_intel_sdvo_connector->tv_chroma_filter);
1654 if (psb_intel_sdvo_connector->dot_crawl)
1655 drm_property_destroy(dev, psb_intel_sdvo_connector->dot_crawl);
1656 if (psb_intel_sdvo_connector->brightness)
1657 drm_property_destroy(dev, psb_intel_sdvo_connector->brightness);
1658}
1659
1660static void psb_intel_sdvo_destroy(struct drm_connector *connector)
1661{
1662 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector);
1663
1664 if (psb_intel_sdvo_connector->tv_format)
1665 drm_property_destroy(connector->dev,
1666 psb_intel_sdvo_connector->tv_format);
1667
1668 psb_intel_sdvo_destroy_enhance_property(connector);
1669 drm_sysfs_connector_remove(connector);
1670 drm_connector_cleanup(connector);
1671 kfree(connector);
1672}
1673
1674static bool psb_intel_sdvo_detect_hdmi_audio(struct drm_connector *connector)
1675{
1676 struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector);
1677 struct edid *edid;
1678 bool has_audio = false;
1679
1680 if (!psb_intel_sdvo->is_hdmi)
1681 return false;
1682
1683 edid = psb_intel_sdvo_get_edid(connector);
1684 if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL)
1685 has_audio = drm_detect_monitor_audio(edid);
1686
1687 return has_audio;
1688}
1689
1690static int
1691psb_intel_sdvo_set_property(struct drm_connector *connector,
1692 struct drm_property *property,
1693 uint64_t val)
1694{
1695 struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector);
1696 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector);
1697 struct drm_psb_private *dev_priv = connector->dev->dev_private;
1698 uint16_t temp_value;
1699 uint8_t cmd;
1700 int ret;
1701
1702 ret = drm_connector_property_set_value(connector, property, val);
1703 if (ret)
1704 return ret;
1705
1706 if (property == dev_priv->force_audio_property) {
1707 int i = val;
1708 bool has_audio;
1709
1710 if (i == psb_intel_sdvo_connector->force_audio)
1711 return 0;
1712
1713 psb_intel_sdvo_connector->force_audio = i;
1714
1715 if (i == 0)
1716 has_audio = psb_intel_sdvo_detect_hdmi_audio(connector);
1717 else
1718 has_audio = i > 0;
1719
1720 if (has_audio == psb_intel_sdvo->has_hdmi_audio)
1721 return 0;
1722
1723 psb_intel_sdvo->has_hdmi_audio = has_audio;
1724 goto done;
1725 }
1726
1727 if (property == dev_priv->broadcast_rgb_property) {
1728 if (val == !!psb_intel_sdvo->color_range)
1729 return 0;
1730
1731 psb_intel_sdvo->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0;
1732 goto done;
1733 }
1734
1735#define CHECK_PROPERTY(name, NAME) \
1736 if (psb_intel_sdvo_connector->name == property) { \
1737 if (psb_intel_sdvo_connector->cur_##name == temp_value) return 0; \
1738 if (psb_intel_sdvo_connector->max_##name < temp_value) return -EINVAL; \
1739 cmd = SDVO_CMD_SET_##NAME; \
1740 psb_intel_sdvo_connector->cur_##name = temp_value; \
1741 goto set_value; \
1742 }
1743
1744 if (property == psb_intel_sdvo_connector->tv_format) {
1745 if (val >= TV_FORMAT_NUM)
1746 return -EINVAL;
1747
1748 if (psb_intel_sdvo->tv_format_index ==
1749 psb_intel_sdvo_connector->tv_format_supported[val])
1750 return 0;
1751
1752 psb_intel_sdvo->tv_format_index = psb_intel_sdvo_connector->tv_format_supported[val];
1753 goto done;
1754 } else if (IS_TV_OR_LVDS(psb_intel_sdvo_connector)) {
1755 temp_value = val;
1756 if (psb_intel_sdvo_connector->left == property) {
1757 drm_connector_property_set_value(connector,
1758 psb_intel_sdvo_connector->right, val);
1759 if (psb_intel_sdvo_connector->left_margin == temp_value)
1760 return 0;
1761
1762 psb_intel_sdvo_connector->left_margin = temp_value;
1763 psb_intel_sdvo_connector->right_margin = temp_value;
1764 temp_value = psb_intel_sdvo_connector->max_hscan -
1765 psb_intel_sdvo_connector->left_margin;
1766 cmd = SDVO_CMD_SET_OVERSCAN_H;
1767 goto set_value;
1768 } else if (psb_intel_sdvo_connector->right == property) {
1769 drm_connector_property_set_value(connector,
1770 psb_intel_sdvo_connector->left, val);
1771 if (psb_intel_sdvo_connector->right_margin == temp_value)
1772 return 0;
1773
1774 psb_intel_sdvo_connector->left_margin = temp_value;
1775 psb_intel_sdvo_connector->right_margin = temp_value;
1776 temp_value = psb_intel_sdvo_connector->max_hscan -
1777 psb_intel_sdvo_connector->left_margin;
1778 cmd = SDVO_CMD_SET_OVERSCAN_H;
1779 goto set_value;
1780 } else if (psb_intel_sdvo_connector->top == property) {
1781 drm_connector_property_set_value(connector,
1782 psb_intel_sdvo_connector->bottom, val);
1783 if (psb_intel_sdvo_connector->top_margin == temp_value)
1784 return 0;
1785
1786 psb_intel_sdvo_connector->top_margin = temp_value;
1787 psb_intel_sdvo_connector->bottom_margin = temp_value;
1788 temp_value = psb_intel_sdvo_connector->max_vscan -
1789 psb_intel_sdvo_connector->top_margin;
1790 cmd = SDVO_CMD_SET_OVERSCAN_V;
1791 goto set_value;
1792 } else if (psb_intel_sdvo_connector->bottom == property) {
1793 drm_connector_property_set_value(connector,
1794 psb_intel_sdvo_connector->top, val);
1795 if (psb_intel_sdvo_connector->bottom_margin == temp_value)
1796 return 0;
1797
1798 psb_intel_sdvo_connector->top_margin = temp_value;
1799 psb_intel_sdvo_connector->bottom_margin = temp_value;
1800 temp_value = psb_intel_sdvo_connector->max_vscan -
1801 psb_intel_sdvo_connector->top_margin;
1802 cmd = SDVO_CMD_SET_OVERSCAN_V;
1803 goto set_value;
1804 }
1805 CHECK_PROPERTY(hpos, HPOS)
1806 CHECK_PROPERTY(vpos, VPOS)
1807 CHECK_PROPERTY(saturation, SATURATION)
1808 CHECK_PROPERTY(contrast, CONTRAST)
1809 CHECK_PROPERTY(hue, HUE)
1810 CHECK_PROPERTY(brightness, BRIGHTNESS)
1811 CHECK_PROPERTY(sharpness, SHARPNESS)
1812 CHECK_PROPERTY(flicker_filter, FLICKER_FILTER)
1813 CHECK_PROPERTY(flicker_filter_2d, FLICKER_FILTER_2D)
1814 CHECK_PROPERTY(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE)
1815 CHECK_PROPERTY(tv_chroma_filter, TV_CHROMA_FILTER)
1816 CHECK_PROPERTY(tv_luma_filter, TV_LUMA_FILTER)
1817 CHECK_PROPERTY(dot_crawl, DOT_CRAWL)
1818 }
1819
1820 return -EINVAL; /* unknown property */
1821
1822set_value:
1823 if (!psb_intel_sdvo_set_value(psb_intel_sdvo, cmd, &temp_value, 2))
1824 return -EIO;
1825
1826
1827done:
1828 if (psb_intel_sdvo->base.base.crtc) {
1829 struct drm_crtc *crtc = psb_intel_sdvo->base.base.crtc;
1830 drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
1831 crtc->y, crtc->fb);
1832 }
1833
1834 return 0;
1835#undef CHECK_PROPERTY
1836}
1837
1838static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = {
1839 .dpms = psb_intel_sdvo_dpms,
1840 .mode_fixup = psb_intel_sdvo_mode_fixup,
1841 .prepare = psb_intel_encoder_prepare,
1842 .mode_set = psb_intel_sdvo_mode_set,
1843 .commit = psb_intel_encoder_commit,
1844};
1845
1846static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = {
1847 .dpms = drm_helper_connector_dpms,
1848 .detect = psb_intel_sdvo_detect,
1849 .fill_modes = drm_helper_probe_single_connector_modes,
1850 .set_property = psb_intel_sdvo_set_property,
1851 .destroy = psb_intel_sdvo_destroy,
1852};
1853
1854static const struct drm_connector_helper_funcs psb_intel_sdvo_connector_helper_funcs = {
1855 .get_modes = psb_intel_sdvo_get_modes,
1856 .mode_valid = psb_intel_sdvo_mode_valid,
1857 .best_encoder = psb_intel_best_encoder,
1858};
1859
1860static void psb_intel_sdvo_enc_destroy(struct drm_encoder *encoder)
1861{
1862 struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder);
1863
1864 if (psb_intel_sdvo->sdvo_lvds_fixed_mode != NULL)
1865 drm_mode_destroy(encoder->dev,
1866 psb_intel_sdvo->sdvo_lvds_fixed_mode);
1867
1868 i2c_del_adapter(&psb_intel_sdvo->ddc);
1869 psb_intel_encoder_destroy(encoder);
1870}
1871
1872static const struct drm_encoder_funcs psb_intel_sdvo_enc_funcs = {
1873 .destroy = psb_intel_sdvo_enc_destroy,
1874};
1875
1876static void
1877psb_intel_sdvo_guess_ddc_bus(struct psb_intel_sdvo *sdvo)
1878{
1879 /* FIXME: At the moment, ddc_bus = 2 is the only thing that works.
1880 * We need to figure out if this is true for all available poulsbo
1881 * hardware, or if we need to fiddle with the guessing code above.
1882 * The problem might go away if we can parse sdvo mappings from bios */
1883 sdvo->ddc_bus = 2;
1884
1885#if 0
1886 uint16_t mask = 0;
1887 unsigned int num_bits;
1888
1889 /* Make a mask of outputs less than or equal to our own priority in the
1890 * list.
1891 */
1892 switch (sdvo->controlled_output) {
1893 case SDVO_OUTPUT_LVDS1:
1894 mask |= SDVO_OUTPUT_LVDS1;
1895 case SDVO_OUTPUT_LVDS0:
1896 mask |= SDVO_OUTPUT_LVDS0;
1897 case SDVO_OUTPUT_TMDS1:
1898 mask |= SDVO_OUTPUT_TMDS1;
1899 case SDVO_OUTPUT_TMDS0:
1900 mask |= SDVO_OUTPUT_TMDS0;
1901 case SDVO_OUTPUT_RGB1:
1902 mask |= SDVO_OUTPUT_RGB1;
1903 case SDVO_OUTPUT_RGB0:
1904 mask |= SDVO_OUTPUT_RGB0;
1905 break;
1906 }
1907
1908 /* Count bits to find what number we are in the priority list. */
1909 mask &= sdvo->caps.output_flags;
1910 num_bits = hweight16(mask);
1911 /* If more than 3 outputs, default to DDC bus 3 for now. */
1912 if (num_bits > 3)
1913 num_bits = 3;
1914
1915 /* Corresponds to SDVO_CONTROL_BUS_DDCx */
1916 sdvo->ddc_bus = 1 << num_bits;
1917#endif
1918}
1919
1920/**
1921 * Choose the appropriate DDC bus for control bus switch command for this
1922 * SDVO output based on the controlled output.
1923 *
1924 * DDC bus number assignment is in a priority order of RGB outputs, then TMDS
1925 * outputs, then LVDS outputs.
1926 */
1927static void
1928psb_intel_sdvo_select_ddc_bus(struct drm_psb_private *dev_priv,
1929 struct psb_intel_sdvo *sdvo, u32 reg)
1930{
1931 struct sdvo_device_mapping *mapping;
1932
1933 if (IS_SDVOB(reg))
1934 mapping = &(dev_priv->sdvo_mappings[0]);
1935 else
1936 mapping = &(dev_priv->sdvo_mappings[1]);
1937
1938 if (mapping->initialized)
1939 sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4);
1940 else
1941 psb_intel_sdvo_guess_ddc_bus(sdvo);
1942}
1943
1944static void
1945psb_intel_sdvo_select_i2c_bus(struct drm_psb_private *dev_priv,
1946 struct psb_intel_sdvo *sdvo, u32 reg)
1947{
1948 struct sdvo_device_mapping *mapping;
1949 u8 pin, speed;
1950
1951 if (IS_SDVOB(reg))
1952 mapping = &dev_priv->sdvo_mappings[0];
1953 else
1954 mapping = &dev_priv->sdvo_mappings[1];
1955
1956 pin = GMBUS_PORT_DPB;
1957 speed = GMBUS_RATE_1MHZ >> 8;
1958 if (mapping->initialized) {
1959 pin = mapping->i2c_pin;
1960 speed = mapping->i2c_speed;
1961 }
1962
1963 if (pin < GMBUS_NUM_PORTS) {
1964 sdvo->i2c = &dev_priv->gmbus[pin].adapter;
1965 gma_intel_gmbus_set_speed(sdvo->i2c, speed);
1966 gma_intel_gmbus_force_bit(sdvo->i2c, true);
1967 } else
1968 sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter;
1969}
1970
1971static bool
1972psb_intel_sdvo_is_hdmi_connector(struct psb_intel_sdvo *psb_intel_sdvo, int device)
1973{
1974 return psb_intel_sdvo_check_supp_encode(psb_intel_sdvo);
1975}
1976
1977static u8
1978psb_intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg)
1979{
1980 struct drm_psb_private *dev_priv = dev->dev_private;
1981 struct sdvo_device_mapping *my_mapping, *other_mapping;
1982
1983 if (IS_SDVOB(sdvo_reg)) {
1984 my_mapping = &dev_priv->sdvo_mappings[0];
1985 other_mapping = &dev_priv->sdvo_mappings[1];
1986 } else {
1987 my_mapping = &dev_priv->sdvo_mappings[1];
1988 other_mapping = &dev_priv->sdvo_mappings[0];
1989 }
1990
1991 /* If the BIOS described our SDVO device, take advantage of it. */
1992 if (my_mapping->slave_addr)
1993 return my_mapping->slave_addr;
1994
1995 /* If the BIOS only described a different SDVO device, use the
1996 * address that it isn't using.
1997 */
1998 if (other_mapping->slave_addr) {
1999 if (other_mapping->slave_addr == 0x70)
2000 return 0x72;
2001 else
2002 return 0x70;
2003 }
2004
2005 /* No SDVO device info is found for another DVO port,
2006 * so use mapping assumption we had before BIOS parsing.
2007 */
2008 if (IS_SDVOB(sdvo_reg))
2009 return 0x70;
2010 else
2011 return 0x72;
2012}
2013
2014static void
2015psb_intel_sdvo_connector_init(struct psb_intel_sdvo_connector *connector,
2016 struct psb_intel_sdvo *encoder)
2017{
2018 drm_connector_init(encoder->base.base.dev,
2019 &connector->base.base,
2020 &psb_intel_sdvo_connector_funcs,
2021 connector->base.base.connector_type);
2022
2023 drm_connector_helper_add(&connector->base.base,
2024 &psb_intel_sdvo_connector_helper_funcs);
2025
2026 connector->base.base.interlace_allowed = 0;
2027 connector->base.base.doublescan_allowed = 0;
2028 connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
2029
2030 psb_intel_connector_attach_encoder(&connector->base, &encoder->base);
2031 drm_sysfs_connector_add(&connector->base.base);
2032}
2033
2034static void
2035psb_intel_sdvo_add_hdmi_properties(struct psb_intel_sdvo_connector *connector)
2036{
2037 /* FIXME: We don't support HDMI at the moment
2038 struct drm_device *dev = connector->base.base.dev;
2039
2040 intel_attach_force_audio_property(&connector->base.base);
2041 if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev))
2042 intel_attach_broadcast_rgb_property(&connector->base.base);
2043 */
2044}
2045
2046static bool
2047psb_intel_sdvo_dvi_init(struct psb_intel_sdvo *psb_intel_sdvo, int device)
2048{
2049 struct drm_encoder *encoder = &psb_intel_sdvo->base.base;
2050 struct drm_connector *connector;
2051 struct psb_intel_connector *intel_connector;
2052 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector;
2053
2054 psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL);
2055 if (!psb_intel_sdvo_connector)
2056 return false;
2057
2058 if (device == 0) {
2059 psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0;
2060 psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0;
2061 } else if (device == 1) {
2062 psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1;
2063 psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1;
2064 }
2065
2066 intel_connector = &psb_intel_sdvo_connector->base;
2067 connector = &intel_connector->base;
2068 // connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
2069 encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
2070 connector->connector_type = DRM_MODE_CONNECTOR_DVID;
2071
2072 if (psb_intel_sdvo_is_hdmi_connector(psb_intel_sdvo, device)) {
2073 connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
2074 psb_intel_sdvo->is_hdmi = true;
2075 }
2076 psb_intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
2077 (1 << INTEL_ANALOG_CLONE_BIT));
2078
2079 psb_intel_sdvo_connector_init(psb_intel_sdvo_connector, psb_intel_sdvo);
2080 if (psb_intel_sdvo->is_hdmi)
2081 psb_intel_sdvo_add_hdmi_properties(psb_intel_sdvo_connector);
2082
2083 return true;
2084}
2085
2086static bool
2087psb_intel_sdvo_tv_init(struct psb_intel_sdvo *psb_intel_sdvo, int type)
2088{
2089 struct drm_encoder *encoder = &psb_intel_sdvo->base.base;
2090 struct drm_connector *connector;
2091 struct psb_intel_connector *intel_connector;
2092 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector;
2093
2094 psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL);
2095 if (!psb_intel_sdvo_connector)
2096 return false;
2097
2098 intel_connector = &psb_intel_sdvo_connector->base;
2099 connector = &intel_connector->base;
2100 encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
2101 connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
2102
2103 psb_intel_sdvo->controlled_output |= type;
2104 psb_intel_sdvo_connector->output_flag = type;
2105
2106 psb_intel_sdvo->is_tv = true;
2107 psb_intel_sdvo->base.needs_tv_clock = true;
2108 psb_intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
2109
2110 psb_intel_sdvo_connector_init(psb_intel_sdvo_connector, psb_intel_sdvo);
2111
2112 if (!psb_intel_sdvo_tv_create_property(psb_intel_sdvo, psb_intel_sdvo_connector, type))
2113 goto err;
2114
2115 if (!psb_intel_sdvo_create_enhance_property(psb_intel_sdvo, psb_intel_sdvo_connector))
2116 goto err;
2117
2118 return true;
2119
2120err:
2121 psb_intel_sdvo_destroy(connector);
2122 return false;
2123}
2124
2125static bool
2126psb_intel_sdvo_analog_init(struct psb_intel_sdvo *psb_intel_sdvo, int device)
2127{
2128 struct drm_encoder *encoder = &psb_intel_sdvo->base.base;
2129 struct drm_connector *connector;
2130 struct psb_intel_connector *intel_connector;
2131 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector;
2132
2133 psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL);
2134 if (!psb_intel_sdvo_connector)
2135 return false;
2136
2137 intel_connector = &psb_intel_sdvo_connector->base;
2138 connector = &intel_connector->base;
2139 connector->polled = DRM_CONNECTOR_POLL_CONNECT;
2140 encoder->encoder_type = DRM_MODE_ENCODER_DAC;
2141 connector->connector_type = DRM_MODE_CONNECTOR_VGA;
2142
2143 if (device == 0) {
2144 psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0;
2145 psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0;
2146 } else if (device == 1) {
2147 psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1;
2148 psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
2149 }
2150
2151 psb_intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
2152 (1 << INTEL_ANALOG_CLONE_BIT));
2153
2154 psb_intel_sdvo_connector_init(psb_intel_sdvo_connector,
2155 psb_intel_sdvo);
2156 return true;
2157}
2158
2159static bool
2160psb_intel_sdvo_lvds_init(struct psb_intel_sdvo *psb_intel_sdvo, int device)
2161{
2162 struct drm_encoder *encoder = &psb_intel_sdvo->base.base;
2163 struct drm_connector *connector;
2164 struct psb_intel_connector *intel_connector;
2165 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector;
2166
2167 psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL);
2168 if (!psb_intel_sdvo_connector)
2169 return false;
2170
2171 intel_connector = &psb_intel_sdvo_connector->base;
2172 connector = &intel_connector->base;
2173 encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
2174 connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
2175
2176 if (device == 0) {
2177 psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0;
2178 psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0;
2179 } else if (device == 1) {
2180 psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1;
2181 psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
2182 }
2183
2184 psb_intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) |
2185 (1 << INTEL_SDVO_LVDS_CLONE_BIT));
2186
2187 psb_intel_sdvo_connector_init(psb_intel_sdvo_connector, psb_intel_sdvo);
2188 if (!psb_intel_sdvo_create_enhance_property(psb_intel_sdvo, psb_intel_sdvo_connector))
2189 goto err;
2190
2191 return true;
2192
2193err:
2194 psb_intel_sdvo_destroy(connector);
2195 return false;
2196}
2197
2198static bool
2199psb_intel_sdvo_output_setup(struct psb_intel_sdvo *psb_intel_sdvo, uint16_t flags)
2200{
2201 psb_intel_sdvo->is_tv = false;
2202 psb_intel_sdvo->base.needs_tv_clock = false;
2203 psb_intel_sdvo->is_lvds = false;
2204
2205 /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
2206
2207 if (flags & SDVO_OUTPUT_TMDS0)
2208 if (!psb_intel_sdvo_dvi_init(psb_intel_sdvo, 0))
2209 return false;
2210
2211 if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK)
2212 if (!psb_intel_sdvo_dvi_init(psb_intel_sdvo, 1))
2213 return false;
2214
2215 /* TV has no XXX1 function block */
2216 if (flags & SDVO_OUTPUT_SVID0)
2217 if (!psb_intel_sdvo_tv_init(psb_intel_sdvo, SDVO_OUTPUT_SVID0))
2218 return false;
2219
2220 if (flags & SDVO_OUTPUT_CVBS0)
2221 if (!psb_intel_sdvo_tv_init(psb_intel_sdvo, SDVO_OUTPUT_CVBS0))
2222 return false;
2223
2224 if (flags & SDVO_OUTPUT_RGB0)
2225 if (!psb_intel_sdvo_analog_init(psb_intel_sdvo, 0))
2226 return false;
2227
2228 if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK)
2229 if (!psb_intel_sdvo_analog_init(psb_intel_sdvo, 1))
2230 return false;
2231
2232 if (flags & SDVO_OUTPUT_LVDS0)
2233 if (!psb_intel_sdvo_lvds_init(psb_intel_sdvo, 0))
2234 return false;
2235
2236 if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK)
2237 if (!psb_intel_sdvo_lvds_init(psb_intel_sdvo, 1))
2238 return false;
2239
2240 if ((flags & SDVO_OUTPUT_MASK) == 0) {
2241 unsigned char bytes[2];
2242
2243 psb_intel_sdvo->controlled_output = 0;
2244 memcpy(bytes, &psb_intel_sdvo->caps.output_flags, 2);
2245 DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
2246 SDVO_NAME(psb_intel_sdvo),
2247 bytes[0], bytes[1]);
2248 return false;
2249 }
2250 psb_intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1);
2251
2252 return true;
2253}
2254
2255static bool psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_sdvo,
2256 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector,
2257 int type)
2258{
2259 struct drm_device *dev = psb_intel_sdvo->base.base.dev;
2260 struct psb_intel_sdvo_tv_format format;
2261 uint32_t format_map, i;
2262
2263 if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo, type))
2264 return false;
2265
2266 BUILD_BUG_ON(sizeof(format) != 6);
2267 if (!psb_intel_sdvo_get_value(psb_intel_sdvo,
2268 SDVO_CMD_GET_SUPPORTED_TV_FORMATS,
2269 &format, sizeof(format)))
2270 return false;
2271
2272 memcpy(&format_map, &format, min(sizeof(format_map), sizeof(format)));
2273
2274 if (format_map == 0)
2275 return false;
2276
2277 psb_intel_sdvo_connector->format_supported_num = 0;
2278 for (i = 0 ; i < TV_FORMAT_NUM; i++)
2279 if (format_map & (1 << i))
2280 psb_intel_sdvo_connector->tv_format_supported[psb_intel_sdvo_connector->format_supported_num++] = i;
2281
2282
2283 psb_intel_sdvo_connector->tv_format =
2284 drm_property_create(dev, DRM_MODE_PROP_ENUM,
2285 "mode", psb_intel_sdvo_connector->format_supported_num);
2286 if (!psb_intel_sdvo_connector->tv_format)
2287 return false;
2288
2289 for (i = 0; i < psb_intel_sdvo_connector->format_supported_num; i++)
2290 drm_property_add_enum(
2291 psb_intel_sdvo_connector->tv_format, i,
2292 i, tv_format_names[psb_intel_sdvo_connector->tv_format_supported[i]]);
2293
2294 psb_intel_sdvo->tv_format_index = psb_intel_sdvo_connector->tv_format_supported[0];
2295 drm_connector_attach_property(&psb_intel_sdvo_connector->base.base,
2296 psb_intel_sdvo_connector->tv_format, 0);
2297 return true;
2298
2299}
2300
2301#define ENHANCEMENT(name, NAME) do { \
2302 if (enhancements.name) { \
2303 if (!psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_MAX_##NAME, &data_value, 4) || \
2304 !psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \
2305 return false; \
2306 psb_intel_sdvo_connector->max_##name = data_value[0]; \
2307 psb_intel_sdvo_connector->cur_##name = response; \
2308 psb_intel_sdvo_connector->name = \
2309 drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \
2310 if (!psb_intel_sdvo_connector->name) return false; \
2311 psb_intel_sdvo_connector->name->values[0] = 0; \
2312 psb_intel_sdvo_connector->name->values[1] = data_value[0]; \
2313 drm_connector_attach_property(connector, \
2314 psb_intel_sdvo_connector->name, \
2315 psb_intel_sdvo_connector->cur_##name); \
2316 DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \
2317 data_value[0], data_value[1], response); \
2318 } \
2319} while(0)
2320
2321static bool
2322psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo,
2323 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector,
2324 struct psb_intel_sdvo_enhancements_reply enhancements)
2325{
2326 struct drm_device *dev = psb_intel_sdvo->base.base.dev;
2327 struct drm_connector *connector = &psb_intel_sdvo_connector->base.base;
2328 uint16_t response, data_value[2];
2329
2330 /* when horizontal overscan is supported, Add the left/right property */
2331 if (enhancements.overscan_h) {
2332 if (!psb_intel_sdvo_get_value(psb_intel_sdvo,
2333 SDVO_CMD_GET_MAX_OVERSCAN_H,
2334 &data_value, 4))
2335 return false;
2336
2337 if (!psb_intel_sdvo_get_value(psb_intel_sdvo,
2338 SDVO_CMD_GET_OVERSCAN_H,
2339 &response, 2))
2340 return false;
2341
2342 psb_intel_sdvo_connector->max_hscan = data_value[0];
2343 psb_intel_sdvo_connector->left_margin = data_value[0] - response;
2344 psb_intel_sdvo_connector->right_margin = psb_intel_sdvo_connector->left_margin;
2345 psb_intel_sdvo_connector->left =
2346 drm_property_create(dev, DRM_MODE_PROP_RANGE,
2347 "left_margin", 2);
2348 if (!psb_intel_sdvo_connector->left)
2349 return false;
2350
2351 psb_intel_sdvo_connector->left->values[0] = 0;
2352 psb_intel_sdvo_connector->left->values[1] = data_value[0];
2353 drm_connector_attach_property(connector,
2354 psb_intel_sdvo_connector->left,
2355 psb_intel_sdvo_connector->left_margin);
2356
2357 psb_intel_sdvo_connector->right =
2358 drm_property_create(dev, DRM_MODE_PROP_RANGE,
2359 "right_margin", 2);
2360 if (!psb_intel_sdvo_connector->right)
2361 return false;
2362
2363 psb_intel_sdvo_connector->right->values[0] = 0;
2364 psb_intel_sdvo_connector->right->values[1] = data_value[0];
2365 drm_connector_attach_property(connector,
2366 psb_intel_sdvo_connector->right,
2367 psb_intel_sdvo_connector->right_margin);
2368 DRM_DEBUG_KMS("h_overscan: max %d, "
2369 "default %d, current %d\n",
2370 data_value[0], data_value[1], response);
2371 }
2372
2373 if (enhancements.overscan_v) {
2374 if (!psb_intel_sdvo_get_value(psb_intel_sdvo,
2375 SDVO_CMD_GET_MAX_OVERSCAN_V,
2376 &data_value, 4))
2377 return false;
2378
2379 if (!psb_intel_sdvo_get_value(psb_intel_sdvo,
2380 SDVO_CMD_GET_OVERSCAN_V,
2381 &response, 2))
2382 return false;
2383
2384 psb_intel_sdvo_connector->max_vscan = data_value[0];
2385 psb_intel_sdvo_connector->top_margin = data_value[0] - response;
2386 psb_intel_sdvo_connector->bottom_margin = psb_intel_sdvo_connector->top_margin;
2387 psb_intel_sdvo_connector->top =
2388 drm_property_create(dev, DRM_MODE_PROP_RANGE,
2389 "top_margin", 2);
2390 if (!psb_intel_sdvo_connector->top)
2391 return false;
2392
2393 psb_intel_sdvo_connector->top->values[0] = 0;
2394 psb_intel_sdvo_connector->top->values[1] = data_value[0];
2395 drm_connector_attach_property(connector,
2396 psb_intel_sdvo_connector->top,
2397 psb_intel_sdvo_connector->top_margin);
2398
2399 psb_intel_sdvo_connector->bottom =
2400 drm_property_create(dev, DRM_MODE_PROP_RANGE,
2401 "bottom_margin", 2);
2402 if (!psb_intel_sdvo_connector->bottom)
2403 return false;
2404
2405 psb_intel_sdvo_connector->bottom->values[0] = 0;
2406 psb_intel_sdvo_connector->bottom->values[1] = data_value[0];
2407 drm_connector_attach_property(connector,
2408 psb_intel_sdvo_connector->bottom,
2409 psb_intel_sdvo_connector->bottom_margin);
2410 DRM_DEBUG_KMS("v_overscan: max %d, "
2411 "default %d, current %d\n",
2412 data_value[0], data_value[1], response);
2413 }
2414
2415 ENHANCEMENT(hpos, HPOS);
2416 ENHANCEMENT(vpos, VPOS);
2417 ENHANCEMENT(saturation, SATURATION);
2418 ENHANCEMENT(contrast, CONTRAST);
2419 ENHANCEMENT(hue, HUE);
2420 ENHANCEMENT(sharpness, SHARPNESS);
2421 ENHANCEMENT(brightness, BRIGHTNESS);
2422 ENHANCEMENT(flicker_filter, FLICKER_FILTER);
2423 ENHANCEMENT(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE);
2424 ENHANCEMENT(flicker_filter_2d, FLICKER_FILTER_2D);
2425 ENHANCEMENT(tv_chroma_filter, TV_CHROMA_FILTER);
2426 ENHANCEMENT(tv_luma_filter, TV_LUMA_FILTER);
2427
2428 if (enhancements.dot_crawl) {
2429 if (!psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_DOT_CRAWL, &response, 2))
2430 return false;
2431
2432 psb_intel_sdvo_connector->max_dot_crawl = 1;
2433 psb_intel_sdvo_connector->cur_dot_crawl = response & 0x1;
2434 psb_intel_sdvo_connector->dot_crawl =
2435 drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2);
2436 if (!psb_intel_sdvo_connector->dot_crawl)
2437 return false;
2438
2439 psb_intel_sdvo_connector->dot_crawl->values[0] = 0;
2440 psb_intel_sdvo_connector->dot_crawl->values[1] = 1;
2441 drm_connector_attach_property(connector,
2442 psb_intel_sdvo_connector->dot_crawl,
2443 psb_intel_sdvo_connector->cur_dot_crawl);
2444 DRM_DEBUG_KMS("dot crawl: current %d\n", response);
2445 }
2446
2447 return true;
2448}
2449
2450static bool
2451psb_intel_sdvo_create_enhance_property_lvds(struct psb_intel_sdvo *psb_intel_sdvo,
2452 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector,
2453 struct psb_intel_sdvo_enhancements_reply enhancements)
2454{
2455 struct drm_device *dev = psb_intel_sdvo->base.base.dev;
2456 struct drm_connector *connector = &psb_intel_sdvo_connector->base.base;
2457 uint16_t response, data_value[2];
2458
2459 ENHANCEMENT(brightness, BRIGHTNESS);
2460
2461 return true;
2462}
2463#undef ENHANCEMENT
2464
2465static bool psb_intel_sdvo_create_enhance_property(struct psb_intel_sdvo *psb_intel_sdvo,
2466 struct psb_intel_sdvo_connector *psb_intel_sdvo_connector)
2467{
2468 union {
2469 struct psb_intel_sdvo_enhancements_reply reply;
2470 uint16_t response;
2471 } enhancements;
2472
2473 BUILD_BUG_ON(sizeof(enhancements) != 2);
2474
2475 enhancements.response = 0;
2476 psb_intel_sdvo_get_value(psb_intel_sdvo,
2477 SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
2478 &enhancements, sizeof(enhancements));
2479 if (enhancements.response == 0) {
2480 DRM_DEBUG_KMS("No enhancement is supported\n");
2481 return true;
2482 }
2483
2484 if (IS_TV(psb_intel_sdvo_connector))
2485 return psb_intel_sdvo_create_enhance_property_tv(psb_intel_sdvo, psb_intel_sdvo_connector, enhancements.reply);
2486 else if(IS_LVDS(psb_intel_sdvo_connector))
2487 return psb_intel_sdvo_create_enhance_property_lvds(psb_intel_sdvo, psb_intel_sdvo_connector, enhancements.reply);
2488 else
2489 return true;
2490}
2491
2492static int psb_intel_sdvo_ddc_proxy_xfer(struct i2c_adapter *adapter,
2493 struct i2c_msg *msgs,
2494 int num)
2495{
2496 struct psb_intel_sdvo *sdvo = adapter->algo_data;
2497
2498 if (!psb_intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus))
2499 return -EIO;
2500
2501 return sdvo->i2c->algo->master_xfer(sdvo->i2c, msgs, num);
2502}
2503
2504static u32 psb_intel_sdvo_ddc_proxy_func(struct i2c_adapter *adapter)
2505{
2506 struct psb_intel_sdvo *sdvo = adapter->algo_data;
2507 return sdvo->i2c->algo->functionality(sdvo->i2c);
2508}
2509
2510static const struct i2c_algorithm psb_intel_sdvo_ddc_proxy = {
2511 .master_xfer = psb_intel_sdvo_ddc_proxy_xfer,
2512 .functionality = psb_intel_sdvo_ddc_proxy_func
2513};
2514
2515static bool
2516psb_intel_sdvo_init_ddc_proxy(struct psb_intel_sdvo *sdvo,
2517 struct drm_device *dev)
2518{
2519 sdvo->ddc.owner = THIS_MODULE;
2520 sdvo->ddc.class = I2C_CLASS_DDC;
2521 snprintf(sdvo->ddc.name, I2C_NAME_SIZE, "SDVO DDC proxy");
2522 sdvo->ddc.dev.parent = &dev->pdev->dev;
2523 sdvo->ddc.algo_data = sdvo;
2524 sdvo->ddc.algo = &psb_intel_sdvo_ddc_proxy;
2525
2526 return i2c_add_adapter(&sdvo->ddc) == 0;
2527}
2528
2529bool psb_intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
2530{
2531 struct drm_psb_private *dev_priv = dev->dev_private;
2532 struct psb_intel_encoder *psb_intel_encoder;
2533 struct psb_intel_sdvo *psb_intel_sdvo;
2534 int i;
2535
2536 psb_intel_sdvo = kzalloc(sizeof(struct psb_intel_sdvo), GFP_KERNEL);
2537 if (!psb_intel_sdvo)
2538 return false;
2539
2540 psb_intel_sdvo->sdvo_reg = sdvo_reg;
2541 psb_intel_sdvo->slave_addr = psb_intel_sdvo_get_slave_addr(dev, sdvo_reg) >> 1;
2542 psb_intel_sdvo_select_i2c_bus(dev_priv, psb_intel_sdvo, sdvo_reg);
2543 if (!psb_intel_sdvo_init_ddc_proxy(psb_intel_sdvo, dev)) {
2544 kfree(psb_intel_sdvo);
2545 return false;
2546 }
2547
2548 /* encoder type will be decided later */
2549 psb_intel_encoder = &psb_intel_sdvo->base;
2550 psb_intel_encoder->type = INTEL_OUTPUT_SDVO;
2551 drm_encoder_init(dev, &psb_intel_encoder->base, &psb_intel_sdvo_enc_funcs, 0);
2552
2553 /* Read the regs to test if we can talk to the device */
2554 for (i = 0; i < 0x40; i++) {
2555 u8 byte;
2556
2557 if (!psb_intel_sdvo_read_byte(psb_intel_sdvo, i, &byte)) {
2558 DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n",
2559 IS_SDVOB(sdvo_reg) ? 'B' : 'C');
2560 goto err;
2561 }
2562 }
2563
2564 if (IS_SDVOB(sdvo_reg))
2565 dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
2566 else
2567 dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
2568
2569 drm_encoder_helper_add(&psb_intel_encoder->base, &psb_intel_sdvo_helper_funcs);
2570
2571 /* In default case sdvo lvds is false */
2572 if (!psb_intel_sdvo_get_capabilities(psb_intel_sdvo, &psb_intel_sdvo->caps))
2573 goto err;
2574
2575 if (psb_intel_sdvo_output_setup(psb_intel_sdvo,
2576 psb_intel_sdvo->caps.output_flags) != true) {
2577 DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
2578 IS_SDVOB(sdvo_reg) ? 'B' : 'C');
2579 goto err;
2580 }
2581
2582 psb_intel_sdvo_select_ddc_bus(dev_priv, psb_intel_sdvo, sdvo_reg);
2583
2584 /* Set the input timing to the screen. Assume always input 0. */
2585 if (!psb_intel_sdvo_set_target_input(psb_intel_sdvo))
2586 goto err;
2587
2588 if (!psb_intel_sdvo_get_input_pixel_clock_range(psb_intel_sdvo,
2589 &psb_intel_sdvo->pixel_clock_min,
2590 &psb_intel_sdvo->pixel_clock_max))
2591 goto err;
2592
2593 DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
2594 "clock range %dMHz - %dMHz, "
2595 "input 1: %c, input 2: %c, "
2596 "output 1: %c, output 2: %c\n",
2597 SDVO_NAME(psb_intel_sdvo),
2598 psb_intel_sdvo->caps.vendor_id, psb_intel_sdvo->caps.device_id,
2599 psb_intel_sdvo->caps.device_rev_id,
2600 psb_intel_sdvo->pixel_clock_min / 1000,
2601 psb_intel_sdvo->pixel_clock_max / 1000,
2602 (psb_intel_sdvo->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
2603 (psb_intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
2604 /* check currently supported outputs */
2605 psb_intel_sdvo->caps.output_flags &
2606 (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
2607 psb_intel_sdvo->caps.output_flags &
2608 (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
2609 return true;
2610
2611err:
2612 drm_encoder_cleanup(&psb_intel_encoder->base);
2613 i2c_del_adapter(&psb_intel_sdvo->ddc);
2614 kfree(psb_intel_sdvo);
2615
2616 return false;
2617}
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo_regs.h b/drivers/gpu/drm/gma500/psb_intel_sdvo_regs.h
new file mode 100644
index 00000000000..600e79744d6
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_intel_sdvo_regs.h
@@ -0,0 +1,723 @@
1/*
2 * Copyright ? 2006-2007 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 * Eric Anholt <eric@anholt.net>
25 */
26
27/**
28 * @file SDVO command definitions and structures.
29 */
30
31#define SDVO_OUTPUT_FIRST (0)
32#define SDVO_OUTPUT_TMDS0 (1 << 0)
33#define SDVO_OUTPUT_RGB0 (1 << 1)
34#define SDVO_OUTPUT_CVBS0 (1 << 2)
35#define SDVO_OUTPUT_SVID0 (1 << 3)
36#define SDVO_OUTPUT_YPRPB0 (1 << 4)
37#define SDVO_OUTPUT_SCART0 (1 << 5)
38#define SDVO_OUTPUT_LVDS0 (1 << 6)
39#define SDVO_OUTPUT_TMDS1 (1 << 8)
40#define SDVO_OUTPUT_RGB1 (1 << 9)
41#define SDVO_OUTPUT_CVBS1 (1 << 10)
42#define SDVO_OUTPUT_SVID1 (1 << 11)
43#define SDVO_OUTPUT_YPRPB1 (1 << 12)
44#define SDVO_OUTPUT_SCART1 (1 << 13)
45#define SDVO_OUTPUT_LVDS1 (1 << 14)
46#define SDVO_OUTPUT_LAST (14)
47
48struct psb_intel_sdvo_caps {
49 u8 vendor_id;
50 u8 device_id;
51 u8 device_rev_id;
52 u8 sdvo_version_major;
53 u8 sdvo_version_minor;
54 unsigned int sdvo_inputs_mask:2;
55 unsigned int smooth_scaling:1;
56 unsigned int sharp_scaling:1;
57 unsigned int up_scaling:1;
58 unsigned int down_scaling:1;
59 unsigned int stall_support:1;
60 unsigned int pad:1;
61 u16 output_flags;
62} __attribute__((packed));
63
64/** This matches the EDID DTD structure, more or less */
65struct psb_intel_sdvo_dtd {
66 struct {
67 u16 clock; /**< pixel clock, in 10kHz units */
68 u8 h_active; /**< lower 8 bits (pixels) */
69 u8 h_blank; /**< lower 8 bits (pixels) */
70 u8 h_high; /**< upper 4 bits each h_active, h_blank */
71 u8 v_active; /**< lower 8 bits (lines) */
72 u8 v_blank; /**< lower 8 bits (lines) */
73 u8 v_high; /**< upper 4 bits each v_active, v_blank */
74 } part1;
75
76 struct {
77 u8 h_sync_off; /**< lower 8 bits, from hblank start */
78 u8 h_sync_width; /**< lower 8 bits (pixels) */
79 /** lower 4 bits each vsync offset, vsync width */
80 u8 v_sync_off_width;
81 /**
82 * 2 high bits of hsync offset, 2 high bits of hsync width,
83 * bits 4-5 of vsync offset, and 2 high bits of vsync width.
84 */
85 u8 sync_off_width_high;
86 u8 dtd_flags;
87 u8 sdvo_flags;
88 /** bits 6-7 of vsync offset at bits 6-7 */
89 u8 v_sync_off_high;
90 u8 reserved;
91 } part2;
92} __attribute__((packed));
93
94struct psb_intel_sdvo_pixel_clock_range {
95 u16 min; /**< pixel clock, in 10kHz units */
96 u16 max; /**< pixel clock, in 10kHz units */
97} __attribute__((packed));
98
99struct psb_intel_sdvo_preferred_input_timing_args {
100 u16 clock;
101 u16 width;
102 u16 height;
103 u8 interlace:1;
104 u8 scaled:1;
105 u8 pad:6;
106} __attribute__((packed));
107
108/* I2C registers for SDVO */
109#define SDVO_I2C_ARG_0 0x07
110#define SDVO_I2C_ARG_1 0x06
111#define SDVO_I2C_ARG_2 0x05
112#define SDVO_I2C_ARG_3 0x04
113#define SDVO_I2C_ARG_4 0x03
114#define SDVO_I2C_ARG_5 0x02
115#define SDVO_I2C_ARG_6 0x01
116#define SDVO_I2C_ARG_7 0x00
117#define SDVO_I2C_OPCODE 0x08
118#define SDVO_I2C_CMD_STATUS 0x09
119#define SDVO_I2C_RETURN_0 0x0a
120#define SDVO_I2C_RETURN_1 0x0b
121#define SDVO_I2C_RETURN_2 0x0c
122#define SDVO_I2C_RETURN_3 0x0d
123#define SDVO_I2C_RETURN_4 0x0e
124#define SDVO_I2C_RETURN_5 0x0f
125#define SDVO_I2C_RETURN_6 0x10
126#define SDVO_I2C_RETURN_7 0x11
127#define SDVO_I2C_VENDOR_BEGIN 0x20
128
129/* Status results */
130#define SDVO_CMD_STATUS_POWER_ON 0x0
131#define SDVO_CMD_STATUS_SUCCESS 0x1
132#define SDVO_CMD_STATUS_NOTSUPP 0x2
133#define SDVO_CMD_STATUS_INVALID_ARG 0x3
134#define SDVO_CMD_STATUS_PENDING 0x4
135#define SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED 0x5
136#define SDVO_CMD_STATUS_SCALING_NOT_SUPP 0x6
137
138/* SDVO commands, argument/result registers */
139
140#define SDVO_CMD_RESET 0x01
141
142/** Returns a struct intel_sdvo_caps */
143#define SDVO_CMD_GET_DEVICE_CAPS 0x02
144
145#define SDVO_CMD_GET_FIRMWARE_REV 0x86
146# define SDVO_DEVICE_FIRMWARE_MINOR SDVO_I2C_RETURN_0
147# define SDVO_DEVICE_FIRMWARE_MAJOR SDVO_I2C_RETURN_1
148# define SDVO_DEVICE_FIRMWARE_PATCH SDVO_I2C_RETURN_2
149
150/**
151 * Reports which inputs are trained (managed to sync).
152 *
153 * Devices must have trained within 2 vsyncs of a mode change.
154 */
155#define SDVO_CMD_GET_TRAINED_INPUTS 0x03
156struct psb_intel_sdvo_get_trained_inputs_response {
157 unsigned int input0_trained:1;
158 unsigned int input1_trained:1;
159 unsigned int pad:6;
160} __attribute__((packed));
161
162/** Returns a struct intel_sdvo_output_flags of active outputs. */
163#define SDVO_CMD_GET_ACTIVE_OUTPUTS 0x04
164
165/**
166 * Sets the current set of active outputs.
167 *
168 * Takes a struct intel_sdvo_output_flags. Must be preceded by a SET_IN_OUT_MAP
169 * on multi-output devices.
170 */
171#define SDVO_CMD_SET_ACTIVE_OUTPUTS 0x05
172
173/**
174 * Returns the current mapping of SDVO inputs to outputs on the device.
175 *
176 * Returns two struct intel_sdvo_output_flags structures.
177 */
178#define SDVO_CMD_GET_IN_OUT_MAP 0x06
179struct psb_intel_sdvo_in_out_map {
180 u16 in0, in1;
181};
182
183/**
184 * Sets the current mapping of SDVO inputs to outputs on the device.
185 *
186 * Takes two struct i380_sdvo_output_flags structures.
187 */
188#define SDVO_CMD_SET_IN_OUT_MAP 0x07
189
190/**
191 * Returns a struct intel_sdvo_output_flags of attached displays.
192 */
193#define SDVO_CMD_GET_ATTACHED_DISPLAYS 0x0b
194
195/**
196 * Returns a struct intel_sdvo_ouptut_flags of displays supporting hot plugging.
197 */
198#define SDVO_CMD_GET_HOT_PLUG_SUPPORT 0x0c
199
200/**
201 * Takes a struct intel_sdvo_output_flags.
202 */
203#define SDVO_CMD_SET_ACTIVE_HOT_PLUG 0x0d
204
205/**
206 * Returns a struct intel_sdvo_output_flags of displays with hot plug
207 * interrupts enabled.
208 */
209#define SDVO_CMD_GET_ACTIVE_HOT_PLUG 0x0e
210
211#define SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE 0x0f
212struct intel_sdvo_get_interrupt_event_source_response {
213 u16 interrupt_status;
214 unsigned int ambient_light_interrupt:1;
215 unsigned int hdmi_audio_encrypt_change:1;
216 unsigned int pad:6;
217} __attribute__((packed));
218
219/**
220 * Selects which input is affected by future input commands.
221 *
222 * Commands affected include SET_INPUT_TIMINGS_PART[12],
223 * GET_INPUT_TIMINGS_PART[12], GET_PREFERRED_INPUT_TIMINGS_PART[12],
224 * GET_INPUT_PIXEL_CLOCK_RANGE, and CREATE_PREFERRED_INPUT_TIMINGS.
225 */
226#define SDVO_CMD_SET_TARGET_INPUT 0x10
227struct psb_intel_sdvo_set_target_input_args {
228 unsigned int target_1:1;
229 unsigned int pad:7;
230} __attribute__((packed));
231
232/**
233 * Takes a struct intel_sdvo_output_flags of which outputs are targeted by
234 * future output commands.
235 *
236 * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12],
237 * GET_OUTPUT_TIMINGS_PART[12], and GET_OUTPUT_PIXEL_CLOCK_RANGE.
238 */
239#define SDVO_CMD_SET_TARGET_OUTPUT 0x11
240
241#define SDVO_CMD_GET_INPUT_TIMINGS_PART1 0x12
242#define SDVO_CMD_GET_INPUT_TIMINGS_PART2 0x13
243#define SDVO_CMD_SET_INPUT_TIMINGS_PART1 0x14
244#define SDVO_CMD_SET_INPUT_TIMINGS_PART2 0x15
245#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART1 0x16
246#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART2 0x17
247#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART1 0x18
248#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART2 0x19
249/* Part 1 */
250# define SDVO_DTD_CLOCK_LOW SDVO_I2C_ARG_0
251# define SDVO_DTD_CLOCK_HIGH SDVO_I2C_ARG_1
252# define SDVO_DTD_H_ACTIVE SDVO_I2C_ARG_2
253# define SDVO_DTD_H_BLANK SDVO_I2C_ARG_3
254# define SDVO_DTD_H_HIGH SDVO_I2C_ARG_4
255# define SDVO_DTD_V_ACTIVE SDVO_I2C_ARG_5
256# define SDVO_DTD_V_BLANK SDVO_I2C_ARG_6
257# define SDVO_DTD_V_HIGH SDVO_I2C_ARG_7
258/* Part 2 */
259# define SDVO_DTD_HSYNC_OFF SDVO_I2C_ARG_0
260# define SDVO_DTD_HSYNC_WIDTH SDVO_I2C_ARG_1
261# define SDVO_DTD_VSYNC_OFF_WIDTH SDVO_I2C_ARG_2
262# define SDVO_DTD_SYNC_OFF_WIDTH_HIGH SDVO_I2C_ARG_3
263# define SDVO_DTD_DTD_FLAGS SDVO_I2C_ARG_4
264# define SDVO_DTD_DTD_FLAG_INTERLACED (1 << 7)
265# define SDVO_DTD_DTD_FLAG_STEREO_MASK (3 << 5)
266# define SDVO_DTD_DTD_FLAG_INPUT_MASK (3 << 3)
267# define SDVO_DTD_DTD_FLAG_SYNC_MASK (3 << 1)
268# define SDVO_DTD_SDVO_FLAS SDVO_I2C_ARG_5
269# define SDVO_DTD_SDVO_FLAG_STALL (1 << 7)
270# define SDVO_DTD_SDVO_FLAG_CENTERED (0 << 6)
271# define SDVO_DTD_SDVO_FLAG_UPPER_LEFT (1 << 6)
272# define SDVO_DTD_SDVO_FLAG_SCALING_MASK (3 << 4)
273# define SDVO_DTD_SDVO_FLAG_SCALING_NONE (0 << 4)
274# define SDVO_DTD_SDVO_FLAG_SCALING_SHARP (1 << 4)
275# define SDVO_DTD_SDVO_FLAG_SCALING_SMOOTH (2 << 4)
276# define SDVO_DTD_VSYNC_OFF_HIGH SDVO_I2C_ARG_6
277
278/**
279 * Generates a DTD based on the given width, height, and flags.
280 *
281 * This will be supported by any device supporting scaling or interlaced
282 * modes.
283 */
284#define SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING 0x1a
285# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_LOW SDVO_I2C_ARG_0
286# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_HIGH SDVO_I2C_ARG_1
287# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_LOW SDVO_I2C_ARG_2
288# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_HIGH SDVO_I2C_ARG_3
289# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_LOW SDVO_I2C_ARG_4
290# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_HIGH SDVO_I2C_ARG_5
291# define SDVO_PREFERRED_INPUT_TIMING_FLAGS SDVO_I2C_ARG_6
292# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_INTERLACED (1 << 0)
293# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_SCALED (1 << 1)
294
295#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1 0x1b
296#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2 0x1c
297
298/** Returns a struct intel_sdvo_pixel_clock_range */
299#define SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE 0x1d
300/** Returns a struct intel_sdvo_pixel_clock_range */
301#define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE 0x1e
302
303/** Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */
304#define SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS 0x1f
305
306/** Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
307#define SDVO_CMD_GET_CLOCK_RATE_MULT 0x20
308/** Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
309#define SDVO_CMD_SET_CLOCK_RATE_MULT 0x21
310# define SDVO_CLOCK_RATE_MULT_1X (1 << 0)
311# define SDVO_CLOCK_RATE_MULT_2X (1 << 1)
312# define SDVO_CLOCK_RATE_MULT_4X (1 << 3)
313
314#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27
315/** 6 bytes of bit flags for TV formats shared by all TV format functions */
316struct psb_intel_sdvo_tv_format {
317 unsigned int ntsc_m:1;
318 unsigned int ntsc_j:1;
319 unsigned int ntsc_443:1;
320 unsigned int pal_b:1;
321 unsigned int pal_d:1;
322 unsigned int pal_g:1;
323 unsigned int pal_h:1;
324 unsigned int pal_i:1;
325
326 unsigned int pal_m:1;
327 unsigned int pal_n:1;
328 unsigned int pal_nc:1;
329 unsigned int pal_60:1;
330 unsigned int secam_b:1;
331 unsigned int secam_d:1;
332 unsigned int secam_g:1;
333 unsigned int secam_k:1;
334
335 unsigned int secam_k1:1;
336 unsigned int secam_l:1;
337 unsigned int secam_60:1;
338 unsigned int hdtv_std_smpte_240m_1080i_59:1;
339 unsigned int hdtv_std_smpte_240m_1080i_60:1;
340 unsigned int hdtv_std_smpte_260m_1080i_59:1;
341 unsigned int hdtv_std_smpte_260m_1080i_60:1;
342 unsigned int hdtv_std_smpte_274m_1080i_50:1;
343
344 unsigned int hdtv_std_smpte_274m_1080i_59:1;
345 unsigned int hdtv_std_smpte_274m_1080i_60:1;
346 unsigned int hdtv_std_smpte_274m_1080p_23:1;
347 unsigned int hdtv_std_smpte_274m_1080p_24:1;
348 unsigned int hdtv_std_smpte_274m_1080p_25:1;
349 unsigned int hdtv_std_smpte_274m_1080p_29:1;
350 unsigned int hdtv_std_smpte_274m_1080p_30:1;
351 unsigned int hdtv_std_smpte_274m_1080p_50:1;
352
353 unsigned int hdtv_std_smpte_274m_1080p_59:1;
354 unsigned int hdtv_std_smpte_274m_1080p_60:1;
355 unsigned int hdtv_std_smpte_295m_1080i_50:1;
356 unsigned int hdtv_std_smpte_295m_1080p_50:1;
357 unsigned int hdtv_std_smpte_296m_720p_59:1;
358 unsigned int hdtv_std_smpte_296m_720p_60:1;
359 unsigned int hdtv_std_smpte_296m_720p_50:1;
360 unsigned int hdtv_std_smpte_293m_480p_59:1;
361
362 unsigned int hdtv_std_smpte_170m_480i_59:1;
363 unsigned int hdtv_std_iturbt601_576i_50:1;
364 unsigned int hdtv_std_iturbt601_576p_50:1;
365 unsigned int hdtv_std_eia_7702a_480i_60:1;
366 unsigned int hdtv_std_eia_7702a_480p_60:1;
367 unsigned int pad:3;
368} __attribute__((packed));
369
370#define SDVO_CMD_GET_TV_FORMAT 0x28
371
372#define SDVO_CMD_SET_TV_FORMAT 0x29
373
374/** Returns the resolutiosn that can be used with the given TV format */
375#define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT 0x83
376struct psb_intel_sdvo_sdtv_resolution_request {
377 unsigned int ntsc_m:1;
378 unsigned int ntsc_j:1;
379 unsigned int ntsc_443:1;
380 unsigned int pal_b:1;
381 unsigned int pal_d:1;
382 unsigned int pal_g:1;
383 unsigned int pal_h:1;
384 unsigned int pal_i:1;
385
386 unsigned int pal_m:1;
387 unsigned int pal_n:1;
388 unsigned int pal_nc:1;
389 unsigned int pal_60:1;
390 unsigned int secam_b:1;
391 unsigned int secam_d:1;
392 unsigned int secam_g:1;
393 unsigned int secam_k:1;
394
395 unsigned int secam_k1:1;
396 unsigned int secam_l:1;
397 unsigned int secam_60:1;
398 unsigned int pad:5;
399} __attribute__((packed));
400
401struct psb_intel_sdvo_sdtv_resolution_reply {
402 unsigned int res_320x200:1;
403 unsigned int res_320x240:1;
404 unsigned int res_400x300:1;
405 unsigned int res_640x350:1;
406 unsigned int res_640x400:1;
407 unsigned int res_640x480:1;
408 unsigned int res_704x480:1;
409 unsigned int res_704x576:1;
410
411 unsigned int res_720x350:1;
412 unsigned int res_720x400:1;
413 unsigned int res_720x480:1;
414 unsigned int res_720x540:1;
415 unsigned int res_720x576:1;
416 unsigned int res_768x576:1;
417 unsigned int res_800x600:1;
418 unsigned int res_832x624:1;
419
420 unsigned int res_920x766:1;
421 unsigned int res_1024x768:1;
422 unsigned int res_1280x1024:1;
423 unsigned int pad:5;
424} __attribute__((packed));
425
426/* Get supported resolution with squire pixel aspect ratio that can be
427 scaled for the requested HDTV format */
428#define SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT 0x85
429
430struct psb_intel_sdvo_hdtv_resolution_request {
431 unsigned int hdtv_std_smpte_240m_1080i_59:1;
432 unsigned int hdtv_std_smpte_240m_1080i_60:1;
433 unsigned int hdtv_std_smpte_260m_1080i_59:1;
434 unsigned int hdtv_std_smpte_260m_1080i_60:1;
435 unsigned int hdtv_std_smpte_274m_1080i_50:1;
436 unsigned int hdtv_std_smpte_274m_1080i_59:1;
437 unsigned int hdtv_std_smpte_274m_1080i_60:1;
438 unsigned int hdtv_std_smpte_274m_1080p_23:1;
439
440 unsigned int hdtv_std_smpte_274m_1080p_24:1;
441 unsigned int hdtv_std_smpte_274m_1080p_25:1;
442 unsigned int hdtv_std_smpte_274m_1080p_29:1;
443 unsigned int hdtv_std_smpte_274m_1080p_30:1;
444 unsigned int hdtv_std_smpte_274m_1080p_50:1;
445 unsigned int hdtv_std_smpte_274m_1080p_59:1;
446 unsigned int hdtv_std_smpte_274m_1080p_60:1;
447 unsigned int hdtv_std_smpte_295m_1080i_50:1;
448
449 unsigned int hdtv_std_smpte_295m_1080p_50:1;
450 unsigned int hdtv_std_smpte_296m_720p_59:1;
451 unsigned int hdtv_std_smpte_296m_720p_60:1;
452 unsigned int hdtv_std_smpte_296m_720p_50:1;
453 unsigned int hdtv_std_smpte_293m_480p_59:1;
454 unsigned int hdtv_std_smpte_170m_480i_59:1;
455 unsigned int hdtv_std_iturbt601_576i_50:1;
456 unsigned int hdtv_std_iturbt601_576p_50:1;
457
458 unsigned int hdtv_std_eia_7702a_480i_60:1;
459 unsigned int hdtv_std_eia_7702a_480p_60:1;
460 unsigned int pad:6;
461} __attribute__((packed));
462
463struct psb_intel_sdvo_hdtv_resolution_reply {
464 unsigned int res_640x480:1;
465 unsigned int res_800x600:1;
466 unsigned int res_1024x768:1;
467 unsigned int res_1280x960:1;
468 unsigned int res_1400x1050:1;
469 unsigned int res_1600x1200:1;
470 unsigned int res_1920x1440:1;
471 unsigned int res_2048x1536:1;
472
473 unsigned int res_2560x1920:1;
474 unsigned int res_3200x2400:1;
475 unsigned int res_3840x2880:1;
476 unsigned int pad1:5;
477
478 unsigned int res_848x480:1;
479 unsigned int res_1064x600:1;
480 unsigned int res_1280x720:1;
481 unsigned int res_1360x768:1;
482 unsigned int res_1704x960:1;
483 unsigned int res_1864x1050:1;
484 unsigned int res_1920x1080:1;
485 unsigned int res_2128x1200:1;
486
487 unsigned int res_2560x1400:1;
488 unsigned int res_2728x1536:1;
489 unsigned int res_3408x1920:1;
490 unsigned int res_4264x2400:1;
491 unsigned int res_5120x2880:1;
492 unsigned int pad2:3;
493
494 unsigned int res_768x480:1;
495 unsigned int res_960x600:1;
496 unsigned int res_1152x720:1;
497 unsigned int res_1124x768:1;
498 unsigned int res_1536x960:1;
499 unsigned int res_1680x1050:1;
500 unsigned int res_1728x1080:1;
501 unsigned int res_1920x1200:1;
502
503 unsigned int res_2304x1440:1;
504 unsigned int res_2456x1536:1;
505 unsigned int res_3072x1920:1;
506 unsigned int res_3840x2400:1;
507 unsigned int res_4608x2880:1;
508 unsigned int pad3:3;
509
510 unsigned int res_1280x1024:1;
511 unsigned int pad4:7;
512
513 unsigned int res_1280x768:1;
514 unsigned int pad5:7;
515} __attribute__((packed));
516
517/* Get supported power state returns info for encoder and monitor, rely on
518 last SetTargetInput and SetTargetOutput calls */
519#define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a
520/* Get power state returns info for encoder and monitor, rely on last
521 SetTargetInput and SetTargetOutput calls */
522#define SDVO_CMD_GET_POWER_STATE 0x2b
523#define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b
524#define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c
525# define SDVO_ENCODER_STATE_ON (1 << 0)
526# define SDVO_ENCODER_STATE_STANDBY (1 << 1)
527# define SDVO_ENCODER_STATE_SUSPEND (1 << 2)
528# define SDVO_ENCODER_STATE_OFF (1 << 3)
529# define SDVO_MONITOR_STATE_ON (1 << 4)
530# define SDVO_MONITOR_STATE_STANDBY (1 << 5)
531# define SDVO_MONITOR_STATE_SUSPEND (1 << 6)
532# define SDVO_MONITOR_STATE_OFF (1 << 7)
533
534#define SDVO_CMD_GET_MAX_PANEL_POWER_SEQUENCING 0x2d
535#define SDVO_CMD_GET_PANEL_POWER_SEQUENCING 0x2e
536#define SDVO_CMD_SET_PANEL_POWER_SEQUENCING 0x2f
537/**
538 * The panel power sequencing parameters are in units of milliseconds.
539 * The high fields are bits 8:9 of the 10-bit values.
540 */
541struct psb_sdvo_panel_power_sequencing {
542 u8 t0;
543 u8 t1;
544 u8 t2;
545 u8 t3;
546 u8 t4;
547
548 unsigned int t0_high:2;
549 unsigned int t1_high:2;
550 unsigned int t2_high:2;
551 unsigned int t3_high:2;
552
553 unsigned int t4_high:2;
554 unsigned int pad:6;
555} __attribute__((packed));
556
557#define SDVO_CMD_GET_MAX_BACKLIGHT_LEVEL 0x30
558struct sdvo_max_backlight_reply {
559 u8 max_value;
560 u8 default_value;
561} __attribute__((packed));
562
563#define SDVO_CMD_GET_BACKLIGHT_LEVEL 0x31
564#define SDVO_CMD_SET_BACKLIGHT_LEVEL 0x32
565
566#define SDVO_CMD_GET_AMBIENT_LIGHT 0x33
567struct sdvo_get_ambient_light_reply {
568 u16 trip_low;
569 u16 trip_high;
570 u16 value;
571} __attribute__((packed));
572#define SDVO_CMD_SET_AMBIENT_LIGHT 0x34
573struct sdvo_set_ambient_light_reply {
574 u16 trip_low;
575 u16 trip_high;
576 unsigned int enable:1;
577 unsigned int pad:7;
578} __attribute__((packed));
579
580/* Set display power state */
581#define SDVO_CMD_SET_DISPLAY_POWER_STATE 0x7d
582# define SDVO_DISPLAY_STATE_ON (1 << 0)
583# define SDVO_DISPLAY_STATE_STANDBY (1 << 1)
584# define SDVO_DISPLAY_STATE_SUSPEND (1 << 2)
585# define SDVO_DISPLAY_STATE_OFF (1 << 3)
586
587#define SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS 0x84
588struct psb_intel_sdvo_enhancements_reply {
589 unsigned int flicker_filter:1;
590 unsigned int flicker_filter_adaptive:1;
591 unsigned int flicker_filter_2d:1;
592 unsigned int saturation:1;
593 unsigned int hue:1;
594 unsigned int brightness:1;
595 unsigned int contrast:1;
596 unsigned int overscan_h:1;
597
598 unsigned int overscan_v:1;
599 unsigned int hpos:1;
600 unsigned int vpos:1;
601 unsigned int sharpness:1;
602 unsigned int dot_crawl:1;
603 unsigned int dither:1;
604 unsigned int tv_chroma_filter:1;
605 unsigned int tv_luma_filter:1;
606} __attribute__((packed));
607
608/* Picture enhancement limits below are dependent on the current TV format,
609 * and thus need to be queried and set after it.
610 */
611#define SDVO_CMD_GET_MAX_FLICKER_FILTER 0x4d
612#define SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE 0x7b
613#define SDVO_CMD_GET_MAX_FLICKER_FILTER_2D 0x52
614#define SDVO_CMD_GET_MAX_SATURATION 0x55
615#define SDVO_CMD_GET_MAX_HUE 0x58
616#define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b
617#define SDVO_CMD_GET_MAX_CONTRAST 0x5e
618#define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61
619#define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64
620#define SDVO_CMD_GET_MAX_HPOS 0x67
621#define SDVO_CMD_GET_MAX_VPOS 0x6a
622#define SDVO_CMD_GET_MAX_SHARPNESS 0x6d
623#define SDVO_CMD_GET_MAX_TV_CHROMA_FILTER 0x74
624#define SDVO_CMD_GET_MAX_TV_LUMA_FILTER 0x77
625struct psb_intel_sdvo_enhancement_limits_reply {
626 u16 max_value;
627 u16 default_value;
628} __attribute__((packed));
629
630#define SDVO_CMD_GET_LVDS_PANEL_INFORMATION 0x7f
631#define SDVO_CMD_SET_LVDS_PANEL_INFORMATION 0x80
632# define SDVO_LVDS_COLOR_DEPTH_18 (0 << 0)
633# define SDVO_LVDS_COLOR_DEPTH_24 (1 << 0)
634# define SDVO_LVDS_CONNECTOR_SPWG (0 << 2)
635# define SDVO_LVDS_CONNECTOR_OPENLDI (1 << 2)
636# define SDVO_LVDS_SINGLE_CHANNEL (0 << 4)
637# define SDVO_LVDS_DUAL_CHANNEL (1 << 4)
638
639#define SDVO_CMD_GET_FLICKER_FILTER 0x4e
640#define SDVO_CMD_SET_FLICKER_FILTER 0x4f
641#define SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE 0x50
642#define SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE 0x51
643#define SDVO_CMD_GET_FLICKER_FILTER_2D 0x53
644#define SDVO_CMD_SET_FLICKER_FILTER_2D 0x54
645#define SDVO_CMD_GET_SATURATION 0x56
646#define SDVO_CMD_SET_SATURATION 0x57
647#define SDVO_CMD_GET_HUE 0x59
648#define SDVO_CMD_SET_HUE 0x5a
649#define SDVO_CMD_GET_BRIGHTNESS 0x5c
650#define SDVO_CMD_SET_BRIGHTNESS 0x5d
651#define SDVO_CMD_GET_CONTRAST 0x5f
652#define SDVO_CMD_SET_CONTRAST 0x60
653#define SDVO_CMD_GET_OVERSCAN_H 0x62
654#define SDVO_CMD_SET_OVERSCAN_H 0x63
655#define SDVO_CMD_GET_OVERSCAN_V 0x65
656#define SDVO_CMD_SET_OVERSCAN_V 0x66
657#define SDVO_CMD_GET_HPOS 0x68
658#define SDVO_CMD_SET_HPOS 0x69
659#define SDVO_CMD_GET_VPOS 0x6b
660#define SDVO_CMD_SET_VPOS 0x6c
661#define SDVO_CMD_GET_SHARPNESS 0x6e
662#define SDVO_CMD_SET_SHARPNESS 0x6f
663#define SDVO_CMD_GET_TV_CHROMA_FILTER 0x75
664#define SDVO_CMD_SET_TV_CHROMA_FILTER 0x76
665#define SDVO_CMD_GET_TV_LUMA_FILTER 0x78
666#define SDVO_CMD_SET_TV_LUMA_FILTER 0x79
667struct psb_intel_sdvo_enhancements_arg {
668 u16 value;
669}__attribute__((packed));
670
671#define SDVO_CMD_GET_DOT_CRAWL 0x70
672#define SDVO_CMD_SET_DOT_CRAWL 0x71
673# define SDVO_DOT_CRAWL_ON (1 << 0)
674# define SDVO_DOT_CRAWL_DEFAULT_ON (1 << 1)
675
676#define SDVO_CMD_GET_DITHER 0x72
677#define SDVO_CMD_SET_DITHER 0x73
678# define SDVO_DITHER_ON (1 << 0)
679# define SDVO_DITHER_DEFAULT_ON (1 << 1)
680
681#define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a
682# define SDVO_CONTROL_BUS_PROM (1 << 0)
683# define SDVO_CONTROL_BUS_DDC1 (1 << 1)
684# define SDVO_CONTROL_BUS_DDC2 (1 << 2)
685# define SDVO_CONTROL_BUS_DDC3 (1 << 3)
686
687/* HDMI op codes */
688#define SDVO_CMD_GET_SUPP_ENCODE 0x9d
689#define SDVO_CMD_GET_ENCODE 0x9e
690#define SDVO_CMD_SET_ENCODE 0x9f
691 #define SDVO_ENCODE_DVI 0x0
692 #define SDVO_ENCODE_HDMI 0x1
693#define SDVO_CMD_SET_PIXEL_REPLI 0x8b
694#define SDVO_CMD_GET_PIXEL_REPLI 0x8c
695#define SDVO_CMD_GET_COLORIMETRY_CAP 0x8d
696#define SDVO_CMD_SET_COLORIMETRY 0x8e
697 #define SDVO_COLORIMETRY_RGB256 0x0
698 #define SDVO_COLORIMETRY_RGB220 0x1
699 #define SDVO_COLORIMETRY_YCrCb422 0x3
700 #define SDVO_COLORIMETRY_YCrCb444 0x4
701#define SDVO_CMD_GET_COLORIMETRY 0x8f
702#define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90
703#define SDVO_CMD_SET_AUDIO_STAT 0x91
704#define SDVO_CMD_GET_AUDIO_STAT 0x92
705#define SDVO_CMD_SET_HBUF_INDEX 0x93
706#define SDVO_CMD_GET_HBUF_INDEX 0x94
707#define SDVO_CMD_GET_HBUF_INFO 0x95
708#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96
709#define SDVO_CMD_GET_HBUF_AV_SPLIT 0x97
710#define SDVO_CMD_SET_HBUF_DATA 0x98
711#define SDVO_CMD_GET_HBUF_DATA 0x99
712#define SDVO_CMD_SET_HBUF_TXRATE 0x9a
713#define SDVO_CMD_GET_HBUF_TXRATE 0x9b
714 #define SDVO_HBUF_TX_DISABLED (0 << 6)
715 #define SDVO_HBUF_TX_ONCE (2 << 6)
716 #define SDVO_HBUF_TX_VSYNC (3 << 6)
717#define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c
718#define SDVO_NEED_TO_STALL (1 << 7)
719
720struct psb_intel_sdvo_encode {
721 u8 dvi_rev;
722 u8 hdmi_rev;
723} __attribute__ ((packed));
diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c
new file mode 100644
index 00000000000..7be802baceb
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_irq.c
@@ -0,0 +1,564 @@
1/**************************************************************************
2 * Copyright (c) 2007, 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 * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
19 * develop this driver.
20 *
21 **************************************************************************/
22/*
23 */
24
25#include <drm/drmP.h>
26#include "psb_drv.h"
27#include "psb_reg.h"
28#include "psb_intel_reg.h"
29#include "power.h"
30
31/*
32 * inline functions
33 */
34
35static inline u32
36psb_pipestat(int pipe)
37{
38 if (pipe == 0)
39 return PIPEASTAT;
40 if (pipe == 1)
41 return PIPEBSTAT;
42 if (pipe == 2)
43 return PIPECSTAT;
44 BUG();
45}
46
47static inline u32
48mid_pipe_event(int pipe)
49{
50 if (pipe == 0)
51 return _PSB_PIPEA_EVENT_FLAG;
52 if (pipe == 1)
53 return _MDFLD_PIPEB_EVENT_FLAG;
54 if (pipe == 2)
55 return _MDFLD_PIPEC_EVENT_FLAG;
56 BUG();
57}
58
59static inline u32
60mid_pipe_vsync(int pipe)
61{
62 if (pipe == 0)
63 return _PSB_VSYNC_PIPEA_FLAG;
64 if (pipe == 1)
65 return _PSB_VSYNC_PIPEB_FLAG;
66 if (pipe == 2)
67 return _MDFLD_PIPEC_VBLANK_FLAG;
68 BUG();
69}
70
71static inline u32
72mid_pipeconf(int pipe)
73{
74 if (pipe == 0)
75 return PIPEACONF;
76 if (pipe == 1)
77 return PIPEBCONF;
78 if (pipe == 2)
79 return PIPECCONF;
80 BUG();
81}
82
83void
84psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
85{
86 if ((dev_priv->pipestat[pipe] & mask) != mask) {
87 u32 reg = psb_pipestat(pipe);
88 dev_priv->pipestat[pipe] |= mask;
89 /* Enable the interrupt, clear any pending status */
90 if (gma_power_begin(dev_priv->dev, false)) {
91 u32 writeVal = PSB_RVDC32(reg);
92 writeVal |= (mask | (mask >> 16));
93 PSB_WVDC32(writeVal, reg);
94 (void) PSB_RVDC32(reg);
95 gma_power_end(dev_priv->dev);
96 }
97 }
98}
99
100void
101psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
102{
103 if ((dev_priv->pipestat[pipe] & mask) != 0) {
104 u32 reg = psb_pipestat(pipe);
105 dev_priv->pipestat[pipe] &= ~mask;
106 if (gma_power_begin(dev_priv->dev, false)) {
107 u32 writeVal = PSB_RVDC32(reg);
108 writeVal &= ~mask;
109 PSB_WVDC32(writeVal, reg);
110 (void) PSB_RVDC32(reg);
111 gma_power_end(dev_priv->dev);
112 }
113 }
114}
115
116void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
117{
118 if (gma_power_begin(dev_priv->dev, false)) {
119 u32 pipe_event = mid_pipe_event(pipe);
120 dev_priv->vdc_irq_mask |= pipe_event;
121 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
122 PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
123 gma_power_end(dev_priv->dev);
124 }
125}
126
127void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
128{
129 if (dev_priv->pipestat[pipe] == 0) {
130 if (gma_power_begin(dev_priv->dev, false)) {
131 u32 pipe_event = mid_pipe_event(pipe);
132 dev_priv->vdc_irq_mask &= ~pipe_event;
133 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
134 PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
135 gma_power_end(dev_priv->dev);
136 }
137 }
138}
139
140/**
141 * Display controller interrupt handler for pipe event.
142 *
143 */
144static void mid_pipe_event_handler(struct drm_device *dev, int pipe)
145{
146 struct drm_psb_private *dev_priv =
147 (struct drm_psb_private *) dev->dev_private;
148
149 uint32_t pipe_stat_val = 0;
150 uint32_t pipe_stat_reg = psb_pipestat(pipe);
151 uint32_t pipe_enable = dev_priv->pipestat[pipe];
152 uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16;
153 uint32_t pipe_clear;
154 uint32_t i = 0;
155
156 spin_lock(&dev_priv->irqmask_lock);
157
158 pipe_stat_val = PSB_RVDC32(pipe_stat_reg);
159 pipe_stat_val &= pipe_enable | pipe_status;
160 pipe_stat_val &= pipe_stat_val >> 16;
161
162 spin_unlock(&dev_priv->irqmask_lock);
163
164 /* Clear the 2nd level interrupt status bits
165 * Sometimes the bits are very sticky so we repeat until they unstick */
166 for (i = 0; i < 0xffff; i++) {
167 PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg);
168 pipe_clear = PSB_RVDC32(pipe_stat_reg) & pipe_status;
169
170 if (pipe_clear == 0)
171 break;
172 }
173
174 if (pipe_clear)
175 dev_err(dev->dev,
176 "%s, can't clear status bits for pipe %d, its value = 0x%x.\n",
177 __func__, pipe, PSB_RVDC32(pipe_stat_reg));
178
179 if (pipe_stat_val & PIPE_VBLANK_STATUS)
180 drm_handle_vblank(dev, pipe);
181
182 if (pipe_stat_val & PIPE_TE_STATUS)
183 drm_handle_vblank(dev, pipe);
184}
185
186/*
187 * Display controller interrupt handler.
188 */
189static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)
190{
191 if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)
192 mid_pipe_event_handler(dev, 0);
193
194 if (vdc_stat & _PSB_VSYNC_PIPEB_FLAG)
195 mid_pipe_event_handler(dev, 1);
196}
197
198irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
199{
200 struct drm_device *dev = (struct drm_device *) arg;
201 struct drm_psb_private *dev_priv =
202 (struct drm_psb_private *) dev->dev_private;
203
204 uint32_t vdc_stat, dsp_int = 0, sgx_int = 0;
205 int handled = 0;
206
207 spin_lock(&dev_priv->irqmask_lock);
208
209 vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);
210
211 if (vdc_stat & _PSB_PIPE_EVENT_FLAG)
212 dsp_int = 1;
213
214 /* FIXME: Handle Medfield
215 if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG)
216 dsp_int = 1;
217 */
218
219 if (vdc_stat & _PSB_IRQ_SGX_FLAG)
220 sgx_int = 1;
221
222 vdc_stat &= dev_priv->vdc_irq_mask;
223 spin_unlock(&dev_priv->irqmask_lock);
224
225 if (dsp_int && gma_power_is_on(dev)) {
226 psb_vdc_interrupt(dev, vdc_stat);
227 handled = 1;
228 }
229
230 if (sgx_int) {
231 /* Not expected - we have it masked, shut it up */
232 u32 s, s2;
233 s = PSB_RSGX32(PSB_CR_EVENT_STATUS);
234 s2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2);
235 PSB_WSGX32(s, PSB_CR_EVENT_HOST_CLEAR);
236 PSB_WSGX32(s2, PSB_CR_EVENT_HOST_CLEAR2);
237 /* if s & _PSB_CE_TWOD_COMPLETE we have 2D done but
238 we may as well poll even if we add that ! */
239 handled = 1;
240 }
241
242 PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R);
243 (void) PSB_RVDC32(PSB_INT_IDENTITY_R);
244 DRM_READMEMORYBARRIER();
245
246 if (!handled)
247 return IRQ_NONE;
248
249 return IRQ_HANDLED;
250}
251
252void psb_irq_preinstall(struct drm_device *dev)
253{
254 struct drm_psb_private *dev_priv =
255 (struct drm_psb_private *) dev->dev_private;
256 unsigned long irqflags;
257
258 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
259
260 if (gma_power_is_on(dev))
261 PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
262 if (dev->vblank_enabled[0])
263 dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
264 if (dev->vblank_enabled[1])
265 dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
266
267 /* FIXME: Handle Medfield irq mask
268 if (dev->vblank_enabled[1])
269 dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG;
270 if (dev->vblank_enabled[2])
271 dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG;
272 */
273
274 /* This register is safe even if display island is off */
275 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
276 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
277}
278
279int psb_irq_postinstall(struct drm_device *dev)
280{
281 struct drm_psb_private *dev_priv =
282 (struct drm_psb_private *) dev->dev_private;
283 unsigned long irqflags;
284
285 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
286
287 /* This register is safe even if display island is off */
288 PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
289 PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
290
291 if (dev->vblank_enabled[0])
292 psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
293 else
294 psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
295
296 if (dev->vblank_enabled[1])
297 psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
298 else
299 psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
300
301 if (dev->vblank_enabled[2])
302 psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
303 else
304 psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
305
306 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
307 return 0;
308}
309
310void psb_irq_uninstall(struct drm_device *dev)
311{
312 struct drm_psb_private *dev_priv =
313 (struct drm_psb_private *) dev->dev_private;
314 unsigned long irqflags;
315
316 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
317
318 PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
319
320 if (dev->vblank_enabled[0])
321 psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
322
323 if (dev->vblank_enabled[1])
324 psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
325
326 if (dev->vblank_enabled[2])
327 psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
328
329 dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
330 _PSB_IRQ_MSVDX_FLAG |
331 _LNC_IRQ_TOPAZ_FLAG;
332
333 /* These two registers are safe even if display island is off */
334 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
335 PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
336
337 wmb();
338
339 /* This register is safe even if display island is off */
340 PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
341 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
342}
343
344void psb_irq_turn_on_dpst(struct drm_device *dev)
345{
346 struct drm_psb_private *dev_priv =
347 (struct drm_psb_private *) dev->dev_private;
348 u32 hist_reg;
349 u32 pwm_reg;
350
351 if (gma_power_begin(dev, false)) {
352 PSB_WVDC32(1 << 31, HISTOGRAM_LOGIC_CONTROL);
353 hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
354 PSB_WVDC32(1 << 31, HISTOGRAM_INT_CONTROL);
355 hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
356
357 PSB_WVDC32(0x80010100, PWM_CONTROL_LOGIC);
358 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
359 PSB_WVDC32(pwm_reg | PWM_PHASEIN_ENABLE
360 | PWM_PHASEIN_INT_ENABLE,
361 PWM_CONTROL_LOGIC);
362 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
363
364 psb_enable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
365
366 hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
367 PSB_WVDC32(hist_reg | HISTOGRAM_INT_CTRL_CLEAR,
368 HISTOGRAM_INT_CONTROL);
369 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
370 PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE,
371 PWM_CONTROL_LOGIC);
372
373 gma_power_end(dev);
374 }
375}
376
377int psb_irq_enable_dpst(struct drm_device *dev)
378{
379 struct drm_psb_private *dev_priv =
380 (struct drm_psb_private *) dev->dev_private;
381 unsigned long irqflags;
382
383 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
384
385 /* enable DPST */
386 mid_enable_pipe_event(dev_priv, 0);
387 psb_irq_turn_on_dpst(dev);
388
389 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
390 return 0;
391}
392
393void psb_irq_turn_off_dpst(struct drm_device *dev)
394{
395 struct drm_psb_private *dev_priv =
396 (struct drm_psb_private *) dev->dev_private;
397 u32 hist_reg;
398 u32 pwm_reg;
399
400 if (gma_power_begin(dev, false)) {
401 PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL);
402 hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
403
404 psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
405
406 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
407 PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE),
408 PWM_CONTROL_LOGIC);
409 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
410
411 gma_power_end(dev);
412 }
413}
414
415int psb_irq_disable_dpst(struct drm_device *dev)
416{
417 struct drm_psb_private *dev_priv =
418 (struct drm_psb_private *) dev->dev_private;
419 unsigned long irqflags;
420
421 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
422
423 mid_disable_pipe_event(dev_priv, 0);
424 psb_irq_turn_off_dpst(dev);
425
426 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
427
428 return 0;
429}
430
431#ifdef PSB_FIXME
432static int psb_vblank_do_wait(struct drm_device *dev,
433 unsigned int *sequence, atomic_t *counter)
434{
435 unsigned int cur_vblank;
436 int ret = 0;
437 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
438 (((cur_vblank = atomic_read(counter))
439 - *sequence) <= (1 << 23)));
440 *sequence = cur_vblank;
441
442 return ret;
443}
444#endif
445
446/*
447 * It is used to enable VBLANK interrupt
448 */
449int psb_enable_vblank(struct drm_device *dev, int pipe)
450{
451 struct drm_psb_private *dev_priv = dev->dev_private;
452 unsigned long irqflags;
453 uint32_t reg_val = 0;
454 uint32_t pipeconf_reg = mid_pipeconf(pipe);
455
456 if (gma_power_begin(dev, false)) {
457 reg_val = REG_READ(pipeconf_reg);
458 gma_power_end(dev);
459 }
460
461 if (!(reg_val & PIPEACONF_ENABLE))
462 return -EINVAL;
463
464 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
465
466 if (pipe == 0)
467 dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
468 else if (pipe == 1)
469 dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
470
471 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
472 PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
473 psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
474
475 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
476
477 return 0;
478}
479
480/*
481 * It is used to disable VBLANK interrupt
482 */
483void psb_disable_vblank(struct drm_device *dev, int pipe)
484{
485 struct drm_psb_private *dev_priv = dev->dev_private;
486 unsigned long irqflags;
487
488 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
489
490 if (pipe == 0)
491 dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEA_FLAG;
492 else if (pipe == 1)
493 dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEB_FLAG;
494
495 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
496 PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
497 psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
498
499 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
500}
501
502/* Called from drm generic code, passed a 'crtc', which
503 * we use as a pipe index
504 */
505u32 psb_get_vblank_counter(struct drm_device *dev, int pipe)
506{
507 uint32_t high_frame = PIPEAFRAMEHIGH;
508 uint32_t low_frame = PIPEAFRAMEPIXEL;
509 uint32_t pipeconf_reg = PIPEACONF;
510 uint32_t reg_val = 0;
511 uint32_t high1 = 0, high2 = 0, low = 0, count = 0;
512
513 switch (pipe) {
514 case 0:
515 break;
516 case 1:
517 high_frame = PIPEBFRAMEHIGH;
518 low_frame = PIPEBFRAMEPIXEL;
519 pipeconf_reg = PIPEBCONF;
520 break;
521 case 2:
522 high_frame = PIPECFRAMEHIGH;
523 low_frame = PIPECFRAMEPIXEL;
524 pipeconf_reg = PIPECCONF;
525 break;
526 default:
527 dev_err(dev->dev, "%s, invalid pipe.\n", __func__);
528 return 0;
529 }
530
531 if (!gma_power_begin(dev, false))
532 return 0;
533
534 reg_val = REG_READ(pipeconf_reg);
535
536 if (!(reg_val & PIPEACONF_ENABLE)) {
537 dev_err(dev->dev, "trying to get vblank count for disabled pipe %d\n",
538 pipe);
539 goto psb_get_vblank_counter_exit;
540 }
541
542 /*
543 * High & low register fields aren't synchronized, so make sure
544 * we get a low value that's stable across two reads of the high
545 * register.
546 */
547 do {
548 high1 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
549 PIPE_FRAME_HIGH_SHIFT);
550 low = ((REG_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
551 PIPE_FRAME_LOW_SHIFT);
552 high2 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
553 PIPE_FRAME_HIGH_SHIFT);
554 } while (high1 != high2);
555
556 count = (high1 << 8) | low;
557
558psb_get_vblank_counter_exit:
559
560 gma_power_end(dev);
561
562 return count;
563}
564
diff --git a/drivers/gpu/drm/gma500/psb_irq.h b/drivers/gpu/drm/gma500/psb_irq.h
new file mode 100644
index 00000000000..216fda38b57
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_irq.h
@@ -0,0 +1,45 @@
1/**************************************************************************
2 * Copyright (c) 2009-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 * Authors:
19 * Benjamin Defnet <benjamin.r.defnet@intel.com>
20 * Rajesh Poornachandran <rajesh.poornachandran@intel.com>
21 *
22 **************************************************************************/
23
24#ifndef _SYSIRQ_H_
25#define _SYSIRQ_H_
26
27#include <drm/drmP.h>
28
29bool sysirq_init(struct drm_device *dev);
30void sysirq_uninit(struct drm_device *dev);
31
32void psb_irq_preinstall(struct drm_device *dev);
33int psb_irq_postinstall(struct drm_device *dev);
34void psb_irq_uninstall(struct drm_device *dev);
35irqreturn_t psb_irq_handler(DRM_IRQ_ARGS);
36
37int psb_irq_enable_dpst(struct drm_device *dev);
38int psb_irq_disable_dpst(struct drm_device *dev);
39void psb_irq_turn_on_dpst(struct drm_device *dev);
40void psb_irq_turn_off_dpst(struct drm_device *dev);
41int psb_enable_vblank(struct drm_device *dev, int pipe);
42void psb_disable_vblank(struct drm_device *dev, int pipe);
43u32 psb_get_vblank_counter(struct drm_device *dev, int pipe);
44
45#endif /* _SYSIRQ_H_ */
diff --git a/drivers/gpu/drm/gma500/psb_lid.c b/drivers/gpu/drm/gma500/psb_lid.c
new file mode 100644
index 00000000000..b867aabe6bf
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_lid.c
@@ -0,0 +1,88 @@
1/**************************************************************************
2 * Copyright (c) 2007, 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: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
18 **************************************************************************/
19
20#include <drm/drmP.h>
21#include "psb_drv.h"
22#include "psb_reg.h"
23#include "psb_intel_reg.h"
24#include <linux/spinlock.h>
25
26static void psb_lid_timer_func(unsigned long data)
27{
28 struct drm_psb_private * dev_priv = (struct drm_psb_private *)data;
29 struct drm_device *dev = (struct drm_device *)dev_priv->dev;
30 struct timer_list *lid_timer = &dev_priv->lid_timer;
31 unsigned long irq_flags;
32 u32 *lid_state = dev_priv->lid_state;
33 u32 pp_status;
34
35 if (readl(lid_state) == dev_priv->lid_last_state)
36 goto lid_timer_schedule;
37
38 if ((readl(lid_state)) & 0x01) {
39 /*lid state is open*/
40 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON);
41 do {
42 pp_status = REG_READ(PP_STATUS);
43 } while ((pp_status & PP_ON) == 0);
44
45 /*FIXME: should be backlight level before*/
46 psb_intel_lvds_set_brightness(dev, 100);
47 } else {
48 psb_intel_lvds_set_brightness(dev, 0);
49
50 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON);
51 do {
52 pp_status = REG_READ(PP_STATUS);
53 } while ((pp_status & PP_ON) == 0);
54 }
55 dev_priv->lid_last_state = readl(lid_state);
56
57lid_timer_schedule:
58 spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
59 if (!timer_pending(lid_timer)) {
60 lid_timer->expires = jiffies + PSB_LID_DELAY;
61 add_timer(lid_timer);
62 }
63 spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
64}
65
66void psb_lid_timer_init(struct drm_psb_private *dev_priv)
67{
68 struct timer_list *lid_timer = &dev_priv->lid_timer;
69 unsigned long irq_flags;
70
71 spin_lock_init(&dev_priv->lid_lock);
72 spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
73
74 init_timer(lid_timer);
75
76 lid_timer->data = (unsigned long)dev_priv;
77 lid_timer->function = psb_lid_timer_func;
78 lid_timer->expires = jiffies + PSB_LID_DELAY;
79
80 add_timer(lid_timer);
81 spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
82}
83
84void psb_lid_timer_takedown(struct drm_psb_private *dev_priv)
85{
86 del_timer_sync(&dev_priv->lid_timer);
87}
88
diff --git a/drivers/gpu/drm/gma500/psb_reg.h b/drivers/gpu/drm/gma500/psb_reg.h
new file mode 100644
index 00000000000..b81c7c1e9c2
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_reg.h
@@ -0,0 +1,582 @@
1/**************************************************************************
2 *
3 * Copyright (c) (2005-2007) Imagination Technologies Limited.
4 * Copyright (c) 2007, Intel Corporation.
5 * All Rights Reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA..
19 *
20 **************************************************************************/
21
22#ifndef _PSB_REG_H_
23#define _PSB_REG_H_
24
25#define PSB_CR_CLKGATECTL 0x0000
26#define _PSB_C_CLKGATECTL_AUTO_MAN_REG (1 << 24)
27#define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT (20)
28#define _PSB_C_CLKGATECTL_USE_CLKG_MASK (0x3 << 20)
29#define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT (16)
30#define _PSB_C_CLKGATECTL_DPM_CLKG_MASK (0x3 << 16)
31#define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT (12)
32#define _PSB_C_CLKGATECTL_TA_CLKG_MASK (0x3 << 12)
33#define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT (8)
34#define _PSB_C_CLKGATECTL_TSP_CLKG_MASK (0x3 << 8)
35#define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT (4)
36#define _PSB_C_CLKGATECTL_ISP_CLKG_MASK (0x3 << 4)
37#define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT (0)
38#define _PSB_C_CLKGATECTL_2D_CLKG_MASK (0x3 << 0)
39#define _PSB_C_CLKGATECTL_CLKG_ENABLED (0)
40#define _PSB_C_CLKGATECTL_CLKG_DISABLED (1)
41#define _PSB_C_CLKGATECTL_CLKG_AUTO (2)
42
43#define PSB_CR_CORE_ID 0x0010
44#define _PSB_CC_ID_ID_SHIFT (16)
45#define _PSB_CC_ID_ID_MASK (0xFFFF << 16)
46#define _PSB_CC_ID_CONFIG_SHIFT (0)
47#define _PSB_CC_ID_CONFIG_MASK (0xFFFF << 0)
48
49#define PSB_CR_CORE_REVISION 0x0014
50#define _PSB_CC_REVISION_DESIGNER_SHIFT (24)
51#define _PSB_CC_REVISION_DESIGNER_MASK (0xFF << 24)
52#define _PSB_CC_REVISION_MAJOR_SHIFT (16)
53#define _PSB_CC_REVISION_MAJOR_MASK (0xFF << 16)
54#define _PSB_CC_REVISION_MINOR_SHIFT (8)
55#define _PSB_CC_REVISION_MINOR_MASK (0xFF << 8)
56#define _PSB_CC_REVISION_MAINTENANCE_SHIFT (0)
57#define _PSB_CC_REVISION_MAINTENANCE_MASK (0xFF << 0)
58
59#define PSB_CR_DESIGNER_REV_FIELD1 0x0018
60
61#define PSB_CR_SOFT_RESET 0x0080
62#define _PSB_CS_RESET_TSP_RESET (1 << 6)
63#define _PSB_CS_RESET_ISP_RESET (1 << 5)
64#define _PSB_CS_RESET_USE_RESET (1 << 4)
65#define _PSB_CS_RESET_TA_RESET (1 << 3)
66#define _PSB_CS_RESET_DPM_RESET (1 << 2)
67#define _PSB_CS_RESET_TWOD_RESET (1 << 1)
68#define _PSB_CS_RESET_BIF_RESET (1 << 0)
69
70#define PSB_CR_DESIGNER_REV_FIELD2 0x001C
71
72#define PSB_CR_EVENT_HOST_ENABLE2 0x0110
73
74#define PSB_CR_EVENT_STATUS2 0x0118
75
76#define PSB_CR_EVENT_HOST_CLEAR2 0x0114
77#define _PSB_CE2_BIF_REQUESTER_FAULT (1 << 4)
78
79#define PSB_CR_EVENT_STATUS 0x012C
80
81#define PSB_CR_EVENT_HOST_ENABLE 0x0130
82
83#define PSB_CR_EVENT_HOST_CLEAR 0x0134
84#define _PSB_CE_MASTER_INTERRUPT (1 << 31)
85#define _PSB_CE_TA_DPM_FAULT (1 << 28)
86#define _PSB_CE_TWOD_COMPLETE (1 << 27)
87#define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS (1 << 25)
88#define _PSB_CE_DPM_TA_MEM_FREE (1 << 24)
89#define _PSB_CE_PIXELBE_END_RENDER (1 << 18)
90#define _PSB_CE_SW_EVENT (1 << 14)
91#define _PSB_CE_TA_FINISHED (1 << 13)
92#define _PSB_CE_TA_TERMINATE (1 << 12)
93#define _PSB_CE_DPM_REACHED_MEM_THRESH (1 << 3)
94#define _PSB_CE_DPM_OUT_OF_MEMORY_GBL (1 << 2)
95#define _PSB_CE_DPM_OUT_OF_MEMORY_MT (1 << 1)
96#define _PSB_CE_DPM_3D_MEM_FREE (1 << 0)
97
98
99#define PSB_USE_OFFSET_MASK 0x0007FFFF
100#define PSB_USE_OFFSET_SIZE (PSB_USE_OFFSET_MASK + 1)
101#define PSB_CR_USE_CODE_BASE0 0x0A0C
102#define PSB_CR_USE_CODE_BASE1 0x0A10
103#define PSB_CR_USE_CODE_BASE2 0x0A14
104#define PSB_CR_USE_CODE_BASE3 0x0A18
105#define PSB_CR_USE_CODE_BASE4 0x0A1C
106#define PSB_CR_USE_CODE_BASE5 0x0A20
107#define PSB_CR_USE_CODE_BASE6 0x0A24
108#define PSB_CR_USE_CODE_BASE7 0x0A28
109#define PSB_CR_USE_CODE_BASE8 0x0A2C
110#define PSB_CR_USE_CODE_BASE9 0x0A30
111#define PSB_CR_USE_CODE_BASE10 0x0A34
112#define PSB_CR_USE_CODE_BASE11 0x0A38
113#define PSB_CR_USE_CODE_BASE12 0x0A3C
114#define PSB_CR_USE_CODE_BASE13 0x0A40
115#define PSB_CR_USE_CODE_BASE14 0x0A44
116#define PSB_CR_USE_CODE_BASE15 0x0A48
117#define PSB_CR_USE_CODE_BASE(_i) (0x0A0C + ((_i) << 2))
118#define _PSB_CUC_BASE_DM_SHIFT (25)
119#define _PSB_CUC_BASE_DM_MASK (0x3 << 25)
120#define _PSB_CUC_BASE_ADDR_SHIFT (0) /* 1024-bit aligned address? */
121#define _PSB_CUC_BASE_ADDR_ALIGNSHIFT (7)
122#define _PSB_CUC_BASE_ADDR_MASK (0x1FFFFFF << 0)
123#define _PSB_CUC_DM_VERTEX (0)
124#define _PSB_CUC_DM_PIXEL (1)
125#define _PSB_CUC_DM_RESERVED (2)
126#define _PSB_CUC_DM_EDM (3)
127
128#define PSB_CR_PDS_EXEC_BASE 0x0AB8
129#define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT (20) /* 1MB aligned address */
130#define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT (20)
131
132#define PSB_CR_EVENT_KICKER 0x0AC4
133#define _PSB_CE_KICKER_ADDRESS_SHIFT (4) /* 128-bit aligned address */
134
135#define PSB_CR_EVENT_KICK 0x0AC8
136#define _PSB_CE_KICK_NOW (1 << 0)
137
138#define PSB_CR_BIF_DIR_LIST_BASE1 0x0C38
139
140#define PSB_CR_BIF_CTRL 0x0C00
141#define _PSB_CB_CTRL_CLEAR_FAULT (1 << 4)
142#define _PSB_CB_CTRL_INVALDC (1 << 3)
143#define _PSB_CB_CTRL_FLUSH (1 << 2)
144
145#define PSB_CR_BIF_INT_STAT 0x0C04
146
147#define PSB_CR_BIF_FAULT 0x0C08
148#define _PSB_CBI_STAT_PF_N_RW (1 << 14)
149#define _PSB_CBI_STAT_FAULT_SHIFT (0)
150#define _PSB_CBI_STAT_FAULT_MASK (0x3FFF << 0)
151#define _PSB_CBI_STAT_FAULT_CACHE (1 << 1)
152#define _PSB_CBI_STAT_FAULT_TA (1 << 2)
153#define _PSB_CBI_STAT_FAULT_VDM (1 << 3)
154#define _PSB_CBI_STAT_FAULT_2D (1 << 4)
155#define _PSB_CBI_STAT_FAULT_PBE (1 << 5)
156#define _PSB_CBI_STAT_FAULT_TSP (1 << 6)
157#define _PSB_CBI_STAT_FAULT_ISP (1 << 7)
158#define _PSB_CBI_STAT_FAULT_USSEPDS (1 << 8)
159#define _PSB_CBI_STAT_FAULT_HOST (1 << 9)
160
161#define PSB_CR_BIF_BANK0 0x0C78
162#define PSB_CR_BIF_BANK1 0x0C7C
163#define PSB_CR_BIF_DIR_LIST_BASE0 0x0C84
164#define PSB_CR_BIF_TWOD_REQ_BASE 0x0C88
165#define PSB_CR_BIF_3D_REQ_BASE 0x0CAC
166
167#define PSB_CR_2D_SOCIF 0x0E18
168#define _PSB_C2_SOCIF_FREESPACE_SHIFT (0)
169#define _PSB_C2_SOCIF_FREESPACE_MASK (0xFF << 0)
170#define _PSB_C2_SOCIF_EMPTY (0x80 << 0)
171
172#define PSB_CR_2D_BLIT_STATUS 0x0E04
173#define _PSB_C2B_STATUS_BUSY (1 << 24)
174#define _PSB_C2B_STATUS_COMPLETE_SHIFT (0)
175#define _PSB_C2B_STATUS_COMPLETE_MASK (0xFFFFFF << 0)
176
177/*
178 * 2D defs.
179 */
180
181/*
182 * 2D Slave Port Data : Block Header's Object Type
183 */
184
185#define PSB_2D_CLIP_BH (0x00000000)
186#define PSB_2D_PAT_BH (0x10000000)
187#define PSB_2D_CTRL_BH (0x20000000)
188#define PSB_2D_SRC_OFF_BH (0x30000000)
189#define PSB_2D_MASK_OFF_BH (0x40000000)
190#define PSB_2D_RESERVED1_BH (0x50000000)
191#define PSB_2D_RESERVED2_BH (0x60000000)
192#define PSB_2D_FENCE_BH (0x70000000)
193#define PSB_2D_BLIT_BH (0x80000000)
194#define PSB_2D_SRC_SURF_BH (0x90000000)
195#define PSB_2D_DST_SURF_BH (0xA0000000)
196#define PSB_2D_PAT_SURF_BH (0xB0000000)
197#define PSB_2D_SRC_PAL_BH (0xC0000000)
198#define PSB_2D_PAT_PAL_BH (0xD0000000)
199#define PSB_2D_MASK_SURF_BH (0xE0000000)
200#define PSB_2D_FLUSH_BH (0xF0000000)
201
202/*
203 * Clip Definition block (PSB_2D_CLIP_BH)
204 */
205#define PSB_2D_CLIPCOUNT_MAX (1)
206#define PSB_2D_CLIPCOUNT_MASK (0x00000000)
207#define PSB_2D_CLIPCOUNT_CLRMASK (0xFFFFFFFF)
208#define PSB_2D_CLIPCOUNT_SHIFT (0)
209/* clip rectangle min & max */
210#define PSB_2D_CLIP_XMAX_MASK (0x00FFF000)
211#define PSB_2D_CLIP_XMAX_CLRMASK (0xFF000FFF)
212#define PSB_2D_CLIP_XMAX_SHIFT (12)
213#define PSB_2D_CLIP_XMIN_MASK (0x00000FFF)
214#define PSB_2D_CLIP_XMIN_CLRMASK (0x00FFF000)
215#define PSB_2D_CLIP_XMIN_SHIFT (0)
216/* clip rectangle offset */
217#define PSB_2D_CLIP_YMAX_MASK (0x00FFF000)
218#define PSB_2D_CLIP_YMAX_CLRMASK (0xFF000FFF)
219#define PSB_2D_CLIP_YMAX_SHIFT (12)
220#define PSB_2D_CLIP_YMIN_MASK (0x00000FFF)
221#define PSB_2D_CLIP_YMIN_CLRMASK (0x00FFF000)
222#define PSB_2D_CLIP_YMIN_SHIFT (0)
223
224/*
225 * Pattern Control (PSB_2D_PAT_BH)
226 */
227#define PSB_2D_PAT_HEIGHT_MASK (0x0000001F)
228#define PSB_2D_PAT_HEIGHT_SHIFT (0)
229#define PSB_2D_PAT_WIDTH_MASK (0x000003E0)
230#define PSB_2D_PAT_WIDTH_SHIFT (5)
231#define PSB_2D_PAT_YSTART_MASK (0x00007C00)
232#define PSB_2D_PAT_YSTART_SHIFT (10)
233#define PSB_2D_PAT_XSTART_MASK (0x000F8000)
234#define PSB_2D_PAT_XSTART_SHIFT (15)
235
236/*
237 * 2D Control block (PSB_2D_CTRL_BH)
238 */
239/* Present Flags */
240#define PSB_2D_SRCCK_CTRL (0x00000001)
241#define PSB_2D_DSTCK_CTRL (0x00000002)
242#define PSB_2D_ALPHA_CTRL (0x00000004)
243/* Colour Key Colour (SRC/DST)*/
244#define PSB_2D_CK_COL_MASK (0xFFFFFFFF)
245#define PSB_2D_CK_COL_CLRMASK (0x00000000)
246#define PSB_2D_CK_COL_SHIFT (0)
247/* Colour Key Mask (SRC/DST)*/
248#define PSB_2D_CK_MASK_MASK (0xFFFFFFFF)
249#define PSB_2D_CK_MASK_CLRMASK (0x00000000)
250#define PSB_2D_CK_MASK_SHIFT (0)
251/* Alpha Control (Alpha/RGB)*/
252#define PSB_2D_GBLALPHA_MASK (0x000FF000)
253#define PSB_2D_GBLALPHA_CLRMASK (0xFFF00FFF)
254#define PSB_2D_GBLALPHA_SHIFT (12)
255#define PSB_2D_SRCALPHA_OP_MASK (0x00700000)
256#define PSB_2D_SRCALPHA_OP_CLRMASK (0xFF8FFFFF)
257#define PSB_2D_SRCALPHA_OP_SHIFT (20)
258#define PSB_2D_SRCALPHA_OP_ONE (0x00000000)
259#define PSB_2D_SRCALPHA_OP_SRC (0x00100000)
260#define PSB_2D_SRCALPHA_OP_DST (0x00200000)
261#define PSB_2D_SRCALPHA_OP_SG (0x00300000)
262#define PSB_2D_SRCALPHA_OP_DG (0x00400000)
263#define PSB_2D_SRCALPHA_OP_GBL (0x00500000)
264#define PSB_2D_SRCALPHA_OP_ZERO (0x00600000)
265#define PSB_2D_SRCALPHA_INVERT (0x00800000)
266#define PSB_2D_SRCALPHA_INVERT_CLR (0xFF7FFFFF)
267#define PSB_2D_DSTALPHA_OP_MASK (0x07000000)
268#define PSB_2D_DSTALPHA_OP_CLRMASK (0xF8FFFFFF)
269#define PSB_2D_DSTALPHA_OP_SHIFT (24)
270#define PSB_2D_DSTALPHA_OP_ONE (0x00000000)
271#define PSB_2D_DSTALPHA_OP_SRC (0x01000000)
272#define PSB_2D_DSTALPHA_OP_DST (0x02000000)
273#define PSB_2D_DSTALPHA_OP_SG (0x03000000)
274#define PSB_2D_DSTALPHA_OP_DG (0x04000000)
275#define PSB_2D_DSTALPHA_OP_GBL (0x05000000)
276#define PSB_2D_DSTALPHA_OP_ZERO (0x06000000)
277#define PSB_2D_DSTALPHA_INVERT (0x08000000)
278#define PSB_2D_DSTALPHA_INVERT_CLR (0xF7FFFFFF)
279
280#define PSB_2D_PRE_MULTIPLICATION_ENABLE (0x10000000)
281#define PSB_2D_PRE_MULTIPLICATION_CLRMASK (0xEFFFFFFF)
282#define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE (0x20000000)
283#define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK (0xDFFFFFFF)
284
285/*
286 *Source Offset (PSB_2D_SRC_OFF_BH)
287 */
288#define PSB_2D_SRCOFF_XSTART_MASK ((0x00000FFF) << 12)
289#define PSB_2D_SRCOFF_XSTART_SHIFT (12)
290#define PSB_2D_SRCOFF_YSTART_MASK (0x00000FFF)
291#define PSB_2D_SRCOFF_YSTART_SHIFT (0)
292
293/*
294 * Mask Offset (PSB_2D_MASK_OFF_BH)
295 */
296#define PSB_2D_MASKOFF_XSTART_MASK ((0x00000FFF) << 12)
297#define PSB_2D_MASKOFF_XSTART_SHIFT (12)
298#define PSB_2D_MASKOFF_YSTART_MASK (0x00000FFF)
299#define PSB_2D_MASKOFF_YSTART_SHIFT (0)
300
301/*
302 * 2D Fence (see PSB_2D_FENCE_BH): bits 0:27 are ignored
303 */
304
305/*
306 *Blit Rectangle (PSB_2D_BLIT_BH)
307 */
308
309#define PSB_2D_ROT_MASK (3 << 25)
310#define PSB_2D_ROT_CLRMASK (~PSB_2D_ROT_MASK)
311#define PSB_2D_ROT_NONE (0 << 25)
312#define PSB_2D_ROT_90DEGS (1 << 25)
313#define PSB_2D_ROT_180DEGS (2 << 25)
314#define PSB_2D_ROT_270DEGS (3 << 25)
315
316#define PSB_2D_COPYORDER_MASK (3 << 23)
317#define PSB_2D_COPYORDER_CLRMASK (~PSB_2D_COPYORDER_MASK)
318#define PSB_2D_COPYORDER_TL2BR (0 << 23)
319#define PSB_2D_COPYORDER_BR2TL (1 << 23)
320#define PSB_2D_COPYORDER_TR2BL (2 << 23)
321#define PSB_2D_COPYORDER_BL2TR (3 << 23)
322
323#define PSB_2D_DSTCK_CLRMASK (0xFF9FFFFF)
324#define PSB_2D_DSTCK_DISABLE (0x00000000)
325#define PSB_2D_DSTCK_PASS (0x00200000)
326#define PSB_2D_DSTCK_REJECT (0x00400000)
327
328#define PSB_2D_SRCCK_CLRMASK (0xFFE7FFFF)
329#define PSB_2D_SRCCK_DISABLE (0x00000000)
330#define PSB_2D_SRCCK_PASS (0x00080000)
331#define PSB_2D_SRCCK_REJECT (0x00100000)
332
333#define PSB_2D_CLIP_ENABLE (0x00040000)
334
335#define PSB_2D_ALPHA_ENABLE (0x00020000)
336
337#define PSB_2D_PAT_CLRMASK (0xFFFEFFFF)
338#define PSB_2D_PAT_MASK (0x00010000)
339#define PSB_2D_USE_PAT (0x00010000)
340#define PSB_2D_USE_FILL (0x00000000)
341/*
342 * Tungsten Graphics note on rop codes: If rop A and rop B are
343 * identical, the mask surface will not be read and need not be
344 * set up.
345 */
346
347#define PSB_2D_ROP3B_MASK (0x0000FF00)
348#define PSB_2D_ROP3B_CLRMASK (0xFFFF00FF)
349#define PSB_2D_ROP3B_SHIFT (8)
350/* rop code A */
351#define PSB_2D_ROP3A_MASK (0x000000FF)
352#define PSB_2D_ROP3A_CLRMASK (0xFFFFFF00)
353#define PSB_2D_ROP3A_SHIFT (0)
354
355#define PSB_2D_ROP4_MASK (0x0000FFFF)
356/*
357 * DWORD0: (Only pass if Pattern control == Use Fill Colour)
358 * Fill Colour RGBA8888
359 */
360#define PSB_2D_FILLCOLOUR_MASK (0xFFFFFFFF)
361#define PSB_2D_FILLCOLOUR_SHIFT (0)
362/*
363 * DWORD1: (Always Present)
364 * X Start (Dest)
365 * Y Start (Dest)
366 */
367#define PSB_2D_DST_XSTART_MASK (0x00FFF000)
368#define PSB_2D_DST_XSTART_CLRMASK (0xFF000FFF)
369#define PSB_2D_DST_XSTART_SHIFT (12)
370#define PSB_2D_DST_YSTART_MASK (0x00000FFF)
371#define PSB_2D_DST_YSTART_CLRMASK (0xFFFFF000)
372#define PSB_2D_DST_YSTART_SHIFT (0)
373/*
374 * DWORD2: (Always Present)
375 * X Size (Dest)
376 * Y Size (Dest)
377 */
378#define PSB_2D_DST_XSIZE_MASK (0x00FFF000)
379#define PSB_2D_DST_XSIZE_CLRMASK (0xFF000FFF)
380#define PSB_2D_DST_XSIZE_SHIFT (12)
381#define PSB_2D_DST_YSIZE_MASK (0x00000FFF)
382#define PSB_2D_DST_YSIZE_CLRMASK (0xFFFFF000)
383#define PSB_2D_DST_YSIZE_SHIFT (0)
384
385/*
386 * Source Surface (PSB_2D_SRC_SURF_BH)
387 */
388/*
389 * WORD 0
390 */
391
392#define PSB_2D_SRC_FORMAT_MASK (0x00078000)
393#define PSB_2D_SRC_1_PAL (0x00000000)
394#define PSB_2D_SRC_2_PAL (0x00008000)
395#define PSB_2D_SRC_4_PAL (0x00010000)
396#define PSB_2D_SRC_8_PAL (0x00018000)
397#define PSB_2D_SRC_8_ALPHA (0x00020000)
398#define PSB_2D_SRC_4_ALPHA (0x00028000)
399#define PSB_2D_SRC_332RGB (0x00030000)
400#define PSB_2D_SRC_4444ARGB (0x00038000)
401#define PSB_2D_SRC_555RGB (0x00040000)
402#define PSB_2D_SRC_1555ARGB (0x00048000)
403#define PSB_2D_SRC_565RGB (0x00050000)
404#define PSB_2D_SRC_0888ARGB (0x00058000)
405#define PSB_2D_SRC_8888ARGB (0x00060000)
406#define PSB_2D_SRC_8888UYVY (0x00068000)
407#define PSB_2D_SRC_RESERVED (0x00070000)
408#define PSB_2D_SRC_1555ARGB_LOOKUP (0x00078000)
409
410
411#define PSB_2D_SRC_STRIDE_MASK (0x00007FFF)
412#define PSB_2D_SRC_STRIDE_CLRMASK (0xFFFF8000)
413#define PSB_2D_SRC_STRIDE_SHIFT (0)
414/*
415 * WORD 1 - Base Address
416 */
417#define PSB_2D_SRC_ADDR_MASK (0x0FFFFFFC)
418#define PSB_2D_SRC_ADDR_CLRMASK (0x00000003)
419#define PSB_2D_SRC_ADDR_SHIFT (2)
420#define PSB_2D_SRC_ADDR_ALIGNSHIFT (2)
421
422/*
423 * Pattern Surface (PSB_2D_PAT_SURF_BH)
424 */
425/*
426 * WORD 0
427 */
428
429#define PSB_2D_PAT_FORMAT_MASK (0x00078000)
430#define PSB_2D_PAT_1_PAL (0x00000000)
431#define PSB_2D_PAT_2_PAL (0x00008000)
432#define PSB_2D_PAT_4_PAL (0x00010000)
433#define PSB_2D_PAT_8_PAL (0x00018000)
434#define PSB_2D_PAT_8_ALPHA (0x00020000)
435#define PSB_2D_PAT_4_ALPHA (0x00028000)
436#define PSB_2D_PAT_332RGB (0x00030000)
437#define PSB_2D_PAT_4444ARGB (0x00038000)
438#define PSB_2D_PAT_555RGB (0x00040000)
439#define PSB_2D_PAT_1555ARGB (0x00048000)
440#define PSB_2D_PAT_565RGB (0x00050000)
441#define PSB_2D_PAT_0888ARGB (0x00058000)
442#define PSB_2D_PAT_8888ARGB (0x00060000)
443
444#define PSB_2D_PAT_STRIDE_MASK (0x00007FFF)
445#define PSB_2D_PAT_STRIDE_CLRMASK (0xFFFF8000)
446#define PSB_2D_PAT_STRIDE_SHIFT (0)
447/*
448 * WORD 1 - Base Address
449 */
450#define PSB_2D_PAT_ADDR_MASK (0x0FFFFFFC)
451#define PSB_2D_PAT_ADDR_CLRMASK (0x00000003)
452#define PSB_2D_PAT_ADDR_SHIFT (2)
453#define PSB_2D_PAT_ADDR_ALIGNSHIFT (2)
454
455/*
456 * Destination Surface (PSB_2D_DST_SURF_BH)
457 */
458/*
459 * WORD 0
460 */
461
462#define PSB_2D_DST_FORMAT_MASK (0x00078000)
463#define PSB_2D_DST_332RGB (0x00030000)
464#define PSB_2D_DST_4444ARGB (0x00038000)
465#define PSB_2D_DST_555RGB (0x00040000)
466#define PSB_2D_DST_1555ARGB (0x00048000)
467#define PSB_2D_DST_565RGB (0x00050000)
468#define PSB_2D_DST_0888ARGB (0x00058000)
469#define PSB_2D_DST_8888ARGB (0x00060000)
470#define PSB_2D_DST_8888AYUV (0x00070000)
471
472#define PSB_2D_DST_STRIDE_MASK (0x00007FFF)
473#define PSB_2D_DST_STRIDE_CLRMASK (0xFFFF8000)
474#define PSB_2D_DST_STRIDE_SHIFT (0)
475/*
476 * WORD 1 - Base Address
477 */
478#define PSB_2D_DST_ADDR_MASK (0x0FFFFFFC)
479#define PSB_2D_DST_ADDR_CLRMASK (0x00000003)
480#define PSB_2D_DST_ADDR_SHIFT (2)
481#define PSB_2D_DST_ADDR_ALIGNSHIFT (2)
482
483/*
484 * Mask Surface (PSB_2D_MASK_SURF_BH)
485 */
486/*
487 * WORD 0
488 */
489#define PSB_2D_MASK_STRIDE_MASK (0x00007FFF)
490#define PSB_2D_MASK_STRIDE_CLRMASK (0xFFFF8000)
491#define PSB_2D_MASK_STRIDE_SHIFT (0)
492/*
493 * WORD 1 - Base Address
494 */
495#define PSB_2D_MASK_ADDR_MASK (0x0FFFFFFC)
496#define PSB_2D_MASK_ADDR_CLRMASK (0x00000003)
497#define PSB_2D_MASK_ADDR_SHIFT (2)
498#define PSB_2D_MASK_ADDR_ALIGNSHIFT (2)
499
500/*
501 * Source Palette (PSB_2D_SRC_PAL_BH)
502 */
503
504#define PSB_2D_SRCPAL_ADDR_SHIFT (0)
505#define PSB_2D_SRCPAL_ADDR_CLRMASK (0xF0000007)
506#define PSB_2D_SRCPAL_ADDR_MASK (0x0FFFFFF8)
507#define PSB_2D_SRCPAL_BYTEALIGN (1024)
508
509/*
510 * Pattern Palette (PSB_2D_PAT_PAL_BH)
511 */
512
513#define PSB_2D_PATPAL_ADDR_SHIFT (0)
514#define PSB_2D_PATPAL_ADDR_CLRMASK (0xF0000007)
515#define PSB_2D_PATPAL_ADDR_MASK (0x0FFFFFF8)
516#define PSB_2D_PATPAL_BYTEALIGN (1024)
517
518/*
519 * Rop3 Codes (2 LS bytes)
520 */
521
522#define PSB_2D_ROP3_SRCCOPY (0xCCCC)
523#define PSB_2D_ROP3_PATCOPY (0xF0F0)
524#define PSB_2D_ROP3_WHITENESS (0xFFFF)
525#define PSB_2D_ROP3_BLACKNESS (0x0000)
526#define PSB_2D_ROP3_SRC (0xCC)
527#define PSB_2D_ROP3_PAT (0xF0)
528#define PSB_2D_ROP3_DST (0xAA)
529
530/*
531 * Sizes.
532 */
533
534#define PSB_SCENE_HW_COOKIE_SIZE 16
535#define PSB_TA_MEM_HW_COOKIE_SIZE 16
536
537/*
538 * Scene stuff.
539 */
540
541#define PSB_NUM_HW_SCENES 2
542
543/*
544 * Scheduler completion actions.
545 */
546
547#define PSB_RASTER_BLOCK 0
548#define PSB_RASTER 1
549#define PSB_RETURN 2
550#define PSB_TA 3
551
552/* Power management */
553#define PSB_PUNIT_PORT 0x04
554#define PSB_OSPMBA 0x78
555#define PSB_APMBA 0x7a
556#define PSB_APM_CMD 0x0
557#define PSB_APM_STS 0x04
558#define PSB_PWRGT_VID_ENC_MASK 0x30
559#define PSB_PWRGT_VID_DEC_MASK 0xc
560#define PSB_PWRGT_GL3_MASK 0xc0
561
562#define PSB_PM_SSC 0x20
563#define PSB_PM_SSS 0x30
564#define PSB_PWRGT_DISPLAY_MASK 0xc /*on a different BA than video/gfx*/
565#define MDFLD_PWRGT_DISPLAY_A_CNTR 0x0000000c
566#define MDFLD_PWRGT_DISPLAY_B_CNTR 0x0000c000
567#define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000
568#define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000
569#define MDFLD_PWRGT_DISPLAY_CNTR (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR) /* 0x000fc00c */
570/* Display SSS register bits are different in A0 vs. B0 */
571#define PSB_PWRGT_GFX_MASK 0x3
572#define MDFLD_PWRGT_DISPLAY_A_STS 0x000000c0
573#define MDFLD_PWRGT_DISPLAY_B_STS 0x00000300
574#define MDFLD_PWRGT_DISPLAY_C_STS 0x00000c00
575#define PSB_PWRGT_GFX_MASK_B0 0xc3
576#define MDFLD_PWRGT_DISPLAY_A_STS_B0 0x0000000c
577#define MDFLD_PWRGT_DISPLAY_B_STS_B0 0x0000c000
578#define MDFLD_PWRGT_DISPLAY_C_STS_B0 0x00030000
579#define MDFLD_PWRGT_DISP_MIPI_STS 0x000c0000
580#define MDFLD_PWRGT_DISPLAY_STS_A0 (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */
581#define MDFLD_PWRGT_DISPLAY_STS_B0 (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */
582#endif