/* * This function is a bit of a catch-all for panel preparation, hopefully * simplifying the logic of functions that need to prepare/unprepare the panel * below. * * If @prepare is true, this function will prepare the panel. Conversely, if it * is false, the panel will be unprepared. * * If @is_modeset_prepare is true, the function will disregard the current state * of the panel and either prepare/unprepare the panel based on @prepare. Once * it finishes, it will update dp->panel_is_modeset to reflect the current state * of the panel. */ static int analogix_dp_prepare_panel(struct analogix_dp_device *dp, bool prepare, bool is_modeset_prepare) { int ret = 0; if (!dp->plat_data->panel) return 0; mutex_lock(&dp->panel_lock); /* * Exit early if this is a temporary prepare/unprepare and we're already * modeset (since we neither want to prepare twice or unprepare early). */ if (dp->panel_is_modeset && !is_modeset_prepare) goto out; if (prepare) ret = drm_panel_prepare(dp->plat_data->panel); else ret = drm_panel_unprepare(dp->plat_data->panel); if (ret) goto out; if (is_modeset_prepare) dp->panel_is_modeset = prepare; out: mutex_unlock(&dp->panel_lock); return ret; }
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); }
static void exynos_dp_bridge_enable(struct drm_bridge *bridge) { struct exynos_dp_device *dp = bridge->driver_private; struct exynos_drm_crtc *crtc = dp_to_crtc(dp); if (dp->dpms_mode == DRM_MODE_DPMS_ON) return; pm_runtime_get_sync(dp->dev); if (dp->panel) { if (drm_panel_prepare(dp->panel)) { DRM_ERROR("failed to setup the panel\n"); return; } } if (crtc->ops->clock_enable) crtc->ops->clock_enable(dp_to_crtc(dp), true); phy_power_on(dp->phy); exynos_dp_init_dp(dp); enable_irq(dp->irq); exynos_dp_commit(&dp->encoder); dp->dpms_mode = DRM_MODE_DPMS_ON; }
static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder); int ret; dsi->mode = adjusted_mode; ret = dw_mipi_dsi_get_lane_bps(dsi); if (ret < 0) return; if (clk_prepare_enable(dsi->pclk)) { dev_err(dsi->dev, "%s: Failed to enable pclk\n", __func__); return; } dw_mipi_dsi_init(dsi); dw_mipi_dsi_dpi_config(dsi, mode); dw_mipi_dsi_packet_handler_config(dsi); dw_mipi_dsi_video_mode_config(dsi); dw_mipi_dsi_video_packet_config(dsi, mode); dw_mipi_dsi_command_mode_config(dsi); dw_mipi_dsi_line_timer_config(dsi); dw_mipi_dsi_vertical_timing_config(dsi); dw_mipi_dsi_dphy_timing_config(dsi); dw_mipi_dsi_dphy_interface_config(dsi); dw_mipi_dsi_clear_err(dsi); if (drm_panel_prepare(dsi->panel)) dev_err(dsi->dev, "failed to prepare panel\n"); clk_disable_unprepare(dsi->pclk); }
static void exynos_dpi_poweron(struct exynos_dpi *ctx) { if (ctx->panel) { drm_panel_prepare(ctx->panel); drm_panel_enable(ctx->panel); } }
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; }
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; }
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); } }
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); }
static void exynos_dp_poweron(struct exynos_drm_display *display) { struct exynos_dp_device *dp = display_to_dp(display); if (dp->dpms_mode == DRM_MODE_DPMS_ON) return; if (dp->panel) { if (drm_panel_prepare(dp->panel)) { DRM_ERROR("failed to setup the panel\n"); return; } } clk_prepare_enable(dp->clock); exynos_dp_phy_init(dp); exynos_dp_init_dp(dp); enable_irq(dp->irq); exynos_dp_commit(display); }
int analogix_dp_resume(struct device *dev) { struct analogix_dp_device *dp = dev_get_drvdata(dev); int ret; ret = clk_prepare_enable(dp->clock); if (ret < 0) { DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret); return ret; } if (dp->plat_data->panel) { if (drm_panel_prepare(dp->plat_data->panel)) { DRM_ERROR("failed to setup the panel\n"); return -EBUSY; } } return 0; }
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; }
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; }