Beispiel #1
0
/*
 * Update the DBI MIPI Panel Frame Buffer.
 */
static void mdfld_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
								int pipe)
{
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
	struct drm_device *dev = dbi_output->dev;
	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 dspcntr_reg = DSPACNTR;
	u32 pipeconf_reg = PIPEACONF;
	u32 dsplinoff_reg = DSPALINOFF;
	u32 dspsurf_reg = DSPASURF;
	u32 reg_offset = 0;

	/* If mode setting on-going, back off */
	if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) ||
		!(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
		return;

	if (pipe == 2) {
		dspcntr_reg = DSPCCNTR;
		pipeconf_reg = PIPECCONF;
		dsplinoff_reg = DSPCLINOFF;
		dspsurf_reg = DSPCSURF;
		reg_offset = MIPIC_REG_OFFSET;
	}

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

	/* Check DBI FIFO status */
	if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
	   !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
	   !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE))
		goto update_fb_out0;

	/* Refresh plane changes */
	REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
	REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
	REG_READ(dspsurf_reg);

	mdfld_dsi_send_dcs(sender,
			   DCS_WRITE_MEM_START,
			   NULL,
			   0,
			   CMD_DATA_SRC_PIPE,
			   MDFLD_DSI_SEND_PACKAGE);

	dbi_output->dsr_fb_update_done = true;
update_fb_out0:
	gma_power_end(dev);
}
Beispiel #2
0
/*
 * send a generic DCS command with a parameter list
 */
int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
			u8 dcs,  u8 *param, u32 num, u8 data_src)
{
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
	int ret;

	if (!sender) {
		WARN_ON(1);
		return -EINVAL;
	}

	ret = mdfld_dsi_send_dcs(sender,
				 dcs,
				 param,
				 num,
				 data_src,
				 MDFLD_DSI_SEND_PACKAGE);

	return ret;
}
int mdfld_dsi_dbi_async_check_fifo_empty(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
	struct mdfld_dsi_dbi_output **dbi_outputs = NULL;
	struct mdfld_dsi_dbi_output *dbi_output = NULL;
	struct mdfld_dsi_pkg_sender *sender = NULL;
	int err = 0;

	dbi_outputs = dsr_info->dbi_outputs;
	dbi_output = 0 ? dbi_outputs[1] : dbi_outputs[0];
	if (!dbi_output)
		return 0;

	sender = mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
	if (!sender) {
		DRM_ERROR("pkg sender is NULL\n");
		return -EINVAL;
	}
	err = mdfld_dsi_check_fifo_empty(sender);
	return err;
}
static
void intel_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output)
{
	struct mdfld_dsi_pkg_sender *sender;
	struct drm_device *dev = dbi_output->dev;
	struct drm_crtc *crtc = dbi_output->base.base.crtc;
	struct psb_intel_crtc *psb_crtc =
		(crtc) ? to_psb_intel_crtc(crtc) : NULL;
	int pipe = dbi_output->channel_num ? 2 : 0;
	u32 dpll_reg = MRST_DPLL_A;
	u32 dspcntr_reg = DSPACNTR;
	u32 pipeconf_reg = PIPEACONF;
	u32 dsplinoff_reg = DSPALINOFF;
	u32 dspsurf_reg = DSPASURF;

	sender = mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
	if (!sender) {
		DRM_ERROR("pkg sender is NULL\n");
		return;
	}

	/* if mode setting on-going, back off */

	if (!IS_ANN_A0(dev)) {
		if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
				(psb_crtc && (psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) ||
				!(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
			return;
	}

	if (pipe == 2) {
		dspcntr_reg = DSPCCNTR;
		pipeconf_reg = PIPECCONF;
		dsplinoff_reg = DSPCLINOFF;
		dspsurf_reg = DSPCSURF;
	}

	/* check DBI FIFO status */
	if (is_panel_vid_or_cmd(dev) == MDFLD_DSI_ENCODER_DBI) {
		if (!(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
		   !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE))
			return;
	} else if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
	   !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
	   !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE))
		return;

	if (!IS_ANN_A0(dev)) {
		/* refresh plane changes */

		REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
		REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
		REG_READ(dspsurf_reg);
	}

	mdfld_dsi_send_dcs(sender,
			   write_mem_start,
			   NULL,
			   0,
			   CMD_DATA_SRC_PIPE,
			   MDFLD_DSI_SEND_PACKAGE);
	dbi_output->dsr_fb_update_done = true;
	mdfld_dsi_cmds_kick_out(sender);
}
/**
 * Update the DBI MIPI Panel Frame Buffer.
 */
