summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2014-09-30 17:33:11 +0200
committerStefan Agner <stefan.agner@toradex.com>2015-07-01 13:35:22 +0200
commit28767ec7d0ddfa9caa589d53ab4039940dfe1075 (patch)
tree1499e7b2bd6acebc6d932403962658660218ded2 /drivers/video
parent19f79db755a2e0e7ffbc9a6d7e85672dd155210d (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.c22
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);
}