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 exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
{
    struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);

    DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);

    if (exynos_crtc->dpms == mode) {
        DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n");
        return;
    }

    if (mode > DRM_MODE_DPMS_ON) {
        /* wait for the completion of page flip. */
        wait_event(exynos_crtc->pending_flip_queue,
                   atomic_read(&exynos_crtc->pending_flip) == 0);
        drm_vblank_off(crtc->dev, exynos_crtc->pipe);
    }

    exynos_drm_fn_encoder(crtc, &mode, exynos_drm_encoder_crtc_dpms);
    exynos_crtc->dpms = mode;
}
Exemple #4
0
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();
}
Exemple #5
0
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;
}