Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* Re: [PATCH v2] video: mx3fb: Add backlight support
From: Tomi Valkeinen @ 2014-05-08 10:48 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1399273010-24706-1-git-send-email-alexander.stein@systec-electronic.com>

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

On 08/05/14 13:47, Tomi Valkeinen wrote:
> Hi,
> 
> On 05/05/14 09:56, Alexander Stein wrote:
>> Signed-off-by: Alexander Stein <alexander.stein@systec-electronic.com>
>> ---
> 
> Please always have a commit description, even if it's more or less the
> same as the subject.

Oh, and I'd rather have a bit more explanation than "add backlight
support". The current driver seems to have some backlight code. So what
are you actually adding with this patch? Etc.

 Tomi



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

^ permalink raw reply

* Re: [PATCH] video: Kconfig: Add a dependency to the Goldfish framebuffer driver
From: Tomi Valkeinen @ 2014-05-08 10:50 UTC (permalink / raw)
  To: linux-fbdev

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

On 23/04/14 13:42, Jean Delvare wrote:
> All other Goldfish drivers depend on GOLDFISH, I see no reason why the
> framebuffer driver would be an exception.
> 
> Signed-off-by: Jean Delvare <jdelvare@suse.de>
> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---
>  drivers/video/fbdev/Kconfig |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> --- linux-3.15-rc2.orig/drivers/video/fbdev/Kconfig	2014-04-22 14:20:30.949107522 +0200
> +++ linux-3.15-rc2/drivers/video/fbdev/Kconfig	2014-04-23 11:51:17.163933232 +0200
> @@ -2169,7 +2169,7 @@ config FB_XILINX
>  
>  config FB_GOLDFISH
>  	tristate "Goldfish Framebuffer"
> -	depends on FB && HAS_DMA
> +	depends on FB && HAS_DMA && (GOLDFISH || COMPILE_TEST)
>  	select FB_CFB_FILLRECT
>  	select FB_CFB_COPYAREA
>  	select FB_CFB_IMAGEBLIT
> 
> 

Queued for 3.16.

 Tomi



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

^ permalink raw reply

* Re: [PATCH] fbcon: Fix memory leak in con2fb_release_oldinfo()
From: Tomi Valkeinen @ 2014-05-08 10:55 UTC (permalink / raw)
  To: Masami Ichikawa, plagnioj, udknight, gregkh, keithp,
	mika.kuoppala, viresh.kumar, linux-kernel, linux-fbdev
In-Reply-To: <1398263722-10436-1-git-send-email-masami256@gmail.com>

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

On 23/04/14 17:35, Masami Ichikawa wrote:
> kmemleak reported a memory leak as below.
> 
> unreferenced object 0xffff8800dab6d8d8 (size 96):
>   comm "swapper/0", pid 1, jiffies 4294877598 (age 38.483s)
>   hex dump (first 32 bytes):
>     00 00 00 00 00 01 00 00 08 00 00 00 10 00 00 00  ................
>     07 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00  ................
>   backtrace:
>     [<ffffffff814e8f2e>] kmemleak_alloc+0x4e/0xb0
>     [<ffffffff811a0600>] __kmalloc+0x280/0x320
>     [<ffffffff81309b61>] soft_cursor+0x231/0x290
>     [<ffffffff81309393>] bit_cursor+0x613/0x650
>     [<ffffffff8130556b>] fbcon_cursor+0x13b/0x1c0
>     [<ffffffff813755f8>] hide_cursor+0x28/0xa0
>     [<ffffffff81376e98>] redraw_screen+0x168/0x240
>     [<ffffffff81303891>] fbcon_prepare_logo+0x381/0x420
>     [<ffffffff81303c7e>] fbcon_init+0x34e/0x590
>     [<ffffffff81375828>] visual_init+0xb8/0x120
>     [<ffffffff81377c93>] do_bind_con_driver+0x163/0x380
>     [<ffffffff81378494>] do_take_over_console+0x114/0x1c0
>     [<ffffffff81303f23>] do_fbcon_takeover+0x63/0xd0
>     [<ffffffff813086dd>] fbcon_event_notify+0x68d/0x7e0
>     [<ffffffff814ff7ac>] notifier_call_chain+0x4c/0x70
>     [<ffffffff8108c85d>] __blocking_notifier_call_chain+0x4d/0x70
> 
> This memory leak cause is, fbcon_ops's cursor_src is allocated in
> soft_cursor() but not released in con2fb_release_oldinfo().
> so, cursor_src is needed to be released when oldinfo is going to be
> released.
> 
> Signed-off-by: Masami Ichikawa <masami256@gmail.com>
> ---
>  drivers/video/console/fbcon.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
> index f447734..57b1d44 100644
> --- a/drivers/video/console/fbcon.c
> +++ b/drivers/video/console/fbcon.c
> @@ -748,6 +748,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
>  		fbcon_del_cursor_timer(oldinfo);
>  		kfree(ops->cursor_state.mask);
>  		kfree(ops->cursor_data);
> +		kfree(ops->cursor_src);
>  		kfree(ops->fontbuffer);
>  		kfree(oldinfo->fbcon_par);
>  		oldinfo->fbcon_par = NULL;
> 

Thanks, queued for 3.16.

 Tomi



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

^ permalink raw reply

* [PATCH v6 1/2] video: ARM CLCD: Add DT support
From: Pawel Moll @ 2014-05-08 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds basic DT bindings for the PL11x CLCD cells
and make their fbdev driver use them.

Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
Changes since v5:
- realised that dma_alloc_writecombine() is a arm-specific function;
  replaced with generic dma_alloc_coherent()/dma_mmap_writecombine()

Changes since v4:
- simplified the pads description property and made it optional

Changes since v3:
- changed wording and order of interrupt-names and interrupts
  properties documentation
- changed wording of arm,pl11x,framebuffer-base property
  documentation
- cleaned up binding documentation indentation

Changes since v2:
- replaced video-ram phandle with arm,pl11x,framebuffer-base
- replaced panel-* properties with arm,pl11x,panel-data-pads
- replaced max-framebuffer-size with max-memory-bandwidth
- modified clcdfb_of_init_tft_panel() to use the pads
  data and take differences between PL110 and PL110 into
  account

Changes since v1:
- minor code cleanups as suggested by Sylwester Nawrocki

 .../devicetree/bindings/video/arm,pl11x.txt        |  83 ++++++++
 drivers/video/fbdev/Kconfig                        |   2 +
 drivers/video/fbdev/amba-clcd.c                    | 219 +++++++++++++++++++++
 3 files changed, 304 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/arm,pl11x.txt

diff --git a/Documentation/devicetree/bindings/video/arm,pl11x.txt b/Documentation/devicetree/bindings/video/arm,pl11x.txt
new file mode 100644
index 0000000..75da7b7
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/arm,pl11x.txt
@@ -0,0 +1,83 @@
+* ARM PrimeCell Color LCD Controller PL110/PL111
+
+See also Documentation/devicetree/bindings/arm/primecell.txt
+
+Required properties:
+
+- compatible: must be one of:
+	"arm,pl110", "arm,primecell"
+	"arm,pl111", "arm,primecell"
+
+- reg: base address and size of the control registers block
+
+- interrupt-names: either the single entry "combined" representing a
+	combined interrupt output (CLCDINTR), or the four entries
+	"mbe", "vcomp", "lnbu", "fuf" representing the individual
+	CLCDMBEINTR, CLCDVCOMPINTR, CLCDLNBUINTR, CLCDFUFINTR interrupts
+
+- interrupts: contains an interrupt specifier for each entry in
+	interrupt-names
+
+- clocks-names: should contain "clcdclk" and "apb_pclk"
+
+- clocks: contains phandle and clock specifier pairs for the entries
+	in the clock-names property. See
+	Documentation/devicetree/binding/clock/clock-bindings.txt
+
+Optional properties:
+
+- arm,pl11x,framebuffer-base: a pair of two 32-bit values, address and size,
+	defining the framebuffer that must be used; if not present, the
+	framebuffer may be located anywhere in the memory
+
+- arm,pl11x,tft-r0g0b0-pads: when connected to a TFT panel, an array of three
+	32-bit values, defining the way CLD pads are wired up; this implicitly
+	defines available color modes, for example:
+	- PL111 TFT 4:4:4 panel:
+		arm,pl11x,tft-r0g0b0-pads = <4 15 20>;
+	- PL110 TFT (1:)5:5:5 panel:
+		arm,pl11x,tft-r0g0b0-pads = <1 7 13>;
+	- PL111 TFT (1:)5:5:5 panel:
+		arm,pl11x,tft-r0g0b0-pads = <3 11 19>;
+	- PL111 TFT 5:6:5 panel:
+		arm,pl11x,tft-r0g0b0-pads = <3 10 19>;
+	- PL110 and PL111 TFT 8:8:8 panel:
+		arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+	- PL110 and PL111 TFT 8:8:8 panel, R & B components swapped:
+		arm,pl11x,tft-r0g0b0-pads = <16 8 0>;
+
+- max-memory-bandwidth: maximum bandwidth in bytes per second that the
+	cell's memory interface can handle
+
+- display-timings: standard display timings sub-node, defining possible
+	video modes of a connected panel; for details see
+	Documentation/devicetree/bindings/video/display-timing.txt
+
+Example:
+
+	clcd@1f0000 {
+		compatible = "arm,pl111", "arm,primecell";
+		reg = <0x1f0000 0x1000>;
+		interrupt-names = "combined";
+		interrupts = <14>;
+		clock-names = "clcdclk", "apb_pclk";
+		clocks = <&v2m_oscclk1>, <&smbclk>;
+
+		arm,pl11x,framebuffer-base = <0x18000000 0x00800000>;
+		arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+		max-memory-bandwidth = <36864000>; /* bps, 640x480@60 16bpp */
+		display-timings {
+			native-mode = <&v2m_clcd_timing0>;
+			v2m_clcd_timing0: vga {
+				clock-frequency = <25175000>;
+				hactive = <640>;
+				hback-porch = <40>;
+				hfront-porch = <24>;
+				hsync-len = <96>;
+				vactive = <480>;
+				vback-porch = <32>;
+				vfront-porch = <11>;
+				vsync-len = <2>;
+			};
+		};
+	};
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index e1f4727..06045d8 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -280,6 +280,8 @@ config FB_ARMCLCD
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
+	select FB_MODE_HELPERS if OF
+	select VIDEOMODE_HELPERS if OF
 	help
 	  This framebuffer device driver is for the ARM PrimeCell PL110
 	  Colour LCD controller.  ARM PrimeCells provide the building
diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
index 14d6b37..c1f2eaa 100644
--- a/drivers/video/fbdev/amba-clcd.c
+++ b/drivers/video/fbdev/amba-clcd.c
@@ -26,6 +26,11 @@
 #include <linux/amba/clcd.h>
 #include <linux/clk.h>
 #include <linux/hardirq.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <video/of_display_timing.h>
+#include <video/of_videomode.h>
 
 #include <asm/sizes.h>
 
@@ -543,6 +548,217 @@ static int clcdfb_register(struct clcd_fb *fb)
 	return ret;
 }
 
