Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* Re: [PATCH] omapdss: use devm_clk_get()
From: Archit Taneja @ 2013-04-10  8:49 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev
In-Reply-To: <51651F25.3020302@ti.com>

On Wednesday 10 April 2013 01:43 PM, Tomi Valkeinen wrote:
> On 2013-04-08 11:55, Archit Taneja wrote:
>> Use devm_clk_get() instead of clk_get() for dss, and for outputs hdmi and venc.
>> This reduces reduces code and simplifies error handling.
>>
>> Signed-off-by: Archit Taneja <archit@ti.com>
>> ---
>>   drivers/video/omap2/dss/dss.c  |   18 +++---------------
>>   drivers/video/omap2/dss/hdmi.c |   16 ++--------------
>>   drivers/video/omap2/dss/venc.c |   10 +---------
>>   3 files changed, 6 insertions(+), 38 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
>> index 054c2a2..645b3bc 100644
>> --- a/drivers/video/omap2/dss/dss.c
>> +++ b/drivers/video/omap2/dss/dss.c
>> @@ -767,13 +767,11 @@ int dss_dpi_select_source(enum omap_channel channel)
>>   static int dss_get_clocks(void)
>>   {
>>   	struct clk *clk;
>> -	int r;
>>
>> -	clk = clk_get(&dss.pdev->dev, "fck");
>> +	clk = devm_clk_get(&dss.pdev->dev, "fck");
>>   	if (IS_ERR(clk)) {
>>   		DSSERR("can't get clock fck\n");
>> -		r = PTR_ERR(clk);
>> -		goto err;
>> +		return PTR_ERR(clk);
>>   	}
>>
>>   	dss.dss_clk = clk;
>> @@ -782,8 +780,7 @@ static int dss_get_clocks(void)
>>   		clk = clk_get(NULL, dss.feat->clk_name);
>>   		if (IS_ERR(clk)) {
>>   			DSSERR("Failed to get %s\n", dss.feat->clk_name);
>> -			r = PTR_ERR(clk);
>> -			goto err;
>> +			return PTR_ERR(clk);
>>   		}
>>   	} else {
>>   		clk = NULL;
>> @@ -792,21 +789,12 @@ static int dss_get_clocks(void)
>>   	dss.dpll4_m4_ck = clk;
>>
>>   	return 0;
>> -
>> -err:
>> -	if (dss.dss_clk)
>> -		clk_put(dss.dss_clk);
>> -	if (dss.dpll4_m4_ck)
>> -		clk_put(dss.dpll4_m4_ck);
>> -
>> -	return r;
>>   }
>
> Why didn't you use devm_clk_get for the dpll4_m4_ck clock also?

clk_get of dpll4_m4_ck isn't tied to a device:

	clk = clk_get(NULL, dss.feat->clk_name);

We can't use devm_clk_get() if we don't tie it to a device, right?

I think the dss.dss_clk clock above is same as the dpll4_m4_ck for all 
OMAPs. We could probably remove the dpll4_m4_clk all together, and use 
dss_clk to get the rate of DSS_FCK coming from PRCM.

Archit


^ permalink raw reply

* Re: [PATCH 1/1] video: wm8505fb: Convert to devm_ioremap_resource()
From: Tomi Valkeinen @ 2013-04-10  8:23 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1365415496-6825-1-git-send-email-sachin.kamat@linaro.org>

[-- Attachment #1: Type: text/plain, Size: 1339 bytes --]

On 2013-04-08 13:04, Sachin Kamat wrote:
> Use the newly introduced devm_ioremap_resource() instead of
> devm_request_and_ioremap() which provides more consistent error handling.
> 
> Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
> ---
>  drivers/video/wm8505fb.c |    7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/video/wm8505fb.c b/drivers/video/wm8505fb.c
> index 19e2e7f..01f9ace 100644
> --- a/drivers/video/wm8505fb.c
> +++ b/drivers/video/wm8505fb.c
> @@ -18,6 +18,7 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/fb.h>
>  #include <linux/errno.h>
> +#include <linux/err.h>
>  #include <linux/init.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
> @@ -303,9 +304,9 @@ static int wm8505fb_probe(struct platform_device *pdev)
>  	fbi->fb.pseudo_palette	= addr;
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	fbi->regbase = devm_request_and_ioremap(&pdev->dev, res);
> -	if (fbi->regbase == NULL)
> -		return -EBUSY;
> +	fbi->regbase = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(fbi->regbase))
> +		return PTR_ERR(fbi->regbase);
>  
>  	disp_timing = of_get_display_timings(pdev->dev.of_node);
>  	if (!disp_timing)
> 

Thanks, applying on top of the previous series from Tony Prisk.

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 899 bytes --]

^ permalink raw reply

* Re: [PATCH] omapdss: use devm_clk_get()
From: Tomi Valkeinen @ 2013-04-10  8:13 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-omap, linux-fbdev
In-Reply-To: <1365411346-30611-1-git-send-email-archit@ti.com>

[-- Attachment #1: Type: text/plain, Size: 1708 bytes --]

On 2013-04-08 11:55, Archit Taneja wrote:
> Use devm_clk_get() instead of clk_get() for dss, and for outputs hdmi and venc.
> This reduces reduces code and simplifies error handling.
> 
> Signed-off-by: Archit Taneja <archit@ti.com>
> ---
>  drivers/video/omap2/dss/dss.c  |   18 +++---------------
>  drivers/video/omap2/dss/hdmi.c |   16 ++--------------
>  drivers/video/omap2/dss/venc.c |   10 +---------
>  3 files changed, 6 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> index 054c2a2..645b3bc 100644
> --- a/drivers/video/omap2/dss/dss.c
> +++ b/drivers/video/omap2/dss/dss.c
> @@ -767,13 +767,11 @@ int dss_dpi_select_source(enum omap_channel channel)
>  static int dss_get_clocks(void)
>  {
>  	struct clk *clk;
> -	int r;
>  
> -	clk = clk_get(&dss.pdev->dev, "fck");
> +	clk = devm_clk_get(&dss.pdev->dev, "fck");
>  	if (IS_ERR(clk)) {
>  		DSSERR("can't get clock fck\n");
> -		r = PTR_ERR(clk);
> -		goto err;
> +		return PTR_ERR(clk);
>  	}
>  
>  	dss.dss_clk = clk;
> @@ -782,8 +780,7 @@ static int dss_get_clocks(void)
>  		clk = clk_get(NULL, dss.feat->clk_name);
>  		if (IS_ERR(clk)) {
>  			DSSERR("Failed to get %s\n", dss.feat->clk_name);
> -			r = PTR_ERR(clk);
> -			goto err;
> +			return PTR_ERR(clk);
>  		}
>  	} else {
>  		clk = NULL;
> @@ -792,21 +789,12 @@ static int dss_get_clocks(void)
>  	dss.dpll4_m4_ck = clk;
>  
>  	return 0;
> -
> -err:
> -	if (dss.dss_clk)
> -		clk_put(dss.dss_clk);
> -	if (dss.dpll4_m4_ck)
> -		clk_put(dss.dpll4_m4_ck);
> -
> -	return r;
>  }

Why didn't you use devm_clk_get for the dpll4_m4_ck clock also?

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 899 bytes --]

^ permalink raw reply

* Re: [PATCH] OMAPDSS: nec-nl8048 panel: Use dev_pm_ops
From: Tomi Valkeinen @ 2013-04-10  8:07 UTC (permalink / raw)
  To: Lars-Peter Clausen
  Cc: Florian Tobias Schandinat, Archit Taneja, linux-omap, linux-fbdev,
	linux-kernel
In-Reply-To: <1365326053-16248-1-git-send-email-lars@metafoo.de>

[-- Attachment #1: Type: text/plain, Size: 401 bytes --]

On 2013-04-07 12:14, Lars-Peter Clausen wrote:
> Use dev_pm_ops instead of the deprecated legacy suspend/resume callbacks.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> ---
>  .../video/omap2/displays/panel-nec-nl8048hl11-01b.c  | 20 ++++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)

Thanks, looks good to me. I'll add to fbdev misc patches.

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 899 bytes --]

^ permalink raw reply

* Re: Status of exporting an fbdev framebuffer with dma_buf?
From: Laurent Pinchart @ 2013-04-09 17:12 UTC (permalink / raw)
  To: Tom Cooksey; +Cc: linaro-mm-sig, dri-devel, linux-media, linux-fbdev

Hi Tom,

On Tuesday 09 April 2013 12:21:08 Tom Cooksey wrote:
> Hi All,
> 
> Last year Laurent posted an RFC patch[i] to add support for exporting an
> fbdev framebuffer through dma_buf. Looking through the mailing list
> archives, it doesn't appear to have progressed beyond an RFC? What would be
> needed to get this merged? It would be useful for our Mali T6xx driver
> (which supports importing dma_buf buffers) to allow the GPU to draw
> directly into the framebuffer on platforms which lack a DRM/KMS driver.

The patch was pretty simple, I don't think it would take lots of efforts to 
get it to mainline. On the other hand, fbdev is a dying API, so I'm not sure 
how much energy we want to spend on upgrading it. I suppose all that would be 
needed is a developer with enough interest in the topic to fix the patch 
according to the comments.

> [i] Subject: "[RFC/PATCH] fb: Add dma-buf support", sent 20/06/2012.

-- 
Regards,

Laurent Pinchart


^ permalink raw reply

* Re: [PATCH 08/10] drivers: mfd: use module_platform_driver_probe()
From: Fabio Porcedda @ 2013-04-09  9:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130409080653.GG24058@zurbaran>

On Tue, Apr 9, 2013 at 10:06 AM, Samuel Ortiz <sameo@linux.intel.com> wrote:
> Hi Fabio,
>
> On Thu, Mar 14, 2013 at 02:11:29PM +0100, Fabio Porcedda wrote:
>> This patch converts the drivers to use the
>> module_platform_driver_probe() macro which makes the code smaller and
>> a bit simpler.
>>
>> Signed-off-by: Fabio Porcedda <fabio.porcedda@gmail.com>
>> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>> Cc: Linus Walleij <linus.walleij@linaro.org>
>> Cc: Samuel Ortiz <sameo@linux.intel.com>
>> Cc: linux-arm-kernel@lists.infradead.org
>> ---
>>  drivers/mfd/davinci_voicecodec.c | 12 +-----------
>>  drivers/mfd/htc-pasic3.c         | 13 +------------
>>  2 files changed, 2 insertions(+), 23 deletions(-)
> Jingoo Han sent a larger patchset to convert many MFD drivers to
> module_platform_driver_probe(), including htc-pasic3 and davinci_voicecodec.
>
> See my mfd-next tree for more details.

I understand, thanks for letting me know.

It's my fault for having waited too long to send this patch set.

Best regards
--
Fabio Porcedda

> Cheers,
> Samuel.
>
> --
> Intel Open Source Technology Centre
> http://oss.intel.com/

^ permalink raw reply

* Re: [PATCH V2] video: implement a simple framebuffer driver
From: Geert Uytterhoeven @ 2013-04-09  8:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130408171637.98b5ad1f867bcbda883af68b@linux-foundation.org>

