Ejemplo n.º 1
0
static void dsi_set_pipe_plane_enable_state(struct drm_device *dev,
							int state, int pipe)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	u32 pipeconf_reg = PIPEACONF;
	u32 dspcntr_reg = DSPACNTR;

	u32 dspcntr = dev_priv->dspcntr[pipe];
	u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;

	if (pipe) {
		pipeconf_reg = PIPECCONF;
		dspcntr_reg = DSPCCNTR;
	} else
		mipi &= (~0x03);

	if (state) {
		/*Set up pipe */
		REG_WRITE(pipeconf_reg, BIT(31));

		if (REG_BIT_WAIT(pipeconf_reg, 1, 30))
			dev_err(&dev->pdev->dev, "%s: Pipe enable timeout\n",
				__func__);

		/*Set up display plane */
		REG_WRITE(dspcntr_reg, dspcntr);
	} else {
		u32 dspbase_reg = pipe ? MDFLD_DSPCBASE : MRST_DSPABASE;

		/* Put DSI lanes to ULPS to disable pipe */
		REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 2, 2, 1);
		REG_READ(MIPI_DEVICE_READY_REG(pipe)); /* posted write? */

		/* LP Hold */
		REG_FLD_MOD(MIPI_PORT_CONTROL(pipe), 0, 16, 16);
		REG_READ(MIPI_PORT_CONTROL(pipe)); /* posted write? */

		/* Disable display plane */
		REG_FLD_MOD(dspcntr_reg, 0, 31, 31);

		/* Flush the plane changes ??? posted write? */
		REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
		REG_READ(dspbase_reg);

		/* Disable PIPE */
		REG_FLD_MOD(pipeconf_reg, 0, 31, 31);

		if (REG_BIT_WAIT(pipeconf_reg, 0, 30))
			dev_err(&dev->pdev->dev, "%s: Pipe disable timeout\n",
				__func__);

		if (REG_BIT_WAIT(MIPI_GEN_FIFO_STAT_REG(pipe), 1, 28))
			dev_err(&dev->pdev->dev, "%s: FIFO not empty\n",
				__func__);
	}
}
Ejemplo n.º 2
0
static void mdfld_wait_for_HS_CTRL_FIFO(struct drm_device *dev, u32 pipe)
{
	u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe);
	int timeout = 0;

	udelay(500);

	/* This will time out after approximately 2+ seconds */
	while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg)
					& DSI_FIFO_GEN_HS_CTRL_FULL)) {
		udelay(100);
		timeout++;
	}
	if (timeout == 20000)
		DRM_INFO("MIPI: HS CMD FIFO was never cleared!\n");
}
Ejemplo n.º 3
0
static void mdfld_wait_for_DPI_CTRL_FIFO(struct drm_device *dev, u32 pipe)
{
	u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe);
	int timeout = 0;

	udelay(500);

	/* This will time out after approximately 2+ seconds */
	while ((timeout < 20000) && ((REG_READ(gen_fifo_stat_reg) &
					DPI_FIFO_EMPTY) != DPI_FIFO_EMPTY)) {
		udelay(100);
		timeout++;
	}

	if (timeout == 20000)
		DRM_ERROR("MIPI: DPI FIFO was never cleared\n");
}
Ejemplo n.º 4
0
static int mdfld_dpu_update_fb(struct drm_device * dev) {
	struct drm_crtc * crtc;
	struct psb_intel_crtc * psb_crtc;
	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;
	bool pipe_updated[2];
	unsigned long irq_flags;
	u32 dpll_reg = PSB_DSI_PLL_CTRL;
	u32 dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_A);
	u32 pipeconf_reg = PSB_PIPECONF(PSB_PIPE_A);
	u32 dsplinoff_reg = PSB_DSPLINOFF(PSB_PIPE_A);
	u32 dspsurf_reg = PSB_DSPSURF(PSB_PIPE_A);
	int pipe;
	int i;
	int ret;

	dbi_output = dpu_info->dbi_outputs;
	pipe_updated[0] = pipe_updated[1] = false;
	
	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true))
		return -EAGAIN;

	/*try to prevent any new damage reports*/	
	if(!spin_trylock_irqsave(&dpu_info->dpu_update_lock, irq_flags)) {
		return -EAGAIN;
	}

	for(i=0; i<dpu_info->dbi_output_num; i++) {
		crtc = dbi_output[i]->base.base.crtc;
		psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; 

                pipe = dbi_output[i]->channel_num ? 2 : 0;

                if(pipe == 2) {
			dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_C);
			pipeconf_reg = PSB_PIPECONF(PSB_PIPE_C);
			dsplinoff_reg = PSB_DSPLINOFF(PSB_PIPE_C);
			dspsurf_reg = PSB_DSPSURF(PSB_PIPE_C);
                }

                if (!(REG_READ(MIPI_GEN_FIFO_STAT_REG(pipe)) & BIT(27)) ||
                   !(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
                   !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
                   !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) {
                        PSB_DEBUG_ENTRY("DBI FIFO is busy, DSI %d state %x\n",
                                        pipe,
                                        REG_READ(MIPI_INTR_STAT_REG(pipe)));
                        continue;
                }

		/*if dbi output is in a exclusive state, pipe change won't be updated*/
		if(dbi_output[i]->dbi_panel_on &&
		   !(dbi_output[i]->mode_flags & MODE_SETTING_ON_GOING) &&
		   !(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) &&
		   !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) {
			ret = mdfld_dpu_update_pipe(dbi_output[i], dpu_info, dbi_output[i]->channel_num ? 2 : 0);
			if(!ret) {
				pipe_updated[i] = true;
			}
		} 
	}
	
	for(i=0; i<dpu_info->dbi_output_num; i++) {
		if(pipe_updated[i]) {
			mdfld_dbi_flush_cb(dbi_output[i], dbi_output[i]->channel_num ? 2 : 0);
		}
	}

	spin_unlock_irqrestore(&dpu_info->dpu_update_lock, irq_flags);
	
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
	
	return 0;
}
Ejemplo n.º 5
0
int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
								int pipe)
{
	struct mdfld_dsi_pkg_sender *pkg_sender;
	struct mdfld_dsi_config *dsi_config =
				mdfld_dsi_get_config(dsi_connector);
	struct drm_device *dev = dsi_config->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	const struct psb_offset *map = &dev_priv->regmap[pipe];
	u32 mipi_val = 0;

	if (!dsi_connector) {
		DRM_ERROR("Invalid parameter\n");
		return -EINVAL;
	}

	pkg_sender = dsi_connector->pkg_sender;

	if (!pkg_sender || IS_ERR(pkg_sender)) {
		pkg_sender = kzalloc(sizeof(struct mdfld_dsi_pkg_sender),
								GFP_KERNEL);
		if (!pkg_sender) {
			DRM_ERROR("Create DSI pkg sender failed\n");
			return -ENOMEM;
		}
		dsi_connector->pkg_sender = (void *)pkg_sender;
	}

	pkg_sender->dev = dev;
	pkg_sender->dsi_connector = dsi_connector;
	pkg_sender->pipe = pipe;
	pkg_sender->pkg_num = 0;
	pkg_sender->panel_mode = 0;
	pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE;

	/*init regs*/
	/* FIXME: should just copy the regmap ptr ? */
	pkg_sender->dpll_reg = map->dpll;
	pkg_sender->dspcntr_reg = map->cntr;
	pkg_sender->pipeconf_reg = map->conf;
	pkg_sender->dsplinoff_reg = map->linoff;
	pkg_sender->dspsurf_reg = map->surf;
	pkg_sender->pipestat_reg = map->status;

	pkg_sender->mipi_intr_stat_reg = MIPI_INTR_STAT_REG(pipe);
	pkg_sender->mipi_lp_gen_data_reg = MIPI_LP_GEN_DATA_REG(pipe);
	pkg_sender->mipi_hs_gen_data_reg = MIPI_HS_GEN_DATA_REG(pipe);
	pkg_sender->mipi_lp_gen_ctrl_reg = MIPI_LP_GEN_CTRL_REG(pipe);
	pkg_sender->mipi_hs_gen_ctrl_reg = MIPI_HS_GEN_CTRL_REG(pipe);
	pkg_sender->mipi_gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe);
	pkg_sender->mipi_data_addr_reg = MIPI_DATA_ADD_REG(pipe);
	pkg_sender->mipi_data_len_reg = MIPI_DATA_LEN_REG(pipe);
	pkg_sender->mipi_cmd_addr_reg = MIPI_CMD_ADD_REG(pipe);
	pkg_sender->mipi_cmd_len_reg = MIPI_CMD_LEN_REG(pipe);

	/*init lock*/
	spin_lock_init(&pkg_sender->lock);

	if (mdfld_get_panel_type(dev, pipe) != TC35876X) {
		/**
		 * For video mode, don't enable DPI timing output here,
		 * will init the DPI timing output during mode setting.
		 */
		mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;

		if (pipe == 0)
			mipi_val |= 0x2;

		REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi_val);
		REG_READ(MIPI_PORT_CONTROL(pipe));

		/* do dsi controller init */
		mdfld_dsi_controller_init(dsi_config, pipe);
	}

	return 0;
}