gma500: remove an un-needed check
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / gma500 / mdfld_device.c
blobe66d04a71191854c235e5280ac54c000aacb40ce
1 /**************************************************************************
2 * Copyright (c) 2011, Intel Corporation.
3 * All Rights Reserved.
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.
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.
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.
18 **************************************************************************/
20 #include <linux/backlight.h>
21 #include <drm/drmP.h>
22 #include <drm/drm.h>
23 #include "psb_reg.h"
24 #include "psb_intel_reg.h"
25 #include "psb_drm.h"
26 #include "psb_drv.h"
27 #include "mdfld_output.h"
28 #include "mdfld_dsi_output.h"
31 * Provide the Medfield specific backlight management
34 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
36 static int mdfld_brightness;
37 struct backlight_device *mdfld_backlight_device;
39 static int mfld_set_brightness(struct backlight_device *bd)
41 struct drm_device *dev = bl_get_data(mdfld_backlight_device);
42 struct drm_psb_private *dev_priv = dev->dev_private;
43 int level = bd->props.brightness;
45 /* Percentage 1-100% being valid */
46 if (level < 1)
47 level = 1;
49 if (gma_power_begin(dev, 0)) {
50 /* Calculate and set the brightness value */
51 u32 adjusted_level;
53 /* Adjust the backlight level with the percent in
54 * dev_priv->blc_adj2;
56 adjusted_level = level * dev_priv->blc_adj2;
57 adjusted_level = adjusted_level / 100;
58 #if 0
59 #ifndef CONFIG_MDFLD_DSI_DPU
60 if(!(dev_priv->dsr_fb_update & MDFLD_DSR_MIPI_CONTROL) &&
61 (dev_priv->dbi_panel_on || dev_priv->dbi_panel_on2)){
62 mdfld_dsi_dbi_exit_dsr(dev,MDFLD_DSR_MIPI_CONTROL, 0, 0);
63 dev_dbg(dev->dev, "Out of DSR before set brightness to %d.\n",adjusted_level);
65 #endif
66 mdfld_dsi_brightness_control(dev, 0, adjusted_level);
68 if ((dev_priv->dbi_panel_on2) || (dev_priv->dpi_panel_on2))
69 mdfld_dsi_brightness_control(dev, 2, adjusted_level);
70 #endif
71 gma_power_end(dev);
73 mdfld_brightness = level;
74 return 0;
77 int psb_get_brightness(struct backlight_device *bd)
79 /* return locally cached var instead of HW read (due to DPST etc.) */
80 /* FIXME: ideally return actual value in case firmware fiddled with
81 it */
82 return mdfld_brightness;
85 static const struct backlight_ops mfld_ops = {
86 .get_brightness = psb_get_brightness,
87 .update_status = mfld_set_brightness,
90 static int mdfld_backlight_init(struct drm_device *dev)
92 struct drm_psb_private *dev_priv = dev->dev_private;
93 struct backlight_properties props;
94 memset(&props, 0, sizeof(struct backlight_properties));
95 props.max_brightness = 100;
96 props.type = BACKLIGHT_PLATFORM;
98 mdfld_backlight_device = backlight_device_register("mfld-bl",
99 NULL, (void *)dev, &mfld_ops, &props);
101 if (IS_ERR(mdfld_backlight_device))
102 return PTR_ERR(mdfld_backlight_device);
104 dev_priv->blc_adj1 = 100;
105 dev_priv->blc_adj2 = 100;
106 mdfld_backlight_device->props.brightness = 100;
107 mdfld_backlight_device->props.max_brightness = 100;
108 backlight_update_status(mdfld_backlight_device);
109 dev_priv->backlight_device = mdfld_backlight_device;
110 return 0;
113 #endif
116 * Provide the Medfield specific chip logic and low level methods for
117 * power management.
120 static void mdfld_init_pm(struct drm_device *dev)
122 /* No work needed here yet */
126 * mdfld_save_display_registers - save registers for pipe
127 * @dev: our device
128 * @pipe: pipe to save
130 * Save the pipe state of the device before we power it off. Keep everything
131 * we need to put it back again
133 static int mdfld_save_display_registers(struct drm_device *dev, int pipe)
135 struct drm_psb_private *dev_priv = dev->dev_private;
136 int i;
138 /* register */
139 u32 dpll_reg = MRST_DPLL_A;
140 u32 fp_reg = MRST_FPA0;
141 u32 pipeconf_reg = PIPEACONF;
142 u32 htot_reg = HTOTAL_A;
143 u32 hblank_reg = HBLANK_A;
144 u32 hsync_reg = HSYNC_A;
145 u32 vtot_reg = VTOTAL_A;
146 u32 vblank_reg = VBLANK_A;
147 u32 vsync_reg = VSYNC_A;
148 u32 pipesrc_reg = PIPEASRC;
149 u32 dspstride_reg = DSPASTRIDE;
150 u32 dsplinoff_reg = DSPALINOFF;
151 u32 dsptileoff_reg = DSPATILEOFF;
152 u32 dspsize_reg = DSPASIZE;
153 u32 dsppos_reg = DSPAPOS;
154 u32 dspsurf_reg = DSPASURF;
155 u32 mipi_reg = MIPI;
156 u32 dspcntr_reg = DSPACNTR;
157 u32 dspstatus_reg = PIPEASTAT;
158 u32 palette_reg = PALETTE_A;
160 /* pointer to values */
161 u32 *dpll_val = &dev_priv->saveDPLL_A;
162 u32 *fp_val = &dev_priv->saveFPA0;
163 u32 *pipeconf_val = &dev_priv->savePIPEACONF;
164 u32 *htot_val = &dev_priv->saveHTOTAL_A;
165 u32 *hblank_val = &dev_priv->saveHBLANK_A;
166 u32 *hsync_val = &dev_priv->saveHSYNC_A;
167 u32 *vtot_val = &dev_priv->saveVTOTAL_A;
168 u32 *vblank_val = &dev_priv->saveVBLANK_A;
169 u32 *vsync_val = &dev_priv->saveVSYNC_A;
170 u32 *pipesrc_val = &dev_priv->savePIPEASRC;
171 u32 *dspstride_val = &dev_priv->saveDSPASTRIDE;
172 u32 *dsplinoff_val = &dev_priv->saveDSPALINOFF;
173 u32 *dsptileoff_val = &dev_priv->saveDSPATILEOFF;
174 u32 *dspsize_val = &dev_priv->saveDSPASIZE;
175 u32 *dsppos_val = &dev_priv->saveDSPAPOS;
176 u32 *dspsurf_val = &dev_priv->saveDSPASURF;
177 u32 *mipi_val = &dev_priv->saveMIPI;
178 u32 *dspcntr_val = &dev_priv->saveDSPACNTR;
179 u32 *dspstatus_val = &dev_priv->saveDSPASTATUS;
180 u32 *palette_val = dev_priv->save_palette_a;
182 switch (pipe) {
183 case 0:
184 break;
185 case 1:
186 /* register */
187 dpll_reg = MDFLD_DPLL_B;
188 fp_reg = MDFLD_DPLL_DIV0;
189 pipeconf_reg = PIPEBCONF;
190 htot_reg = HTOTAL_B;
191 hblank_reg = HBLANK_B;
192 hsync_reg = HSYNC_B;
193 vtot_reg = VTOTAL_B;
194 vblank_reg = VBLANK_B;
195 vsync_reg = VSYNC_B;
196 pipesrc_reg = PIPEBSRC;
197 dspstride_reg = DSPBSTRIDE;
198 dsplinoff_reg = DSPBLINOFF;
199 dsptileoff_reg = DSPBTILEOFF;
200 dspsize_reg = DSPBSIZE;
201 dsppos_reg = DSPBPOS;
202 dspsurf_reg = DSPBSURF;
203 dspcntr_reg = DSPBCNTR;
204 dspstatus_reg = PIPEBSTAT;
205 palette_reg = PALETTE_B;
207 /* values */
208 dpll_val = &dev_priv->saveDPLL_B;
209 fp_val = &dev_priv->saveFPB0;
210 pipeconf_val = &dev_priv->savePIPEBCONF;
211 htot_val = &dev_priv->saveHTOTAL_B;
212 hblank_val = &dev_priv->saveHBLANK_B;
213 hsync_val = &dev_priv->saveHSYNC_B;
214 vtot_val = &dev_priv->saveVTOTAL_B;
215 vblank_val = &dev_priv->saveVBLANK_B;
216 vsync_val = &dev_priv->saveVSYNC_B;
217 pipesrc_val = &dev_priv->savePIPEBSRC;
218 dspstride_val = &dev_priv->saveDSPBSTRIDE;
219 dsplinoff_val = &dev_priv->saveDSPBLINOFF;
220 dsptileoff_val = &dev_priv->saveDSPBTILEOFF;
221 dspsize_val = &dev_priv->saveDSPBSIZE;
222 dsppos_val = &dev_priv->saveDSPBPOS;
223 dspsurf_val = &dev_priv->saveDSPBSURF;
224 dspcntr_val = &dev_priv->saveDSPBCNTR;
225 dspstatus_val = &dev_priv->saveDSPBSTATUS;
226 palette_val = dev_priv->save_palette_b;
227 break;
228 case 2:
229 /* register */
230 pipeconf_reg = PIPECCONF;
231 htot_reg = HTOTAL_C;
232 hblank_reg = HBLANK_C;
233 hsync_reg = HSYNC_C;
234 vtot_reg = VTOTAL_C;
235 vblank_reg = VBLANK_C;
236 vsync_reg = VSYNC_C;
237 pipesrc_reg = PIPECSRC;
238 dspstride_reg = DSPCSTRIDE;
239 dsplinoff_reg = DSPCLINOFF;
240 dsptileoff_reg = DSPCTILEOFF;
241 dspsize_reg = DSPCSIZE;
242 dsppos_reg = DSPCPOS;
243 dspsurf_reg = DSPCSURF;
244 mipi_reg = MIPI_C;
245 dspcntr_reg = DSPCCNTR;
246 dspstatus_reg = PIPECSTAT;
247 palette_reg = PALETTE_C;
249 /* pointer to values */
250 pipeconf_val = &dev_priv->savePIPECCONF;
251 htot_val = &dev_priv->saveHTOTAL_C;
252 hblank_val = &dev_priv->saveHBLANK_C;
253 hsync_val = &dev_priv->saveHSYNC_C;
254 vtot_val = &dev_priv->saveVTOTAL_C;
255 vblank_val = &dev_priv->saveVBLANK_C;
256 vsync_val = &dev_priv->saveVSYNC_C;
257 pipesrc_val = &dev_priv->savePIPECSRC;
258 dspstride_val = &dev_priv->saveDSPCSTRIDE;
259 dsplinoff_val = &dev_priv->saveDSPCLINOFF;
260 dsptileoff_val = &dev_priv->saveDSPCTILEOFF;
261 dspsize_val = &dev_priv->saveDSPCSIZE;
262 dsppos_val = &dev_priv->saveDSPCPOS;
263 dspsurf_val = &dev_priv->saveDSPCSURF;
264 mipi_val = &dev_priv->saveMIPI_C;
265 dspcntr_val = &dev_priv->saveDSPCCNTR;
266 dspstatus_val = &dev_priv->saveDSPCSTATUS;
267 palette_val = dev_priv->save_palette_c;
268 break;
269 default:
270 DRM_ERROR("%s, invalid pipe number.\n", __func__);
271 return -EINVAL;
274 /* Pipe & plane A info */
275 *dpll_val = PSB_RVDC32(dpll_reg);
276 *fp_val = PSB_RVDC32(fp_reg);
277 *pipeconf_val = PSB_RVDC32(pipeconf_reg);
278 *htot_val = PSB_RVDC32(htot_reg);
279 *hblank_val = PSB_RVDC32(hblank_reg);
280 *hsync_val = PSB_RVDC32(hsync_reg);
281 *vtot_val = PSB_RVDC32(vtot_reg);
282 *vblank_val = PSB_RVDC32(vblank_reg);
283 *vsync_val = PSB_RVDC32(vsync_reg);
284 *pipesrc_val = PSB_RVDC32(pipesrc_reg);
285 *dspstride_val = PSB_RVDC32(dspstride_reg);
286 *dsplinoff_val = PSB_RVDC32(dsplinoff_reg);
287 *dsptileoff_val = PSB_RVDC32(dsptileoff_reg);
288 *dspsize_val = PSB_RVDC32(dspsize_reg);
289 *dsppos_val = PSB_RVDC32(dsppos_reg);
290 *dspsurf_val = PSB_RVDC32(dspsurf_reg);
291 *dspcntr_val = PSB_RVDC32(dspcntr_reg);
292 *dspstatus_val = PSB_RVDC32(dspstatus_reg);
294 /*save palette (gamma) */
295 for (i = 0; i < 256; i++)
296 palette_val[i] = PSB_RVDC32(palette_reg + (i<<2));
298 if (pipe == 1) {
299 dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
300 dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
301 dev_priv->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL);
302 dev_priv->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL);
303 return 0;
305 *mipi_val = PSB_RVDC32(mipi_reg);
306 return 0;
310 * mdfld_save_cursor_overlay_registers - save cursor overlay info
311 * @dev: our device
313 * Save the cursor and overlay register state
315 static int mdfld_save_cursor_overlay_registers(struct drm_device *dev)
317 struct drm_psb_private *dev_priv = dev->dev_private;
319 /* Save cursor regs */
320 dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
321 dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
322 dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);
324 dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
325 dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
326 dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
328 dev_priv->saveDSPCCURSOR_CTRL = PSB_RVDC32(CURCCNTR);
329 dev_priv->saveDSPCCURSOR_BASE = PSB_RVDC32(CURCBASE);
330 dev_priv->saveDSPCCURSOR_POS = PSB_RVDC32(CURCPOS);
332 /* HW overlay */
333 dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD);
334 dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0);
335 dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1);
336 dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2);
337 dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3);
338 dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4);
339 dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
341 dev_priv->saveOV_OVADD_C = PSB_RVDC32(OV_OVADD + OV_C_OFFSET);
342 dev_priv->saveOV_OGAMC0_C = PSB_RVDC32(OV_OGAMC0 + OV_C_OFFSET);
343 dev_priv->saveOV_OGAMC1_C = PSB_RVDC32(OV_OGAMC1 + OV_C_OFFSET);
344 dev_priv->saveOV_OGAMC2_C = PSB_RVDC32(OV_OGAMC2 + OV_C_OFFSET);
345 dev_priv->saveOV_OGAMC3_C = PSB_RVDC32(OV_OGAMC3 + OV_C_OFFSET);
346 dev_priv->saveOV_OGAMC4_C = PSB_RVDC32(OV_OGAMC4 + OV_C_OFFSET);
347 dev_priv->saveOV_OGAMC5_C = PSB_RVDC32(OV_OGAMC5 + OV_C_OFFSET);
349 return 0;
352 * mdfld_restore_display_registers - restore the state of a pipe
353 * @dev: our device
354 * @pipe: the pipe to restore
356 * Restore the state of a pipe to that which was saved by the register save
357 * functions.
359 static int mdfld_restore_display_registers(struct drm_device *dev, int pipe)
361 /* To get panel out of ULPS mode */
362 struct drm_psb_private *dev_priv = dev->dev_private;
363 struct mdfld_dsi_config *dsi_config = NULL;
364 u32 i = 0;
365 u32 dpll = 0;
366 u32 timeout = 0;
367 u32 reg_offset = 0;
369 /* register */
370 u32 dpll_reg = MRST_DPLL_A;
371 u32 fp_reg = MRST_FPA0;
372 u32 pipeconf_reg = PIPEACONF;
373 u32 htot_reg = HTOTAL_A;
374 u32 hblank_reg = HBLANK_A;
375 u32 hsync_reg = HSYNC_A;
376 u32 vtot_reg = VTOTAL_A;
377 u32 vblank_reg = VBLANK_A;
378 u32 vsync_reg = VSYNC_A;
379 u32 pipesrc_reg = PIPEASRC;
380 u32 dspstride_reg = DSPASTRIDE;
381 u32 dsplinoff_reg = DSPALINOFF;
382 u32 dsptileoff_reg = DSPATILEOFF;
383 u32 dspsize_reg = DSPASIZE;
384 u32 dsppos_reg = DSPAPOS;
385 u32 dspsurf_reg = DSPASURF;
386 u32 dspstatus_reg = PIPEASTAT;
387 u32 mipi_reg = MIPI;
388 u32 dspcntr_reg = DSPACNTR;
389 u32 palette_reg = PALETTE_A;
391 /* values */
392 u32 dpll_val = dev_priv->saveDPLL_A & ~DPLL_VCO_ENABLE;
393 u32 fp_val = dev_priv->saveFPA0;
394 u32 pipeconf_val = dev_priv->savePIPEACONF;
395 u32 htot_val = dev_priv->saveHTOTAL_A;
396 u32 hblank_val = dev_priv->saveHBLANK_A;
397 u32 hsync_val = dev_priv->saveHSYNC_A;
398 u32 vtot_val = dev_priv->saveVTOTAL_A;
399 u32 vblank_val = dev_priv->saveVBLANK_A;
400 u32 vsync_val = dev_priv->saveVSYNC_A;
401 u32 pipesrc_val = dev_priv->savePIPEASRC;
402 u32 dspstride_val = dev_priv->saveDSPASTRIDE;
403 u32 dsplinoff_val = dev_priv->saveDSPALINOFF;
404 u32 dsptileoff_val = dev_priv->saveDSPATILEOFF;
405 u32 dspsize_val = dev_priv->saveDSPASIZE;
406 u32 dsppos_val = dev_priv->saveDSPAPOS;
407 u32 dspsurf_val = dev_priv->saveDSPASURF;
408 u32 dspstatus_val = dev_priv->saveDSPASTATUS;
409 u32 mipi_val = dev_priv->saveMIPI;
410 u32 dspcntr_val = dev_priv->saveDSPACNTR;
411 u32 *palette_val = dev_priv->save_palette_a;
413 switch (pipe) {
414 case 0:
415 dsi_config = dev_priv->dsi_configs[0];
416 break;
417 case 1:
418 /* register */
419 dpll_reg = MDFLD_DPLL_B;
420 fp_reg = MDFLD_DPLL_DIV0;
421 pipeconf_reg = PIPEBCONF;
422 htot_reg = HTOTAL_B;
423 hblank_reg = HBLANK_B;
424 hsync_reg = HSYNC_B;
425 vtot_reg = VTOTAL_B;
426 vblank_reg = VBLANK_B;
427 vsync_reg = VSYNC_B;
428 pipesrc_reg = PIPEBSRC;
429 dspstride_reg = DSPBSTRIDE;
430 dsplinoff_reg = DSPBLINOFF;
431 dsptileoff_reg = DSPBTILEOFF;
432 dspsize_reg = DSPBSIZE;
433 dsppos_reg = DSPBPOS;
434 dspsurf_reg = DSPBSURF;
435 dspcntr_reg = DSPBCNTR;
436 palette_reg = PALETTE_B;
437 dspstatus_reg = PIPEBSTAT;
439 /* values */
440 dpll_val = dev_priv->saveDPLL_B & ~DPLL_VCO_ENABLE;
441 fp_val = dev_priv->saveFPB0;
442 pipeconf_val = dev_priv->savePIPEBCONF;
443 htot_val = dev_priv->saveHTOTAL_B;
444 hblank_val = dev_priv->saveHBLANK_B;
445 hsync_val = dev_priv->saveHSYNC_B;
446 vtot_val = dev_priv->saveVTOTAL_B;
447 vblank_val = dev_priv->saveVBLANK_B;
448 vsync_val = dev_priv->saveVSYNC_B;
449 pipesrc_val = dev_priv->savePIPEBSRC;
450 dspstride_val = dev_priv->saveDSPBSTRIDE;
451 dsplinoff_val = dev_priv->saveDSPBLINOFF;
452 dsptileoff_val = dev_priv->saveDSPBTILEOFF;
453 dspsize_val = dev_priv->saveDSPBSIZE;
454 dsppos_val = dev_priv->saveDSPBPOS;
455 dspsurf_val = dev_priv->saveDSPBSURF;
456 dspcntr_val = dev_priv->saveDSPBCNTR;
457 dspstatus_val = dev_priv->saveDSPBSTATUS;
458 palette_val = dev_priv->save_palette_b;
459 break;
460 case 2:
461 reg_offset = MIPIC_REG_OFFSET;
463 /* register */
464 pipeconf_reg = PIPECCONF;
465 htot_reg = HTOTAL_C;
466 hblank_reg = HBLANK_C;
467 hsync_reg = HSYNC_C;
468 vtot_reg = VTOTAL_C;
469 vblank_reg = VBLANK_C;
470 vsync_reg = VSYNC_C;
471 pipesrc_reg = PIPECSRC;
472 dspstride_reg = DSPCSTRIDE;
473 dsplinoff_reg = DSPCLINOFF;
474 dsptileoff_reg = DSPCTILEOFF;
475 dspsize_reg = DSPCSIZE;
476 dsppos_reg = DSPCPOS;
477 dspsurf_reg = DSPCSURF;
478 mipi_reg = MIPI_C;
479 dspcntr_reg = DSPCCNTR;
480 palette_reg = PALETTE_C;
481 dspstatus_reg = PIPECSTAT;
483 /* values */
484 pipeconf_val = dev_priv->savePIPECCONF;
485 htot_val = dev_priv->saveHTOTAL_C;
486 hblank_val = dev_priv->saveHBLANK_C;
487 hsync_val = dev_priv->saveHSYNC_C;
488 vtot_val = dev_priv->saveVTOTAL_C;
489 vblank_val = dev_priv->saveVBLANK_C;
490 vsync_val = dev_priv->saveVSYNC_C;
491 pipesrc_val = dev_priv->savePIPECSRC;
492 dspstride_val = dev_priv->saveDSPCSTRIDE;
493 dsplinoff_val = dev_priv->saveDSPCLINOFF;
494 dsptileoff_val = dev_priv->saveDSPCTILEOFF;
495 dspsize_val = dev_priv->saveDSPCSIZE;
496 dsppos_val = dev_priv->saveDSPCPOS;
497 dspsurf_val = dev_priv->saveDSPCSURF;
498 dspstatus_val = dev_priv->saveDSPCSTATUS;
499 mipi_val = dev_priv->saveMIPI_C;
500 dspcntr_val = dev_priv->saveDSPCCNTR;
501 palette_val = dev_priv->save_palette_c;
503 dsi_config = dev_priv->dsi_configs[1];
504 break;
505 default:
506 DRM_ERROR("%s, invalid pipe number.\n", __func__);
507 return -EINVAL;
510 /* Make sure VGA plane is off. it initializes to on after reset!*/
511 PSB_WVDC32(0x80000000, VGACNTRL);
512 if (pipe == 1) {
513 PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg);
514 PSB_RVDC32(dpll_reg);
516 PSB_WVDC32(fp_val, fp_reg);
517 } else {
518 dpll = PSB_RVDC32(dpll_reg);
520 if (!(dpll & DPLL_VCO_ENABLE)) {
522 /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
523 if (dpll & MDFLD_PWR_GATE_EN) {
524 dpll &= ~MDFLD_PWR_GATE_EN;
525 PSB_WVDC32(dpll, dpll_reg);
526 udelay(500); /* FIXME: 1 ? */
529 PSB_WVDC32(fp_val, fp_reg);
530 PSB_WVDC32(dpll_val, dpll_reg);
531 /* FIXME_MDFLD PO - change 500 to 1 after PO */
532 udelay(500);
534 dpll_val |= DPLL_VCO_ENABLE;
535 PSB_WVDC32(dpll_val, dpll_reg);
536 PSB_RVDC32(dpll_reg);
538 /* wait for DSI PLL to lock */
539 while ((timeout < 20000) && !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
540 udelay(150);
541 timeout++;
544 if (timeout == 20000) {
545 DRM_ERROR("%s, can't lock DSIPLL.\n",
546 __func__);
547 return -EINVAL;
551 /* Restore mode */
552 PSB_WVDC32(htot_val, htot_reg);
553 PSB_WVDC32(hblank_val, hblank_reg);
554 PSB_WVDC32(hsync_val, hsync_reg);
555 PSB_WVDC32(vtot_val, vtot_reg);
556 PSB_WVDC32(vblank_val, vblank_reg);
557 PSB_WVDC32(vsync_val, vsync_reg);
558 PSB_WVDC32(pipesrc_val, pipesrc_reg);
559 PSB_WVDC32(dspstatus_val, dspstatus_reg);
561 /* Set up the plane */
562 PSB_WVDC32(dspstride_val, dspstride_reg);
563 PSB_WVDC32(dsplinoff_val, dsplinoff_reg);
564 PSB_WVDC32(dsptileoff_val, dsptileoff_reg);
565 PSB_WVDC32(dspsize_val, dspsize_reg);
566 PSB_WVDC32(dsppos_val, dsppos_reg);
567 PSB_WVDC32(dspsurf_val, dspsurf_reg);
569 if (pipe == 1) {
570 PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
571 PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
572 PSB_WVDC32(dev_priv->saveHDMIPHYMISCCTL, HDMIPHYMISCCTL);
573 PSB_WVDC32(dev_priv->saveHDMIB_CONTROL, HDMIB_CONTROL);
575 } else {
576 /* Set up pipe related registers */
577 PSB_WVDC32(mipi_val, mipi_reg);
578 /* Setup MIPI adapter + MIPI IP registers */
579 mdfld_dsi_controller_init(dsi_config, pipe);
580 msleep(20);
582 /* Enable the plane */
583 PSB_WVDC32(dspcntr_val, dspcntr_reg);
584 msleep(20);
585 /* Enable the pipe */
586 PSB_WVDC32(pipeconf_val, pipeconf_reg);
588 for (i = 0; i < 256; i++)
589 PSB_WVDC32(palette_val[i], palette_reg + (i<<2));
590 if (pipe == 1)
591 return 0;
592 if (!mdfld_panel_dpi(dev))
593 mdfld_enable_te(dev, pipe);
594 return 0;
598 * mdfld_restore_cursor_overlay_registers - restore cursor
599 * @dev: our device
601 * Restore the cursor and overlay state that was saved earlier
603 static int mdfld_restore_cursor_overlay_registers(struct drm_device *dev)
605 struct drm_psb_private *dev_priv = dev->dev_private;
607 /* Enable Cursor A */
608 PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
609 PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
610 PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);
612 PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR);
613 PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS);
614 PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE);
616 PSB_WVDC32(dev_priv->saveDSPCCURSOR_CTRL, CURCCNTR);
617 PSB_WVDC32(dev_priv->saveDSPCCURSOR_POS, CURCPOS);
618 PSB_WVDC32(dev_priv->saveDSPCCURSOR_BASE, CURCBASE);
620 /* Restore HW overlay */
621 PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD);
622 PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0);
623 PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1);
624 PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2);
625 PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3);
626 PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4);
627 PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
629 PSB_WVDC32(dev_priv->saveOV_OVADD_C, OV_OVADD + OV_C_OFFSET);
630 PSB_WVDC32(dev_priv->saveOV_OGAMC0_C, OV_OGAMC0 + OV_C_OFFSET);
631 PSB_WVDC32(dev_priv->saveOV_OGAMC1_C, OV_OGAMC1 + OV_C_OFFSET);
632 PSB_WVDC32(dev_priv->saveOV_OGAMC2_C, OV_OGAMC2 + OV_C_OFFSET);
633 PSB_WVDC32(dev_priv->saveOV_OGAMC3_C, OV_OGAMC3 + OV_C_OFFSET);
634 PSB_WVDC32(dev_priv->saveOV_OGAMC4_C, OV_OGAMC4 + OV_C_OFFSET);
635 PSB_WVDC32(dev_priv->saveOV_OGAMC5_C, OV_OGAMC5 + OV_C_OFFSET);
637 return 0;
641 * mdfld_save_display_registers - save registers lost on suspend
642 * @dev: our DRM device
644 * Save the state we need in order to be able to restore the interface
645 * upon resume from suspend
647 static int mdfld_save_registers(struct drm_device *dev)
649 /* FIXME: We need to shut down panels here if using them
650 and once the right bits are merged */
651 mdfld_save_cursor_overlay_registers(dev);
652 mdfld_save_display_registers(dev, 0);
653 mdfld_save_display_registers(dev, 0);
654 mdfld_save_display_registers(dev, 2);
655 mdfld_save_display_registers(dev, 1);
656 mdfld_disable_crtc(dev, 0);
657 mdfld_disable_crtc(dev, 2);
658 mdfld_disable_crtc(dev, 1);
659 return 0;
663 * mdfld_restore_display_registers - restore lost register state
664 * @dev: our DRM device
666 * Restore register state that was lost during suspend and resume.
668 static int mdfld_restore_registers(struct drm_device *dev)
670 mdfld_restore_display_registers(dev, 1);
671 mdfld_restore_display_registers(dev, 0);
672 mdfld_restore_display_registers(dev, 2);
673 mdfld_restore_cursor_overlay_registers(dev);
674 return 0;
677 static int mdfld_power_down(struct drm_device *dev)
679 /* FIXME */
680 return 0;
683 static int mdfld_power_up(struct drm_device *dev)
685 /* FIXME */
686 return 0;
689 const struct psb_ops mdfld_chip_ops = {
690 .name = "Medfield",
691 .accel_2d = 0,
692 .crtc_helper = &mdfld_helper_funcs,
693 .crtc_funcs = &mdfld_intel_crtc_funcs,
695 .output_init = mdfld_output_init,
697 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
698 .backlight_init = mdfld_backlight_init,
699 #endif
701 .init_pm = mdfld_init_pm,
702 .save_regs = mdfld_save_registers,
703 .restore_regs = mdfld_restore_registers,
704 .power_down = mdfld_power_down,
705 .power_up = mdfld_power_up,