Exemplo n.º 1
0
int mdfld_dpu_exit_dsr(struct drm_device * dev)
{
	struct mdfld_dsi_dbi_output ** dbi_output;
	struct drm_psb_private * dev_priv = dev->dev_private;
	struct mdfld_dbi_dpu_info * dpu_info = dev_priv->dbi_dpu_info;
	int i;
	int pipe;
	
	dbi_output = dpu_info->dbi_outputs;
	
	for(i=0; i<dpu_info->dbi_output_num; i++) {
		/*if this output is not in DSR mode, don't call exit dsr*/
		if(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR) {
			__mdfld_dbi_exit_dsr(dbi_output[i], dbi_output[i]->channel_num ? 2 : 0);
		}
	}

	/*enable te interrupt*/
	for (i = 0; i < dpu_info->dbi_output_num; i++) {
		/*if this output is not in DSR mode, don't call exit dsr*/
		pipe = dbi_output[i]->channel_num ? 2 : 0;
		if (dbi_output[i]->dbi_panel_on && pipe) {
			mdfld_disable_te(dev, 0);
			mdfld_enable_te(dev, 2);
		} else if (dbi_output[i]->dbi_panel_on && !pipe) {
			mdfld_disable_te(dev, 2);
			mdfld_enable_te(dev, 0);
		}
	}

	return 0;
	
}
Exemplo n.º 2
0
static void pyr_dsi_dbi_set_power(struct drm_encoder * encoder, bool on)
{
	int ret = 0;
	struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	/*struct drm_device * dev = dbi_output->dev;*/
	struct drm_device* dev = encoder->dev;
	struct drm_psb_private * dev_priv = dev->dev_private;
	u32 reg_offset = 0;
	int pipe = (dbi_output->channel_num == 0) ? 0 : 2;

	PSB_DEBUG_ENTRY("pipe %d : %s, panel on: %s\n",pipe, on ? "On" : "Off", dbi_output->dbi_panel_on ? "True" : "False");
        
	if(pipe == 2) {
		if(on)
			dev_priv->dual_mipi = true;
		else
			dev_priv->dual_mipi = false;

		reg_offset = MIPIC_REG_OFFSET;
	} else {
		if (!on)
			dev_priv->dual_mipi = false;
	}

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) {
		DRM_ERROR("hw begin failed\n");
		return;
	}


	if(on) {
		if(dbi_output->dbi_panel_on)
			goto out_err;
					
		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
		if(ret) {
			DRM_ERROR("power on error\n");
			goto out_err;
		}

		dbi_output->dbi_panel_on = true;

		if(pipe == 2) {
			dev_priv->dbi_panel_on2 = true;
		} else {
			dev_priv->dbi_panel_on = true;

			if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
				mdfld_enable_te(dev, 0);
		}
		
	} else {
		if(!dbi_output->dbi_panel_on && !dbi_output->first_boot) 
			goto out_err;
					
		dbi_output->dbi_panel_on = false;
		dbi_output->first_boot = false;

		if(pipe == 2) {
			dev_priv->dbi_panel_on2 = false;

			if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
				mdfld_disable_te(dev, 2);
		} else {
			dev_priv->dbi_panel_on = false;

			if (dev_priv->platform_rev_id != MDFLD_PNW_A0) {
				mdfld_disable_te(dev, 0);

				if (dev_priv->dbi_panel_on2)
					mdfld_enable_te(dev, 2);
			}
		}

		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
		if(ret) {
			DRM_ERROR("power on error\n");
			goto out_err;
		}
	}

out_err:
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	if(ret)
		DRM_ERROR("failed\n");
	else
		PSB_DEBUG_ENTRY("successfully\n");
}
Exemplo n.º 3
0
static void mdfld_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
{
	int ret = 0;
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
				MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
		mdfld_dsi_encoder_get_config(dsi_encoder);
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_encoder_get_pkg_sender(dsi_encoder);
	struct drm_device *dev = encoder->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	u32 reg_offset = 0;
	int pipe = (dbi_output->channel_num == 0) ? 0 : 2;
	u32 data = 0;

	dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n",
			pipe, on ? "On" : "Off",
			dbi_output->dbi_panel_on ? "True" : "False");

	if (pipe == 2) {
		if (on)
			dev_priv->dual_mipi = true;
		else
			dev_priv->dual_mipi = false;
		reg_offset = MIPIC_REG_OFFSET;
	} else {
		if (!on)
			dev_priv->dual_mipi = false;
	}

	if (!gma_power_begin(dev, true)) {
		dev_err(dev->dev, "hw begin failed\n");
		return;
	}

	if (on) {
		if (dbi_output->dbi_panel_on)
			goto out_err;

		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
		if (ret) {
			dev_err(dev->dev, "power on error\n");
			goto out_err;
		}

		dbi_output->dbi_panel_on = true;

		if (pipe == 2)
			dev_priv->dbi_panel_on2 = true;
		else
			dev_priv->dbi_panel_on = true;
		mdfld_enable_te(dev, pipe);
	} else {
		if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
			goto out_err;

		dbi_output->dbi_panel_on = false;
		dbi_output->first_boot = false;

		if (pipe == 2)
			dev_priv->dbi_panel_on2 = false;
		else
			dev_priv->dbi_panel_on = false;

		mdfld_disable_te(dev, pipe);

		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
		if (ret) {
			dev_err(dev->dev, "power on error\n");
			goto out_err;
		}
	}

	/*
	 * FIXME: this is a WA for TPO panel crash on DPMS on & off around
	 * 83 times. the root cause of this issue is that Booster in
	 * drvIC crashed. Add this WA so that we can resume the driver IC
	 * once we found that booster has a fault
	 */
	mdfld_dsi_get_power_mode(dsi_config,
				&data,
				MDFLD_DSI_HS_TRANSMISSION);

	if (on && data && !(data & (1 << 7))) {
		/* Soft reset */
		mdfld_dsi_send_dcs(sender,
				   DCS_SOFT_RESET,
				   NULL,
				   0,
				   CMD_DATA_SRC_PIPE,
				   MDFLD_DSI_SEND_PACKAGE);

		/* Init drvIC */
		if (dbi_output->p_funcs->drv_ic_init)
			dbi_output->p_funcs->drv_ic_init(dsi_config,
							 pipe);
	}
 
