static void mdfld_generic_dsi_dbi_save(struct drm_encoder *encoder) { struct mdfld_dsi_encoder *dsi_encoder; struct mdfld_dsi_config *dsi_config; struct drm_device *dev; int pipe; PSB_DEBUG_ENTRY("\n"); if (!encoder) return; dsi_encoder = MDFLD_DSI_ENCODER(encoder); dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); dev = dsi_config->dev; pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); DCLockMutex(); mdfld_generic_dsi_dbi_set_power(encoder, false); drm_handle_vblank(dev, pipe); /* Turn off vsync (TE) interrupt. */ drm_vblank_off(dev, pipe); /* Make the pending flip request as completed. */ DCUnAttachPipe(pipe); DC_MRFLD_onPowerOff(pipe); DCUnLockMutex(); }
static void mdfld_generic_dsi_dbi_dpms(struct drm_encoder *encoder, int mode) { struct mdfld_dsi_encoder *dsi_encoder; struct mdfld_dsi_dbi_output *dbi_output; struct drm_device *dev; struct mdfld_dsi_config *dsi_config; struct drm_psb_private *dev_priv; dsi_encoder = MDFLD_DSI_ENCODER(encoder); dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); if (!dsi_config) { DRM_ERROR("dsi_config is NULL\n"); return; } dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); dev = dsi_config->dev; dev_priv = dev->dev_private; PSB_DEBUG_ENTRY("%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off")); mutex_lock(&dev_priv->dpms_mutex); DCLockMutex(); if (mode == DRM_MODE_DPMS_ON) { mdfld_generic_dsi_dbi_set_power(encoder, true); DCAttachPipe(dsi_config->pipe); DC_MRFLD_onPowerOn(dsi_config->pipe); } else { mdfld_generic_dsi_dbi_set_power(encoder, false); drm_handle_vblank(dev, dsi_config->pipe); /* Turn off TE interrupt. */ drm_vblank_off(dev, dsi_config->pipe); /* Make the pending flip request as completed. */ DCUnAttachPipe(dsi_config->pipe); DC_MRFLD_onPowerOff(dsi_config->pipe); } DCUnLockMutex(); mutex_unlock(&dev_priv->dpms_mutex); }
static void mdfld_dsi_dpi_save(struct drm_encoder *encoder) { struct mdfld_dsi_encoder *dsi_encoder; struct mdfld_dsi_config *dsi_config; struct drm_device *dev; int pipe; if (!encoder) return; PSB_DEBUG_ENTRY("\n"); dsi_encoder = MDFLD_DSI_ENCODER(encoder); dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); dev = dsi_config->dev; pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); DCLockMutex(); /* give time to the last flip to take effective, * if we disable hardware too quickly, overlay hardware may crash, * causing pipe hang next time when we try to use overlay */ msleep(50); DC_MRFLD_onPowerOff(pipe); msleep(50); __mdfld_dsi_dpi_set_power(encoder, false); drm_handle_vblank(dev, pipe); /* Turn off vsync interrupt. */ drm_vblank_off(dev, pipe); /* Make the pending flip request as completed. */ DCUnAttachPipe(pipe); DCUnLockMutex(); }
static void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode) { struct mdfld_dsi_encoder *dsi_encoder; struct mdfld_dsi_config *dsi_config; struct drm_device *dev; struct drm_psb_private *dev_priv; struct mdfld_dsi_dpi_output *dpi_output; struct panel_funcs *p_funcs; dsi_encoder = MDFLD_DSI_ENCODER(encoder); dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); if (!dsi_config) { DRM_ERROR("dsi_config is NULL\n"); return; } dev = dsi_config->dev; dev_priv = dev->dev_private; dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); p_funcs = dpi_output->p_funcs; PSB_DEBUG_ENTRY("%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : DRM_MODE_DPMS_STANDBY == mode ? "standby" : "off")); mutex_lock(&dev_priv->dpms_mutex); DCLockMutex(); if (mode == DRM_MODE_DPMS_ON) { mdfld_dsi_dpi_set_power(encoder, true); DCAttachPipe(dsi_config->pipe); DC_MRFLD_onPowerOn(dsi_config->pipe); #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE { struct mdfld_dsi_hw_context *ctx = &dsi_config->dsi_hw_context; struct backlight_device bd; bd.props.brightness = ctx->lastbrightnesslevel; psb_set_brightness(&bd); } #endif } else if (mode == DRM_MODE_DPMS_STANDBY) { #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE struct mdfld_dsi_hw_context *ctx = &dsi_config->dsi_hw_context; struct backlight_device bd; ctx->lastbrightnesslevel = psb_get_brightness(&bd); bd.props.brightness = 0; psb_set_brightness(&bd); #endif /* Make the pending flip request as completed. */ DCUnAttachPipe(dsi_config->pipe); msleep(50); DC_MRFLD_onPowerOff(dsi_config->pipe); msleep(50); } else { mdfld_dsi_dpi_set_power(encoder, false); drm_handle_vblank(dev, dsi_config->pipe); /* Turn off TE interrupt. */ drm_vblank_off(dev, dsi_config->pipe); /* Make the pending flip request as completed. */ DCUnAttachPipe(dsi_config->pipe); DC_MRFLD_onPowerOff(dsi_config->pipe); } DCUnLockMutex(); mutex_unlock(&dev_priv->dpms_mutex); }
static int enter_dsr_locked(struct mdfld_dsi_config *dsi_config, int level) { 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; 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"); err = mdfld_dsi_wait_for_fifos_empty(sender); if (err) { DRM_ERROR("mdfld_dsi_dsr: FIFO not empty\n"); 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()) { /* 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); 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; } PSB_DEBUG_ENTRY("mdfld_dsi_dsr: entering DSR level 0\n"); err = mdfld_dsi_wait_for_fifos_empty(sender); if (err) { DRM_ERROR("mdfld_dsi_dsr: FIFO not empty\n"); return err; } /* * To set the vblank_enabled to false with drm_vblank_off(), as * vblank_disable_and_save() would be scheduled late (<= 5s), and it * would cause drm_vblank_get() fail to turn on vsync interrupt * immediately. */ drm_vblank_off(dev, dsi_config->pipe); DC_MRFLD_onPowerOff(dsi_config->pipe); /*turn off dbi interface put in ulps*/ __dbi_power_off(dsi_config); PSB_DEBUG_ENTRY("entered\n"); return 0; }