GFX-Display:dynamic caculate DSI clock according mode
[platform/kernel/kernel-mfld-blackbay.git] / drivers / staging / mrst / drv / psb_powermgmt.c
1 /**************************************************************************
2  * Copyright (c) 2009, 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  *
28  */
29 #include "psb_powermgmt.h"
30 #include "psb_drv.h"
31 #include "psb_intel_reg.h"
32 #include "psb_msvdx.h"
33 #include "lnc_topaz.h"
34 #include "pnw_topaz.h"
35 #include "mdfld_gl3.h"
36 #include <linux/mutex.h>
37 #include "lnc_topaz_hw_reg.h"
38 #include "mdfld_dsi_dbi.h"
39 #include "mdfld_dsi_dbi_dpu.h"
40 #include <asm/intel_scu_ipc.h>
41 #include "psb_intel_hdmi.h"
42 #include "mdfld_ti_tpd.h"
43 #ifdef CONFIG_GFX_RTPM
44 #include <linux/pm_runtime.h>
45 #endif
46
47 #include <linux/earlysuspend.h>
48
49 #undef OSPM_GFX_DPK
50 #define SCU_CMD_VPROG2  0xe3
51
52 struct drm_device *gpDrmDevice = NULL;
53 static struct mutex g_ospm_mutex;
54 static bool gbSuspendInProgress = false;
55 static bool gbResumeInProgress = false;
56 static int g_hw_power_status_mask;
57 static atomic_t g_display_access_count;
58 static atomic_t g_graphics_access_count;
59 static atomic_t g_videoenc_access_count;
60 static atomic_t g_videodec_access_count;
61 extern u32 DISP_PLANEB_STATUS;
62
63 static bool gbSuspended = false;
64 bool gbgfxsuspended = false;
65
66 void acquire_ospm_lock(void)
67 {
68         mutex_lock(&g_ospm_mutex);
69 }
70
71 void release_ospm_lock(void)
72 {
73         mutex_unlock(&g_ospm_mutex);
74 }
75 /*
76  * gfx_early_suspend
77  *
78  */
79 static void gfx_early_suspend(struct early_suspend *h);
80 static void gfx_late_resume(struct early_suspend *h);
81
82 static struct early_suspend gfx_early_suspend_desc = {
83         .level = EARLY_SUSPEND_LEVEL_DISABLE_FB,
84         .suspend = gfx_early_suspend,
85         .resume = gfx_late_resume,
86 };
87
88 static int ospm_runtime_pm_topaz_suspend(struct drm_device *dev)
89 {
90         int ret = 0;
91         struct drm_psb_private *dev_priv = dev->dev_private;
92         struct topaz_private *topaz_priv = dev_priv->topaz_private;
93         struct pnw_topaz_private *pnw_topaz_priv = dev_priv->topaz_private;
94         struct psb_video_ctx *pos, *n;
95         int encode_ctx = 0, encode_running = 0;
96
97
98         list_for_each_entry_safe(pos, n, &dev_priv->video_ctx, head) {
99                 int entrypoint = pos->ctx_type & 0xff;
100                 if (entrypoint == VAEntrypointEncSlice ||
101                     entrypoint == VAEntrypointEncPicture) {
102                         encode_ctx = 1;
103                         break;
104                 }
105         }
106
107         /* have encode context, but not started, or is just closed */
108         if (encode_ctx && dev_priv->topaz_ctx)
109                 encode_running = 1;
110
111         if (!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND))
112                 goto out;
113
114         if (atomic_read(&g_videoenc_access_count)) {
115                 ret = -1;
116                 goto out;
117         }
118
119 #ifdef CONFIG_MDFD_VIDEO_DECODE
120         if (IS_MRST(dev)) {
121                 if (lnc_check_topaz_idle(dev)) {
122                         ret = -2;
123                         goto out;
124                 }
125         }
126
127         if (IS_MDFLD(dev)) {
128                 if (pnw_check_topaz_idle(dev)) {
129                         ret = -2;
130                         goto out;
131                 }
132         }
133         psb_irq_uninstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND);
134         if (IS_MRST(dev)) {
135                 if (encode_running)
136                         lnc_topaz_save_mtx_state(gpDrmDevice);
137                 TOPAZ_NEW_PMSTATE(dev, topaz_priv, PSB_PMSTATE_POWERDOWN);
138         }
139
140         if (IS_MDFLD(dev)) {
141                 if (encode_running)
142                         pnw_topaz_save_mtx_state(gpDrmDevice);
143                 PNW_TOPAZ_NEW_PMSTATE(dev, pnw_topaz_priv,
144                                 PSB_PMSTATE_POWERDOWN);
145         }
146 #endif
147         ospm_power_island_down(OSPM_VIDEO_ENC_ISLAND);
148 out:
149         return ret;
150 }
151
152
153 static int ospm_runtime_pm_msvdx_resume(struct drm_device *dev)
154 {
155         struct drm_psb_private *dev_priv = dev->dev_private;
156         struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
157
158         /*printk(KERN_ALERT "ospm_runtime_pm_msvdx_resume\n");*/
159
160 #ifdef CONFIG_MDFD_VIDEO_DECODE
161         MSVDX_NEW_PMSTATE(dev, msvdx_priv, PSB_PMSTATE_POWERUP);
162
163         psb_msvdx_restore_context(dev);
164 #endif
165
166         return 0;
167 }
168
169 static int ospm_runtime_pm_topaz_resume(struct drm_device *dev)
170 {
171         struct drm_psb_private *dev_priv = dev->dev_private;
172         struct topaz_private *topaz_priv = dev_priv->topaz_private;
173         struct pnw_topaz_private *pnw_topaz_priv = dev_priv->topaz_private;
174         struct psb_video_ctx *pos, *n;
175         int encode_ctx = 0, encode_running = 0;
176
177         /*printk(KERN_ALERT "ospm_runtime_pm_topaz_resume\n");*/
178
179         list_for_each_entry_safe(pos, n, &dev_priv->video_ctx, head) {
180                 int entrypoint = pos->ctx_type & 0xff;
181                 if (entrypoint == VAEntrypointEncSlice ||
182                     entrypoint == VAEntrypointEncPicture) {
183                         encode_ctx = 1;
184                         break;
185                 }
186         }
187
188         /* have encode context, but not started, or is just closed */
189         if (encode_ctx && dev_priv->topaz_ctx)
190                 encode_running = 1;
191
192         if (encode_ctx)
193                 PSB_DEBUG_PM("Topaz: has encode context, running=%d\n",
194                              encode_running);
195         else
196                 PSB_DEBUG_PM("Topaz: no encode running\n");
197
198 #ifdef CONFIG_MDFD_VIDEO_DECODE
199         if (IS_MRST(dev)) {
200                 if (encode_running) { /* has encode session running */
201                         psb_irq_uninstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND);
202                         lnc_topaz_restore_mtx_state(gpDrmDevice);
203                 }
204                 TOPAZ_NEW_PMSTATE(dev, topaz_priv, PSB_PMSTATE_POWERUP);
205         }
206
207         if (IS_MDFLD(dev)) {
208                 if (encode_running) { /* has encode session running */
209                         psb_irq_uninstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND);
210                         pnw_topaz_restore_mtx_state(gpDrmDevice);
211                 }
212                 PNW_TOPAZ_NEW_PMSTATE(dev, pnw_topaz_priv, PSB_PMSTATE_POWERUP);
213         }
214 #endif
215         return 0;
216 }
217
218 #ifdef FIX_OSPM_POWER_DOWN
219 void ospm_apm_power_down_msvdx(struct drm_device *dev)
220 {
221         return;
222         mutex_lock(&g_ospm_mutex);
223
224         if (atomic_read(&g_videodec_access_count))
225                 goto out;
226         if (psb_check_msvdx_idle(dev))
227                 goto out;
228
229         gbSuspendInProgress = true;
230         psb_msvdx_save_context(dev);
231 #ifdef FIXME_MRST_VIDEO_DEC
232         ospm_power_island_down(OSPM_VIDEO_DEC_ISLAND);
233 #endif
234         gbSuspendInProgress = false;
235 out:
236         mutex_unlock(&g_ospm_mutex);
237         return;
238 }
239
240 void ospm_apm_power_down_topaz(struct drm_device *dev)
241 {
242         return; /* todo for OSPM */
243
244         mutex_lock(&g_ospm_mutex);
245
246         if (atomic_read(&g_videoenc_access_count))
247                 goto out;
248         if (lnc_check_topaz_idle(dev))
249                 goto out;
250
251         gbSuspendInProgress = true;
252         lnc_topaz_save_mtx_state(dev);
253         ospm_power_island_down(OSPM_VIDEO_ENC_ISLAND);
254         gbSuspendInProgress = false;
255 out:
256         mutex_unlock(&g_ospm_mutex);
257         return;
258 }
259 #else
260 void ospm_apm_power_down_msvdx(struct drm_device *dev)
261 {
262         struct drm_psb_private *dev_priv = dev->dev_private;
263         struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
264
265         mutex_lock(&g_ospm_mutex);
266         if (!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND))
267                 goto out;
268
269         if (atomic_read(&g_videodec_access_count))
270                 goto out;
271 #ifdef CONFIG_MDFD_VIDEO_DECODE
272         if (psb_check_msvdx_idle(dev))
273                 goto out;
274
275         gbSuspendInProgress = true;
276         psb_msvdx_save_context(dev);
277 #endif
278         ospm_power_island_down(OSPM_VIDEO_DEC_ISLAND);
279 #ifdef CONFIG_MDFD_GL3
280         /* Power off GL3 */
281         ospm_power_island_down(OSPM_GL3_CACHE_ISLAND);
282 #endif
283         gbSuspendInProgress = false;
284         MSVDX_NEW_PMSTATE(dev, msvdx_priv, PSB_PMSTATE_POWERDOWN);
285 out:
286         mutex_unlock(&g_ospm_mutex);
287         return;
288 }
289
290 void ospm_apm_power_down_topaz(struct drm_device *dev)
291 {
292         struct drm_psb_private *dev_priv = dev->dev_private;
293         struct topaz_private *topaz_priv = dev_priv->topaz_private;
294         struct pnw_topaz_private *pnw_topaz_priv = dev_priv->topaz_private;
295
296         mutex_lock(&g_ospm_mutex);
297
298         if (!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND))
299                 goto out;
300         if (atomic_read(&g_videoenc_access_count))
301                 goto out;
302 #ifdef CONFIG_MDFD_VIDEO_DECODE
303         if (IS_MRST(dev))
304                 if (lnc_check_topaz_idle(dev))
305                         goto out;
306         if (IS_MDFLD(dev))
307                 if (pnw_check_topaz_idle(dev))
308                         goto out;
309         gbSuspendInProgress = true;
310         if (IS_MRST(dev)) {
311                 psb_irq_uninstall_islands(dev, OSPM_VIDEO_ENC_ISLAND);
312                 lnc_topaz_save_mtx_state(dev);
313                 TOPAZ_NEW_PMSTATE(dev, topaz_priv, PSB_PMSTATE_POWERDOWN);
314         }
315         if (IS_MDFLD(dev)) {
316                 psb_irq_uninstall_islands(dev, OSPM_VIDEO_ENC_ISLAND);
317                 pnw_topaz_save_mtx_state(gpDrmDevice);
318                 PNW_TOPAZ_NEW_PMSTATE(dev, pnw_topaz_priv, PSB_PMSTATE_POWERDOWN);
319         }
320         ospm_power_island_down(OSPM_VIDEO_ENC_ISLAND);
321 #endif
322
323 #ifdef CONFIG_MDFD_GL3
324         /* Power off GL3 */
325         if (IS_MDFLD(dev))
326                 ospm_power_island_down(OSPM_GL3_CACHE_ISLAND);
327 #endif
328
329         gbSuspendInProgress = false;
330 out:
331         mutex_unlock(&g_ospm_mutex);
332         return;
333 }
334 #endif
335 /*
336  * ospm_power_init
337  *
338  * Description: Initialize this ospm power management module
339  */
340 void ospm_power_init(struct drm_device *dev)
341 {
342         struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private;
343         unsigned long flags;
344
345         gpDrmDevice = dev;
346
347         mutex_init(&g_ospm_mutex);
348         spin_lock_init(&dev_priv->ospm_lock);
349
350         dev_priv->drm_psb_widi = 0;
351         spin_lock_irqsave(&dev_priv->ospm_lock, flags);
352         g_hw_power_status_mask = OSPM_ALL_ISLANDS;
353         spin_unlock_irqrestore(&dev_priv->ospm_lock, flags);
354
355         atomic_set(&g_display_access_count, 0);
356         atomic_set(&g_graphics_access_count, 0);
357         atomic_set(&g_videoenc_access_count, 0);
358         atomic_set(&g_videodec_access_count, 0);
359
360         register_early_suspend(&gfx_early_suspend_desc);
361
362 #ifdef OSPM_STAT
363         dev_priv->graphics_state = PSB_PWR_STATE_ON;
364         dev_priv->gfx_last_mode_change = jiffies;
365         dev_priv->gfx_on_time = 0;
366         dev_priv->gfx_off_time = 0;
367 #endif
368
369
370 }
371
372 /*
373  * ospm_power_uninit
374  *
375  * Description: Uninitialize this ospm power management module
376  */
377 void ospm_power_uninit(void)
378 {
379     unregister_early_suspend(&gfx_early_suspend_desc);
380     mutex_destroy(&g_ospm_mutex);
381 #ifdef CONFIG_GFX_RTPM
382         pm_runtime_get_noresume(&gpDrmDevice->pdev->dev);
383 #endif
384 }
385 /*
386 * ospm_post_init
387 *
388 * Description: Power gate unused GFX & Display islands.
389 */
390 void ospm_post_init(struct drm_device *dev)
391 {
392         u32 dc_islands  = 0;
393         struct drm_psb_private *dev_priv =
394                 (struct drm_psb_private *)dev->dev_private;
395
396 #ifndef CONFIG_MDFD_GL3
397         ospm_power_island_down(OSPM_GL3_CACHE_ISLAND);
398 #endif
399         /*Save & Power gate un-used display islands.*/
400         mdfld_save_display(dev);
401
402         if (!(dev_priv->panel_desc & DISPLAY_A))
403                 dc_islands |= OSPM_DISPLAY_A_ISLAND;
404
405         if (!(dev_priv->panel_desc & DISPLAY_B))
406                 dc_islands |= OSPM_DISPLAY_B_ISLAND;
407
408         if (!(dev_priv->panel_desc & DISPLAY_C))
409                 dc_islands |= OSPM_DISPLAY_C_ISLAND;
410
411         if (!(dev_priv->panel_desc))
412                 dc_islands |= OSPM_MIPI_ISLAND;
413
414 #ifdef OSPM_GFX_DPK
415         printk(KERN_ALERT
416                 "%s dc_islands: %x to be powered OFF\n",
417                 __func__, dc_islands);
418 #endif
419         /*
420         If pmu_nc_set_power_state fails then accessing HW
421         reg would result in a crash - IERR/Fabric error.
422         */
423         if (pmu_nc_set_power_state(dc_islands,
424                 OSPM_ISLAND_DOWN, OSPM_REG_TYPE))
425                 BUG();
426
427 /* if HDMI is disabled in the kernel .config, then we want to
428 disable these MSIC power rails permanently.  */
429 #ifndef CONFIG_MDFD_HDMI
430         if (IS_MDFLD_OLD(dev)) {
431                 /* turn off HDMI power rails */
432                 intel_scu_ipc_iowrite8(MSIC_VHDMICNT, VHDMI_OFF);
433                 intel_scu_ipc_iowrite8(MSIC_VCC330CNT, VCC330_OFF);
434         }
435 #endif
436
437 }
438
439 /*
440  * save_display_registers
441  *
442  * Description: We are going to suspend so save current display
443  * register state.
444  */
445 static int save_display_registers(struct drm_device *dev)
446 {
447         struct drm_psb_private *dev_priv = dev->dev_private;
448         struct drm_crtc * crtc;
449         struct drm_connector * connector;
450         int i;
451
452         /* Display arbitration control + watermarks */
453         dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
454         dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1);
455         dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2);
456         dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3);
457         dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4);
458         dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5);
459         dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
460         dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
461
462         if (IS_MRST(dev)) {
463                 /* Pipe & plane A info */
464                 dev_priv->savePIPEACONF = PSB_RVDC32(PIPEACONF);
465                 dev_priv->savePIPEASRC = PSB_RVDC32(PIPEASRC);
466                 dev_priv->saveFPA0 = PSB_RVDC32(MRST_FPA0);
467                 dev_priv->saveFPA1 = PSB_RVDC32(MRST_FPA1);
468                 dev_priv->saveDPLL_A = PSB_RVDC32(MRST_DPLL_A);
469                 dev_priv->saveHTOTAL_A = PSB_RVDC32(HTOTAL_A);
470                 dev_priv->saveHBLANK_A = PSB_RVDC32(HBLANK_A);
471                 dev_priv->saveHSYNC_A = PSB_RVDC32(HSYNC_A);
472                 dev_priv->saveVTOTAL_A = PSB_RVDC32(VTOTAL_A);
473                 dev_priv->saveVBLANK_A = PSB_RVDC32(VBLANK_A);
474                 dev_priv->saveVSYNC_A = PSB_RVDC32(VSYNC_A);
475                 dev_priv->saveBCLRPAT_A = PSB_RVDC32(BCLRPAT_A);
476                 dev_priv->saveDSPACNTR = PSB_RVDC32(DSPACNTR);
477                 dev_priv->saveDSPASTRIDE = PSB_RVDC32(DSPASTRIDE);
478                 dev_priv->saveDSPAADDR = PSB_RVDC32(DSPABASE);
479                 dev_priv->saveDSPASURF = PSB_RVDC32(DSPASURF);
480                 dev_priv->saveDSPALINOFF = PSB_RVDC32(DSPALINOFF);
481                 dev_priv->saveDSPATILEOFF = PSB_RVDC32(DSPATILEOFF);
482
483                 /*save cursor regs*/
484                 dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
485                 dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
486                 dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);
487
488                 /*save palette (gamma) */
489                 for (i = 0; i < 256; i++)
490                         dev_priv->save_palette_a[i] = PSB_RVDC32(PALETTE_A + (i<<2));
491
492                 /*save performance state*/
493                 dev_priv->savePERF_MODE = PSB_RVDC32(MRST_PERF_MODE);
494
495                 /* LVDS state */
496                 dev_priv->savePP_CONTROL = PSB_RVDC32(PP_CONTROL);
497                 dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
498                 dev_priv->savePFIT_AUTO_RATIOS = PSB_RVDC32(PFIT_AUTO_RATIOS);
499                 dev_priv->saveBLC_PWM_CTL = PSB_RVDC32(BLC_PWM_CTL);
500                 dev_priv->saveBLC_PWM_CTL2 = PSB_RVDC32(BLC_PWM_CTL2);
501                 dev_priv->saveLVDS = PSB_RVDC32(LVDS);
502                 dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
503                 dev_priv->savePP_ON_DELAYS = PSB_RVDC32(LVDSPP_ON);
504                 dev_priv->savePP_OFF_DELAYS = PSB_RVDC32(LVDSPP_OFF);
505                 dev_priv->savePP_DIVISOR = PSB_RVDC32(PP_CYCLE);
506
507                 /* HW overlay */
508                 dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD);
509                 dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0);
510                 dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1);
511                 dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2);
512                 dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3);
513                 dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4);
514                 dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
515
516                 /* MIPI DSI */
517                 dev_priv->saveMIPI = PSB_RVDC32(MIPI);
518                 dev_priv->saveDEVICE_READY_REG = PSB_RVDC32(DEVICE_READY_REG);
519                 dev_priv->saveINTR_EN_REG  = PSB_RVDC32(INTR_EN_REG);
520                 dev_priv->saveDSI_FUNC_PRG_REG  = PSB_RVDC32(DSI_FUNC_PRG_REG);
521                 dev_priv->saveHS_TX_TIMEOUT_REG = PSB_RVDC32(HS_TX_TIMEOUT_REG);
522                 dev_priv->saveLP_RX_TIMEOUT_REG = PSB_RVDC32(LP_RX_TIMEOUT_REG);
523                 dev_priv->saveTURN_AROUND_TIMEOUT_REG =
524                         PSB_RVDC32(TURN_AROUND_TIMEOUT_REG);
525                 dev_priv->saveDEVICE_RESET_REG = PSB_RVDC32(DEVICE_RESET_REG);
526                 dev_priv->saveDPI_RESOLUTION_REG =
527                         PSB_RVDC32(DPI_RESOLUTION_REG);
528                 dev_priv->saveHORIZ_SYNC_PAD_COUNT_REG =
529                         PSB_RVDC32(HORIZ_SYNC_PAD_COUNT_REG);
530                 dev_priv->saveHORIZ_BACK_PORCH_COUNT_REG =
531                         PSB_RVDC32(HORIZ_BACK_PORCH_COUNT_REG);
532                 dev_priv->saveHORIZ_FRONT_PORCH_COUNT_REG =
533                         PSB_RVDC32(HORIZ_FRONT_PORCH_COUNT_REG);
534                 dev_priv->saveHORIZ_ACTIVE_AREA_COUNT_REG =
535                         PSB_RVDC32(HORIZ_ACTIVE_AREA_COUNT_REG);
536                 dev_priv->saveVERT_SYNC_PAD_COUNT_REG =
537                         PSB_RVDC32(VERT_SYNC_PAD_COUNT_REG);
538                 dev_priv->saveVERT_BACK_PORCH_COUNT_REG =
539                         PSB_RVDC32(VERT_BACK_PORCH_COUNT_REG);
540                 dev_priv->saveVERT_FRONT_PORCH_COUNT_REG =
541                         PSB_RVDC32(VERT_FRONT_PORCH_COUNT_REG);
542                 dev_priv->saveHIGH_LOW_SWITCH_COUNT_REG =
543                         PSB_RVDC32(HIGH_LOW_SWITCH_COUNT_REG);
544                 dev_priv->saveINIT_COUNT_REG = PSB_RVDC32(INIT_COUNT_REG);
545                 dev_priv->saveMAX_RET_PAK_REG = PSB_RVDC32(MAX_RET_PAK_REG);
546                 dev_priv->saveVIDEO_FMT_REG = PSB_RVDC32(VIDEO_FMT_REG);
547                 dev_priv->saveEOT_DISABLE_REG = PSB_RVDC32(EOT_DISABLE_REG);
548                 dev_priv->saveLP_BYTECLK_REG = PSB_RVDC32(LP_BYTECLK_REG);
549                 dev_priv->saveHS_LS_DBI_ENABLE_REG =
550                         PSB_RVDC32(HS_LS_DBI_ENABLE_REG);
551                 dev_priv->saveTXCLKESC_REG = PSB_RVDC32(TXCLKESC_REG);
552                 dev_priv->saveDPHY_PARAM_REG  = PSB_RVDC32(DPHY_PARAM_REG);
553                 dev_priv->saveMIPI_CONTROL_REG = PSB_RVDC32(MIPI_CONTROL_REG);
554
555                 /* DPST registers */
556                 dev_priv->saveHISTOGRAM_INT_CONTROL_REG = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
557                 dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
558                 dev_priv->savePWM_CONTROL_LOGIC = PSB_RVDC32(PWM_CONTROL_LOGIC);
559
560
561         } else { /*PSB*/
562                 /*save crtc and output state*/
563                 mutex_lock(&dev->mode_config.mutex);
564                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
565                         if(drm_helper_crtc_in_use(crtc)) {
566                                 crtc->funcs->save(crtc);
567                         }
568                 }
569
570                 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
571                         connector->funcs->save(connector);
572                 }
573                 mutex_unlock(&dev->mode_config.mutex);
574         }
575
576         /* Interrupt state */
577         /*
578          * Handled in psb_irq.c
579          */
580
581         return 0;
582 }
583
584 /*
585  * restore_display_registers
586  *
587  * Description: We are going to resume so restore display register state.
588  */
589 static int restore_display_registers(struct drm_device *dev)
590 {
591         struct drm_psb_private *dev_priv = dev->dev_private;
592         struct drm_crtc * crtc;
593         struct drm_connector * connector;
594         unsigned long i, pp_stat;
595
596         /* Display arbitration + watermarks */
597         PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
598         PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1);
599         PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2);
600         PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3);
601         PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4);
602         PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5);
603         PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6);
604         PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT);
605
606         /*make sure VGA plane is off. it initializes to on after reset!*/
607         PSB_WVDC32(0x80000000, VGACNTRL);
608
609         if (IS_MRST(dev)) {
610                 /* set the plls */
611                 PSB_WVDC32(dev_priv->saveFPA0, MRST_FPA0);
612                 PSB_WVDC32(dev_priv->saveFPA1, MRST_FPA1);
613                 /* Actually enable it */
614                 PSB_WVDC32(dev_priv->saveDPLL_A, MRST_DPLL_A);
615                 DRM_UDELAY(150);
616
617                 /* Restore mode */
618                 PSB_WVDC32(dev_priv->saveHTOTAL_A, HTOTAL_A);
619                 PSB_WVDC32(dev_priv->saveHBLANK_A, HBLANK_A);
620                 PSB_WVDC32(dev_priv->saveHSYNC_A, HSYNC_A);
621                 PSB_WVDC32(dev_priv->saveVTOTAL_A, VTOTAL_A);
622                 PSB_WVDC32(dev_priv->saveVBLANK_A, VBLANK_A);
623                 PSB_WVDC32(dev_priv->saveVSYNC_A, VSYNC_A);
624                 PSB_WVDC32(dev_priv->savePIPEASRC, PIPEASRC);
625                 PSB_WVDC32(dev_priv->saveBCLRPAT_A, BCLRPAT_A);
626
627                 /*restore performance mode*/
628                 PSB_WVDC32(dev_priv->savePERF_MODE, MRST_PERF_MODE);
629
630                 /*enable the pipe*/
631                 if (dev_priv->iLVDS_enable)
632                         PSB_WVDC32(dev_priv->savePIPEACONF, PIPEACONF);
633
634                 /* Setup MIPI */
635                 PSB_WVDC32(dev_priv->saveINTR_EN_REG, INTR_EN_REG);
636                 PSB_WVDC32(dev_priv->saveDSI_FUNC_PRG_REG, DSI_FUNC_PRG_REG);
637                 PSB_WVDC32(dev_priv->saveHS_TX_TIMEOUT_REG, HS_TX_TIMEOUT_REG);
638                 PSB_WVDC32(dev_priv->saveLP_RX_TIMEOUT_REG, LP_RX_TIMEOUT_REG);
639                 PSB_WVDC32(dev_priv->saveTURN_AROUND_TIMEOUT_REG,
640                         TURN_AROUND_TIMEOUT_REG);
641                 PSB_WVDC32(dev_priv->saveDEVICE_RESET_REG, DEVICE_RESET_REG);
642                 PSB_WVDC32(dev_priv->saveDPI_RESOLUTION_REG,
643                         DPI_RESOLUTION_REG);
644                 PSB_WVDC32(dev_priv->saveHORIZ_SYNC_PAD_COUNT_REG,
645                         HORIZ_SYNC_PAD_COUNT_REG);
646                 PSB_WVDC32(dev_priv->saveHORIZ_BACK_PORCH_COUNT_REG,
647                         HORIZ_BACK_PORCH_COUNT_REG);
648                 PSB_WVDC32(dev_priv->saveHORIZ_FRONT_PORCH_COUNT_REG,
649                         HORIZ_FRONT_PORCH_COUNT_REG);
650                 PSB_WVDC32(dev_priv->saveHORIZ_ACTIVE_AREA_COUNT_REG,
651                         HORIZ_ACTIVE_AREA_COUNT_REG);
652                 PSB_WVDC32(dev_priv->saveVERT_SYNC_PAD_COUNT_REG,
653                         VERT_SYNC_PAD_COUNT_REG);
654                 PSB_WVDC32(dev_priv->saveVERT_BACK_PORCH_COUNT_REG,
655                         VERT_BACK_PORCH_COUNT_REG);
656                 PSB_WVDC32(dev_priv->saveVERT_FRONT_PORCH_COUNT_REG,
657                         VERT_FRONT_PORCH_COUNT_REG);
658                 PSB_WVDC32(dev_priv->saveHIGH_LOW_SWITCH_COUNT_REG,
659                         HIGH_LOW_SWITCH_COUNT_REG);
660                 PSB_WVDC32(dev_priv->saveINIT_COUNT_REG, INIT_COUNT_REG);
661                 PSB_WVDC32(dev_priv->saveMAX_RET_PAK_REG, MAX_RET_PAK_REG);
662                 PSB_WVDC32(dev_priv->saveVIDEO_FMT_REG, VIDEO_FMT_REG);
663                 PSB_WVDC32(dev_priv->saveEOT_DISABLE_REG, EOT_DISABLE_REG);
664                 PSB_WVDC32(dev_priv->saveLP_BYTECLK_REG, LP_BYTECLK_REG);
665                 PSB_WVDC32(dev_priv->saveHS_LS_DBI_ENABLE_REG,
666                         HS_LS_DBI_ENABLE_REG);
667                 PSB_WVDC32(dev_priv->saveTXCLKESC_REG, TXCLKESC_REG);
668                 PSB_WVDC32(dev_priv->saveDPHY_PARAM_REG, DPHY_PARAM_REG);
669                 PSB_WVDC32(dev_priv->saveMIPI_CONTROL_REG, MIPI_CONTROL_REG);
670
671                 /*set up the plane*/
672                 PSB_WVDC32(dev_priv->saveDSPALINOFF, DSPALINOFF);
673                 PSB_WVDC32(dev_priv->saveDSPASTRIDE, DSPASTRIDE);
674                 PSB_WVDC32(dev_priv->saveDSPATILEOFF, DSPATILEOFF);
675
676                 /* Enable the plane */
677                 PSB_WVDC32(dev_priv->saveDSPACNTR, DSPACNTR);
678                 PSB_WVDC32(dev_priv->saveDSPASURF, DSPASURF);
679
680                 /*Enable Cursor A*/
681                 PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
682                 PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
683                 PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);
684
685                 /* restore palette (gamma) */
686                 /*DRM_UDELAY(50000); */
687                 for (i = 0; i < 256; i++)
688                         PSB_WVDC32(dev_priv->save_palette_a[i], PALETTE_A + (i<<2));
689
690                 if (dev_priv->iLVDS_enable) {
691                         PSB_WVDC32(dev_priv->saveBLC_PWM_CTL2, BLC_PWM_CTL2);
692                         PSB_WVDC32(dev_priv->saveLVDS, LVDS); /*port 61180h*/
693                         PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
694                         PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
695                         PSB_WVDC32(dev_priv->savePFIT_AUTO_RATIOS, PFIT_AUTO_RATIOS);
696                         PSB_WVDC32(dev_priv->saveBLC_PWM_CTL, BLC_PWM_CTL);
697                         PSB_WVDC32(dev_priv->savePP_ON_DELAYS, LVDSPP_ON);
698                         PSB_WVDC32(dev_priv->savePP_OFF_DELAYS, LVDSPP_OFF);
699                         PSB_WVDC32(dev_priv->savePP_DIVISOR, PP_CYCLE);
700                         PSB_WVDC32(dev_priv->savePP_CONTROL, PP_CONTROL);
701                 } else {
702                         PSB_WVDC32(MIPI_PORT_EN | MIPI_BORDER_EN, MIPI); /*force on port*/
703                         PSB_WVDC32(1, DEVICE_READY_REG);/* force on to re-program */
704
705                         if (dev_priv->saveDEVICE_READY_REG) {
706                                 if ((REG_READ(INTR_STAT_REG) & SPL_PKT_SENT)) {
707                                         REG_WRITE(INTR_STAT_REG, SPL_PKT_SENT);
708                                 }
709
710                                 /*send turn on packet*/
711                                 PSB_WVDC32(DPI_TURN_ON, DPI_CONTROL_REG);
712
713                                 /*wait for special packet sent interrupt*/
714                                 mrst_wait_for_INTR_PKT_SENT(dev);
715
716                                 msleep(100);
717                         }
718
719                         if(dev_priv->init_drvIC)
720                                 dev_priv->init_drvIC(dev);
721                         PSB_WVDC32(dev_priv->saveMIPI, MIPI); /*port 61190h*/
722                         PSB_WVDC32(dev_priv->saveDEVICE_READY_REG, DEVICE_READY_REG);
723                         PSB_WVDC32(dev_priv->savePIPEACONF, PIPEACONF);
724                         PSB_WVDC32(dev_priv->saveBLC_PWM_CTL2, BLC_PWM_CTL2);
725                         PSB_WVDC32(dev_priv->saveBLC_PWM_CTL, BLC_PWM_CTL);
726                 }
727
728
729                 /*wait for cycle delay*/
730                 do {
731                         pp_stat = PSB_RVDC32(PP_STATUS);
732                 } while (pp_stat & 0x08000000);
733
734                 DRM_UDELAY(999);
735                 /*wait for panel power up*/
736                 do {
737                         pp_stat = PSB_RVDC32(PP_STATUS);
738                 } while (pp_stat & 0x10000000);
739
740                 /* restore HW overlay */
741                 PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD);
742                 PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0);
743                 PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1);
744                 PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2);
745                 PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3);
746                 PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4);
747                 PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
748
749                 /* DPST registers */
750                 PSB_WVDC32(dev_priv->saveHISTOGRAM_INT_CONTROL_REG, HISTOGRAM_INT_CONTROL);
751                 PSB_WVDC32(dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG, HISTOGRAM_LOGIC_CONTROL);
752                 PSB_WVDC32(dev_priv->savePWM_CONTROL_LOGIC, PWM_CONTROL_LOGIC);
753
754
755         } else { /*PSB*/
756                 mutex_lock(&dev->mode_config.mutex);
757                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
758                         if(drm_helper_crtc_in_use(crtc))
759                                 crtc->funcs->restore(crtc);
760                 }
761
762                 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
763                         connector->funcs->restore(connector);
764                 }
765                 mutex_unlock(&dev->mode_config.mutex);
766         }
767
768
769         /*Interrupt state*/
770         /*
771          * Handled in psb_irq.c
772          */
773
774         return 0;
775 }
776 /*
777  * mdfld_save_display_registers
778  *
779  * Description: We are going to suspend so save current display
780  * register state.
781  *
782  */
783 static int mdfld_save_display_registers (struct drm_device *dev, int pipe)
784 {
785         struct drm_psb_private *dev_priv = dev->dev_private;
786         int i;
787
788         /* regester */
789         u32 dpll_reg = MRST_DPLL_A;
790         u32 fp_reg = MRST_FPA0;
791         u32 pipeconf_reg = PIPEACONF;
792         u32 htot_reg = HTOTAL_A;
793         u32 hblank_reg = HBLANK_A;
794         u32 hsync_reg = HSYNC_A;
795         u32 vtot_reg = VTOTAL_A;
796         u32 vblank_reg = VBLANK_A;
797         u32 vsync_reg = VSYNC_A;
798         u32 pipesrc_reg = PIPEASRC;
799         u32 dspstride_reg = DSPASTRIDE;
800         u32 dsplinoff_reg = DSPALINOFF;
801         u32 dsptileoff_reg = DSPATILEOFF;
802         u32 dspsize_reg = DSPASIZE;
803         u32 dsppos_reg = DSPAPOS;
804         u32 dspsurf_reg = DSPASURF;
805         u32 mipi_reg = MIPI;
806         u32 dspcntr_reg = DSPACNTR;
807         u32 dspstatus_reg = PIPEASTAT;
808         u32 palette_reg = PALETTE_A;
809
810         /* pointer to values */
811         u32 *dpll_val = &dev_priv->saveDPLL_A;
812         u32 *fp_val = &dev_priv->saveFPA0;
813         u32 *pipeconf_val = &dev_priv->savePIPEACONF;
814         u32 *htot_val = &dev_priv->saveHTOTAL_A;
815         u32 *hblank_val = &dev_priv->saveHBLANK_A;
816         u32 *hsync_val = &dev_priv->saveHSYNC_A;
817         u32 *vtot_val = &dev_priv->saveVTOTAL_A;
818         u32 *vblank_val = &dev_priv->saveVBLANK_A;
819         u32 *vsync_val = &dev_priv->saveVSYNC_A;
820         u32 *pipesrc_val = &dev_priv->savePIPEASRC;
821         u32 *dspstride_val = &dev_priv->saveDSPASTRIDE;
822         u32 *dsplinoff_val = &dev_priv->saveDSPALINOFF;
823         u32 *dsptileoff_val = &dev_priv->saveDSPATILEOFF;
824         u32 *dspsize_val = &dev_priv->saveDSPASIZE;
825         u32 *dsppos_val = &dev_priv->saveDSPAPOS;
826         u32 *dspsurf_val = &dev_priv->saveDSPASURF;
827         u32 *mipi_val = &dev_priv->saveMIPI;
828         u32 *dspcntr_val = &dev_priv->saveDSPACNTR;
829         u32 *dspstatus_val = &dev_priv->saveDSPASTATUS;
830         u32 *palette_val = dev_priv->save_palette_a;
831         PSB_DEBUG_ENTRY("\n");
832
833         /**
834          * For MIPI panels, all plane/pipe/port/DSI controller values
835          * were already saved in dsi_hw_context, no need to save/restore
836          * for these registers.
837          * NOTE: only support TMD panel now, add support for other MIPI
838          * panels later
839          */
840 #ifndef CONFIG_SUPPORT_TOSHIBA_MIPI_DISPLAY
841 #ifndef CONFIG_SUPPORT_TOSHIBA_MIPI_LVDS_BRIDGE
842         if (pipe != 1 && ((get_panel_type(dev, pipe) == TMD_VID) ||
843                 (get_panel_type(dev, pipe) == TMD_6X10_VID) ||
844                 (get_panel_type(dev, pipe) == H8C7_VID) ||
845                 (get_panel_type(dev, pipe) == GI_SONY_VID) ||
846                 /* SC1 setting */
847                 (get_panel_type(dev, pipe) == AUO_SC1_VID)))
848                 return 0;
849 #endif
850 #endif
851
852         switch (pipe) {
853         case 0:
854                 break;
855         case 1:
856                 /* regester */
857                 dpll_reg = MDFLD_DPLL_B;
858                 fp_reg = MDFLD_DPLL_DIV0;
859                 pipeconf_reg = PIPEBCONF;
860                 htot_reg = HTOTAL_B;
861                 hblank_reg = HBLANK_B;
862                 hsync_reg = HSYNC_B;
863                 vtot_reg = VTOTAL_B;
864                 vblank_reg = VBLANK_B;
865                 vsync_reg = VSYNC_B;
866                 pipesrc_reg = PIPEBSRC;
867                 dspstride_reg = DSPBSTRIDE;
868                 dsplinoff_reg = DSPBLINOFF;
869                 dsptileoff_reg = DSPBTILEOFF;
870                 dspsize_reg = DSPBSIZE;
871                 dsppos_reg = DSPBPOS;
872                 dspsurf_reg = DSPBSURF;
873                 dspcntr_reg = DSPBCNTR;
874                 dspstatus_reg = PIPEBSTAT;
875                 palette_reg = PALETTE_B;
876
877                 /* values */
878                 dpll_val = &dev_priv->saveDPLL_B;
879                 fp_val = &dev_priv->saveFPB0;
880                 pipeconf_val = &dev_priv->savePIPEBCONF;
881                 htot_val = &dev_priv->saveHTOTAL_B;
882                 hblank_val = &dev_priv->saveHBLANK_B;
883                 hsync_val = &dev_priv->saveHSYNC_B;
884                 vtot_val = &dev_priv->saveVTOTAL_B;
885                 vblank_val = &dev_priv->saveVBLANK_B;
886                 vsync_val = &dev_priv->saveVSYNC_B;
887                 pipesrc_val = &dev_priv->savePIPEBSRC;
888                 dspstride_val = &dev_priv->saveDSPBSTRIDE;
889                 dsplinoff_val = &dev_priv->saveDSPBLINOFF;
890                 dsptileoff_val = &dev_priv->saveDSPBTILEOFF;
891                 dspsize_val = &dev_priv->saveDSPBSIZE;
892                 dsppos_val = &dev_priv->saveDSPBPOS;
893                 dspsurf_val = &dev_priv->saveDSPBSURF;
894                 dspcntr_val = &dev_priv->saveDSPBCNTR;
895                 dspstatus_val = &dev_priv->saveDSPBSTATUS;
896                 palette_val = dev_priv->save_palette_b;
897                 break;
898         case 2:
899                 /* regester */
900                 pipeconf_reg = PIPECCONF;
901                 htot_reg = HTOTAL_C;
902                 hblank_reg = HBLANK_C;
903                 hsync_reg = HSYNC_C;
904                 vtot_reg = VTOTAL_C;
905                 vblank_reg = VBLANK_C;
906                 vsync_reg = VSYNC_C;
907                 pipesrc_reg = PIPECSRC;
908                 dspstride_reg = DSPCSTRIDE;
909                 dsplinoff_reg = DSPCLINOFF;
910                 dsptileoff_reg = DSPCTILEOFF;
911                 dspsize_reg = DSPCSIZE;
912                 dsppos_reg = DSPCPOS;
913                 dspsurf_reg = DSPCSURF;
914                 mipi_reg = MIPI_C;
915                 dspcntr_reg = DSPCCNTR;
916                 dspstatus_reg = PIPECSTAT;
917                 palette_reg = PALETTE_C;
918
919                 /* pointer to values */
920                 pipeconf_val = &dev_priv->savePIPECCONF;
921                 htot_val = &dev_priv->saveHTOTAL_C;
922                 hblank_val = &dev_priv->saveHBLANK_C;
923                 hsync_val = &dev_priv->saveHSYNC_C;
924                 vtot_val = &dev_priv->saveVTOTAL_C;
925                 vblank_val = &dev_priv->saveVBLANK_C;
926                 vsync_val = &dev_priv->saveVSYNC_C;
927                 pipesrc_val = &dev_priv->savePIPECSRC;
928                 dspstride_val = &dev_priv->saveDSPCSTRIDE;
929                 dsplinoff_val = &dev_priv->saveDSPCLINOFF;
930                 dsptileoff_val = &dev_priv->saveDSPCTILEOFF;
931                 dspsize_val = &dev_priv->saveDSPCSIZE;
932                 dsppos_val = &dev_priv->saveDSPCPOS;
933                 dspsurf_val = &dev_priv->saveDSPCSURF;
934                 mipi_val = &dev_priv->saveMIPI_C;
935                 dspcntr_val = &dev_priv->saveDSPCCNTR;
936                 dspstatus_val = &dev_priv->saveDSPCSTATUS;
937                 palette_val = dev_priv->save_palette_c;
938                 break;
939         default:
940                 DRM_ERROR("%s, invalid pipe number.\n", __func__);
941                 return -EINVAL;
942         }
943
944         /* Pipe & plane A info */
945         *dpll_val = PSB_RVDC32(dpll_reg);
946         *fp_val = PSB_RVDC32(fp_reg);
947         *pipeconf_val = PSB_RVDC32(pipeconf_reg);
948         *htot_val = PSB_RVDC32(htot_reg);
949         *hblank_val = PSB_RVDC32(hblank_reg);
950         *hsync_val = PSB_RVDC32(hsync_reg);
951         *vtot_val = PSB_RVDC32(vtot_reg);
952         *vblank_val = PSB_RVDC32(vblank_reg);
953         *vsync_val = PSB_RVDC32(vsync_reg);
954         *pipesrc_val = PSB_RVDC32(pipesrc_reg);
955         *dspstride_val = PSB_RVDC32(dspstride_reg);
956         *dsplinoff_val = PSB_RVDC32(dsplinoff_reg);
957         *dsptileoff_val = PSB_RVDC32(dsptileoff_reg);
958         *dspsize_val = PSB_RVDC32(dspsize_reg);
959         *dsppos_val = PSB_RVDC32(dsppos_reg);
960         *dspsurf_val = PSB_RVDC32(dspsurf_reg);
961         *dspcntr_val = PSB_RVDC32(dspcntr_reg);
962         *dspstatus_val = PSB_RVDC32(dspstatus_reg);
963
964         /*save palette (gamma) */
965         for (i = 0; i < 256; i++)
966                 palette_val[i] = PSB_RVDC32(palette_reg + (i<<2));
967
968         if (pipe == 1) {
969                 dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
970                 dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
971
972                 dev_priv->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL);
973                 dev_priv->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL);
974                 return 0;
975         }
976
977         *mipi_val = PSB_RVDC32(mipi_reg);
978         return 0;
979 }
980 /*
981  * mdfld_save_cursor_overlay_registers
982  *
983  * Description: We are going to suspend so save current cursor and overlay display
984  * register state.
985  */
986 static int mdfld_save_cursor_overlay_registers(struct drm_device *dev)
987 {
988         struct drm_psb_private *dev_priv = dev->dev_private;
989
990         /*save cursor regs*/
991         dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
992         dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
993         dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);
994
995         dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
996         dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
997         dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
998
999         dev_priv->saveDSPCCURSOR_CTRL = PSB_RVDC32(CURCCNTR);
1000         dev_priv->saveDSPCCURSOR_BASE = PSB_RVDC32(CURCBASE);
1001         dev_priv->saveDSPCCURSOR_POS = PSB_RVDC32(CURCPOS);
1002
1003         /* HW overlay */
1004         dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD);
1005         dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0);
1006         dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1);
1007         dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2);
1008         dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3);
1009         dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4);
1010         dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
1011
1012         dev_priv->saveOV_OVADD_C = PSB_RVDC32(OV_OVADD + OV_C_OFFSET);
1013         dev_priv->saveOV_OGAMC0_C = PSB_RVDC32(OV_OGAMC0 + OV_C_OFFSET);
1014         dev_priv->saveOV_OGAMC1_C = PSB_RVDC32(OV_OGAMC1 + OV_C_OFFSET);
1015         dev_priv->saveOV_OGAMC2_C = PSB_RVDC32(OV_OGAMC2 + OV_C_OFFSET);
1016         dev_priv->saveOV_OGAMC3_C = PSB_RVDC32(OV_OGAMC3 + OV_C_OFFSET);
1017         dev_priv->saveOV_OGAMC4_C = PSB_RVDC32(OV_OGAMC4 + OV_C_OFFSET);
1018         dev_priv->saveOV_OGAMC5_C = PSB_RVDC32(OV_OGAMC5 + OV_C_OFFSET);
1019
1020         return 0;
1021 }
1022 /*
1023  * mdfld_restore_display_registers
1024  *
1025  * Description: We are going to resume so restore display register state.
1026  *
1027  */
1028 static int mdfld_restore_display_registers(struct drm_device *dev, int pipe)
1029 {
1030         struct drm_psb_private *dev_priv = dev->dev_private;
1031         struct mdfld_dsi_config * dsi_config = NULL;
1032         u32 i = 0;
1033         u32 dpll = 0;
1034         u32 timeout = 0;
1035         u32 reg_offset = 0;
1036
1037         /* regester */
1038         u32 dpll_reg = MRST_DPLL_A;
1039         u32 fp_reg = MRST_FPA0;
1040         u32 pipeconf_reg = PIPEACONF;
1041         u32 htot_reg = HTOTAL_A;
1042         u32 hblank_reg = HBLANK_A;
1043         u32 hsync_reg = HSYNC_A;
1044         u32 vtot_reg = VTOTAL_A;
1045         u32 vblank_reg = VBLANK_A;
1046         u32 vsync_reg = VSYNC_A;
1047         u32 pipesrc_reg = PIPEASRC;
1048         u32 dspstride_reg = DSPASTRIDE;
1049         u32 dsplinoff_reg = DSPALINOFF;
1050         u32 dsptileoff_reg = DSPATILEOFF;
1051         u32 dspsize_reg = DSPASIZE;
1052         u32 dsppos_reg = DSPAPOS;
1053         u32 dspsurf_reg = DSPASURF;
1054         u32 dspstatus_reg = PIPEASTAT;
1055         u32 mipi_reg = MIPI;
1056         u32 dspcntr_reg = DSPACNTR;
1057         u32 palette_reg = PALETTE_A;
1058
1059         /* values */
1060         u32 dpll_val = dev_priv->saveDPLL_A & ~DPLL_VCO_ENABLE;
1061         u32 fp_val = dev_priv->saveFPA0;
1062         u32 pipeconf_val = dev_priv->savePIPEACONF;
1063         u32 htot_val = dev_priv->saveHTOTAL_A;
1064         u32 hblank_val = dev_priv->saveHBLANK_A;
1065         u32 hsync_val = dev_priv->saveHSYNC_A;
1066         u32 vtot_val = dev_priv->saveVTOTAL_A;
1067         u32 vblank_val = dev_priv->saveVBLANK_A;
1068         u32 vsync_val = dev_priv->saveVSYNC_A;
1069         u32 pipesrc_val = dev_priv->savePIPEASRC;
1070         u32 dspstride_val = dev_priv->saveDSPASTRIDE;
1071         u32 dsplinoff_val = dev_priv->saveDSPALINOFF;
1072         u32 dsptileoff_val = dev_priv->saveDSPATILEOFF;
1073         u32 dspsize_val = dev_priv->saveDSPASIZE;
1074         u32 dsppos_val = dev_priv->saveDSPAPOS;
1075         u32 dspsurf_val = dev_priv->saveDSPASURF;
1076         u32 dspstatus_val = dev_priv->saveDSPASTATUS;
1077         u32 mipi_val = dev_priv->saveMIPI;
1078         u32 dspcntr_val = dev_priv->saveDSPACNTR;
1079         u32 *palette_val = dev_priv->save_palette_a;
1080         PSB_DEBUG_ENTRY("\n");
1081
1082         /**
1083          * For MIPI panels, all plane/pipe/port/DSI controller values
1084          * were already saved in dsi_hw_context, no need to save/restore
1085          * for these registers.
1086          * NOTE: only support TMD panel now, add support for other MIPI
1087          * panels later
1088          */
1089 #ifndef CONFIG_SUPPORT_TOSHIBA_MIPI_DISPLAY
1090 #ifndef CONFIG_SUPPORT_TOSHIBA_MIPI_LVDS_BRIDGE
1091         if (pipe != 1 && ((get_panel_type(dev, pipe) == TMD_VID) ||
1092                 (get_panel_type(dev, pipe) == TMD_6X10_VID) ||
1093                 (get_panel_type(dev, pipe) == H8C7_VID) ||
1094                 (get_panel_type(dev, pipe) == GI_SONY_VID) ||
1095                 /* SC1 setting */
1096                 (get_panel_type(dev, pipe) == AUO_SC1_VID)))
1097                 return 0;
1098 #endif
1099 #endif
1100
1101         switch (pipe) {
1102         case 0:
1103                 dsi_config = dev_priv->dsi_configs[0];
1104                 break;
1105         case 1:
1106                 /* regester */
1107                 dpll_reg = MDFLD_DPLL_B;
1108                 fp_reg = MDFLD_DPLL_DIV0;
1109                 pipeconf_reg = PIPEBCONF;
1110                 htot_reg = HTOTAL_B;
1111                 hblank_reg = HBLANK_B;
1112                 hsync_reg = HSYNC_B;
1113                 vtot_reg = VTOTAL_B;
1114                 vblank_reg = VBLANK_B;
1115                 vsync_reg = VSYNC_B;
1116                 pipesrc_reg = PIPEBSRC;
1117                 dspstride_reg = DSPBSTRIDE;
1118                 dsplinoff_reg = DSPBLINOFF;
1119                 dsptileoff_reg = DSPBTILEOFF;
1120                 dspsize_reg = DSPBSIZE;
1121                 dsppos_reg = DSPBPOS;
1122                 dspsurf_reg = DSPBSURF;
1123                 dspcntr_reg = DSPBCNTR;
1124                 palette_reg = PALETTE_B;
1125                 dspstatus_reg = PIPEBSTAT;
1126
1127                 /* values */
1128                 dpll_val = dev_priv->saveDPLL_B & ~DPLL_VCO_ENABLE;
1129                 fp_val = dev_priv->saveFPB0;
1130                 pipeconf_val = dev_priv->savePIPEBCONF;
1131                 htot_val = dev_priv->saveHTOTAL_B;
1132                 hblank_val = dev_priv->saveHBLANK_B;
1133                 hsync_val = dev_priv->saveHSYNC_B;
1134                 vtot_val = dev_priv->saveVTOTAL_B;
1135                 vblank_val = dev_priv->saveVBLANK_B;
1136                 vsync_val = dev_priv->saveVSYNC_B;
1137                 pipesrc_val = dev_priv->savePIPEBSRC;
1138                 dspstride_val = dev_priv->saveDSPBSTRIDE;
1139                 dsplinoff_val = dev_priv->saveDSPBLINOFF;
1140                 dsptileoff_val = dev_priv->saveDSPBTILEOFF;
1141                 dspsize_val = dev_priv->saveDSPBSIZE;
1142                 dsppos_val = dev_priv->saveDSPBPOS;
1143                 dspsurf_val = dev_priv->saveDSPBSURF;
1144                 dspcntr_val = dev_priv->saveDSPBCNTR & ~DISPLAY_PLANE_ENABLE;
1145                 dspstatus_val = dev_priv->saveDSPBSTATUS;
1146                 palette_val = dev_priv->save_palette_b;
1147                 break;
1148         case 2:
1149                 reg_offset = MIPIC_REG_OFFSET;
1150
1151                 /* regester */
1152                 pipeconf_reg = PIPECCONF;
1153                 htot_reg = HTOTAL_C;
1154                 hblank_reg = HBLANK_C;
1155                 hsync_reg = HSYNC_C;
1156                 vtot_reg = VTOTAL_C;
1157                 vblank_reg = VBLANK_C;
1158                 vsync_reg = VSYNC_C;
1159                 pipesrc_reg = PIPECSRC;
1160                 dspstride_reg = DSPCSTRIDE;
1161                 dsplinoff_reg = DSPCLINOFF;
1162                 dsptileoff_reg = DSPCTILEOFF;
1163                 dspsize_reg = DSPCSIZE;
1164                 dsppos_reg = DSPCPOS;
1165                 dspsurf_reg = DSPCSURF;
1166                 mipi_reg = MIPI_C;
1167                 dspcntr_reg = DSPCCNTR;
1168                 palette_reg = PALETTE_C;
1169                 dspstatus_reg = PIPECSTAT;
1170
1171                 /* values */
1172                 pipeconf_val = dev_priv->savePIPECCONF;
1173                 htot_val = dev_priv->saveHTOTAL_C;
1174                 hblank_val = dev_priv->saveHBLANK_C;
1175                 hsync_val = dev_priv->saveHSYNC_C;
1176                 vtot_val = dev_priv->saveVTOTAL_C;
1177                 vblank_val = dev_priv->saveVBLANK_C;
1178                 vsync_val = dev_priv->saveVSYNC_C;
1179                 pipesrc_val = dev_priv->savePIPECSRC;
1180                 dspstride_val = dev_priv->saveDSPCSTRIDE;
1181                 dsplinoff_val = dev_priv->saveDSPCLINOFF;
1182                 dsptileoff_val = dev_priv->saveDSPCTILEOFF;
1183                 dspsize_val = dev_priv->saveDSPCSIZE;
1184                 dsppos_val = dev_priv->saveDSPCPOS;
1185                 dspsurf_val = dev_priv->saveDSPCSURF;
1186                 dspstatus_val = dev_priv->saveDSPCSTATUS;
1187                 mipi_val = dev_priv->saveMIPI_C;
1188                 dspcntr_val = dev_priv->saveDSPCCNTR;
1189                 palette_val = dev_priv->save_palette_c;
1190
1191                 dsi_config = dev_priv->dsi_configs[1];
1192                 break;
1193         default:
1194                 DRM_ERROR("%s, invalid pipe number.\n", __func__);
1195                 return -EINVAL;
1196         }
1197
1198         /*make sure VGA plane is off. it initializes to on after reset!*/
1199         PSB_WVDC32(0x80000000, VGACNTRL);
1200
1201         dpll = PSB_RVDC32(dpll_reg);
1202
1203         if (!(dpll & DPLL_VCO_ENABLE)) {
1204                 /**
1205                  * When ungating power of DPLL, needs to wait 0.5us
1206                  * before enable the VCO
1207                  */
1208                 if (dpll & MDFLD_PWR_GATE_EN) {
1209                         dpll &= ~MDFLD_PWR_GATE_EN;
1210                         PSB_WVDC32(dpll, dpll_reg);
1211                         /* FIXME_MDFLD PO - change 500 to 1 after PO */
1212                         udelay(500);
1213                 }
1214
1215                 PSB_WVDC32(fp_val, fp_reg);
1216                 PSB_WVDC32(dpll_val, dpll_reg);
1217                 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1218                 udelay(500);
1219
1220                 dpll_val |= DPLL_VCO_ENABLE;
1221                 PSB_WVDC32(dpll_val, dpll_reg);
1222                 PSB_RVDC32(dpll_reg);
1223
1224                 /* wait for DSI PLL to lock */
1225                 /**
1226                  * FIXME: HDMI PLL cannot be locked on pipe 1,
1227                  * replace pipe == 0 with pipe != 2 when HDMI
1228                  * restore is ready
1229                  */
1230                 while ((pipe == 0) &&
1231                         (timeout < 20000) &&
1232                         !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
1233                         udelay(150);
1234                         timeout++;
1235                 }
1236
1237                 if (timeout == 20000) {
1238                         DRM_ERROR("%s, can't lock DSIPLL.\n", __func__);
1239                         return -EINVAL;
1240                 }
1241         }
1242
1243         /* Restore mode */
1244         PSB_WVDC32(htot_val, htot_reg);
1245         PSB_WVDC32(hblank_val, hblank_reg);
1246         PSB_WVDC32(hsync_val, hsync_reg);
1247         PSB_WVDC32(vtot_val, vtot_reg);
1248         PSB_WVDC32(vblank_val, vblank_reg);
1249         PSB_WVDC32(vsync_val, vsync_reg);
1250         PSB_WVDC32(pipesrc_val, pipesrc_reg);
1251         PSB_WVDC32(dspstatus_val,dspstatus_reg);
1252
1253         /*set up the plane*/
1254         PSB_WVDC32(dspstride_val, dspstride_reg);
1255         PSB_WVDC32(dsplinoff_val, dsplinoff_reg);
1256         PSB_WVDC32(dsptileoff_val, dsptileoff_reg);
1257         PSB_WVDC32(dspsize_val, dspsize_reg);
1258         PSB_WVDC32(dsppos_val, dsppos_reg);
1259         PSB_WVDC32(dspsurf_val, dspsurf_reg);
1260
1261         if (pipe == 1) {
1262                 PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
1263                 PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
1264
1265                 PSB_WVDC32(dev_priv->saveHDMIPHYMISCCTL, HDMIPHYMISCCTL);
1266                 PSB_WVDC32(dev_priv->saveHDMIB_CONTROL, HDMIB_CONTROL);
1267
1268         } else {
1269                 /*set up pipe related registers*/
1270                 PSB_WVDC32(mipi_val, mipi_reg);
1271
1272                 /* setup MIPI adapter + MIPI IP registers */
1273                 mdfld_dsi_controller_init(dsi_config, pipe);
1274
1275                 if(in_atomic() || in_interrupt())
1276                         mdelay(20);
1277                 else
1278                         msleep(20);
1279
1280                 /*TODO: remove MIPI restore code later*/
1281                 /*dsi_config->dvr_ic_inited = 0;*/
1282                 /*mdfld_dsi_tmd_drv_ic_init(dsi_config, pipe);*/
1283         }
1284
1285         /*enable the plane*/
1286         PSB_WVDC32(dspcntr_val, dspcntr_reg);
1287
1288     if(in_atomic() || in_interrupt())
1289         mdelay(20);
1290     else
1291         msleep(20);
1292
1293 #if 0 /* revisit it later and check if we want to enter/exit from ULPS */
1294         /* LP Hold Release */
1295         temp = REG_READ(mipi_reg);
1296         temp |= LP_OUTPUT_HOLD_RELEASE;
1297         REG_WRITE(mipi_reg, temp);
1298         mdelay(1);
1299
1300
1301         /* Set DSI host to exit from Utra Low Power State */
1302         temp = REG_READ(device_ready_reg);
1303         temp &= ~ULPS_MASK;
1304         temp |= 0x3;
1305         temp |= EXIT_ULPS_DEV_READY;
1306         REG_WRITE(device_ready_reg, temp);
1307         mdelay(1);
1308
1309         temp = REG_READ(device_ready_reg);
1310         temp &= ~ULPS_MASK;
1311         temp |= EXITING_ULPS;
1312         REG_WRITE(device_ready_reg, temp);
1313         mdelay(1);
1314 #endif
1315
1316         /*enable the pipe*/
1317     PSB_WVDC32(pipeconf_val, pipeconf_reg);
1318
1319         /* restore palette (gamma) */
1320         /*DRM_UDELAY(50000); */
1321         for (i = 0; i < 256; i++)
1322                 PSB_WVDC32(palette_val[i], palette_reg + (i<<2));
1323
1324         if (pipe == 1)
1325                 return 0;
1326
1327         if ((get_panel_type(dev, pipe) == GI_SONY_CMD)||(get_panel_type(dev, pipe) == H8C7_CMD))
1328                 psb_enable_vblank(dev, pipe);
1329         else if (IS_MDFLD(dev) && (dev_priv->platform_rev_id != MDFLD_PNW_A0) &&
1330                         !is_panel_vid_or_cmd(dev))
1331                 mdfld_enable_te(dev, pipe);
1332
1333         return 0;
1334 }
1335
1336 /*
1337  * mdfld_restore_cursor_overlay_registers
1338  *
1339  * Description: We are going to resume so restore cursor and overlay register state.
1340  */
1341 static int mdfld_restore_cursor_overlay_registers(struct drm_device *dev)
1342 {
1343         struct drm_psb_private *dev_priv = dev->dev_private;
1344
1345         /*Enable Cursor A*/
1346         PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
1347         PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
1348         PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);
1349
1350         PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR);
1351         PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS);
1352         PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE);
1353
1354         PSB_WVDC32(dev_priv->saveDSPCCURSOR_CTRL, CURCCNTR);
1355         PSB_WVDC32(dev_priv->saveDSPCCURSOR_POS, CURCPOS);
1356         PSB_WVDC32(dev_priv->saveDSPCCURSOR_BASE, CURCBASE);
1357
1358         /* restore HW overlay */
1359         PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD);
1360         PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0);
1361         PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1);
1362         PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2);
1363         PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3);
1364         PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4);
1365         PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
1366
1367         PSB_WVDC32(dev_priv->saveOV_OVADD_C, OV_OVADD + OV_C_OFFSET);
1368         PSB_WVDC32(dev_priv->saveOV_OGAMC0_C, OV_OGAMC0 + OV_C_OFFSET);
1369         PSB_WVDC32(dev_priv->saveOV_OGAMC1_C, OV_OGAMC1 + OV_C_OFFSET);
1370         PSB_WVDC32(dev_priv->saveOV_OGAMC2_C, OV_OGAMC2 + OV_C_OFFSET);
1371         PSB_WVDC32(dev_priv->saveOV_OGAMC3_C, OV_OGAMC3 + OV_C_OFFSET);
1372         PSB_WVDC32(dev_priv->saveOV_OGAMC4_C, OV_OGAMC4 + OV_C_OFFSET);
1373         PSB_WVDC32(dev_priv->saveOV_OGAMC5_C, OV_OGAMC5 + OV_C_OFFSET);
1374
1375         return 0;
1376 }
1377
1378 /*
1379  *  mdfld_save_display
1380  *
1381  * Description: Save display status before DPMS OFF for RuntimePM
1382  */
1383 void mdfld_save_display(struct drm_device *dev)
1384 {
1385         struct drm_psb_private *dev_priv = dev->dev_private;
1386 #ifdef OSPM_GFX_DPK
1387                 printk(KERN_ALERT "ospm_save_display\n");
1388 #endif
1389         mdfld_save_cursor_overlay_registers(dev);
1390
1391         if (dev_priv->panel_desc & DISPLAY_A) mdfld_save_display_registers(dev, 0);
1392         if (dev_priv->panel_desc & DISPLAY_C) mdfld_save_display_registers(dev, 2);  //h8c7_cmd
1393 }
1394
1395 /*
1396  * powermgmt_suspend_display
1397  *
1398  * Description: Suspend the display hardware saving state and disabling
1399  * as necessary.
1400  */
1401 void ospm_suspend_display(struct drm_device *dev)
1402 {
1403         struct drm_psb_private *dev_priv = dev->dev_private;
1404         int pp_stat, ret=0;
1405
1406 #ifdef OSPM_GFX_DPK
1407         printk(KERN_ALERT "%s\n", __func__);
1408 #endif
1409
1410         if (!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
1411 #ifdef OSPM_GFX_DPK
1412                 printk(KERN_ALERT "%s - IGNORING!!!!\n", __func__);
1413 #endif
1414                 return;
1415         }
1416
1417         if (IS_MDFLD(dev)) {
1418                 mdfld_save_cursor_overlay_registers(dev);
1419
1420                 if (dev_priv->panel_desc & DISPLAY_A)
1421                         mdfld_save_display_registers(dev, 0);
1422                 if (dev_priv->panel_desc & DISPLAY_B)
1423                         mdfld_save_display_registers(dev, 1);
1424                 if (dev_priv->panel_desc & DISPLAY_C)
1425                         mdfld_save_display_registers(dev, 2);
1426
1427                 if (dev_priv->panel_desc & DISPLAY_A)
1428                         mdfld_disable_crtc(dev, 0);
1429                 if (dev_priv->panel_desc & DISPLAY_B)
1430                         mdfld_disable_crtc(dev, 1);
1431                 if (dev_priv->panel_desc & DISPLAY_C)
1432                         mdfld_disable_crtc(dev, 2);
1433
1434                 /*save performance state*/
1435                 dev_priv->savePERF_MODE = PSB_RVDC32(MRST_PERF_MODE);
1436                 dev_priv->saveVED_CG_DIS = PSB_RVDC32(PSB_MSVDX_CLOCKGATING);
1437 #ifdef CONFIG_MDFD_GL3
1438                 dev_priv->saveGL3_CTL = PSB_RVDC32(MDFLD_GL3_CONTROL);
1439                 dev_priv->saveGL3_USE_WRT_INVAL = PSB_RVDC32(MDFLD_GL3_USE_WRT_INVAL);
1440 #endif
1441
1442 #if 0 /* revisit it later and check if we want to enter/exit from ULPS */
1443                 /* Put the panel in ULPS mode for S0ix. */
1444                 temp = REG_READ(device_ready_reg);
1445                 temp &= ~ULPS_MASK;
1446                 temp |= ENTERING_ULPS;
1447                 REG_WRITE(device_ready_reg, temp);
1448
1449                 /* LP Hold */
1450                 temp = REG_READ(mipi_reg);
1451                 temp &= ~LP_OUTPUT_HOLD;
1452                 REG_WRITE(mipi_reg, temp);
1453                 mdelay(1);
1454 #endif
1455
1456         } else {
1457                 save_display_registers(dev);
1458
1459                 if (dev_priv->iLVDS_enable) {
1460                         /*shutdown the panel*/
1461                         PSB_WVDC32(0, PP_CONTROL);
1462
1463                         do {
1464                                 pp_stat = PSB_RVDC32(PP_STATUS);
1465                         } while (pp_stat & 0x80000000);
1466
1467                         /*turn off the plane*/
1468                         PSB_WVDC32(0x58000000, DSPACNTR);
1469                         PSB_WVDC32(0, DSPASURF);/*trigger the plane disable*/
1470                         /*wait ~4 ticks*/
1471                         msleep(4);
1472
1473                         /*turn off pipe*/
1474                         PSB_WVDC32(0x0, PIPEACONF);
1475                         /*wait ~8 ticks*/
1476                         msleep(8);
1477
1478                         /*turn off PLLs*/
1479                         PSB_WVDC32(0, MRST_DPLL_A);
1480                 } else {
1481                         PSB_WVDC32(DPI_SHUT_DOWN, DPI_CONTROL_REG);
1482                         PSB_WVDC32(0x0, PIPEACONF);
1483                         PSB_WVDC32(0x2faf0000, BLC_PWM_CTL);
1484                         while (REG_READ(0x70008) & 0x40000000);
1485                         while ((PSB_RVDC32(GEN_FIFO_STAT_REG) & DPI_FIFO_EMPTY)
1486                                 != DPI_FIFO_EMPTY);
1487                         PSB_WVDC32(0, DEVICE_READY_REG);
1488
1489                         /* turn off panel power */
1490                         ret = 0;
1491 #ifdef CONFIG_X86_MDFLD
1492                         ret = intel_scu_ipc_simple_command(IPC_MSG_PANEL_ON_OFF, IPC_CMD_PANEL_OFF);
1493                         if (ret)
1494                                 printk(KERN_WARNING "IPC 0xE9 failed to turn off pnl pwr. Error is: %x\n", ret);
1495 #endif
1496                 }
1497         }
1498
1499         ospm_power_island_down(OSPM_DISPLAY_ISLAND);
1500 }
1501
1502 /*
1503  * is_hdmi_plugged_out
1504  *
1505  * Description: to check whether hdmi is plugged out in S3 suspend
1506  *
1507  */
1508 static bool is_hdmi_plugged_out(struct drm_device *dev)
1509 {
1510         u8 data = 0;
1511         bool hdmi_plugged_out = true;
1512
1513         if (IS_MDFLD_OLD(dev)) {
1514                 intel_scu_ipc_ioread8(MSIC_HDMI_STATUS, &data);
1515
1516                 if (data & HPD_SIGNAL_STATUS)
1517                         hdmi_plugged_out = false;
1518                 else
1519                         hdmi_plugged_out = true;
1520         } else if (IS_CTP(dev)) {
1521                 if (gpio_get_value(CLV_TI_HPD_GPIO_PIN) == 0)
1522                         hdmi_plugged_out = true;
1523                 else
1524                         hdmi_plugged_out = false;
1525         }
1526
1527         return hdmi_plugged_out;
1528 }
1529
1530 /*
1531  * ospm_resume_display
1532  *
1533  * Description: Resume the display hardware restoring state and enabling
1534  * as necessary.
1535  */
1536 void ospm_resume_display(struct pci_dev *pdev)
1537 {
1538         struct drm_device *dev = pci_get_drvdata(pdev);
1539         struct drm_psb_private *dev_priv = dev->dev_private;
1540         struct psb_gtt *pg = dev_priv->pg;
1541 #if (defined(CONFIG_SND_INTELMID_HDMI_AUDIO) || \
1542                 defined(CONFIG_SND_INTELMID_HDMI_AUDIO_MODULE))
1543         char *uevent_string = NULL;
1544 #endif
1545
1546 #ifdef OSPM_GFX_DPK
1547         printk(KERN_ALERT "%s\n", __func__);
1548 #endif
1549         if (ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
1550 #ifdef OSPM_GFX_DPK
1551                 printk(KERN_ALERT "%s - IGNORING!!!!\n", __func__);
1552 #endif
1553                 printk(KERN_ALERT "[DISPLAY] Exit %s because hw on\n",
1554                                 __func__);
1555                 return;
1556         }
1557
1558         if (IS_MDFLD(dev)) {
1559                 /*restore performance mode*/
1560                 PSB_WVDC32(dev_priv->savePERF_MODE, MRST_PERF_MODE);
1561                 PSB_WVDC32(dev_priv->saveVED_CG_DIS, PSB_MSVDX_CLOCKGATING);
1562 #ifdef CONFIG_MDFD_GL3
1563                 PSB_WVDC32(dev_priv->saveGL3_CTL, MDFLD_GL3_CONTROL);
1564                 PSB_WVDC32(dev_priv->saveGL3_USE_WRT_INVAL, MDFLD_GL3_USE_WRT_INVAL);
1565 #endif
1566     }
1567
1568         /* turn on the display power island */
1569         ospm_power_island_up(OSPM_DISPLAY_ISLAND);
1570
1571         PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
1572         pci_write_config_word(pdev, PSB_GMCH_CTRL,
1573                         pg->gmch_ctrl | _PSB_GMCH_ENABLED);
1574
1575         /* Don't reinitialize the GTT as it is unnecessary.  The gtt is
1576          * stored in memory so it will automatically be restored.  All
1577          * we need to do is restore the PGETBL_CTL which we already do
1578          * above.
1579          */
1580         /*psb_gtt_init(dev_priv->pg, 1);*/
1581
1582         if (IS_MDFLD(dev)) {
1583                 if (dev_priv->panel_desc & DISPLAY_C)
1584                         mdfld_restore_display_registers(dev, 2);
1585                 if (dev_priv->panel_desc & DISPLAY_A)
1586                         mdfld_restore_display_registers(dev, 0);
1587                 /*
1588                  * Don't restore Display B registers during resuming, if HDMI
1589                  * isn't turned on before suspending.
1590                  */
1591                 if (dev_priv->panel_desc & DISPLAY_B) {
1592                         mdfld_restore_display_registers(dev, 1);
1593                         /*devices connect status will be changed
1594                          when system suspend,re-detect once here*/
1595 #if (defined(CONFIG_SND_INTELMID_HDMI_AUDIO) || \
1596                 defined(CONFIG_SND_INTELMID_HDMI_AUDIO_MODULE))
1597                         if (!is_hdmi_plugged_out(dev)) {
1598                                 PSB_DEBUG_ENTRY("resume hdmi_state %d", hdmi_state);
1599                                 if (dev_priv->had_pvt_data && hdmi_state) {
1600                                         if (!dev_priv->had_interface->resume(dev_priv->had_pvt_data)) {
1601                                                 uevent_string = "HDMI_AUDIO_PM_RESUMED=1";
1602                                                 psb_sysfs_uevent(dev_priv->dev, uevent_string);
1603                                         }
1604                                 }
1605                         } else {
1606                                 PSB_DEBUG_ENTRY("hdmi is unplugged: %d!\n", hdmi_state);
1607                                 if (hdmi_state)
1608                                         schedule_work(&dev_priv->hdmi_hotplug_wq);
1609                                 msleep(100);
1610                         }
1611 #endif
1612                 }
1613                 mdfld_restore_cursor_overlay_registers(dev);
1614
1615         }else{
1616                 if (!dev_priv->iLVDS_enable) {
1617 #ifdef CONFIG_X86_MDFLD
1618                         int ret=0;
1619                         ret = intel_scu_ipc_simple_command(IPC_MSG_PANEL_ON_OFF, IPC_CMD_PANEL_ON);
1620                         if (ret)
1621                                 printk(KERN_WARNING "IPC 0xE9 failed to turn on pnl pwr.  Error is: %x\n", ret);
1622                         msleep(2000); /* wait 2 seconds */
1623 #endif
1624                 }
1625
1626                 restore_display_registers(dev);
1627         }
1628 }
1629
1630 #if 1 /* for debugging ospm */
1631 /*
1632  * ospm_suspend_pci
1633  *
1634  * Description: Suspend the pci device saving state and disabling
1635  * as necessary.
1636  */
1637 static void ospm_suspend_pci(struct pci_dev *pdev)
1638 {
1639         struct drm_device *dev = pci_get_drvdata(pdev);
1640         struct drm_psb_private *dev_priv = dev->dev_private;
1641         int bsm, vbt;
1642
1643         if (gbSuspended)
1644                 return;
1645
1646 #ifdef OSPM_GFX_DPK
1647         printk(KERN_ALERT "ospm_suspend_pci\n");
1648 #endif
1649
1650         pci_save_state(pdev);
1651         pci_read_config_dword(pdev, 0x5C, &bsm);
1652         dev_priv->saveBSM = bsm;
1653         pci_read_config_dword(pdev, 0xFC, &vbt);
1654         dev_priv->saveVBT = vbt;
1655         pci_read_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, &dev_priv->msi_addr);
1656         pci_read_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, &dev_priv->msi_data);
1657
1658         pci_disable_device(pdev);
1659         pci_set_power_state(pdev, PCI_D3hot);
1660         /*
1661         Disabling the IPC call to SCU
1662         to turn off Vprog2 as SCU doesn't
1663         support this IPC.
1664         This will be enabled once SCU support
1665         is available.
1666         */
1667
1668 #if 0
1669         /*Notify SCU on GFX suspend for VProg2.*/
1670         {
1671                 unsigned int gfx_off = 0;
1672                 unsigned int  ret = 0;
1673                 ret = intel_scu_ipc_command(SCU_CMD_VPROG2, 0, &gfx_off, 1, NULL, 0);
1674                 if (ret)
1675                         printk(KERN_WARNING
1676                         "%s IPC 0xE3 failed; error is: %x\n", __func__, ret);
1677         }
1678 #endif
1679
1680         gbSuspended = true;
1681         gbgfxsuspended = true;
1682 }
1683
1684 /*
1685  * ospm_resume_pci
1686  *
1687  * Description: Resume the pci device restoring state and enabling
1688  * as necessary.
1689  */
1690 static bool ospm_resume_pci(struct pci_dev *pdev)
1691 {
1692         struct drm_device *dev = pci_get_drvdata(pdev);
1693         struct drm_psb_private *dev_priv = dev->dev_private;
1694         int ret = 0;
1695
1696         if (!gbSuspended)
1697                 return true;
1698
1699 #ifdef OSPM_GFX_DPK
1700         printk(KERN_ALERT "ospm_resume_pci\n");
1701 #endif
1702         /*
1703         Disabling the IPC call to SCU
1704         to turn on Vprog2 as SCU doesn't
1705         support this IPC.
1706         This will be enabled once SCU support
1707         is available.
1708         */
1709 #if 0
1710         /*Notify SCU on GFX resume for VProg2.*/
1711         {
1712                 unsigned int gfx_on = 1;
1713                 unsigned int ret = 0;
1714                 ret = intel_scu_ipc_command(SCU_CMD_VPROG2, 0, &gfx_on, 1, NULL, 0);
1715                 if (ret)
1716                         printk(KERN_WARNING
1717                         "%s IPC 0xE3 failed; error is: %x\n", __func__, ret);
1718         }
1719 #endif
1720
1721         pci_set_power_state(pdev, PCI_D0);
1722         pci_restore_state(pdev);
1723         pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM);
1724         pci_write_config_dword(pdev, 0xFC, dev_priv->saveVBT);
1725         /* retoring MSI address and data in PCIx space */
1726         pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr);
1727         pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data);
1728         ret = pci_enable_device(pdev);
1729
1730         if (ret != 0)
1731                 printk(KERN_ALERT "ospm_resume_pci: pci_enable_device failed: %d\n", ret);
1732         else
1733                 gbSuspended = false;
1734
1735         return !gbSuspended;
1736 }
1737 #endif
1738
1739 static void gfx_early_suspend(struct early_suspend *h)
1740 {
1741         struct drm_psb_private* dev_priv = gpDrmDevice->dev_private;
1742         struct drm_device *dev = dev_priv->dev;
1743         struct drm_encoder *encoder;
1744         struct drm_encoder_helper_funcs *enc_funcs;
1745
1746 #ifdef OSPM_GFX_DPK
1747         printk(KERN_ALERT "\n   gfx_early_suspend\n");
1748 #endif
1749
1750         if( dev_priv->drm_psb_widi )
1751                 dev_priv->drm_psb_widi = 0;
1752     if (dev_priv->pvr_screen_event_handler)
1753         dev_priv->pvr_screen_event_handler(dev, 0);
1754         /*Display off*/
1755         if (IS_MDFLD(gpDrmDevice)) {
1756                 if ((dev_priv->panel_id == TMD_VID) ||
1757                         (dev_priv->panel_id == H8C7_VID) ||
1758                         (dev_priv->panel_id == TMD_6X10_VID) ||
1759                         (dev_priv->panel_id == GI_SONY_VID) ||
1760                         (dev_priv->panel_id == GI_SONY_CMD) ||
1761                         (dev_priv->panel_id == H8C7_CMD) ||
1762                         (dev_priv->panel_id == AUO_SC1_VID) ||
1763                         /* SC1 setting */
1764                         (dev_priv->panel_id == AUO_SC1_CMD)) {
1765 #if defined(CONFIG_SUPPORT_TOSHIBA_MIPI_DISPLAY) || defined(CONFIG_SUPPORT_TOSHIBA_MIPI_LVDS_BRIDGE)
1766                         if (dev_priv->encoder0 &&
1767                                 (dev_priv->panel_desc & DISPLAY_A))
1768                                 mdfld_dsi_dpi_set_power(
1769                                         dev_priv->encoder0, false);
1770                         if (dev_priv->encoder2 &&
1771                                 (dev_priv->panel_desc & DISPLAY_C))
1772                                 mdfld_dsi_dpi_set_power(
1773                                         dev_priv->encoder2, false);
1774 #else
1775                                 list_for_each_entry(encoder,
1776                                         &dev->mode_config.encoder_list,
1777                                         head) {
1778                                         enc_funcs = encoder->helper_private;
1779                                         if (!drm_helper_encoder_in_use(encoder))
1780                                                 continue;
1781                                         if (enc_funcs && enc_funcs->save)
1782                                                 enc_funcs->save(encoder);
1783                         }
1784 #endif
1785                 } else if (dev_priv->panel_id == TPO_CMD) {
1786                         if (dev_priv->encoder0 &&
1787                                 (dev_priv->panel_desc & DISPLAY_A))
1788                                 mdfld_dsi_dbi_set_power(
1789                                         &dev_priv->encoder0->base, false);
1790                         if (dev_priv->encoder2 &&
1791                                 (dev_priv->panel_desc & DISPLAY_C))
1792                                 mdfld_dsi_dbi_set_power(
1793                                         &dev_priv->encoder2->base, false);
1794                 } else
1795                         printk(KERN_ALERT "panel type is not support currently\n");
1796         }
1797
1798         gbdispstatus = false;
1799
1800 #ifdef CONFIG_GFX_RTPM
1801 #ifdef OSPM_GFX_DPK
1802         printk(KERN_ALERT " allow GFX runtime_pm\n");
1803 #endif
1804         pm_runtime_allow(&gpDrmDevice->pdev->dev);
1805 #endif
1806
1807 }
1808
1809 static void gfx_late_resume(struct early_suspend *h)
1810 {
1811         struct drm_psb_private* dev_priv = gpDrmDevice->dev_private;
1812         struct drm_device *dev = dev_priv->dev;
1813         struct drm_encoder *encoder;
1814         struct drm_encoder_helper_funcs *enc_funcs;
1815         u32 dspcntr_val;
1816 #ifdef OSPM_GFX_DPK
1817         printk(KERN_ALERT "\ngfx_late_resume\n");
1818 #endif
1819
1820         if( dev_priv->drm_psb_widi )
1821                 dev_priv->drm_psb_widi = 0;
1822
1823         if(IS_MDFLD(gpDrmDevice)){
1824
1825 #ifdef CONFIG_GFX_RTPM
1826                 pm_runtime_forbid(&gpDrmDevice->pdev->dev);
1827                 mutex_lock(&g_ospm_mutex);
1828                 ospm_resume_pci(gpDrmDevice->pdev);
1829                 ospm_resume_display(gpDrmDevice->pdev);
1830                 psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
1831                 psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
1832                 mutex_unlock(&g_ospm_mutex);
1833 #endif
1834                 if (IS_MDFLD(gpDrmDevice)) {
1835                         if ((dev_priv->panel_id == TMD_VID) ||
1836                                 (dev_priv->panel_id == H8C7_VID) ||
1837                                 (dev_priv->panel_id == TMD_6X10_VID) ||
1838                                 (dev_priv->panel_id == GI_SONY_VID) ||
1839                                 (dev_priv->panel_id == GI_SONY_CMD) ||
1840                                 (dev_priv->panel_id == H8C7_CMD) ||
1841                                 (dev_priv->panel_id == AUO_SC1_VID) ||
1842                                 /* SC1 setting */
1843                                 (dev_priv->panel_id == AUO_SC1_CMD)) {
1844 #if     defined(CONFIG_SUPPORT_TOSHIBA_MIPI_DISPLAY) || defined(CONFIG_SUPPORT_TOSHIBA_MIPI_LVDS_BRIDGE)
1845                                 if (dev_priv->encoder0 &&
1846                                         (dev_priv->panel_desc & DISPLAY_A))
1847                                         mdfld_dsi_dpi_set_power(
1848                                                 dev_priv->encoder0, true);
1849                                 if (dev_priv->encoder2 &&
1850                                         (dev_priv->panel_desc & DISPLAY_C))
1851                                         mdfld_dsi_dpi_set_power(
1852                                                 dev_priv->encoder2, true);
1853 #else
1854                                 list_for_each_entry(encoder,
1855                                         &dev->mode_config.encoder_list,
1856                                         head) {
1857                                         enc_funcs = encoder->helper_private;
1858                                         if (!drm_helper_encoder_in_use(encoder))
1859                                                 continue;
1860                                         if (enc_funcs && enc_funcs->restore)
1861                                                 enc_funcs->restore(encoder);
1862                         }
1863 #endif
1864                         } else if (dev_priv->panel_id == TPO_CMD) {
1865                                 if (dev_priv->encoder0 &&
1866                                         (dev_priv->panel_desc & DISPLAY_A))
1867                                         mdfld_dsi_dbi_set_power(
1868                                                 &dev_priv->encoder0->base, true);
1869                                 if (dev_priv->encoder2 &&
1870                                         (dev_priv->panel_desc & DISPLAY_C))
1871                                         mdfld_dsi_dbi_set_power(
1872                                                 &dev_priv->encoder2->base, true);
1873                         } else {
1874                                 printk(KERN_ALERT "%s invalid panel\n",
1875                                         __func__);
1876                         }
1877                 }
1878
1879                 if (dev_priv->panel_desc & DISPLAY_B) {
1880                         dspcntr_val = PSB_RVDC32(DSPBCNTR);
1881                         /* comply the status with HDMI DPMS */
1882                         if (DISP_PLANEB_STATUS == DISPLAY_PLANE_DISABLE)
1883                                 PSB_WVDC32(dspcntr_val & ~DISPLAY_PLANE_ENABLE, DSPBCNTR);
1884                         else
1885                                 PSB_WVDC32(dspcntr_val | DISPLAY_PLANE_ENABLE, DSPBCNTR);
1886                 }
1887         if (dev_priv->pvr_screen_event_handler)
1888             dev_priv->pvr_screen_event_handler(dev, 1);
1889                 gbdispstatus = true;
1890
1891                 if (lastFailedBrightness > 0)
1892                         psb_set_brightness(NULL);
1893         }
1894 }
1895
1896 /*
1897  * ospm_power_suspend
1898  *
1899  * Description: OSPM is telling our driver to suspend so save state
1900  * and power down all hardware.
1901  */
1902 int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state)
1903 {
1904         int ret = 0;
1905         int graphics_access_count;
1906         int videoenc_access_count;
1907         int videodec_access_count;
1908         int display_access_count;
1909 #if (defined(CONFIG_SND_INTELMID_HDMI_AUDIO) || \
1910                 defined(CONFIG_SND_INTELMID_HDMI_AUDIO_MODULE))
1911         struct drm_psb_private *dev_priv = gpDrmDevice->dev_private;
1912         struct snd_intel_had_interface *had_interface = dev_priv->had_interface;
1913         int hdmi_audio_busy = 0;
1914         pm_event_t hdmi_audio_event;
1915 #endif
1916         if(gbSuspendInProgress || gbResumeInProgress)
1917         {
1918 #ifdef OSPM_GFX_DPK
1919                 printk(KERN_ALERT "%s system BUSY\n", __func__);
1920 #endif
1921                 return  -EBUSY;
1922         }
1923 #ifdef OSPM_GFX_DPK
1924         printk(KERN_ALERT "%s\n", __func__);
1925 #endif
1926         mutex_lock(&g_ospm_mutex);
1927         if (!gbSuspended) {
1928                 graphics_access_count = atomic_read(&g_graphics_access_count);
1929                 videoenc_access_count = atomic_read(&g_videoenc_access_count);
1930                 videodec_access_count = atomic_read(&g_videodec_access_count);
1931                 display_access_count = atomic_read(&g_display_access_count);
1932 #if (defined(CONFIG_SND_INTELMID_HDMI_AUDIO) || \
1933                 defined(CONFIG_SND_INTELMID_HDMI_AUDIO_MODULE))
1934                 if (dev_priv->had_pvt_data && hdmi_state) {
1935                         hdmi_audio_event.event = 0;
1936                         hdmi_audio_busy =
1937                                 had_interface->suspend(dev_priv->had_pvt_data,
1938                                                         hdmi_audio_event);
1939                 }
1940 #endif
1941
1942                 if (graphics_access_count
1943                         || videoenc_access_count
1944                         || videodec_access_count
1945                         || display_access_count
1946 #if (defined(CONFIG_SND_INTELMID_HDMI_AUDIO) || \
1947                 defined(CONFIG_SND_INTELMID_HDMI_AUDIO_MODULE))
1948                         || hdmi_audio_busy
1949 #endif
1950                 )
1951                         ret = -EBUSY;
1952                 if (!ret) {
1953                         gbSuspendInProgress = true;
1954
1955                         //! may cause runtime resume during early suspend
1956                         //psb_irq_uninstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
1957                         ospm_suspend_display(gpDrmDevice);
1958 #if 0   /* FIXME: video driver support for Linux Runtime PM */
1959                         /* FIXME: video driver support for Linux Runtime PM */
1960                         if (ospm_runtime_pm_msvdx_suspend(gpDrmDevice) != 0) {
1961                                 suspend_pci = false;
1962                         }
1963
1964 #endif
1965                         if (ospm_runtime_pm_topaz_suspend(gpDrmDevice) != 0)
1966                                 ret = -EBUSY;
1967
1968                         if (!ret)
1969                                 ospm_suspend_pci(pdev);
1970                         gbSuspendInProgress = false;
1971                 } else {
1972                         printk(KERN_ALERT "ospm_power_suspend: device busy: graphics %d videoenc %d videodec %d display %d\n", graphics_access_count, videoenc_access_count, videodec_access_count, display_access_count);
1973                 }
1974         }
1975
1976
1977         mutex_unlock(&g_ospm_mutex);
1978         return ret;
1979 }
1980
1981 /*
1982  * ospm_power_island_up
1983  *
1984  * Description: Restore power to the specified island(s) (powergating)
1985  */
1986 void ospm_power_island_up(int hw_islands)
1987 {
1988         u32 dc_islands  = 0;
1989         u32 gfx_islands = hw_islands;
1990         unsigned long flags;
1991         struct drm_psb_private *dev_priv =
1992                 (struct drm_psb_private *) gpDrmDevice->dev_private;
1993
1994 #ifdef OSPM_GFX_DPK
1995          printk(KERN_ALERT "%s hw_islands: %x\n",
1996                  __func__, hw_islands);
1997 #endif
1998         if (hw_islands & OSPM_DISPLAY_ISLAND) {
1999
2000 #ifdef CONFIG_MDFD_HDMI
2001                 if (IS_MDFLD_OLD(dev_priv->dev)) {
2002                         /*
2003                          * Always turn on MSIC VCC330 and VHDMI when display is
2004                          * on.
2005                          */
2006                         intel_scu_ipc_iowrite8(MSIC_VCC330CNT, VCC330_ON);
2007                         /*
2008                          * MSIC documentation requires that there be a 500us
2009                          * delay after enabling VCC330 before you can enable
2010                          * VHDMI
2011                          */
2012                         usleep_range(500, 1000);
2013                         /* turn on HDMI power rails */
2014                         intel_scu_ipc_iowrite8(MSIC_VHDMICNT,
2015                                         VHDMI_ON | VHDMI_DB_30MS);
2016                 }
2017 #endif
2018                 /*Power-up required islands only*/
2019                 if (dev_priv->panel_desc & DISPLAY_A)
2020                         dc_islands |= OSPM_DISPLAY_A_ISLAND;
2021
2022                 if (dev_priv->panel_desc & DISPLAY_B)
2023                         dc_islands |= OSPM_DISPLAY_B_ISLAND;
2024
2025                 if (dev_priv->panel_desc & DISPLAY_C)
2026                         dc_islands |= OSPM_DISPLAY_C_ISLAND;
2027
2028                 if (dev_priv->panel_desc)
2029                         dc_islands |= OSPM_MIPI_ISLAND;
2030
2031                 /*
2032                 If pmu_nc_set_power_state fails then accessing HW
2033                 reg would result in a crash - IERR/Fabric error.
2034                 */
2035                 spin_lock_irqsave(&dev_priv->ospm_lock, flags);
2036                 if (pmu_nc_set_power_state(dc_islands,
2037                         OSPM_ISLAND_UP, OSPM_REG_TYPE))
2038                         BUG();
2039                 g_hw_power_status_mask |= OSPM_DISPLAY_ISLAND;
2040                 spin_unlock_irqrestore(&dev_priv->ospm_lock, flags);
2041
2042                 /* handle other islands */
2043                 gfx_islands = hw_islands & ~OSPM_DISPLAY_ISLAND;
2044         }
2045
2046         if (gfx_islands) {
2047 #ifdef OSPM_GFX_DPK
2048                 printk(KERN_ALERT "%s other hw_islands: %x\n",
2049                          __func__, gfx_islands);
2050 #endif
2051                 /*
2052                 If pmu_nc_set_power_state fails then accessing HW
2053                 reg would result in a crash - IERR/Fabric error.
2054                 */
2055 #ifdef CONFIG_MDFD_GL3
2056                 if (IS_D0(gpDrmDevice)) {
2057                         /*
2058                          * GL3 power island needs to be on for MSVDX working.
2059                          * We found this during enabling new MSVDX firmware
2060                          * uploading mechanism(by PUNIT) for Penwell D0.
2061                          */
2062                         if ((gfx_islands & OSPM_VIDEO_DEC_ISLAND) &&
2063                                         !ospm_power_is_hw_on(OSPM_GL3_CACHE_ISLAND))
2064                                 gfx_islands |= OSPM_GL3_CACHE_ISLAND;
2065                 }
2066 #endif
2067                 spin_lock_irqsave(&dev_priv->ospm_lock, flags);
2068                 if (pmu_nc_set_power_state(gfx_islands,
2069                                            OSPM_ISLAND_UP, APM_REG_TYPE))
2070                         BUG();
2071                 g_hw_power_status_mask |= gfx_islands;
2072                 spin_unlock_irqrestore(&dev_priv->ospm_lock, flags);
2073         }
2074 }
2075 /*
2076  * ospm_power_resume
2077  */
2078 int ospm_power_resume(struct pci_dev *pdev)
2079 {
2080         if(gbSuspendInProgress || gbResumeInProgress)
2081         {
2082 #ifdef OSPM_GFX_DPK
2083                 printk(KERN_ALERT "%s: Suspend/ResumeInProgress\n",
2084                         __func__);
2085 #endif
2086                 return 0;
2087         }
2088
2089         mutex_lock(&g_ospm_mutex);
2090
2091 #ifdef OSPM_GFX_DPK
2092         printk(KERN_ALERT "OSPM_GFX_DPK: ospm_power_resume\n");
2093 #endif
2094
2095         gbResumeInProgress = true;
2096
2097         ospm_resume_pci(pdev);
2098
2099         ospm_resume_display(gpDrmDevice->pdev);
2100         psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
2101         psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
2102
2103         gbResumeInProgress = false;
2104
2105         mutex_unlock(&g_ospm_mutex);
2106
2107         return 0;
2108 }
2109
2110
2111 /*
2112  * ospm_power_island_down
2113  *
2114  * Description: Cut power to the specified island(s) (powergating)
2115  */
2116 void ospm_power_island_down(int hw_islands)
2117 {
2118         u32 dc_islands = 0;
2119         u32 gfx_islands = hw_islands;
2120         unsigned long flags;
2121         struct drm_psb_private *dev_priv =
2122                 (struct drm_psb_private *) gpDrmDevice->dev_private;
2123
2124 #ifdef OSPM_GFX_DPK
2125         printk(KERN_ALERT "%s hw_islands: %x\n",
2126                 __func__, hw_islands);
2127 #endif
2128
2129         if (hw_islands & OSPM_DISPLAY_ISLAND) {
2130                 /*Power gate all display islands.*/
2131                 dc_islands |= (OSPM_DISPLAY_A_ISLAND |
2132                                 OSPM_DISPLAY_B_ISLAND |
2133                                 OSPM_DISPLAY_C_ISLAND |
2134                                 OSPM_MIPI_ISLAND);
2135
2136                 /*
2137                 If pmu_nc_set_power_state fails then accessing HW
2138                 reg would result in a crash - IERR/Fabric error.
2139                 */
2140                 spin_lock_irqsave(&dev_priv->ospm_lock, flags);
2141                 g_hw_power_status_mask &= ~OSPM_DISPLAY_ISLAND;
2142                 if (pmu_nc_set_power_state(dc_islands,
2143                                            OSPM_ISLAND_DOWN, OSPM_REG_TYPE))
2144                         BUG();
2145                 spin_unlock_irqrestore(&dev_priv->ospm_lock, flags);
2146
2147 #ifdef CONFIG_MDFD_HDMI
2148                 if (IS_MDFLD_OLD(dev_priv->dev)) {
2149                         /*
2150                          * Turn off MSIC VCC330 and VHDMI if HDMI is
2151                          * disconnected.
2152                          */
2153                         if (!hdmi_state) {
2154                                 /* turn off HDMI power rails */
2155                                 intel_scu_ipc_iowrite8(MSIC_VHDMICNT,
2156                                                 VHDMI_OFF);
2157                                 intel_scu_ipc_iowrite8(MSIC_VCC330CNT,
2158                                                 VCC330_OFF);
2159                         }
2160                 }
2161 #endif
2162                 /* handle other islands */
2163                 gfx_islands = hw_islands & ~OSPM_DISPLAY_ISLAND;
2164         }
2165
2166         if (gfx_islands) {
2167 #ifdef OSPM_GFX_DPK
2168                 printk(KERN_ALERT "%s other hw_islands: %x\n",
2169                          __func__, gfx_islands);
2170 #endif
2171                 spin_lock_irqsave(&dev_priv->ospm_lock, flags);
2172                 if (gfx_islands & OSPM_GL3_CACHE_ISLAND) {
2173 #ifdef CONFIG_MDFD_GL3
2174                         /*
2175                         Make sure both GFX & Video aren't
2176                         using GL3
2177                         */
2178                         if (atomic_read(&g_graphics_access_count) ||
2179                                         (g_hw_power_status_mask &
2180                                         (OSPM_VIDEO_DEC_ISLAND |
2181                                         OSPM_VIDEO_ENC_ISLAND |
2182                                         OSPM_GRAPHICS_ISLAND)) ||
2183                                         (drm_psb_gl3_enable == 0)) {
2184 #ifdef OSPM_GFX_DPK
2185                                 printk(KERN_ALERT
2186                                 "%s GL3 in use - can't turn OFF\n",
2187                                 __func__);
2188 #endif
2189                                 gfx_islands &=  ~OSPM_GL3_CACHE_ISLAND;
2190                                 if (!gfx_islands)
2191                                         goto out;
2192                         }
2193 #endif
2194                 }
2195
2196                 /*
2197                 If pmu_nc_set_power_state fails then accessing HW
2198                 reg would result in a crash - IERR/Fabric error.
2199                 */
2200                 g_hw_power_status_mask &= ~gfx_islands;
2201                 if (pmu_nc_set_power_state(gfx_islands,
2202                         OSPM_ISLAND_DOWN, APM_REG_TYPE))
2203                         BUG();
2204 out:
2205                 spin_unlock_irqrestore(&dev_priv->ospm_lock, flags);
2206         }
2207 }
2208
2209 /*
2210  * ospm_power_is_hw_on
2211  *
2212  * Description: do an instantaneous check for if the specified islands
2213  * are on.  Only use this in cases where you know the g_state_change_mutex
2214  * is already held such as in irq install/uninstall.  Otherwise, use
2215  * ospm_power_using_hw_begin().
2216  */
2217 bool ospm_power_is_hw_on(int hw_islands)
2218 {
2219         unsigned long flags;
2220         struct drm_psb_private *dev_priv =
2221                 (struct drm_psb_private *) gpDrmDevice->dev_private;
2222         bool ret = false;
2223         spin_lock_irqsave(&dev_priv->ospm_lock, flags);
2224         ret = ((g_hw_power_status_mask & hw_islands)
2225                         == hw_islands) ? true : false;
2226         spin_unlock_irqrestore(&dev_priv->ospm_lock, flags);
2227         return ret;
2228 }
2229
2230 /*
2231  * ospm_power_using_hw_begin
2232  *
2233  * Description: Notify PowerMgmt module that you will be accessing the
2234  * specified island's hw so don't power it off.  If force_on is true,
2235  * this will power on the specified island if it is off.
2236  * Otherwise, this will return false and the caller is expected to not
2237  * access the hw.
2238  *
2239  * NOTE *** If this is called from and interrupt handler or other atomic
2240  * context, then it will return false if we are in the middle of a
2241  * power state transition and the caller will be expected to handle that
2242  * even if force_on is set to true.
2243  */
2244 bool ospm_power_using_hw_begin(int hw_island, UHBUsage usage)
2245 {
2246         bool ret = true;
2247         bool island_is_off = false;
2248         bool b_atomic = (in_interrupt() || in_atomic());
2249         bool locked = true;
2250         struct pci_dev *pdev = gpDrmDevice->pdev;
2251         IMG_UINT32 deviceID = 0;
2252         bool force_on = usage ? true: false;
2253
2254 #ifdef CONFIG_GFX_RTPM
2255         if(gbSuspendInProgress) {
2256 #ifdef OSPM_GFX_DPK
2257                 printk(KERN_ALERT "%s Suspend In Progress, call pm_runtime_get_noresume\n", __func__);
2258 #endif
2259                 pm_runtime_get_noresume(&pdev->dev);
2260         } else {
2261                 pm_runtime_get(&pdev->dev);
2262         }
2263 #endif
2264         /*quick path, not 100% race safe, but should be enough comapre to current other code in this file */
2265         if (!force_on) {
2266                 if (!ospm_power_is_hw_on(hw_island)) {
2267 #ifdef CONFIG_GFX_RTPM
2268                         pm_runtime_put(&pdev->dev);
2269 #endif
2270                         return false;
2271         }
2272                 else {
2273                         locked = false;
2274                         goto increase_count;
2275                 }
2276         }
2277         if (!b_atomic)
2278                 mutex_lock(&g_ospm_mutex);
2279
2280         island_is_off = !ospm_power_is_hw_on(hw_island);
2281
2282         if (b_atomic && (gbSuspendInProgress || gbResumeInProgress || gbSuspended) && force_on && island_is_off)
2283                 ret = false;
2284
2285         if (ret && island_is_off && !force_on)
2286                 ret = false;
2287
2288         if (ret && island_is_off && force_on) {
2289                 gbResumeInProgress = true;
2290
2291                 ret = ospm_resume_pci(pdev);
2292
2293                 if (ret) {
2294                         switch(hw_island)
2295                         {
2296                         case OSPM_DISPLAY_ISLAND:
2297                                 deviceID = gui32MRSTDisplayDeviceID;
2298                                 ospm_resume_display(pdev);
2299                                 psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
2300                                 psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
2301                                 break;
2302                         case OSPM_GRAPHICS_ISLAND:
2303                                 deviceID = gui32SGXDeviceID;
2304 #ifdef CONFIG_MDFD_GL3
2305                                 ospm_power_island_up(OSPM_GRAPHICS_ISLAND |
2306                                                 OSPM_GL3_CACHE_ISLAND);
2307 #else
2308                                 ospm_power_island_up(OSPM_GRAPHICS_ISLAND);
2309 #endif
2310                                 psb_irq_preinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND);
2311                                 psb_irq_postinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND);
2312                                 break;
2313 #if 1 /* for debugging video driver ospm */
2314                         case OSPM_VIDEO_DEC_ISLAND:
2315                                 if(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
2316                                         /* printk(KERN_ALERT "%s power on display for video decode use\n", __func__); */
2317                                         deviceID = gui32MRSTDisplayDeviceID;
2318                                         ospm_resume_display(pdev);
2319                                         psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
2320                                         psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
2321                                 }
2322                                 else{
2323                                         /* printk(KERN_ALERT "%s display is already on for video decode use\n", __func__);*/
2324                                 }
2325
2326                                 if(!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) {
2327                                         /* printk(KERN_ALERT "%s power on video decode\n", __func__); */
2328                                         deviceID = gui32MRSTMSVDXDeviceID;
2329 #ifdef CONFIG_MDFD_GL3
2330                                         ospm_power_island_up(OSPM_GL3_CACHE_ISLAND | OSPM_VIDEO_DEC_ISLAND);
2331                                         if (IS_D0(gpDrmDevice)) {
2332                                                 struct drm_psb_private *dev_priv =
2333                                                         (struct drm_psb_private *) gpDrmDevice->dev_private;
2334                                                 int ret;
2335
2336                                                 ret = psb_wait_for_register(dev_priv, MSVDX_COMMS_SIGNATURE,
2337                                                                             MSVDX_COMMS_SIGNATURE_VALUE,
2338                                                                             0xffffffff);
2339                                                 if (ret)
2340                                                         DRM_ERROR("MSVDX: firmware fails to initialize.\n");
2341                                         }
2342 #else
2343                                         ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND);
2344 #endif
2345                                         ospm_runtime_pm_msvdx_resume(gpDrmDevice);
2346                                         psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND);
2347                                         psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND);
2348                                 }
2349                                 else{
2350                                         /* printk(KERN_ALERT "%s video decode is already on\n", __func__); */
2351                                 }
2352
2353                                 break;
2354                         case OSPM_VIDEO_ENC_ISLAND:
2355                                 if (IS_MRST(gpDrmDevice) &&
2356                                                 (!ospm_power_is_hw_on(
2357                                                         OSPM_DISPLAY_ISLAND))) {
2358                                         deviceID = gui32MRSTDisplayDeviceID;
2359                                         ospm_resume_display(pdev);
2360                                         psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
2361                                         psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
2362                                 }
2363
2364                                 if(!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) {
2365                                         /* printk(KERN_ALERT "%s power on video encode\n", __func__); */
2366                                         deviceID = gui32MRSTTOPAZDeviceID;
2367 #ifdef CONFIG_MDFD_GL3
2368                                         ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND);
2369                                         ospm_power_island_up(OSPM_GL3_CACHE_ISLAND);
2370 #else
2371                                         ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND);
2372 #endif
2373                                         ospm_runtime_pm_topaz_resume(gpDrmDevice);
2374                                         psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND);
2375                                         psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND);
2376                                 }
2377                                 else{
2378                                         /* printk(KERN_ALERT "%s video decode is already on\n", __func__); */
2379                                 }
2380 #endif
2381                                 break;
2382                         default:
2383                                 printk(KERN_ALERT "%s unknown island !!!!\n",
2384                                                 __func__);
2385                                 break;
2386                         }
2387
2388                 }
2389
2390                 if (!ret)
2391                         printk(KERN_ALERT "%s: %d failed\n",
2392                                         __func__, hw_island);
2393
2394                 gbResumeInProgress = false;
2395         }
2396 increase_count:
2397         if (ret) {
2398                 switch(hw_island)
2399                 {
2400                 case OSPM_GRAPHICS_ISLAND:
2401                         atomic_inc(&g_graphics_access_count);
2402                         break;
2403                 case OSPM_VIDEO_ENC_ISLAND:
2404                         atomic_inc(&g_videoenc_access_count);
2405                         break;
2406                 case OSPM_VIDEO_DEC_ISLAND:
2407                         atomic_inc(&g_videodec_access_count);
2408                         break;
2409                 case OSPM_DISPLAY_ISLAND:
2410                         atomic_inc(&g_display_access_count);
2411                         break;
2412                 }
2413
2414         }
2415 #ifdef CONFIG_GFX_RTPM
2416         else{
2417                 pm_runtime_put(&pdev->dev);
2418         }
2419 #endif
2420
2421         if (!b_atomic && locked)
2422                 mutex_unlock(&g_ospm_mutex);
2423
2424         return ret;
2425 }
2426 EXPORT_SYMBOL(ospm_power_using_hw_begin);
2427
2428
2429 /*
2430  * ospm_power_using_hw_end
2431  *
2432  * Description: Notify PowerMgmt module that you are done accessing the
2433  * specified island's hw so feel free to power it off.  Note that this
2434  * function doesn't actually power off the islands.
2435  */
2436 void ospm_power_using_hw_end(int hw_island)
2437 {
2438         switch(hw_island)
2439         {
2440         case OSPM_GRAPHICS_ISLAND:
2441                 atomic_dec(&g_graphics_access_count);
2442                 break;
2443         case OSPM_VIDEO_ENC_ISLAND:
2444                 atomic_dec(&g_videoenc_access_count);
2445                 break;
2446         case OSPM_VIDEO_DEC_ISLAND:
2447                 atomic_dec(&g_videodec_access_count);
2448                 break;
2449         case OSPM_DISPLAY_ISLAND:
2450                 atomic_dec(&g_display_access_count);
2451                 break;
2452         }
2453
2454 #ifdef CONFIG_GFX_RTPM
2455         /* decrement runtime pm ref count */
2456         pm_runtime_put(&gpDrmDevice->pdev->dev);
2457 #endif
2458
2459         WARN_ON(atomic_read(&g_graphics_access_count) < 0);
2460         WARN_ON(atomic_read(&g_videoenc_access_count) < 0);
2461         WARN_ON(atomic_read(&g_videodec_access_count) < 0);
2462         WARN_ON(atomic_read(&g_display_access_count) < 0);
2463 }
2464 EXPORT_SYMBOL(ospm_power_using_hw_end);
2465
2466 int ospm_runtime_pm_allow(struct drm_device * dev)
2467 {
2468         struct drm_psb_private * dev_priv = dev->dev_private;
2469         bool panel_on, panel_on2;
2470
2471         PSB_DEBUG_ENTRY("%s\n", __func__);
2472
2473 #ifdef OSPM_GFX_DPK
2474         printk(KERN_ALERT "%s\n", __func__);
2475 #endif
2476         if(dev_priv->rpm_enabled)
2477                 return 0;
2478
2479         if(is_panel_vid_or_cmd(dev)) {
2480                 /*DPI panel*/
2481                 panel_on = dev_priv->dpi_panel_on;
2482                 panel_on2 = dev_priv->dpi_panel_on2;
2483         } else {
2484                 /*DBI panel*/
2485                 panel_on = dev_priv->dbi_panel_on;
2486                 panel_on2 = dev_priv->dbi_panel_on2;
2487         }
2488
2489 #ifdef CONFIG_GFX_RTPM
2490         if(panel_on && panel_on2) {
2491                 pm_runtime_allow(&dev->pdev->dev);
2492                 dev_priv->rpm_enabled = 1;
2493                 DRM_INFO("Runtime PM enabled\n");
2494         }
2495 #endif
2496
2497         return 0;
2498 }
2499
2500 void ospm_runtime_pm_forbid(struct drm_device * dev)
2501 {
2502         struct drm_psb_private * dev_priv = dev->dev_private;
2503
2504         DRM_INFO("%s\n", __func__);
2505
2506 #ifdef OSPM_GFX_DPK
2507         printk(KERN_ALERT "%s\n", __func__);
2508 #endif
2509
2510 #ifdef CONFIG_GFX_RTPM
2511         pm_runtime_forbid(&dev->pdev->dev);
2512 #endif
2513         dev_priv->rpm_enabled = 0;
2514 }
2515
2516 int psb_runtime_suspend(struct device *dev)
2517 {
2518         pm_message_t state;
2519         int ret = 0;
2520         state.event = 0;
2521 #ifdef OSPM_GFX_DPK
2522         printk(KERN_ALERT "%s\n", __func__);
2523 #endif
2524         if (atomic_read(&g_graphics_access_count) || atomic_read(&g_videoenc_access_count)
2525                 || (gbdispstatus == true)
2526                 || atomic_read(&g_videodec_access_count) || atomic_read(&g_display_access_count)){
2527 #ifdef OSPM_GFX_DPK
2528                 printk(KERN_ALERT "GFX:%d VEC:%d VED:%d DC:%d DSR:%d\n",
2529                         atomic_read(&g_graphics_access_count),
2530                         atomic_read(&g_videoenc_access_count),
2531                         atomic_read(&g_videodec_access_count),
2532                         atomic_read(&g_display_access_count), gbdispstatus);
2533 #endif
2534                 return -EBUSY;
2535         }
2536         else
2537                 ret = ospm_power_suspend(gpDrmDevice->pdev, state);
2538
2539         return ret;
2540 }
2541
2542 int psb_runtime_resume(struct device *dev)
2543 {
2544         /* Notify HDMI Audio sub-system about the resume. */
2545
2546 #ifdef OSPM_GFX_DPK
2547         printk(KERN_ALERT "%s\n", __func__);
2548 #endif
2549         /* Nop for GFX */
2550         return 0;
2551 }
2552
2553 int psb_runtime_idle(struct device *dev)
2554 {
2555 #if (defined(CONFIG_SND_INTELMID_HDMI_AUDIO) || \
2556                 defined(CONFIG_SND_INTELMID_HDMI_AUDIO_MODULE))
2557         struct drm_psb_private* dev_priv = gpDrmDevice->dev_private;
2558         struct snd_intel_had_interface *had_interface = dev_priv->had_interface;
2559         int hdmi_audio_busy = 0;
2560         pm_event_t hdmi_audio_event;
2561         char *uevent_string = NULL;
2562
2563         if (dev_priv->had_pvt_data && hdmi_state) {
2564                 hdmi_audio_event.event = 0;
2565                 hdmi_audio_busy =
2566                         had_interface->suspend(dev_priv->had_pvt_data,
2567                                         hdmi_audio_event);
2568                 if (!hdmi_audio_busy) {
2569                         uevent_string = "HDMI_AUDIO_PM_SUSPENDED=1";
2570                         psb_sysfs_uevent(dev_priv->dev, uevent_string);
2571                 }
2572         }
2573 #endif
2574
2575         if (atomic_read(&g_graphics_access_count) || atomic_read(&g_videoenc_access_count)
2576                 || atomic_read(&g_videodec_access_count) || atomic_read(&g_display_access_count)
2577                 || (gbdispstatus == true)
2578 #if (defined(CONFIG_SND_INTELMID_HDMI_AUDIO) || \
2579         defined(CONFIG_SND_INTELMID_HDMI_AUDIO_MODULE))
2580                 || hdmi_audio_busy
2581 #endif
2582
2583 #if 0   /* FIXME: video driver support for Linux Runtime PM */
2584                 || (msvdx_hw_busy == 1)
2585                 || (topaz_hw_busy == 1))
2586 #else
2587                 )
2588 #endif
2589                         return -EBUSY;
2590                 else
2591                         return 0;
2592 }