1 /**************************************************************************
2 * Copyright (c) 2009, Intel Corporation.
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:
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
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
25 * Benjamin Defnet <benjamin.r.defnet@intel.com>
26 * Rajesh Poornachandran <rajesh.poornachandran@intel.com>
29 #include "psb_powermgmt.h"
31 #include "psb_intel_reg.h"
32 #include "psb_msvdx.h"
33 #include "pnw_topaz.h"
34 #include "mdfld_gl3.h"
35 #include "pvr_trace_cmd.h"
37 #include <linux/mutex.h>
38 #include <linux/intel_mid_pm.h>
39 #include "mdfld_dsi_dbi.h"
40 #include "mdfld_dsi_dbi_dpu.h"
41 #include <asm/intel_scu_ipc.h>
45 struct drm_device *gpDrmDevice = NULL;
46 static struct mutex g_ospm_mutex;
47 static int g_hw_power_status_mask;
48 static atomic_t g_display_access_count;
49 static atomic_t g_graphics_access_count;
50 static atomic_t g_videoenc_access_count;
51 static atomic_t g_videodec_access_count;
53 void ospm_power_island_up(int hw_islands);
54 void ospm_power_island_down(int hw_islands);
55 static bool gbSuspended = false;
56 static int psb_runtime_hdmi_audio_suspend(struct drm_device *drm_dev);
59 static int ospm_runtime_check_msvdx_hw_busy(struct drm_device *dev)
61 struct drm_psb_private *dev_priv = dev->dev_private;
62 struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
65 if (!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) {
66 //printk(KERN_ALERT "%s VIDEO DEC HW is not on\n", __func__);
71 msvdx_priv->msvdx_hw_busy = REG_READ(0x20D0) & (0x1 << 9);
72 if (psb_check_msvdx_idle(dev)) {
73 //printk(KERN_ALERT "%s video decode hw busy\n", __func__);
76 //printk(KERN_ALERT "%s video decode hw idle\n", __func__);
83 static int ospm_runtime_check_topaz_hw_busy(struct drm_device *dev)
85 //struct drm_psb_private *dev_priv = dev->dev_private;
86 //struct topaz_private *topaz_priv = dev_priv->topaz_private;
89 if (!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) {
90 //printk(KERN_ALERT "%s VIDEO ENC HW is not on\n", __func__);
95 //topaz_priv->topaz_hw_busy = REG_READ(0x20D0) & (0x1 << 11);
97 if (pnw_check_topaz_idle(dev)) {
98 //printk(KERN_ALERT "%s video encode hw busy %d\n", __func__,
99 // topaz_priv->topaz_hw_busy);
102 //printk(KERN_ALERT "%s video encode hw idle\n", __func__);
109 static int ospm_runtime_pm_msvdx_suspend(struct drm_device *dev)
112 struct drm_psb_private *dev_priv = dev->dev_private;
113 struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
115 //printk(KERN_ALERT "enter %s\n", __func__);
117 if (!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) {
118 //printk(KERN_ALERT "%s VIDEO DEC HW is not on\n", __func__);
122 if (atomic_read(&g_videodec_access_count)) {
123 //printk(KERN_ALERT "%s videodec access count exit\n", __func__);
128 msvdx_priv->msvdx_hw_busy = REG_READ(0x20D0) & (0x1 << 9);
129 if (psb_check_msvdx_idle(dev)) {
130 //printk(KERN_ALERT "%s video decode hw busy exit\n", __func__);
135 MSVDX_NEW_PMSTATE(dev, msvdx_priv, PSB_PMSTATE_POWERDOWN);
136 psb_irq_uninstall_islands(dev, OSPM_VIDEO_DEC_ISLAND);
137 psb_msvdx_save_context(dev);
138 ospm_power_island_down(OSPM_VIDEO_DEC_ISLAND);
139 //printk(KERN_ALERT "%s done\n", __func__);
144 static int ospm_runtime_pm_msvdx_resume(struct drm_device *dev)
146 struct drm_psb_private *dev_priv = dev->dev_private;
147 struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
149 //printk(KERN_ALERT "ospm_runtime_pm_msvdx_resume\n");
151 MSVDX_NEW_PMSTATE(dev, msvdx_priv, PSB_PMSTATE_POWERUP);
153 psb_msvdx_restore_context(dev);
158 static int ospm_runtime_pm_topaz_suspend(struct drm_device *dev)
161 struct drm_psb_private *dev_priv = dev->dev_private;
162 struct pnw_topaz_private *pnw_topaz_priv = dev_priv->topaz_private;
163 struct psb_video_ctx *pos, *n;
164 int encode_ctx = 0, encode_running = 0;
166 //printk(KERN_ALERT "enter %s\n", __func__);
167 list_for_each_entry_safe(pos, n, &dev_priv->video_ctx, head) {
168 int entrypoint = pos->ctx_type & 0xff;
169 if (entrypoint == VAEntrypointEncSlice ||
170 entrypoint == VAEntrypointEncPicture) {
176 /* have encode context, but not started, or is just closed */
177 if (encode_ctx && dev_priv->topaz_ctx)
181 PSB_DEBUG_PM("Topaz: has encode context, running=%d\n",
184 PSB_DEBUG_PM("Topaz: no encode context\n");
186 if (!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) {
187 //printk(KERN_ALERT "%s VIDEO ENC HW is not on\n", __func__);
191 if (atomic_read(&g_videoenc_access_count)) {
192 //printk(KERN_ALERT "%s videoenc access count exit\n", __func__);
197 if (pnw_check_topaz_idle(dev)) {
198 //printk(KERN_ALERT "%s video encode hw busy exit\n", __func__);
203 psb_irq_uninstall_islands(dev, OSPM_VIDEO_ENC_ISLAND);
205 if (encode_running) /* has encode session running */
206 pnw_topaz_save_mtx_state(dev);
207 PNW_TOPAZ_NEW_PMSTATE(dev, pnw_topaz_priv, PSB_PMSTATE_POWERDOWN);
209 ospm_power_island_down(OSPM_VIDEO_ENC_ISLAND);
210 //printk(KERN_ALERT "%s done\n", __func__);
215 static int ospm_runtime_pm_topaz_resume(struct drm_device *dev)
217 struct drm_psb_private *dev_priv = dev->dev_private;
218 struct pnw_topaz_private *pnw_topaz_priv = dev_priv->topaz_private;
219 struct psb_video_ctx *pos, *n;
220 int encode_ctx = 0, encode_running = 0;
222 //printk(KERN_ALERT "ospm_runtime_pm_topaz_resume\n");
223 list_for_each_entry_safe(pos, n, &dev_priv->video_ctx, head) {
224 int entrypoint = pos->ctx_type & 0xff;
225 if (entrypoint == VAEntrypointEncSlice ||
226 entrypoint == VAEntrypointEncPicture) {
232 /* have encode context, but not started, or is just closed */
233 if (encode_ctx && dev_priv->topaz_ctx)
237 PSB_DEBUG_PM("Topaz: has encode context, running=%d\n",
240 PSB_DEBUG_PM("Topaz: no encode running\n");
242 if (encode_running) { /* has encode session running */
243 psb_irq_uninstall_islands(dev, OSPM_VIDEO_ENC_ISLAND);
244 pnw_topaz_restore_mtx_state(dev);
246 PNW_TOPAZ_NEW_PMSTATE(dev, pnw_topaz_priv, PSB_PMSTATE_POWERUP);
252 #ifdef FIX_OSPM_POWER_DOWN
253 void ospm_apm_power_down_msvdx(struct drm_device *dev)
256 mutex_lock(&g_ospm_mutex);
258 if (atomic_read(&g_videodec_access_count))
260 if (psb_check_msvdx_idle(dev))
263 psb_msvdx_save_context(dev);
264 #ifdef FIXME_MRST_VIDEO_DEC
265 ospm_power_island_down(OSPM_VIDEO_DEC_ISLAND);
268 mutex_unlock(&g_ospm_mutex);
272 void ospm_apm_power_down_topaz(struct drm_device *dev)
274 return; /* todo for OSPM */
276 mutex_lock(&g_ospm_mutex);
278 if (atomic_read(&g_videoenc_access_count))
280 if (lnc_check_topaz_idle(dev))
283 lnc_topaz_save_mtx_state(dev);
284 ospm_power_island_down(OSPM_VIDEO_ENC_ISLAND);
286 mutex_unlock(&g_ospm_mutex);
290 void ospm_apm_power_down_msvdx(struct drm_device *dev)
292 struct drm_psb_private *dev_priv = dev->dev_private;
293 struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
295 mutex_lock(&g_ospm_mutex);
296 if (!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND))
299 if (atomic_read(&g_videodec_access_count))
301 if (psb_check_msvdx_idle(dev))
304 psb_msvdx_save_context(dev);
305 ospm_power_island_down(OSPM_VIDEO_DEC_ISLAND);
306 MSVDX_NEW_PMSTATE(dev, msvdx_priv, PSB_PMSTATE_POWERDOWN);
308 mutex_unlock(&g_ospm_mutex);
312 void ospm_apm_power_down_topaz(struct drm_device *dev)
314 struct drm_psb_private *dev_priv = dev->dev_private;
315 struct pnw_topaz_private *pnw_topaz_priv = dev_priv->topaz_private;
317 mutex_lock(&g_ospm_mutex);
319 if (!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND))
321 if (atomic_read(&g_videoenc_access_count))
323 if (pnw_check_topaz_idle(dev))
326 psb_irq_uninstall_islands(dev, OSPM_VIDEO_ENC_ISLAND);
327 pnw_topaz_save_mtx_state(dev);
328 PNW_TOPAZ_NEW_PMSTATE(dev, pnw_topaz_priv, PSB_PMSTATE_POWERDOWN);
330 ospm_power_island_down(OSPM_VIDEO_ENC_ISLAND);
332 mutex_unlock(&g_ospm_mutex);
337 #ifdef CONFIG_EARLYSUSPEND
339 * REVISIT: The early suspend and late resume handlers should not call
340 * pm_runtime_put() and pm_runtime_get_sync() directly, but rather the DPMS
341 * handlers should do it.
343 static void gfx_early_suspend(struct early_suspend *es)
345 struct drm_psb_private *dev_priv =
346 container_of(es, struct drm_psb_private, early_suspend);
347 struct drm_device *dev = dev_priv->dev;
348 struct drm_encoder *encoder;
350 dev_dbg(&dev->pdev->dev, "%s\n", __func__);
351 dev_priv->hdmi_audio_busy =
352 psb_runtime_hdmi_audio_suspend(dev) == -EBUSY;
354 mutex_lock(&dev->mode_config.mutex);
355 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
356 struct drm_encoder_helper_funcs *ehf = encoder->helper_private;
357 if (drm_helper_encoder_in_use(encoder) && ehf && ehf->dpms
358 #ifndef JIRA_ANDROID-1553
360 * Local MIPI fails to turn back on from a DPMS off/on cycle if
361 * HDMI audio returns busy to disallow system suspend.
362 * Once ANDROID-1553 is fixed, the expectation is to turn off
363 * MIPI but keep display island on if there is active audio
364 * playback over HDMI.
365 * Refer Jira bug# Android-1553 for more details.
367 && !dev_priv->hdmi_audio_busy
370 ehf->dpms(encoder, DRM_MODE_DPMS_OFF);
372 mutex_unlock(&dev->mode_config.mutex);
374 pm_runtime_put(&dev->pdev->dev);
377 static void gfx_late_resume(struct early_suspend *es)
379 struct drm_psb_private *dev_priv =
380 container_of(es, struct drm_psb_private, early_suspend);
381 struct drm_device *dev = dev_priv->dev;
382 struct drm_encoder *encoder;
384 dev_dbg(&dev->pdev->dev, "%s\n", __func__);
386 pm_runtime_get_sync(&dev->pdev->dev);
388 mutex_lock(&dev->mode_config.mutex);
389 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
390 struct drm_encoder_helper_funcs *ehf = encoder->helper_private;
392 if (drm_helper_encoder_in_use(encoder) && ehf && ehf->mode_set
394 #ifndef JIRA_ANDROID-1553
396 Local MIPI fails to turn back on from a DPMS off/on cycle if HDMI
397 audio returns busy to disallow system suspend.
398 Once ANDROID-1553 is fixed, the expectation is to turn off MIPI but
399 keep display island on if there is active audio playback over HDMI
400 Refer Jira bug# Android-1553 for more details.
402 && !(dev_priv->hdmi_audio_busy)
405 struct drm_crtc *crtc = encoder->crtc;
408 ehf->mode_set(encoder,
411 ehf->dpms(encoder, DRM_MODE_DPMS_ON);
414 mutex_unlock(&dev->mode_config.mutex);
418 static inline unsigned long palette_reg(int pipe, int idx)
420 return PSB_PALETTE(pipe) + (idx << 2);
424 * mdfld_save_pipe_registers
426 * Description: We are going to suspend so save current display
429 * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio
431 static int mdfld_save_pipe_registers(struct drm_device *dev, int pipe)
434 struct drm_psb_private *dev_priv = dev->dev_private;
435 struct psb_pipe_regs *pr = &dev_priv->pipe_regs[pipe];
438 PSB_DEBUG_ENTRY("\n");
442 pr->pll_ctrl = PSB_RVDC32(PSB_DSI_PLL_CTRL);
443 pr->pll_div = PSB_RVDC32(PSB_DSI_PLL_DIV_M1);
444 pr->mipi_ctrl = PSB_RVDC32(MIPI_PORT_CONTROL(pipe));
447 pr->pll_ctrl = PSB_RVDC32(PSB_DPLL_CTRL);
448 pr->pll_div = PSB_RVDC32(PSB_DPLL_DIV0);
449 dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
450 dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
451 dev_priv->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL);
452 dev_priv->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL);
455 pr->mipi_ctrl = PSB_RVDC32(MIPI_PORT_CONTROL(pipe));
458 DRM_ERROR("%s, invalid pipe number. \n", __FUNCTION__);
462 /* Pipe & plane A info */
463 pr->pipe_conf = PSB_RVDC32(PSB_PIPECONF(pipe));
464 pr->dsp_cntr = PSB_RVDC32(PSB_DSPCNTR(pipe));
466 pr->htotal = PSB_RVDC32(PSB_HTOTAL(pipe));
467 pr->hblank = PSB_RVDC32(PSB_HBLANK(pipe));
468 pr->hsync = PSB_RVDC32(PSB_HSYNC(pipe));
469 pr->vtotal = PSB_RVDC32(PSB_VTOTAL(pipe));
470 pr->vblank = PSB_RVDC32(PSB_VBLANK(pipe));
471 pr->vsync = PSB_RVDC32(PSB_VSYNC(pipe));
472 pr->src = PSB_RVDC32(PSB_PIPESRC(pipe));
473 pr->dsp_stride = PSB_RVDC32(PSB_DSPSTRIDE(pipe));
474 pr->dsp_line_offs = PSB_RVDC32(PSB_DSPLINOFF(pipe));
475 pr->dsp_tile_offs = PSB_RVDC32(PSB_DSPTILEOFF(pipe));
476 pr->dsp_size = PSB_RVDC32(PSB_DSPSIZE(pipe));
477 pr->dsp_pos = PSB_RVDC32(PSB_DSPPOS(pipe));
478 pr->dsp_surf = PSB_RVDC32(PSB_DSPSURF(pipe));
479 pr->dsp_status = PSB_RVDC32(PSB_PIPESTAT(pipe));
481 /*save palette (gamma) */
482 for (i = 0; i < ARRAY_SIZE(pr->palette); i++)
483 pr->palette[i] = PSB_RVDC32(palette_reg(pipe, i));
488 * mdfld_save_cursor_overlay_registers
490 * Description: We are going to suspend so save current cursor and overlay display
493 static int mdfld_save_cursor_overlay_registers(struct drm_device *dev)
495 struct drm_psb_private *dev_priv = dev->dev_private;
499 dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
500 dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
501 dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);
503 dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
504 dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
505 dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
507 dev_priv->saveDSPCCURSOR_CTRL = PSB_RVDC32(CURCCNTR);
508 dev_priv->saveDSPCCURSOR_BASE = PSB_RVDC32(CURCBASE);
509 dev_priv->saveDSPCCURSOR_POS = PSB_RVDC32(CURCPOS);
512 for (i = 0; i < ARRAY_SIZE(dev_priv->overlays); i++)
513 mdfld_overlay_suspend(dev_priv->overlays[i]);
518 * mdfld_restore_pipe_registers
520 * Description: We are going to resume so restore display register state.
522 * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio
524 static int mdfld_restore_pipe_registers(struct drm_device *dev, int pipe)
527 //to get panel out of ULPS mode.
529 struct drm_psb_private *dev_priv = dev->dev_private;
530 struct psb_pipe_regs *pr = &dev_priv->pipe_regs[pipe];
531 struct mdfld_dsi_dbi_output * dsi_output = dev_priv->dbi_output;
532 struct mdfld_dsi_config * dsi_config = NULL;
539 PSB_DEBUG_ENTRY("\n");
543 dpll_reg = PSB_DSI_PLL_CTRL;
544 pll_div_reg = PSB_DSI_PLL_DIV_M1;
545 dsi_config = dev_priv->dsi_configs[0];
548 dpll_reg = PSB_DPLL_CTRL;
549 pll_div_reg = PSB_DPLL_DIV0;
552 dsi_output = dev_priv->dbi_output2;
553 dsi_config = dev_priv->dsi_configs[1];
556 DRM_ERROR("%s, invalid pipe number. \n", __FUNCTION__);
560 dpll_val = pr->pll_ctrl & ~DPLL_VCO_ENABLE;
562 /*make sure VGA plane is off. it initializes to on after reset!*/
563 PSB_WVDC32(0x80000000, VGACNTRL);
567 PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg);
568 PSB_RVDC32(dpll_reg);
569 PSB_WVDC32(pr->pll_div, pll_div_reg);
573 dpll = PSB_RVDC32(dpll_reg);
575 if (!(dpll & DPLL_VCO_ENABLE)) {
576 /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
577 if (dpll & MDFLD_PWR_GATE_EN) {
578 dpll &= ~MDFLD_PWR_GATE_EN;
579 PSB_WVDC32(dpll, dpll_reg);
580 /* FIXME_MDFLD PO - change 500 to 1 after PO */
584 PSB_WVDC32(pr->pll_div, pll_div_reg);
585 PSB_WVDC32(dpll_val, dpll_reg);
586 /* FIXME_MDFLD PO - change 500 to 1 after PO */
589 dpll_val |= DPLL_VCO_ENABLE;
590 PSB_WVDC32(dpll_val, dpll_reg);
591 PSB_RVDC32(dpll_reg);
593 if (REG_FLAG_WAIT_SET(PSB_PIPECONF(pipe),
594 PIPECONF_DSIPLL_LOCK)) {
595 DRM_ERROR("%s, can't lock DSIPLL.\n", __func__);
602 PSB_WVDC32(pr->htotal, PSB_HTOTAL(pipe));
603 PSB_WVDC32(pr->hblank, PSB_HBLANK(pipe));
604 PSB_WVDC32(pr->hsync, PSB_HSYNC(pipe));
605 PSB_WVDC32(pr->vtotal, PSB_VTOTAL(pipe));
606 PSB_WVDC32(pr->vblank, PSB_VBLANK(pipe));
607 PSB_WVDC32(pr->vsync, PSB_VSYNC(pipe));
608 PSB_WVDC32(pr->src, PSB_PIPESRC(pipe));
609 PSB_WVDC32(pr->dsp_status, PSB_PIPESTAT(pipe));
610 PSB_WVDC32(pr->dsp_stride, PSB_DSPSTRIDE(pipe));
611 PSB_WVDC32(pr->dsp_line_offs, PSB_DSPLINOFF(pipe));
612 PSB_WVDC32(pr->dsp_tile_offs, PSB_DSPTILEOFF(pipe));
613 PSB_WVDC32(pr->dsp_size, PSB_DSPSIZE(pipe));
614 PSB_WVDC32(pr->dsp_pos, PSB_DSPPOS(pipe));
615 PSB_WVDC32(pr->dsp_surf, PSB_DSPSURF(pipe));
618 /* restore palette (gamma) */
619 /*DRM_UDELAY(50000); */
620 for (i = 0; i < ARRAY_SIZE(pr->palette); i++)
621 PSB_WVDC32(pr->palette[i], palette_reg(pipe, i));
623 PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
624 PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
626 /*TODO: resume HDMI port */
628 /*TODO: resume pipe*/
631 PSB_WVDC32(pr->dsp_cntr & ~DISPLAY_PLANE_ENABLE,
637 /*set up pipe related registers*/
638 PSB_WVDC32(pr->mipi_ctrl, MIPI_PORT_CONTROL(pipe));
640 /*setup MIPI adapter + MIPI IP registers*/
642 mdfld_dsi_controller_init(dsi_config, pipe);
644 if (in_atomic() || in_interrupt())
650 PSB_WVDC32(pr->dsp_cntr, PSB_DSPCNTR(pipe));
652 if (in_atomic() || in_interrupt())
657 /* LP Hold Release */
658 temp = REG_READ(MIPI_PORT_CONTROL(pipe));
659 temp |= LP_OUTPUT_HOLD_RELEASE;
660 REG_WRITE(MIPI_PORT_CONTROL(pipe), temp);
663 if (pipe == PSB_PIPE_A) {
664 /* Set DSI host to exit from Utra Low Power State */
665 temp = REG_READ(MIPI_DEVICE_READY_REG(pipe));
668 temp |= EXIT_ULPS_DEV_READY;
669 REG_WRITE(MIPI_DEVICE_READY_REG(pipe), temp);
672 temp = REG_READ(MIPI_DEVICE_READY_REG(pipe));
674 temp |= EXITING_ULPS;
675 REG_WRITE(MIPI_DEVICE_READY_REG(pipe), temp);
680 PSB_WVDC32(pr->pipe_conf, PSB_PIPECONF(pipe));
682 /* restore palette (gamma) */
683 /*DRM_UDELAY(50000); */
684 for (i = 0; i < ARRAY_SIZE(pr->palette); i++)
685 PSB_WVDC32(pr->palette[i], palette_reg(pipe, i));
691 * mdfld_restore_cursor_overlay_registers
693 * Description: We are going to resume so restore cursor and overlay register state.
695 static int mdfld_restore_cursor_overlay_registers(struct drm_device *dev)
697 struct drm_psb_private *dev_priv = dev->dev_private;
701 PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
702 PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
703 PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);
705 PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR);
706 PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS);
707 PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE);
709 PSB_WVDC32(dev_priv->saveDSPCCURSOR_CTRL, CURCCNTR);
710 PSB_WVDC32(dev_priv->saveDSPCCURSOR_POS, CURCPOS);
711 PSB_WVDC32(dev_priv->saveDSPCCURSOR_BASE, CURCBASE);
713 for (i = 0; i < ARRAY_SIZE(dev_priv->overlays); i++)
714 mdfld_overlay_resume(dev_priv->overlays[i]);
720 * powermgmt_suspend_display
722 * Description: Suspend the display hardware saving state and disabling
725 static void ospm_suspend_display(struct drm_device *dev)
727 struct drm_psb_private *dev_priv = dev->dev_private;
728 //to put panel into ULPS mode.
730 u32 device_ready_reg = DEVICE_READY_REG;
734 printk(KERN_ALERT "%s \n", __func__);
736 if (!(g_hw_power_status_mask & OSPM_DISPLAY_ISLAND))
739 mdfld_save_cursor_overlay_registers(dev);
741 mdfld_save_pipe_registers(dev, 0);
742 mdfld_save_pipe_registers(dev, 2);
743 android_hdmi_save_display_registers(dev);
744 /* save the gunit register controlling write-combining */
745 dev_priv->savePERF_MODE = PSB_RVDC32(MRST_PERF_MODE);
747 mdfld_disable_crtc(dev, 0);
748 mdfld_disable_crtc(dev, 2);
749 android_disable_hdmi(dev);
751 /* Put the panel in ULPS mode for S0ix. */
752 temp = REG_READ(device_ready_reg);
754 temp |= ENTERING_ULPS;
755 REG_WRITE(device_ready_reg, temp);
758 temp = REG_READ(mipi_reg);
759 temp &= ~LP_OUTPUT_HOLD;
760 REG_WRITE(mipi_reg, temp);
763 ospm_power_island_down(OSPM_DISPLAY_ISLAND);
767 * ospm_resume_display
769 * Description: Resume the display hardware restoring state and enabling
772 static void ospm_resume_display(struct drm_device *drm_dev)
774 struct drm_psb_private *dev_priv = drm_dev->dev_private;
775 struct psb_gtt *pg = dev_priv->pg;
778 printk(KERN_ALERT "%s \n", __func__);
780 if (g_hw_power_status_mask & OSPM_DISPLAY_ISLAND)
783 /* turn on the display power island */
784 ospm_power_island_up(OSPM_DISPLAY_ISLAND);
786 PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
787 pci_write_config_word(drm_dev->pdev, PSB_GMCH_CTRL,
788 pg->gmch_ctrl | _PSB_GMCH_ENABLED);
790 /* Don't reinitialize the GTT as it is unnecessary. The gtt is
791 * stored in memory so it will automatically be restored. All
792 * we need to do is restore the PGETBL_CTL which we already do
795 /*psb_gtt_init(dev_priv->pg, 1);*/
797 /* restore gunit register controlling write-combining */
798 PSB_WVDC32(dev_priv->savePERF_MODE, MRST_PERF_MODE);
799 android_hdmi_restore_and_enable_display(drm_dev);
800 mdfld_restore_pipe_registers(drm_dev, 0);
801 mdfld_restore_pipe_registers(drm_dev, 2);
802 mdfld_restore_cursor_overlay_registers(drm_dev);
805 static void pvrcmd_device_power(unsigned type, enum pvr_trcmd_device dev)
807 struct pvr_trcmd_power *p;
809 p = pvr_trcmd_reserve(type, 0, "irq", sizeof *p);
811 p = pvr_trcmd_reserve(type, task_tgid_nr(current),
812 current->comm, sizeof *p);
820 * Description: Suspend the pci device saving state and disabling
823 static void ospm_suspend_pci(struct pci_dev *pdev)
825 struct drm_device *dev = pci_get_drvdata(pdev);
826 struct drm_psb_private *dev_priv = dev->dev_private;
832 printk(KERN_ALERT "ospm_suspend_pci\n");
835 #ifdef CONFIG_MDFD_GL3
838 pvrcmd_device_power(PVR_TRCMD_SUSPEND, PVR_TRCMD_DEVICE_PCI);
839 /* Power off GL3 after all GFX sub-systems are powered off. */
840 ospm_power_island_down(OSPM_GL3_CACHE_ISLAND);
842 pci_read_config_dword(pdev, 0x5C, &dev_priv->saveBSM);
843 pci_read_config_dword(pdev, 0xFC, &dev_priv->saveVBT);
844 pci_read_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, &dev_priv->msi_addr);
845 pci_read_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, &dev_priv->msi_data);
853 * Description: Resume the pci device restoring state and enabling
856 static bool ospm_resume_pci(struct pci_dev *pdev)
858 struct drm_device *dev = pci_get_drvdata(pdev);
859 struct drm_psb_private *dev_priv = dev->dev_private;
865 printk(KERN_ALERT "ospm_resume_pci\n");
867 pvrcmd_device_power(PVR_TRCMD_RESUME, PVR_TRCMD_DEVICE_PCI);
869 pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM);
870 pci_write_config_dword(pdev, 0xFC, dev_priv->saveVBT);
871 pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr);
872 pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data);
876 #ifdef CONFIG_MDFD_GL3
877 /* Powerup GL3 - can be used by any GFX-sub-system. */
878 ospm_power_island_up(OSPM_GL3_CACHE_ISLAND);
887 * Description: OSPM is telling our driver to suspend so save state
888 * and power down all hardware.
890 int ospm_power_suspend(struct device *dev)
892 struct pci_dev *pdev = to_pci_dev(dev);
893 struct drm_device *drm_dev = pci_get_drvdata(pdev);
895 int graphics_access_count;
896 int videoenc_access_count;
897 int videodec_access_count;
898 int display_access_count;
899 bool suspend_pci = true;
901 mutex_lock(&g_ospm_mutex);
906 graphics_access_count = atomic_read(&g_graphics_access_count);
907 videoenc_access_count = atomic_read(&g_videoenc_access_count);
908 videodec_access_count = atomic_read(&g_videodec_access_count);
909 display_access_count = atomic_read(&g_display_access_count);
911 if (graphics_access_count || videoenc_access_count ||
912 videodec_access_count || display_access_count) {
915 printk(KERN_ALERT "%s: device busy: graphics %d videoenc %d videodec %d display %d\n",
916 __func__, graphics_access_count, videoenc_access_count,
917 videodec_access_count, display_access_count);
921 psb_irq_uninstall_islands(drm_dev, OSPM_DISPLAY_ISLAND);
922 ospm_suspend_display(drm_dev);
924 /* FIXME: video driver support for Linux Runtime PM */
925 if (ospm_runtime_pm_msvdx_suspend(drm_dev))
928 if (ospm_runtime_pm_topaz_suspend(drm_dev))
932 ospm_suspend_pci(pdev);
934 * REVISIT: else pci is not suspended but this happily returns success
938 pci_save_state(pdev);
939 pci_set_power_state(pdev, PCI_D3hot);
941 mutex_unlock(&g_ospm_mutex);
945 /* The PMU/P-Unit driver has different island definitions */
946 static int to_pmu_islands(int reg_type, int islands)
950 if (reg_type == APM_REG_TYPE) {
951 if (islands & OSPM_GRAPHICS_ISLAND)
952 ret |= APM_GRAPHICS_ISLAND;
953 if (islands & OSPM_VIDEO_DEC_ISLAND)
954 ret |= APM_VIDEO_DEC_ISLAND;
955 if (islands & OSPM_VIDEO_ENC_ISLAND)
956 ret |= APM_VIDEO_ENC_ISLAND;
957 if (islands & OSPM_GL3_CACHE_ISLAND)
958 ret |= APM_GL3_CACHE_ISLAND;
959 } else if (reg_type == OSPM_REG_TYPE) {
960 if (islands & OSPM_DISPLAY_ISLAND)
961 ret |= OSPM_DISPLAY_A_ISLAND | OSPM_DISPLAY_B_ISLAND |
962 OSPM_DISPLAY_C_ISLAND | OSPM_MIPI_ISLAND;
968 static int ospm_set_power_state(int state_type, int islands)
972 pmu_islands = to_pmu_islands(APM_REG_TYPE, islands);
974 pmu_nc_set_power_state(pmu_islands, state_type, APM_REG_TYPE);
976 pmu_islands = to_pmu_islands(OSPM_REG_TYPE, islands);
978 pmu_nc_set_power_state(pmu_islands, state_type, OSPM_REG_TYPE);
984 * ospm_power_island_up
986 * Description: Restore power to the specified island(s) (powergating)
988 void ospm_power_island_up(int islands)
990 #ifndef CONFIG_MDFD_GL3
991 islands &= ~OSPM_GL3_CACHE_ISLAND;
994 if (islands & OSPM_GRAPHICS_ISLAND)
995 pvrcmd_device_power(PVR_TRCMD_RESUME, PVR_TRCMD_DEVICE_SGX);
997 if (islands & OSPM_DISPLAY_ISLAND)
998 pvrcmd_device_power(PVR_TRCMD_RESUME, PVR_TRCMD_DEVICE_DISPC);
1000 ospm_set_power_state(OSPM_ISLAND_UP, islands);
1002 g_hw_power_status_mask |= islands;
1006 * ospm_power_island_down
1008 * Description: Cut power to the specified island(s) (powergating)
1010 void ospm_power_island_down(int islands)
1012 g_hw_power_status_mask &= ~islands;
1014 if (islands & OSPM_GRAPHICS_ISLAND)
1015 pvrcmd_device_power(PVR_TRCMD_SUSPEND, PVR_TRCMD_DEVICE_SGX);
1017 if (islands & OSPM_DISPLAY_ISLAND)
1018 pvrcmd_device_power(PVR_TRCMD_SUSPEND, PVR_TRCMD_DEVICE_DISPC);
1020 ospm_set_power_state(OSPM_ISLAND_DOWN, islands);
1026 int ospm_power_resume(struct device *dev)
1028 struct pci_dev *pdev = to_pci_dev(dev);
1029 struct drm_device *drm_dev = pci_get_drvdata(pdev);
1031 mutex_lock(&g_ospm_mutex);
1034 printk(KERN_ALERT "OSPM_GFX_DPK: ospm_power_resume \n");
1037 ospm_resume_pci(pdev);
1039 pci_set_power_state(pdev, PCI_D0);
1040 pci_restore_state(pdev);
1041 ospm_resume_display(drm_dev);
1042 psb_irq_preinstall_islands(drm_dev, OSPM_DISPLAY_ISLAND);
1043 psb_irq_postinstall_islands(drm_dev, OSPM_DISPLAY_ISLAND);
1045 mutex_unlock(&g_ospm_mutex);
1051 * ospm_power_is_hw_on
1053 * Description: do an instantaneous check for if the specified islands
1054 * are on. Only use this in cases where you know the g_state_change_mutex
1055 * is already held such as in irq install/uninstall. Otherwise, use
1056 * ospm_power_using_hw_begin().
1058 bool ospm_power_is_hw_on(int hw_islands)
1060 return ((g_hw_power_status_mask & hw_islands) == hw_islands) ? true : false;
1063 bool ospm_power_using_hw_begin_atomic(int hw_island)
1065 struct drm_device *drm_dev = gpDrmDevice; /* FIXME: Pass as parameter */
1067 /* fail if island is off, no can do in atomic context */
1068 if (!(g_hw_power_status_mask & hw_island))
1071 pm_runtime_get(&drm_dev->pdev->dev);
1073 switch (hw_island) {
1074 case OSPM_GRAPHICS_ISLAND:
1075 atomic_inc(&g_graphics_access_count);
1077 case OSPM_VIDEO_ENC_ISLAND:
1078 atomic_inc(&g_videoenc_access_count);
1080 case OSPM_VIDEO_DEC_ISLAND:
1081 atomic_inc(&g_videodec_access_count);
1083 case OSPM_DISPLAY_ISLAND:
1084 atomic_inc(&g_display_access_count);
1092 * ospm_power_using_hw_begin
1094 * Description: Notify PowerMgmt module that you will be accessing the
1095 * specified island's hw so don't power it off. If force_on is true,
1096 * this will power on the specified island if it is off.
1097 * Otherwise, this will return false and the caller is expected to not
1100 * NOTE *** If this is called from and interrupt handler or other atomic
1101 * context, then it will return false if we are in the middle of a
1102 * power state transition and the caller will be expected to handle that
1103 * even if force_on is set to true.
1105 bool ospm_power_using_hw_begin(int hw_island, bool force_on)
1107 struct drm_device *drm_dev = gpDrmDevice; /* FIXME: Pass as parameter */
1110 WARN(in_interrupt() || in_atomic(), "%s called in atomic context\n",
1113 /* no force, increase count if island on, otherwise fail */
1115 return ospm_power_using_hw_begin_atomic(hw_island);
1117 /* note: the runtime pm resume callback takes g_ospm_mutex */
1118 pm_runtime_get_sync(&drm_dev->pdev->dev);
1120 mutex_lock(&g_ospm_mutex);
1122 /* our job here is done if island is already on */
1123 if (g_hw_power_status_mask & hw_island)
1124 goto increase_count;
1126 switch (hw_island) {
1127 case OSPM_DISPLAY_ISLAND:
1128 ospm_resume_display(drm_dev);
1129 psb_irq_preinstall_islands(drm_dev, OSPM_DISPLAY_ISLAND);
1130 psb_irq_postinstall_islands(drm_dev, OSPM_DISPLAY_ISLAND);
1133 case OSPM_GRAPHICS_ISLAND:
1134 ospm_power_island_up(OSPM_GRAPHICS_ISLAND);
1135 psb_irq_preinstall_islands(drm_dev, OSPM_GRAPHICS_ISLAND);
1136 psb_irq_postinstall_islands(drm_dev, OSPM_GRAPHICS_ISLAND);
1139 case OSPM_VIDEO_DEC_ISLAND:
1140 WARN_ON(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND));
1142 ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND);
1143 ospm_runtime_pm_msvdx_resume(drm_dev);
1144 psb_irq_preinstall_islands(drm_dev, OSPM_VIDEO_DEC_ISLAND);
1145 psb_irq_postinstall_islands(drm_dev, OSPM_VIDEO_DEC_ISLAND);
1148 case OSPM_VIDEO_ENC_ISLAND:
1149 WARN_ON(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND));
1151 ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND);
1152 ospm_runtime_pm_topaz_resume(drm_dev);
1153 psb_irq_preinstall_islands(drm_dev, OSPM_VIDEO_ENC_ISLAND);
1154 psb_irq_postinstall_islands(drm_dev, OSPM_VIDEO_ENC_ISLAND);
1162 switch (hw_island) {
1163 case OSPM_GRAPHICS_ISLAND:
1164 atomic_inc(&g_graphics_access_count);
1166 case OSPM_VIDEO_ENC_ISLAND:
1167 atomic_inc(&g_videoenc_access_count);
1169 case OSPM_VIDEO_DEC_ISLAND:
1170 atomic_inc(&g_videodec_access_count);
1172 case OSPM_DISPLAY_ISLAND:
1173 atomic_inc(&g_display_access_count);
1177 mutex_unlock(&g_ospm_mutex);
1184 * ospm_power_using_hw_end
1186 * Description: Notify PowerMgmt module that you are done accessing the
1187 * specified island's hw so feel free to power it off. Note that this
1188 * function doesn't actually power off the islands.
1190 void ospm_power_using_hw_end(int hw_island)
1192 struct drm_device *drm_dev = gpDrmDevice; /* FIXME: Pass as parameter */
1194 switch (hw_island) {
1195 case OSPM_GRAPHICS_ISLAND:
1196 atomic_dec(&g_graphics_access_count);
1198 case OSPM_VIDEO_ENC_ISLAND:
1199 atomic_dec(&g_videoenc_access_count);
1201 case OSPM_VIDEO_DEC_ISLAND:
1202 atomic_dec(&g_videodec_access_count);
1204 case OSPM_DISPLAY_ISLAND:
1205 atomic_dec(&g_display_access_count);
1209 pm_runtime_put(&drm_dev->pdev->dev);
1211 WARN_ON(atomic_read(&g_graphics_access_count) < 0);
1212 WARN_ON(atomic_read(&g_videoenc_access_count) < 0);
1213 WARN_ON(atomic_read(&g_videodec_access_count) < 0);
1214 WARN_ON(atomic_read(&g_display_access_count) < 0);
1217 #ifdef CONFIG_SND_INTELMID_HDMI_AUDIO
1218 static int psb_runtime_hdmi_audio_suspend(struct drm_device *drm_dev)
1220 struct drm_psb_private *dev_priv = drm_dev->dev_private;
1221 pm_event_t pm_event = {0};
1224 if (!dev_priv->had_pvt_data)
1227 r = dev_priv->had_interface->suspend(dev_priv->had_pvt_data, pm_event);
1229 return r ? -EBUSY : 0;
1232 static void psb_runtime_hdmi_audio_resume(struct drm_device *drm_dev)
1234 struct drm_psb_private *dev_priv = drm_dev->dev_private;
1236 if (dev_priv->had_pvt_data)
1237 dev_priv->had_interface->resume(dev_priv->had_pvt_data);
1240 static inline int psb_runtime_hdmi_audio_suspend(struct drm_device *drm_dev)
1244 static inline void psb_runtime_hdmi_audio_resume(struct drm_device *drm_dev)
1249 int psb_runtime_idle(struct device *dev)
1251 struct pci_dev *pdev = to_pci_dev(dev);
1252 struct drm_device *drm_dev = pci_get_drvdata(pdev);
1253 struct drm_psb_private *dev_priv = drm_dev->dev_private;
1255 if (dev_priv->dpi_panel_on || dev_priv->dpi_panel_on2 ||
1256 atomic_read(&g_graphics_access_count) ||
1257 atomic_read(&g_videoenc_access_count) ||
1258 atomic_read(&g_videodec_access_count) ||
1259 atomic_read(&g_display_access_count) ||
1260 ospm_runtime_check_msvdx_hw_busy(drm_dev) == 1 ||
1261 ospm_runtime_check_topaz_hw_busy(drm_dev) == 1 ||
1262 dev_priv->hdmi_audio_busy) {
1265 dev_dbg(&drm_dev->pdev->dev,
1266 "%s: GFX: %d VEC: %d VED: %d DC: %d\n",
1268 atomic_read(&g_graphics_access_count),
1269 atomic_read(&g_videoenc_access_count),
1270 atomic_read(&g_videodec_access_count),
1271 atomic_read(&g_display_access_count));
1280 int psb_runtime_suspend(struct device *dev)
1282 struct pci_dev *pdev = to_pci_dev(dev);
1283 struct drm_device *drm_dev = pci_get_drvdata(pdev);
1287 dev_dbg(&drm_dev->pdev->dev, "%s\n", __func__);
1290 r = psb_runtime_idle(dev);
1294 /* REVISIT: if ospm_power_suspend fails, do what with hdmi audio? */
1296 return ospm_power_suspend(dev);
1299 int psb_runtime_resume(struct device *dev)
1301 struct pci_dev *pdev = to_pci_dev(dev);
1302 struct drm_device *drm_dev = pci_get_drvdata(pdev);
1304 ospm_power_resume(dev);
1305 psb_runtime_hdmi_audio_resume(drm_dev);
1313 * Description: Initialize this ospm power management module
1315 void ospm_power_init(struct drm_device *dev)
1317 struct drm_psb_private *dev_priv = dev->dev_private;
1321 dev_priv->apm_base = MDFLD_MSG_READ32(PSB_PUNIT_PORT, PSB_APMBA) &
1324 mutex_init(&g_ospm_mutex);
1326 /* Specify the islands to keep powered up at boot */
1327 g_hw_power_status_mask = OSPM_ALL_ISLANDS;
1328 #ifndef CONFIG_MDFD_GL3
1329 g_hw_power_status_mask &= ~OSPM_GL3_CACHE_ISLAND;
1332 /* Set power island states according to g_hw_power_status_mask */
1333 ospm_set_power_state(OSPM_ISLAND_UP, g_hw_power_status_mask);
1334 ospm_set_power_state(OSPM_ISLAND_DOWN,
1335 OSPM_ALL_ISLANDS ^ g_hw_power_status_mask);
1337 atomic_set(&g_display_access_count, 0);
1338 atomic_set(&g_graphics_access_count, 0);
1339 atomic_set(&g_videoenc_access_count, 0);
1340 atomic_set(&g_videodec_access_count, 0);
1342 #ifdef CONFIG_EARLYSUSPEND
1343 dev_priv->early_suspend.suspend = gfx_early_suspend;
1344 dev_priv->early_suspend.resume = gfx_late_resume;
1345 dev_priv->early_suspend.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING;
1346 register_early_suspend(&dev_priv->early_suspend);
1349 /* Runtime PM for PCI drivers. */
1350 pm_runtime_put_noidle(&dev->pdev->dev);
1356 * Description: Uninitialize this ospm power management module
1358 void ospm_power_uninit(struct drm_device *drm_dev)
1360 /* Runtime PM for PCI drivers. */
1361 pm_runtime_get_noresume(&drm_dev->pdev->dev);
1363 mutex_destroy(&g_ospm_mutex);