1 /**************************************************************************
2 * Copyright (c) 2011, Intel Corporation.
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
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>
24 #include "psb_intel_reg.h"
27 #include "mdfld_output.h"
28 #include "mdfld_dsi_output.h"
32 * Provide the Medfield specific backlight management
35 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
37 static int mdfld_brightness
;
38 struct backlight_device
*mdfld_backlight_device
;
40 static int mfld_set_brightness(struct backlight_device
*bd
)
42 struct drm_device
*dev
= bl_get_data(mdfld_backlight_device
);
43 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
44 int level
= bd
->props
.brightness
;
46 /* Percentage 1-100% being valid */
50 if (gma_power_begin(dev
, 0)) {
51 /* Calculate and set the brightness value */
54 /* Adjust the backlight level with the percent in
57 adjusted_level
= level
* dev_priv
->blc_adj2
;
58 adjusted_level
= adjusted_level
/ 100;
60 #ifndef CONFIG_MDFLD_DSI_DPU
61 if(!(dev_priv
->dsr_fb_update
& MDFLD_DSR_MIPI_CONTROL
) &&
62 (dev_priv
->dbi_panel_on
|| dev_priv
->dbi_panel_on2
)){
63 mdfld_dsi_dbi_exit_dsr(dev
,MDFLD_DSR_MIPI_CONTROL
, 0, 0);
64 dev_dbg(dev
->dev
, "Out of DSR before set brightness to %d.\n",adjusted_level
);
67 mdfld_dsi_brightness_control(dev
, 0, adjusted_level
);
69 if ((dev_priv
->dbi_panel_on2
) || (dev_priv
->dpi_panel_on2
))
70 mdfld_dsi_brightness_control(dev
, 2, adjusted_level
);
74 mdfld_brightness
= level
;
78 int psb_get_brightness(struct backlight_device
*bd
)
80 /* return locally cached var instead of HW read (due to DPST etc.) */
81 /* FIXME: ideally return actual value in case firmware fiddled with
83 return mdfld_brightness
;
86 static const struct backlight_ops mfld_ops
= {
87 .get_brightness
= psb_get_brightness
,
88 .update_status
= mfld_set_brightness
,
91 static int mdfld_backlight_init(struct drm_device
*dev
)
93 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
94 struct backlight_properties props
;
95 memset(&props
, 0, sizeof(struct backlight_properties
));
96 props
.max_brightness
= 100;
97 props
.type
= BACKLIGHT_PLATFORM
;
99 mdfld_backlight_device
= backlight_device_register("mfld-bl",
100 NULL
, (void *)dev
, &mfld_ops
, &props
);
102 if (IS_ERR(mdfld_backlight_device
))
103 return PTR_ERR(mdfld_backlight_device
);
105 dev_priv
->blc_adj1
= 100;
106 dev_priv
->blc_adj2
= 100;
107 mdfld_backlight_device
->props
.brightness
= 100;
108 mdfld_backlight_device
->props
.max_brightness
= 100;
109 backlight_update_status(mdfld_backlight_device
);
110 dev_priv
->backlight_device
= mdfld_backlight_device
;
117 * Provide the Medfield specific chip logic and low level methods for
121 static void mdfld_init_pm(struct drm_device
*dev
)
123 /* No work needed here yet */
127 * mdfld_save_display_registers - save registers for pipe
129 * @pipe: pipe to save
131 * Save the pipe state of the device before we power it off. Keep everything
132 * we need to put it back again
134 static int mdfld_save_display_registers(struct drm_device
*dev
, int pipe
)
136 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
140 u32 dpll_reg
= MRST_DPLL_A
;
141 u32 fp_reg
= MRST_FPA0
;
142 u32 pipeconf_reg
= PIPEACONF
;
143 u32 htot_reg
= HTOTAL_A
;
144 u32 hblank_reg
= HBLANK_A
;
145 u32 hsync_reg
= HSYNC_A
;
146 u32 vtot_reg
= VTOTAL_A
;
147 u32 vblank_reg
= VBLANK_A
;
148 u32 vsync_reg
= VSYNC_A
;
149 u32 pipesrc_reg
= PIPEASRC
;
150 u32 dspstride_reg
= DSPASTRIDE
;
151 u32 dsplinoff_reg
= DSPALINOFF
;
152 u32 dsptileoff_reg
= DSPATILEOFF
;
153 u32 dspsize_reg
= DSPASIZE
;
154 u32 dsppos_reg
= DSPAPOS
;
155 u32 dspsurf_reg
= DSPASURF
;
157 u32 dspcntr_reg
= DSPACNTR
;
158 u32 dspstatus_reg
= PIPEASTAT
;
159 u32 palette_reg
= PALETTE_A
;
161 /* pointer to values */
162 u32
*dpll_val
= &dev_priv
->saveDPLL_A
;
163 u32
*fp_val
= &dev_priv
->saveFPA0
;
164 u32
*pipeconf_val
= &dev_priv
->savePIPEACONF
;
165 u32
*htot_val
= &dev_priv
->saveHTOTAL_A
;
166 u32
*hblank_val
= &dev_priv
->saveHBLANK_A
;
167 u32
*hsync_val
= &dev_priv
->saveHSYNC_A
;
168 u32
*vtot_val
= &dev_priv
->saveVTOTAL_A
;
169 u32
*vblank_val
= &dev_priv
->saveVBLANK_A
;
170 u32
*vsync_val
= &dev_priv
->saveVSYNC_A
;
171 u32
*pipesrc_val
= &dev_priv
->savePIPEASRC
;
172 u32
*dspstride_val
= &dev_priv
->saveDSPASTRIDE
;
173 u32
*dsplinoff_val
= &dev_priv
->saveDSPALINOFF
;
174 u32
*dsptileoff_val
= &dev_priv
->saveDSPATILEOFF
;
175 u32
*dspsize_val
= &dev_priv
->saveDSPASIZE
;
176 u32
*dsppos_val
= &dev_priv
->saveDSPAPOS
;
177 u32
*dspsurf_val
= &dev_priv
->saveDSPASURF
;
178 u32
*mipi_val
= &dev_priv
->saveMIPI
;
179 u32
*dspcntr_val
= &dev_priv
->saveDSPACNTR
;
180 u32
*dspstatus_val
= &dev_priv
->saveDSPASTATUS
;
181 u32
*palette_val
= dev_priv
->save_palette_a
;
188 dpll_reg
= MDFLD_DPLL_B
;
189 fp_reg
= MDFLD_DPLL_DIV0
;
190 pipeconf_reg
= PIPEBCONF
;
192 hblank_reg
= HBLANK_B
;
195 vblank_reg
= VBLANK_B
;
197 pipesrc_reg
= PIPEBSRC
;
198 dspstride_reg
= DSPBSTRIDE
;
199 dsplinoff_reg
= DSPBLINOFF
;
200 dsptileoff_reg
= DSPBTILEOFF
;
201 dspsize_reg
= DSPBSIZE
;
202 dsppos_reg
= DSPBPOS
;
203 dspsurf_reg
= DSPBSURF
;
204 dspcntr_reg
= DSPBCNTR
;
205 dspstatus_reg
= PIPEBSTAT
;
206 palette_reg
= PALETTE_B
;
209 dpll_val
= &dev_priv
->saveDPLL_B
;
210 fp_val
= &dev_priv
->saveFPB0
;
211 pipeconf_val
= &dev_priv
->savePIPEBCONF
;
212 htot_val
= &dev_priv
->saveHTOTAL_B
;
213 hblank_val
= &dev_priv
->saveHBLANK_B
;
214 hsync_val
= &dev_priv
->saveHSYNC_B
;
215 vtot_val
= &dev_priv
->saveVTOTAL_B
;
216 vblank_val
= &dev_priv
->saveVBLANK_B
;
217 vsync_val
= &dev_priv
->saveVSYNC_B
;
218 pipesrc_val
= &dev_priv
->savePIPEBSRC
;
219 dspstride_val
= &dev_priv
->saveDSPBSTRIDE
;
220 dsplinoff_val
= &dev_priv
->saveDSPBLINOFF
;
221 dsptileoff_val
= &dev_priv
->saveDSPBTILEOFF
;
222 dspsize_val
= &dev_priv
->saveDSPBSIZE
;
223 dsppos_val
= &dev_priv
->saveDSPBPOS
;
224 dspsurf_val
= &dev_priv
->saveDSPBSURF
;
225 dspcntr_val
= &dev_priv
->saveDSPBCNTR
;
226 dspstatus_val
= &dev_priv
->saveDSPBSTATUS
;
227 palette_val
= dev_priv
->save_palette_b
;
231 pipeconf_reg
= PIPECCONF
;
233 hblank_reg
= HBLANK_C
;
236 vblank_reg
= VBLANK_C
;
238 pipesrc_reg
= PIPECSRC
;
239 dspstride_reg
= DSPCSTRIDE
;
240 dsplinoff_reg
= DSPCLINOFF
;
241 dsptileoff_reg
= DSPCTILEOFF
;
242 dspsize_reg
= DSPCSIZE
;
243 dsppos_reg
= DSPCPOS
;
244 dspsurf_reg
= DSPCSURF
;
246 dspcntr_reg
= DSPCCNTR
;
247 dspstatus_reg
= PIPECSTAT
;
248 palette_reg
= PALETTE_C
;
250 /* pointer to values */
251 pipeconf_val
= &dev_priv
->savePIPECCONF
;
252 htot_val
= &dev_priv
->saveHTOTAL_C
;
253 hblank_val
= &dev_priv
->saveHBLANK_C
;
254 hsync_val
= &dev_priv
->saveHSYNC_C
;
255 vtot_val
= &dev_priv
->saveVTOTAL_C
;
256 vblank_val
= &dev_priv
->saveVBLANK_C
;
257 vsync_val
= &dev_priv
->saveVSYNC_C
;
258 pipesrc_val
= &dev_priv
->savePIPECSRC
;
259 dspstride_val
= &dev_priv
->saveDSPCSTRIDE
;
260 dsplinoff_val
= &dev_priv
->saveDSPCLINOFF
;
261 dsptileoff_val
= &dev_priv
->saveDSPCTILEOFF
;
262 dspsize_val
= &dev_priv
->saveDSPCSIZE
;
263 dsppos_val
= &dev_priv
->saveDSPCPOS
;
264 dspsurf_val
= &dev_priv
->saveDSPCSURF
;
265 mipi_val
= &dev_priv
->saveMIPI_C
;
266 dspcntr_val
= &dev_priv
->saveDSPCCNTR
;
267 dspstatus_val
= &dev_priv
->saveDSPCSTATUS
;
268 palette_val
= dev_priv
->save_palette_c
;
271 DRM_ERROR("%s, invalid pipe number.\n", __func__
);
275 /* Pipe & plane A info */
276 *dpll_val
= PSB_RVDC32(dpll_reg
);
277 *fp_val
= PSB_RVDC32(fp_reg
);
278 *pipeconf_val
= PSB_RVDC32(pipeconf_reg
);
279 *htot_val
= PSB_RVDC32(htot_reg
);
280 *hblank_val
= PSB_RVDC32(hblank_reg
);
281 *hsync_val
= PSB_RVDC32(hsync_reg
);
282 *vtot_val
= PSB_RVDC32(vtot_reg
);
283 *vblank_val
= PSB_RVDC32(vblank_reg
);
284 *vsync_val
= PSB_RVDC32(vsync_reg
);
285 *pipesrc_val
= PSB_RVDC32(pipesrc_reg
);
286 *dspstride_val
= PSB_RVDC32(dspstride_reg
);
287 *dsplinoff_val
= PSB_RVDC32(dsplinoff_reg
);
288 *dsptileoff_val
= PSB_RVDC32(dsptileoff_reg
);
289 *dspsize_val
= PSB_RVDC32(dspsize_reg
);
290 *dsppos_val
= PSB_RVDC32(dsppos_reg
);
291 *dspsurf_val
= PSB_RVDC32(dspsurf_reg
);
292 *dspcntr_val
= PSB_RVDC32(dspcntr_reg
);
293 *dspstatus_val
= PSB_RVDC32(dspstatus_reg
);
295 /*save palette (gamma) */
296 for (i
= 0; i
< 256; i
++)
297 palette_val
[i
] = PSB_RVDC32(palette_reg
+ (i
<<2));
300 dev_priv
->savePFIT_CONTROL
= PSB_RVDC32(PFIT_CONTROL
);
301 dev_priv
->savePFIT_PGM_RATIOS
= PSB_RVDC32(PFIT_PGM_RATIOS
);
302 dev_priv
->saveHDMIPHYMISCCTL
= PSB_RVDC32(HDMIPHYMISCCTL
);
303 dev_priv
->saveHDMIB_CONTROL
= PSB_RVDC32(HDMIB_CONTROL
);
306 *mipi_val
= PSB_RVDC32(mipi_reg
);
311 * mdfld_save_cursor_overlay_registers - save cursor overlay info
314 * Save the cursor and overlay register state
316 static int mdfld_save_cursor_overlay_registers(struct drm_device
*dev
)
318 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
320 /* Save cursor regs */
321 dev_priv
->saveDSPACURSOR_CTRL
= PSB_RVDC32(CURACNTR
);
322 dev_priv
->saveDSPACURSOR_BASE
= PSB_RVDC32(CURABASE
);
323 dev_priv
->saveDSPACURSOR_POS
= PSB_RVDC32(CURAPOS
);
325 dev_priv
->saveDSPBCURSOR_CTRL
= PSB_RVDC32(CURBCNTR
);
326 dev_priv
->saveDSPBCURSOR_BASE
= PSB_RVDC32(CURBBASE
);
327 dev_priv
->saveDSPBCURSOR_POS
= PSB_RVDC32(CURBPOS
);
329 dev_priv
->saveDSPCCURSOR_CTRL
= PSB_RVDC32(CURCCNTR
);
330 dev_priv
->saveDSPCCURSOR_BASE
= PSB_RVDC32(CURCBASE
);
331 dev_priv
->saveDSPCCURSOR_POS
= PSB_RVDC32(CURCPOS
);
334 dev_priv
->saveOV_OVADD
= PSB_RVDC32(OV_OVADD
);
335 dev_priv
->saveOV_OGAMC0
= PSB_RVDC32(OV_OGAMC0
);
336 dev_priv
->saveOV_OGAMC1
= PSB_RVDC32(OV_OGAMC1
);
337 dev_priv
->saveOV_OGAMC2
= PSB_RVDC32(OV_OGAMC2
);
338 dev_priv
->saveOV_OGAMC3
= PSB_RVDC32(OV_OGAMC3
);
339 dev_priv
->saveOV_OGAMC4
= PSB_RVDC32(OV_OGAMC4
);
340 dev_priv
->saveOV_OGAMC5
= PSB_RVDC32(OV_OGAMC5
);
342 dev_priv
->saveOV_OVADD_C
= PSB_RVDC32(OV_OVADD
+ OV_C_OFFSET
);
343 dev_priv
->saveOV_OGAMC0_C
= PSB_RVDC32(OV_OGAMC0
+ OV_C_OFFSET
);
344 dev_priv
->saveOV_OGAMC1_C
= PSB_RVDC32(OV_OGAMC1
+ OV_C_OFFSET
);
345 dev_priv
->saveOV_OGAMC2_C
= PSB_RVDC32(OV_OGAMC2
+ OV_C_OFFSET
);
346 dev_priv
->saveOV_OGAMC3_C
= PSB_RVDC32(OV_OGAMC3
+ OV_C_OFFSET
);
347 dev_priv
->saveOV_OGAMC4_C
= PSB_RVDC32(OV_OGAMC4
+ OV_C_OFFSET
);
348 dev_priv
->saveOV_OGAMC5_C
= PSB_RVDC32(OV_OGAMC5
+ OV_C_OFFSET
);
353 * mdfld_restore_display_registers - restore the state of a pipe
355 * @pipe: the pipe to restore
357 * Restore the state of a pipe to that which was saved by the register save
360 static int mdfld_restore_display_registers(struct drm_device
*dev
, int pipe
)
362 /* To get panel out of ULPS mode */
363 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
364 struct mdfld_dsi_config
*dsi_config
= NULL
;
371 u32 dpll_reg
= MRST_DPLL_A
;
372 u32 fp_reg
= MRST_FPA0
;
373 u32 pipeconf_reg
= PIPEACONF
;
374 u32 htot_reg
= HTOTAL_A
;
375 u32 hblank_reg
= HBLANK_A
;
376 u32 hsync_reg
= HSYNC_A
;
377 u32 vtot_reg
= VTOTAL_A
;
378 u32 vblank_reg
= VBLANK_A
;
379 u32 vsync_reg
= VSYNC_A
;
380 u32 pipesrc_reg
= PIPEASRC
;
381 u32 dspstride_reg
= DSPASTRIDE
;
382 u32 dsplinoff_reg
= DSPALINOFF
;
383 u32 dsptileoff_reg
= DSPATILEOFF
;
384 u32 dspsize_reg
= DSPASIZE
;
385 u32 dsppos_reg
= DSPAPOS
;
386 u32 dspsurf_reg
= DSPASURF
;
387 u32 dspstatus_reg
= PIPEASTAT
;
389 u32 dspcntr_reg
= DSPACNTR
;
390 u32 palette_reg
= PALETTE_A
;
393 u32 dpll_val
= dev_priv
->saveDPLL_A
& ~DPLL_VCO_ENABLE
;
394 u32 fp_val
= dev_priv
->saveFPA0
;
395 u32 pipeconf_val
= dev_priv
->savePIPEACONF
;
396 u32 htot_val
= dev_priv
->saveHTOTAL_A
;
397 u32 hblank_val
= dev_priv
->saveHBLANK_A
;
398 u32 hsync_val
= dev_priv
->saveHSYNC_A
;
399 u32 vtot_val
= dev_priv
->saveVTOTAL_A
;
400 u32 vblank_val
= dev_priv
->saveVBLANK_A
;
401 u32 vsync_val
= dev_priv
->saveVSYNC_A
;
402 u32 pipesrc_val
= dev_priv
->savePIPEASRC
;
403 u32 dspstride_val
= dev_priv
->saveDSPASTRIDE
;
404 u32 dsplinoff_val
= dev_priv
->saveDSPALINOFF
;
405 u32 dsptileoff_val
= dev_priv
->saveDSPATILEOFF
;
406 u32 dspsize_val
= dev_priv
->saveDSPASIZE
;
407 u32 dsppos_val
= dev_priv
->saveDSPAPOS
;
408 u32 dspsurf_val
= dev_priv
->saveDSPASURF
;
409 u32 dspstatus_val
= dev_priv
->saveDSPASTATUS
;
410 u32 mipi_val
= dev_priv
->saveMIPI
;
411 u32 dspcntr_val
= dev_priv
->saveDSPACNTR
;
412 u32
*palette_val
= dev_priv
->save_palette_a
;
416 dsi_config
= dev_priv
->dsi_configs
[0];
420 dpll_reg
= MDFLD_DPLL_B
;
421 fp_reg
= MDFLD_DPLL_DIV0
;
422 pipeconf_reg
= PIPEBCONF
;
424 hblank_reg
= HBLANK_B
;
427 vblank_reg
= VBLANK_B
;
429 pipesrc_reg
= PIPEBSRC
;
430 dspstride_reg
= DSPBSTRIDE
;
431 dsplinoff_reg
= DSPBLINOFF
;
432 dsptileoff_reg
= DSPBTILEOFF
;
433 dspsize_reg
= DSPBSIZE
;
434 dsppos_reg
= DSPBPOS
;
435 dspsurf_reg
= DSPBSURF
;
436 dspcntr_reg
= DSPBCNTR
;
437 palette_reg
= PALETTE_B
;
438 dspstatus_reg
= PIPEBSTAT
;
441 dpll_val
= dev_priv
->saveDPLL_B
& ~DPLL_VCO_ENABLE
;
442 fp_val
= dev_priv
->saveFPB0
;
443 pipeconf_val
= dev_priv
->savePIPEBCONF
;
444 htot_val
= dev_priv
->saveHTOTAL_B
;
445 hblank_val
= dev_priv
->saveHBLANK_B
;
446 hsync_val
= dev_priv
->saveHSYNC_B
;
447 vtot_val
= dev_priv
->saveVTOTAL_B
;
448 vblank_val
= dev_priv
->saveVBLANK_B
;
449 vsync_val
= dev_priv
->saveVSYNC_B
;
450 pipesrc_val
= dev_priv
->savePIPEBSRC
;
451 dspstride_val
= dev_priv
->saveDSPBSTRIDE
;
452 dsplinoff_val
= dev_priv
->saveDSPBLINOFF
;
453 dsptileoff_val
= dev_priv
->saveDSPBTILEOFF
;
454 dspsize_val
= dev_priv
->saveDSPBSIZE
;
455 dsppos_val
= dev_priv
->saveDSPBPOS
;
456 dspsurf_val
= dev_priv
->saveDSPBSURF
;
457 dspcntr_val
= dev_priv
->saveDSPBCNTR
;
458 dspstatus_val
= dev_priv
->saveDSPBSTATUS
;
459 palette_val
= dev_priv
->save_palette_b
;
462 reg_offset
= MIPIC_REG_OFFSET
;
465 pipeconf_reg
= PIPECCONF
;
467 hblank_reg
= HBLANK_C
;
470 vblank_reg
= VBLANK_C
;
472 pipesrc_reg
= PIPECSRC
;
473 dspstride_reg
= DSPCSTRIDE
;
474 dsplinoff_reg
= DSPCLINOFF
;
475 dsptileoff_reg
= DSPCTILEOFF
;
476 dspsize_reg
= DSPCSIZE
;
477 dsppos_reg
= DSPCPOS
;
478 dspsurf_reg
= DSPCSURF
;
480 dspcntr_reg
= DSPCCNTR
;
481 palette_reg
= PALETTE_C
;
482 dspstatus_reg
= PIPECSTAT
;
485 pipeconf_val
= dev_priv
->savePIPECCONF
;
486 htot_val
= dev_priv
->saveHTOTAL_C
;
487 hblank_val
= dev_priv
->saveHBLANK_C
;
488 hsync_val
= dev_priv
->saveHSYNC_C
;
489 vtot_val
= dev_priv
->saveVTOTAL_C
;
490 vblank_val
= dev_priv
->saveVBLANK_C
;
491 vsync_val
= dev_priv
->saveVSYNC_C
;
492 pipesrc_val
= dev_priv
->savePIPECSRC
;
493 dspstride_val
= dev_priv
->saveDSPCSTRIDE
;
494 dsplinoff_val
= dev_priv
->saveDSPCLINOFF
;
495 dsptileoff_val
= dev_priv
->saveDSPCTILEOFF
;
496 dspsize_val
= dev_priv
->saveDSPCSIZE
;
497 dsppos_val
= dev_priv
->saveDSPCPOS
;
498 dspsurf_val
= dev_priv
->saveDSPCSURF
;
499 dspstatus_val
= dev_priv
->saveDSPCSTATUS
;
500 mipi_val
= dev_priv
->saveMIPI_C
;
501 dspcntr_val
= dev_priv
->saveDSPCCNTR
;
502 palette_val
= dev_priv
->save_palette_c
;
504 dsi_config
= dev_priv
->dsi_configs
[1];
507 DRM_ERROR("%s, invalid pipe number.\n", __func__
);
511 /* Make sure VGA plane is off. it initializes to on after reset!*/
512 PSB_WVDC32(0x80000000, VGACNTRL
);
514 PSB_WVDC32(dpll_val
& ~DPLL_VCO_ENABLE
, dpll_reg
);
515 PSB_RVDC32(dpll_reg
);
517 PSB_WVDC32(fp_val
, fp_reg
);
519 dpll
= PSB_RVDC32(dpll_reg
);
521 if (!(dpll
& DPLL_VCO_ENABLE
)) {
523 /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
524 if (dpll
& MDFLD_PWR_GATE_EN
) {
525 dpll
&= ~MDFLD_PWR_GATE_EN
;
526 PSB_WVDC32(dpll
, dpll_reg
);
527 udelay(500); /* FIXME: 1 ? */
530 PSB_WVDC32(fp_val
, fp_reg
);
531 PSB_WVDC32(dpll_val
, dpll_reg
);
532 /* FIXME_MDFLD PO - change 500 to 1 after PO */
535 dpll_val
|= DPLL_VCO_ENABLE
;
536 PSB_WVDC32(dpll_val
, dpll_reg
);
537 PSB_RVDC32(dpll_reg
);
539 /* wait for DSI PLL to lock */
540 while ((timeout
< 20000) && !(PSB_RVDC32(pipeconf_reg
) & PIPECONF_DSIPLL_LOCK
)) {
545 if (timeout
== 20000) {
546 DRM_ERROR("%s, can't lock DSIPLL.\n",
553 PSB_WVDC32(htot_val
, htot_reg
);
554 PSB_WVDC32(hblank_val
, hblank_reg
);
555 PSB_WVDC32(hsync_val
, hsync_reg
);
556 PSB_WVDC32(vtot_val
, vtot_reg
);
557 PSB_WVDC32(vblank_val
, vblank_reg
);
558 PSB_WVDC32(vsync_val
, vsync_reg
);
559 PSB_WVDC32(pipesrc_val
, pipesrc_reg
);
560 PSB_WVDC32(dspstatus_val
, dspstatus_reg
);
562 /* Set up the plane */
563 PSB_WVDC32(dspstride_val
, dspstride_reg
);
564 PSB_WVDC32(dsplinoff_val
, dsplinoff_reg
);
565 PSB_WVDC32(dsptileoff_val
, dsptileoff_reg
);
566 PSB_WVDC32(dspsize_val
, dspsize_reg
);
567 PSB_WVDC32(dsppos_val
, dsppos_reg
);
568 PSB_WVDC32(dspsurf_val
, dspsurf_reg
);
571 PSB_WVDC32(dev_priv
->savePFIT_CONTROL
, PFIT_CONTROL
);
572 PSB_WVDC32(dev_priv
->savePFIT_PGM_RATIOS
, PFIT_PGM_RATIOS
);
573 PSB_WVDC32(dev_priv
->saveHDMIPHYMISCCTL
, HDMIPHYMISCCTL
);
574 PSB_WVDC32(dev_priv
->saveHDMIB_CONTROL
, HDMIB_CONTROL
);
577 /* Set up pipe related registers */
578 PSB_WVDC32(mipi_val
, mipi_reg
);
579 /* Setup MIPI adapter + MIPI IP registers */
580 mdfld_dsi_controller_init(dsi_config
, pipe
);
583 /* Enable the plane */
584 PSB_WVDC32(dspcntr_val
, dspcntr_reg
);
586 /* Enable the pipe */
587 PSB_WVDC32(pipeconf_val
, pipeconf_reg
);
589 for (i
= 0; i
< 256; i
++)
590 PSB_WVDC32(palette_val
[i
], palette_reg
+ (i
<<2));
593 if (!mdfld_panel_dpi(dev
))
594 mdfld_enable_te(dev
, pipe
);
599 * mdfld_restore_cursor_overlay_registers - restore cursor
602 * Restore the cursor and overlay state that was saved earlier
604 static int mdfld_restore_cursor_overlay_registers(struct drm_device
*dev
)
606 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
608 /* Enable Cursor A */
609 PSB_WVDC32(dev_priv
->saveDSPACURSOR_CTRL
, CURACNTR
);
610 PSB_WVDC32(dev_priv
->saveDSPACURSOR_POS
, CURAPOS
);
611 PSB_WVDC32(dev_priv
->saveDSPACURSOR_BASE
, CURABASE
);
613 PSB_WVDC32(dev_priv
->saveDSPBCURSOR_CTRL
, CURBCNTR
);
614 PSB_WVDC32(dev_priv
->saveDSPBCURSOR_POS
, CURBPOS
);
615 PSB_WVDC32(dev_priv
->saveDSPBCURSOR_BASE
, CURBBASE
);
617 PSB_WVDC32(dev_priv
->saveDSPCCURSOR_CTRL
, CURCCNTR
);
618 PSB_WVDC32(dev_priv
->saveDSPCCURSOR_POS
, CURCPOS
);
619 PSB_WVDC32(dev_priv
->saveDSPCCURSOR_BASE
, CURCBASE
);
621 /* Restore HW overlay */
622 PSB_WVDC32(dev_priv
->saveOV_OVADD
, OV_OVADD
);
623 PSB_WVDC32(dev_priv
->saveOV_OGAMC0
, OV_OGAMC0
);
624 PSB_WVDC32(dev_priv
->saveOV_OGAMC1
, OV_OGAMC1
);
625 PSB_WVDC32(dev_priv
->saveOV_OGAMC2
, OV_OGAMC2
);
626 PSB_WVDC32(dev_priv
->saveOV_OGAMC3
, OV_OGAMC3
);
627 PSB_WVDC32(dev_priv
->saveOV_OGAMC4
, OV_OGAMC4
);
628 PSB_WVDC32(dev_priv
->saveOV_OGAMC5
, OV_OGAMC5
);
630 PSB_WVDC32(dev_priv
->saveOV_OVADD_C
, OV_OVADD
+ OV_C_OFFSET
);
631 PSB_WVDC32(dev_priv
->saveOV_OGAMC0_C
, OV_OGAMC0
+ OV_C_OFFSET
);
632 PSB_WVDC32(dev_priv
->saveOV_OGAMC1_C
, OV_OGAMC1
+ OV_C_OFFSET
);
633 PSB_WVDC32(dev_priv
->saveOV_OGAMC2_C
, OV_OGAMC2
+ OV_C_OFFSET
);
634 PSB_WVDC32(dev_priv
->saveOV_OGAMC3_C
, OV_OGAMC3
+ OV_C_OFFSET
);
635 PSB_WVDC32(dev_priv
->saveOV_OGAMC4_C
, OV_OGAMC4
+ OV_C_OFFSET
);
636 PSB_WVDC32(dev_priv
->saveOV_OGAMC5_C
, OV_OGAMC5
+ OV_C_OFFSET
);
642 * mdfld_save_display_registers - save registers lost on suspend
643 * @dev: our DRM device
645 * Save the state we need in order to be able to restore the interface
646 * upon resume from suspend
648 static int mdfld_save_registers(struct drm_device
*dev
)
650 /* FIXME: We need to shut down panels here if using them
651 and once the right bits are merged */
652 mdfld_save_cursor_overlay_registers(dev
);
653 mdfld_save_display_registers(dev
, 0);
654 mdfld_save_display_registers(dev
, 0);
655 mdfld_save_display_registers(dev
, 2);
656 mdfld_save_display_registers(dev
, 1);
657 mdfld_disable_crtc(dev
, 0);
658 mdfld_disable_crtc(dev
, 2);
659 mdfld_disable_crtc(dev
, 1);
664 * mdfld_restore_display_registers - restore lost register state
665 * @dev: our DRM device
667 * Restore register state that was lost during suspend and resume.
669 static int mdfld_restore_registers(struct drm_device
*dev
)
671 mdfld_restore_display_registers(dev
, 1);
672 mdfld_restore_display_registers(dev
, 0);
673 mdfld_restore_display_registers(dev
, 2);
674 mdfld_restore_cursor_overlay_registers(dev
);
678 static int mdfld_power_down(struct drm_device
*dev
)
684 static int mdfld_power_up(struct drm_device
*dev
)
690 const struct psb_ops mdfld_chip_ops
= {
695 .sgx_offset
= MRST_SGX_OFFSET
,
697 .chip_setup
= mid_chip_setup
,
699 .crtc_helper
= &mdfld_helper_funcs
,
700 .crtc_funcs
= &mdfld_intel_crtc_funcs
,
702 .output_init
= mdfld_output_init
,
704 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
705 .backlight_init
= mdfld_backlight_init
,
708 .init_pm
= mdfld_init_pm
,
709 .save_regs
= mdfld_save_registers
,
710 .restore_regs
= mdfld_restore_registers
,
711 .power_down
= mdfld_power_down
,
712 .power_up
= mdfld_power_up
,