/** * Power off sequence for command mode MIPI panel. * NOTE: do NOT modify this function */ static int __dbi_panel_power_off(struct mdfld_dsi_config *dsi_config, struct panel_funcs *p_funcs) { struct mdfld_dsi_hw_registers *regs; struct mdfld_dsi_hw_context *ctx; struct drm_device *dev; struct drm_psb_private *dev_priv; int err = 0; if (!dsi_config) return -EINVAL; PSB_DEBUG_ENTRY("\n"); regs = &dsi_config->regs; ctx = &dsi_config->dsi_hw_context; dev = dsi_config->dev; dev_priv = dev->dev_private; mdfld_dsi_dsr_forbid_locked(dsi_config); ctx->lastbrightnesslevel = psb_brightness; if (p_funcs && p_funcs->set_brightness) if (p_funcs->set_brightness(dsi_config, 0)) DRM_ERROR("Failed to set panel brightness\n"); /*wait for two TE, let pending PVR flip complete*/ msleep(32); /** * Different panel may have different ways to have * panel turned off. Support it! */ if (p_funcs && p_funcs->power_off) { if (p_funcs->power_off(dsi_config)) { DRM_ERROR("Failed to power off panel\n"); err = -EAGAIN; goto power_off_err; } } /*power off dbi interface*/ __dbi_power_off(dsi_config); power_off_err: mdfld_dsi_dsr_allow_locked(dsi_config); return err; }
static int enter_dsr_locked(struct mdfld_dsi_config *dsi_config, int level) { u32 val = 0; struct mdfld_dsi_hw_registers *regs; struct mdfld_dsi_hw_context *ctx; struct drm_psb_private *dev_priv; struct drm_device *dev; struct mdfld_dsi_pkg_sender *sender; int err; pm_message_t state; int pipe0_enabled; int pipe2_enabled; PSB_DEBUG_ENTRY("mdfld_dsi_dsr: enter dsr\n"); if (!dsi_config) return -EINVAL; regs = &dsi_config->regs; ctx = &dsi_config->dsi_hw_context; dev = dsi_config->dev; dev_priv = dev->dev_private; sender = mdfld_dsi_get_pkg_sender(dsi_config); if (!sender) { DRM_ERROR("Failed to get dsi sender\n"); return -EINVAL; } if (level < DSR_EXITED) { DRM_ERROR("Why to do this?"); return -EINVAL; } if (level > DSR_ENTERED_LEVEL0) { /** * TODO: require OSPM interfaces to tell OSPM module that * display controller is ready to be power gated. * OSPM module needs to response this request ASAP. * NOTE: it makes no sense to have display controller islands * & pci power gated here directly. OSPM module is the only one * who can power gate/ungate power islands. * FIXME: since there's no ospm interfaces for acquiring * suspending DSI related power islands, we have to call OSPM * interfaces to power gate display islands and pci right now, * which should NOT happen in this way!!! */ if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { DRM_ERROR("Failed power on display island\n"); return -EINVAL; } PSB_DEBUG_ENTRY("mdfld_dsi_dsr: entering DSR level 1\n"); /*Disable TE, don't need it anymore*/ mdfld_disable_te(dev, dsi_config->pipe); err = mdfld_dsi_wait_for_fifos_empty(sender); if (err) { DRM_ERROR("mdfld_dsi_dsr: FIFO not empty\n"); mdfld_enable_te(dev, dsi_config->pipe); ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); return err; } ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); /*suspend whole PCI host and related islands ** if failed at this try, revive te for another chance */ state.event = 0; if (ospm_power_suspend(gpDrmDevice->pdev, state)) { /* Only display island is powered off then ** need revive the whole TE */ if (!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) exit_dsr_locked(dsi_config); else mdfld_enable_te(dev, dsi_config->pipe); return -EINVAL; } /* *suspend pci *FIXME: should I do it here? *how about decoder/encoder is working?? *OSPM should check the refcout of each islands before *actually power off PCI!!! *need invoke this in the same context, we need deal with *DSR lock later for suspend PCI may go to sleep!!! */ /*ospm_suspend_pci(dev->pdev);*/ PSB_DEBUG_ENTRY("mdfld_dsi_dsr: entered\n"); return 0; } /* * if DSR_EXITED < level < DSR_ENTERED_LEVEL1, we only have the display * controller components turned off instead of power gate them. * this is useful for HDMI & WIDI. */ if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { DRM_ERROR("Failed power on display island\n"); return -EINVAL; } PSB_DEBUG_ENTRY("mdfld_dsi_dsr: entering DSR level 0\n"); /*Disable TE, don't need it anymore*/ mdfld_disable_te(dev, dsi_config->pipe); err = mdfld_dsi_wait_for_fifos_empty(sender); if (err) { DRM_ERROR("mdfld_dsi_dsr: FIFO not empty\n"); mdfld_enable_te(dev, dsi_config->pipe); ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); return err; } /*turn off dbi interface put in ulps*/ __dbi_power_off(dsi_config); ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); PSB_DEBUG_ENTRY("entered\n"); return 0; }