static void pyr_dsi_dbi_update_fb (struct mdfld_dsi_dbi_output * dbi_output, int pipe)
{
	struct mdfld_dsi_pkg_sender * sender =
		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
	struct drm_device * dev = dbi_output->dev;
	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 dspcntr_reg = DSPACNTR;
	u32 pipeconf_reg = PIPEACONF;
	u32 dsplinoff_reg = DSPALINOFF;
	u32 dspsurf_reg = DSPASURF;
	/*u32 mipi_state_reg = MIPIA_INTR_STAT_REG;*/
	u32 hs_gen_ctrl_reg = HS_GEN_CTRL_REG;
	u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
	u32 reg_offset = 0;

	u32 intr_status;
	u32 fifo_stat_reg_val;
	u32 dpll_reg_val;
	u32 dspcntr_reg_val;
	u32 pipeconf_reg_val;

	/*if mode setting on-going, back off*/
	if((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) ||
		!(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
		return;

	/*
	 * Look for errors here.  In particular we're checking for whatever
 	 * error status might have appeared during the last frame transmit
 	 * (memory write).
 	 *
 	 * Normally, the bits we're testing here would be set infrequently,
 	 * if at all.  However, the Pyrenees panel (at least) returns
 	 * at least one error bit on most frames.  So we've disabled the
 	 * kernel message for now.
 	 *
 	 * Still clear whatever error bits are set, except don't clear the
 	 * ones that would make the Penwell DSI controller reset if we
 	 * cleared them.
 	 */
	intr_status = REG_READ(INTR_STAT_REG);
	if ((intr_status & 0x26FFFFFF) != 0) {
		/* DRM_ERROR("DSI status: 0x%08X\n", intr_status); */
		intr_status &= 0x26F3FFFF;
	        REG_WRITE(INTR_STAT_REG, intr_status);
	}
		
	if(pipe == 2) {
		dspcntr_reg = DSPCCNTR;
		pipeconf_reg = PIPECCONF;
		dsplinoff_reg = DSPCLINOFF;
		dspsurf_reg = DSPCSURF;

		hs_gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
		gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET,

		reg_offset = MIPIC_REG_OFFSET;
	}

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

	fifo_stat_reg_val = REG_READ(MIPIA_GEN_FIFO_STAT_REG + reg_offset);
	dpll_reg_val = REG_READ(dpll_reg);
	dspcntr_reg_val = REG_READ(dspcntr_reg);
	pipeconf_reg_val = REG_READ(pipeconf_reg);

	if(!(fifo_stat_reg_val & BIT27) ||
	   !(dpll_reg_val & DPLL_VCO_ENABLE) ||
	   !(dspcntr_reg_val & DISPLAY_PLANE_ENABLE) ||
	   !(pipeconf_reg_val & DISPLAY_PLANE_ENABLE)) {
		goto update_fb_out0;
	}
	
	/*refresh plane changes*/
	REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
	REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
	REG_READ(dspsurf_reg);

	mdfld_dsi_send_dcs(sender,
			   write_mem_start,
			   NULL,
			   0,
			   CMD_DATA_SRC_PIPE,
			   MDFLD_DSI_SEND_PACKAGE);

	/*
	* The idea here is to transmit a Generic Read command after the
	* Write Memory Start/Continue commands finish.  This asks for
	* the panel to return an "ACK No Errors," or (if it has errors
	* to report) an Error Report.  This allows us to monitor the
	* panel's perception of the health of the DSI.
	*/

	mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
	REG_WRITE(hs_gen_ctrl_reg, (1 << WORD_COUNTS_POS) | GEN_READ_0);

	dbi_output->dsr_fb_update_done = true;
update_fb_out0:
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
}
Beispiel #6
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");
}
void mdfld_panel_generic_dsi_dbi_update_fb(
	struct mdfld_dsi_dbi_output *dbi_output,
	int pipe)
{
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
	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 dspcntr_reg = DSPACNTR;
	u32 pipeconf_reg = PIPEACONF;
	u32 dsplinoff_reg = DSPALINOFF;
	u32 dspsurf_reg = DSPASURF;

	if (!dev_priv->dsi_init_done)
		return;

	/* if mode setting on-going, back off */
	if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
			(psb_crtc &&
			 (psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) ||
			!(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
		return;

	if (pipe == 2) {
		dspcntr_reg = DSPCCNTR;
		pipeconf_reg = PIPECCONF;
		dsplinoff_reg = DSPCLINOFF;
		dspsurf_reg = DSPCSURF;
	}

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

	/* check DBI FIFO status */
	if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
	   !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
	   !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) {
		goto update_fb_out0;
	}

	/* refresh plane changes */
	REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
	REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
	REG_READ(dspsurf_reg);

	mdfld_dsi_send_dcs(sender,
			   write_mem_start,
			   NULL,
			   0,
			   CMD_DATA_SRC_PIPE,
			   MDFLD_DSI_SEND_PACKAGE);

	dbi_output->dsr_fb_update_done = true;


update_fb_out0:
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
}
Beispiel #8
0
/*
 * set refreshing area
 */
int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
				u16 x1, u16 y1, u16 x2, u16 y2)
{
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
	u8 param[4];
	u8 cmd;
	int err;

	if (!sender) {
		WARN_ON(1);
		return -EINVAL;
	}

	/* Set column */
	cmd = DCS_SET_COLUMN_ADDRESS;
	param[0] = x1 >> 8;
	param[1] = x1;
	param[2] = x2 >> 8;
	param[3] = x2;

	err = mdfld_dsi_send_dcs(sender,
				 cmd,
				 param,
				 4,
				 CMD_DATA_SRC_SYSTEM_MEM,
				 MDFLD_DSI_QUEUE_PACKAGE);
	if (err) {
		dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
		goto err_out;
	}

	/* Set page */
	cmd = DCS_SET_PAGE_ADDRESS;
	param[0] = y1 >> 8;
	param[1] = y1;
	param[2] = y2 >> 8;
	param[3] = y2;

	err = mdfld_dsi_send_dcs(sender,
				 cmd,
				 param,
				 4,
				 CMD_DATA_SRC_SYSTEM_MEM,
				 MDFLD_DSI_QUEUE_PACKAGE);
	if (err) {
		dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
		goto err_out;
	}

	/*update screen*/
	err = mdfld_dsi_send_dcs(sender,
				 write_mem_start,
				 NULL,
				 0,
				 CMD_DATA_SRC_PIPE,
				 MDFLD_DSI_QUEUE_PACKAGE);
	if (err) {
		dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
		goto err_out;
	}
	mdfld_dsi_cmds_kick_out(sender);
err_out:
	return err;
}
Beispiel #9
0
/*
 * set panel's power state
 */
int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
								int mode)
{
	struct drm_device *dev = dbi_output->dev;
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
	u8 param = 0;
	u32 err = 0;

	if (!sender) {
		WARN_ON(1);
		return -EINVAL;
	}

	if (mode == DRM_MODE_DPMS_ON) {
		/* Exit sleep mode */
		err = mdfld_dsi_send_dcs(sender,
					 DCS_EXIT_SLEEP_MODE,
					 NULL,
					 0,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 MDFLD_DSI_QUEUE_PACKAGE);
		if (err) {
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
						DCS_EXIT_SLEEP_MODE);
			goto power_err;
		}

		/* Set display on */
		err = mdfld_dsi_send_dcs(sender,
					 DCS_SET_DISPLAY_ON,
					 NULL,
					 0,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 MDFLD_DSI_QUEUE_PACKAGE);
		if (err) {
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
							DCS_SET_DISPLAY_ON);
			goto power_err;
		}

		/* set tear effect on */
		err = mdfld_dsi_send_dcs(sender,
					 DCS_SET_TEAR_ON,
					 &param,
					 1,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 MDFLD_DSI_QUEUE_PACKAGE);
		if (err) {
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
							set_tear_on);
			goto power_err;
		}

		/**
		 * FIXME: remove this later
		 */
		err = mdfld_dsi_send_dcs(sender,
					 DCS_WRITE_MEM_START,
					 NULL,
					 0,
					 CMD_DATA_SRC_PIPE,
					 MDFLD_DSI_QUEUE_PACKAGE);
		if (err) {
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
						DCS_WRITE_MEM_START);
			goto power_err;
		}
	} else {
		/* Set tear effect off */
		err = mdfld_dsi_send_dcs(sender,
					 DCS_SET_TEAR_OFF,
					 NULL,
					 0,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 MDFLD_DSI_QUEUE_PACKAGE);
		if (err) {
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
							DCS_SET_TEAR_OFF);
			goto power_err;
		}

		/* Turn display off */
		err = mdfld_dsi_send_dcs(sender,
					 DCS_SET_DISPLAY_OFF,
					 NULL,
					 0,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 MDFLD_DSI_QUEUE_PACKAGE);
		if (err) {
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
						DCS_SET_DISPLAY_OFF);
			goto power_err;
		}

		/* Now enter sleep mode */
		err = mdfld_dsi_send_dcs(sender,
					 DCS_ENTER_SLEEP_MODE,
					 NULL,
					 0,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 MDFLD_DSI_QUEUE_PACKAGE);
		if (err) {
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
							DCS_ENTER_SLEEP_MODE);
			goto power_err;
		}
	}
	mdfld_dsi_cmds_kick_out(sender);
power_err:
	return err;
}