/**
 * 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;
}
示例#2
0
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;
}