diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 4f2e1b35eb38..4516800e5ab0 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1801,6 +1801,14 @@ config FB_WM8505 integrated LCD controller. This driver covers the WM8505, WM8650 and WM8850 SoCs. +config FB_WM8505_VGA + bool "Enable VGA output + Disable LCD output" + depends on FB_WM8505 + help + Select this option to enable the VGA output on the APC8750. + Do NOT select this option if you have a netbook or tablet, as it + will disable the LCD output. + config FB_WMT_GE_ROPS bool "VT8500/WM8xxx accelerated raster ops support" depends on (FB = y) && (FB_VT8500 || FB_WM8505) diff --git a/drivers/video/wm8505fb.c b/drivers/video/wm8505fb.c index 537d199612af..2b023ca56520 100644 --- a/drivers/video/wm8505fb.c +++ b/drivers/video/wm8505fb.c @@ -14,6 +14,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -45,6 +46,9 @@ struct wm8505fb_info { struct fb_info fb; void __iomem *regbase; unsigned int contrast; +#ifdef CONFIG_FB_WM8505_VGA + struct clk *clk_dvo; +#endif }; @@ -67,7 +71,12 @@ static int wm8505fb_init_hw(struct fb_info *info) * 0x31C sets the correct color mode (RGB565) for WM8650 * Bit 8+9 (0x300) are ignored on WM8505 as reserved */ +#ifdef CONFIG_FB_WM8505_VGA + writel(0x338, fbi->regbase + WMT_GOVR_COLORSPACE); +#else writel(0x31c, fbi->regbase + WMT_GOVR_COLORSPACE); +#endif + writel(1, fbi->regbase + WMT_GOVR_COLORSPACE1); /* Virtual buffer size */ @@ -76,7 +85,13 @@ static int wm8505fb_init_hw(struct fb_info *info) /* black magic ;) */ writel(0xf, fbi->regbase + WMT_GOVR_FHI); + +#ifdef CONFIG_FB_WM8505_VGA + writel(0xe, fbi->regbase + WMT_GOVR_DVO_SET); +#else writel(4, fbi->regbase + WMT_GOVR_DVO_SET); +#endif + writel(1, fbi->regbase + WMT_GOVR_MIF_ENABLE); writel(1, fbi->regbase + WMT_GOVR_REG_UPDATE); @@ -103,11 +118,17 @@ static int wm8505fb_set_timing(struct fb_info *info) writel(h_end, fbi->regbase + WMT_GOVR_TIMING_H_END); writel(h_all, fbi->regbase + WMT_GOVR_TIMING_H_ALL); writel(h_sync, fbi->regbase + WMT_GOVR_TIMING_H_SYNC); +#ifdef CONFIG_FB_WM8505_VGA + writel(h_sync, fbi->regbase + WMT_VGA_TIMING_H_SYNC); +#endif writel(v_start, fbi->regbase + WMT_GOVR_TIMING_V_START); writel(v_end, fbi->regbase + WMT_GOVR_TIMING_V_END); writel(v_all, fbi->regbase + WMT_GOVR_TIMING_V_ALL); writel(v_sync, fbi->regbase + WMT_GOVR_TIMING_V_SYNC); +#ifdef CONFIG_FB_WM8505_VGA + writel(0x1f80, fbi->regbase + WMT_VGA_TIMING_V_SYNC); +#endif writel(1, fbi->regbase + WMT_GOVR_TG); @@ -121,6 +142,9 @@ static int wm8505fb_set_par(struct fb_info *info) if (!fbi) return -EINVAL; +#ifdef CONFIG_FB_WM8505_VGA + clk_set_rate(fbi->clk_dvo, PICOS2KHZ(info->var.pixclock)*1000); +#endif if (info->var.bits_per_pixel == 32) { info->var.red.offset = 16; @@ -320,6 +344,16 @@ static int wm8505fb_probe(struct platform_device *pdev) if (ret) return ret; +#ifdef CONFIG_FB_WM8505_VGA + fbi->clk_dvo = of_clk_get(pdev->dev.of_node, 0); + if (IS_ERR(fbi->clk_dvo)) { + dev_err(&pdev->dev, "Error getting clock\n"); + return PTR_ERR(fbi->clk_dvo); + } + + clk_prepare_enable(fbi->clk_dvo); +#endif + fb_videomode_to_var(&fbi->fb.var, &mode); fbi->fb.var.nonstd = 0; diff --git a/drivers/video/wm8505fb_regs.h b/drivers/video/wm8505fb_regs.h index 4dd41668c6d1..7a6fe334b887 100644 --- a/drivers/video/wm8505fb_regs.h +++ b/drivers/video/wm8505fb_regs.h @@ -73,4 +73,7 @@ #define WMT_GOVR_TIMING_V_SYNC 0x128 #define WMT_GOVR_TIMING_H_SYNC 0x12c +#define WMT_VGA_TIMING_H_SYNC 0x190 +#define WMT_VGA_TIMING_V_SYNC 0x194 + #endif /* _WM8505FB_REGS_H */