mirror of
https://github.com/torvalds/linux.git
synced 2024-12-21 02:21:36 +00:00
imx-drm fixes for mode fixup, dw_hdmi/imx, and parallel-display
- A clock fix for too large pixel clocks depending on the DI clock flag simplification patch - Pruning of unsupported modes and a missing end of array element for dw_hdmi-imx - LVDS modeset fix for mode fixup - Fix parallel-display deferred probing if drm_panel is used -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJU68LkAAoJEFDCiBxwnmDrU88P/093tyHInYjgzDS9UIyNHKfK TbGzpOP/WiaDcN5MxY2aBCUwzXxRZacQBSxTZLPwT5Zm0vuLbYDlqII5ttH6xI1A eSFhH89zntcWHHtbu5iQ0BE6doKpyzDX8RD/0uS/DANdKfdyyl51mv+FSYKuoOQR OW3SGrFY6YrWW2Fmi7IstJ4vfdM3f0HO/kaMAMnADCdPMquObrL0LMLI+r8JVqEQ FpaNwzD/KuyBoaYuNm+l/LsMkfsZZdTVuwnRLqNx+avB/a318GdN6Argzh23kEDb cxyzMv9/eP/hMzMAMaoCdlhcgWnBWQ9rPP9CVVHjT7juv4Bj4/IIfWimXNUOdfE1 ld1jKxsx07xKQHq+Vmh/648N+0utUABZzq9I/toyKDa37zC3pDMeG1ZgELnEXbN8 8mf69SLE62hZEuempM54h2enMPH4nbvOVKcRMZXIpGNiPyNK890B9aijbZUVQ9Wm K5td2bKbaqSiq17PRyFddFPy9CkDASMFwiLZ9cfeCoVYb1tiFAV6maBEsTJPi18H OVhy5CC5PeR8VlqaKcR3Nt/+pTtl1vkou2yAvYFMeO3iX1U3VQ1J5o0MuAA2E1sC /mRJ4jCbMzlCFsqo/2CSu/DG2gF9UfhU/CQ4vLTNU09lBWTRwkeC7JHnJUawVSJL LTcGvb1Fb2R0NkE7nqET =CrJz -----END PGP SIGNATURE----- Merge tag 'imx-drm-fixes-2015-02-24' of git://git.pengutronix.de/git/pza/linux into drm-fixes imx-drm fixes for mode fixup, dw_hdmi/imx, and parallel-display - A clock fix for too large pixel clocks depending on the DI clock flag simplification patch - Pruning of unsupported modes and a missing end of array element for dw_hdmi-imx - LVDS modeset fix for mode fixup - Fix parallel-display deferred probing if drm_panel is used * tag 'imx-drm-fixes-2015-02-24' of git://git.pengutronix.de/git/pza/linux: DRM: i.MX: parallel display: Support probe deferral for finding DRM panel drm/imx: imx-ldb: enable DI clock in encoder_mode_set drm/imx: dw_hdmi-imx: add end of array element to current control array drm/imx: dw_hdmi-imx: add mode_valid callback prune unsupported modes gpu: ipu-v3: do not divide by zero if the pixel clock is too large
This commit is contained in:
commit
9d0685ae04
@ -70,7 +70,9 @@ static const struct dw_hdmi_curr_ctrl imx_cur_ctr[] = {
|
||||
118800000, { 0x091c, 0x091c, 0x06dc },
|
||||
}, {
|
||||
216000000, { 0x06dc, 0x0b5c, 0x091c },
|
||||
}
|
||||
}, {
|
||||
~0UL, { 0x0000, 0x0000, 0x0000 },
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dw_hdmi_sym_term imx_sym_term[] = {
|
||||
@ -136,11 +138,34 @@ static struct drm_encoder_funcs dw_hdmi_imx_encoder_funcs = {
|
||||
.destroy = drm_encoder_cleanup,
|
||||
};
|
||||
|
||||
static enum drm_mode_status imx6q_hdmi_mode_valid(struct drm_connector *con,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
if (mode->clock < 13500)
|
||||
return MODE_CLOCK_LOW;
|
||||
if (mode->clock > 266000)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
static enum drm_mode_status imx6dl_hdmi_mode_valid(struct drm_connector *con,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
if (mode->clock < 13500)
|
||||
return MODE_CLOCK_LOW;
|
||||
if (mode->clock > 270000)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
static struct dw_hdmi_plat_data imx6q_hdmi_drv_data = {
|
||||
.mpll_cfg = imx_mpll_cfg,
|
||||
.cur_ctr = imx_cur_ctr,
|
||||
.sym_term = imx_sym_term,
|
||||
.dev_type = IMX6Q_HDMI,
|
||||
.mpll_cfg = imx_mpll_cfg,
|
||||
.cur_ctr = imx_cur_ctr,
|
||||
.sym_term = imx_sym_term,
|
||||
.dev_type = IMX6Q_HDMI,
|
||||
.mode_valid = imx6q_hdmi_mode_valid,
|
||||
};
|
||||
|
||||
static struct dw_hdmi_plat_data imx6dl_hdmi_drv_data = {
|
||||
@ -148,6 +173,7 @@ static struct dw_hdmi_plat_data imx6dl_hdmi_drv_data = {
|
||||
.cur_ctr = imx_cur_ctr,
|
||||
.sym_term = imx_sym_term,
|
||||
.dev_type = IMX6DL_HDMI,
|
||||
.mode_valid = imx6dl_hdmi_mode_valid,
|
||||
};
|
||||
|
||||
static const struct of_device_id dw_hdmi_imx_dt_ids[] = {
|
||||
|
@ -163,22 +163,7 @@ 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->hwmode;
|
||||
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:
|
||||
@ -247,6 +232,9 @@ static void imx_ldb_encoder_mode_set(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;
|
||||
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,
|
||||
@ -257,6 +245,16 @@ static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder,
|
||||
"%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)
|
||||
|
@ -236,8 +236,11 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
|
||||
}
|
||||
|
||||
panel_node = of_parse_phandle(np, "fsl,panel", 0);
|
||||
if (panel_node)
|
||||
if (panel_node) {
|
||||
imxpd->panel = of_drm_find_panel(panel_node);
|
||||
if (!imxpd->panel)
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
imxpd->dev = dev;
|
||||
|
||||
|
@ -459,6 +459,8 @@ static void ipu_di_config_clock(struct ipu_di *di,
|
||||
|
||||
clkrate = clk_get_rate(di->clk_ipu);
|
||||
div = DIV_ROUND_CLOSEST(clkrate, sig->mode.pixelclock);
|
||||
if (div == 0)
|
||||
div = 1;
|
||||
rate = clkrate / div;
|
||||
|
||||
error = rate / (sig->mode.pixelclock / 1000);
|
||||
|
Loading…
Reference in New Issue
Block a user