+#ifdef CONFIG_OF
+static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0)
+{
+	static struct {
+		unsigned int part;
+		u32 r0, g0, b0;
+		u32 caps;
+	} panels[] = {
+		{ 0x110, 1,  7, 13, CLCD_CAP_5551 },
+		{ 0x110, 0,  8, 16, CLCD_CAP_888 },
+		{ 0x111, 4, 14, 20, CLCD_CAP_444 },
+		{ 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 },
+		{ 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 |
+				    CLCD_CAP_565 },
+		{ 0x111, 0,  8, 16, CLCD_CAP_444 | CLCD_CAP_5551 |
+				    CLCD_CAP_565 | CLCD_CAP_888 },
+	};
+	int i;
+
+	/* Bypass pixel clock divider, data output on the falling edge */
+	fb->panel->tim2 = TIM2_BCD | TIM2_IPC;
+
+	/* TFT display, vert. comp. interrupt at the start of the back porch */
+	fb->panel->cntl |= CNTL_LCDTFT | CNTL_LCDVCOMP(1);
+
+	fb->panel->caps = 0;
+
+	/* Match the setup with known variants */
+	for (i = 0; i < ARRAY_SIZE(panels) && !fb->panel->caps; i++) {
+		if (amba_part(fb->dev) != panels[i].part)
+			continue;
+		if (g0 != panels[i].g0)
+			continue;
+		if (r0 = panels[i].r0 && b0 = panels[i].b0)
+			fb->panel->caps = panels[i].caps & CLCD_CAP_RGB;
+		if (r0 = panels[i].b0 && b0 = panels[i].r0)
+			fb->panel->caps = panels[i].caps & CLCD_CAP_BGR;
+	}
+
+	return fb->panel->caps ? 0 : -EINVAL;
+}
+
+static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode)
+{
+	return snprintf(buf, size, "%ux%u@%u", mode->xres, mode->yres,
+			mode->refresh);
+}
+
+static int clcdfb_of_init_display(struct clcd_fb *fb)
+{
+	struct device_node *node = fb->dev->dev.of_node;
+	int err, len;
+	char *mode_name;
+	u32 max_bandwidth;
+	u32 tft_r0b0g0[3];
+
+	fb->panel = devm_kzalloc(&fb->dev->dev, sizeof(*fb->panel), GFP_KERNEL);
+	if (!fb->panel)
+		return -ENOMEM;
+
+	err = of_get_fb_videomode(node, &fb->panel->mode, OF_USE_NATIVE_MODE);
+	if (err)
+		return err;
+
+	len = clcdfb_snprintf_mode(NULL, 0, &fb->panel->mode);
+	mode_name = devm_kzalloc(&fb->dev->dev, len + 1, GFP_KERNEL);
+	clcdfb_snprintf_mode(mode_name, len + 1, &fb->panel->mode);
+	fb->panel->mode.name = mode_name;
+
+	err = of_property_read_u32(node, "max-memory-bandwidth",
+			&max_bandwidth);
+	if (!err)
+		fb->panel->bpp = 8 * max_bandwidth / (fb->panel->mode.xres *
+				fb->panel->mode.yres * fb->panel->mode.refresh);
+	else
+		fb->panel->bpp = 32;
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	fb->panel->cntl |= CNTL_BEBO;
+#endif
+	fb->panel->width = -1;
+	fb->panel->height = -1;
+
+	if (of_property_read_u32_array(node, "arm,pl11x,tft-r0g0b0-pads",
+			tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) = 0)
+		return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0],
+				 tft_r0b0g0[1],  tft_r0b0g0[2]);
+
+	return -ENOENT;
+}
+
+static int clcdfb_of_vram_setup(struct clcd_fb *fb)
+{
+	int err;
+	u32 values[2];
+	phys_addr_t phys_base;
+	size_t size;
+
+	err = clcdfb_of_init_display(fb);
+	if (err)
+		return err;
+
+	err = of_property_read_u32_array(fb->dev->dev.of_node,
+			"arm,pl11x,framebuffer-base",
+			values, ARRAY_SIZE(values));
+	if (err)
+		return err;
+
+	phys_base = values[0];
+	size = values[1];
+
+	fb->fb.screen_base = ioremap(phys_base, size);
+	if (!fb->fb.screen_base)
+		return -ENOMEM;
+
+	fb->fb.fix.smem_start = phys_base;
+	fb->fb.fix.smem_len = size;
+
+	return 0;
+}
+
+static int clcdfb_of_vram_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+	unsigned long off, user_size, kernel_size;
+
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
+	user_size = vma->vm_end - vma->vm_start;
+	kernel_size = fb->fb.fix.smem_len;
+
+	if (off >= kernel_size || user_size > (kernel_size - off))
+		return -ENXIO;
+
+	return remap_pfn_range(vma, vma->vm_start,
+			__phys_to_pfn(fb->fb.fix.smem_start) + vma->vm_pgoff,
+			user_size,
+			pgprot_writecombine(vma->vm_page_prot));
+}
+
+static void clcdfb_of_vram_remove(struct clcd_fb *fb)
+{
+	iounmap(fb->fb.screen_base);
+}
+
+static int clcdfb_of_dma_setup(struct clcd_fb *fb)
+{
+	unsigned long framesize;
+	dma_addr_t dma;
+	int err;
+
+	err = clcdfb_of_init_display(fb);
+	if (err)
+		return err;
+
+	framesize = fb->panel->mode.xres * fb->panel->mode.yres *
+			fb->panel->bpp / 8;
+	fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize,
+			&dma, GFP_KERNEL);
+	if (!fb->fb.screen_base)
+		return -ENOMEM;
+
+	fb->fb.fix.smem_start = dma;
+	fb->fb.fix.smem_len = framesize;
+
+	return 0;
+}
+
+static int clcdfb_of_dma_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+	return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base,
+			fb->fb.fix.smem_start, fb->fb.fix.smem_len);
+}
+
+static void clcdfb_of_dma_remove(struct clcd_fb *fb)
+{
+	dma_free_coherent(&fb->dev->dev, fb->fb.fix.smem_len,
+			fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
+{
+	struct clcd_board *board = devm_kzalloc(&dev->dev, sizeof(*board),
+			GFP_KERNEL);
+	struct device_node *node = dev->dev.of_node;
+
+	if (!board)
+		return NULL;
+
+	board->name = of_node_full_name(node);
+	board->caps = CLCD_CAP_ALL;
+	board->check = clcdfb_check;
+	board->decode = clcdfb_decode;
+	if (of_find_property(node, "arm,pl11x,framebuffer-base", NULL)) {
+		board->setup = clcdfb_of_vram_setup;
+		board->mmap = clcdfb_of_vram_mmap;
+		board->remove = clcdfb_of_vram_remove;
+	} else {
+		board->setup = clcdfb_of_dma_setup;
+		board->mmap = clcdfb_of_dma_mmap;
+		board->remove = clcdfb_of_dma_remove;
+	}
+
+	return board;
+}
+#else
+static struct clcd_board *clcdfb_of_get_board(struct amba_dev *dev)
+{
+	return NULL;
+}
+#endif
+
 static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
 {
 	struct clcd_board *board = dev_get_platdata(&dev->dev);
@@ -550,6 +766,9 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
 	int ret;
 
 	if (!board)
+		board = clcdfb_of_get_board(dev);
+
+	if (!board)
 		return -EINVAL;
 
 	ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
-- 
1.9.1


^ permalink raw reply related

* [PATCH v6 2/2] ARM: vexpress: Add CLCD Device Tree properties
From: Pawel Moll @ 2014-05-08 11:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1399546830-2931-1-git-send-email-pawel.moll@arm.com>

... for V2M-P1 motherboard CLCD (limited to 640x480 16bpp and using
dedicated video RAM bank) and for V2P-CA9 (up to 1024x768 16bpp).

Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
 arch/arm/boot/dts/vexpress-v2m-rs1.dtsi | 21 ++++++++++++++++++++-
 arch/arm/boot/dts/vexpress-v2m.dtsi     | 21 ++++++++++++++++++++-
 arch/arm/boot/dts/vexpress-v2p-ca9.dts  | 18 ++++++++++++++++++
 3 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
index ac870fb..c95a4cb 100644
--- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
@@ -230,9 +230,28 @@
 			clcd@1f0000 {
 				compatible = "arm,pl111", "arm,primecell";
 				reg = <0x1f0000 0x1000>;
+				interrupt-names = "combined";
 				interrupts = <14>;
 				clocks = <&v2m_oscclk1>, <&smbclk>;
 				clock-names = "clcdclk", "apb_pclk";
+
+				arm,pl11x,framebuffer-base = <0x18000000 0x00800000>;
+				arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+				max-memory-bandwidth = <36864000>; /* Bps, 640x480@60 16bpp */
+				display-timings {
+					native-mode = <&v2m_clcd_timing0>;
+					v2m_clcd_timing0: vga {
+						clock-frequency = <25175000>;
+						hactive = <640>;
+						hback-porch = <40>;
+						hfront-porch = <24>;
+						hsync-len = <96>;
+						vactive = <480>;
+						vback-porch = <32>;
+						vfront-porch = <11>;
+						vsync-len = <2>;
+					};
+				};
 			};
 		};
 
@@ -282,7 +301,7 @@
 				/* CLCD clock */
 				compatible = "arm,vexpress-osc";
 				arm,vexpress-sysreg,func = <1 1>;
-				freq-range = <23750000 63500000>;
+				freq-range = <23750000 65000000>;
 				#clock-cells = <0>;
 				clock-output-names = "v2m:oscclk1";
 			};
diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi
index f142036..9224834 100644
--- a/arch/arm/boot/dts/vexpress-v2m.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m.dtsi
@@ -229,9 +229,28 @@
 			clcd@1f000 {
 				compatible = "arm,pl111", "arm,primecell";
 				reg = <0x1f000 0x1000>;
+				interrupt-names = "combined";
 				interrupts = <14>;
 				clocks = <&v2m_oscclk1>, <&smbclk>;
 				clock-names = "clcdclk", "apb_pclk";
+
+				arm,pl11x,framebuffer-base = <0x4c000000 0x00800000>;
+				arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+				max-memory-bandwidth = <36864000>; /* Bps, 640x480@60 16bpp */
+				display-timings {
+					native-mode = <&v2m_clcd_timing0>;
+					v2m_clcd_timing0: vga {
+						clock-frequency = <25175000>;
+						hactive = <640>;
+						hback-porch = <40>;
+						hfront-porch = <24>;
+						hsync-len = <96>;
+						vactive = <480>;
+						vback-porch = <32>;
+						vfront-porch = <11>;
+						vsync-len = <2>;
+					};
+				};
 			};
 		};
 
@@ -281,7 +300,7 @@
 				/* CLCD clock */
 				compatible = "arm,vexpress-osc";
 				arm,vexpress-sysreg,func = <1 1>;
-				freq-range = <23750000 63500000>;
+				freq-range = <23750000 65000000>;
 				#clock-cells = <0>;
 				clock-output-names = "v2m:oscclk1";
 			};
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
index 62d9b22..ed4f223 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
@@ -70,9 +70,27 @@
 	clcd@10020000 {
 		compatible = "arm,pl111", "arm,primecell";
 		reg = <0x10020000 0x1000>;
+		interrupt-names = "combined";
 		interrupts = <0 44 4>;
 		clocks = <&oscclk1>, <&oscclk2>;
 		clock-names = "clcdclk", "apb_pclk";
+
+		arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+		max-memory-bandwidth = <94371840>; /* Bps, 1024x768@60 16bpp */
+		display-timings {
+			native-mode = <&clcd_timing0>;
+			clcd_timing0: xga {
+				clock-frequency = <63500127>;
+				hactive = <1024>;
+				hback-porch = <152>;
+				hfront-porch = <48>;
+				hsync-len = <104>;
+				vactive = <768>;
+				vback-porch = <23>;
+				vfront-porch = <3>;
+				vsync-len = <4>;
+			};
+		};
 	};
 
 	memory-controller@100e0000 {
-- 
1.9.1


^ permalink raw reply related

* Re: [PATCH v6 1/2] video: ARM CLCD: Add DT support
From: Pawel Moll @ 2014-05-08 11:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1399546830-2931-1-git-send-email-pawel.moll@arm.com>

On Thu, 2014-05-08 at 12:00 +0100, Pawel Moll wrote:
> This patch adds basic DT bindings for the PL11x CLCD cells
> and make their fbdev driver use them.
> 
> Signed-off-by: Pawel Moll <pawel.moll@arm.com>

Russell,

I've added it to your patch system as 8005/2. If you were so kind to
have a look, I would appreciate either ack or nak.

Thanks!

Pawel


^ permalink raw reply

* [PATCH v3] video: mx3fb: Add backlight control support
From: Alexander Stein @ 2014-05-08 14:38 UTC (permalink / raw)
  To: linux-fbdev

This patch add backlight control support to allow dimming the backlight
using the internal PWM. Currently the brightness is set fixed to a
maximum of 255.

Signed-off-by: Alexander Stein <alexander.stein@systec-electronic.com>
---
Changes in v3:
* Add a more descriptive commit message

Changes in v2:
* rebased to v3.15-rc4

 drivers/video/fbdev/mx3fb.c | 98 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)

diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c
index 142e860..10a7244 100644
--- a/drivers/video/fbdev/mx3fb.c
+++ b/drivers/video/fbdev/mx3fb.c
@@ -27,6 +27,7 @@
 #include <linux/clk.h>
 #include <linux/mutex.h>
 #include <linux/dma/ipu-dma.h>
+#include <linux/backlight.h>
 
 #include <linux/platform_data/dma-imx.h>
 #include <linux/platform_data/video-mx3fb.h>
@@ -34,6 +35,12 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
+#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || \
+	(defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) && \
+		defined(CONFIG_MX3FB_MODULE))
+#define PWM_BACKLIGHT_AVAILABLE
+#endif
+
 #define MX3FB_NAME		"mx3_sdc_fb"
 
 #define MX3FB_REG_OFFSET	0xB4
@@ -242,6 +249,10 @@ struct mx3fb_data {
 	spinlock_t		lock;
 	struct device		*dev;
 
+#ifdef PWM_BACKLIGHT_AVAILABLE
+	struct backlight_device	*bl;
+#endif
+
 	uint32_t		h_start_width;
 	uint32_t		v_start_width;
 	enum disp_data_mapping	disp_data_fmt;
@@ -271,6 +282,74 @@ struct mx3fb_info {
 	struct fb_var_screeninfo	cur_var; /* current var info */
 };
 
+static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value);
+
+#ifdef PWM_BACKLIGHT_AVAILABLE
+static u32 sdc_get_brightness(struct mx3fb_data *mx3fb);
+
+static int mx3fb_bl_get_brightness(struct backlight_device *bl)
+{
+	struct mx3fb_data *fbd = bl_get_data(bl);
+
+	return sdc_get_brightness(fbd);
+}
+
+static int mx3fb_bl_update_status(struct backlight_device *bl)
+{
+	struct mx3fb_data *fbd = bl_get_data(bl);
+	int brightness = bl->props.brightness;
+
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+	if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	fbd->backlight_level = (fbd->backlight_level & ~0xFF) | brightness;
+
+	sdc_set_brightness(fbd, fbd->backlight_level);
+
+	return 0;
+}
+
+static const struct backlight_ops mx3fb_lcdc_bl_ops = {
+	.update_status = mx3fb_bl_update_status,
+	.get_brightness = mx3fb_bl_get_brightness,
+};
+
+static void mx3fb_init_backlight(struct mx3fb_data *fbd)
+{
+	struct backlight_properties props;
+	struct backlight_device	*bl;
+
+	if (fbd->bl)
+		return;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.max_brightness = 0xff;
+	props.type = BACKLIGHT_RAW;
+	sdc_set_brightness(fbd, fbd->backlight_level);
+
+	bl = backlight_device_register("mx3fb-bl", fbd->dev, fbd,
+				       &mx3fb_lcdc_bl_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(fbd->dev, "error %ld on backlight register\n",
+				PTR_ERR(bl));
+		return;
+	}
+
+	fbd->bl = bl;
+	bl->props.power = FB_BLANK_UNBLANK;
+	bl->props.fb_blank = FB_BLANK_UNBLANK;
+	bl->props.brightness = mx3fb_bl_get_brightness(bl);
+}
+
+static void mx3fb_exit_backlight(struct mx3fb_data *fbd)
+{
+	if (fbd->bl)
+		backlight_device_unregister(fbd->bl);
+}
+#endif
+
 static void mx3fb_dma_done(void *);
 
 /* Used fb-mode and bpp. Can be set on kernel command line, therefore file-static. */
