From b51339fff240ff179730f8963a758147fd60f3ec Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Oct 2008 20:23:26 +0900 Subject: sh: sh_mobile lcdc clock framework support Add clock framework support to the lcdc driver and adjust the board specific code accordingly. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_lcdcfb.c | 46 ++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'drivers/video/sh_mobile_lcdcfb.c') diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index efff672fd7b..c81ee00c54d 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -35,6 +35,7 @@ struct sh_mobile_lcdc_chan { struct sh_mobile_lcdc_priv { void __iomem *base; #ifdef CONFIG_HAVE_CLK + struct clk *dot_clk; struct clk *clk; #endif unsigned long lddckr; @@ -207,6 +208,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) int k, m; int ret = 0; +#ifdef CONFIG_HAVE_CLK + clk_enable(priv->clk); + if (priv->dot_clk) + clk_enable(priv->dot_clk); +#endif /* reset */ lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET); lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0); @@ -371,6 +377,12 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) /* stop the lcdc */ sh_mobile_lcdc_start_stop(priv, 0); + +#ifdef CONFIG_HAVE_CLK + if (priv->dot_clk) + clk_disable(priv->dot_clk); + clk_disable(priv->clk); +#endif } static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) @@ -413,9 +425,13 @@ static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) return -EINVAL; } -static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, +static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev, + int clock_source, struct sh_mobile_lcdc_priv *priv) { +#ifdef CONFIG_HAVE_CLK + char clk_name[8]; +#endif char *str; int icksel; @@ -430,14 +446,20 @@ static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, priv->lddckr = icksel << 16; #ifdef CONFIG_HAVE_CLK + snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id); + priv->clk = clk_get(&pdev->dev, clk_name); + if (IS_ERR(priv->clk)) { + dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); + return PTR_ERR(priv->clk); + } + if (str) { - priv->clk = clk_get(dev, str); - if (IS_ERR(priv->clk)) { - dev_err(dev, "cannot get clock %s\n", str); - return PTR_ERR(priv->clk); + priv->dot_clk = clk_get(&pdev->dev, str); + if (IS_ERR(priv->dot_clk)) { + dev_err(&pdev->dev, "cannot get dot clock %s\n", str); + clk_put(priv->clk); + return PTR_ERR(priv->dot_clk); } - - clk_enable(priv->clk); } #endif @@ -587,8 +609,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) goto err1; } - error = sh_mobile_lcdc_setup_clocks(&pdev->dev, - pdata->clock_source, priv); + error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv); if (error) { dev_err(&pdev->dev, "unable to setup clocks\n"); goto err1; @@ -697,10 +718,9 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) } #ifdef CONFIG_HAVE_CLK - if (priv->clk) { - clk_disable(priv->clk); - clk_put(priv->clk); - } + if (priv->dot_clk) + clk_put(priv->dot_clk); + clk_put(priv->clk); #endif if (priv->base) -- cgit v1.2.3 From 2540c111ead82cad605ec2b14a1905ad914cc124 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 17 Dec 2008 17:29:49 +0900 Subject: sh_mobile_lcdc: use FB_SYS helpers instead of FB_CFB Since the sh_mobile_lcdc hardware has the framebuffer(s) in system RAM, use FB_SYS instead of FB_CFB. Also hook in read and write helpers. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_lcdcfb.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/video/sh_mobile_lcdcfb.c') diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index c81ee00c54d..e339d829183 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -499,9 +499,11 @@ static struct fb_fix_screeninfo sh_mobile_lcdc_fix = { static struct fb_ops sh_mobile_lcdc_ops = { .fb_setcolreg = sh_mobile_lcdc_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_read = fb_sys_read, + .fb_write = fb_sys_write, + .fb_fillrect = sys_fillrect, + .fb_copyarea = sys_copyarea, + .fb_imageblit = sys_imageblit, }; static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) -- cgit v1.2.3 From 8564557a03c12adb9c4b76ae1e86db4113a04d13 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Dec 2008 15:34:41 +0900 Subject: video: sh_mobile_lcdcfb deferred io support This patch adds sh_mobile_lcdcfb deferred io support for SYS panels. The LCDC hardware block managed by the sh_mobile_lcdcfb driver supports RGB or SYS panel configurations. SYS panels come with an external display controller that is resposible for refreshing the actual LCD panel. RGB panels are controlled directly by the LCDC and they need to be refreshed by the LCDC hardware. In the case of SYS panels we can save some power by configuring the LCDC hardware block in one-shot mode. In this one-shot mode panel refresh is managed by software. This works well together with deferred io since it allows us to stop clocks for most of the time and only enable clocks when we actually want to trigger an update. When there is no fbdev activity the clocks are kept stopped which allows us to deep sleep. The refresh rate in deferred io mode is set using platform data. The same platform data can also be used to disable deferred io mode. As with other deferred io frame buffers user space code should use fsync() on the frame buffer device to trigger an update. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_lcdcfb.c | 170 ++++++++++++++++++++++++++++++++++----- 1 file changed, 148 insertions(+), 22 deletions(-) (limited to 'drivers/video/sh_mobile_lcdcfb.c') diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index e339d829183..0e2b8fd24df 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -16,7 +16,9 @@ #include #include #include +#include #include