On Tue, Apr 9, 2013 at 2:16 AM, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Wed,  3 Apr 2013 20:39:43 -0600 Stephen Warren <swarren@wwwdotorg.org> wrote:
>> A simple frame-buffer describes a raw memory region that may be rendered
>> to, with the assumption that the display hardware has already been set
>> up to scan out from that buffer.
>>
>> This is useful in cases where a bootloader exists and has set up the
>> display hardware, but a Linux driver doesn't yet exist for the display
>> hardware.
>>
>> ...
>>
>> +config FB_SIMPLE
>> +     bool "Simple framebuffer support"
>> +     depends on (FB = y) && OF
>
> It's sad that this simple little thing requires Open Firmware.  Could
> it be generalised in some way so that the small amount of setup info
> could be provided by other means (eg, module_param) or does the
> dependency go deeper than that?

Indeed. Instead of consolidating, we seem to get more of them: offb, vesafb,
efifb, ...

cfr. near the tail of drivers/video/Makefile (don't know about all of them):
 # Platform or fallback drivers go here
obj-$(CONFIG_FB_UVESA)            += uvesafb.o
obj-$(CONFIG_FB_VESA)             += vesafb.o
obj-$(CONFIG_FB_EFI)              += efifb.o
obj-$(CONFIG_FB_VGA16)            += vga16fb.o
obj-$(CONFIG_FB_OF)               += offb.o
obj-$(CONFIG_FB_BF537_LQ035)      += bf537-lq035.o
obj-$(CONFIG_FB_BF54X_LQ043)      += bf54x-lq043fb.o
obj-$(CONFIG_FB_BFIN_LQ035Q1)     += bfin-lq035q1-fb.o
obj-$(CONFIG_FB_BFIN_T350MCQB)    += bfin-t350mcqb-fb.o
obj-$(CONFIG_FB_BFIN_7393)        += bfin_adv7393fb.o
obj-$(CONFIG_FB_MX3)              += mx3fb.o
obj-$(CONFIG_FB_DA8XX)            += da8xx-fb.o
obj-$(CONFIG_FB_MXS)              += mxsfb.o
obj-$(CONFIG_FB_SSD1307)          += ssd1307fb.o

# the test framebuffer is last
obj-$(CONFIG_FB_VIRTUAL)          += vfb.o

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH 08/10] drivers: mfd: use module_platform_driver_probe()
From: Samuel Ortiz @ 2013-04-09  8:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1363266691-15757-10-git-send-email-fabio.porcedda@gmail.com>

Hi Fabio,

On Thu, Mar 14, 2013 at 02:11:29PM +0100, Fabio Porcedda wrote:
> This patch converts the drivers to use the
> module_platform_driver_probe() macro which makes the code smaller and
> a bit simpler.
> 
> Signed-off-by: Fabio Porcedda <fabio.porcedda@gmail.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> Cc: linux-arm-kernel@lists.infradead.org
> ---
>  drivers/mfd/davinci_voicecodec.c | 12 +-----------
>  drivers/mfd/htc-pasic3.c         | 13 +------------
>  2 files changed, 2 insertions(+), 23 deletions(-)
Jingoo Han sent a larger patchset to convert many MFD drivers to
module_platform_driver_probe(), including htc-pasic3 and davinci_voicecodec.

See my mfd-next tree for more details.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply

* Re: [PATCH V2] video: implement a simple framebuffer driver
From: Stephen Warren @ 2013-04-09  3:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130408171637.98b5ad1f867bcbda883af68b@linux-foundation.org>

On 04/08/2013 06:16 PM, Andrew Morton wrote:
> On Wed,  3 Apr 2013 20:39:43 -0600 Stephen Warren <swarren@wwwdotorg.org> wrote:
> 
>> A simple frame-buffer describes a raw memory region that may be rendered
>> to, with the assumption that the display hardware has already been set
>> up to scan out from that buffer.
>>
>> This is useful in cases where a bootloader exists and has set up the
>> display hardware, but a Linux driver doesn't yet exist for the display
>> hardware.
>>
>> ...
>>
>> +config FB_SIMPLE
>> +	bool "Simple framebuffer support"
>> +	depends on (FB = y) && OF
> 
> It's sad that this simple little thing requires Open Firmware.  Could
> it be generalised in some way so that the small amount of setup info
> could be provided by other means (eg, module_param) or does the
> dependency go deeper than that?

I wouldn't be at all surprised if others want to feed it platform data
rather than parameterizing it through device tree. All my platforms use
DT though, so I didn't want to add that support without any user; it'd
just be dead code for now. But, if someone wants that, I can certainly
code it up or test/review after the change etc.

^ permalink raw reply

* Re: [PATCH V2] video: implement a simple framebuffer driver
From: Andrew Morton @ 2013-04-09  0:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1365043183-28905-1-git-send-email-swarren@wwwdotorg.org>

On Wed,  3 Apr 2013 20:39:43 -0600 Stephen Warren <swarren@wwwdotorg.org> wrote:

> A simple frame-buffer describes a raw memory region that may be rendered
> to, with the assumption that the display hardware has already been set
> up to scan out from that buffer.
> 
> This is useful in cases where a bootloader exists and has set up the
> display hardware, but a Linux driver doesn't yet exist for the display
> hardware.
> 
> ...
>
> +config FB_SIMPLE
> +	bool "Simple framebuffer support"
> +	depends on (FB = y) && OF

It's sad that this simple little thing requires Open Firmware.  Could
it be generalised in some way so that the small amount of setup info
could be provided by other means (eg, module_param) or does the
dependency go deeper than that?

> +struct simplefb_format simplefb_formats[] = {
> +	{ "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0} },
> +};

I'll make this static.


^ permalink raw reply

* Re: [PATCH 1/1] video: wm8505fb: Convert to devm_ioremap_resource()
From: Tony Prisk @ 2013-04-08 18:31 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1365415496-6825-1-git-send-email-sachin.kamat@linaro.org>

On 08/04/13 22:04, Sachin Kamat wrote:
> Use the newly introduced devm_ioremap_resource() instead of
> devm_request_and_ioremap() which provides more consistent error handling.
>
> Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
> ---
>   drivers/video/wm8505fb.c |    7 ++++---
>   1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/video/wm8505fb.c b/drivers/video/wm8505fb.c
> index 19e2e7f..01f9ace 100644
> --- a/drivers/video/wm8505fb.c
> +++ b/drivers/video/wm8505fb.c
> @@ -18,6 +18,7 @@
>   #include <linux/dma-mapping.h>
>   #include <linux/fb.h>
>   #include <linux/errno.h>
> +#include <linux/err.h>
>   #include <linux/init.h>
>   #include <linux/interrupt.h>
>   #include <linux/io.h>
> @@ -303,9 +304,9 @@ static int wm8505fb_probe(struct platform_device *pdev)
>   	fbi->fb.pseudo_palette	= addr;
>   
>   	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	fbi->regbase = devm_request_and_ioremap(&pdev->dev, res);
> -	if (fbi->regbase = NULL)
> -		return -EBUSY;
> +	fbi->regbase = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(fbi->regbase))
> +		return PTR_ERR(fbi->regbase);
>   
>   	disp_timing = of_get_display_timings(pdev->dev.of_node);
>   	if (!disp_timing)
Looks fine,

Acked-by: Tony Prisk <linux@prisktech.co.nz>

Regards
Tony P

^ permalink raw reply

* [PATCH] of: videomode: Fix module loading problem
From: Mohsin Kazmi @ 2013-04-08 11:05 UTC (permalink / raw)
  To: linux-fbdev

This patch adds the support load as a module of_videomode.c which is required by parallel display.
I have encountered the following problem.

imx_parallel_display: Unknown symbol of_get_video_mode (err 0)
insmod: can't insert 'imx-parallel-display.ko': unknown symbol in module, or unknown parameter

of_get_video_mode() is available in of_videomode.c but it couldn't loaded and gave the following error.

of_videomode: Unknown symbol of_property_read_u32_array (err 0)
modprobe: can't load module of_videomode (kernel/drivers/of/of_videomode.ko): unknown symbol in module, or unknown parameter

I have discussed this with Dmitry Eremin-Solenikov. He told me to do so as in this patch and it works.

Signed-off-by: Mohsin Kazmi <mohsin_kazmi@mentor.com>
---
 drivers/of/of_videomode.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/of/of_videomode.c b/drivers/of/of_videomode.c
index 859aefb..cd55f89 100644
--- a/drivers/of/of_videomode.c
+++ b/drivers/of/of_videomode.c
@@ -10,6 +10,7 @@
 #include <linux/export.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc.h>
+#include <linux/module.h>
 
 int of_get_video_mode(struct device_node *np, struct drm_display_mode *dmode,
 		struct fb_videomode *fbmode)
@@ -106,3 +107,5 @@ int of_get_video_mode(struct device_node *np, struct drm_display_mode *dmode,
 	return 0;
 }
 EXPORT_SYMBOL_GPL(of_get_video_mode);
+
+MODULE_LICENSE("GPL");
-- 
1.8.0


^ permalink raw reply related

* [PATCH 1/1] video: wm8505fb: Convert to devm_ioremap_resource()
From: Sachin Kamat @ 2013-04-08 10:16 UTC (permalink / raw)
  To: linux-fbdev

Use the newly introduced devm_ioremap_resource() instead of
devm_request_and_ioremap() which provides more consistent error handling.

Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
---
 drivers/video/wm8505fb.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/video/wm8505fb.c b/drivers/video/wm8505fb.c
index 19e2e7f..01f9ace 100644
--- a/drivers/video/wm8505fb.c
+++ b/drivers/video/wm8505fb.c
@@ -18,6 +18,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/fb.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -303,9 +304,9 @@ static int wm8505fb_probe(struct platform_device *pdev)
 	fbi->fb.pseudo_palette	= addr;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	fbi->regbase = devm_request_and_ioremap(&pdev->dev, res);
-	if (fbi->regbase = NULL)
-		return -EBUSY;
+	fbi->regbase = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(fbi->regbase))
+		return PTR_ERR(fbi->regbase);
 
 	disp_timing = of_get_display_timings(pdev->dev.of_node);
 	if (!disp_timing)
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH] omapdss: use devm_clk_get()
From: Archit Taneja @ 2013-04-08  8:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja

Use devm_clk_get() instead of clk_get() for dss, and for outputs hdmi and venc.
This reduces reduces code and simplifies error handling.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dss.c  |   18 +++---------------
 drivers/video/omap2/dss/hdmi.c |   16 ++--------------
 drivers/video/omap2/dss/venc.c |   10 +---------
 3 files changed, 6 insertions(+), 38 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 054c2a2..645b3bc 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -767,13 +767,11 @@ int dss_dpi_select_source(enum omap_channel channel)
 static int dss_get_clocks(void)
 {
 	struct clk *clk;
-	int r;
 
-	clk = clk_get(&dss.pdev->dev, "fck");
+	clk = devm_clk_get(&dss.pdev->dev, "fck");
 	if (IS_ERR(clk)) {
 		DSSERR("can't get clock fck\n");
-		r = PTR_ERR(clk);
-		goto err;
+		return PTR_ERR(clk);
 	}
 
 	dss.dss_clk = clk;
@@ -782,8 +780,7 @@ static int dss_get_clocks(void)
 		clk = clk_get(NULL, dss.feat->clk_name);
 		if (IS_ERR(clk)) {
 			DSSERR("Failed to get %s\n", dss.feat->clk_name);
-			r = PTR_ERR(clk);
-			goto err;
+			return PTR_ERR(clk);
 		}
 	} else {
 		clk = NULL;
@@ -792,21 +789,12 @@ static int dss_get_clocks(void)
 	dss.dpll4_m4_ck = clk;
 
 	return 0;
-
-err:
-	if (dss.dss_clk)
-		clk_put(dss.dss_clk);
-	if (dss.dpll4_m4_ck)
-		clk_put(dss.dpll4_m4_ck);
-
-	return r;
 }
 
 static void dss_put_clocks(void)
 {
 	if (dss.dpll4_m4_ck)
 		clk_put(dss.dpll4_m4_ck);
-	clk_put(dss.dss_clk);
 }
 
 static int dss_runtime_get(void)
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 7292364..c7e0bf7 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -804,7 +804,7 @@ static int hdmi_get_clocks(struct platform_device *pdev)
 {
 	struct clk *clk;
 
-	clk = clk_get(&pdev->dev, "sys_clk");
+	clk = devm_clk_get(&pdev->dev, "sys_clk");
 	if (IS_ERR(clk)) {
 		DSSERR("can't get sys_clk\n");
 		return PTR_ERR(clk);
@@ -815,12 +815,6 @@ static int hdmi_get_clocks(struct platform_device *pdev)
 	return 0;
 }
 
-static void hdmi_put_clocks(void)
-{
-	if (hdmi.sys_clk)
-		clk_put(hdmi.sys_clk);
-}
-
 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
 int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts)
 {
@@ -1100,7 +1094,7 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 	r = hdmi_panel_init();
 	if (r) {
 		DSSERR("can't init panel\n");
-		goto err_panel_init;
+		return r;
 	}
 
 	dss_debugfs_create_file("hdmi", hdmi_dump_regs);
@@ -1110,10 +1104,6 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 	hdmi_probe_pdata(pdev);
 
 	return 0;
-
-err_panel_init:
-	hdmi_put_clocks();
-	return r;
 }
 
 static int __exit hdmi_remove_child(struct device *dev, void *data)
@@ -1135,8 +1125,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
 
 	pm_runtime_disable(&pdev->dev);
 
-	hdmi_put_clocks();
-
 	return 0;
 }
 
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 006caf3..c27ab6f 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -721,7 +721,7 @@ static int venc_get_clocks(struct platform_device *pdev)
 	struct clk *clk;
 
 	if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK)) {
-		clk = clk_get(&pdev->dev, "tv_dac_clk");
+		clk = devm_clk_get(&pdev->dev, "tv_dac_clk");
 		if (IS_ERR(clk)) {
 			DSSERR("can't get tv_dac_clk\n");
 			return PTR_ERR(clk);
@@ -735,12 +735,6 @@ static int venc_get_clocks(struct platform_device *pdev)
 	return 0;
 }
 
-static void venc_put_clocks(void)
-{
-	if (venc.tv_dac_clk)
-		clk_put(venc.tv_dac_clk);
-}
-
 static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev)
 {
 	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
@@ -886,7 +880,6 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 err_panel_init:
 err_runtime_get:
 	pm_runtime_disable(&pdev->dev);
-	venc_put_clocks();
 	return r;
 }
 
@@ -904,7 +897,6 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
 	venc_uninit_output(pdev);
 
 	pm_runtime_disable(&pdev->dev);
-	venc_put_clocks();
 
 	return 0;
 }
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH v6] video: mxsfb: Introduce regulator support
From: Shawn Guo @ 2013-04-08  8:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1365360299-8707-1-git-send-email-festevam@gmail.com>

On Sun, Apr 07, 2013 at 03:44:59PM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@freescale.com>
> 
> Instead of using a custom binding for retrieving the GPIO that activates the 
> LCD from devicetree, use a standard regulator.
> 
> This approach has the advantage to be more generic. 
> 
> For example: in the case of a board that has a PMIC supplying the LCD voltage, 
> the current approach would not work, as it only searches for a GPIO pin.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>

Applied, thanks.


^ permalink raw reply

* Re: [PATCH v3 2/2] video: imxfb: Add DT support
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-04-08  7:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1365157876-1757-3-git-send-email-mpa@pengutronix.de>

On 12:31 Fri 05 Apr     , Markus Pargmann wrote:
> Add devicetree support for imx framebuffer driver. It uses the generic
> display bindings and helper functions.
> 
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> ---
>  .../devicetree/bindings/video/fsl,imx-fb.txt       |  49 ++++++
>  drivers/video/imxfb.c                              | 192 +++++++++++++++++----
>  2 files changed, 207 insertions(+), 34 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/video/fsl,imx-fb.txt
> 
> diff --git a/Documentation/devicetree/bindings/video/fsl,imx-fb.txt b/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
> new file mode 100644
> index 0000000..bde9c77
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
> @@ -0,0 +1,49 @@
> +Freescale imx21 Framebuffer
> +
> +This framebuffer driver supports devices imx1, imx21, imx25, and imx27.
> +
> +Required properties:
> +- compatible : "fsl,<chip>-fb", chip should be imx1 or imx21
> +- reg : Should contain 1 register ranges(address and length)
> +- interrupts : One interrupt of the fb dev
> +
> +Required nodes:
> +- display: Phandle to a display node as described in
> +	Documentation/devicetree/bindings/video/display-timing.txt
> +	Additional, the display node has to define properties:
> +	- fsl,bpp: Bits per pixel
> +	- fsl,pcr: LCDC PCR value
> +
> +Optional properties:
> +- dmacr-eukrea: Should be set for eukrea boards.
why ?

