blob: 000d316c6afdb2dbe654b5665542fc4208c7e933 [file] [log] [blame]
Kirill A. Shutemov026abc32012-03-08 16:02:20 +00001/**************************************************************************
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 "psb_drv.h"
21#include "mid_bios.h"
22#include "mdfld_output.h"
23#include "mdfld_dsi_output.h"
24#include "tc35876x-dsi-lvds.h"
25
26#include <asm/intel_scu_ipc.h>
27
28#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
29
30#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF
31#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
32#define BLC_PWM_FREQ_CALC_CONSTANT 32
33#define MHz 1000000
34#define BRIGHTNESS_MIN_LEVEL 1
35#define BRIGHTNESS_MAX_LEVEL 100
36#define BRIGHTNESS_MASK 0xFF
37#define BLC_POLARITY_NORMAL 0
38#define BLC_POLARITY_INVERSE 1
39#define BLC_ADJUSTMENT_MAX 100
40
41#define MDFLD_BLC_PWM_PRECISION_FACTOR 10
42#define MDFLD_BLC_MAX_PWM_REG_FREQ 0xFFFE
43#define MDFLD_BLC_MIN_PWM_REG_FREQ 0x2
44
45#define MDFLD_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
46#define MDFLD_BACKLIGHT_PWM_CTL_SHIFT (16)
47
48static struct backlight_device *mdfld_backlight_device;
49
50int mdfld_set_brightness(struct backlight_device *bd)
51{
52 struct drm_device *dev =
53 (struct drm_device *)bl_get_data(mdfld_backlight_device);
54 struct drm_psb_private *dev_priv = dev->dev_private;
55 int level = bd->props.brightness;
56
57 DRM_DEBUG_DRIVER("backlight level set to %d\n", level);
58
59 /* Perform value bounds checking */
60 if (level < BRIGHTNESS_MIN_LEVEL)
61 level = BRIGHTNESS_MIN_LEVEL;
62
63 if (gma_power_begin(dev, false)) {
64 u32 adjusted_level = 0;
65
66 /*
67 * Adjust the backlight level with the percent in
68 * dev_priv->blc_adj2
69 */
70 adjusted_level = level * dev_priv->blc_adj2;
71 adjusted_level = adjusted_level / BLC_ADJUSTMENT_MAX;
72 dev_priv->brightness_adjusted = adjusted_level;
73
74 if (mdfld_get_panel_type(dev, 0) == TC35876X) {
75 if (dev_priv->dpi_panel_on[0] ||
76 dev_priv->dpi_panel_on[2])
77 tc35876x_brightness_control(dev,
78 dev_priv->brightness_adjusted);
79 } else {
80 if (dev_priv->dpi_panel_on[0])
81 mdfld_dsi_brightness_control(dev, 0,
82 dev_priv->brightness_adjusted);
83 }
84
85 if (dev_priv->dpi_panel_on[2])
86 mdfld_dsi_brightness_control(dev, 2,
87 dev_priv->brightness_adjusted);
88 gma_power_end(dev);
89 }
90
91 /* cache the brightness for later use */
92 dev_priv->brightness = level;
93 return 0;
94}
95
Kirill A. Shutemov1c6a6262012-03-08 16:11:14 +000096static int mdfld_get_brightness(struct backlight_device *bd)
Kirill A. Shutemov026abc32012-03-08 16:02:20 +000097{
98 struct drm_device *dev =
99 (struct drm_device *)bl_get_data(mdfld_backlight_device);
100 struct drm_psb_private *dev_priv = dev->dev_private;
101
102 DRM_DEBUG_DRIVER("brightness = 0x%x \n", dev_priv->brightness);
103
104 /* return locally cached var instead of HW read (due to DPST etc.) */
105 return dev_priv->brightness;
106}
107
108static const struct backlight_ops mdfld_ops = {
109 .get_brightness = mdfld_get_brightness,
110 .update_status = mdfld_set_brightness,
111};
112
113static int device_backlight_init(struct drm_device *dev)
114{
115 struct drm_psb_private *dev_priv = (struct drm_psb_private *)
116 dev->dev_private;
117
118 dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
119 dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
120
121 return 0;
122}
123
Kirill A. Shutemov1c6a6262012-03-08 16:11:14 +0000124static int mdfld_backlight_init(struct drm_device *dev)
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000125{
126 struct backlight_properties props;
127 int ret = 0;
128
129 memset(&props, 0, sizeof(struct backlight_properties));
130 props.max_brightness = BRIGHTNESS_MAX_LEVEL;
131 props.type = BACKLIGHT_PLATFORM;
132 mdfld_backlight_device = backlight_device_register("mdfld-bl",
133 NULL, (void *)dev, &mdfld_ops, &props);
134
135 if (IS_ERR(mdfld_backlight_device))
136 return PTR_ERR(mdfld_backlight_device);
137
138 ret = device_backlight_init(dev);
139 if (ret)
140 return ret;
141
142 mdfld_backlight_device->props.brightness = BRIGHTNESS_MAX_LEVEL;
143 mdfld_backlight_device->props.max_brightness = BRIGHTNESS_MAX_LEVEL;
144 backlight_update_status(mdfld_backlight_device);
145 return 0;
146}
147#endif
148
149struct backlight_device *mdfld_get_backlight_device(void)
150{
151#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
152 return mdfld_backlight_device;
153#else
154 return NULL;
155#endif
156}
157
158/*
159 * mdfld_save_display_registers
160 *
161 * Description: We are going to suspend so save current display
162 * register state.
163 *
164 * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio
165 */
Alan Cox62563042012-05-11 11:30:16 +0100166static int mdfld_save_display_registers(struct drm_device *dev, int pipenum)
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000167{
168 struct drm_psb_private *dev_priv = dev->dev_private;
169 struct medfield_state *regs = &dev_priv->regs.mdfld;
Alan Cox62563042012-05-11 11:30:16 +0100170 struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum];
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000171 int i;
Alan Coxf693dfb2012-05-11 11:30:33 +0100172 u32 *mipi_val;
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000173
174 /* register */
175 u32 dpll_reg = MRST_DPLL_A;
176 u32 fp_reg = MRST_FPA0;
177 u32 pipeconf_reg = PIPEACONF;
178 u32 htot_reg = HTOTAL_A;
179 u32 hblank_reg = HBLANK_A;
180 u32 hsync_reg = HSYNC_A;
181 u32 vtot_reg = VTOTAL_A;
182 u32 vblank_reg = VBLANK_A;
183 u32 vsync_reg = VSYNC_A;
184 u32 pipesrc_reg = PIPEASRC;
185 u32 dspstride_reg = DSPASTRIDE;
186 u32 dsplinoff_reg = DSPALINOFF;
187 u32 dsptileoff_reg = DSPATILEOFF;
188 u32 dspsize_reg = DSPASIZE;
189 u32 dsppos_reg = DSPAPOS;
190 u32 dspsurf_reg = DSPASURF;
191 u32 mipi_reg = MIPI;
192 u32 dspcntr_reg = DSPACNTR;
193 u32 dspstatus_reg = PIPEASTAT;
194 u32 palette_reg = PALETTE_A;
195
Alan Cox62563042012-05-11 11:30:16 +0100196 switch (pipenum) {
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000197 case 0:
Alan Coxf693dfb2012-05-11 11:30:33 +0100198 mipi_val = &regs->saveMIPI;
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000199 break;
200 case 1:
Alan Coxf693dfb2012-05-11 11:30:33 +0100201 mipi_val = &regs->saveMIPI;
202 /* register */
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000203 dpll_reg = MDFLD_DPLL_B;
204 fp_reg = MDFLD_DPLL_DIV0;
205 pipeconf_reg = PIPEBCONF;
206 htot_reg = HTOTAL_B;
207 hblank_reg = HBLANK_B;
208 hsync_reg = HSYNC_B;
209 vtot_reg = VTOTAL_B;
210 vblank_reg = VBLANK_B;
211 vsync_reg = VSYNC_B;
212 pipesrc_reg = PIPEBSRC;
213 dspstride_reg = DSPBSTRIDE;
214 dsplinoff_reg = DSPBLINOFF;
215 dsptileoff_reg = DSPBTILEOFF;
216 dspsize_reg = DSPBSIZE;
217 dsppos_reg = DSPBPOS;
218 dspsurf_reg = DSPBSURF;
219 dspcntr_reg = DSPBCNTR;
220 dspstatus_reg = PIPEBSTAT;
221 palette_reg = PALETTE_B;
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000222 break;
223 case 2:
224 /* register */
225 pipeconf_reg = PIPECCONF;
226 htot_reg = HTOTAL_C;
227 hblank_reg = HBLANK_C;
228 hsync_reg = HSYNC_C;
229 vtot_reg = VTOTAL_C;
230 vblank_reg = VBLANK_C;
231 vsync_reg = VSYNC_C;
232 pipesrc_reg = PIPECSRC;
233 dspstride_reg = DSPCSTRIDE;
234 dsplinoff_reg = DSPCLINOFF;
235 dsptileoff_reg = DSPCTILEOFF;
236 dspsize_reg = DSPCSIZE;
237 dsppos_reg = DSPCPOS;
238 dspsurf_reg = DSPCSURF;
239 mipi_reg = MIPI_C;
240 dspcntr_reg = DSPCCNTR;
241 dspstatus_reg = PIPECSTAT;
242 palette_reg = PALETTE_C;
243
244 /* pointer to values */
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000245 mipi_val = &regs->saveMIPI_C;
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000246 break;
247 default:
248 DRM_ERROR("%s, invalid pipe number.\n", __func__);
249 return -EINVAL;
250 }
251
252 /* Pipe & plane A info */
Alan Coxf693dfb2012-05-11 11:30:33 +0100253 pipe->dpll = PSB_RVDC32(dpll_reg);
254 pipe->fp0 = PSB_RVDC32(fp_reg);
255 pipe->conf = PSB_RVDC32(pipeconf_reg);
256 pipe->htotal = PSB_RVDC32(htot_reg);
257 pipe->hblank = PSB_RVDC32(hblank_reg);
258 pipe->hsync = PSB_RVDC32(hsync_reg);
259 pipe->vtotal = PSB_RVDC32(vtot_reg);
260 pipe->vblank = PSB_RVDC32(vblank_reg);
261 pipe->vsync = PSB_RVDC32(vsync_reg);
262 pipe->src = PSB_RVDC32(pipesrc_reg);
263 pipe->stride = PSB_RVDC32(dspstride_reg);
264 pipe->linoff = PSB_RVDC32(dsplinoff_reg);
265 pipe->tileoff = PSB_RVDC32(dsptileoff_reg);
266 pipe->size = PSB_RVDC32(dspsize_reg);
267 pipe->pos = PSB_RVDC32(dsppos_reg);
268 pipe->surf = PSB_RVDC32(dspsurf_reg);
269 pipe->cntr = PSB_RVDC32(dspcntr_reg);
270 pipe->status = PSB_RVDC32(dspstatus_reg);
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000271
272 /*save palette (gamma) */
273 for (i = 0; i < 256; i++)
Alan Coxf693dfb2012-05-11 11:30:33 +0100274 pipe->palette[i] = PSB_RVDC32(palette_reg + (i << 2));
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000275
Alan Cox62563042012-05-11 11:30:16 +0100276 if (pipenum == 1) {
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000277 regs->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
278 regs->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
279
280 regs->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL);
281 regs->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL);
282 return 0;
283 }
284
285 *mipi_val = PSB_RVDC32(mipi_reg);
286 return 0;
287}
288
289/*
290 * mdfld_restore_display_registers
291 *
292 * Description: We are going to resume so restore display register state.
293 *
294 * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio
295 */
Alan Cox62563042012-05-11 11:30:16 +0100296static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum)
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000297{
298 /* To get panel out of ULPS mode. */
299 u32 temp = 0;
300 u32 device_ready_reg = DEVICE_READY_REG;
301 struct drm_psb_private *dev_priv = dev->dev_private;
302 struct mdfld_dsi_config *dsi_config = NULL;
303 struct medfield_state *regs = &dev_priv->regs.mdfld;
Alan Cox62563042012-05-11 11:30:16 +0100304 struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum];
Alan Coxf693dfb2012-05-11 11:30:33 +0100305 u32 i;
306 u32 dpll;
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000307 u32 timeout = 0;
308
Alan Cox62563042012-05-11 11:30:16 +0100309 /* register */
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000310 u32 dpll_reg = MRST_DPLL_A;
311 u32 fp_reg = MRST_FPA0;
312 u32 pipeconf_reg = PIPEACONF;
313 u32 htot_reg = HTOTAL_A;
314 u32 hblank_reg = HBLANK_A;
315 u32 hsync_reg = HSYNC_A;
316 u32 vtot_reg = VTOTAL_A;
317 u32 vblank_reg = VBLANK_A;
318 u32 vsync_reg = VSYNC_A;
319 u32 pipesrc_reg = PIPEASRC;
320 u32 dspstride_reg = DSPASTRIDE;
321 u32 dsplinoff_reg = DSPALINOFF;
322 u32 dsptileoff_reg = DSPATILEOFF;
323 u32 dspsize_reg = DSPASIZE;
324 u32 dsppos_reg = DSPAPOS;
325 u32 dspsurf_reg = DSPASURF;
326 u32 dspstatus_reg = PIPEASTAT;
327 u32 mipi_reg = MIPI;
328 u32 dspcntr_reg = DSPACNTR;
329 u32 palette_reg = PALETTE_A;
330
331 /* values */
Alan Cox62563042012-05-11 11:30:16 +0100332 u32 dpll_val = pipe->dpll;
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000333 u32 mipi_val = regs->saveMIPI;
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000334
Alan Cox62563042012-05-11 11:30:16 +0100335 switch (pipenum) {
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000336 case 0:
Alan Cox62563042012-05-11 11:30:16 +0100337 dpll_val &= ~DPLL_VCO_ENABLE;
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000338 dsi_config = dev_priv->dsi_configs[0];
339 break;
340 case 1:
Alan Cox62563042012-05-11 11:30:16 +0100341 /* register */
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000342 dpll_reg = MDFLD_DPLL_B;
343 fp_reg = MDFLD_DPLL_DIV0;
344 pipeconf_reg = PIPEBCONF;
345 htot_reg = HTOTAL_B;
346 hblank_reg = HBLANK_B;
347 hsync_reg = HSYNC_B;
348 vtot_reg = VTOTAL_B;
349 vblank_reg = VBLANK_B;
350 vsync_reg = VSYNC_B;
351 pipesrc_reg = PIPEBSRC;
352 dspstride_reg = DSPBSTRIDE;
353 dsplinoff_reg = DSPBLINOFF;
354 dsptileoff_reg = DSPBTILEOFF;
355 dspsize_reg = DSPBSIZE;
356 dsppos_reg = DSPBPOS;
357 dspsurf_reg = DSPBSURF;
358 dspcntr_reg = DSPBCNTR;
359 dspstatus_reg = PIPEBSTAT;
360 palette_reg = PALETTE_B;
361
362 /* values */
Alan Cox62563042012-05-11 11:30:16 +0100363 dpll_val &= ~DPLL_VCO_ENABLE;
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000364 break;
365 case 2:
Alan Cox62563042012-05-11 11:30:16 +0100366 /* register */
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000367 pipeconf_reg = PIPECCONF;
368 htot_reg = HTOTAL_C;
369 hblank_reg = HBLANK_C;
370 hsync_reg = HSYNC_C;
371 vtot_reg = VTOTAL_C;
372 vblank_reg = VBLANK_C;
373 vsync_reg = VSYNC_C;
374 pipesrc_reg = PIPECSRC;
375 dspstride_reg = DSPCSTRIDE;
376 dsplinoff_reg = DSPCLINOFF;
377 dsptileoff_reg = DSPCTILEOFF;
378 dspsize_reg = DSPCSIZE;
379 dsppos_reg = DSPCPOS;
380 dspsurf_reg = DSPCSURF;
381 mipi_reg = MIPI_C;
382 dspcntr_reg = DSPCCNTR;
383 dspstatus_reg = PIPECSTAT;
384 palette_reg = PALETTE_C;
385
386 /* values */
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000387 mipi_val = regs->saveMIPI_C;
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000388 dsi_config = dev_priv->dsi_configs[1];
389 break;
390 default:
391 DRM_ERROR("%s, invalid pipe number.\n", __func__);
392 return -EINVAL;
393 }
394
395 /*make sure VGA plane is off. it initializes to on after reset!*/
396 PSB_WVDC32(0x80000000, VGACNTRL);
397
Alan Cox62563042012-05-11 11:30:16 +0100398 if (pipenum == 1) {
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000399 PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg);
400 PSB_RVDC32(dpll_reg);
401
Alan Coxf693dfb2012-05-11 11:30:33 +0100402 PSB_WVDC32(pipe->fp0, fp_reg);
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000403 } else {
404
405 dpll = PSB_RVDC32(dpll_reg);
406
407 if (!(dpll & DPLL_VCO_ENABLE)) {
408
409 /* When ungating power of DPLL, needs to wait 0.5us
410 before enable the VCO */
411 if (dpll & MDFLD_PWR_GATE_EN) {
412 dpll &= ~MDFLD_PWR_GATE_EN;
413 PSB_WVDC32(dpll, dpll_reg);
414 /* FIXME_MDFLD PO - change 500 to 1 after PO */
415 udelay(500);
416 }
417
Alan Coxf693dfb2012-05-11 11:30:33 +0100418 PSB_WVDC32(pipe->fp0, fp_reg);
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000419 PSB_WVDC32(dpll_val, dpll_reg);
420 /* FIXME_MDFLD PO - change 500 to 1 after PO */
421 udelay(500);
422
423 dpll_val |= DPLL_VCO_ENABLE;
424 PSB_WVDC32(dpll_val, dpll_reg);
425 PSB_RVDC32(dpll_reg);
426
427 /* wait for DSI PLL to lock */
428 while (timeout < 20000 &&
429 !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
430 udelay(150);
431 timeout++;
432 }
433
434 if (timeout == 20000) {
435 DRM_ERROR("%s, can't lock DSIPLL.\n",
436 __func__);
437 return -EINVAL;
438 }
439 }
440 }
441 /* Restore mode */
Alan Coxf693dfb2012-05-11 11:30:33 +0100442 PSB_WVDC32(pipe->htotal, htot_reg);
443 PSB_WVDC32(pipe->hblank, hblank_reg);
444 PSB_WVDC32(pipe->hsync, hsync_reg);
445 PSB_WVDC32(pipe->vtotal, vtot_reg);
446 PSB_WVDC32(pipe->vblank, vblank_reg);
447 PSB_WVDC32(pipe->vsync, vsync_reg);
448 PSB_WVDC32(pipe->src, pipesrc_reg);
449 PSB_WVDC32(pipe->status, dspstatus_reg);
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000450
451 /*set up the plane*/
Alan Coxf693dfb2012-05-11 11:30:33 +0100452 PSB_WVDC32(pipe->stride, dspstride_reg);
453 PSB_WVDC32(pipe->linoff, dsplinoff_reg);
454 PSB_WVDC32(pipe->tileoff, dsptileoff_reg);
455 PSB_WVDC32(pipe->size, dspsize_reg);
456 PSB_WVDC32(pipe->pos, dsppos_reg);
457 PSB_WVDC32(pipe->surf, dspsurf_reg);
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000458
Alan Cox62563042012-05-11 11:30:16 +0100459 if (pipenum == 1) {
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000460 /* restore palette (gamma) */
461 /*DRM_UDELAY(50000); */
462 for (i = 0; i < 256; i++)
Alan Coxf693dfb2012-05-11 11:30:33 +0100463 PSB_WVDC32(pipe->palette[i], palette_reg + (i << 2));
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000464
465 PSB_WVDC32(regs->savePFIT_CONTROL, PFIT_CONTROL);
466 PSB_WVDC32(regs->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
467
468 /*TODO: resume HDMI port */
469
470 /*TODO: resume pipe*/
471
472 /*enable the plane*/
Alan Coxf693dfb2012-05-11 11:30:33 +0100473 PSB_WVDC32(pipe->cntr & ~DISPLAY_PLANE_ENABLE, dspcntr_reg);
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000474
475 return 0;
476 }
477
478 /*set up pipe related registers*/
479 PSB_WVDC32(mipi_val, mipi_reg);
480
481 /*setup MIPI adapter + MIPI IP registers*/
482 if (dsi_config)
Alan Cox62563042012-05-11 11:30:16 +0100483 mdfld_dsi_controller_init(dsi_config, pipenum);
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000484
485 if (in_atomic() || in_interrupt())
486 mdelay(20);
487 else
488 msleep(20);
489
490 /*enable the plane*/
Alan Coxf693dfb2012-05-11 11:30:33 +0100491 PSB_WVDC32(pipe->cntr, dspcntr_reg);
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000492
493 if (in_atomic() || in_interrupt())
494 mdelay(20);
495 else
496 msleep(20);
497
498 /* LP Hold Release */
499 temp = REG_READ(mipi_reg);
500 temp |= LP_OUTPUT_HOLD_RELEASE;
501 REG_WRITE(mipi_reg, temp);
502 mdelay(1);
503
504
505 /* Set DSI host to exit from Utra Low Power State */
506 temp = REG_READ(device_ready_reg);
507 temp &= ~ULPS_MASK;
508 temp |= 0x3;
509 temp |= EXIT_ULPS_DEV_READY;
510 REG_WRITE(device_ready_reg, temp);
511 mdelay(1);
512
513 temp = REG_READ(device_ready_reg);
514 temp &= ~ULPS_MASK;
515 temp |= EXITING_ULPS;
516 REG_WRITE(device_ready_reg, temp);
517 mdelay(1);
518
519 /*enable the pipe*/
Alan Coxf693dfb2012-05-11 11:30:33 +0100520 PSB_WVDC32(pipe->conf, pipeconf_reg);
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000521
522 /* restore palette (gamma) */
523 /*DRM_UDELAY(50000); */
524 for (i = 0; i < 256; i++)
Alan Coxf693dfb2012-05-11 11:30:33 +0100525 PSB_WVDC32(pipe->palette[i], palette_reg + (i << 2));
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000526
527 return 0;
528}
529
530static int mdfld_save_registers(struct drm_device *dev)
531{
532 /* mdfld_save_cursor_overlay_registers(dev); */
533 mdfld_save_display_registers(dev, 0);
534 mdfld_save_display_registers(dev, 2);
535 mdfld_disable_crtc(dev, 0);
536 mdfld_disable_crtc(dev, 2);
537
538 return 0;
539}
540
541static int mdfld_restore_registers(struct drm_device *dev)
542{
543 mdfld_restore_display_registers(dev, 2);
544 mdfld_restore_display_registers(dev, 0);
545 /* mdfld_restore_cursor_overlay_registers(dev); */
546
547 return 0;
548}
549
550static int mdfld_power_down(struct drm_device *dev)
551{
552 /* FIXME */
553 return 0;
554}
555
556static int mdfld_power_up(struct drm_device *dev)
557{
558 /* FIXME */
559 return 0;
560}
561
Alan Cox8512e072012-05-11 11:30:53 +0100562/* Medfield */
563static const struct psb_offset mdfld_regmap[3] = {
564 {
565 .fp0 = MRST_FPA0,
566 .fp1 = MRST_FPA1,
567 .cntr = DSPACNTR,
568 .conf = PIPEACONF,
569 .src = PIPEASRC,
570 .dpll = MRST_DPLL_A,
571 .htotal = HTOTAL_A,
572 .hblank = HBLANK_A,
573 .hsync = HSYNC_A,
574 .vtotal = VTOTAL_A,
575 .vblank = VBLANK_A,
576 .vsync = VSYNC_A,
577 .stride = DSPASTRIDE,
578 .size = DSPASIZE,
579 .pos = DSPAPOS,
580 .surf = DSPASURF,
581 .addr = DSPABASE,
582 .status = PIPEASTAT,
583 .linoff = DSPALINOFF,
584 .tileoff = DSPATILEOFF,
585 .palette = PALETTE_A,
586 },
587 {
588 .fp0 = MDFLD_DPLL_DIV0,
589 .cntr = DSPBCNTR,
590 .conf = PIPEBCONF,
591 .src = PIPEBSRC,
592 .dpll = MDFLD_DPLL_B,
593 .htotal = HTOTAL_B,
594 .hblank = HBLANK_B,
595 .hsync = HSYNC_B,
596 .vtotal = VTOTAL_B,
597 .vblank = VBLANK_B,
598 .vsync = VSYNC_B,
599 .stride = DSPBSTRIDE,
600 .size = DSPBSIZE,
601 .pos = DSPBPOS,
602 .surf = DSPBSURF,
603 .addr = DSPBBASE,
604 .status = PIPEBSTAT,
605 .linoff = DSPBLINOFF,
606 .tileoff = DSPBTILEOFF,
607 .palette = PALETTE_B,
608 },
609 {
610 .cntr = DSPCCNTR,
611 .conf = PIPECCONF,
612 .src = PIPECSRC,
613 /* No DPLL_C */
614 .dpll = MRST_DPLL_A,
615 .htotal = HTOTAL_C,
616 .hblank = HBLANK_C,
617 .hsync = HSYNC_C,
618 .vtotal = VTOTAL_C,
619 .vblank = VBLANK_C,
620 .vsync = VSYNC_C,
621 .stride = DSPCSTRIDE,
622 .size = DSPBSIZE,
623 .pos = DSPCPOS,
624 .surf = DSPCSURF,
625 .addr = DSPCBASE,
626 .status = PIPECSTAT,
627 .linoff = DSPCLINOFF,
628 .tileoff = DSPCTILEOFF,
629 .palette = PALETTE_C,
630 },
631};
632
633static int mdfld_chip_setup(struct drm_device *dev)
634{
635 struct drm_psb_private *dev_priv = dev->dev_private;
636 dev_priv->regmap = mdfld_regmap;
637 return mid_chip_setup(dev);
638}
639
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000640const struct psb_ops mdfld_chip_ops = {
641 .name = "mdfld",
642 .accel_2d = 0,
643 .pipes = 3,
644 .crtcs = 3,
Patrik Jakobsson87438492012-04-28 23:20:42 +0200645 .lvds_mask = (1 << 1),
646 .hdmi_mask = (1 << 1),
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000647 .sgx_offset = MRST_SGX_OFFSET,
648
Alan Cox8512e072012-05-11 11:30:53 +0100649 .chip_setup = mdfld_chip_setup,
Kirill A. Shutemov026abc32012-03-08 16:02:20 +0000650 .crtc_helper = &mdfld_helper_funcs,
651 .crtc_funcs = &psb_intel_crtc_funcs,
652
653 .output_init = mdfld_output_init,
654
655#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
656 .backlight_init = mdfld_backlight_init,
657#endif
658
659 .save_regs = mdfld_save_registers,
660 .restore_regs = mdfld_restore_registers,
661 .power_down = mdfld_power_down,
662 .power_up = mdfld_power_up,
663};