summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev/fsl-dcu-fb.c
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2014-09-30 17:33:11 +0200
committerStefan Agner <stefan.agner@toradex.com>2014-11-19 11:29:46 +0100
commitbd4dbda18234af959568a24c0e09a9ee62a5834e (patch)
tree42f8184171adcdb196692d91042e8486026e981b /drivers/video/fbdev/fsl-dcu-fb.c
parent5fccb8702a099b03b7d25cd648f14435dbe92a06 (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/fbdev/fsl-dcu-fb.c')
-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);
}