@@ -628,6 +707,18 @@ static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t a
 	return 0;
 }
 
+#ifdef PWM_BACKLIGHT_AVAILABLE
+static u32 sdc_get_brightness(struct mx3fb_data *mx3fb)
+{
+	u32 brightness;
+
+	brightness = mx3fb_read_reg(mx3fb, SDC_PWM_CTRL);
+	brightness = (brightness >> 16) & 0xFF;
+
+	return brightness;
+}
+#endif
+
 static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value)
 {
 	dev_dbg(mx3fb->dev, "%s: value = %d\n", __func__, value);
@@ -1534,6 +1625,9 @@ static int mx3fb_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto eisdc0;
 
+#ifdef PWM_BACKLIGHT_AVAILABLE
+	mx3fb_init_backlight(mx3fb);
+#endif
 	return 0;
 
 eisdc0:
@@ -1557,6 +1651,10 @@ static int mx3fb_remove(struct platform_device *dev)
 	chan = &mx3_fbi->idmac_channel->dma_chan;
 	release_fbi(fbi);
 
+#ifdef PWM_BACKLIGHT_AVAILABLE
+	mx3fb_exit_backlight(mx3fb);
+#endif
+
 	dma_release_channel(chan);
 	dmaengine_put();
 
-- 
1.8.5.5


^ permalink raw reply related

* [PATCH v3 0/3] Add display support for gta04 device
From: Marek Belisko @ 2014-05-08 20:16 UTC (permalink / raw)
  To: linux-arm-kernel

This 3 patches adding display support for openmoko gta04 device.
First patch add DT bindings for topolly td028 panel. Second add description for
dss + panel and third fix panel probing when panel is compiled as module.

Changes from v2:
- add missing 'port' node for dpi_out endpoint (comment from Tomi Valkeinen)

Changes from v1:
- extend panel compatible string by 'omapdss'
- add tpo-td028 panel to dss_compat_conv_list
- add MODULE_ALIAS macro to properly probe panel when is compiled as module

Marek Belisko (3):
  omapdss: panel-tpo-td028ec1: Add DT support.
  ARM: dts: oma3-gta04: Add display support
  omapdss: panel-tpo-td028ec1: Add module alias

 .../bindings/video/toppoly,td028ttec1.txt          | 30 ++++++++
 arch/arm/boot/dts/omap3-gta04.dts                  | 87 ++++++++++++++++++++++
 arch/arm/mach-omap2/display.c                      |  1 +
 .../omap2/displays-new/panel-tpo-td028ttec1.c      | 33 +++++++-
 4 files changed, 150 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/video/toppoly,td028ttec1.txt

-- 
1.9.1


^ permalink raw reply

* [PATCH v3 1/3] omapdss: panel-tpo-td028ec1: Add DT support.
From: Marek Belisko @ 2014-05-08 20:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1399580212-5183-1-git-send-email-marek@goldelico.com>

Signed-off-by: Marek Belisko <marek@goldelico.com>
---
 .../bindings/video/toppoly,td028ttec1.txt          | 30 ++++++++++++++++++++
 arch/arm/mach-omap2/display.c                      |  1 +
 .../omap2/displays-new/panel-tpo-td028ttec1.c      | 32 +++++++++++++++++++++-
 3 files changed, 62 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/video/toppoly,td028ttec1.txt

diff --git a/Documentation/devicetree/bindings/video/toppoly,td028ttec1.txt b/Documentation/devicetree/bindings/video/toppoly,td028ttec1.txt
new file mode 100644
index 0000000..7175dc3
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/toppoly,td028ttec1.txt
@@ -0,0 +1,30 @@
+Toppoly TD028TTEC1 Panel
+============
+
+Required properties:
+- compatible: "toppoly,td028ttec1"
+
+Optional properties:
+- label: a symbolic name for the panel
+
+Required nodes:
+- Video port for DPI input
+
+Example
+-------
+
+lcd-panel: td028ttec1@0 {
+	compatible = "toppoly,td028ttec1";
+	reg = <0>;
+	spi-max-frequency = <100000>;
+	spi-cpol;
+	spi-cpha;
+
+	label = "lcd";
+	port {
+		lcd_in: endpoint {
+			remote-endpoint = <&dpi_out>;
+		};
+	};
+};
+
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 16d33d8..66a2ee0 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -566,6 +566,7 @@ static const char * const dss_compat_conv_list[] __initconst = {
 	"svideo-connector",
 	"ti,tfp410",
 	"ti,tpd12s015",
+	"toppoly,td028ttec1",
 };
 
 /* prepend compatible string with "omapdss," */
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
index fae6adc..5b3466e 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
@@ -206,7 +206,8 @@ static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
 	if (omapdss_device_is_enabled(dssdev))
 		return 0;
 
-	in->ops.dpi->set_data_lines(in, ddata->data_lines);
+	if (ddata->data_lines)
+		in->ops.dpi->set_data_lines(in, ddata->data_lines);
 	in->ops.dpi->set_timings(in, &ddata->videomode);
 
 	r = in->ops.dpi->enable(in);
@@ -389,6 +390,23 @@ static int td028ttec1_panel_probe_pdata(struct spi_device *spi)
 	return 0;
 }
 
+static int td028ttec1_probe_of(struct spi_device *spi)
+{
+	struct device_node *node = spi->dev.of_node;
+	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
+	struct omap_dss_device *in;
+
+	in = omapdss_of_find_source_for_first_ep(node);
+	if (IS_ERR(in)) {
+		dev_err(&spi->dev, "failed to find video source\n");
+		return PTR_ERR(in);
+	}
+
+	ddata->in = in;
+
+	return 0;
+}
+
 static int td028ttec1_panel_probe(struct spi_device *spi)
 {
 	struct panel_drv_data *ddata;
@@ -418,6 +436,10 @@ static int td028ttec1_panel_probe(struct spi_device *spi)
 		r = td028ttec1_panel_probe_pdata(spi);
 		if (r)
 			return r;
+	} else if (spi->dev.of_node) {
+		r = td028ttec1_probe_of(spi);
+		if (r)
+			return r;
 	} else {
 		return -ENODEV;
 	}
@@ -463,6 +485,13 @@ static int td028ttec1_panel_remove(struct spi_device *spi)
 	return 0;
 }
 
+static const struct of_device_id td028ttec1_of_match[] = {
+	{ .compatible = "omapdss,toppoly,td028ttec1", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, td028ttec1_of_match);
+
 static struct spi_driver td028ttec1_spi_driver = {
 	.probe		= td028ttec1_panel_probe,
 	.remove		= td028ttec1_panel_remove,
@@ -470,6 +499,7 @@ static struct spi_driver td028ttec1_spi_driver = {
 	.driver         = {
 		.name   = "panel-tpo-td028ttec1",
 		.owner  = THIS_MODULE,
+		.of_match_table = td028ttec1_of_match,
 	},
 };
 
-- 
1.9.1


^ permalink raw reply related

* [PATCH v3 2/3] ARM: dts: oma3-gta04: Add display support
From: Marek Belisko @ 2014-05-08 20:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1399580212-5183-1-git-send-email-marek@goldelico.com>

This patch add support for lcd display on gta04 board. Display control
is connected to spi (used spi bitbang driver).

Signed-off-by: Marek Belisko <marek@goldelico.com>
---
 arch/arm/boot/dts/omap3-gta04.dts | 87 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dts
index f8ad125..eb9ab1a 100644
--- a/arch/arm/boot/dts/omap3-gta04.dts
+++ b/arch/arm/boot/dts/omap3-gta04.dts
@@ -44,6 +44,36 @@
 		ti,mcbsp = <&mcbsp2>;
 		ti,codec = <&twl_audio>;
 	};
+
+	spi_lcd {
+		compatible = "spi-gpio";
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi_gpio_pins>;
+
+		gpio-sck = <&gpio1 12 0>;
+		gpio-miso = <&gpio1 18 0>;
+		gpio-mosi = <&gpio1 20 0>;
+		cs-gpios = <&gpio1 19 0>;
+		num-chipselects = <1>;
+
+		/* lcd panel */
+		lcd: td028ttec1@0 {
+			compatible = "toppoly,td028ttec1";
+			reg = <0>;
+			spi-max-frequency = <100000>;
+			spi-cpol;
+			spi-cpha;
+
+			label = "lcd";
+			port {
+				lcd_in: endpoint {
+					remote-endpoint = <&dpi_out>;
+				};
+			};
+		};
+	};
 };
 
 &omap3_pmx_core {
@@ -78,6 +108,47 @@
 			0x11e (PIN_INPUT_PULLUP | MUX_MODE0)	/* sdmmc1_dat3.sdmmc1_dat3 */
 		>;
 	};
+
+	dss_dpi_pins: pinmux_dss_dpi_pins {
+               pinctrl-single,pins = <
+                       0x0a4 (PIN_OUTPUT | MUX_MODE0)   /* dss_pclk.dss_pclk */
+                       0x0a6 (PIN_OUTPUT | MUX_MODE0)   /* dss_hsync.dss_hsync */
+                       0x0a8 (PIN_OUTPUT | MUX_MODE0)   /* dss_vsync.dss_vsync */
+                       0x0aa (PIN_OUTPUT | MUX_MODE0)   /* dss_acbias.dss_acbias */
+                       0x0ac (PIN_OUTPUT | MUX_MODE0)   /* dss_data0.dss_data0 */
+                       0x0ae (PIN_OUTPUT | MUX_MODE0)   /* dss_data1.dss_data1 */
+                       0x0b0 (PIN_OUTPUT | MUX_MODE0)   /* dss_data2.dss_data2 */
+                       0x0b2 (PIN_OUTPUT | MUX_MODE0)   /* dss_data3.dss_data3 */
+                       0x0b4 (PIN_OUTPUT | MUX_MODE0)   /* dss_data4.dss_data4 */
+                       0x0b6 (PIN_OUTPUT | MUX_MODE0)   /* dss_data5.dss_data5 */
+                       0x0b8 (PIN_OUTPUT | MUX_MODE0)   /* dss_data6.dss_data6 */
+                       0x0ba (PIN_OUTPUT | MUX_MODE0)   /* dss_data7.dss_data7 */
+                       0x0bc (PIN_OUTPUT | MUX_MODE0)   /* dss_data8.dss_data8 */
+                       0x0be (PIN_OUTPUT | MUX_MODE0)   /* dss_data9.dss_data9 */
+                       0x0c0 (PIN_OUTPUT | MUX_MODE0)   /* dss_data10.dss_data10 */
+                       0x0c2 (PIN_OUTPUT | MUX_MODE0)   /* dss_data11.dss_data11 */
+                       0x0c4 (PIN_OUTPUT | MUX_MODE0)   /* dss_data12.dss_data12 */
+                       0x0c6 (PIN_OUTPUT | MUX_MODE0)   /* dss_data13.dss_data13 */
+                       0x0c8 (PIN_OUTPUT | MUX_MODE0)   /* dss_data14.dss_data14 */
+                       0x0ca (PIN_OUTPUT | MUX_MODE0)   /* dss_data15.dss_data15 */
+                       0x0cc (PIN_OUTPUT | MUX_MODE0)   /* dss_data16.dss_data16 */
+                       0x0ce (PIN_OUTPUT | MUX_MODE0)   /* dss_data17.dss_data17 */
+                       0x0d0 (PIN_OUTPUT | MUX_MODE0)   /* dss_data18.dss_data18 */
+                       0x0d2 (PIN_OUTPUT | MUX_MODE0)   /* dss_data19.dss_data19 */
+                       0x0d4 (PIN_OUTPUT | MUX_MODE0)   /* dss_data20.dss_data20 */
+                       0x0d6 (PIN_OUTPUT | MUX_MODE0)   /* dss_data21.dss_data21 */
+                       0x0d8 (PIN_OUTPUT | MUX_MODE0)   /* dss_data22.dss_data22 */
+                       0x0da (PIN_OUTPUT | MUX_MODE0)   /* dss_data23.dss_data23 */
+               >;
+       };
+
+	spi_gpio_pins: spi_gpio_pinmux {
+		pinctrl-single,pins = <0x5a8 (PIN_OUTPUT | MUX_MODE4) /* clk */
+			0x5b6 (PIN_OUTPUT | MUX_MODE4) /* cs */
+			0x5b8 (PIN_OUTPUT | MUX_MODE4) /* tx */
+			0x5b4 (PIN_INPUT | MUX_MODE4) /* rx */
+		>;
+	};
 };
 
 &i2c1 {
@@ -219,3 +290,19 @@
 	regulator-min-microvolt = <2800000>;
 	regulator-max-microvolt = <3150000>;
 };
