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__);
	}
}
static void mdfld_mipi_config(struct mdfld_dsi_config *dsi_config, int pipe)
{
	struct drm_device *dev = dsi_config->dev;
	int lane_count = dsi_config->lane_count;

	if (pipe) {
		REG_WRITE(MIPI_PORT_CONTROL(0), 0x00000002);
		REG_WRITE(MIPI_PORT_CONTROL(2), 0x80000000);
	} else {
		REG_WRITE(MIPI_PORT_CONTROL(0), 0x80010000);
		REG_WRITE(MIPI_PORT_CONTROL(2), 0x00);
	}

	REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x150A600F);
	REG_WRITE(MIPI_VIDEO_MODE_FORMAT_REG(pipe), 0x0000000F);

	/* lane_count = 3 */
	REG_WRITE(MIPI_DSI_FUNC_PRG_REG(pipe), 0x00000200 | lane_count);

	mdfld_mipi_set_video_timing(dsi_config, pipe);
}
static void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
{
	struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder);
	struct mdfld_dsi_dpi_output *dpi_output =
				MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
				mdfld_dsi_encoder_get_config(dsi_encoder);
	int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
	struct drm_device *dev = dsi_config->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;

	/*start up display island if it was shutdown*/
	if (!gma_power_begin(dev, true))
		return;

	if (on) {
		if (mdfld_get_panel_type(dev, pipe) == TMD_VID)
			mdfld_dsi_dpi_turn_on(dpi_output, pipe);
		else if (mdfld_get_panel_type(dev, pipe) == TC35876X)
			mdfld_dsi_configure_up(dsi_encoder, pipe);
		else {
			/*enable mipi port*/
			REG_WRITE(MIPI_PORT_CONTROL(pipe),
				REG_READ(MIPI_PORT_CONTROL(pipe)) | BIT(31));
			REG_READ(MIPI_PORT_CONTROL(pipe));

			mdfld_dsi_dpi_turn_on(dpi_output, pipe);
			mdfld_dsi_tpo_ic_init(dsi_config, pipe);
		}
		dev_priv->dpi_panel_on[pipe] = true;
	} else {
		if (mdfld_get_panel_type(dev, pipe) == TMD_VID)
			mdfld_dsi_dpi_shut_down(dpi_output, pipe);
		else if (mdfld_get_panel_type(dev, pipe) == TC35876X)
			mdfld_dsi_configure_down(dsi_encoder, pipe);
		else {
			mdfld_dsi_dpi_shut_down(dpi_output, pipe);

			/*disable mipi port*/
			REG_WRITE(MIPI_PORT_CONTROL(pipe),
				REG_READ(MIPI_PORT_CONTROL(pipe)) & ~BIT(31));
			REG_READ(MIPI_PORT_CONTROL(pipe));
		}
		dev_priv->dpi_panel_on[pipe] = false;
	}
	gma_power_end(dev);
}
void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
				   struct drm_display_mode *mode,
				   struct drm_display_mode *adjusted_mode)
{
	struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder);
	struct mdfld_dsi_dpi_output *dpi_output =
					MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
				mdfld_dsi_encoder_get_config(dsi_encoder);
	struct drm_device *dev = dsi_config->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);

	u32 pipeconf_reg = PIPEACONF;
	u32 dspcntr_reg = DSPACNTR;

	u32 pipeconf;
	u32 dspcntr;
	u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;

	if (pipe == -1)
		return;

	pipeconf = dev_priv->pipeconf[pipe];
	dspcntr = dev_priv->dspcntr[pipe];

	if (pipe) {
		pipeconf_reg = PIPECCONF;
		dspcntr_reg = DSPCCNTR;
	} else {
		if (mdfld_get_panel_type(dev, pipe) == TC35876X)
			mipi &= (~0x03); /* Use all four lanes */
		else
			mipi |= 2;
	}

	/*start up display island if it was shutdown*/
	if (!gma_power_begin(dev, true))
		return;

	if (mdfld_get_panel_type(dev, pipe) == TC35876X) {
		/*
		 * The following logic is required to reset the bridge and
		 * configure. This also starts the DSI clock at 200MHz.
		 */
		tc35876x_set_bridge_reset_state(dev, 0);  /*Pull High Reset */
		tc35876x_toshiba_bridge_panel_on(dev);
		udelay(100);
		/* Now start the DSI clock */
		REG_WRITE(MRST_DPLL_A, 0x00);
		REG_WRITE(MRST_FPA0, 0xC1);
		REG_WRITE(MRST_DPLL_A, 0x00800000);
		udelay(500);
		REG_WRITE(MRST_DPLL_A, 0x80800000);

		if (REG_BIT_WAIT(pipeconf_reg, 1, 29))
			dev_err(&dev->pdev->dev, "%s: DSI PLL lock timeout\n",
				__func__);

		REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x2A0c6008);

		mipi_set_properties(dsi_config, pipe);
		mdfld_mipi_config(dsi_config, pipe);
		mdfld_set_pipe_timing(dsi_config, pipe);

		REG_WRITE(DSPABASE, 0x00);
		REG_WRITE(DSPASIZE,
			((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));

		REG_WRITE(DSPACNTR, 0x98000000);
		REG_WRITE(DSPASURF, 0x00);

		REG_WRITE(VGACNTRL, 0x80000000);
		REG_WRITE(DEVICE_READY_REG, 0x00000001);

		REG_WRITE(MIPI_PORT_CONTROL(pipe), 0x80810000);
	} else {
		/*set up mipi port FIXME: do at init time */
		REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi);
	}
	REG_READ(MIPI_PORT_CONTROL(pipe));

	if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
		/* NOP */
	} else if (mdfld_get_panel_type(dev, pipe) == TC35876X) {
		/* set up DSI controller DPI interface */
		mdfld_dsi_dpi_controller_init(dsi_config, pipe);

		/* Configure MIPI Bridge and Panel */
		tc35876x_configure_lvds_bridge(dev);
		dev_priv->dpi_panel_on[pipe] = true;
	} else {
		/*turn on DPI interface*/
		mdfld_dsi_dpi_turn_on(dpi_output, pipe);
	}

	/*set up pipe*/
	REG_WRITE(pipeconf_reg, pipeconf);
	REG_READ(pipeconf_reg);

	/*set up display plane*/
	REG_WRITE(dspcntr_reg, dspcntr);
	REG_READ(dspcntr_reg);

	msleep(20); /* FIXME: this should wait for vblank */

	if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
		/* NOP */
	} else if (mdfld_get_panel_type(dev, pipe) == TC35876X) {
		mdfld_dsi_dpi_turn_on(dpi_output, pipe);
	} else {
		/* init driver ic */
		mdfld_dsi_tpo_ic_init(dsi_config, pipe);
		/*init backlight*/
		mdfld_dsi_brightness_init(dsi_config, pipe);
	}

	gma_power_end(dev);
}
Beispiel #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;
}