diff options
author | Bhuvanchandra DV <bhuvanchandra.dv@toradex.com> | 2016-06-15 14:51:00 +0200 |
---|---|---|
committer | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2017-12-21 14:27:34 +0100 |
commit | b3b18d7be775138b5d57d6610d3e8dd7535f099c (patch) | |
tree | 16d33ef9605c2b00217d850ac421e04e34e117e2 /drivers | |
parent | 72c709d9839d23bafb4fa12e28ca572ba18fa73e (diff) |
video: mxc: ldb: Add support for LVDS configuration via kernel boot arguments
Add support for LVDS frame buffer configuration via kernel boot arguments.
Fix use of the device tree native-mode property.
Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Acked-by: Max Krummenacher <max.krummenacher@toradex.com>
(cherry picked from commit 122acb64708ac40faa8c5755624a0bcfbebcb9e8)
(cherry picked from commit 735d4f8addae71ef4a70eb16a9639bd6204fd2b9)
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/fbdev/mxc/ldb.c | 59 |
1 files changed, 46 insertions, 13 deletions
diff --git a/drivers/video/fbdev/mxc/ldb.c b/drivers/video/fbdev/mxc/ldb.c index 1d6c9e08590c..66a8fe51a84d 100644 --- a/drivers/video/fbdev/mxc/ldb.c +++ b/drivers/video/fbdev/mxc/ldb.c @@ -22,6 +22,7 @@ #include <linux/regmap.h> #include <linux/types.h> #include <video/of_videomode.h> +#include <video/of_display_timing.h> #include <video/videomode.h> #include "mxc_dispdrv.h" @@ -77,7 +78,8 @@ struct ldb_data; struct ldb_chan { struct ldb_data *ldb; struct fb_info *fbi; - struct videomode vm; + unsigned long serial_clk; + struct display_timings *timings; enum crtc crtc; int chno; bool is_used; @@ -301,8 +303,10 @@ static int ldb_init(struct mxc_dispdrv_handle *mddh, struct device *dev = ldb->dev; struct fb_info *fbi = setting->fbi; struct ldb_chan *chan; - struct fb_videomode fb_vm; - int chno; + struct fb_videomode fb_vm, native_mode; + int chno, i, ret; + struct videomode vm; + unsigned long pixelclock; chno = ldb->chan[ldb->primary_chno].is_used ? !ldb->primary_chno : ldb->primary_chno; @@ -322,10 +326,40 @@ static int ldb_init(struct mxc_dispdrv_handle *mddh, chan->fbi = fbi; - fb_videomode_from_videomode(&chan->vm, &fb_vm); - fb_videomode_to_var(&fbi->var, &fb_vm); - setting->crtc = chan->crtc; + + INIT_LIST_HEAD(&fbi->modelist); + for (i = 0; i < chan->timings->num_timings; i++) { + ret = videomode_from_timings(chan->timings, &vm, i); + if (ret < 0) { + dev_err(ldb->dev, + "failed to get video mode from timings\n"); + return ret; + } + + ret = fb_videomode_from_videomode(&vm, &fb_vm); + if (ret < 0) { + dev_err(ldb->dev, + "failed to get fb video mode from video mode\n"); + return ret; + } + + if (i == chan->timings->native_mode) + fb_videomode_from_videomode(&vm, &native_mode); + + fb_add_videomode(&fb_vm, &fbi->modelist); + fb_videomode_to_var(&fbi->var, &fb_vm); + } + + fb_find_mode(&fbi->var, fbi, setting->dft_mode_str, &fb_vm, + chan->timings->num_timings, &native_mode, + setting->default_bpp); + + /* Calculate the LVDS clock */ + fb_var_to_videomode(&fb_vm, &fbi->var); + + pixelclock = fb_vm.pixclock ? (1000000000UL/(fb_vm.pixclock)) * 1000: 0; + chan->serial_clk = ldb->spl_mode ? pixelclock * 7 / 2 : pixelclock * 7; return 0; } @@ -399,7 +433,6 @@ static int ldb_setup(struct mxc_dispdrv_handle *mddh, struct clk *other_ldb_di_sel = NULL; struct bus_mux bus_mux; int ret = 0, id = 0, chno, other_chno; - unsigned long serial_clk; u32 mux_val; ret = find_ldb_chno(ldb, fbi, &chno); @@ -453,9 +486,7 @@ static int ldb_setup(struct mxc_dispdrv_handle *mddh, clk_set_parent(ldb->div_sel_clk[chno], ldb_di_parent); ldb_di_sel = clk_get_parent(ldb_di_parent); ldb_di_sel_parent = clk_get_parent(ldb_di_sel); - serial_clk = ldb->spl_mode ? chan.vm.pixelclock * 7 / 2 : - chan.vm.pixelclock * 7; - clk_set_rate(ldb_di_sel_parent, serial_clk); + clk_set_rate(ldb_di_sel_parent, chan.serial_clk); /* * split mode or dual mode: @@ -834,9 +865,11 @@ static int ldb_probe(struct platform_device *pdev) return -EINVAL; } - ret = of_get_videomode(child, &chan->vm, 0); - if (ret) - return -EINVAL; + chan->timings = of_get_display_timings(child); + if (!chan->timings) { + dev_err(ldb->dev, "failed to get display timings\n"); + ret = -ENOENT; + } sprintf(clkname, "ldb_di%d", i); ldb->ldb_di_clk[i] = devm_clk_get(dev, clkname); |