+
+&dss {
+	pinctrl-names = "default";
+	pinctrl-0 = < &dss_dpi_pins >;
+
+	status = "okay";
+
+	vdds_dsi-supply = <&vpll2>;
+
+	port {
+		dpi_out: endpoint {
+			remote-endpoint = <&lcd_in>;
+			data-lines = <24>;
+		};
+	};
+};
-- 
1.9.1


^ permalink raw reply related

* [PATCH v3 3/3] omapdss: panel-tpo-td028ec1: Add module alias
From: Marek Belisko @ 2014-05-08 20:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1399580212-5183-1-git-send-email-marek@goldelico.com>

Add module alias string to make it working when panel is compiled as module.
Without this change panel module is not probed thus display is not working.

Signed-off-by: Marek Belisko <marek@goldelico.com>
---
 drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
index 5b3466e..728808b 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
@@ -505,6 +505,7 @@ static struct spi_driver td028ttec1_spi_driver = {
 
 module_spi_driver(td028ttec1_spi_driver);
 
+MODULE_ALIAS("spi:toppoly,td028ttec1");
 MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>");
 MODULE_DESCRIPTION("Toppoly TD028TTEC1 panel driver");
 MODULE_LICENSE("GPL");
-- 
1.9.1


^ permalink raw reply related

* Re: [PATCH 13/13] video: omap: allow building on !MMU
From: Tony Lindgren @ 2014-05-08 21:53 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Peter Griffin, Arnd Bergmann, linux-kernel, linaro-kernel,
	Jean-Christophe Plagniol-Villard, linux-fbdev, linux-omap,
	Aaro Koskinen, Janusz Krzysztofik
In-Reply-To: <5369F973.10803@ti.com>

* Tomi Valkeinen <tomi.valkeinen@ti.com> [140507 02:15]:
> On 24/04/14 15:28, Peter Griffin wrote:
> > From: Arnd Bergmann <arnd@arndb.de>
> > 
> > The omap lcdc driver has an elaborate mmap_kern function
> > to map the frame buffer into kernel address space as
> > write-combined. This uses functions that are only available
> > on MMU-enabled builds.
> > 
> > It does seem equivalent to ioremap_wc though, so we should
> > be able to just use that instead.
> > 
> > This patch is build-tested only, it needs to be run on real
> > hardware before applying.
> 
> I don't have omap1 boards, and I don't know anyone that has. I don't
> even know if the omap1 fb is working or not...
> 
> Tony, any idea of omap1's fb? Are you able to test this?

I have three omap1 boards in my rack that I use for my boot
testing. Tried to enable framebuffer but so far no luck on
any of them. So I'm not much of a help here. Looks like the
patch should work though..

Aaro & Janusz, care to take a look at the patch in this
thread?

Regards,

Tony

^ permalink raw reply

* Re: [PATCH 13/13] video: omap: allow building on !MMU
From: Aaro Koskinen @ 2014-05-08 23:04 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Tomi Valkeinen, Peter Griffin, Arnd Bergmann, linux-kernel,
	linaro-kernel, Jean-Christophe Plagniol-Villard, linux-fbdev,
	linux-omap, Janusz Krzysztofik
In-Reply-To: <20140508215338.GE2198@atomide.com>

Hi,

On Thu, May 08, 2014 at 02:53:38PM -0700, Tony Lindgren wrote:
> * Tomi Valkeinen <tomi.valkeinen@ti.com> [140507 02:15]:
> > I don't have omap1 boards, and I don't know anyone that has. I don't
> > even know if the omap1 fb is working or not...

OMAP1 fb is working very well. As a matter of fact, it's much more usable
for me than fb on OMAP2/3 - apart from N900 (on which fb is working again
with 3.15) none of my 4 other OMAP2/3 boards have a working display/fb
in mainline yet. :-(

> > Tony, any idea of omap1's fb? Are you able to test this?
> 
> I have three omap1 boards in my rack that I use for my boot
> testing. Tried to enable framebuffer but so far no luck on
> any of them. So I'm not much of a help here. Looks like the
> patch should work though..
> 
> Aaro & Janusz, care to take a look at the patch in this
> thread?

I couldn't figure out how to enter this code path. Amstrad E3 & Nokia
770 will take the alloc_fbmem() path & exit, and based on quick look
I could not see way to enter mmap_kern(). Is that dead code?

A.

^ permalink raw reply

* Re: [PATCH 13/13] video: omap: allow building on !MMU
From: Tony Lindgren @ 2014-05-08 23:17 UTC (permalink / raw)
  To: Aaro Koskinen
  Cc: Tomi Valkeinen, Peter Griffin, Arnd Bergmann, linux-kernel,
	linaro-kernel, Jean-Christophe Plagniol-Villard, linux-fbdev,
	linux-omap, Janusz Krzysztofik
In-Reply-To: <20140508230415.GA6670@drone.musicnaut.iki.fi>

* Aaro Koskinen <aaro.koskinen@iki.fi> [140508 16:09]:
> Hi,
> 
> On Thu, May 08, 2014 at 02:53:38PM -0700, Tony Lindgren wrote:
> > * Tomi Valkeinen <tomi.valkeinen@ti.com> [140507 02:15]:
> > > I don't have omap1 boards, and I don't know anyone that has. I don't
> > > even know if the omap1 fb is working or not...
> 
> OMAP1 fb is working very well. As a matter of fact, it's much more usable
> for me than fb on OMAP2/3 - apart from N900 (on which fb is working again
> with 3.15) none of my 4 other OMAP2/3 boards have a working display/fb
> in mainline yet. :-(

I hear you.. What do you have in the .config for omap1?
Would be nice to enable the framebuffer in omap1_defconfig?
 
> > > Tony, any idea of omap1's fb? Are you able to test this?
> > 
> > I have three omap1 boards in my rack that I use for my boot
> > testing. Tried to enable framebuffer but so far no luck on
> > any of them. So I'm not much of a help here. Looks like the
> > patch should work though..
> > 
> > Aaro & Janusz, care to take a look at the patch in this
> > thread?
> 
> I couldn't figure out how to enter this code path. Amstrad E3 & Nokia
> 770 will take the alloc_fbmem() path & exit, and based on quick look
> I could not see way to enter mmap_kern(). Is that dead code?

Could be. It may be something left from when we had code to keep
the bootloader logo displayed while booting kernel.

Regards,

Tony

^ permalink raw reply

* Re: [PATCH 1/4] OMAPDSS: Fix DSS clock multiplier issue on 3703 and probably 3630
From: Tony Lindgren @ 2014-05-08 23:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1398815562-24113-2-git-send-email-tony@atomide.com>

* Tony Lindgren <tony@atomide.com> [140429 16:53]:
> Otherwise we can get often errors like the following and the
> display won't come on:
> 
> omapdss APPLY error: FIFO UNDERFLOW on gfx, disabling the overlay
> omapdss APPLY error: SYNC_LOST on channel lcd, restarting
> the output with video overlays disabled
> 
> There are some earlier references to this issue:
> 
> http://www.spinics.net/lists/linux-omap/msg59511.html
> http://www.spinics.net/lists/linux-omap/msg59724.html
> 
> It seems that it's safe to set the lower values even for 3630.
> If we can confirm that 3630 works with the higher values
> reliably we can add further detection.

BTW, I'm also seeing this warning on 3730-evm it may be related:

[    3.523101] ------------[ cut here ]------------
[    3.528015] WARNING: CPU: 0 PID: 6 at drivers/video/fbdev/omap2/dss/dss.c:483 dss_set_fck_rate+0x6c/0x8c()
[    3.538360] clk rate mismatch: 108000000 != 115200000
[    3.543518] Modules linked in:
[    3.546966] CPU: 0 PID: 6 Comm: kworker/u2:0 Tainted: G        W     3.15.0-rc3-00015-gaa296fa-dirty #391
[    3.557159] Workqueue: deferwq deferred_probe_work_func
[    3.562774] [<c0014cbc>] (unwind_backtrace) from [<c001191c>] (show_stack+0x10/0x14)
[    3.571014] [<c001191c>] (show_stack) from [<c05660b4>] (dump_stack+0x80/0x9c)
[    3.578704] [<c05660b4>] (dump_stack) from [<c003f558>] (warn_slowpath_common+0x68/0x8c)
[    3.587249] [<c003f558>] (warn_slowpath_common) from [<c003f610>] (warn_slowpath_fmt+0x30/0x40)
[    3.596496] [<c003f610>] (warn_slowpath_fmt) from [<c03129f0>] (dss_set_fck_rate+0x6c/0x8c)
[    3.605407] [<c03129f0>] (dss_set_fck_rate) from [<c0323728>] (dpi_display_enable+0x23c/0x2e4)
[    3.614562] [<c0323728>] (dpi_display_enable) from [<c03323a8>] (sharp_ls_enable+0x58/0xc4)
[    3.623474] [<c03323a8>] (sharp_ls_enable) from [<c0335ee0>] (omapfb_probe+0x548/0x848)
[    3.631988] [<c0335ee0>] (omapfb_probe) from [<c0378cfc>] (platform_drv_probe+0x18/0x48)
[    3.640594] [<c0378cfc>] (platform_drv_probe) from [<c0377938>] (driver_probe_device+0x110/0x22c)
[    3.650024] [<c0377938>] (driver_probe_device) from [<c0376038>] (bus_for_each_drv+0x44/0x8c)
[    3.659088] [<c0376038>] (bus_for_each_drv) from [<c03777f0>] (device_attach+0x74/0x8c)
[    3.667541] [<c03777f0>] (device_attach) from [<c0376ecc>] (bus_probe_device+0x88/0xb0)
[    3.676025] [<c0376ecc>] (bus_probe_device) from [<c03772d0>] (deferred_probe_work_func+0x64/0x94)
[    3.685546] [<c03772d0>] (deferred_probe_work_func) from [<c0057220>] (process_one_work+0x1b4/0x4bc)
[    3.695251] [<c0057220>] (process_one_work) from [<c0057908>] (worker_thread+0x11c/0x398)
[    3.704620] [<c0057908>] (worker_thread) from [<c005df10>] (kthread+0xc8/0xe4)
[    3.712280] [<c005df10>] (kthread) from [<c000e768>] (ret_from_fork+0x14/0x2c)
[    3.719909] ---[ end trace 1c9526c1a2975498 ]---

 
> Signed-off-by: Tony Lindgren <tony@atomide.com>
> ---
>  drivers/video/fbdev/omap2/dss/dss.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
> index d55266c..ad6561f 100644
> --- a/drivers/video/fbdev/omap2/dss/dss.c
> +++ b/drivers/video/fbdev/omap2/dss/dss.c
> @@ -707,9 +707,10 @@ static const struct dss_features omap34xx_dss_feats __initconst = {
>  	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3,
>  };
>  
> +/* Supposedly 3630 can use div 32 mult 2, but that needs to be rechecked */
>  static const struct dss_features omap3630_dss_feats __initconst = {
> -	.fck_div_max		=	32,
> -	.dss_fck_multiplier	=	1,
> +	.fck_div_max		=	16,
> +	.dss_fck_multiplier	=	2,
>  	.parent_clk_name	=	"dpll4_ck",
>  	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3,
>  };
> -- 
> 1.8.1.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 2/4] OMAPDSS: panel-sharp-ls037v7dw01: update to use gpiod
From: Tony Lindgren @ 2014-05-08 23:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5369EB90.8060007@ti.com>

* Tomi Valkeinen <tomi.valkeinen@ti.com> [140507 01:15]:
> On 30/04/14 02:52, Tony Lindgren wrote:
> > +static struct gpio_desc *
> > +sharp_ls_get_gpio(struct device *dev, int gpio, unsigned long flags,
> > +		  char *desc)
> > +{
> > +	int r;
> > +
> > +	r = devm_gpio_request_one(dev, gpio, flags, desc);
> > +	if (r) {
> > +		dev_err(dev, "no %s gpio\n", desc);
> 
> As it's fine to not have a gpio, I guess this error print should be removed.

OK I made it a dev_dbg, it may help somebody while
configuring the panel.
 
> Also, if the error is EPROBE_DEFER, the driver should fail and return
> that. The same goes for the DT version in the next patch.

Good catch. It's a bit unfortunate that all drivers have to
sprinkle EPROBE_DEFER handling all over the place, that issue
is really caused by a missing resource management layer at
the bus level :(

Below is the updated patch, please feel free to pick if OK.

Regards,

Tony

8<---------------
From: Tony Lindgren <tony@atomide.com>
Date: Mon, 28 Apr 2014 20:22:20 -0700
Subject: [PATCH] OMAPDSS: panel-sharp-ls037v7dw01: update to use gpiod

Using gpiod will make it easier to add device tree support
for this panel in the following patches.

Note that all the GPIOs for this panel are optional, any
of the the GPIOs could be configured with external pulls
instead of GPIOs, so let's not error out if GPIOs are not
found to make the panel more generic.

Signed-off-by: Tony Lindgren <tony@atomide.com>

--- a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
@@ -26,11 +26,11 @@ struct panel_drv_data {
 
 	struct omap_video_timings videomode;
 
-	int resb_gpio;
-	int ini_gpio;
-	int mo_gpio;
-	int lr_gpio;
-	int ud_gpio;
+	struct gpio_desc *resb_gpio;	/* low = reset active min 20 us */
+	struct gpio_desc *ini_gpio;	/* high = power on */
+	struct gpio_desc *mo_gpio;	/* low = 480x640, high = 240x320 */
+	struct gpio_desc *lr_gpio;	/* high = conventional horizontal scanning */
+	struct gpio_desc *ud_gpio;	/* high = conventional vertical scanning */
 };
 
 static const struct omap_video_timings sharp_ls_timings = {
@@ -105,11 +105,11 @@ static int sharp_ls_enable(struct omap_dss_device *dssdev)
 	/* wait couple of vsyncs until enabling the LCD */
 	msleep(50);
 
-	if (gpio_is_valid(ddata->resb_gpio))
-		gpio_set_value_cansleep(ddata->resb_gpio, 1);
+	if (!IS_ERR(ddata->resb_gpio))
+		gpiod_set_value_cansleep(ddata->resb_gpio, 1);
 
-	if (gpio_is_valid(ddata->ini_gpio))
-		gpio_set_value_cansleep(ddata->ini_gpio, 1);
+	if (!IS_ERR(ddata->ini_gpio))
+		gpiod_set_value_cansleep(ddata->ini_gpio, 1);
 
 	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
 
@@ -124,11 +124,11 @@ static void sharp_ls_disable(struct omap_dss_device *dssdev)
 	if (!omapdss_device_is_enabled(dssdev))
 		return;
 
-	if (gpio_is_valid(ddata->ini_gpio))
-		gpio_set_value_cansleep(ddata->ini_gpio, 0);
+	if (!IS_ERR(ddata->ini_gpio))
+		gpiod_set_value_cansleep(ddata->ini_gpio, 0);
 
-	if (gpio_is_valid(ddata->resb_gpio))
-		gpio_set_value_cansleep(ddata->resb_gpio, 0);
+	if (!IS_ERR(ddata->resb_gpio))
+		gpiod_set_value_cansleep(ddata->resb_gpio, 0);
 
 	/* wait at least 5 vsyncs after disabling the LCD */
 
@@ -182,6 +182,21 @@ static struct omap_dss_driver sharp_ls_ops = {
 	.get_resolution	= omapdss_default_get_resolution,
 };
 
+static struct gpio_desc *
+sharp_ls_get_gpio(struct device *dev, int gpio, unsigned long flags,
+		  char *desc)
+{
+	int r;
+
+	r = devm_gpio_request_one(dev, gpio, flags, desc);
+	if (r) {
+		dev_dbg(dev, "no %s gpio\n", desc);
+		return ERR_PTR(r);
+	}
+
+	return gpio_to_desc(gpio);
+}
+
 static int sharp_ls_probe_pdata(struct platform_device *pdev)
 {
 	const struct panel_sharp_ls037v7dw01_platform_data *pdata;
@@ -204,11 +219,26 @@ static int sharp_ls_probe_pdata(struct platform_device *pdev)
 	dssdev = &ddata->dssdev;
 	dssdev->name = pdata->name;
 
-	ddata->resb_gpio = pdata->resb_gpio;
-	ddata->ini_gpio = pdata->ini_gpio;
-	ddata->mo_gpio = pdata->mo_gpio;
-	ddata->lr_gpio = pdata->lr_gpio;
-	ddata->ud_gpio = pdata->ud_gpio;
+	ddata->mo_gpio = sharp_ls_get_gpio(&pdev->dev, pdata->mo_gpio,
+					   GPIOF_OUT_INIT_LOW, "lcd MO");
+	if (PTR_ERR(ddata->mo_gpio) = -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+	ddata->lr_gpio = sharp_ls_get_gpio(&pdev->dev, pdata->lr_gpio,
+					   GPIOF_OUT_INIT_HIGH, "lcd LR");
+	if (PTR_ERR(ddata->lr_gpio) = -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+	ddata->ud_gpio = sharp_ls_get_gpio(&pdev->dev, pdata->ud_gpio,
+					   GPIOF_OUT_INIT_HIGH, "lcd UD");
+	if (PTR_ERR(ddata->ud_gpio) = -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+	ddata->resb_gpio = sharp_ls_get_gpio(&pdev->dev, pdata->resb_gpio,
+					     GPIOF_OUT_INIT_LOW, "lcd RESB");
+	if (PTR_ERR(ddata->resb_gpio) = -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+	ddata->ini_gpio = sharp_ls_get_gpio(&pdev->dev, pdata->ini_gpio,
+					    GPIOF_OUT_INIT_LOW, "lcd INI");
+	if (PTR_ERR(ddata->ini_gpio) = -EPROBE_DEFER)
+		return -EPROBE_DEFER;
 
 	return 0;
 }
@@ -233,41 +263,6 @@ static int sharp_ls_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	if (gpio_is_valid(ddata->mo_gpio)) {
-		r = devm_gpio_request_one(&pdev->dev, ddata->mo_gpio,
-				GPIOF_OUT_INIT_LOW, "lcd MO");
-		if (r)
-			goto err_gpio;
-	}
-
-	if (gpio_is_valid(ddata->lr_gpio)) {
-		r = devm_gpio_request_one(&pdev->dev, ddata->lr_gpio,
-				GPIOF_OUT_INIT_HIGH, "lcd LR");
-		if (r)
-			goto err_gpio;
-	}
-
-	if (gpio_is_valid(ddata->ud_gpio)) {
-		r = devm_gpio_request_one(&pdev->dev, ddata->ud_gpio,
-				GPIOF_OUT_INIT_HIGH, "lcd UD");
-		if (r)
-			goto err_gpio;
-	}
-
-	if (gpio_is_valid(ddata->resb_gpio)) {
-		r = devm_gpio_request_one(&pdev->dev, ddata->resb_gpio,
-				GPIOF_OUT_INIT_LOW, "lcd RESB");
-		if (r)
-			goto err_gpio;
-	}
-
-	if (gpio_is_valid(ddata->ini_gpio)) {
-		r = devm_gpio_request_one(&pdev->dev, ddata->ini_gpio,
-				GPIOF_OUT_INIT_LOW, "lcd INI");
-		if (r)
-			goto err_gpio;
-	}
-
 	ddata->videomode = sharp_ls_timings;
 
 	dssdev = &ddata->dssdev;
@@ -287,7 +282,6 @@ static int sharp_ls_probe(struct platform_device *pdev)
 	return 0;
 
 err_reg:
-err_gpio:
 	omap_dss_put_device(ddata->in);
 	return r;
 }

^ permalink raw reply

* Re: [PATCH 3/4] OMAPDSS: panel-sharp-ls037v7dw01: add device tree support
From: Tony Lindgren @ 2014-05-08 23:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140507175919.GH9502@atomide.com>

* Tony Lindgren <tony@atomide.com> [140507 11:00]:
> * Tomi Valkeinen <tomi.valkeinen@ti.com> [140507 09:03]:
> > On 07/05/14 18:03, Tony Lindgren wrote:
> > > 
> > > BTW, I'm also personally fine with all five gpios showing in a single
> > > gpios property, I'm not too exited about naming anything in DT..
> > 
> > I don't have a strong opinion here. I don't have much experience with
> > DT, especially with making bindings compatible with other ones.
> > 
> > I'd just forget the simple-panel, and have single gpio array.
> 
> Well if it's a don't care flag for both of us, let's try to use
> the existing standard for simple-panel.txt and add mode-gpios
> property. I'll post a patch for that.

Here's an updated version using enable-gpios, reset-gpios and
mode-gpios. So it follows simple-panel.txt and adds mode-gpios
that's currently specific to this panel only.

Also updated for -EPROBE_DEFER handling, tested that by changing
one of the GPIOs to be a twl4030 GPIO.

Regards,

Tony

8<------------------
From: Tony Lindgren <tony@atomide.com>
Date: Mon, 28 Apr 2014 20:22:21 -0700
Subject: [PATCH] OMAPDSS: panel-sharp-ls037v7dw01: add device tree support

We can pass the GPIO configuration for ls037v7dw01 in a standard
gpios property.

Signed-off-by: Tony Lindgren <tony@atomide.com>

--- /dev/null
+++ b/Documentation/devicetree/bindings/panel/sharp,ls037v7dw01.txt
@@ -0,0 +1,56 @@
+SHARP LS037V7DW01 TFT-LCD panel
+
+Required properties:
+- compatible: should be "sharp,ls037v7dw01"
+
+Optional properties:
+- enable-gpios: a GPIO spec for the optional enable pin
+  this pin is the INI pin as specified in the LS037V7DW01.pdf file.
+- reset-gpios: a GPIO spec for the optional reset pin
+  this pin is the RESB pin as specified in the LS037V7DW01.pdf file.
+- mode-gpios: a GPIO 
+  ordered MO, LR, and UD as specified in the LS037V7DW01.pdf file.
+
+This binding is compatible with the simple-panel binding, which is specified
+in simple-panel.txt in this directory.
+
+This panel can have zero to five GPIOs to configure
+to change configuration between QVGA and VGA mode
+and the scan direction. As these pins can be also
+configured with external pulls, all the GPIOs are
+considered optional with holes in the array.
+
+Example when connected to a omap2+ based device:
+
+	lcd0: display {
+		compatible = "sharp,ls037v7dw01";
+		power-supply = <&lcd_3v3>;
+		enable-gpios = <&gpio5 24 GPIO_ACTIVE_HIGH>;	/* gpio152, lcd INI */
+		reset-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>;	/* gpio155, lcd RESB */
+		mode-gpios = <&gpio5 26 GPIO_ACTIVE_HIGH	/* gpio154, lcd MO */
+			      &gpio1 2 GPIO_ACTIVE_HIGH		/* gpio2, lcd LR */
+			      &gpio1 3 GPIO_ACTIVE_HIGH>;	/* gpio3, lcd UD */
+
+		panel-timing {
+			clock-frequency = <19200000>;
+			hback-porch = <28>;
+			hactive = <480>;
+			hfront-porch = <1>;
+			hsync-len = <2>;
+			vback-porch = <1>;
+			vactive = <640>;
+			vfront-porch = <1>;
+			vsync-len = <1>;
+			hsync-active = <0>;
+			vsync-active = <0>;
+			de-active = <1>;
+			pixelclk-active = <1>;
+		};
+
+		port {
+			lcd_in: endpoint {
+				remote-endpoint = <&dpi_out>;
+			};
+		};
+	};
+
--- a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
@@ -12,15 +12,19 @@
 #include <linux/delay.h>
 #include <linux/gpio.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-
+#include <linux/regulator/consumer.h>
+#include <video/of_display_timing.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-data.h>
 
 struct panel_drv_data {
 	struct omap_dss_device dssdev;
 	struct omap_dss_device *in;
+	struct regulator *vcc;
 
 	int data_lines;
 
@@ -95,7 +99,8 @@ static int sharp_ls_enable(struct omap_dss_device *dssdev)
 	if (omapdss_device_is_enabled(dssdev))
 		return 0;
 
-	in->ops.dpi->set_data_lines(in, ddata->data_lines);
+	if (ddata->data_lines)
+		in->ops.dpi->set_data_lines(in, ddata->data_lines);
 	in->ops.dpi->set_timings(in, &ddata->videomode);
 
 	r = in->ops.dpi->enable(in);
@@ -240,6 +245,88 @@ static int sharp_ls_probe_pdata(struct platform_device *pdev)
 	if (PTR_ERR(ddata->ini_gpio) = -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
+	ddata->videomode = sharp_ls_timings;
+
+	return 0;
+}
+
+static struct gpio_desc *
+sharp_ls_get_gpio_of(struct device *dev, int index, int val, char *desc)
+{
+	struct gpio_desc *gpio;
+
+	gpio = devm_gpiod_get_index(dev, desc, index);
+	if (IS_ERR(gpio))
+		return gpio;
+
+	gpiod_direction_output(gpio, val);
+
+	return gpio;
+}
+
+static int sharp_ls_probe_of(struct platform_device *pdev)
+{
+	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+	struct device_node *node = pdev->dev.of_node;
+	struct omap_dss_device *in;
+	struct display_timing timing;
+	struct videomode vm;
+	int r;
+
+	ddata->vcc = devm_regulator_get(&pdev->dev, "envdd");
+	if (IS_ERR(ddata->vcc)) {
+		dev_err(&pdev->dev, "failed to get regulator\n");
+		return PTR_ERR(ddata->vcc);
+	}
+
+	r = regulator_enable(ddata->vcc);
+	if (r != 0) {
+		dev_err(&pdev->dev, "failed to enable regulator\n");
+		return r;
+	}
+
+	/* lcd INI */
+	ddata->ini_gpio = sharp_ls_get_gpio_of(&pdev->dev, 3, 0, "enable");
+	if (PTR_ERR(ddata->ini_gpio) = -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+
+	/* lcd RESB */
+	ddata->resb_gpio = sharp_ls_get_gpio_of(&pdev->dev, 0, 0, "reset");
+	if (PTR_ERR(ddata->resb_gpio) = -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+
+	/* lcd MO */
+	ddata->mo_gpio = sharp_ls_get_gpio_of(&pdev->dev, 0, 0, "mode");
+	if (PTR_ERR(ddata->mo_gpio) = -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+
+	/* lcd LR */
+	ddata->lr_gpio = sharp_ls_get_gpio_of(&pdev->dev, 1, 1, "mode");
+	if (PTR_ERR(ddata->lr_gpio) = -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+
+	/* lcd UD */
+	ddata->ud_gpio = sharp_ls_get_gpio_of(&pdev->dev, 2, 1, "mode");
+	if (PTR_ERR(ddata->ud_gpio) = -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+
+	r = of_get_display_timing(node, "panel-timing", &timing);
+	if (r) {
+		dev_err(&pdev->dev, "failed to get video timing\n");
+		return r;
+	}
+
+	videomode_from_timing(&timing, &vm);
+	videomode_to_omap_video_timings(&vm, &ddata->videomode);
+
+	in = omapdss_of_find_source_for_first_ep(node);
+	if (IS_ERR(in)) {
+		dev_err(&pdev->dev, "failed to find video source\n");
+		return PTR_ERR(in);
+	}
+
+	ddata->in = in;
+
 	return 0;
 }
 
@@ -259,12 +346,14 @@ static int sharp_ls_probe(struct platform_device *pdev)
 		r = sharp_ls_probe_pdata(pdev);
 		if (r)
 			return r;
+	} else if (pdev->dev.of_node) {
+		r = sharp_ls_probe_of(pdev);
+		if (r)
+			return r;
 	} else {
 		return -ENODEV;
 	}
 
-	ddata->videomode = sharp_ls_timings;
-
 	dssdev = &ddata->dssdev;
 	dssdev->dev = &pdev->dev;
 	dssdev->driver = &sharp_ls_ops;
@@ -302,12 +391,20 @@ static int __exit sharp_ls_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id sharp_ls_of_match[] = {
+	{ .compatible = "sharp,ls037v7dw01", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, sharp_ls_of_match);
+
 static struct platform_driver sharp_ls_driver = {
 	.probe = sharp_ls_probe,
 	.remove = __exit_p(sharp_ls_remove),
 	.driver = {
 		.name = "panel-sharp-ls037v7dw01",
 		.owner = THIS_MODULE,
+		.of_match_table = sharp_ls_of_match,
 	},
 };
 

^ permalink raw reply

* Re: [PATCH 4/4] ARM: dts: Add LCD panel sharp ls037v7dw01 support for omap3-evm and ldp
From: Tony Lindgren @ 2014-05-08 23:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140505183919.GA15463@atomide.com>

* Tony Lindgren <tony@atomide.com> [140505 11:40]:
> * Tony Lindgren <tony@atomide.com> [140430 10:48]:
> > * Joachim Eastwood <manabian@gmail.com> [140429 18:08]:
> > > On 30 April 2014 01:52, Tony Lindgren <tony@atomide.com> wrote:
> > > > +       reset-gpios = <&gpio2 23 GPIO_ACTIVE_HIGH>;     /* gpio55, lcd RESB */
> > > > +       gpios = <&gpio2 24 GPIO_ACTIVE_LOW      /* gpio56, lcd MO */
> > > 
> > > enable-gpios ?
> > 
> > Oops yes, changed from gpios to enable-gpios while reading the panel
> > binding doc, probably forgot to commit the change, will update.
> 
> Here's an updated version of this one.

One more update for the use of enable-gpios, reset-gpios and
mode-gpios to follow the binding described in simple-panel.txt.

Tomi feel free to pick this one up too, I'd assume you prefer
to do an immutable branch for the .dts changes that we both
can merge in as needed.

Regards,

Tony

8<-------------------
From: Tony Lindgren <tony@atomide.com>
Date: Mon, 28 Apr 2014 20:22:21 -0700
Subject: [PATCH] ARM: dts: Add LCD panel sharp ls037v7dw01 support for omap3-evm and ldp

Looks like quite a few omaps have sharp ls037v7dw01 that's configured
as various panel dpi entries for whatever legacy reasons. For device
tree based support, let's just configure these properly for panel
ls037v7dw01 instead of panel dpi.

This patch creates a common file for panel ls037v7dw01, and makes
boards ldp and omap3-evm to use it. The panel for ldp is configured
in the qvga mode and omap3-evm panel in vga mode.

The ls037v7dw01 also seems to be coupled with an ad7846 touchscreen
controller for the omaps, so let's add a basic configuration for
the touchscreen also using the default values.

Note that we can now remove the regulator-name = "vdds_dsi"
entry for ldp, that's no longer needed as we have the entry
for vdds_dsi-supply = <&vpll2>.

Signed-off-by: Tony Lindgren <tony@atomide.com>

--- /dev/null
+++ b/arch/arm/boot/dts/omap-panel-sharp-ls037v7dw01.dtsi
@@ -0,0 +1,82 @@
+/*
+ * Common file for omap dpi panels with QVGA and reset pins
+ *
+ * Note that the board specifc DTS file needs to specify
+ * at minimum the GPIO enable-gpios for display, and
+ * gpios for gpio-backlight.
+ */
+
+/ {
+	aliases {
+		display0 = &lcd0;
+	};
+
+	backlight0: backlight {
+		compatible = "gpio-backlight";
+	};
+
+	/* 3.3V GPIO controlled regulator for LCD_ENVDD */
+	lcd_3v3: regulator-lcd-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "lcd_3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		startup-delay-us = <70000>;
+		regulator-always-on;
+	};
+
+	lcd0: display {
+		compatible = "sharp,ls037v7dw01";
+		label = "lcd";
+		power-supply = <&lcd_3v3>;
+		panel-timing {
+			clock-frequency = <5400000>;
+			hback-porch = <39>;
+			hactive = <240>;
+			hfront-porch = <3>;
+			hsync-len = <3>;
+			vback-porch = <7>;
+			vactive = <320>;
+			vfront-porch = <2>;
+			vsync-len = <1>;
+			hsync-active = <0>;
+			vsync-active = <0>;
+			de-active = <1>;
+			pixelclk-active = <1>;
+		};
+
+		port {
+			lcd_in: endpoint {
+				remote-endpoint = <&dpi_out>;
+			};
+		};
+	};
+};
+
+&dss {
+	status = "ok";
+	vdds_dsi-supply = <&vpll2>;
+	port {
+		dpi_out: endpoint {
+			remote-endpoint = <&lcd_in>;
+			data-lines = <18>;
+		};
+	};
+};
+
+&mcspi1 {
+	tsc2046@0 {
+		reg = <0>;			/* CS0 */
+		compatible = "ti,tsc2046";
+		spi-max-frequency = <1000000>;
+		vcc-supply = <&lcd_3v3>;
+		ti,x-min = /bits/ 16 <0>;
+		ti,x-max = /bits/ 16 <8000>;
+		ti,y-min = /bits/ 16 <0>;
+		ti,y-max = /bits/ 16 <4800>;
+		ti,x-plate-ohms = /bits/ 16 <40>;
+		ti,pressure-max = /bits/ 16 <255>;
+		ti,swap-xy;
+		linux,wakeup;
+	};
+};
--- a/arch/arm/boot/dts/omap3-evm-37xx.dts
+++ b/arch/arm/boot/dts/omap3-evm-37xx.dts
@@ -26,7 +26,44 @@
 	};
 };
 
+&dss {
+	pinctrl-names = "default";
+	pinctrl-0 = <
+		&dss_dpi_pins1
+		&dss_dpi_pins2
+	>;
+};
+
 &omap3_pmx_core {
+	dss_dpi_pins1: pinmux_dss_dpi_pins2 {
+		pinctrl-single,pins = <
+			OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0)   /* dss_pclk.dss_pclk */
+			OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0)   /* dss_hsync.dss_hsync */
+			OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0)   /* dss_vsync.dss_vsync */
+			OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0)   /* dss_acbias.dss_acbias */
+
+			OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0)   /* dss_data6.dss_data6 */
+			OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0)   /* dss_data7.dss_data7 */
+			OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0)   /* dss_data8.dss_data8 */
+			OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0)   /* dss_data9.dss_data9 */
+			OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0)   /* dss_data10.dss_data10 */
+			OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0)   /* dss_data11.dss_data11 */
+			OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0)   /* dss_data12.dss_data12 */
+			OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0)   /* dss_data13.dss_data13 */
+			OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0)   /* dss_data14.dss_data14 */
+			OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0)   /* dss_data15.dss_data15 */
+			OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0)   /* dss_data16.dss_data16 */
+			OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0)   /* dss_data17.dss_data17 */
+
+			OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE3)   /* dss_data18.dss_data0 */
+			OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE3)   /* dss_data19.dss_data1 */
+			OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE3)   /* dss_data20.dss_data2 */
+			OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE3)   /* dss_data21.dss_data3 */
+			OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE3)   /* dss_data22.dss_data4 */
+			OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE3)   /* dss_data23.dss_data5 */
+		>;
+	};
+
 	mmc1_pins: pinmux_mmc1_pins {
 		pinctrl-single,pins = <
 			0x114 (PIN_OUTPUT_PULLUP | MUX_MODE0)	/* sdmmc1_clk.sdmmc1_clk */
@@ -75,6 +112,19 @@
 	};
 };
 