and This should be prefix by yhe Vendor here Eukrea
> +
> +Example:
> +
> +	imxfb: fb@10021000 {
> +		compatible = "fsl,imx27-fb", "fsl,imx21-fb";
> +		interrupts = <61>;
> +		reg = <0x10021000 0x1000>;
> +		display = <&display0>;
> +	};
> +
> +	...
> +
> +	display0: display0 {
> +		model = "Primeview-PD050VL1";
> +		native-mode = <&timing_disp0>;
> +		fsl,bpp = <16>;		/* non-standard but required */
> +		fsl,pcr = <0xf0c88080>;	/* non-standard but required */
> +		display-timings {
> +			timing_disp0: 640x480 {
> +				hactive = <640>;
> +				vactive = <480>;
> +				hback-porch = <112>;
> +				hfront-porch = <36>;
> +				hsync-len = <32>;
> +				vback-porch = <33>;
> +				vfront-porch = <33>;
> +				vsync-len = <2>;
> +				clock-frequency = <25000000>;
> +			};
> +		};
> +	};
> diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
> index ef2b587..5a9bc598 100644
> --- a/drivers/video/imxfb.c
> +++ b/drivers/video/imxfb.c
> @@ -32,6 +32,12 @@
>  #include <linux/io.h>
>  #include <linux/math64.h>
>  #include <linux/uaccess.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +
> +#include <video/of_display_timing.h>
> +#include <video/of_videomode.h>
> +#include <video/videomode.h>
>  
>  #include <linux/platform_data/video-imxfb.h>
>  
> @@ -117,10 +123,13 @@
>  #define LGWCR_GWAV(alpha)	(((alpha) & 0xff) << 24)
>  #define LGWCR_GWE	(1 << 22)
>  
> +#define IMXFB_LSCR1_DEFAULT 0x00120300
> +#define IMXFB_DMACR_DEFAULT 0x00020010
> +#define IMXFB_DMACR_EUKREA_DEFAULT 0x00040060
> +
>  /* Used fb-mode. Can be set on kernel command line, therefore file-static. */
>  static const char *fb_mode;
>  
> -
>  /*
>   * These are the bitfields for each
>   * display depth that we support.
> @@ -192,6 +201,19 @@ static struct platform_device_id imxfb_devtype[] = {
>  };
>  MODULE_DEVICE_TABLE(platform, imxfb_devtype);
>  
> +static struct of_device_id imxfb_of_dev_id[] = {
> +	{
> +		.compatible = "fsl,imx1-fb",
> +		.data = &imxfb_devtype[IMX1_FB],
> +	}, {
> +		.compatible = "fsl,imx21-fb",
> +		.data = &imxfb_devtype[IMX21_FB],
> +	}, {
> +		/* sentinel */
> +	}
> +};
> +MODULE_DEVICE_TABLE(of, imxfb_of_dev_id);
> +
>  static inline int is_imx1_fb(struct imxfb_info *fbi)
>  {
>  	return fbi->devtype = IMX1_FB;
> @@ -324,6 +346,9 @@ static const struct imx_fb_videomode *imxfb_find_mode(struct imxfb_info *fbi)
>  	struct imx_fb_videomode *m;
>  	int i;
>  
> +	if (!fb_mode)
> +		return &fbi->mode[0];
> +
>  	for (i = 0, m = &fbi->mode[0]; i < fbi->num_modes; i++, m++) {
>  		if (!strcmp(m->mode.name, fb_mode))
>  			return m;
> @@ -479,6 +504,9 @@ static int imxfb_bl_update_status(struct backlight_device *bl)
>  	struct imxfb_info *fbi = bl_get_data(bl);
>  	int brightness = bl->props.brightness;
>  
> +	if (!fbi->pwmr)
> +		return 0;
> +
>  	if (bl->props.power != FB_BLANK_UNBLANK)
>  		brightness = 0;
>  	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
> @@ -719,7 +747,8 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
>  
>  	writel(fbi->pcr, fbi->regs + LCDC_PCR);
>  #ifndef PWMR_BACKLIGHT_AVAILABLE
> -	writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
> +	if (fbi->pwmr)
> +		writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
>  #endif
>  	writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
>  	writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
> @@ -758,13 +787,12 @@ static int imxfb_resume(struct platform_device *dev)
>  #define imxfb_resume	NULL
>  #endif
>  
> -static int __init imxfb_init_fbinfo(struct platform_device *pdev)
> +static int imxfb_init_fbinfo(struct platform_device *pdev)
>  {
>  	struct imx_fb_platform_data *pdata = pdev->dev.platform_data;
>  	struct fb_info *info = dev_get_drvdata(&pdev->dev);
>  	struct imxfb_info *fbi = info->par;
> -	struct imx_fb_videomode *m;
> -	int i;
> +	struct device_node *np;
>  
>  	pr_debug("%s\n",__func__);
>  
> @@ -795,41 +823,96 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
>  	info->fbops			= &imxfb_ops;
>  	info->flags			= FBINFO_FLAG_DEFAULT |
>  					  FBINFO_READS_FAST;
> -	info->var.grayscale		= pdata->cmap_greyscale;
> -	fbi->cmap_inverse		= pdata->cmap_inverse;
> -	fbi->cmap_static		= pdata->cmap_static;
> -	fbi->lscr1			= pdata->lscr1;
> -	fbi->dmacr			= pdata->dmacr;
> -	fbi->pwmr			= pdata->pwmr;
> -	fbi->lcd_power			= pdata->lcd_power;
> -	fbi->backlight_power		= pdata->backlight_power;
> -
> -	for (i = 0, m = &pdata->mode[0]; i < pdata->num_modes; i++, m++)
> -		info->fix.smem_len = max_t(size_t, info->fix.smem_len,
> -				m->mode.xres * m->mode.yres * m->bpp / 8);
> +	if (pdata) {
> +		info->var.grayscale		= pdata->cmap_greyscale;
> +		fbi->cmap_inverse		= pdata->cmap_inverse;
> +		fbi->cmap_static		= pdata->cmap_static;
> +		fbi->lscr1			= pdata->lscr1;
> +		fbi->dmacr			= pdata->dmacr;
> +		fbi->pwmr			= pdata->pwmr;
> +		fbi->lcd_power			= pdata->lcd_power;
> +		fbi->backlight_power		= pdata->backlight_power;
> +	} else {
> +		np = pdev->dev.of_node;
> +		info->var.grayscale = of_property_read_bool(np,
> +						"cmap-greyscale");
> +		fbi->cmap_inverse = of_property_read_bool(np, "cmap-inverse");
> +		fbi->cmap_static = of_property_read_bool(np, "cmap-static");
> +
> +		fbi->lscr1 = IMXFB_LSCR1_DEFAULT;
> +		if (of_property_read_bool(np, "dmacr-eukrea"))
> +			fbi->dmacr = IMXFB_DMACR_EUKREA_DEFAULT;
> +		else
> +			fbi->dmacr = IMXFB_DMACR_DEFAULT;
> +
> +		/* These two function pointers could be used by some specific
> +		 * platforms. */
> +		fbi->lcd_power = NULL;
> +		fbi->backlight_power = NULL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int imxfb_of_read_mode(struct device *dev, struct device_node *np,
> +		struct imx_fb_videomode *imxfb_mode)
> +{
> +	int ret;
> +	struct fb_videomode *of_mode = &imxfb_mode->mode;
> +	u32 bpp;
> +	u32 pcr;
> +
> +	ret = of_property_read_string(np, "model", &of_mode->name);
> +	if (ret)
> +		of_mode->name = NULL;
> +
> +	ret = of_get_fb_videomode(np, of_mode, OF_USE_NATIVE_MODE);
> +	if (ret) {
> +		dev_err(dev, "Failed to get videomode from DT\n");
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32(np, "fsl,bpp", &bpp);
> +	ret |= of_property_read_u32(np, "fsl,pcr", &pcr);
> +
> +	if (ret) {
> +		dev_err(dev, "Failed to read bpp and pcr from DT\n");
> +		return -EINVAL;
> +	}
> +
> +	if (bpp < 1 || bpp > 255) {
> +		dev_err(dev, "Bits per pixel have to be between 1 and 255\n");
> +		return -EINVAL;
> +	}
> +
> +	imxfb_mode->bpp = bpp;
> +	imxfb_mode->pcr = pcr;
>  
>  	return 0;
>  }
>  
> -static int __init imxfb_probe(struct platform_device *pdev)
> +static int imxfb_probe(struct platform_device *pdev)
>  {
>  	struct imxfb_info *fbi;
>  	struct fb_info *info;
>  	struct imx_fb_platform_data *pdata;
>  	struct resource *res;
> +	struct imx_fb_videomode *m;
> +	const struct of_device_id *of_id;
>  	int ret, i;
> +	int bytes_per_pixel;
>  
>  	dev_info(&pdev->dev, "i.MX Framebuffer driver\n");
>  
> +	of_id = of_match_device(imxfb_of_dev_id, &pdev->dev);
> +	if (of_id)
> +		pdev->id_entry = of_id->data;
> +
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	if (!res)
>  		return -ENODEV;
>  
>  	pdata = pdev->dev.platform_data;
> -	if (!pdata) {
> -		dev_err(&pdev->dev,"No platform_data available\n");
> -		return -ENOMEM;
> -	}
>  
>  	info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
>  	if (!info)
> @@ -837,15 +920,55 @@ static int __init imxfb_probe(struct platform_device *pdev)
>  
>  	fbi = info->par;
>  
> -	if (!fb_mode)
> -		fb_mode = pdata->mode[0].mode.name;
> -
>  	platform_set_drvdata(pdev, info);
>  
>  	ret = imxfb_init_fbinfo(pdev);
>  	if (ret < 0)
>  		goto failed_init;
>  
> +	if (pdata) {
> +		if (!fb_mode)
> +			fb_mode = pdata->mode[0].mode.name;
> +
> +		fbi->mode = pdata->mode;
> +		fbi->num_modes = pdata->num_modes;
> +	} else {
> +		struct device_node *display_np;
> +		fb_mode = NULL;
> +
> +		display_np = of_parse_phandle(pdev->dev.of_node, "display", 0);
> +		if (!display_np) {
> +			dev_err(&pdev->dev, "No display defined in devicetree\n");
> +			ret = -EINVAL;
> +			goto failed_of_parse;
> +		}
> +
> +		/*
> +		 * imxfb does not support more modes, we choose only the native
> +		 * mode.
> +		 */
> +		fbi->num_modes = 1;
> +
> +		fbi->mode = devm_kzalloc(&pdev->dev,
> +				sizeof(struct imx_fb_videomode), GFP_KERNEL);
> +		if (!fbi->mode) {
> +			ret = -ENOMEM;
> +			goto failed_of_parse;
> +		}
> +
> +		ret = imxfb_of_read_mode(&pdev->dev, display_np, fbi->mode);
> +		if (ret)
> +			goto failed_of_parse;
> +	}
> +
> +	/* Calculate maximum bytes used per pixel. In most cases this should
> +	 * be the same as m->bpp/8 */
> +	m = &fbi->mode[0];
> +	bytes_per_pixel = (m->bpp + 7) / 8;
> +	for (i = 0; i < fbi->num_modes; i++, m++)
> +		info->fix.smem_len = max_t(size_t, info->fix.smem_len,
> +				m->mode.xres * m->mode.yres * bytes_per_pixel);
> +
>  	res = request_mem_region(res->start, resource_size(res),
>  				DRIVER_NAME);
>  	if (!res) {
> @@ -878,7 +1001,8 @@ static int __init imxfb_probe(struct platform_device *pdev)
>  		goto failed_ioremap;
>  	}
>  
> -	if (!pdata->fixed_screen_cpu) {
> +	/* Seems not being used by anyone, so no support for oftree */
> +	if (!pdata || !pdata->fixed_screen_cpu) {
>  		fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
>  		fbi->map_cpu = dma_alloc_writecombine(&pdev->dev,
>  				fbi->map_size, &fbi->map_dma, GFP_KERNEL);
> @@ -903,18 +1027,16 @@ static int __init imxfb_probe(struct platform_device *pdev)
>  		info->fix.smem_start = fbi->screen_dma;
>  	}
>  
> -	if (pdata->init) {
> +	if (pdata && pdata->init) {
>  		ret = pdata->init(fbi->pdev);
>  		if (ret)
>  			goto failed_platform_init;
>  	}
>  
> -	fbi->mode = pdata->mode;
> -	fbi->num_modes = pdata->num_modes;
>  
>  	INIT_LIST_HEAD(&info->modelist);
> -	for (i = 0; i < pdata->num_modes; i++)
> -		fb_add_videomode(&pdata->mode[i].mode, &info->modelist);
> +	for (i = 0; i < fbi->num_modes; i++)
> +		fb_add_videomode(&fbi->mode[i].mode, &info->modelist);
>  
>  	/*
>  	 * This makes sure that our colour bitfield
> @@ -944,10 +1066,10 @@ static int __init imxfb_probe(struct platform_device *pdev)
>  failed_register:
>  	fb_dealloc_cmap(&info->cmap);
>  failed_cmap:
> -	if (pdata->exit)
> +	if (pdata && pdata->exit)
>  		pdata->exit(fbi->pdev);
>  failed_platform_init:
> -	if (!pdata->fixed_screen_cpu)
> +	if (pdata && !pdata->fixed_screen_cpu)
>  		dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
>  			fbi->map_dma);
>  failed_map:
> @@ -956,6 +1078,7 @@ failed_ioremap:
>  failed_getclock:
>  	release_mem_region(res->start, resource_size(res));
>  failed_req:
> +failed_of_parse:
>  	kfree(info->pseudo_palette);
>  failed_init:
>  	platform_set_drvdata(pdev, NULL);
> @@ -980,7 +1103,7 @@ static int imxfb_remove(struct platform_device *pdev)
>  	unregister_framebuffer(info);
>  
>  	pdata = pdev->dev.platform_data;
> -	if (pdata->exit)
> +	if (pdata && pdata->exit)
>  		pdata->exit(fbi->pdev);
>  
>  	fb_dealloc_cmap(&info->cmap);
> @@ -1009,6 +1132,7 @@ static struct platform_driver imxfb_driver = {
>  	.shutdown	= imxfb_shutdown,
>  	.driver		= {
>  		.name	= DRIVER_NAME,
> +		.of_match_table = imxfb_of_dev_id,
>  	},
>  	.id_table	= imxfb_devtype,
>  };
> -- 
> 1.8.1.5
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply

* [PATCH v6] video: mxsfb: Introduce regulator support
From: Fabio Estevam @ 2013-04-07 18:44 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fabio Estevam <fabio.estevam@freescale.com>

Instead of using a custom binding for retrieving the GPIO that activates the 
LCD from devicetree, use a standard regulator.

This approach has the advantage to be more generic. 

For example: in the case of a board that has a PMIC supplying the LCD voltage, 
the current approach would not work, as it only searches for a GPIO pin.

Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
---
Changes since v5:
- Remove 'Optional properties' line from mxsfb.txt
- Place regultar_disable in the end of mxsfb_disable_controller
- Check for IS_ERR((IS_ERR(host->reg_lcd)) inside probe
Chages since v4:
- Merged the 2 previous patches into one in order not to break keep mxsfb functionality
- Remove unneeded change in mxsfb.txt
- Use regulator_disable to pair with regulator_enable
Changes since v3:
- None
Changes since v2:
- Use devm_regulator_get()
Changes since v1:
- No changes
 Documentation/devicetree/bindings/fb/mxsfb.txt |    4 ---
 arch/arm/boot/dts/imx23-evk.dts                |   11 ++++++-
 arch/arm/boot/dts/imx28-evk.dts                |   11 ++++++-
 drivers/video/mxsfb.c                          |   41 +++++++++++++-----------
 4 files changed, 43 insertions(+), 24 deletions(-)

diff --git a/Documentation/devicetree/bindings/fb/mxsfb.txt b/Documentation/devicetree/bindings/fb/mxsfb.txt
index 7ba3b76..96ec517 100644
--- a/Documentation/devicetree/bindings/fb/mxsfb.txt
+++ b/Documentation/devicetree/bindings/fb/mxsfb.txt
@@ -7,9 +7,6 @@ Required properties:
 - interrupts: Should contain lcdif interrupts
 - display : phandle to display node (see below for details)
 
-Optional properties:
-- panel-enable-gpios : Should specify the gpio for panel enable
-
 * display node
 
 Required properties:
@@ -25,7 +22,6 @@ lcdif@80030000 {
 	compatible = "fsl,imx28-lcdif";
 	reg = <0x80030000 2000>;
 	interrupts = <38 86>;
-	panel-enable-gpios = <&gpio3 30 0>;
 
 	display: display {
 		bits-per-pixel = <32>;
diff --git a/arch/arm/boot/dts/imx23-evk.dts b/arch/arm/boot/dts/imx23-evk.dts
index 7880e17..da0588a 100644
--- a/arch/arm/boot/dts/imx23-evk.dts
+++ b/arch/arm/boot/dts/imx23-evk.dts
@@ -59,7 +59,7 @@
 			lcdif@80030000 {
 				pinctrl-names = "default";
 				pinctrl-0 = <&lcdif_24bit_pins_a>;
-				panel-enable-gpios = <&gpio1 18 0>;
+				lcd-supply = <&reg_lcd_3v3>;
 				display = <&display>;
 				status = "okay";
 
@@ -120,6 +120,15 @@
 			regulator-max-microvolt = <3300000>;
 			gpio = <&gpio1 29 0>;
 		};
+
+		reg_lcd_3v3: lcd-3v3 {
+			compatible = "regulator-fixed";
+			regulator-name = "lcd-3v3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpio1 18 0>;
+			enable-active-high;
+		};
 	};
 
 	backlight {
diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts
index 2d4ea3b..3637bf3 100644
--- a/arch/arm/boot/dts/imx28-evk.dts
+++ b/arch/arm/boot/dts/imx28-evk.dts
@@ -123,7 +123,7 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&lcdif_24bit_pins_a
 					     &lcdif_pins_evk>;
-				panel-enable-gpios = <&gpio3 30 0>;
+				lcd-supply = <&reg_lcd_3v3>;
 				display = <&display>;
 				status = "okay";
 
@@ -310,6 +310,15 @@
 			gpio = <&gpio3 8 0>;
 			enable-active-high;
 		};
+
+		reg_lcd_3v3: lcd-3v3 {
+			compatible = "regulator-fixed";
+			regulator-name = "lcd-3v3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpio3 30 0>;
+			enable-active-high;
+		};
 	};
 
 	sound {
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index eac7c1a..1b2c26d 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -42,7 +42,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/of_device.h>
-#include <linux/of_gpio.h>
 #include <video/of_display_timing.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
@@ -50,6 +49,7 @@
 #include <linux/io.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/fb.h>
+#include <linux/regulator/consumer.h>
 #include <video/videomode.h>
 
 #define REG_SET	4
@@ -179,6 +179,7 @@ struct mxsfb_info {
 	unsigned dotclk_delay;
 	const struct mxsfb_devdata *devdata;
 	u32 sync;
+	struct regulator *reg_lcd;
 };
 
 #define mxsfb_is_v3(host) (host->devdata->ipversion = 3)
@@ -338,9 +339,19 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
 {
 	struct mxsfb_info *host = to_imxfb_host(fb_info);
 	u32 reg;
+	int ret;
 
 	dev_dbg(&host->pdev->dev, "%s\n", __func__);
 
+	if (host->reg_lcd) {
+		ret = regulator_enable(host->reg_lcd);
+		if (ret) {
+			dev_err(&host->pdev->dev,
+				"lcd regulator enable failed:	%d\n", ret);
+			return;
+		}
+	}
+
 	clk_prepare_enable(host->clk);
 	clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
 
@@ -362,6 +373,7 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
 	struct mxsfb_info *host = to_imxfb_host(fb_info);
 	unsigned loop;
 	u32 reg;
+	int ret;
 
 	dev_dbg(&host->pdev->dev, "%s\n", __func__);
 
@@ -385,6 +397,13 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
 	clk_disable_unprepare(host->clk);
 
 	host->enabled = 0;
+
+	if (host->reg_lcd) {
+		ret = regulator_disable(host->reg_lcd);
+		if (ret)
+			dev_err(&host->pdev->dev,
+				"lcd regulator disable failed: %d\n", ret);
+	}
 }
 
 static int mxsfb_set_par(struct fb_info *fb_info)
@@ -859,8 +878,6 @@ static int mxsfb_probe(struct platform_device *pdev)
 	struct fb_info *fb_info;
 	struct fb_modelist *modelist;
 	struct pinctrl *pinctrl;
-	int panel_enable;
-	enum of_gpio_flags flags;
 	int ret;
 
 	if (of_id)
@@ -904,21 +921,9 @@ static int mxsfb_probe(struct platform_device *pdev)
 		goto fb_release;
 	}
 
-	panel_enable = of_get_named_gpio_flags(pdev->dev.of_node,
-					       "panel-enable-gpios", 0, &flags);
-	if (gpio_is_valid(panel_enable)) {
-		unsigned long f = GPIOF_OUT_INIT_HIGH;
-		if (flags = OF_GPIO_ACTIVE_LOW)
-			f = GPIOF_OUT_INIT_LOW;
-		ret = devm_gpio_request_one(&pdev->dev, panel_enable,
-					    f, "panel-enable");
-		if (ret) {
-			dev_err(&pdev->dev,
-				"failed to request gpio %d: %d\n",
-				panel_enable, ret);
-			goto fb_release;
-		}
-	}
+	host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
+	if (IS_ERR(host->reg_lcd))
+		host->reg_lcd = NULL;
 
 	fb_info->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16,
 					       GFP_KERNEL);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH] OMAPDSS: nec-nl8048 panel: Use dev_pm_ops
From: Lars-Peter Clausen @ 2013-04-07  8:21 UTC (permalink / raw)
  To: Tomi Valkeinen, Florian Tobias Schandinat
  Cc: Archit Taneja, linux-omap, linux-fbdev, linux-kernel,
	Lars-Peter Clausen

Use dev_pm_ops instead of the deprecated legacy suspend/resume callbacks.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 .../video/omap2/displays/panel-nec-nl8048hl11-01b.c  | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 1e0097d..20c3cd9 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -242,16 +242,22 @@ static int nec_8048_spi_remove(struct spi_device *spi)
 	return 0;
 }
 
-static int nec_8048_spi_suspend(struct spi_device *spi, pm_message_t mesg)
+#ifdef CONFIG_PM_SLEEP
+
+static int nec_8048_spi_suspend(struct device *dev)
 {
+	struct spi_device *spi = to_spi_device(dev);
+
 	nec_8048_spi_send(spi, 2, 0x01);
 	mdelay(40);
 
 	return 0;
 }
 
-static int nec_8048_spi_resume(struct spi_device *spi)
+static int nec_8048_spi_resume(struct device *dev)
 {
+	struct spi_device *spi = to_spi_device(dev);
+
 	/* reinitialize the panel */
 	spi_setup(spi);
 	nec_8048_spi_send(spi, 2, 0x00);
@@ -260,14 +266,20 @@ static int nec_8048_spi_resume(struct spi_device *spi)
 	return 0;
 }
 
+static SIMPLE_DEV_PM_OPS(nec_8048_spi_pm_ops, nec_8048_spi_suspend,
+		nec_8048_spi_resume);
+#define NEC_8048_SPI_PM_OPS (&nec_8048_spi_pm_ops)
+#else
+#define NEC_8048_SPI_PM_OPS NULL
+#endif
+
 static struct spi_driver nec_8048_spi_driver = {
 	.probe		= nec_8048_spi_probe,
 	.remove		= nec_8048_spi_remove,
-	.suspend	= nec_8048_spi_suspend,
-	.resume		= nec_8048_spi_resume,
 	.driver		= {
 		.name	= "nec_8048_spi",
 		.owner	= THIS_MODULE,
+		.pm	= NEC_8048_SPI_PM_OPS,
 	},
 };
 
-- 
1.8.0


^ permalink raw reply related

* Re: [PATCH v5] video: mxsfb: Introduce regulator support
From: Shawn Guo @ 2013-04-07  6:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1365171587-31833-1-git-send-email-fabio.estevam@freescale.com>

On Fri, Apr 05, 2013 at 11:19:47AM -0300, Fabio Estevam wrote:
> Instead of using a custom binding for retrieving the GPIO that activates the 
> LCD from devicetree, use a standard regulator.
> 
> This approach has the advantage to be more generic. 
> 
> For example: in the case of a board that has a PMIC supplying the LCD voltage, 
> the current approach would not work, as it only searches for a GPIO pin.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
> ---
> Chages since v4:
> - Merged the 2 previous patches into one in order not to break keep mxsfb functionality
> - Remove unneeded change in mxsfb.txt
> - Use regulator_disable to pair with regulator_enable
> Changes since v3:
> - None
> Changes since v2:
> - Use devm_regulator_get()
> Changes since v1:
> - No changes
>  Documentation/devicetree/bindings/fb/mxsfb.txt |    2 --
>  arch/arm/boot/dts/imx23-evk.dts                |   11 ++++++-
>  arch/arm/boot/dts/imx28-evk.dts                |   11 ++++++-
>  drivers/video/mxsfb.c                          |   41 +++++++++++++-----------
>  4 files changed, 43 insertions(+), 22 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/fb/mxsfb.txt b/Documentation/devicetree/bindings/fb/mxsfb.txt
> index 7ba3b76..5d810eb 100644
> --- a/Documentation/devicetree/bindings/fb/mxsfb.txt
> +++ b/Documentation/devicetree/bindings/fb/mxsfb.txt
> @@ -8,7 +8,6 @@ Required properties:
>  - display : phandle to display node (see below for details)
>  
>  Optional properties:

So this line should be removed together?

> -- panel-enable-gpios : Should specify the gpio for panel enable
>  
>  * display node
>  
> @@ -25,7 +24,6 @@ lcdif@80030000 {
>  	compatible = "fsl,imx28-lcdif";
>  	reg = <0x80030000 2000>;
>  	interrupts = <38 86>;
> -	panel-enable-gpios = <&gpio3 30 0>;
>  
>  	display: display {
>  		bits-per-pixel = <32>;
> diff --git a/arch/arm/boot/dts/imx23-evk.dts b/arch/arm/boot/dts/imx23-evk.dts
> index 7880e17..da0588a 100644
> --- a/arch/arm/boot/dts/imx23-evk.dts
> +++ b/arch/arm/boot/dts/imx23-evk.dts
> @@ -59,7 +59,7 @@
>  			lcdif@80030000 {
>  				pinctrl-names = "default";
>  				pinctrl-0 = <&lcdif_24bit_pins_a>;
> -				panel-enable-gpios = <&gpio1 18 0>;
> +				lcd-supply = <&reg_lcd_3v3>;
>  				display = <&display>;
>  				status = "okay";
>  
> @@ -120,6 +120,15 @@
>  			regulator-max-microvolt = <3300000>;
>  			gpio = <&gpio1 29 0>;
>  		};
> +
> +		reg_lcd_3v3: lcd-3v3 {
> +			compatible = "regulator-fixed";
> +			regulator-name = "lcd-3v3";
> +			regulator-min-microvolt = <3300000>;
> +			regulator-max-microvolt = <3300000>;
> +			gpio = <&gpio1 18 0>;
> +			enable-active-high;
> +		};
>  	};
>  
>  	backlight {
> diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts
> index 2d4ea3b..3637bf3 100644
> --- a/arch/arm/boot/dts/imx28-evk.dts
> +++ b/arch/arm/boot/dts/imx28-evk.dts
> @@ -123,7 +123,7 @@
>  				pinctrl-names = "default";
>  				pinctrl-0 = <&lcdif_24bit_pins_a
>  					     &lcdif_pins_evk>;
> -				panel-enable-gpios = <&gpio3 30 0>;
> +				lcd-supply = <&reg_lcd_3v3>;
>  				display = <&display>;
>  				status = "okay";
>  
> @@ -310,6 +310,15 @@
>  			gpio = <&gpio3 8 0>;
>  			enable-active-high;
>  		};
> +
> +		reg_lcd_3v3: lcd-3v3 {
> +			compatible = "regulator-fixed";
> +			regulator-name = "lcd-3v3";
> +			regulator-min-microvolt = <3300000>;
> +			regulator-max-microvolt = <3300000>;
> +			gpio = <&gpio3 30 0>;
> +			enable-active-high;
> +		};
>  	};
>  
>  	sound {
> diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
> index eac7c1a..74fbfd1 100644
> --- a/drivers/video/mxsfb.c
> +++ b/drivers/video/mxsfb.c
> @@ -42,7 +42,6 @@
>  #include <linux/module.h>
>  #include <linux/kernel.h>
>  #include <linux/of_device.h>
> -#include <linux/of_gpio.h>
>  #include <video/of_display_timing.h>
>  #include <linux/platform_device.h>
>  #include <linux/clk.h>
> @@ -50,6 +49,7 @@
>  #include <linux/io.h>
>  #include <linux/pinctrl/consumer.h>
>  #include <linux/fb.h>
> +#include <linux/regulator/consumer.h>
>  #include <video/videomode.h>
>  
>  #define REG_SET	4
> @@ -179,6 +179,7 @@ struct mxsfb_info {
>  	unsigned dotclk_delay;
>  	const struct mxsfb_devdata *devdata;
>  	u32 sync;
> +	struct regulator *reg_lcd;
>  };
>  
>  #define mxsfb_is_v3(host) (host->devdata->ipversion = 3)
> @@ -338,9 +339,19 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
>  {
>  	struct mxsfb_info *host = to_imxfb_host(fb_info);
>  	u32 reg;
> +	int ret;
>  
>  	dev_dbg(&host->pdev->dev, "%s\n", __func__);
>  
> +	if (!IS_ERR(host->reg_lcd)) {
> +		ret = regulator_enable(host->reg_lcd);
> +		if (ret) {
> +			dev_err(&host->pdev->dev,
> +				"lcd regulator enable failed:	%d\n", ret);
> +			return;
> +		}
> +	}
> +
>  	clk_prepare_enable(host->clk);
>  	clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
>  
> @@ -362,9 +373,19 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
>  	struct mxsfb_info *host = to_imxfb_host(fb_info);
>  	unsigned loop;
>  	u32 reg;
> +	int ret;
>  
>  	dev_dbg(&host->pdev->dev, "%s\n", __func__);
>  
> +	if (!IS_ERR(host->reg_lcd)) {
> +		ret = regulator_disable(host->reg_lcd);
> +		if (ret) {
> +			dev_err(&host->pdev->dev,
> +				"lcd regulator disable failed: %d\n", ret);
> +			return;
> +		}
> +	}
> +
Shouldn't this be done as the last step of disabling?

>  	/*
>  	 * Even if we disable the controller here, it will still continue
>  	 * until its FIFOs are running out of data
> @@ -859,8 +880,6 @@ static int mxsfb_probe(struct platform_device *pdev)
>  	struct fb_info *fb_info;
>  	struct fb_modelist *modelist;
>  	struct pinctrl *pinctrl;
> -	int panel_enable;
> -	enum of_gpio_flags flags;
>  	int ret;
>  
>  	if (of_id)
> @@ -904,21 +923,7 @@ static int mxsfb_probe(struct platform_device *pdev)
>  		goto fb_release;
>  	}
>  
> -	panel_enable = of_get_named_gpio_flags(pdev->dev.of_node,
> -					       "panel-enable-gpios", 0, &flags);
> -	if (gpio_is_valid(panel_enable)) {
> -		unsigned long f = GPIOF_OUT_INIT_HIGH;
> -		if (flags = OF_GPIO_ACTIVE_LOW)
> -			f = GPIOF_OUT_INIT_LOW;
> -		ret = devm_gpio_request_one(&pdev->dev, panel_enable,
> -					    f, "panel-enable");
> -		if (ret) {
> -			dev_err(&pdev->dev,
> -				"failed to request gpio %d: %d\n",
> -				panel_enable, ret);
> -			goto fb_release;
> -		}
> -	}
> +	host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");

I prefer to check return here ...

	if (IS_ERR(host->reg_lcd))
		host->reg_lcd = NULL;

... and then use if (host->reg_lcd) in mxsfb_enable[disable]_controller().

Shawn

>  
>  	fb_info->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16,
>  					       GFP_KERNEL);
> -- 
> 1.7.9.5
> 
> 


^ permalink raw reply

* [PATCH v4, part3 07/15] mm, acornfb: use free_reserved_area() to simplify code
From: Jiang Liu @ 2013-04-06 13:55 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Jiang Liu, David Rientjes, Wen Congyang, Mel Gorman, Minchan Kim,
	KAMEZAWA Hiroyuki, Michal Hocko, James Bottomley, Sergei Shtylyov,
	David Howells, Mark Salter, Jianguo Wu, linux-mm, linux-arch,
	linux-kernel, Florian Tobias Schandinat, linux-fbdev
In-Reply-To: <1365256509-29024-1-git-send-email-jiang.liu@huawei.com>

Use common help function free_reserved_area() to simplify code.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: linux-fbdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/video/acornfb.c |   28 ++--------------------------
 1 file changed, 2 insertions(+), 26 deletions(-)

diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 6488a73..344f2bb 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -1188,32 +1188,8 @@ static int acornfb_detect_monitortype(void)
 static inline void
 free_unused_pages(unsigned int virtual_start, unsigned int virtual_end)
 {
-	int mb_freed = 0;
-
-	/*
-	 * Align addresses
-	 */
-	virtual_start = PAGE_ALIGN(virtual_start);
-	virtual_end = PAGE_ALIGN(virtual_end);
-
-	while (virtual_start < virtual_end) {
-		struct page *page;
-
-		/*
-		 * Clear page reserved bit,
-		 * set count to 1, and free
-		 * the page.
-		 */
-		page = virt_to_page(virtual_start);
-		ClearPageReserved(page);
-		init_page_count(page);
-		free_page(virtual_start);
-
-		virtual_start += PAGE_SIZE;
-		mb_freed += PAGE_SIZE / 1024;
-	}
-
-	printk("acornfb: freed %dK memory\n", mb_freed);
+	free_reserved_area(virtual_start, PAGE_ALIGN(virtual_end),
+			   -1, "acornfb");
 }
 
 static int acornfb_probe(struct platform_device *dev)
-- 
1.7.9.5


^ permalink raw reply related

* Graphics and Display Microconference @LPC2013
From: Laurent Pinchart @ 2013-04-06  0:17 UTC (permalink / raw)
  To: dri-devel, linux-fbdev

Hello everybody,

I've submitted a graphics and display microconference for the Linux Plumbers 
Conference 2013, and just realized that I haven't announced the proposal on 
the dri-devel and linux-fbdev mailing lists.

The proposal is available at 
http://wiki.linuxplumbersconf.org/2013:graphics_and_display. Please send me 
feedback on the proposed topics, and add your name to the attendees list if 
you plan to participate.

-- 
Regards,

Laurent Pinchart


^ permalink raw reply

* [PATCH v5] video: mxsfb: Introduce regulator support
From: Fabio Estevam @ 2013-04-05 14:19 UTC (permalink / raw)
  To: linux-arm-kernel

Instead of using a custom binding for retrieving the GPIO that activates the 
LCD from devicetree, use a standard regulator.

This approach has the advantage to be more generic. 

For example: in the case of a board that has a PMIC supplying the LCD voltage, 
the current approach would not work, as it only searches for a GPIO pin.

Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
---
Chages since v4:
- Merged the 2 previous patches into one in order not to break keep mxsfb functionality
- Remove unneeded change in mxsfb.txt
- Use regulator_disable to pair with regulator_enable
Changes since v3:
- None
Changes since v2:
- Use devm_regulator_get()
Changes since v1:
- No changes
 Documentation/devicetree/bindings/fb/mxsfb.txt |    2 --
 arch/arm/boot/dts/imx23-evk.dts                |   11 ++++++-
 arch/arm/boot/dts/imx28-evk.dts                |   11 ++++++-
 drivers/video/mxsfb.c                          |   41 +++++++++++++-----------
 4 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/Documentation/devicetree/bindings/fb/mxsfb.txt b/Documentation/devicetree/bindings/fb/mxsfb.txt
index 7ba3b76..5d810eb 100644
--- a/Documentation/devicetree/bindings/fb/mxsfb.txt
+++ b/Documentation/devicetree/bindings/fb/mxsfb.txt
@@ -8,7 +8,6 @@ Required properties:
 - display : phandle to display node (see below for details)
 
 Optional properties:
-- panel-enable-gpios : Should specify the gpio for panel enable
 
 * display node
 
@@ -25,7 +24,6 @@ lcdif@80030000 {
 	compatible = "fsl,imx28-lcdif";
 	reg = <0x80030000 2000>;
 	interrupts = <38 86>;
-	panel-enable-gpios = <&gpio3 30 0>;
 
 	display: display {
 		bits-per-pixel = <32>;
diff --git a/arch/arm/boot/dts/imx23-evk.dts b/arch/arm/boot/dts/imx23-evk.dts
index 7880e17..da0588a 100644
--- a/arch/arm/boot/dts/imx23-evk.dts
+++ b/arch/arm/boot/dts/imx23-evk.dts
@@ -59,7 +59,7 @@
 			lcdif@80030000 {
 				pinctrl-names = "default";
 				pinctrl-0 = <&lcdif_24bit_pins_a>;
-				panel-enable-gpios = <&gpio1 18 0>;
+				lcd-supply = <&reg_lcd_3v3>;
 				display = <&display>;
 				status = "okay";
 
@@ -120,6 +120,15 @@
 			regulator-max-microvolt = <3300000>;
 			gpio = <&gpio1 29 0>;
 		};
+
+		reg_lcd_3v3: lcd-3v3 {
+			compatible = "regulator-fixed";
+			regulator-name = "lcd-3v3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpio1 18 0>;
+			enable-active-high;
+		};
 	};
 
 	backlight {
diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts
index 2d4ea3b..3637bf3 100644
--- a/arch/arm/boot/dts/imx28-evk.dts
+++ b/arch/arm/boot/dts/imx28-evk.dts
@@ -123,7 +123,7 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&lcdif_24bit_pins_a
 					     &lcdif_pins_evk>;
-				panel-enable-gpios = <&gpio3 30 0>;
+				lcd-supply = <&reg_lcd_3v3>;
 				display = <&display>;
 				status = "okay";
 
@@ -310,6 +310,15 @@
 			gpio = <&gpio3 8 0>;
 			enable-active-high;
 		};
+
+		reg_lcd_3v3: lcd-3v3 {
+			compatible = "regulator-fixed";
+			regulator-name = "lcd-3v3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpio3 30 0>;
+			enable-active-high;
+		};
 	};
 
 	sound {
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index eac7c1a..74fbfd1 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -42,7 +42,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/of_device.h>
-#include <linux/of_gpio.h>
 #include <video/of_display_timing.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
@@ -50,6 +49,7 @@
 #include <linux/io.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/fb.h>
+#include <linux/regulator/consumer.h>
 #include <video/videomode.h>
 
 #define REG_SET	4
@@ -179,6 +179,7 @@ struct mxsfb_info {
 	unsigned dotclk_delay;
 	const struct mxsfb_devdata *devdata;
 	u32 sync;
+	struct regulator *reg_lcd;
 };
 
 #define mxsfb_is_v3(host) (host->devdata->ipversion = 3)
@@ -338,9 +339,19 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
 {
 	struct mxsfb_info *host = to_imxfb_host(fb_info);
 	u32 reg;
+	int ret;
 
 	dev_dbg(&host->pdev->dev, "%s\n", __func__);
 
+	if (!IS_ERR(host->reg_lcd)) {
+		ret = regulator_enable(host->reg_lcd);
+		if (ret) {
+			dev_err(&host->pdev->dev,
+				"lcd regulator enable failed:	%d\n", ret);
+			return;
+		}
+	}
+
 	clk_prepare_enable(host->clk);
 	clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
 
@@ -362,9 +373,19 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
 	struct mxsfb_info *host = to_imxfb_host(fb_info);
 	unsigned loop;
 	u32 reg;
+	int ret;
 
 	dev_dbg(&host->pdev->dev, "%s\n", __func__);
 
+	if (!IS_ERR(host->reg_lcd)) {
+		ret = regulator_disable(host->reg_lcd);
+		if (ret) {
+			dev_err(&host->pdev->dev,
+				"lcd regulator disable failed: %d\n", ret);
+			return;
+		}
+	}
+
 	/*
 	 * Even if we disable the controller here, it will still continue
 	 * until its FIFOs are running out of data
@@ -859,8 +880,6 @@ static int mxsfb_probe(struct platform_device *pdev)
 	struct fb_info *fb_info;
 	struct fb_modelist *modelist;
 	struct pinctrl *pinctrl;
-	int panel_enable;
-	enum of_gpio_flags flags;
 	int ret;
 
 	if (of_id)
@@ -904,21 +923,7 @@ static int mxsfb_probe(struct platform_device *pdev)
 		goto fb_release;
 	}
 
-	panel_enable = of_get_named_gpio_flags(pdev->dev.of_node,
-					       "panel-enable-gpios", 0, &flags);
-	if (gpio_is_valid(panel_enable)) {
-		unsigned long f = GPIOF_OUT_INIT_HIGH;
-		if (flags = OF_GPIO_ACTIVE_LOW)
-			f = GPIOF_OUT_INIT_LOW;
-		ret = devm_gpio_request_one(&pdev->dev, panel_enable,
-					    f, "panel-enable");
-		if (ret) {
-			dev_err(&pdev->dev,
-				"failed to request gpio %d: %d\n",
-				panel_enable, ret);
-			goto fb_release;
-		}
-	}
+	host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
 
 	fb_info->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16,
 					       GFP_KERNEL);
-- 
1.7.9.5



^ permalink raw reply related

* [PATCH v3 2/2] video: imxfb: Add DT support
From: Markus Pargmann @ 2013-04-05 10:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1365157876-1757-1-git-send-email-mpa@pengutronix.de>

Add devicetree support for imx framebuffer driver. It uses the generic
display bindings and helper functions.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Mark Rutland <mark.rutland@arm.com>
---
 .../devicetree/bindings/video/fsl,imx-fb.txt       |  49 ++++++
 drivers/video/imxfb.c                              | 192 +++++++++++++++++----
 2 files changed, 207 insertions(+), 34 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/video/fsl,imx-fb.txt

diff --git a/Documentation/devicetree/bindings/video/fsl,imx-fb.txt b/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
new file mode 100644
index 0000000..bde9c77
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
@@ -0,0 +1,49 @@
+Freescale imx21 Framebuffer
+
+This framebuffer driver supports devices imx1, imx21, imx25, and imx27.
+
+Required properties:
+- compatible : "fsl,<chip>-fb", chip should be imx1 or imx21
+- reg : Should contain 1 register ranges(address and length)
+- interrupts : One interrupt of the fb dev
+
+Required nodes:
+- display: Phandle to a display node as described in
+	Documentation/devicetree/bindings/video/display-timing.txt
+	Additional, the display node has to define properties:
+	- fsl,bpp: Bits per pixel
+	- fsl,pcr: LCDC PCR value
+
+Optional properties:
+- dmacr-eukrea: Should be set for eukrea boards.
+
+Example:
+
+	imxfb: fb@10021000 {
+		compatible = "fsl,imx27-fb", "fsl,imx21-fb";
+		interrupts = <61>;
+		reg = <0x10021000 0x1000>;
+		display = <&display0>;
+	};
+
+	...
+
+	display0: display0 {
+		model = "Primeview-PD050VL1";
+		native-mode = <&timing_disp0>;
+		fsl,bpp = <16>;		/* non-standard but required */
+		fsl,pcr = <0xf0c88080>;	/* non-standard but required */
+		display-timings {
+			timing_disp0: 640x480 {
+				hactive = <640>;
+				vactive = <480>;
+				hback-porch = <112>;
+				hfront-porch = <36>;
+				hsync-len = <32>;
+				vback-porch = <33>;
+				vfront-porch = <33>;
+				vsync-len = <2>;
+				clock-frequency = <25000000>;
+			};
+		};
+	};
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index ef2b587..5a9bc598 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -32,6 +32,12 @@
 #include <linux/io.h>
 #include <linux/math64.h>
 #include <linux/uaccess.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#include <video/of_display_timing.h>
+#include <video/of_videomode.h>
+#include <video/videomode.h>
 
 #include <linux/platform_data/video-imxfb.h>
 
@@ -117,10 +123,13 @@
 #define LGWCR_GWAV(alpha)	(((alpha) & 0xff) << 24)
 #define LGWCR_GWE	(1 << 22)
 
+#define IMXFB_LSCR1_DEFAULT 0x00120300
+#define IMXFB_DMACR_DEFAULT 0x00020010
+#define IMXFB_DMACR_EUKREA_DEFAULT 0x00040060
+
 /* Used fb-mode. Can be set on kernel command line, therefore file-static. */
 static const char *fb_mode;
 
-
 /*
  * These are the bitfields for each
  * display depth that we support.
@@ -192,6 +201,19 @@ static struct platform_device_id imxfb_devtype[] = {
 };
 MODULE_DEVICE_TABLE(platform, imxfb_devtype);
 
+static struct of_device_id imxfb_of_dev_id[] = {
+	{
+		.compatible = "fsl,imx1-fb",
+		.data = &imxfb_devtype[IMX1_FB],
+	}, {
+		.compatible = "fsl,imx21-fb",
+		.data = &imxfb_devtype[IMX21_FB],
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, imxfb_of_dev_id);
+
 static inline int is_imx1_fb(struct imxfb_info *fbi)
 {
 	return fbi->devtype = IMX1_FB;
@@ -324,6 +346,9 @@ static const struct imx_fb_videomode *imxfb_find_mode(struct imxfb_info *fbi)
 	struct imx_fb_videomode *m;
 	int i;
 
+	if (!fb_mode)
+		return &fbi->mode[0];
+
 	for (i = 0, m = &fbi->mode[0]; i < fbi->num_modes; i++, m++) {
 		if (!strcmp(m->mode.name, fb_mode))
 			return m;
@@ -479,6 +504,9 @@ static int imxfb_bl_update_status(struct backlight_device *bl)
 	struct imxfb_info *fbi = bl_get_data(bl);
 	int brightness = bl->props.brightness;
 
+	if (!fbi->pwmr)
+		return 0;
+
 	if (bl->props.power != FB_BLANK_UNBLANK)
 		brightness = 0;
 	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
@@ -719,7 +747,8 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
 
 	writel(fbi->pcr, fbi->regs + LCDC_PCR);
 #ifndef PWMR_BACKLIGHT_AVAILABLE
-	writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
+	if (fbi->pwmr)
+		writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
 #endif
 	writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
 	writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
@@ -758,13 +787,12 @@ static int imxfb_resume(struct platform_device *dev)
 #define imxfb_resume	NULL
 #endif
 
-static int __init imxfb_init_fbinfo(struct platform_device *pdev)
+static int imxfb_init_fbinfo(struct platform_device *pdev)
 {
 	struct imx_fb_platform_data *pdata = pdev->dev.platform_data;
 	struct fb_info *info = dev_get_drvdata(&pdev->dev);
 	struct imxfb_info *fbi = info->par;
-	struct imx_fb_videomode *m;
-	int i;
+	struct device_node *np;
 
 	pr_debug("%s\n",__func__);
 
@@ -795,41 +823,96 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
 	info->fbops			= &imxfb_ops;
 	info->flags			= FBINFO_FLAG_DEFAULT |
 					  FBINFO_READS_FAST;
-	info->var.grayscale		= pdata->cmap_greyscale;
-	fbi->cmap_inverse		= pdata->cmap_inverse;
-	fbi->cmap_static		= pdata->cmap_static;
-	fbi->lscr1			= pdata->lscr1;
-	fbi->dmacr			= pdata->dmacr;
-	fbi->pwmr			= pdata->pwmr;
-	fbi->lcd_power			= pdata->lcd_power;
-	fbi->backlight_power		= pdata->backlight_power;
-
-	for (i = 0, m = &pdata->mode[0]; i < pdata->num_modes; i++, m++)
-		info->fix.smem_len = max_t(size_t, info->fix.smem_len,
-				m->mode.xres * m->mode.yres * m->bpp / 8);
+	if (pdata) {
+		info->var.grayscale		= pdata->cmap_greyscale;
+		fbi->cmap_inverse		= pdata->cmap_inverse;
+		fbi->cmap_static		= pdata->cmap_static;
+		fbi->lscr1			= pdata->lscr1;
+		fbi->dmacr			= pdata->dmacr;
+		fbi->pwmr			= pdata->pwmr;
+		fbi->lcd_power			= pdata->lcd_power;
+		fbi->backlight_power		= pdata->backlight_power;
+	} else {
+		np = pdev->dev.of_node;
+		info->var.grayscale = of_property_read_bool(np,
+						"cmap-greyscale");
+		fbi->cmap_inverse = of_property_read_bool(np, "cmap-inverse");
+		fbi->cmap_static = of_property_read_bool(np, "cmap-static");
+
+		fbi->lscr1 = IMXFB_LSCR1_DEFAULT;
+		if (of_property_read_bool(np, "dmacr-eukrea"))
+			fbi->dmacr = IMXFB_DMACR_EUKREA_DEFAULT;
+		else
+			fbi->dmacr = IMXFB_DMACR_DEFAULT;
+
+		/* These two function pointers could be used by some specific
+		 * platforms. */
+		fbi->lcd_power = NULL;
+		fbi->backlight_power = NULL;
+	}
+
+	return 0;
+}
+
+static int imxfb_of_read_mode(struct device *dev, struct device_node *np,
+		struct imx_fb_videomode *imxfb_mode)
+{
+	int ret;
+	struct fb_videomode *of_mode = &imxfb_mode->mode;
+	u32 bpp;
+	u32 pcr;
+
+	ret = of_property_read_string(np, "model", &of_mode->name);
+	if (ret)
+		of_mode->name = NULL;
+
+	ret = of_get_fb_videomode(np, of_mode, OF_USE_NATIVE_MODE);
+	if (ret) {
+		dev_err(dev, "Failed to get videomode from DT\n");
+		return ret;
+	}
+
+	ret = of_property_read_u32(np, "fsl,bpp", &bpp);
+	ret |= of_property_read_u32(np, "fsl,pcr", &pcr);
+
+	if (ret) {
+		dev_err(dev, "Failed to read bpp and pcr from DT\n");
+		return -EINVAL;
+	}
+
+	if (bpp < 1 || bpp > 255) {
+		dev_err(dev, "Bits per pixel have to be between 1 and 255\n");
+		return -EINVAL;
+	}
+
+	imxfb_mode->bpp = bpp;
+	imxfb_mode->pcr = pcr;
 
 	return 0;
 }
 
-static int __init imxfb_probe(struct platform_device *pdev)
+static int imxfb_probe(struct platform_device *pdev)
 {
 	struct imxfb_info *fbi;
 	struct fb_info *info;
 	struct imx_fb_platform_data *pdata;
 	struct resource *res;
+	struct imx_fb_videomode *m;
+	const struct of_device_id *of_id;
 	int ret, i;
+	int bytes_per_pixel;
 
 	dev_info(&pdev->dev, "i.MX Framebuffer driver\n");
 
+	of_id = of_match_device(imxfb_of_dev_id, &pdev->dev);
+	if (of_id)
+		pdev->id_entry = of_id->data;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		return -ENODEV;
 
 	pdata = pdev->dev.platform_data;
-	if (!pdata) {
-		dev_err(&pdev->dev,"No platform_data available\n");
-		return -ENOMEM;
-	}
 
 	info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
 	if (!info)
@@ -837,15 +920,55 @@ static int __init imxfb_probe(struct platform_device *pdev)
 
 	fbi = info->par;
 
-	if (!fb_mode)
-		fb_mode = pdata->mode[0].mode.name;
-
 	platform_set_drvdata(pdev, info);
 
 	ret = imxfb_init_fbinfo(pdev);
 	if (ret < 0)
 		goto failed_init;
 
+	if (pdata) {
+		if (!fb_mode)
+			fb_mode = pdata->mode[0].mode.name;
+
+		fbi->mode = pdata->mode;
+		fbi->num_modes = pdata->num_modes;
+	} else {
+		struct device_node *display_np;
+		fb_mode = NULL;
+
+		display_np = of_parse_phandle(pdev->dev.of_node, "display", 0);
+		if (!display_np) {
+			dev_err(&pdev->dev, "No display defined in devicetree\n");
+			ret = -EINVAL;
+			goto failed_of_parse;
+		}
+
+		/*
+		 * imxfb does not support more modes, we choose only the native
+		 * mode.
+		 */
+		fbi->num_modes = 1;
+
+		fbi->mode = devm_kzalloc(&pdev->dev,
+				sizeof(struct imx_fb_videomode), GFP_KERNEL);
+		if (!fbi->mode) {
+			ret = -ENOMEM;
+			goto failed_of_parse;
+		}
+
+		ret = imxfb_of_read_mode(&pdev->dev, display_np, fbi->mode);
+		if (ret)
+			goto failed_of_parse;
+	}
+
+	/* Calculate maximum bytes used per pixel. In most cases this should
+	 * be the same as m->bpp/8 */
+	m = &fbi->mode[0];
+	bytes_per_pixel = (m->bpp + 7) / 8;
+	for (i = 0; i < fbi->num_modes; i++, m++)
+		info->fix.smem_len = max_t(size_t, info->fix.smem_len,
+				m->mode.xres * m->mode.yres * bytes_per_pixel);
+
 	res = request_mem_region(res->start, resource_size(res),
 				DRIVER_NAME);
 	if (!res) {
@@ -878,7 +1001,8 @@ static int __init imxfb_probe(struct platform_device *pdev)
 		goto failed_ioremap;
 	}
 
-	if (!pdata->fixed_screen_cpu) {
+	/* Seems not being used by anyone, so no support for oftree */
+	if (!pdata || !pdata->fixed_screen_cpu) {
 		fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
 		fbi->map_cpu = dma_alloc_writecombine(&pdev->dev,
 				fbi->map_size, &fbi->map_dma, GFP_KERNEL);
@@ -903,18 +1027,16 @@ static int __init imxfb_probe(struct platform_device *pdev)
 		info->fix.smem_start = fbi->screen_dma;
 	}
 
-	if (pdata->init) {
+	if (pdata && pdata->init) {
 		ret = pdata->init(fbi->pdev);
 		if (ret)
 			goto failed_platform_init;
 	}
 
-	fbi->mode = pdata->mode;
-	fbi->num_modes = pdata->num_modes;
 
 	INIT_LIST_HEAD(&info->modelist);
-	for (i = 0; i < pdata->num_modes; i++)
-		fb_add_videomode(&pdata->mode[i].mode, &info->modelist);
+	for (i = 0; i < fbi->num_modes; i++)
+		fb_add_videomode(&fbi->mode[i].mode, &info->modelist);
 
 	/*
 	 * This makes sure that our colour bitfield
@@ -944,10 +1066,10 @@ static int __init imxfb_probe(struct platform_device *pdev)
 failed_register:
 	fb_dealloc_cmap(&info->cmap);
 failed_cmap:
-	if (pdata->exit)
+	if (pdata && pdata->exit)
 		pdata->exit(fbi->pdev);
 failed_platform_init:
-	if (!pdata->fixed_screen_cpu)
+	if (pdata && !pdata->fixed_screen_cpu)
 		dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
 			fbi->map_dma);
 failed_map:
@@ -956,6 +1078,7 @@ failed_ioremap:
 failed_getclock:
 	release_mem_region(res->start, resource_size(res));
 failed_req:
+failed_of_parse:
 	kfree(info->pseudo_palette);
 failed_init:
 	platform_set_drvdata(pdev, NULL);
@@ -980,7 +1103,7 @@ static int imxfb_remove(struct platform_device *pdev)
 	unregister_framebuffer(info);
 
 	pdata = pdev->dev.platform_data;
-	if (pdata->exit)
+	if (pdata && pdata->exit)
 		pdata->exit(fbi->pdev);
 
 	fb_dealloc_cmap(&info->cmap);
@@ -1009,6 +1132,7 @@ static struct platform_driver imxfb_driver = {
 	.shutdown	= imxfb_shutdown,
 	.driver		= {
 		.name	= DRIVER_NAME,
+		.of_match_table = imxfb_of_dev_id,
 	},
 	.id_table	= imxfb_devtype,
 };
-- 
1.8.1.5


^ permalink raw reply related

* [PATCH v3 1/2] imxfb: Set alpha value of the framebuffer
From: Markus Pargmann @ 2013-04-05 10:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1365157876-1757-1-git-send-email-mpa@pengutronix.de>

From: Christian Hemp <c.hemp@phytec.de>

Based on Sascha Hauer's patch i.MX27 clock: Do not disable lcd clocks during
startup.
This patch gives a interface to chance the alphavalue of the framebuffer.

Signed-off-by: Christian Hemp <c.hemp@phytec.de>

rebased to 3.7
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 drivers/video/imxfb.c                     | 35 +++++++++++++++++++++++++++++++
 include/linux/platform_data/video-imxfb.h |  3 +++
 2 files changed, 38 insertions(+)

diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 0abf2bf..ef2b587 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -31,6 +31,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
 #include <linux/math64.h>
+#include <linux/uaccess.h>
 
 #include <linux/platform_data/video-imxfb.h>
 
@@ -112,6 +113,10 @@
 #define LCDISR_EOF	(1<<1)
 #define LCDISR_BOF	(1<<0)
 
+#define LCDC_LGWCR	0x64
+#define LGWCR_GWAV(alpha)	(((alpha) & 0xff) << 24)
+#define LGWCR_GWE	(1 << 22)
+
 /* Used fb-mode. Can be set on kernel command line, therefore file-static. */
 static const char *fb_mode;
 
@@ -610,6 +615,35 @@ static int imxfb_blank(int blank, struct fb_info *info)
 	return 0;
 }
 
+static int imxfb_ioctl(struct fb_info *info, unsigned int cmd,
+			unsigned long arg)
+{
+	struct imxfb_info *fbi = info->par;
+	int alpha, ret = 0;
+	unsigned int tmp;
+
+	switch (cmd) {
+	case IMXFB_ALPHA:
+		if (get_user(alpha, (int __user *)arg)) {
+			ret = -EFAULT;
+		} else {
+			tmp = readl(fbi->regs + LCDC_LGWCR);
+			tmp &= ~LGWCR_GWAV(0xff);
+			tmp |= LGWCR_GWAV(alpha);
+			if (!alpha)
+				tmp &= ~LGWCR_GWE;
+			else
+				tmp |= LGWCR_GWE;
+			writel(tmp , fbi->regs + LCDC_LGWCR);
+		}
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
 static struct fb_ops imxfb_ops = {
 	.owner		= THIS_MODULE,
 	.fb_check_var	= imxfb_check_var,
@@ -619,6 +653,7 @@ static struct fb_ops imxfb_ops = {
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
 	.fb_blank	= imxfb_blank,
+	.fb_ioctl	= imxfb_ioctl,
 };
 
 /*
diff --git a/include/linux/platform_data/video-imxfb.h b/include/linux/platform_data/video-imxfb.h
index 9de8f06..ce3875f 100644
--- a/include/linux/platform_data/video-imxfb.h
+++ b/include/linux/platform_data/video-imxfb.h
@@ -51,6 +51,9 @@
 #define DMACR_HM(x)	(((x) & 0xf) << 16)
 #define DMACR_TM(x)	((x) & 0xf)
 
+#define IMXFB_IOW(num, dtype)	_IOW('I', num, dtype)
+#define IMXFB_ALPHA		IMXFB_IOW(31, int)
+
 struct imx_fb_videomode {
 	struct fb_videomode mode;
 	u32 pcr;
-- 
1.8.1.5


^ permalink raw reply related

* [PATCH v3 0/2] video: imxfb DT support
From: Markus Pargmann @ 2013-04-05 10:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This series adds DT support for imxfb. Changes in v3 are
described in the notes of patch 2.

Regards,

Markus


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox