예제 #1
0
static void exynos_dpi_poweron(struct exynos_dpi *ctx)
{
	if (ctx->panel) {
		drm_panel_prepare(ctx->panel);
		drm_panel_enable(ctx->panel);
	}
}
예제 #2
0
static void imx_pd_encoder_commit(struct drm_encoder *encoder)
{
	struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);

	drm_panel_prepare(imxpd->panel);
	drm_panel_enable(imxpd->panel);
}
예제 #3
0
static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder)
{
	struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
	int mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node, encoder);
	u32 val;

	if (clk_prepare_enable(dsi->pclk)) {
		dev_err(dsi->dev, "%s: Failed to enable pclk\n", __func__);
		return;
	}

	dw_mipi_dsi_phy_init(dsi);
	dw_mipi_dsi_wait_for_two_frames(dsi);

	dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_VID_MODE);
	drm_panel_enable(dsi->panel);

	clk_disable_unprepare(dsi->pclk);

	if (mux)
		val = DSI0_SEL_VOP_LIT | (DSI0_SEL_VOP_LIT << 16);
	else
		val = DSI0_SEL_VOP_LIT << 16;

	regmap_write(dsi->grf_regmap, GRF_SOC_CON6, val);
	dev_dbg(dsi->dev, "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG");
}
예제 #4
0
static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode)
{
	struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);

	if (mode != DRM_MODE_DPMS_ON)
		drm_panel_disable(imxpd->panel);
	else
		drm_panel_enable(imxpd->panel);
}
예제 #5
0
static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
			to_mdp4_lcdc_encoder(encoder);
	unsigned long pc = mdp4_lcdc_encoder->pixclock;
	struct mdp4_kms *mdp4_kms = get_kms(encoder);
	struct drm_panel *panel;
	uint32_t config;
	int i, ret;

	if (WARN_ON(mdp4_lcdc_encoder->enabled))
		return;

	/* TODO: hard-coded for 18bpp: */
	config =
		MDP4_DMA_CONFIG_R_BPC(BPC6) |
		MDP4_DMA_CONFIG_G_BPC(BPC6) |
		MDP4_DMA_CONFIG_B_BPC(BPC6) |
		MDP4_DMA_CONFIG_PACK(0x21) |
		MDP4_DMA_CONFIG_DEFLKR_EN |
		MDP4_DMA_CONFIG_DITHER_EN;

	if (!of_property_read_bool(dev->dev->of_node, "qcom,lcdc-align-lsb"))
		config |= MDP4_DMA_CONFIG_PACK_ALIGN_MSB;

	mdp4_crtc_set_config(encoder->crtc, config);
	mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0);

	bs_set(mdp4_lcdc_encoder, 1);

	for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) {
		ret = regulator_enable(mdp4_lcdc_encoder->regs[i]);
		if (ret)
			DRM_DEV_ERROR(dev->dev, "failed to enable regulator: %d\n", ret);
	}

	DBG("setting lcdc_clk=%lu", pc);
	ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc);
	if (ret)
		DRM_DEV_ERROR(dev->dev, "failed to configure lcdc_clk: %d\n", ret);
	ret = clk_prepare_enable(mdp4_lcdc_encoder->lcdc_clk);
	if (ret)
		DRM_DEV_ERROR(dev->dev, "failed to enable lcdc_clk: %d\n", ret);

	panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node);
	if (!IS_ERR(panel)) {
		drm_panel_prepare(panel);
		drm_panel_enable(panel);
	}

	setup_phy(encoder);

	mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 1);

	mdp4_lcdc_encoder->enabled = true;
}
예제 #6
0
static void exynos_dp_commit(struct drm_encoder *encoder)
{
	struct exynos_dp_device *dp = encoder_to_dp(encoder);
	int ret;

	/* Keep the panel disabled while we configure video */
	if (dp->panel) {
		if (drm_panel_disable(dp->panel))
			DRM_ERROR("failed to disable the panel\n");
	}

	ret = exynos_dp_detect_hpd(dp);
	if (ret) {
		/* Cable has been disconnected, we're done */
		return;
	}

	ret = exynos_dp_handle_edid(dp);
	if (ret) {
		dev_err(dp->dev, "unable to handle edid\n");
		return;
	}

	ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
					dp->video_info->link_rate);
	if (ret) {
		dev_err(dp->dev, "unable to do link train\n");
		return;
	}

	exynos_dp_enable_scramble(dp, 1);
	exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
	exynos_dp_enable_enhanced_mode(dp, 1);

	exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
	exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);

	exynos_dp_init_video(dp);
	ret = exynos_dp_config_video(dp);
	if (ret)
		dev_err(dp->dev, "unable to config video\n");

	/* Safe to enable the panel now */
	if (dp->panel) {
		if (drm_panel_enable(dp->panel))
			DRM_ERROR("failed to enable the panel\n");
	}

	/* Enable video */
	exynos_dp_start_video(dp);
}
static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
			to_mdp4_lcdc_encoder(encoder);
	unsigned long pc = mdp4_lcdc_encoder->pixclock;
	struct mdp4_kms *mdp4_kms = get_kms(encoder);
	struct drm_panel *panel = mdp4_lcdc_encoder->panel;
	int i, ret;

	if (WARN_ON(mdp4_lcdc_encoder->enabled))
		return;

	/* TODO: hard-coded for 18bpp: */
	mdp4_crtc_set_config(encoder->crtc,
			MDP4_DMA_CONFIG_R_BPC(BPC6) |
			MDP4_DMA_CONFIG_G_BPC(BPC6) |
			MDP4_DMA_CONFIG_B_BPC(BPC6) |
			MDP4_DMA_CONFIG_PACK_ALIGN_MSB |
			MDP4_DMA_CONFIG_PACK(0x21) |
			MDP4_DMA_CONFIG_DEFLKR_EN |
			MDP4_DMA_CONFIG_DITHER_EN);
	mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0);

	bs_set(mdp4_lcdc_encoder, 1);

	for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) {
		ret = regulator_enable(mdp4_lcdc_encoder->regs[i]);
		if (ret)
			dev_err(dev->dev, "failed to enable regulator: %d\n", ret);
	}

	DBG("setting lcdc_clk=%lu", pc);
	ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc);
	if (ret)
		dev_err(dev->dev, "failed to configure lcdc_clk: %d\n", ret);
	ret = clk_prepare_enable(mdp4_lcdc_encoder->lcdc_clk);
	if (ret)
		dev_err(dev->dev, "failed to enable lcdc_clk: %d\n", ret);

	if (panel) {
		drm_panel_prepare(panel);
		drm_panel_enable(panel);
	}

	setup_phy(encoder);

	mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 1);

	mdp4_lcdc_encoder->enabled = true;
}
예제 #8
0
파일: output.c 프로젝트: 383530895/linux
static void tegra_encoder_dpms(struct drm_encoder *encoder, int mode)
{
	struct tegra_output *output = encoder_to_output(encoder);
	struct drm_panel *panel = output->panel;

	if (mode != DRM_MODE_DPMS_ON) {
		drm_panel_disable(panel);
		tegra_output_disable(output);
		drm_panel_unprepare(panel);
	} else {
		drm_panel_prepare(panel);
		tegra_output_enable(output);
		drm_panel_enable(panel);
	}
}
예제 #9
0
파일: imx-ldb.c 프로젝트: 19Dan01/linux
static void imx_ldb_encoder_commit(struct drm_encoder *encoder)
{
	struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
	struct imx_ldb *ldb = imx_ldb_ch->ldb;
	int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
	int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);

	drm_panel_prepare(imx_ldb_ch->panel);

	if (dual) {
		clk_prepare_enable(ldb->clk[0]);
		clk_prepare_enable(ldb->clk[1]);
	}

	if (imx_ldb_ch == &ldb->channel[0] || dual) {
		ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
		if (mux == 0 || ldb->lvds_mux)
			ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI0;
		else if (mux == 1)
			ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI1;
	}
	if (imx_ldb_ch == &ldb->channel[1] || dual) {
		ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK;
		if (mux == 1 || ldb->lvds_mux)
			ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI1;
		else if (mux == 0)
			ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI0;
	}

	if (ldb->lvds_mux) {
		const struct bus_mux *lvds_mux = NULL;

		if (imx_ldb_ch == &ldb->channel[0])
			lvds_mux = &ldb->lvds_mux[0];
		else if (imx_ldb_ch == &ldb->channel[1])
			lvds_mux = &ldb->lvds_mux[1];

		regmap_update_bits(ldb->regmap, lvds_mux->reg, lvds_mux->mask,
				   mux << lvds_mux->shift);
	}

	regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl);

	drm_panel_enable(imx_ldb_ch->panel);
}
예제 #10
0
static void analogix_dp_commit(struct analogix_dp_device *dp)
{
	int ret;

	/* Keep the panel disabled while we configure video */
	if (dp->plat_data->panel) {
		if (drm_panel_disable(dp->plat_data->panel))
			DRM_ERROR("failed to disable the panel\n");
	}

	ret = analogix_dp_set_link_train(dp, dp->video_info.max_lane_count,
					 dp->video_info.max_link_rate);
	if (ret) {
		dev_err(dp->dev, "unable to do link train\n");
		return;
	}

	analogix_dp_enable_scramble(dp, 1);
	analogix_dp_enable_rx_to_enhanced_mode(dp, 1);
	analogix_dp_enable_enhanced_mode(dp, 1);

	analogix_dp_init_video(dp);
	ret = analogix_dp_config_video(dp);
	if (ret)
		dev_err(dp->dev, "unable to config video\n");

	/* Safe to enable the panel now */
	if (dp->plat_data->panel) {
		if (drm_panel_enable(dp->plat_data->panel))
			DRM_ERROR("failed to enable the panel\n");
	}

	/* Enable video */
	analogix_dp_start_video(dp);

	dp->psr_support = analogix_dp_detect_sink_psr(dp);
	if (dp->psr_support)
		analogix_dp_enable_sink_psr(dp);
}
예제 #11
0
파일: rcar_lvds.c 프로젝트: lumag/linux
static void rcar_lvds_enable(struct drm_bridge *bridge)
{
	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
	const struct drm_display_mode *mode = &lvds->display_mode;
	/*
	 * FIXME: We should really retrieve the CRTC through the state, but how
	 * do we get a state pointer?
	 */
	struct drm_crtc *crtc = lvds->bridge.encoder->crtc;
	u32 lvdpllcr;
	u32 lvdhcr;
	u32 lvdcr0;
	int ret;

	WARN_ON(lvds->enabled);

	ret = clk_prepare_enable(lvds->clock);
	if (ret < 0)
		return;

	/*
	 * Hardcode the channels and control signals routing for now.
	 *
	 * HSYNC -> CTRL0
	 * VSYNC -> CTRL1
	 * DISP  -> CTRL2
	 * 0     -> CTRL3
	 */
	rcar_lvds_write(lvds, LVDCTRCR, LVDCTRCR_CTR3SEL_ZERO |
			LVDCTRCR_CTR2SEL_DISP | LVDCTRCR_CTR1SEL_VSYNC |
			LVDCTRCR_CTR0SEL_HSYNC);

	if (lvds->info->quirks & RCAR_LVDS_QUIRK_LANES)
		lvdhcr = LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 3)
		       | LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 1);
	else
		lvdhcr = LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 1)
		       | LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 3);

	rcar_lvds_write(lvds, LVDCHCR, lvdhcr);

	/* PLL clock configuration. */
	if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN2_PLLCR)
		lvdpllcr = rcar_lvds_lvdpllcr_gen2(mode->clock);
	else
		lvdpllcr = rcar_lvds_lvdpllcr_gen3(mode->clock);
	rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);

	/* Set the LVDS mode and select the input. */
	lvdcr0 = lvds->mode << LVDCR0_LVMD_SHIFT;
	if (drm_crtc_index(crtc) == 2)
		lvdcr0 |= LVDCR0_DUSEL;
	rcar_lvds_write(lvds, LVDCR0, lvdcr0);

	/* Turn all the channels on. */
	rcar_lvds_write(lvds, LVDCR1,
			LVDCR1_CHSTBY(3) | LVDCR1_CHSTBY(2) |
			LVDCR1_CHSTBY(1) | LVDCR1_CHSTBY(0) | LVDCR1_CLKSTBY);

	if (lvds->info->gen < 3) {
		/* Enable LVDS operation and turn the bias circuitry on. */
		lvdcr0 |= LVDCR0_BEN | LVDCR0_LVEN;
		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
	}

	/* Turn the PLL on. */
	lvdcr0 |= LVDCR0_PLLON;
	rcar_lvds_write(lvds, LVDCR0, lvdcr0);

	if (lvds->info->gen > 2) {
		/* Set LVDS normal mode. */
		lvdcr0 |= LVDCR0_PWD;
		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
	}

	if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN3_LVEN) {
		/* Turn on the LVDS PHY. */
		lvdcr0 |= LVDCR0_LVEN;
		rcar_lvds_write(lvds, LVDCR0, lvdcr0);
	}

	/* Wait for the startup delay. */
	usleep_range(100, 150);

	/* Turn the output on. */
	lvdcr0 |= LVDCR0_LVRES;
	rcar_lvds_write(lvds, LVDCR0, lvdcr0);

	if (lvds->panel) {
		drm_panel_prepare(lvds->panel);
		drm_panel_enable(lvds->panel);
	}

	lvds->enabled = true;
}
예제 #12
0
파일: dsi_manager.c 프로젝트: Lyude/linux
static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
{
	int id = dsi_mgr_bridge_get_id(bridge);
	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
	struct mipi_dsi_host *host = msm_dsi->host;
	struct drm_panel *panel = msm_dsi->panel;
	struct msm_dsi_phy_shared_timings phy_shared_timings[DSI_MAX];
	bool is_dual_dsi = IS_DUAL_DSI();
	int ret;

	DBG("id=%d", id);
	if (!msm_dsi_device_connected(msm_dsi))
		return;

	ret = dsi_mgr_phy_enable(id, phy_shared_timings);
	if (ret)
		goto phy_en_fail;

	/* Do nothing with the host if it is slave-DSI in case of dual DSI */
	if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
		return;

	ret = msm_dsi_host_power_on(host, &phy_shared_timings[id], is_dual_dsi);
	if (ret) {
		pr_err("%s: power on host %d failed, %d\n", __func__, id, ret);
		goto host_on_fail;
	}

	if (is_dual_dsi && msm_dsi1) {
		ret = msm_dsi_host_power_on(msm_dsi1->host,
				&phy_shared_timings[DSI_1], is_dual_dsi);
		if (ret) {
			pr_err("%s: power on host1 failed, %d\n",
							__func__, ret);
			goto host1_on_fail;
		}
	}

	/* Always call panel functions once, because even for dual panels,
	 * there is only one drm_panel instance.
	 */
	if (panel) {
		ret = drm_panel_prepare(panel);
		if (ret) {
			pr_err("%s: prepare panel %d failed, %d\n", __func__,
								id, ret);
			goto panel_prep_fail;
		}
	}

	ret = msm_dsi_host_enable(host);
	if (ret) {
		pr_err("%s: enable host %d failed, %d\n", __func__, id, ret);
		goto host_en_fail;
	}

	if (is_dual_dsi && msm_dsi1) {
		ret = msm_dsi_host_enable(msm_dsi1->host);
		if (ret) {
			pr_err("%s: enable host1 failed, %d\n", __func__, ret);
			goto host1_en_fail;
		}
	}

	if (panel) {
		ret = drm_panel_enable(panel);
		if (ret) {
			pr_err("%s: enable panel %d failed, %d\n", __func__, id,
									ret);
			goto panel_en_fail;
		}
	}

	return;

panel_en_fail:
	if (is_dual_dsi && msm_dsi1)
		msm_dsi_host_disable(msm_dsi1->host);
host1_en_fail:
	msm_dsi_host_disable(host);
host_en_fail:
	if (panel)
		drm_panel_unprepare(panel);
panel_prep_fail:
	if (is_dual_dsi && msm_dsi1)
		msm_dsi_host_power_off(msm_dsi1->host);
host1_on_fail:
	msm_dsi_host_power_off(host);
host_on_fail:
	dsi_mgr_phy_disable(id);
phy_en_fail:
	return;
}