+&omap3_pmx_wkup {
+	dss_dpi_pins2: pinmux_dss_dpi_pins1 {
+		pinctrl-single,pins = <
+			0x0a (PIN_OUTPUT | MUX_MODE3)   /* sys_boot0.dss_data18 */
+			0x0c (PIN_OUTPUT | MUX_MODE3)   /* sys_boot1.dss_data19 */
+			0x10 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot3.dss_data20 */
+			0x12 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot4.dss_data21 */
+			0x14 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot5.dss_data22 */
+			0x16 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot6.dss_data23 */
+		>;
+	};
+};
+
 &mmc1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc1_pins>;
--- a/arch/arm/boot/dts/omap3-evm-common.dtsi
+++ b/arch/arm/boot/dts/omap3-evm-common.dtsi
@@ -44,6 +44,11 @@
 
 #include "twl4030.dtsi"
 #include "twl4030_omap3.dtsi"
+#include "omap-panel-sharp-ls037v7dw01.dtsi"
+
+&backlight0 {
+	gpios = <&twl_gpio 18 GPIO_ACTIVE_HIGH>;
+};
 
 &i2c2 {
 	clock-frequency = <400000>;
@@ -61,6 +66,48 @@
 	};
 };
 
+&lcd_3v3 {
+	gpio = <&gpio5 25 GPIO_ACTIVE_LOW>;	/* gpio153 */
+	enable-active-low;
+};
+
+&lcd0 {
+	enable-gpios = <&gpio5 24 GPIO_ACTIVE_HIGH>;	/* gpio152, lcd INI */
+	reset-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>;	/* gpio155, lcd RESB */
+	/*
+	 * The LCD is sideways, so we want the VGA mode instead of
+	 * QVGA mode. Probably also want to have omapfb.rotate=3
+	 * in the kernel cmdline until there's a binding for that.
+	 */
+	mode-gpios = <&gpio5 26 GPIO_ACTIVE_HIGH	/* gpio154, lcd MO */
+		      &gpio1 2 GPIO_ACTIVE_HIGH		/* gpio2, lcd LR */
+		      &gpio1 3 GPIO_ACTIVE_HIGH>;	/* gpio3, lcd UD */
+
+	panel-timing {
+		clock-frequency = <19200000>;
+		hback-porch = <28>;
+		hactive = <480>;
+		hfront-porch = <1>;
+		hsync-len = <2>;
+		vback-porch = <1>;
+		vactive = <640>;
+		vfront-porch = <1>;
+		vsync-len = <1>;
+		hsync-active = <0>;
+		vsync-active = <0>;
+		de-active = <1>;
+		pixelclk-active = <1>;
+	};
+};
+
+&mcspi1 {
+	tsc2046@0 {
+		interrupt-parent = <&gpio6>;
+		interrupts = <15 0>;		/* gpio175 */
+		pendown-gpio = <&gpio6 15 0>;
+	};
+};
+
 &mmc1 {
 	vmmc-supply = <&vmmc1>;
 	vmmc_aux-supply = <&vsim>;
--- a/arch/arm/boot/dts/omap3-ldp.dts
+++ b/arch/arm/boot/dts/omap3-ldp.dts
@@ -164,6 +164,11 @@
 
 #include "twl4030.dtsi"
 #include "twl4030_omap3.dtsi"
+#include "omap-panel-sharp-ls037v7dw01.dtsi"
+
+&backlight0 {
+	gpios = <&twl_gpio 15 GPIO_ACTIVE_LOW>;
+};
 
 &i2c2 {
 	clock-frequency = <400000>;
@@ -173,6 +178,24 @@
 	clock-frequency = <400000>;
 };
 
+&lcd_3v3 {
+	gpio = <&twl_gpio 7 GPIO_ACTIVE_HIGH>;
+	enable-active-high;
+};
+
+&lcd0 {
+	reset-gpios = <&gpio2 23 GPIO_ACTIVE_HIGH>;	/* gpio55, lcd RESB */
+	mode-gpios = <&gpio2 24 GPIO_ACTIVE_LOW>;	/* gpio56, lcd MO */
+};
+
+&mcspi1 {
+	tsc2046@0 {
+		interrupt-parent = <&gpio2>;
+		interrupts = <22 0>;		/* gpio54 */
+		pendown-gpio = <&gpio2 22 0>;
+	};
+};
+
 &mmc1 {
 	/* See 35xx errata 2.1.1.128 in SPRZ278F */
 	compatible = "ti,omap3-pre-es3-hsmmc";
@@ -247,8 +270,3 @@
 	/* Needed for ads7846 */
         regulator-name = "vcc";
 };
-
-&vpll2 {
-       /* Needed for DSS */
-       regulator-name = "vdds_dsi";
-};

^ permalink raw reply

* [PATCH] backlight: gpio-backlight: Fix warning when the GPIO is on a I2C chip
From: Tony Lindgren @ 2014-05-09  1:24 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-kernel, linux-fbdev, linux-omap, Bryan Wu, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen

If the GPIO for the backlight is on an I2C chip, we currently
get nasty warnings like this during the boot:

WARNING: CPU: 0 PID: 6 at drivers/gpio/gpiolib.c:2364 gpiod_set_raw_value+0x40/0x4c()
Modules linked in:
CPU: 0 PID: 6 Comm: kworker/u2:0 Not tainted 3.15.0-rc4-12393-gcde9f4e #400
Workqueue: deferwq deferred_probe_work_func
[<c0014cbc>] (unwind_backtrace) from [<c001191c>] (show_stack+0x10/0x14)
[<c001191c>] (show_stack) from [<c0566ae0>] (dump_stack+0x80/0x9c)
[<c0566ae0>] (dump_stack) from [<c003f61c>] (warn_slowpath_common+0x68/0x8c)
[<c003f61c>] (warn_slowpath_common) from [<c003f65c>] (warn_slowpath_null+0x1c/0x24)
[<c003f65c>] (warn_slowpath_null) from [<c02f7e10>] (gpiod_set_raw_value+0x40/0x4c)
[<c02f7e10>] (gpiod_set_raw_value) from [<c0308fbc>] (gpio_backlight_update_status+0x4c/0x74)
[<c0308fbc>] (gpio_backlight_update_status) from [<c030914c>] (gpio_backlight_probe+0x168/0x254)
[<c030914c>] (gpio_backlight_probe) from [<c0378fa8>] (platform_drv_probe+0x18/0x48)
[<c0378fa8>] (platform_drv_probe) from [<c0377c40>] (driver_probe_device+0x10c/0x238)
[<c0377c40>] (driver_probe_device) from [<c0376330>] (bus_for_each_drv+0x44/0x8c)
[<c0376330>] (bus_for_each_drv) from [<c0377afc>] (device_attach+0x74/0x8c)
[<c0377afc>] (device_attach) from [<c03771c4>] (bus_probe_device+0x88/0xb0)
[<c03771c4>] (bus_probe_device) from [<c03775c8>] (deferred_probe_work_func+0x64/0x94)
[<c03775c8>] (deferred_probe_work_func) from [<c00572e8>] (process_one_work+0x1b4/0x4bc)
[<c00572e8>] (process_one_work) from [<c00579d0>] (worker_thread+0x11c/0x398)
[<c00579d0>] (worker_thread) from [<c005dfd8>] (kthread+0xc8/0xe4)
[<c005dfd8>] (kthread) from [<c000e768>] (ret_from_fork+0x14/0x2c)

Fix this by using gpio_set_value_cansleep() as suggested in
drivers/gpio/gpiolib.c:2364. This is what the other backlight drivers
are also doing.

Signed-off-by: Tony Lindgren <tony@atomide.com>

--- a/drivers/video/backlight/gpio_backlight.c
+++ b/drivers/video/backlight/gpio_backlight.c
@@ -38,7 +38,8 @@ static int gpio_backlight_update_status(struct backlight_device *bl)
 	    bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
 		brightness = 0;
 
-	gpio_set_value(gbl->gpio, brightness ? gbl->active : !gbl->active);
+	gpio_set_value_cansleep(gbl->gpio,
+				brightness ? gbl->active : !gbl->active);
 
 	return 0;
 }

