static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder) { struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder); regmap_update_bits(hdmi->regmap, IOMUXC_GPR3, IMX6Q_GPR3_HDMI_MUX_CTL_MASK, mux << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT); }
static void imx_hdmi_encoder_commit(struct drm_encoder *encoder) { struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder); imx_hdmi_set_ipu_di_mux(hdmi, mux); imx_hdmi_poweron(hdmi); }
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 imx_ldb_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *orig_mode, struct drm_display_mode *mode) { 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; unsigned long serial_clk; unsigned long di_clk = mode->clock * 1000; int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder); if (mode->clock > 170000) { dev_warn(ldb->dev, "%s: mode exceeds 170 MHz pixel clock\n", __func__); } if (mode->clock > 85000 && !dual) { dev_warn(ldb->dev, "%s: mode exceeds 85 MHz pixel clock\n", __func__); } if (dual) { serial_clk = 3500UL * mode->clock; imx_ldb_set_clock(ldb, mux, 0, serial_clk, di_clk); imx_ldb_set_clock(ldb, mux, 1, serial_clk, di_clk); } else { serial_clk = 7000UL * mode->clock; imx_ldb_set_clock(ldb, mux, imx_ldb_ch->chno, serial_clk, di_clk); } /* FIXME - assumes straight connections DI0 --> CH0, DI1 --> CH1 */ if (imx_ldb_ch == &ldb->channel[0]) { if (mode->flags & DRM_MODE_FLAG_NVSYNC) ldb->ldb_ctrl |= LDB_DI0_VS_POL_ACT_LOW; else if (mode->flags & DRM_MODE_FLAG_PVSYNC) ldb->ldb_ctrl &= ~LDB_DI0_VS_POL_ACT_LOW; } if (imx_ldb_ch == &ldb->channel[1]) { if (mode->flags & DRM_MODE_FLAG_NVSYNC) ldb->ldb_ctrl |= LDB_DI1_VS_POL_ACT_LOW; else if (mode->flags & DRM_MODE_FLAG_PVSYNC) ldb->ldb_ctrl &= ~LDB_DI1_VS_POL_ACT_LOW; } }
static void imx_ldb_encoder_prepare(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; struct drm_display_mode *mode = &encoder->crtc->mode; u32 pixel_fmt; unsigned long serial_clk; unsigned long di_clk = mode->clock * 1000; int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder); if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) { /* dual channel LVDS mode */ serial_clk = 3500UL * mode->clock; imx_ldb_set_clock(ldb, mux, 0, serial_clk, di_clk); imx_ldb_set_clock(ldb, mux, 1, serial_clk, di_clk); } else { serial_clk = 7000UL * mode->clock; imx_ldb_set_clock(ldb, mux, imx_ldb_ch->chno, serial_clk, di_clk); } switch (imx_ldb_ch->chno) { case 0: pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH0_24) ? V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666; break; case 1: pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH1_24) ? V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666; break; default: dev_err(ldb->dev, "unable to config di%d panel format\n", imx_ldb_ch->chno); pixel_fmt = V4L2_PIX_FMT_RGB24; } imx_drm_panel_format(encoder, pixel_fmt); }