out_err:
	gma_power_end(dev);
	if (ret)
		dev_err(dev->dev, "failed\n");
}
Exemplo n.º 4
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;
}
int mdfld_panel_generic_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
{
	int ret = 0;
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
		MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct panel_funcs *p_funcs = dbi_output->p_funcs;
	struct mdfld_dsi_connector *dsi_connector =
		mdfld_dsi_encoder_get_connector(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
		mdfld_dsi_encoder_get_config(dsi_encoder);
	struct drm_device *dev = encoder->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	u32 reg_offset = 0;
	int pipe = (dbi_output->channel_num == 0) ? 0 : 2;

	PSB_DEBUG_ENTRY("pipe %d : %s, panel on: %s\n", pipe, on ? "On" : "Off",
			dbi_output->dbi_panel_on ? "True" : "False");

	if (pipe == 2) {
		if (on)
			dev_priv->dual_mipi = true;
		else
			dev_priv->dual_mipi = false;

		reg_offset = MIPIC_REG_OFFSET;
	} else {
		if (!on)
			dev_priv->dual_mipi = false;
	}

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
				OSPM_UHB_FORCE_POWER_ON)) {
		DRM_ERROR("hw begin failed\n");
		return -EAGAIN;
	}

	mutex_lock(&dsi_config->context_lock);

	if (on) {
		if (dbi_output->dbi_panel_on)
			goto out_err;

		ret = mdfld_panel_generic_dsi_dbi_power_on(encoder);
		if (ret) {
			DRM_ERROR("power on error\n");
			goto out_err;
		}

		dbi_output->dbi_panel_on = true;

		if (pipe == 2)
			dev_priv->dbi_panel_on2 = true;
		else
			dev_priv->dbi_panel_on = true;

		if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
			mdfld_enable_te(dev, pipe);

		/* wake up error detector if ESD enabled */
		if (p_funcs->esd_detection)
			mdfld_dsi_error_detector_wakeup(dsi_connector);
		else
			PSB_DEBUG_ENTRY("ESD detection disabled\n");

		dsi_config->dsi_hw_context.panel_on = 1;
	} else {
		if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
			goto out_err;

		dbi_output->dbi_panel_on = false;
		dbi_output->first_boot = false;

		if (pipe == 2)
			dev_priv->dbi_panel_on2 = false;
		else
			dev_priv->dbi_panel_on = false;

		if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
			mdfld_disable_te(dev, pipe);

		ret = mdfld_panel_generic_dsi_dbi_power_off(encoder);
		if (ret) {
			DRM_ERROR("power on error\n");
			goto out_err;
		}

		dsi_config->dsi_hw_context.panel_on = 0;
	}

out_err:
	mutex_unlock(&dsi_config->context_lock);
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	if (ret)
		DRM_ERROR("failed\n");
	else
		PSB_DEBUG_ENTRY("successfully\n");

	return ret;
}
Exemplo n.º 6
0
/*
 * Enter DSR
 */
void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
{
	u32 reg_val;
	struct drm_device *dev = dbi_output->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct drm_crtc *crtc = dbi_output->base.base.crtc;
	struct psb_intel_crtc *psb_crtc = (crtc) ?
					to_psb_intel_crtc(crtc) : NULL;
	u32 dpll_reg = MRST_DPLL_A;
	u32 pipeconf_reg = PIPEACONF;
	u32 dspcntr_reg = DSPACNTR;

	if (!dbi_output)
		return;

	/* FIXME check if can go */
	dev_priv->is_in_idle = true;

	gdbi_output = dbi_output;
	if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
		return;

	if (pipe == 2) {
		dpll_reg = MRST_DPLL_A;
		pipeconf_reg = PIPECCONF;
		dspcntr_reg = DSPCCNTR;
	}

	if (!gma_power_begin(dev, true)) {
		dev_err(dev->dev, "hw begin failed\n");
		return;
	}
	/* Disable te interrupts */
	mdfld_disable_te(dev, pipe);

	/* Disable plane */
	reg_val = REG_READ(dspcntr_reg);
	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
		REG_WRITE(dspcntr_reg, reg_val & ~DISPLAY_PLANE_ENABLE);
		REG_READ(dspcntr_reg);
	}

	/* Disable pipe */
	reg_val = REG_READ(pipeconf_reg);
	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
		reg_val &= ~DISPLAY_PLANE_ENABLE;
		reg_val |= (PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF);
		REG_WRITE(pipeconf_reg, reg_val);
		REG_READ(pipeconf_reg);
		mdfldWaitForPipeDisable(dev, pipe);
	}

	/* Disable DPLL */
	reg_val = REG_READ(dpll_reg);
	if (!(reg_val & DPLL_VCO_ENABLE)) {
		reg_val &= ~DPLL_VCO_ENABLE;
		REG_WRITE(dpll_reg, reg_val);
		REG_READ(dpll_reg);
		udelay(500);
	}

	gma_power_end(dev);
	dbi_output->mode_flags |= MODE_SETTING_IN_DSR;
	if (pipe == 2) {
		enter_dsr = 1;
		/* pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */
	}
}