^ permalink raw reply

* Re: [PATCH] backlight: gpio-backlight: Fix warning when the GPIO is on a I2C chip
From: Jingoo Han @ 2014-05-09  2:25 UTC (permalink / raw)
  To: 'Tony Lindgren'
  Cc: 'Lee Jones', linux-kernel, linux-fbdev, linux-omap,
	'Bryan Wu', 'Jean-Christophe Plagniol-Villard',
	'Tomi Valkeinen', 'Jingoo Han'
In-Reply-To: <20140509012454.GL2198@atomide.com>

On Friday, May 09, 2014 10:25 AM, Lee Jones wrote:
> 
> If the GPIO for the backlight is on an I2C chip, we currently
> get nasty warnings like this during the boot:
> 
> WARNING: CPU: 0 PID: 6 at drivers/gpio/gpiolib.c:2364 gpiod_set_raw_value+0x40/0x4c()
> Modules linked in:
> CPU: 0 PID: 6 Comm: kworker/u2:0 Not tainted 3.15.0-rc4-12393-gcde9f4e #400
> Workqueue: deferwq deferred_probe_work_func
> [<c0014cbc>] (unwind_backtrace) from [<c001191c>] (show_stack+0x10/0x14)
> [<c001191c>] (show_stack) from [<c0566ae0>] (dump_stack+0x80/0x9c)
> [<c0566ae0>] (dump_stack) from [<c003f61c>] (warn_slowpath_common+0x68/0x8c)
> [<c003f61c>] (warn_slowpath_common) from [<c003f65c>] (warn_slowpath_null+0x1c/0x24)
> [<c003f65c>] (warn_slowpath_null) from [<c02f7e10>] (gpiod_set_raw_value+0x40/0x4c)
> [<c02f7e10>] (gpiod_set_raw_value) from [<c0308fbc>] (gpio_backlight_update_status+0x4c/0x74)
> [<c0308fbc>] (gpio_backlight_update_status) from [<c030914c>] (gpio_backlight_probe+0x168/0x254)
> [<c030914c>] (gpio_backlight_probe) from [<c0378fa8>] (platform_drv_probe+0x18/0x48)
> [<c0378fa8>] (platform_drv_probe) from [<c0377c40>] (driver_probe_device+0x10c/0x238)
> [<c0377c40>] (driver_probe_device) from [<c0376330>] (bus_for_each_drv+0x44/0x8c)
> [<c0376330>] (bus_for_each_drv) from [<c0377afc>] (device_attach+0x74/0x8c)
> [<c0377afc>] (device_attach) from [<c03771c4>] (bus_probe_device+0x88/0xb0)
> [<c03771c4>] (bus_probe_device) from [<c03775c8>] (deferred_probe_work_func+0x64/0x94)
> [<c03775c8>] (deferred_probe_work_func) from [<c00572e8>] (process_one_work+0x1b4/0x4bc)
> [<c00572e8>] (process_one_work) from [<c00579d0>] (worker_thread+0x11c/0x398)
> [<c00579d0>] (worker_thread) from [<c005dfd8>] (kthread+0xc8/0xe4)
> [<c005dfd8>] (kthread) from [<c000e768>] (ret_from_fork+0x14/0x2c)
> 
> Fix this by using gpio_set_value_cansleep() as suggested in
> drivers/gpio/gpiolib.c:2364. This is what the other backlight drivers
> are also doing.

