diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2014-09-30 17:33:11 +0200 |
---|---|---|
committer | Stefan Agner <stefan.agner@toradex.com> | 2015-07-01 13:35:22 +0200 |
commit | 28767ec7d0ddfa9caa589d53ab4039940dfe1075 (patch) | |
tree | 1499e7b2bd6acebc6d932403962658660218ded2 /drivers/video | |
parent | 19f79db755a2e0e7ffbc9a6d7e85672dd155210d (diff) |
video: fsl-dcu-fb: support signal polarity configuration
Use the display timing configurations hsync-/vsync- and pixelclk-
active properties. The hsync- and vsync-active configuration is
available through the fb_videomode sync field. But pixelclk-active
need to be stored seperately because when converting the struct
display_timing to struct fb_videomode, this information gets lost.
Hence we cannot pick a mode from the modelist and expect that
pixelclk-active is set correctly. But currently modelist is not
used by anything, hence this is no issue.
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/fbdev/fsl-dcu-fb.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/drivers/video/fbdev/fsl-dcu-fb.c b/drivers/video/fbdev/fsl-dcu-fb.c index c0a09fa361a0..2ceb44c4a5c7 100644 --- a/drivers/video/fbdev/fsl-dcu-fb.c +++ b/drivers/video/fbdev/fsl-dcu-fb.c @@ -143,6 +143,7 @@ struct dcu_fb_data { struct list_head modelist; struct fb_videomode native_mode; u32 bits_per_pixel; + bool clk_pol_negedge; }; struct layer_display_offset { @@ -439,7 +440,7 @@ static void update_controller(struct fb_info *info) struct fb_var_screeninfo *var = &info->var; struct mfb_info *mfbi = info->par; struct dcu_fb_data *dcufb = mfbi->parent; - unsigned int div; + unsigned int div, pol = 0; div = fsl_dcu_calc_div(info); writel((div - 1), dcufb->reg_base + DCU_DIV_RATIO); @@ -459,9 +460,17 @@ static void update_controller(struct fb_info *info) DCU_VSYN_PARA_FP(var->lower_margin), dcufb->reg_base + DCU_VSYN_PARA); - writel(DCU_SYN_POL_INV_PXCK_FALL | DCU_SYN_POL_NEG_REMAIN | - DCU_SYN_POL_INV_VS_LOW | DCU_SYN_POL_INV_HS_LOW, - dcufb->reg_base + DCU_SYN_POL); + /* Reference Manual is wrong, INV_PXCK => 1 means falling edge! */ + if (dcufb->clk_pol_negedge) + pol |= DCU_SYN_POL_INV_PXCK_FALL; + + if (!(var->sync & FB_SYNC_HOR_HIGH_ACT)) + pol |= DCU_SYN_POL_INV_HS_LOW; + + if (!(var->sync & FB_SYNC_VERT_HIGH_ACT)) + pol |= DCU_SYN_POL_INV_VS_LOW; + + writel(pol, dcufb->reg_base + DCU_SYN_POL); writel(DCU_BGND_R(0) | DCU_BGND_G(0) | DCU_BGND_B(0), dcufb->reg_base + DCU_BGND); @@ -804,8 +813,11 @@ static int fsl_dcu_init_modelist(struct dcu_fb_data *dcufb) if (ret < 0) goto put_display_node; - if (i == timings->native_mode) + if (i == timings->native_mode) { fb_videomode_from_videomode(&vm, &dcufb->native_mode); + dcufb->clk_pol_negedge = timings->timings[i]->flags & + DISPLAY_FLAGS_PIXDATA_NEGEDGE; + } fb_add_videomode(&fb_vm, &dcufb->modelist); } |