OK, I see.
However, gpio_backlight drive can be used by a lot of gpio drivers.
In some cases, 'can_sleep' is 'false' and gpio_set_value_cansleep()
is unnecessary.

In my opinion, gpio_set_value_cansleep() or gpio_set_value() can be
called selectively by 'can_sleep' value.

How about the following?

-       gpio_set_value(gbl->gpio, brightness ? gbl->active : !gbl->active);
+       if (gpio_cansleep(gbl->gpio))
+               gpio_set_value_cansleep(gbl->gpio,
+                                       brightness ? gbl->active : !gbl->active);
+       else
+               gpio_set_value(gbl->gpio, brightness ? gbl->active : !gbl->active);

Best regards,
Jingoo Han

> 
> Signed-off-by: Tony Lindgren <tony@atomide.com>
> 
> --- a/drivers/video/backlight/gpio_backlight.c
> +++ b/drivers/video/backlight/gpio_backlight.c
> @@ -38,7 +38,8 @@ static int gpio_backlight_update_status(struct backlight_device *bl)
>  	    bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
>  		brightness = 0;
> 
> -	gpio_set_value(gbl->gpio, brightness ? gbl->active : !gbl->active);
> +	gpio_set_value_cansleep(gbl->gpio,
> +				brightness ? gbl->active : !gbl->active);
> 
>  	return 0;
>  }
> --


^ permalink raw reply

* Re: [PATCH] backlight: gpio-backlight: Fix warning when the GPIO is on a I2C chip
From: Tony Lindgren @ 2014-05-09  3:09 UTC (permalink / raw)
  To: Jingoo Han
  Cc: 'Lee Jones', linux-kernel, linux-fbdev, linux-omap,
	'Bryan Wu', 'Jean-Christophe Plagniol-Villard',
	'Tomi Valkeinen'
In-Reply-To: <004701cf6b2d$e1a39c10$a4ead430$%han@samsung.com>

* Jingoo Han <jg1.han@samsung.com> [140508 19:25]:
> On Friday, May 09, 2014 10:25 AM, Lee Jones wrote:
> > 
> > If the GPIO for the backlight is on an I2C chip, we currently
> > get nasty warnings like this during the boot:
> > 
> > WARNING: CPU: 0 PID: 6 at drivers/gpio/gpiolib.c:2364 gpiod_set_raw_value+0x40/0x4c()
> > Modules linked in:
> > CPU: 0 PID: 6 Comm: kworker/u2:0 Not tainted 3.15.0-rc4-12393-gcde9f4e #400
> > Workqueue: deferwq deferred_probe_work_func
> > [<c0014cbc>] (unwind_backtrace) from [<c001191c>] (show_stack+0x10/0x14)
> > [<c001191c>] (show_stack) from [<c0566ae0>] (dump_stack+0x80/0x9c)
> > [<c0566ae0>] (dump_stack) from [<c003f61c>] (warn_slowpath_common+0x68/0x8c)
> > [<c003f61c>] (warn_slowpath_common) from [<c003f65c>] (warn_slowpath_null+0x1c/0x24)
> > [<c003f65c>] (warn_slowpath_null) from [<c02f7e10>] (gpiod_set_raw_value+0x40/0x4c)
> > [<c02f7e10>] (gpiod_set_raw_value) from [<c0308fbc>] (gpio_backlight_update_status+0x4c/0x74)
> > [<c0308fbc>] (gpio_backlight_update_status) from [<c030914c>] (gpio_backlight_probe+0x168/0x254)
> > [<c030914c>] (gpio_backlight_probe) from [<c0378fa8>] (platform_drv_probe+0x18/0x48)
> > [<c0378fa8>] (platform_drv_probe) from [<c0377c40>] (driver_probe_device+0x10c/0x238)
> > [<c0377c40>] (driver_probe_device) from [<c0376330>] (bus_for_each_drv+0x44/0x8c)
> > [<c0376330>] (bus_for_each_drv) from [<c0377afc>] (device_attach+0x74/0x8c)
> > [<c0377afc>] (device_attach) from [<c03771c4>] (bus_probe_device+0x88/0xb0)
> > [<c03771c4>] (bus_probe_device) from [<c03775c8>] (deferred_probe_work_func+0x64/0x94)
> > [<c03775c8>] (deferred_probe_work_func) from [<c00572e8>] (process_one_work+0x1b4/0x4bc)
> > [<c00572e8>] (process_one_work) from [<c00579d0>] (worker_thread+0x11c/0x398)
> > [<c00579d0>] (worker_thread) from [<c005dfd8>] (kthread+0xc8/0xe4)
> > [<c005dfd8>] (kthread) from [<c000e768>] (ret_from_fork+0x14/0x2c)
> > 
> > Fix this by using gpio_set_value_cansleep() as suggested in
> > drivers/gpio/gpiolib.c:2364. This is what the other backlight drivers
> > are also doing.
> 
> OK, I see.
> However, gpio_backlight drive can be used by a lot of gpio drivers.
> In some cases, 'can_sleep' is 'false' and gpio_set_value_cansleep()
> is unnecessary.
> 
> In my opinion, gpio_set_value_cansleep() or gpio_set_value() can be
> called selectively by 'can_sleep' value.
> 
> How about the following?
> 
> -       gpio_set_value(gbl->gpio, brightness ? gbl->active : !gbl->active);
> +       if (gpio_cansleep(gbl->gpio))
> +               gpio_set_value_cansleep(gbl->gpio,
> +                                       brightness ? gbl->active : !gbl->active);
> +       else
> +               gpio_set_value(gbl->gpio, brightness ? gbl->active : !gbl->active);

It should be always fine to use gpio_set_value_cansleep(), see your
old thread from few years ago related to another backlight driver:

https://lkml.org/lkml/2012/12/5/343

Regards,

Tony

^ permalink raw reply

* Re: [PATCH] backlight: gpio-backlight: Fix warning when the GPIO is on a I2C chip
From: Jingoo Han @ 2014-05-09  3:42 UTC (permalink / raw)
  To: 'Tony Lindgren'
  Cc: 'Lee Jones', linux-kernel, linux-fbdev, linux-omap,
	'Bryan Wu', 'Jean-Christophe Plagniol-Villard',
	'Tomi Valkeinen', 'Linus Walleij',
	'Alexandre Courbot', 'Russell King',
	'Jingoo Han'
In-Reply-To: <20140509030925.GN2198@atomide.com>

On Friday, May 09, 2014 12:09 PM, Tony Lindgren wrote:
> On Friday, May 09, 2014 11:25 AM, Jingoo Han wrote:
> > On Friday, May 09, 2014 10:25 AM, Lee Jones wrote:
> > >
> > > If the GPIO for the backlight is on an I2C chip, we currently
> > > get nasty warnings like this during the boot:
> > >
> > > WARNING: CPU: 0 PID: 6 at drivers/gpio/gpiolib.c:2364 gpiod_set_raw_value+0x40/0x4c()
> > > Modules linked in:
> > > CPU: 0 PID: 6 Comm: kworker/u2:0 Not tainted 3.15.0-rc4-12393-gcde9f4e #400
> > > Workqueue: deferwq deferred_probe_work_func
> > > [<c0014cbc>] (unwind_backtrace) from [<c001191c>] (show_stack+0x10/0x14)
> > > [<c001191c>] (show_stack) from [<c0566ae0>] (dump_stack+0x80/0x9c)
> > > [<c0566ae0>] (dump_stack) from [<c003f61c>] (warn_slowpath_common+0x68/0x8c)
> > > [<c003f61c>] (warn_slowpath_common) from [<c003f65c>] (warn_slowpath_null+0x1c/0x24)
> > > [<c003f65c>] (warn_slowpath_null) from [<c02f7e10>] (gpiod_set_raw_value+0x40/0x4c)
> > > [<c02f7e10>] (gpiod_set_raw_value) from [<c0308fbc>] (gpio_backlight_update_status+0x4c/0x74)
> > > [<c0308fbc>] (gpio_backlight_update_status) from [<c030914c>] (gpio_backlight_probe+0x168/0x254)
> > > [<c030914c>] (gpio_backlight_probe) from [<c0378fa8>] (platform_drv_probe+0x18/0x48)
> > > [<c0378fa8>] (platform_drv_probe) from [<c0377c40>] (driver_probe_device+0x10c/0x238)
> > > [<c0377c40>] (driver_probe_device) from [<c0376330>] (bus_for_each_drv+0x44/0x8c)
> > > [<c0376330>] (bus_for_each_drv) from [<c0377afc>] (device_attach+0x74/0x8c)
> > > [<c0377afc>] (device_attach) from [<c03771c4>] (bus_probe_device+0x88/0xb0)
> > > [<c03771c4>] (bus_probe_device) from [<c03775c8>] (deferred_probe_work_func+0x64/0x94)
> > > [<c03775c8>] (deferred_probe_work_func) from [<c00572e8>] (process_one_work+0x1b4/0x4bc)
> > > [<c00572e8>] (process_one_work) from [<c00579d0>] (worker_thread+0x11c/0x398)
> > > [<c00579d0>] (worker_thread) from [<c005dfd8>] (kthread+0xc8/0xe4)
> > > [<c005dfd8>] (kthread) from [<c000e768>] (ret_from_fork+0x14/0x2c)
> > >
> > > Fix this by using gpio_set_value_cansleep() as suggested in
> > > drivers/gpio/gpiolib.c:2364. This is what the other backlight drivers
> > > are also doing.
> >
> > OK, I see.
> > However, gpio_backlight drive can be used by a lot of gpio drivers.
> > In some cases, 'can_sleep' is 'false' and gpio_set_value_cansleep()
> > is unnecessary.
> >
> > In my opinion, gpio_set_value_cansleep() or gpio_set_value() can be
> > called selectively by 'can_sleep' value.
> >
> > How about the following?
> >
> > -       gpio_set_value(gbl->gpio, brightness ? gbl->active : !gbl->active);
> > +       if (gpio_cansleep(gbl->gpio))
> > +               gpio_set_value_cansleep(gbl->gpio,
> > +                                       brightness ? gbl->active : !gbl->active);
> > +       else
> > +               gpio_set_value(gbl->gpio, brightness ? gbl->active : !gbl->active);
> 
> It should be always fine to use gpio_set_value_cansleep(), see your
> old thread from few years ago related to another backlight driver:
> 
> https://lkml.org/lkml/2012/12/5/343

(+cc Linus Walleij, Alexandre Courbot, Russell King)

OK, I see.

gpio_set_value_cansleep() calls gpiod_set_raw_value_cansleep(),
and gpio_set_value() calls gpiod_set_raw_value() as below.

./drivers/gpio/gpiolib.c
void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value)
{
        might_sleep_if(extra_checks);
        if (!desc)
                return;
        _gpiod_set_raw_value(desc, value);
}
EXPORT_SYMBOL_GPL(gpiod_set_raw_value_cansleep);

./drivers/gpio/gpiolib.c
void gpiod_set_raw_value(struct gpio_desc *desc, int value)
{
        if (!desc)
                return;
        /* Should be using gpio_set_value_cansleep() */
        WARN_ON(desc->chip->can_sleep);
        _gpiod_set_raw_value(desc, value);
}
EXPORT_SYMBOL_GPL(gpiod_set_raw_value);

Then, the difference between gpio_set_value_cansleep() or
gpio_set_value() is whether might_sleep_if(extra_checks) is
called or not.

So, you said that "It should be always fine to use 
gpio_set_value_cansleep()", right?

Linus Walleij,
Is there any reason to keep these two functions such as
gpiod_set_raw_value_cansleep() and gpiod_set_raw_value()?

Best regards,
Jingoo Han


^ permalink raw reply

* Re: [PATCH 4/4] ARM: dts: Add LCD panel sharp ls037v7dw01 support for omap3-evm and ldp
From: Tomi Valkeinen @ 2014-05-09  7:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140508233628.GJ2198@atomide.com>

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

On 09/05/14 02:36, Tony Lindgren wrote:

> --- /dev/null
> +++ b/arch/arm/boot/dts/omap-panel-sharp-ls037v7dw01.dtsi
> @@ -0,0 +1,82 @@
> +/*
> + * Common file for omap dpi panels with QVGA and reset pins
> + *
> + * Note that the board specifc DTS file needs to specify
> + * at minimum the GPIO enable-gpios for display, and
> + * gpios for gpio-backlight.
> + */

This looks very board specific to me... The regulator and the use of
mcspi1 depend on the board, so this file can't be used on just any omap
board with the same panel. And this can (probably) only be used on
boards with a single display. Do those boards have tv-out?

So I have nothing against having common files, but shouldn't this be
named something more specific? If the boards involved are TI's OMAP3
development boards, maybe this should be something like...
omap3-ti-dev-panel-sharp-ls037v7dw01.dtsi. Well, that's a quite long one.

> +/ {
> +	aliases {
> +		display0 = &lcd0;
> +	};
> +
> +	backlight0: backlight {
> +		compatible = "gpio-backlight";
> +	};
> +
> +	/* 3.3V GPIO controlled regulator for LCD_ENVDD */
> +	lcd_3v3: regulator-lcd-3v3 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "lcd_3v3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		startup-delay-us = <70000>;
> +		regulator-always-on;

Why always-on?

 Tomi



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

^ permalink raw reply

* Re: [PATCH 3/4] OMAPDSS: panel-sharp-ls037v7dw01: add device tree support
From: Tomi Valkeinen @ 2014-05-09  7:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140508233300.GI2198@atomide.com>

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

On 09/05/14 02:33, Tony Lindgren wrote:

> We can pass the GPIO configuration for ls037v7dw01 in a standard
> gpios property.
> 
> Signed-off-by: Tony Lindgren <tony@atomide.com>
> 
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/panel/sharp,ls037v7dw01.txt
> @@ -0,0 +1,56 @@
> +SHARP LS037V7DW01 TFT-LCD panel
> +
> +Required properties:
> +- compatible: should be "sharp,ls037v7dw01"
> +
> +Optional properties:
> +- enable-gpios: a GPIO spec for the optional enable pin
> +  this pin is the INI pin as specified in the LS037V7DW01.pdf file.
> +- reset-gpios: a GPIO spec for the optional reset pin
> +  this pin is the RESB pin as specified in the LS037V7DW01.pdf file.
> +- mode-gpios: a GPIO 
> +  ordered MO, LR, and UD as specified in the LS037V7DW01.pdf file.
> +
> +This binding is compatible with the simple-panel binding, which is specified
> +in simple-panel.txt in this directory.

The video port data is required also. See for example
Documentation/devicetree/bindings/video/panel-dsi-cm.txt or
Documentation/devicetree/bindings/video/hdmi-connector.txt.

Also, all the bindings I've made are in
Documentation/devicetree/bindings/video/, and I'd rather keep the video
bindings OMAP uses in the same place.

> +This panel can have zero to five GPIOs to configure
> +to change configuration between QVGA and VGA mode
> +and the scan direction. As these pins can be also
> +configured with external pulls, all the GPIOs are
> +considered optional with holes in the array.
> +
> +Example when connected to a omap2+ based device:
> +
> +	lcd0: display {
> +		compatible = "sharp,ls037v7dw01";
> +		power-supply = <&lcd_3v3>;
> +		enable-gpios = <&gpio5 24 GPIO_ACTIVE_HIGH>;	/* gpio152, lcd INI */
> +		reset-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>;	/* gpio155, lcd RESB */
> +		mode-gpios = <&gpio5 26 GPIO_ACTIVE_HIGH	/* gpio154, lcd MO */
> +			      &gpio1 2 GPIO_ACTIVE_HIGH		/* gpio2, lcd LR */
> +			      &gpio1 3 GPIO_ACTIVE_HIGH>;	/* gpio3, lcd UD */
> +
> +		panel-timing {
> +			clock-frequency = <19200000>;
> +			hback-porch = <28>;
> +			hactive = <480>;
> +			hfront-porch = <1>;
> +			hsync-len = <2>;
> +			vback-porch = <1>;
> +			vactive = <640>;
> +			vfront-porch = <1>;
> +			vsync-len = <1>;
> +			hsync-active = <0>;
> +			vsync-active = <0>;
> +			de-active = <1>;
> +			pixelclk-active = <1>;
> +		};

I don't think we should define panel-timing here. We know it's
sharp,ls037v7dw01, so the driver knows the video timings. Also, if we
would extend the driver to support both resolution modes, it needs to
support two different timings, so the above doesn't work in that case
either.

Although if the MO gpio is not controlled by the driver, we should tell
the driver whether that gpio is high or low.

> +static int sharp_ls_probe_of(struct platform_device *pdev)
> +{
> +	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
> +	struct device_node *node = pdev->dev.of_node;
> +	struct omap_dss_device *in;
> +	struct display_timing timing;
> +	struct videomode vm;
> +	int r;
> +
> +	ddata->vcc = devm_regulator_get(&pdev->dev, "envdd");
> +	if (IS_ERR(ddata->vcc)) {
> +		dev_err(&pdev->dev, "failed to get regulator\n");
> +		return PTR_ERR(ddata->vcc);
> +	}
> +
> +	r = regulator_enable(ddata->vcc);
> +	if (r != 0) {
> +		dev_err(&pdev->dev, "failed to enable regulator\n");
> +		return r;
> +	}

The regulator should be enabled when the panel is enabled, not at probe
time.

> +static const struct of_device_id sharp_ls_of_match[] = {
> +	{ .compatible = "sharp,ls037v7dw01", },

At the moment our display drivers are OMAP specific, and for that reason
we should prefix the compatible strings with "omapdss,". For example,
drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c:

	{ .compatible = "omapdss,panel-dsi-cm", },

But we should still have the right compatible string in the .dts, so we
convert the compatible name in arch/arm/mach-omap2/display.c, with
'dss_compat_conv_list' array, to which this panel's name should be added.

 Tomi



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

^ permalink raw reply

* Re: [PATCH 1/4] OMAPDSS: Fix DSS clock multiplier issue on 3703 and probably 3630
From: Tomi Valkeinen @ 2014-05-09  7:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1398815562-24113-2-git-send-email-tony@atomide.com>

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

On 30/04/14 02:52, Tony Lindgren wrote:
> Otherwise we can get often errors like the following and the
> display won't come on:
> 
> omapdss APPLY error: FIFO UNDERFLOW on gfx, disabling the overlay
> omapdss APPLY error: SYNC_LOST on channel lcd, restarting
> the output with video overlays disabled
> 
> There are some earlier references to this issue:
> 
> http://www.spinics.net/lists/linux-omap/msg59511.html
> http://www.spinics.net/lists/linux-omap/msg59724.html

Those don't sound like the same issue, but it's hard to say. What kind
of clock rates do you get? Cat you paste debugfs/omapdss/clk, with and
without this patch?

What resolution do you have? If it's a very high resolution (say, DVI
output to a monitor), it could just be an issue of
not-enough-memory-bandwidth.

> It seems that it's safe to set the lower values even for 3630.
> If we can confirm that 3630 works with the higher values
> reliably we can add further detection.
> 
> Signed-off-by: Tony Lindgren <tony@atomide.com>
> ---
>  drivers/video/fbdev/omap2/dss/dss.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
> index d55266c..ad6561f 100644
> --- a/drivers/video/fbdev/omap2/dss/dss.c
> +++ b/drivers/video/fbdev/omap2/dss/dss.c
> @@ -707,9 +707,10 @@ static const struct dss_features omap34xx_dss_feats __initconst = {
>  	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3,
>  };
>  
> +/* Supposedly 3630 can use div 32 mult 2, but that needs to be rechecked */
>  static const struct dss_features omap3630_dss_feats __initconst = {
> -	.fck_div_max		=	32,
> -	.dss_fck_multiplier	=	1,
> +	.fck_div_max		=	16,
> +	.dss_fck_multiplier	=	2,

These values tell about the clock hardware, they are not settings that
can be changed to change the clock. OMAP3630 has a fixed x2 multiplier
and a divider with maximum value of 16.

 Tomi



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

^ 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