Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH -next 00/26] treewide: Use dma_zalloc_coherent
From: Joe Perches @ 2014-06-15 20:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: linuxppc-dev, linux-sh, linux-ide, linux-nvme, linux-crypto,
	dmaengine, dri-devel, linux-rdma, linux-arm-msm, linux-mmc,
	netdev, e1000-devel, ath10k, linux-wireless, wcn36xx, users,
	linux-scsi, linux-usb, linux-fbdev, alsa-devel

Use the zeroing function instead of dma_alloc_coherent & memset(,0,)

Joe Perches (26):
  powerpc: Use dma_zalloc_coherent
  sh: Use dma_zalloc_coherent
  ata: Use dma_zalloc_coherent
  block: Use dma_zalloc_coherent
  crypto: Use dma_zalloc_coherent
  dma: Use dma_zalloc_coherent
  gpu: Use dma_zalloc_coherent
  infiniband: Use dma_zalloc_coherent
  mmc: Use dma_zalloc_coherent
  broadcom: Use dma_zalloc_coherent
  hisilicon: Use dma_zalloc_coherent
  intel: Use dma_zalloc_coherent
  ath: Use dma_zalloc_coherent
  rt2x00: Use dma_zalloc_coherent
  bfa: Use dma_zalloc_coherent
  bnx2fc: Use dma_zalloc_coherent
  bnx2i: Use dma_zalloc_coherent
  dpt_i2o: Use dma_zalloc_coherent
  lpfc: Use dma_zalloc_coherent
  megaraid: Use dma_zalloc_coherent
  mvsas: Use dma_zalloc_coherent
  qla2xxx: Use dma_zalloc_coherent
  qla4xxx: Use dma_zalloc_coherent
  usb: Use dma_zalloc_coherent
  fbdev: Use dma_zalloc_coherent
  sound: Use dma_zalloc_coherent

 arch/powerpc/platforms/pasemi/dma_lib.c       |  8 ++--
 arch/powerpc/sysdev/fsl_rmu.c                 |  9 ++--
 arch/sh/mm/consistent.c                       |  4 +-
 drivers/ata/sata_fsl.c                        |  5 +--
 drivers/block/nvme-core.c                     |  5 +--
 drivers/crypto/amcc/crypto4xx_core.c          |  8 ++--
 drivers/crypto/ixp4xx_crypto.c                |  8 ++--
 drivers/dma/imx-sdma.c                        |  5 +--
 drivers/dma/mxs-dma.c                         |  8 ++--
 drivers/gpu/drm/drm_pci.c                     |  6 +--
 drivers/infiniband/hw/cxgb3/cxio_hal.c        |  7 ++--
 drivers/infiniband/hw/mthca/mthca_memfree.c   |  5 +--
 drivers/infiniband/hw/ocrdma/ocrdma_hw.c      | 20 ++++-----
 drivers/infiniband/hw/ocrdma/ocrdma_stats.c   |  6 +--
 drivers/infiniband/hw/ocrdma/ocrdma_verbs.c   |  8 ++--
 drivers/mmc/host/msm_sdcc.c                   |  8 ++--
 drivers/net/ethernet/broadcom/bcm63xx_enet.c  |  6 +--
 drivers/net/ethernet/hisilicon/hix5hd2_gmac.c |  5 +--
 drivers/net/ethernet/intel/ixgb/ixgb_main.c   |  6 +--
 drivers/net/wireless/ath/ath10k/pci.c         |  8 +---
 drivers/net/wireless/ath/ath10k/wmi.c         |  8 +---
 drivers/net/wireless/ath/wcn36xx/dxe.c        |  6 +--
 drivers/net/wireless/rt2x00/rt2x00mmio.c      |  8 ++--
 drivers/scsi/bfa/bfad_bsg.c                   |  6 +--
 drivers/scsi/bnx2fc/bnx2fc_hwi.c              | 59 ++++++++++++---------------
 drivers/scsi/bnx2fc/bnx2fc_tgt.c              | 51 ++++++++++-------------
 drivers/scsi/bnx2i/bnx2i_hwi.c                | 14 +++----
 drivers/scsi/dpt_i2o.c                        | 19 ++++-----
 drivers/scsi/lpfc/lpfc_bsg.c                  |  5 +--
 drivers/scsi/lpfc/lpfc_init.c                 | 22 ++++------
 drivers/scsi/lpfc/lpfc_mbox.c                 |  6 +--
 drivers/scsi/lpfc/lpfc_sli.c                  | 14 +++----
 drivers/scsi/megaraid/megaraid_sas_fusion.c   |  9 ++--
 drivers/scsi/mvsas/mv_init.c                  | 26 +++++-------
 drivers/scsi/qla2xxx/qla_init.c               | 10 ++---
 drivers/scsi/qla4xxx/ql4_init.c               |  5 +--
 drivers/scsi/qla4xxx/ql4_mbx.c                | 21 ++++------
 drivers/scsi/qla4xxx/ql4_nx.c                 |  5 +--
 drivers/scsi/qla4xxx/ql4_os.c                 | 12 +++---
 drivers/usb/dwc2/hcd_ddma.c                   | 20 ++++-----
 drivers/usb/host/uhci-hcd.c                   |  7 ++--
 drivers/video/fbdev/da8xx-fb.c                |  9 ++--
 sound/aoa/soundbus/i2sbus/core.c              | 12 ++----
 sound/sparc/dbri.c                            |  6 +--
 44 files changed, 197 insertions(+), 308 deletions(-)

-- 
1.8.1.2.459.gbcd45b4.dirty


^ permalink raw reply

* [PATCH -next 25/26] fbdev: Use dma_zalloc_coherent
From: Joe Perches @ 2014-06-15 20:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jean-Christophe Plagniol-Villard, Tomi Valkeinen, linux-fbdev
In-Reply-To: <cover.1402863904.git.joe@perches.com>

Use the zeroing function instead of dma_alloc_coherent & memset(,0,)

Signed-off-by: Joe Perches <joe@perches.com>
---
 drivers/video/fbdev/da8xx-fb.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c
index a8484f7..788f6b3 100644
--- a/drivers/video/fbdev/da8xx-fb.c
+++ b/drivers/video/fbdev/da8xx-fb.c
@@ -1447,18 +1447,15 @@ static int fb_probe(struct platform_device *device)
 		da8xx_fb_fix.line_length - 1;
 
 	/* allocate palette buffer */
-	par->v_palette_base = dma_alloc_coherent(NULL,
-					       PALETTE_SIZE,
-					       (resource_size_t *)
-					       &par->p_palette_base,
-					       GFP_KERNEL | GFP_DMA);
+	par->v_palette_base = dma_zalloc_coherent(NULL, PALETTE_SIZE,
+						  (resource_size_t *)&par->p_palette_base,
+						  GFP_KERNEL | GFP_DMA);
 	if (!par->v_palette_base) {
 		dev_err(&device->dev,
 			"GLCD: kmalloc for palette buffer failed\n");
 		ret = -EINVAL;
 		goto err_release_fb_mem;
 	}
-	memset(par->v_palette_base, 0, PALETTE_SIZE);
 
 	par->irq = platform_get_irq(device, 0);
 	if (par->irq < 0) {
-- 
1.8.1.2.459.gbcd45b4.dirty


^ permalink raw reply related

* [PATCH] video: fbdev: sis: init301.c:  Cleaning up useless if statement
From: Rickard Strandqvist @ 2014-06-15 21:52 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen
  Cc: Rickard Strandqvist, Jingoo Han, Laurent Pinchart, Rob Clark,
	linux-fbdev, linux-kernel

The same code regardless of the outcome of the if statement. This may of
course be a miss and there should be a difference in the code.
And sets a variable that is missed, a probable cut and paste mistake.

This was partly found using a static code analysis program called cppcheck.

Rickard Strandqvist (1):
  video: fbdev: sis: init301.c:  Cleaning up useless if statement

 drivers/video/fbdev/sis/init301.c |   19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

-- 
1.7.10.4


^ permalink raw reply

* [PATCH] video: fbdev: sis: init301.c:  Cleaning up useless if statement
From: Rickard Strandqvist @ 2014-06-15 21:52 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen
  Cc: Rickard Strandqvist, Jingoo Han, Laurent Pinchart, Rob Clark,
	linux-fbdev, linux-kernel
In-Reply-To: <1402869130-4962-1-git-send-email-rickard_strandqvist@spectrumdigital.se>

Same code is run regardless of the outcome of the if statement.
And sets a variable that is missed, a probable cut and paste mistake.

Signed-off-by: Rickard Strandqvist <rickard_strandqvist@spectrumdigital.se>
---
 drivers/video/fbdev/sis/init301.c |   19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/video/fbdev/sis/init301.c b/drivers/video/fbdev/sis/init301.c
index a89e3ca..008ab4a 100644
--- a/drivers/video/fbdev/sis/init301.c
+++ b/drivers/video/fbdev/sis/init301.c
@@ -1714,7 +1714,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
 			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
 			    } else {
 			       SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
-			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRS  =  112;
+			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
 			       SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
 			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
 			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
@@ -6850,11 +6850,9 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
 	   if(SiS_Pr->SiS_VGAHDE >= 1280) {
               tempch = 20;
               tempbx &= ~0x20;
-           } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
-              tempch = 25;
            } else {
-	      tempch = 25; /* OK */
-	   }
+              tempch = 25; /* OK */
+          }
         }
      }
   }
@@ -7971,13 +7969,8 @@ SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
          }
       } else {						/* ---- PAL ---- */
          /* We don't play around with FSCI in PAL mode */
-         if(resindex = 0x04) {
-            SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
-            SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on */
-         } else {
-            SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
-            SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on */
-         }
+         SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF);	/* loop filter off */
+         SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE);	/* ACIV on */
       }
 
 #endif  /* 300 */
@@ -9663,8 +9656,6 @@ SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 	      delay = 0x0a;
 	   } else if(IS_SIS740) {
 	      delay = 0x00;
-	   } else if(SiS_Pr->ChipType < SIS_330) {
-	      delay = 0x0c;
 	   } else {
 	      delay = 0x0c;
 	   }
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH -next 25/26] fbdev: Use dma_zalloc_coherent
From: Geert Uytterhoeven @ 2014-06-15 22:16 UTC (permalink / raw)
  To: Joe Perches
  Cc: linux-kernel@vger.kernel.org, Jean-Christophe Plagniol-Villard,
	Tomi Valkeinen, Linux Fbdev development list
In-Reply-To: <881b8f8d85c96b6e9d8735aa10bbf18468688b9d.1402863905.git.joe@perches.com>

On Sun, Jun 15, 2014 at 10:37 PM, Joe Perches <joe@perches.com> wrote:
> diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c
> index a8484f7..788f6b3 100644
> --- a/drivers/video/fbdev/da8xx-fb.c
> +++ b/drivers/video/fbdev/da8xx-fb.c
> @@ -1447,18 +1447,15 @@ static int fb_probe(struct platform_device *device)
>                 da8xx_fb_fix.line_length - 1;
>
>         /* allocate palette buffer */
> -       par->v_palette_base = dma_alloc_coherent(NULL,
> -                                              PALETTE_SIZE,
> -                                              (resource_size_t *)
> -                                              &par->p_palette_base,
> -                                              GFP_KERNEL | GFP_DMA);
> +       par->v_palette_base = dma_zalloc_coherent(NULL, PALETTE_SIZE,
> +                                                 (resource_size_t *)&par->p_palette_base,

Suggestion for further cleanup: It seems this cast is no longer needed.

> +                                                 GFP_KERNEL | GFP_DMA);

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 -next 25/26] fbdev: Use dma_zalloc_coherent
From: Joe Perches @ 2014-06-15 23:32 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: linux-kernel@vger.kernel.org, Jean-Christophe Plagniol-Villard,
	Tomi Valkeinen, Linux Fbdev development list
In-Reply-To: <CAMuHMdWHJ1LY0r1aMZViQW_ZZYrbGkHb4Hpkt+YZfRbERfyE3Q@mail.gmail.com>

On Mon, 2014-06-16 at 00:16 +0200, Geert Uytterhoeven wrote:
> On Sun, Jun 15, 2014 at 10:37 PM, Joe Perches <joe@perches.com> wrote:
> > diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c
[]
> > @@ -1447,18 +1447,15 @@ static int fb_probe(struct platform_device *device)
> >                 da8xx_fb_fix.line_length - 1;
> >
> >         /* allocate palette buffer */
> > -       par->v_palette_base = dma_alloc_coherent(NULL,
> > -                                              PALETTE_SIZE,
> > -                                              (resource_size_t *)
> > -                                              &par->p_palette_base,
> > -                                              GFP_KERNEL | GFP_DMA);
> > +       par->v_palette_base = dma_zalloc_coherent(NULL, PALETTE_SIZE,
> > +                                                 (resource_size_t *)&par->p_palette_base,
> 
> Suggestion for further cleanup: It seems this cast is no longer needed.

Sure, but after this is applied.


^ permalink raw reply

* [RFC 0/2]  backlight: add new tps611xx backlight driver
From: Daniel Jeong @ 2014-06-16  2:17 UTC (permalink / raw)
  To: Jingoo Han, Bryan Wu, Lee Jones, Jean-Christophe Plagniol-Villard,
	Tomi Valkeinen, Grant Likely, Rob Herring, Randy Dunlap
  Cc: Daniel Jeong, linux-kernel, linux-fbdev, devicetree, linux-doc,
	Daniel Jeong

This driver a general version for tps611xx backlgiht chips of TI.
It supports tps61158, tps61161, tps61163 and tps61165 backlight driver
based on EasyScale protocol.

Daniel Jeong (2):
  backlight: add new tps611xx backlight driver
  backlight: add new tps611xx backlight device tree support

 .../video/backlight/tps611xx-backlight.txt         |   16 +
 drivers/video/backlight/Kconfig                    |    7 +
 drivers/video/backlight/Makefile                   |    1 +
 drivers/video/backlight/tps611xx_bl.c              |  486 ++++++++++++++++++++
 include/linux/platform_data/tps611xx_bl.h          |   30 ++
 5 files changed, 540 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
 create mode 100644 drivers/video/backlight/tps611xx_bl.c
 create mode 100644 include/linux/platform_data/tps611xx_bl.h

-- 
1.7.9.5


^ permalink raw reply

* [RFC 1/2] backlight: add new tps611xx backlight driver
From: Daniel Jeong @ 2014-06-16  2:17 UTC (permalink / raw)
  To: Jingoo Han, Bryan Wu, Lee Jones, Jean-Christophe Plagniol-Villard,
	Tomi Valkeinen, Grant Likely, Rob Herring, Randy Dunlap
  Cc: Daniel Jeong, linux-kernel, linux-fbdev, devicetree, linux-doc,
	Daniel Jeong
In-Reply-To: <1402885043-3626-1-git-send-email-gshark.jeong@gmail.com>

This driver a general version for tps611xx backlgiht chips of TI.
It supports tps61158, tps61161, tps61163 and tps61165 backlight driver
based on EasyScale protocol.

Signed-off-by: Daniel Jeong <gshark.jeong@gmail.com>
---
 drivers/video/backlight/Kconfig           |    7 +
 drivers/video/backlight/Makefile          |    1 +
 drivers/video/backlight/tps611xx_bl.c     |  486 +++++++++++++++++++++++++++++
 include/linux/platform_data/tps611xx_bl.h |   30 ++
 4 files changed, 524 insertions(+)
 create mode 100644 drivers/video/backlight/tps611xx_bl.c
 create mode 100644 include/linux/platform_data/tps611xx_bl.h

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 5a3eb2e..c779a85 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -418,6 +418,13 @@ config BACKLIGHT_TPS65217
 	  If you have a Texas Instruments TPS65217 say Y to enable the
 	  backlight driver.
 
+config BACKLIGHT_TPS611xx
+	tristate "TPS611xx Backlight"
+	depends on BACKLIGHT_CLASS_DEVICE && GPIOLIB
+	help
+	  This supports TI TPS61158, TPS61161, TPS61163 and TPS61165
+	  backlight driver based on EasyScale Protocol.
+
 config BACKLIGHT_AS3711
 	tristate "AS3711 Backlight"
 	depends on BACKLIGHT_CLASS_DEVICE && MFD_AS3711
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index bb82002..44f1641 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -52,4 +52,5 @@ obj-$(CONFIG_BACKLIGHT_PWM)		+= pwm_bl.o
 obj-$(CONFIG_BACKLIGHT_SAHARA)		+= kb3886_bl.o
 obj-$(CONFIG_BACKLIGHT_TOSA)		+= tosa_bl.o
 obj-$(CONFIG_BACKLIGHT_TPS65217)	+= tps65217_bl.o
+obj-$(CONFIG_BACKLIGHT_TPS611xx)	+= tps611xx_bl.o
 obj-$(CONFIG_BACKLIGHT_WM831X)		+= wm831x_bl.o
diff --git a/drivers/video/backlight/tps611xx_bl.c b/drivers/video/backlight/tps611xx_bl.c
new file mode 100644
index 0000000..4b76cdd
--- /dev/null
+++ b/drivers/video/backlight/tps611xx_bl.c
@@ -0,0 +1,486 @@
+/*
+ * Simple driver for Texas Instruments TPS611XX Backlight driver chip
+ *        using EasyScale Interface. It supports TPS61158, TPS61161,
+ *        TPS61163 and TPS61165.
+ *
+ * Copyright (C) 2014 Texas Instruments
+ * Author: Daniel Jeong  <gshark.jeong@gmail.com>
+ *	       Ldd Mlp <ldd-mlp@list.ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_data/tps611xx_bl.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define CMD_FORWARD 0
+#define CMD_BACKWARD 1
+
+enum tps611xx_id {
+	TPS61158_ID = 0,
+	TPS61161_ID,
+	TPS61163_ID,
+	TPS61165_ID,
+};
+
+/*
+ * easyscale time spec
+ * @es_delay : es delay time(ns)
+ * @es_det   : es detection time(ns)
+ * @start    : start time of data stream(ns)
+ * @eos      : end time of data stream(ns)
+ * @reset    : ic shutdown time(ms)
+ * @logic_1_low : low time high bit(ns)
+ * @logic_0_low : low time low bit(ns)
+ * @ackn        : duation of ack condistion(ns)
+ * @ack_poll    : ack polling duration(ns)
+ */
+struct tps611xx_time {
+	unsigned int es_delay;
+	unsigned int es_det;
+	unsigned int start;
+	unsigned int eos;
+	unsigned int reset;
+	unsigned int logic_1_low;
+	unsigned int logic_0_low;
+	unsigned int ackn;
+	unsigned int ack_poll;
+};
+
+/*
+ * @seq : sequence of data transfer
+ * @size: size of data
+ * @brt_max : max brightness
+ * @brt_bmask : bit mask of dimming bits
+ * @rfa_bmask : bit mask of request of ack
+ */
+struct tps611xx_command {
+	int seq;
+	int size;
+	int brt_max;
+	int brt_bmask;
+	int rfa_bmask;
+};
+
+/*
+ * @id : product id
+ * @name : product name
+ * @addr : device address
+ * @cmd  : es command info
+ * @time : es time info
+ */
+struct tps611xx_esdata {
+	enum tps611xx_id id;
+	char *name;
+	int addr;
+	struct tps611xx_command cmd;
+	struct tps611xx_time time;
+};
+
+struct tps611xx_bl_data {
+	struct device *dev;
+	struct backlight_device *bled;
+	struct tps611xx_platform_data *pdata;
+
+	/*
+	 * @rfa_en : acknowlege request enable
+	 * @en_gpio: enable pin gpio no.
+	 * @esdata : easyscale data
+	 */
+	int rfa_en;
+	unsigned int en_gpio;
+	const struct tps611xx_esdata *esdata;
+};
+
+static struct tps611xx_esdata tps611xx_info[] = {
+	[TPS61158_ID] = {
+			 .id = TPS61158_ID,
+			 .name = "tps61158",
+			 .addr = 0x5800,
+			 .cmd = {
+				 .seq = CMD_FORWARD,
+				 .size = 16,
+				 .brt_max = 31,
+				 .brt_bmask = 0x1f,
+				 .rfa_bmask = 0x80},
+			 .time = {
+				  .es_delay = 100000,
+				  .es_det = 450000,
+				  .start = 3500,
+				  .eos = 3500,
+				  .reset = 4,
+				  .logic_1_low = 5000,
+				  .logic_0_low = 15000,
+				  .ackn = 900000,
+				  .ack_poll = 2000},
+			 },
+
+	[TPS61161_ID] = {
+			 .id = TPS61161_ID,
+			 .name = "tps61161",
+			 .addr = 0x7200,
+			 .cmd = {
+				 .seq = CMD_FORWARD,
+				 .size = 16,
+				 .brt_max = 31,
+				 .brt_bmask = 0x1f,
+				 .rfa_bmask = 0x80},
+			 .time = {
+				  .es_delay = 120000,
+				  .es_det = 280000,
+				  .start = 2000,
+				  .eos = 2000,
+				  .reset = 3,
+				  .logic_1_low = 3000,
+				  .logic_0_low = 7000,
+				  .ackn = 512000,
+				  .ack_poll = 2000},
+			 },
+
+	[TPS61163_ID] = {
+			 .id = TPS61163_ID,
+			 .name = "tps61163",
+			 .addr = 0x8F0000,
+			 .cmd = {
+				 .seq = CMD_BACKWARD,
+				 .size = 24,
+				 .brt_max = 511,
+				 .brt_bmask = 0x1ff,
+				 .rfa_bmask = 0x400},
+			 .time = {
+				  .es_delay = 100000,
+				  .es_det = 260000,
+				  .start = 2000,
+				  .eos = 2000,
+				  .reset = 3,
+				  .logic_1_low = 3000,
+				  .logic_0_low = 7000,
+				  .ackn = 512000,
+				  .ack_poll = 2000},
+			 },
+
+	[TPS61165_ID] = {
+			 .id = TPS61165_ID,
+			 .name = "tps61165",
+			 .addr = 0x7200,
+			 .cmd = {
+				 .seq = CMD_FORWARD,
+				 .size = 16,
+				 .brt_max = 31,
+				 .brt_bmask = 0x1f,
+				 .rfa_bmask = 0x80},
+			 .time = {
+				  .es_delay = 120000,
+				  .es_det = 280000,
+				  .start = 4000,
+				  .eos = 4000,
+				  .reset = 3,
+				  .logic_1_low = 3000,
+				  .logic_0_low = 7000,
+				  .ackn = 512000,
+				  .ack_poll = 2000},
+			 },
+};
+
+static int tps611xx_bl_update_status(struct backlight_device *bl)
+{
+	struct tps611xx_bl_data *pchip = bl_get_data(bl);
+	const struct tps611xx_esdata *esdata = pchip->esdata;
+	int data_in, t_low, t_logic, max_bmask;
+	unsigned long flags;
+
+	data_in = esdata->addr | (bl->props.brightness & esdata->cmd.brt_bmask);
+	if (pchip->rfa_en)
+		data_in |= esdata->cmd.rfa_bmask;
+
+	max_bmask = 0x1 << esdata->cmd.size;
+	t_logic = esdata->time.logic_1_low + esdata->time.logic_0_low;
+
+	local_irq_save(flags);
+	/* t_start : 2us high before data byte */
+	gpio_direction_output(pchip->en_gpio, 1);
+	ndelay(esdata->time.start);
+
+	/* forward command transfer */
+	if (esdata->cmd.seq = CMD_FORWARD) {
+		int addr_bmask = max_bmask >> 8;
+
+		for (max_bmask >>= 1; max_bmask > 0x0; max_bmask >>= 1) {
+			if (data_in & max_bmask)
+				t_low = esdata->time.logic_1_low;
+			else
+				t_low = esdata->time.logic_0_low;
+
+			gpio_direction_output(pchip->en_gpio, 0);
+			ndelay(t_low);
+			gpio_direction_output(pchip->en_gpio, 1);
+			ndelay(t_logic - t_low);
+
+			if (max_bmask = addr_bmask) {
+				gpio_direction_output(pchip->en_gpio, 0);
+				/* t_eos : low after address byte */
+				ndelay(esdata->time.eos);
+				gpio_direction_output(pchip->en_gpio, 1);
+				/* t_start : high before data byte */
+				ndelay(esdata->time.start);
+			}
+		}
+	} else {
+		/* backward command tansfer */
+		int bmask;
+
+		for (bmask = 0x01; bmask < max_bmask; bmask <<= 1) {
+			if (data_in & bmask)
+				t_low = esdata->time.logic_1_low;
+			else
+				t_low = esdata->time.logic_0_low;
+
+			gpio_direction_output(pchip->en_gpio, 0);
+			ndelay(t_low);
+			gpio_direction_output(pchip->en_gpio, 1);
+			ndelay(t_logic - t_low);
+		}
+	}
+
+	/*
+	 * t_eos : low after address byte
+	 * t_ackVal is also t_eos
+	 */
+	gpio_direction_output(pchip->en_gpio, 0);
+	ndelay(esdata->time.eos);
+
+	/* RFA management  */
+	if (pchip->rfa_en) {
+		int max_ack_time = esdata->time.ackn;
+		/* set input */
+		gpio_direction_input(pchip->en_gpio);
+		/* read acknowledge from chip */
+		while (max_ack_time > 0) {
+			if (gpio_get_value(pchip->en_gpio) = 0)
+				break;
+			max_ack_time -= esdata->time.ack_poll;
+		}
+		if (max_ack_time <= 0)
+			dev_err(pchip->dev,
+				"easyscale : no ack from %s\n", esdata->name);
+		else
+			ndelay(max_ack_time);
+	}
+	gpio_direction_output(pchip->en_gpio, 1);
+	local_irq_restore(flags);
+
+	return bl->props.brightness;
+}
+
+static int tps611xx_bl_get_brightness(struct backlight_device *bl)
+{
+	return bl->props.brightness;
+}
+
+static const struct backlight_ops tps611xx_bl_ops = {
+	.update_status = tps611xx_bl_update_status,
+	.get_brightness = tps611xx_bl_get_brightness,
+};
+
+static ssize_t tps611xx_enable_store(struct device *dev,
+				     struct device_attribute *devAttr,
+				     const char *buf, size_t size)
+{
+	struct tps611xx_bl_data *pchip = dev_get_drvdata(dev);
+	const struct tps611xx_esdata *esdata = pchip->esdata;
+	unsigned long flags;
+	unsigned int input;
+	int ret;
+
+	ret = kstrtouint(buf, 10, &input);
+	if (ret)
+		return -EINVAL;
+
+	local_irq_save(flags);
+	if (input = 0) {
+		/* chip disable */
+		gpio_direction_output(pchip->en_gpio, 0);
+		/* low more than reset ms to reset */
+		mdelay(esdata->time.reset);
+	} else {
+		/* easyscale detection window */
+		gpio_direction_output(pchip->en_gpio, 1);
+		ndelay(esdata->time.es_delay);
+		gpio_direction_output(pchip->en_gpio, 0);
+		ndelay(esdata->time.es_det);
+		gpio_direction_output(pchip->en_gpio, 1);
+	}
+	local_irq_restore(flags);
+
+	return size;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR, NULL, tps611xx_enable_store);
+
+#ifdef CONFIG_OF
+static struct of_device_id tps611xx_backlight_of_match[] = {
+	{.compatible = "ti,tps61158_bl", .data = &tps611xx_info[TPS61158_ID]},
+	{.compatible = "ti,tps61161_bl", .data = &tps611xx_info[TPS61161_ID]},
+	{.compatible = "ti,tps61163_bl", .data = &tps611xx_info[TPS61163_ID]},
+	{.compatible = "ti,tps61165_bl", .data = &tps611xx_info[TPS61165_ID]},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, tps611xx_backlight_of_match);
+
+static int tps611xx_backlight_parse_dt(struct tps611xx_bl_data *pchip)
+{
+	struct device *dev = pchip->dev;
+	struct device_node *node = dev->of_node;
+	const struct of_device_id *of_id +	    of_match_device(tps611xx_backlight_of_match, dev);
+	u32 value;
+	int ret;
+
+	if (!node)
+		return -ENODEV;
+
+	if (!of_id || !of_id->data) {
+		dev_err(dev, "Failed to find tps611xx chip id\n");
+		return -EFAULT;
+	}
+	pchip->esdata = of_id->data;
+
+	ret = of_property_read_u32(node, "en_gpio_num", &value);
+	if (ret < 0)
+		return ret;
+	pchip->en_gpio = value;
+	ret = of_property_read_u32(node, "rfa_en", &value);
+	if (ret < 0)
+		return ret;
+	pchip->rfa_en = value;
+
+	return 0;
+}
+#else
+static int tps611xx_backlight_parse_dt(struct tps611xx_bl_data *pchip)
+{
+	return -ENODEV;
+}
+#endif
+
+static int tps611xx_backlight_probe(struct platform_device *pdev)
+{
+	struct tps611xx_bl_data *pchip;
+	struct backlight_properties props;
+	const struct tps611xx_esdata *esdata;
+	struct tps611xx_platform_data *pdata = dev_get_platdata(&pdev->dev);
+	unsigned long flags;
+	int ret;
+
+	pchip = devm_kzalloc(&pdev->dev,
+			     sizeof(struct tps611xx_bl_data), GFP_KERNEL);
+	if (pchip = NULL)
+		return -ENOMEM;
+	pchip->dev = &pdev->dev;
+
+	if (pdata = NULL) {
+		ret = tps611xx_backlight_parse_dt(pchip);
+		if (ret < 0)
+			return ret;
+	} else {
+		pchip->rfa_en = pdata->rfa_en;
+		pchip->en_gpio = pdata->en_gpio_num;
+		pchip->esdata = (const struct tps611xx_esdata *)
+		    platform_get_device_id(pdev)->driver_data;
+	}
+	esdata = pchip->esdata;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.brightness = esdata->cmd.brt_max;
+	props.max_brightness = esdata->cmd.brt_max;
+	props.type = BACKLIGHT_RAW;
+	pchip->bled +	    devm_backlight_device_register(pchip->dev, TPS611XX_NAME,
+					   pchip->dev, pchip,
+					   &tps611xx_bl_ops, &props);
+	if (IS_ERR(pchip->bled))
+		return PTR_ERR(pchip->bled);
+
+	/* for enable/disable */
+	ret = device_create_file(&(pchip->bled->dev), &dev_attr_enable);
+	if (ret < 0) {
+		dev_err(pchip->dev, "failed : add sysfs entries\n");
+		return ret;
+	}
+	platform_set_drvdata(pdev, pchip);
+
+	/* EasyScale init */
+	ret = gpio_request_one(pchip->en_gpio, GPIOF_OUT_INIT_HIGH, "tps611xx");
+	if (ret) {
+		device_remove_file(&(pchip->bled->dev), &dev_attr_enable);
+		dev_err(pchip->dev, "failed : get gpio %d\n", pchip->en_gpio);
+		return ret;
+	}
+
+	/*
+	 * ES Detection Window
+	 *   - ES detect delay
+	 *   - ES detect time
+	 */
+	local_irq_save(flags);
+	gpio_direction_output(pchip->en_gpio, 1);
+	ndelay(esdata->time.es_delay);
+	gpio_direction_output(pchip->en_gpio, 0);
+	ndelay(esdata->time.es_det);
+	gpio_direction_output(pchip->en_gpio, 1);
+	local_irq_restore(flags);
+	dev_info(pchip->dev,
+		 "%s EasyScale is initialized\n", pchip->esdata->name);
+	return 0;
+}
+
+static int tps611xx_backlight_remove(struct platform_device *pdev)
+{
+	struct tps611xx_bl_data *pchip = platform_get_drvdata(pdev);
+	const struct tps611xx_esdata *esdata = pchip->esdata;
+
+	device_remove_file(&(pchip->bled->dev), &dev_attr_enable);
+	gpio_direction_output(pchip->en_gpio, 0);
+	mdelay(esdata->time.reset);
+	return 0;
+}
+
+static const struct platform_device_id tps611xx_id_table[] = {
+	{TPS61158_NAME, (unsigned long)&tps611xx_info[TPS61158_ID]},
+	{TPS61161_NAME, (unsigned long)&tps611xx_info[TPS61161_ID]},
+	{TPS61163_NAME, (unsigned long)&tps611xx_info[TPS61163_ID]},
+	{TPS61165_NAME, (unsigned long)&tps611xx_info[TPS61165_ID]},
+	{}
+};
+
+static struct platform_driver tps611xx_backlight_driver = {
+	.driver = {
+		   .name = TPS611XX_NAME,
+		   .owner = THIS_MODULE,
+		   .of_match_table = of_match_ptr(tps611xx_backlight_of_match),
+		   },
+	.probe = tps611xx_backlight_probe,
+	.remove = tps611xx_backlight_remove,
+	.id_table = tps611xx_id_table,
+};
+
+module_platform_driver(tps611xx_backlight_driver);
+
+MODULE_DESCRIPTION("EasyScale based tps611xx Backlight Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:tps611xx_bl");
diff --git a/include/linux/platform_data/tps611xx_bl.h b/include/linux/platform_data/tps611xx_bl.h
new file mode 100644
index 0000000..b7c4504
--- /dev/null
+++ b/include/linux/platform_data/tps611xx_bl.h
@@ -0,0 +1,30 @@
+/*
+ * Simple driver for Texas Instruments TPS61163a Backlight driver chip
+ * Copyright (C) 2014 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __TPS611XX_H
+#define __TPS611XX_H
+
+#define TPS611XX_NAME "tps611xx_bl"
+#define TPS61158_NAME "tps61158_bl"
+#define TPS61161_NAME "tps61161_bl"
+#define TPS61163_NAME "tps61163_bl"
+#define TPS61165_NAME "tps61165_bl"
+
+/* struct tps61163a platform data
+ * @rfa_en : request for acknowledge
+ * @en_gpio_num : gpio number for en_pin
+ */
+struct tps611xx_platform_data {
+
+	int rfa_en;
+	unsigned int en_gpio_num;
+};
+
+#endif /* __TPS61163A_H */
-- 
1.7.9.5


^ permalink raw reply related

* [RFC 2/2] backlight: device tree: add new tps611xx backlight driver
From: Daniel Jeong @ 2014-06-16  2:17 UTC (permalink / raw)
  To: Jingoo Han, Bryan Wu, Lee Jones, Jean-Christophe Plagniol-Villard,
	Tomi Valkeinen, Grant Likely, Rob Herring, Randy Dunlap
  Cc: Daniel Jeong, linux-kernel, linux-fbdev, devicetree, linux-doc,
	Daniel Jeong
In-Reply-To: <1402885043-3626-1-git-send-email-gshark.jeong@gmail.com>

This commit is about tps611xx device tree documentation.

Signed-off-by: Daniel Jeong <gshark.jeong@gmail.com>
---
 .../video/backlight/tps611xx-backlight.txt         |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt

diff --git a/Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt b/Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
new file mode 100644
index 0000000..8a0935d
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
@@ -0,0 +1,16 @@
+TPS611xx family of backlight driver based on EasyScale.
+
+It supports tps61158, tps61161, tps61163 and tps61165.
+
+Required properties:
+- compatible: "ti,tps61158_bl", "ti,tps61161_bl", "ti,tps61163_bl", "ti,tps61165_bl"
+- rfa_en: enable request for acknowledge.
+- en_gpio_num: gpio number for en pin.
+
+Example:
+
+	backlight {
+		compatible = "ti,tps61163_bl";
+		rfa_en = <1>;
+		en_gpio_num = <45>;
+	};
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCH] offb: Fix little-endian support
From: Benjamin Herrenschmidt @ 2014-06-16  7:23 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Cedric Le Goater, Dinar Valeev, Tomi Valkeinen,
	Jean-Christophe Plagniol-Villard, linux-fbdev, linux-kernel
In-Reply-To: <s5h8uq4qm3h.wl%tiwai@suse.de>


On Wed, 2014-05-14 at 19:57 +0200, Takashi Iwai wrote:
> 
> Hm, so it actually regressed on BE?
> 
> It's strange because fb_math_be() should be true and the patch won't
> change the values in that case...

Shouldn't the patch be based on foreign endian being set rather than
just "be" anyway ?

IE. If the fb is LE and the host is LE we *also* don't want to change
the ordering, which will be the case when we fix qemu...

Cheers,
Ben.




^ permalink raw reply

* Re: [PATCH] offb: Fix little-endian support
From: Benjamin Herrenschmidt @ 2014-06-16  7:32 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Cedric Le Goater, Dinar Valeev, Tomi Valkeinen,
	Jean-Christophe Plagniol-Villard, linux-fbdev, linux-kernel
In-Reply-To: <s5h8uq4qm3h.wl%tiwai@suse.de>


On Wed, 2014-05-14 at 19:57 +0200, Takashi Iwai wrote:
> 
> Hm, so it actually regressed on BE?
> 
> It's strange because fb_math_be() should be true and the patch won't
> change the values in that case...

Shouldn't the patch be based on foreign endian being set rather than
just "be" anyway ?

IE. If the fb is LE and the host is LE we *also* don't want to change
the ordering, which will be the case when we fix qemu...

Cheers,
Ben.




^ permalink raw reply

* Re: [PATCH] offb: Fix little-endian support
From: Benjamin Herrenschmidt @ 2014-06-16  7:35 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
	Cedric Le Goater, linux-fbdev, linux-kernel
In-Reply-To: <1400073709-15012-1-git-send-email-tiwai@suse.de>

On Wed, 2014-05-14 at 15:21 +0200, Takashi Iwai wrote:
>         case 16:                /* RGB 565 */
>                 var->bits_per_pixel = 16;
> -               var->red.offset = 11;
> +               if (fb_be_math(info)) {
> +                       var->red.offset = 11;
> +                       var->green.offset = 5;
> +                       var->blue.offset = 0;
> +               } else {
> +                       var->red.offset = 0;
> +                       var->green.offset = 5;
> +                       var->blue.offset = 11;
> +               }
>                 var->red.length = 5;
> -               var->green.offset = 5;
>                 var->green.length = 6;
> -               var->blue.offset = 0;
>                 var->blue.length = 5;
>                 var->transp.offset = 0;
>                 var->transp.length = 0;
>                 break;

I somewhat doubt that this (and 5:5:5) actually work, do they ? the
green gets split into two separate fields, which we can't express
properly here...

Cheers,
Ben.



^ permalink raw reply

* Re: [RFC 1/2] backlight: add new tps611xx backlight driver
From: Jingoo Han @ 2014-06-16 12:19 UTC (permalink / raw)
  To: 'Daniel Jeong'
  Cc: 'Daniel Jeong', linux-kernel, linux-fbdev, devicetree,
	linux-doc, 'Bryan Wu', 'Lee Jones',
	'Jean-Christophe Plagniol-Villard',
	'Tomi Valkeinen', 'Grant Likely',
	'Rob Herring', 'Randy Dunlap',
	'Jingoo Han'
In-Reply-To: <1402885043-3626-2-git-send-email-gshark.jeong@gmail.com>

On Monday, June 16, 2014 11:17 AM, Daniel Jeong wrote:
> 
> This driver a general version for tps611xx backlgiht chips of TI.
> It supports tps61158, tps61161, tps61163 and tps61165 backlight driver
> based on EasyScale protocol.

"EasyScale" protocol is a TI-specific protocol. How about adding more
detailed description as below? I referred to the datasheet of tps61158.

based on EasyScale protocol (1-Wire Control Interface). The protocol
consists of a device specific address byte and a data byte. The device
specific address byte is fixed to 58 hex. The data byte consists of
five bits for information, two address bits ("00"), and the RFA bit.

> 
> Signed-off-by: Daniel Jeong <gshark.jeong@gmail.com>
> ---
>  drivers/video/backlight/Kconfig           |    7 +
>  drivers/video/backlight/Makefile          |    1 +
>  drivers/video/backlight/tps611xx_bl.c     |  486 +++++++++++++++++++++++++++++
>  include/linux/platform_data/tps611xx_bl.h |   30 ++
>  4 files changed, 524 insertions(+)
>  create mode 100644 drivers/video/backlight/tps611xx_bl.c
>  create mode 100644 include/linux/platform_data/tps611xx_bl.h
> 
> diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
> index 5a3eb2e..c779a85 100644
> --- a/drivers/video/backlight/Kconfig
> +++ b/drivers/video/backlight/Kconfig
> @@ -418,6 +418,13 @@ config BACKLIGHT_TPS65217
>  	  If you have a Texas Instruments TPS65217 say Y to enable the
>  	  backlight driver.
> 
> +config BACKLIGHT_TPS611xx
> +	tristate "TPS611xx Backlight"
> +	depends on BACKLIGHT_CLASS_DEVICE && GPIOLIB
> +	help
> +	  This supports TI TPS61158, TPS61161, TPS61163 and TPS61165
> +	  backlight driver based on EasyScale Protocol.
> +
>  config BACKLIGHT_AS3711
>  	tristate "AS3711 Backlight"
>  	depends on BACKLIGHT_CLASS_DEVICE && MFD_AS3711
> diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
> index bb82002..44f1641 100644
> --- a/drivers/video/backlight/Makefile
> +++ b/drivers/video/backlight/Makefile
> @@ -52,4 +52,5 @@ obj-$(CONFIG_BACKLIGHT_PWM)		+= pwm_bl.o
>  obj-$(CONFIG_BACKLIGHT_SAHARA)		+= kb3886_bl.o
>  obj-$(CONFIG_BACKLIGHT_TOSA)		+= tosa_bl.o
>  obj-$(CONFIG_BACKLIGHT_TPS65217)	+= tps65217_bl.o
> +obj-$(CONFIG_BACKLIGHT_TPS611xx)	+= tps611xx_bl.o
>  obj-$(CONFIG_BACKLIGHT_WM831X)		+= wm831x_bl.o
> diff --git a/drivers/video/backlight/tps611xx_bl.c b/drivers/video/backlight/tps611xx_bl.c
> new file mode 100644
> index 0000000..4b76cdd
> --- /dev/null
> +++ b/drivers/video/backlight/tps611xx_bl.c
> @@ -0,0 +1,486 @@
> +/*
> + * Simple driver for Texas Instruments TPS611XX Backlight driver chip
> + *        using EasyScale Interface. It supports TPS61158, TPS61161,
> + *        TPS61163 and TPS61165.
> + *
> + * Copyright (C) 2014 Texas Instruments
> + * Author: Daniel Jeong  <gshark.jeong@gmail.com>
> + *	       Ldd Mlp <ldd-mlp@list.ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/backlight.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/fb.h>
> +#include <linux/gpio.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_data/tps611xx_bl.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +#define CMD_FORWARD 0
> +#define CMD_BACKWARD 1
> +
> +enum tps611xx_id {
> +	TPS61158_ID = 0,
> +	TPS61161_ID,
> +	TPS61163_ID,
> +	TPS61165_ID,
> +};
> +
> +/*
> + * easyscale time spec
> + * @es_delay : es delay time(ns)
> + * @es_det   : es detection time(ns)
> + * @start    : start time of data stream(ns)
> + * @eos      : end time of data stream(ns)
> + * @reset    : ic shutdown time(ms)
> + * @logic_1_low : low time high bit(ns)
> + * @logic_0_low : low time low bit(ns)
> + * @ackn        : duation of ack condistion(ns)
> + * @ack_poll    : ack polling duration(ns)
> + */
> +struct tps611xx_time {
> +	unsigned int es_delay;
> +	unsigned int es_det;
> +	unsigned int start;
> +	unsigned int eos;
> +	unsigned int reset;
> +	unsigned int logic_1_low;
> +	unsigned int logic_0_low;
> +	unsigned int ackn;
> +	unsigned int ack_poll;
> +};
> +
> +/*
> + * @seq : sequence of data transfer
> + * @size: size of data
> + * @brt_max : max brightness
> + * @brt_bmask : bit mask of dimming bits
> + * @rfa_bmask : bit mask of request of ack

s/request of ack/request for ack ?

> + */
> +struct tps611xx_command {
> +	int seq;
> +	int size;
> +	int brt_max;
> +	int brt_bmask;
> +	int rfa_bmask;
> +};
> +
> +/*
> + * @id : product id
> + * @name : product name
> + * @addr : device address
> + * @cmd  : es command info
> + * @time : es time info
> + */
> +struct tps611xx_esdata {
> +	enum tps611xx_id id;
> +	char *name;
> +	int addr;
> +	struct tps611xx_command cmd;
> +	struct tps611xx_time time;
> +};
> +
> +struct tps611xx_bl_data {
> +	struct device *dev;
> +	struct backlight_device *bled;
> +	struct tps611xx_platform_data *pdata;
> +
> +	/*
> +	 * @rfa_en : acknowlege request enable

s/acknowledge/acknowledge

How about the following?

+	 * @rfa_en : request for acknowledge enable

> +	 * @en_gpio: enable pin gpio no.
> +	 * @esdata : easyscale data
> +	 */
> +	int rfa_en;
> +	unsigned int en_gpio;
> +	const struct tps611xx_esdata *esdata;
> +};
> +
> +static struct tps611xx_esdata tps611xx_info[] = {
> +	[TPS61158_ID] = {
> +			 .id = TPS61158_ID,
> +			 .name = "tps61158",
> +			 .addr = 0x5800,
> +			 .cmd = {
> +				 .seq = CMD_FORWARD,
> +				 .size = 16,
> +				 .brt_max = 31,
> +				 .brt_bmask = 0x1f,
> +				 .rfa_bmask = 0x80},

Would you keep the coding style? The following looks better.

+				 .rfa_bmask = 0x80
+			},


> +			.time = {
> +				  .es_delay = 100000,
> +				  .es_det = 450000,
> +				  .start = 3500,
> +				  .eos = 3500,
> +				  .reset = 4,
> +				  .logic_1_low = 5000,
> +				  .logic_0_low = 15000,
> +				  .ackn = 900000,
> +				  .ack_poll = 2000},
> +			 },
> +
> +	[TPS61161_ID] = {
> +			 .id = TPS61161_ID,
> +			 .name = "tps61161",
> +			 .addr = 0x7200,
> +			 .cmd = {
> +				 .seq = CMD_FORWARD,
> +				 .size = 16,
> +				 .brt_max = 31,
> +				 .brt_bmask = 0x1f,
> +				 .rfa_bmask = 0x80},
> +			 .time = {
> +				  .es_delay = 120000,
> +				  .es_det = 280000,
> +				  .start = 2000,
> +				  .eos = 2000,
> +				  .reset = 3,
> +				  .logic_1_low = 3000,
> +				  .logic_0_low = 7000,
> +				  .ackn = 512000,
> +				  .ack_poll = 2000},
> +			 },
> +
> +	[TPS61163_ID] = {
> +			 .id = TPS61163_ID,
> +			 .name = "tps61163",
> +			 .addr = 0x8F0000,
> +			 .cmd = {
> +				 .seq = CMD_BACKWARD,
> +				 .size = 24,
> +				 .brt_max = 511,
> +				 .brt_bmask = 0x1ff,
> +				 .rfa_bmask = 0x400},
> +			 .time = {
> +				  .es_delay = 100000,
> +				  .es_det = 260000,
> +				  .start = 2000,
> +				  .eos = 2000,
> +				  .reset = 3,
> +				  .logic_1_low = 3000,
> +				  .logic_0_low = 7000,
> +				  .ackn = 512000,
> +				  .ack_poll = 2000},
> +			 },
> +
> +	[TPS61165_ID] = {
> +			 .id = TPS61165_ID,
> +			 .name = "tps61165",
> +			 .addr = 0x7200,
> +			 .cmd = {
> +				 .seq = CMD_FORWARD,
> +				 .size = 16,
> +				 .brt_max = 31,
> +				 .brt_bmask = 0x1f,
> +				 .rfa_bmask = 0x80},
> +			 .time = {
> +				  .es_delay = 120000,
> +				  .es_det = 280000,
> +				  .start = 4000,
> +				  .eos = 4000,
> +				  .reset = 3,
> +				  .logic_1_low = 3000,
> +				  .logic_0_low = 7000,
> +				  .ackn = 512000,
> +				  .ack_poll = 2000},
> +			 },
> +};
> +
> +static int tps611xx_bl_update_status(struct backlight_device *bl)
> +{
> +	struct tps611xx_bl_data *pchip = bl_get_data(bl);
> +	const struct tps611xx_esdata *esdata = pchip->esdata;
> +	int data_in, t_low, t_logic, max_bmask;
> +	unsigned long flags;
> +
> +	data_in = esdata->addr | (bl->props.brightness & esdata->cmd.brt_bmask);
> +	if (pchip->rfa_en)
> +		data_in |= esdata->cmd.rfa_bmask;
> +
> +	max_bmask = 0x1 << esdata->cmd.size;
> +	t_logic = esdata->time.logic_1_low + esdata->time.logic_0_low;
> +
> +	local_irq_save(flags);
> +	/* t_start : 2us high before data byte */
> +	gpio_direction_output(pchip->en_gpio, 1);
> +	ndelay(esdata->time.start);
> +
> +	/* forward command transfer */
> +	if (esdata->cmd.seq = CMD_FORWARD) {
> +		int addr_bmask = max_bmask >> 8;
> +
> +		for (max_bmask >>= 1; max_bmask > 0x0; max_bmask >>= 1) {
> +			if (data_in & max_bmask)
> +				t_low = esdata->time.logic_1_low;
> +			else
> +				t_low = esdata->time.logic_0_low;
> +
> +			gpio_direction_output(pchip->en_gpio, 0);
> +			ndelay(t_low);
> +			gpio_direction_output(pchip->en_gpio, 1);
> +			ndelay(t_logic - t_low);
> +
> +			if (max_bmask = addr_bmask) {
> +				gpio_direction_output(pchip->en_gpio, 0);
> +				/* t_eos : low after address byte */
> +				ndelay(esdata->time.eos);
> +				gpio_direction_output(pchip->en_gpio, 1);
> +				/* t_start : high before data byte */
> +				ndelay(esdata->time.start);
> +			}
> +		}
> +	} else {
> +		/* backward command tansfer */
> +		int bmask;
> +
> +		for (bmask = 0x01; bmask < max_bmask; bmask <<= 1) {
> +			if (data_in & bmask)
> +				t_low = esdata->time.logic_1_low;
> +			else
> +				t_low = esdata->time.logic_0_low;
> +
> +			gpio_direction_output(pchip->en_gpio, 0);
> +			ndelay(t_low);
> +			gpio_direction_output(pchip->en_gpio, 1);
> +			ndelay(t_logic - t_low);
> +		}
> +	}
> +
> +	/*
> +	 * t_eos : low after address byte
> +	 * t_ackVal is also t_eos
> +	 */
> +	gpio_direction_output(pchip->en_gpio, 0);
> +	ndelay(esdata->time.eos);
> +
> +	/* RFA management  */
> +	if (pchip->rfa_en) {
> +		int max_ack_time = esdata->time.ackn;
> +		/* set input */
> +		gpio_direction_input(pchip->en_gpio);
> +		/* read acknowledge from chip */
> +		while (max_ack_time > 0) {
> +			if (gpio_get_value(pchip->en_gpio) = 0)
> +				break;
> +			max_ack_time -= esdata->time.ack_poll;
> +		}
> +		if (max_ack_time <= 0)
> +			dev_err(pchip->dev,
> +				"easyscale : no ack from %s\n", esdata->name);
> +		else
> +			ndelay(max_ack_time);
> +	}
> +	gpio_direction_output(pchip->en_gpio, 1);
> +	local_irq_restore(flags);
> +
> +	return bl->props.brightness;
> +}
> +
> +static int tps611xx_bl_get_brightness(struct backlight_device *bl)
> +{
> +	return bl->props.brightness;
> +}
> +
> +static const struct backlight_ops tps611xx_bl_ops = {
> +	.update_status = tps611xx_bl_update_status,
> +	.get_brightness = tps611xx_bl_get_brightness,
> +};
> +
> +static ssize_t tps611xx_enable_store(struct device *dev,
> +				     struct device_attribute *devAttr,
> +				     const char *buf, size_t size)
> +{
> +	struct tps611xx_bl_data *pchip = dev_get_drvdata(dev);
> +	const struct tps611xx_esdata *esdata = pchip->esdata;
> +	unsigned long flags;
> +	unsigned int input;
> +	int ret;
> +
> +	ret = kstrtouint(buf, 10, &input);
> +	if (ret)
> +		return -EINVAL;
> +
> +	local_irq_save(flags);
> +	if (input = 0) {
> +		/* chip disable */
> +		gpio_direction_output(pchip->en_gpio, 0);
> +		/* low more than reset ms to reset */
> +		mdelay(esdata->time.reset);
> +	} else {
> +		/* easyscale detection window */
> +		gpio_direction_output(pchip->en_gpio, 1);
> +		ndelay(esdata->time.es_delay);
> +		gpio_direction_output(pchip->en_gpio, 0);
> +		ndelay(esdata->time.es_det);
> +		gpio_direction_output(pchip->en_gpio, 1);
> +	}
> +	local_irq_restore(flags);
> +
> +	return size;
> +}
> +
> +static DEVICE_ATTR(enable, S_IWUSR, NULL, tps611xx_enable_store);
> +
> +#ifdef CONFIG_OF
> +static struct of_device_id tps611xx_backlight_of_match[] = {

Please add 'const' as below.

+static const struct of_device_id tps611xx_backlight_of_match[] = {

> +	{.compatible = "ti,tps61158_bl", .data = &tps611xx_info[TPS61158_ID]},
> +	{.compatible = "ti,tps61161_bl", .data = &tps611xx_info[TPS61161_ID]},
> +	{.compatible = "ti,tps61163_bl", .data = &tps611xx_info[TPS61163_ID]},
> +	{.compatible = "ti,tps61165_bl", .data = &tps611xx_info[TPS61165_ID]},
> +	{}
> +};
> +
> +MODULE_DEVICE_TABLE(of, tps611xx_backlight_of_match);
> +
> +static int tps611xx_backlight_parse_dt(struct tps611xx_bl_data *pchip)
> +{
> +	struct device *dev = pchip->dev;
> +	struct device_node *node = dev->of_node;
> +	const struct of_device_id *of_id > +	    of_match_device(tps611xx_backlight_of_match, dev);
> +	u32 value;
> +	int ret;
> +
> +	if (!node)
> +		return -ENODEV;
> +
> +	if (!of_id || !of_id->data) {
> +		dev_err(dev, "Failed to find tps611xx chip id\n");
> +		return -EFAULT;
> +	}
> +	pchip->esdata = of_id->data;
> +
> +	ret = of_property_read_u32(node, "en_gpio_num", &value);
> +	if (ret < 0)
> +		return ret;
> +	pchip->en_gpio = value;
> +	ret = of_property_read_u32(node, "rfa_en", &value);
> +	if (ret < 0)
> +		return ret;
> +	pchip->rfa_en = value;
> +
> +	return 0;
> +}
> +#else
> +static int tps611xx_backlight_parse_dt(struct tps611xx_bl_data *pchip)
> +{
> +	return -ENODEV;
> +}
> +#endif
> +
> +static int tps611xx_backlight_probe(struct platform_device *pdev)
> +{
> +	struct tps611xx_bl_data *pchip;
> +	struct backlight_properties props;
> +	const struct tps611xx_esdata *esdata;
> +	struct tps611xx_platform_data *pdata = dev_get_platdata(&pdev->dev);
> +	unsigned long flags;
> +	int ret;
> +
> +	pchip = devm_kzalloc(&pdev->dev,
> +			     sizeof(struct tps611xx_bl_data), GFP_KERNEL);
> +	if (pchip = NULL)
> +		return -ENOMEM;
> +	pchip->dev = &pdev->dev;
> +
> +	if (pdata = NULL) {
> +		ret = tps611xx_backlight_parse_dt(pchip);
> +		if (ret < 0)
> +			return ret;
> +	} else {
> +		pchip->rfa_en = pdata->rfa_en;
> +		pchip->en_gpio = pdata->en_gpio_num;
> +		pchip->esdata = (const struct tps611xx_esdata *)
> +		    platform_get_device_id(pdev)->driver_data;
> +	}
> +	esdata = pchip->esdata;
> +
> +	memset(&props, 0, sizeof(struct backlight_properties));
> +	props.brightness = esdata->cmd.brt_max;
> +	props.max_brightness = esdata->cmd.brt_max;
> +	props.type = BACKLIGHT_RAW;
> +	pchip->bled > +	    devm_backlight_device_register(pchip->dev, TPS611XX_NAME,
> +					   pchip->dev, pchip,
> +					   &tps611xx_bl_ops, &props);
> +	if (IS_ERR(pchip->bled))
> +		return PTR_ERR(pchip->bled);
> +
> +	/* for enable/disable */
> +	ret = device_create_file(&(pchip->bled->dev), &dev_attr_enable);
> +	if (ret < 0) {
> +		dev_err(pchip->dev, "failed : add sysfs entries\n");
> +		return ret;
> +	}
> +	platform_set_drvdata(pdev, pchip);
> +
> +	/* EasyScale init */
> +	ret = gpio_request_one(pchip->en_gpio, GPIOF_OUT_INIT_HIGH, "tps611xx");
> +	if (ret) {
> +		device_remove_file(&(pchip->bled->dev), &dev_attr_enable);
> +		dev_err(pchip->dev, "failed : get gpio %d\n", pchip->en_gpio);
> +		return ret;
> +	}
> +
> +	/*
> +	 * ES Detection Window
> +	 *   - ES detect delay
> +	 *   - ES detect time
> +	 */
> +	local_irq_save(flags);
> +	gpio_direction_output(pchip->en_gpio, 1);
> +	ndelay(esdata->time.es_delay);
> +	gpio_direction_output(pchip->en_gpio, 0);
> +	ndelay(esdata->time.es_det);
> +	gpio_direction_output(pchip->en_gpio, 1);
> +	local_irq_restore(flags);
> +	dev_info(pchip->dev,
> +		 "%s EasyScale is initialized\n", pchip->esdata->name);
> +	return 0;
> +}
> +
> +static int tps611xx_backlight_remove(struct platform_device *pdev)
> +{
> +	struct tps611xx_bl_data *pchip = platform_get_drvdata(pdev);
> +	const struct tps611xx_esdata *esdata = pchip->esdata;
> +
> +	device_remove_file(&(pchip->bled->dev), &dev_attr_enable);
> +	gpio_direction_output(pchip->en_gpio, 0);
> +	mdelay(esdata->time.reset);
> +	return 0;
> +}
> +
> +static const struct platform_device_id tps611xx_id_table[] = {
> +	{TPS61158_NAME, (unsigned long)&tps611xx_info[TPS61158_ID]},
> +	{TPS61161_NAME, (unsigned long)&tps611xx_info[TPS61161_ID]},
> +	{TPS61163_NAME, (unsigned long)&tps611xx_info[TPS61163_ID]},
> +	{TPS61165_NAME, (unsigned long)&tps611xx_info[TPS61165_ID]},
> +	{}
> +};
> +
> +static struct platform_driver tps611xx_backlight_driver = {
> +	.driver = {
> +		   .name = TPS611XX_NAME,
> +		   .owner = THIS_MODULE,
> +		   .of_match_table = of_match_ptr(tps611xx_backlight_of_match),
> +		   },
> +	.probe = tps611xx_backlight_probe,
> +	.remove = tps611xx_backlight_remove,
> +	.id_table = tps611xx_id_table,
> +};
> +
> +module_platform_driver(tps611xx_backlight_driver);
> +
> +MODULE_DESCRIPTION("EasyScale based tps611xx Backlight Driver");
> +MODULE_LICENSE("GPL");

How about adding 'GPL v2' instead of 'GPL'?

+ MODULE_LICENSE("GPL v2");

> +MODULE_ALIAS("platform:tps611xx_bl");
> diff --git a/include/linux/platform_data/tps611xx_bl.h b/include/linux/platform_data/tps611xx_bl.h
> new file mode 100644
> index 0000000..b7c4504
> --- /dev/null
> +++ b/include/linux/platform_data/tps611xx_bl.h
> @@ -0,0 +1,30 @@
> +/*
> + * Simple driver for Texas Instruments TPS61163a Backlight driver chip
> + * Copyright (C) 2014 Texas Instruments
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#ifndef __TPS611XX_H
> +#define __TPS611XX_H
> +
> +#define TPS611XX_NAME "tps611xx_bl"
> +#define TPS61158_NAME "tps61158_bl"
> +#define TPS61161_NAME "tps61161_bl"
> +#define TPS61163_NAME "tps61163_bl"
> +#define TPS61165_NAME "tps61165_bl"
> +
> +/* struct tps61163a platform data

Please use the proper coding style as below.

+/*
+ * struct tps61163a platform data

> + * @rfa_en : request for acknowledge
> + * @en_gpio_num : gpio number for en_pin
> + */
> +struct tps611xx_platform_data {
> +
> +	int rfa_en;
> +	unsigned int en_gpio_num;
> +};
> +
> +#endif /* __TPS61163A_H */

s/__TPS61163A_H/__TPS611XX_H


Best regards,
Jingoo Han

> --
> 1.7.9.5


^ permalink raw reply

* Re: [PATCH] offb: Fix little-endian support
From: Benjamin Herrenschmidt @ 2014-06-16 23:54 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
	Cedric Le Goater, linux-fbdev, linux-kernel
In-Reply-To: <1402904135.7661.34.camel@pasglop>

On Mon, 2014-06-16 at 17:35 +1000, Benjamin Herrenschmidt wrote:

> I somewhat doubt that this (and 5:5:5) actually work, do they ? the
> green gets split into two separate fields, which we can't express
> properly here...

So the conclusion of further investigation is:

 - The right fix is to fix qemu to flip endian

 - There's an open discussion as to whether qemu could do it
automatically when the guest endian changes on powerpc as a quick fix,
the long run approach is to have a register to control it, I'm working
on it. offb can then "learn" to flick it like it does the palette hack
today.

 - If we want to ever support foreign endian offb with X, we need to do
things a bit differently based on the foreign endian bit that is already
there.

 - We must revert the existing cmap swap patch from the kernel, it's
broken and will break things when we fix qemu (and breaks with real HW
in LE mode). I've sent a revert request to Linus and CC'ed stable.

Cheers,
Ben.



^ permalink raw reply

* Re: [PATCH] offb: Fix little-endian support
From: Takashi Iwai @ 2014-06-17 10:01 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
	Cedric Le Goater, linux-fbdev, linux-kernel
In-Reply-To: <1402962847.7661.82.camel@pasglop>

At Tue, 17 Jun 2014 09:54:07 +1000,
Benjamin Herrenschmidt wrote:
> 
> On Mon, 2014-06-16 at 17:35 +1000, Benjamin Herrenschmidt wrote:
> 
> > I somewhat doubt that this (and 5:5:5) actually work, do they ? the
> > green gets split into two separate fields, which we can't express
> > properly here...
> 
> So the conclusion of further investigation is:
> 
>  - The right fix is to fix qemu to flip endian
> 
>  - There's an open discussion as to whether qemu could do it
> automatically when the guest endian changes on powerpc as a quick fix,
> the long run approach is to have a register to control it, I'm working
> on it. offb can then "learn" to flick it like it does the palette hack
> today.
> 
>  - If we want to ever support foreign endian offb with X, we need to do
> things a bit differently based on the foreign endian bit that is already
> there.
> 
>  - We must revert the existing cmap swap patch from the kernel, it's
> broken and will break things when we fix qemu (and breaks with real HW
> in LE mode). I've sent a revert request to Linus and CC'ed stable.

Yeah, I agree.  Both the current palette fix and my patch are really
wrong band-aiding.

(Though, the issue in X is rather a problem of X itself.  X should
 work with the tweaked RGB offsets.)


thanks,

Takashi

^ permalink raw reply

* [PATCH v7 1/2] video: ARM CLCD: Add DT support
From: Pawel Moll @ 2014-06-17 15:21 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 v6:
- replaced in-node device-timing subnode with the standard
  video interface bindings (as in: ports & endpoints); only
  "panel-dpi" compatible panels are supported in the driver

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        | 102 ++++++++
 drivers/video/fbdev/Kconfig                        |   1 +
 drivers/video/fbdev/amba-clcd.c                    | 268 +++++++++++++++++++++
 3 files changed, 371 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..54124c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/arm,pl11x.txt
@@ -0,0 +1,102 @@
+* 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
+
+- max-memory-bandwidth: maximum bandwidth in bytes per second that the
+	cell's memory interface can handle
+
+Required sub-nodes:
+
+- port: describes LCD panel signals, following the common binding
+	for video transmitter interfaces; see
+	Documentation/devicetree/bindings/media/video-interfaces.txt;
+	when it is a TFT panel, the port's endpoint must define the
+	following property:
+
+	- arm,pl11x,tft-r0g0b0-pads: 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>;
+
+
+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>;
+		max-memory-bandwidth = <36864000>; /* bps, 640x480@60 16bpp */
+
+		port {
+			v2m_clcd_pads: endpoint {
+				remote-endpoint = <&v2m_clcd_panel>;
+				arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+			};
+		};
+
+	};
+
+	panel {
+		compatible = "panel-dpi";
+
+		port {
+			v2m_clcd_panel: endpoint {
+				remote-endpoint = <&v2m_clcd_pads>;
+			};
+		};
+
+		panel-timing {
+			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 59c98bfd..a518fe5 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -280,6 +280,7 @@ config FB_ARMCLCD
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
+	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..64eae1b 100644
--- a/drivers/video/fbdev/amba-clcd.c
+++ b/drivers/video/fbdev/amba-clcd.c
@@ -26,6 +26,13 @@
 #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 <linux/of_graph.h>
+#include <video/display_timing.h>
+#include <video/of_display_timing.h>
+#include <video/videomode.h>
 
 #include <asm/sizes.h>
 
@@ -543,6 +550,264 @@ static int clcdfb_register(struct clcd_fb *fb)
 	return ret;
 }
 
+#ifdef CONFIG_OF
+static int clcdfb_of_get_dpi_panel_mode(struct device_node *node,
+		struct fb_videomode *mode)
+{
+	int err;
+	struct display_timing timing;
+	struct videomode video;
+
+	err = of_get_display_timing(node, "panel-timing", &timing);
+	if (err)
+		return err;
+
+	videomode_from_timing(&timing, &video);
+
+	err = fb_videomode_from_videomode(&video, mode);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+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_get_mode(struct device *dev, struct device_node *endpoint,
+		struct fb_videomode *mode)
+{
+	int err;
+	struct device_node *panel;
+	char *name;
+	int len;
+
+	panel = of_graph_get_remote_port_parent(endpoint);
+	if (!panel)
+		return -ENODEV;
+
+	/* Only directly connected DPI panels supported for now */
+	if (of_device_is_compatible(panel, "panel-dpi"))
+		err = clcdfb_of_get_dpi_panel_mode(panel, mode);
+	else
+		err = -ENOENT;
+	if (err)
+		return err;
+
+	len = clcdfb_snprintf_mode(NULL, 0, mode);
+	name = devm_kzalloc(dev, len + 1, GFP_KERNEL);
+	clcdfb_snprintf_mode(name, len + 1, mode);
+	mode->name = name;
+
+	return 0;
+}
+
+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_of_init_display(struct clcd_fb *fb)
+{
+	struct device_node *endpoint;
+	int err;
+	u32 max_bandwidth;
+	u32 tft_r0b0g0[3];
+
+	fb->panel = devm_kzalloc(&fb->dev->dev, sizeof(*fb->panel), GFP_KERNEL);
+	if (!fb->panel)
+		return -ENOMEM;
+
+	endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL);
+	if (!endpoint)
+		return -ENODEV;
+
+	err = clcdfb_of_get_mode(&fb->dev->dev, endpoint, &fb->panel->mode);
+	if (err)
+		return err;
+
+	err = of_property_read_u32(fb->dev->dev.of_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(endpoint,
+			"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 +815,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 v7 2/2] ARM: vexpress: Add CLCD Device Tree properties
From: Pawel Moll @ 2014-06-17 15:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1403018494-10264-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 | 34 ++++++++++++++++++++++++++++++++-
 arch/arm/boot/dts/vexpress-v2m.dtsi     | 34 ++++++++++++++++++++++++++++++++-
 arch/arm/boot/dts/vexpress-v2p-ca9.dts  | 31 ++++++++++++++++++++++++++++++
 3 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
index 756c986..0ac0623 100644
--- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
@@ -246,9 +246,41 @@
 			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>;
+				max-memory-bandwidth = <36864000>; /* Bps, 640x480@60 16bpp */
+
+				port {
+					v2m_clcd_pads: endpoint {
+						remote-endpoint = <&v2m_clcd_panel>;
+						arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+					};
+				};
+
+				panel {
+					compatible = "panel-dpi";
+
+					port {
+						v2m_clcd_panel: endpoint {
+							remote-endpoint = <&v2m_clcd_pads>;
+						};
+					};
+
+					panel-timing {
+						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>;
+					};
+				};
 			};
 		};
 
@@ -350,7 +382,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 ba856d6..bbe1858 100644
--- a/arch/arm/boot/dts/vexpress-v2m.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m.dtsi
@@ -245,9 +245,41 @@
 			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>;
+				max-memory-bandwidth = <36864000>; /* Bps, 640x480@60 16bpp */
+
+				port {
+					v2m_clcd_pads: endpoint {
+						remote-endpoint = <&v2m_clcd_panel>;
+						arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+					};
+				};
+
+				panel {
+					compatible = "panel-dpi";
+
+					port {
+						v2m_clcd_panel: endpoint {
+							remote-endpoint = <&v2m_clcd_pads>;
+						};
+					};
+
+					panel-timing {
+						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>;
+					};
+				};
 			};
 		};
 
@@ -349,7 +381,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..31107cd 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
@@ -70,9 +70,40 @@
 	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";
+		max-memory-bandwidth = <94371840>; /* Bps, 1024x768@60 16bpp */
+
+		port {
+			clcd_pads: endpoint {
+				remote-endpoint = <&clcd_panel>;
+				arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+			};
+		};
+
+		panel {
+			compatible = "panel-dpi";
+
+			port {
+				clcd_panel: endpoint {
+					remote-endpoint = <&clcd_pads>;
+				};
+			};
+
+			panel-timing {
+				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] video: OF display-timings support for ocfb
From: Stefan Kristiansson @ 2014-06-17 21:08 UTC (permalink / raw)
  To: Franck Jullien; +Cc: linux-kernel, linux-fbdev, tomi.valkeinen, plagnioj
In-Reply-To: <1402517871-27503-1-git-send-email-franck.jullien@gmail.com>

On Wed, Jun 11, 2014 at 10:17:51PM +0200, Franck Jullien wrote:
> Signed-off-by: Franck Jullien <franck.jullien@gmail.com>
> ---
>  drivers/video/fbdev/Kconfig |    2 ++
>  drivers/video/fbdev/ocfb.c  |   31 ++++++++++++++++++++++++++-----
>  2 files changed, 28 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
> index e1f4727..b4ac6bb 100644
> --- a/drivers/video/fbdev/Kconfig
> +++ b/drivers/video/fbdev/Kconfig
> @@ -942,6 +942,8 @@ config FB_OPENCORES
>  	select FB_CFB_FILLRECT
>  	select FB_CFB_COPYAREA
>  	select FB_CFB_IMAGEBLIT
> +	select VIDEOMODE_HELPERS
> +	select FB_MODE_HELPERS
>  	help
>  	  This enables support for the OpenCores VGA/LCD core.
>  
> diff --git a/drivers/video/fbdev/ocfb.c b/drivers/video/fbdev/ocfb.c
> index 7f9dc9b..6d15565 100644
> --- a/drivers/video/fbdev/ocfb.c
> +++ b/drivers/video/fbdev/ocfb.c
> @@ -22,6 +22,8 @@
>  #include <linux/string.h>
>  #include <linux/slab.h>
>  
> +#include <video/of_display_timing.h>
> +
>  /* OCFB register defines */
>  #define OCFB_CTRL	0x000
>  #define OCFB_STAT	0x004
> @@ -310,11 +312,30 @@ static int ocfb_probe(struct platform_device *pdev)
>  	fbdev->info.device = &pdev->dev;
>  	fbdev->info.par = fbdev;
>  
> -	/* Video mode setup */
> -	if (!fb_find_mode(&fbdev->info.var, &fbdev->info, mode_option,
> -			  NULL, 0, &default_mode, 16)) {
> -		dev_err(&pdev->dev, "No valid video modes found\n");
> -		return -EINVAL;
> +	if (!mode_option && IS_ENABLED(CONFIG_OF)) {
> +		struct fb_videomode mode;
> +		u32 bpp;
> +
> +		ret = of_get_fb_videomode(pdev->dev.of_node, &mode,
> +					  OF_USE_NATIVE_MODE);
> +		if (ret)
> +			return ret;
> +
> +		fb_videomode_to_var(&fbdev->info.var, &mode);
> +
> +		ret = of_property_read_u32(pdev->dev.of_node, "bits-per-pixel",
> +					   &bpp);
> +		if (ret)
> +			return ret;
> +
> +		fbdev->info.var.bits_per_pixel = bpp;
> +
> +	} else {
> +		if (!fb_find_mode(&fbdev->info.var, &fbdev->info, mode_option,
> +				  NULL, 0, &default_mode, 16)) {
> +			dev_err(&pdev->dev, "No valid video modes found\n");
> +			return -EINVAL;
> +		}
>  	}
>  	ocfb_init_var(fbdev);
>  	ocfb_init_fix(fbdev);


Nice, this was something that was discussed as a possible future improvement
when I first posted this driver.

Acked-by: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>

^ permalink raw reply

* [PATCH] drivers:video:fbdev atmel_lcdfb.c power GPIO registration bug
From: Michael Welling @ 2014-06-19  1:52 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Nicolas Ferre,
	linux-fbdev, linux-kernel
  Cc: Michael Welling

A list that was intended for storing power control GPIOs was never
initialized correctly or filled. Without these lines of added code
the kernel hangs when trying to access an uninitialized list when a
power control GPIO is registered with the device tree.

Signed-off-by: Michael Welling <mwelling@ieee.org>
---
 drivers/video/fbdev/atmel_lcdfb.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
index e683b6e..d36e830 100644
--- a/drivers/video/fbdev/atmel_lcdfb.c
+++ b/drivers/video/fbdev/atmel_lcdfb.c
@@ -1057,6 +1057,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
 		goto put_display_node;
 	}
 
+	INIT_LIST_HEAD(&pdata->pwr_gpios);
 	ret = -ENOMEM;
 	for (i = 0; i < of_gpio_named_count(display_np, "atmel,power-control-gpio"); i++) {
 		gpio = of_get_named_gpio_flags(display_np, "atmel,power-control-gpio",
@@ -1082,6 +1083,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
 			dev_err(dev, "set direction output gpio %d failed\n", gpio);
 			goto put_display_node;
 		}
+		list_add(&og->list, &pdata->pwr_gpios);
 	}
 
 	if (is_gpio_power)
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCH v7][ 3/5] video: mx3fb: Introduce regulator support.
From: Denis Carikli @ 2014-06-19  6:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1394788369-5096-3-git-send-email-denis@eukrea.com>

On 03/14/2014 10:12 AM, Denis Carikli wrote:
> +	/* In dt mode,
> +	 * using devm_regulator_get would require that the proprety referencing
> +	 * the regulator phandle has to be inside the mx3fb node.
> +	 */
> +	if (np) {
> +		if (regulator_name)
> +			mx3fbi->reg_lcd = regulator_get(NULL, regulator_name);
mx3fbi->reg_lcd is NULL if no regulator is present in the dts(i).
I'll fix it in the driver (instead of forcing the use of a dummy regulator).

Denis.

^ permalink raw reply

* Re: [PATCH] drivers:video:fbdev atmel_lcdfb.c power GPIO registration bug
From: Nicolas Ferre @ 2014-06-19  7:04 UTC (permalink / raw)
  To: Michael Welling, Jean-Christophe Plagniol-Villard, Tomi Valkeinen,
	linux-fbdev, linux-kernel
In-Reply-To: <1403142732-31706-1-git-send-email-mwelling@ieee.org>

On 19/06/2014 03:52, Michael Welling :
> A list that was intended for storing power control GPIOs was never
> initialized correctly or filled. Without these lines of added code
> the kernel hangs when trying to access an uninitialized list when a
> power control GPIO is registered with the device tree.
> 
> Signed-off-by: Michael Welling <mwelling@ieee.org>

Indeed.

Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>

Thanks, best regards,

> ---
>  drivers/video/fbdev/atmel_lcdfb.c |    2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
> index e683b6e..d36e830 100644
> --- a/drivers/video/fbdev/atmel_lcdfb.c
> +++ b/drivers/video/fbdev/atmel_lcdfb.c
> @@ -1057,6 +1057,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
>  		goto put_display_node;
>  	}
>  
> +	INIT_LIST_HEAD(&pdata->pwr_gpios);
>  	ret = -ENOMEM;
>  	for (i = 0; i < of_gpio_named_count(display_np, "atmel,power-control-gpio"); i++) {
>  		gpio = of_get_named_gpio_flags(display_np, "atmel,power-control-gpio",
> @@ -1082,6 +1083,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
>  			dev_err(dev, "set direction output gpio %d failed\n", gpio);
>  			goto put_display_node;
>  		}
> +		list_add(&og->list, &pdata->pwr_gpios);
>  	}
>  
>  	if (is_gpio_power)
> 


-- 
Nicolas Ferre

^ permalink raw reply

* [PATCH v2 1/2] video: clps711x: Add new Cirrus Logic CLPS711X framebuffer driver
From: Alexander Shiyan @ 2014-06-19 16:20 UTC (permalink / raw)
  To: linux-fbdev

This adds support for the framebuffer available in the Cirrus
Logic CLPS711X CPUs.
FB features:
- 1-2-4 bits per pixel.
- Programmable panel size to a maximum of 1024x256 at 4 bps.
- Relocatible Frame Buffer (SRAM or SDRAM).
- Programmable refresh rates.
- 16 gray scale values.
This new driver is designed to usage with devicetree only.
The driver have been tested with custom board equipped
Cirrus Logic EP7312.

Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
---
 drivers/video/fbdev/Kconfig       |  21 +-
 drivers/video/fbdev/Makefile      |   3 +-
 drivers/video/fbdev/clps711x-fb.c | 397 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 415 insertions(+), 6 deletions(-)
 create mode 100644 drivers/video/fbdev/clps711x-fb.c

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 59c98bfd..06e1ff8 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -301,15 +301,26 @@ config FB_ACORN
 	  hardware found in Acorn RISC PCs and other ARM-based machines.  If
 	  unsure, say N.
 
-config FB_CLPS711X
-	bool "CLPS711X LCD support"
-	depends on (FB = y) && ARM && ARCH_CLPS711X
+config FB_CLPS711X_OLD
+	bool
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
+
+config FB_CLPS711X
+	tristate "CLPS711X LCD support"
+	depends on FB && (ARCH_CLPS711X || COMPILE_TEST)
+	select FB_CLPS711X_OLD if ARCH_CLPS711X && !ARCH_MULTIPLATFORM
+	select BACKLIGHT_LCD_SUPPORT
+	select FB_MODE_HELPERS
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select LCD_CLASS_DEVICE
+	select VIDEOMODE_HELPERS
 	help
-	  Say Y to enable the Framebuffer driver for the CLPS7111 and
-	  EP7212 processors.
+	  Say Y to enable the Framebuffer driver for the Cirrus Logic
+	  CLPS711X CPUs.
 
 config FB_SA1100
 	bool "SA-1100 LCD support"
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 0284f2a..4e0b8c4 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -14,7 +14,8 @@ obj-$(CONFIG_FB_WMT_GE_ROPS)   += wmt_ge_rops.o
 # Hardware specific drivers go first
 obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o
 obj-$(CONFIG_FB_ARC)              += arcfb.o
-obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
+obj-$(CONFIG_FB_CLPS711X)	  += clps711x-fb.o
+obj-$(CONFIG_FB_CLPS711X_OLD)	  += clps711xfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
 obj-$(CONFIG_FB_GRVGA)            += grvga.o
 obj-$(CONFIG_FB_PM2)              += pm2fb.o
diff --git a/drivers/video/fbdev/clps711x-fb.c b/drivers/video/fbdev/clps711x-fb.c
new file mode 100644
index 0000000..4d17fbb
--- /dev/null
+++ b/drivers/video/fbdev/clps711x-fb.c
@@ -0,0 +1,397 @@
+/*
+ * Cirrus Logic CLPS711X FB driver
+ *
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ * Based on driver by Russell King <rmk@arm.linux.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/clps711x.h>
+#include <linux/regulator/consumer.h>
+#include <video/of_display_timing.h>
+
+#define CLPS711X_FB_NAME	"clps711x-fb"
+#define CLPS711X_FB_BPP_MAX	(4)
+
+/* Registers relative to LCDCON */
+#define CLPS711X_LCDCON		(0x0000)
+# define LCDCON_GSEN		BIT(30)
+# define LCDCON_GSMD		BIT(31)
+#define CLPS711X_PALLSW		(0x0280)
+#define CLPS711X_PALMSW		(0x02c0)
+#define CLPS711X_FBADDR		(0x0d40)
+
+struct clps711x_fb_info {
+	struct clk		*clk;
+	void __iomem		*base;
+	struct regmap		*syscon;
+	resource_size_t		buffsize;
+	struct fb_videomode	mode;
+	struct regulator	*lcd_pwr;
+	u32			ac_prescale;
+	bool			cmap_invert;
+};
+
+static int clps711x_fb_setcolreg(u_int regno, u_int red, u_int green,
+				 u_int blue, u_int transp, struct fb_info *info)
+{
+	struct clps711x_fb_info *cfb = info->par;
+	u32 level, mask, shift;
+
+	if (regno >= BIT(info->var.bits_per_pixel))
+		return -EINVAL;
+
+	shift = 4 * (regno & 7);
+	mask  = 0xf << shift;
+	/* gray = 0.30*R + 0.58*G + 0.11*B */
+	level = (((red * 77 + green * 151 + blue * 28) >> 20) << shift) & mask;
+	if (cfb->cmap_invert)
+		level = 0xf - level;
+
+	regno = (regno < 8) ? CLPS711X_PALLSW : CLPS711X_PALMSW;
+
+	writel((readl(cfb->base + regno) & ~mask) | level, cfb->base + regno);
+
+	return 0;
+}
+
+static int clps711x_fb_check_var(struct fb_var_screeninfo *var,
+				 struct fb_info *info)
+{
+	u32 val;
+
+	if (var->bits_per_pixel < 1 ||
+	    var->bits_per_pixel > CLPS711X_FB_BPP_MAX)
+		return -EINVAL;
+
+	if (!var->pixclock)
+		return -EINVAL;
+
+	val = DIV_ROUND_UP(var->xres, 16) - 1;
+	if (val < 0x01 || val > 0x3f)
+		return -EINVAL;
+
+	val = DIV_ROUND_UP(var->yres * var->xres * var->bits_per_pixel, 128);
+	val--;
+	if (val < 0x001 || val > 0x1fff)
+		return -EINVAL;
+
+	var->transp.msb_right	= 0;
+	var->transp.offset	= 0;
+	var->transp.length	= 0;
+	var->red.msb_right	= 0;
+	var->red.offset		= 0;
+	var->red.length		= var->bits_per_pixel;
+	var->green		= var->red;
+	var->blue		= var->red;
+	var->grayscale		= var->bits_per_pixel > 1;
+
+	return 0;
+}
+
+static int clps711x_fb_set_par(struct fb_info *info)
+{
+	struct clps711x_fb_info *cfb = info->par;
+	resource_size_t size;
+	u32 lcdcon, pps;
+
+	size = (info->var.xres * info->var.yres * info->var.bits_per_pixel) / 8;
+	if (size > cfb->buffsize)
+		return -EINVAL;
+
+	switch (info->var.bits_per_pixel) {
+	case 1:
+		info->fix.visual = FB_VISUAL_MONO01;
+		break;
+	case 2:
+	case 4:
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	info->fix.line_length = info->var.xres * info->var.bits_per_pixel / 8;
+	info->fix.smem_len = size;
+
+	lcdcon = (info->var.xres * info->var.yres *
+		  info->var.bits_per_pixel) / 128 - 1;
+	lcdcon |= ((info->var.xres / 16) - 1) << 13;
+	lcdcon |= (cfb->ac_prescale & 0x1f) << 25;
+
+	pps = clk_get_rate(cfb->clk) / (PICOS2KHZ(info->var.pixclock) * 1000);
+	if (pps)
+		pps--;
+	lcdcon |= (pps & 0x3f) << 19;
+
+	if (info->var.bits_per_pixel = 4)
+		lcdcon |= LCDCON_GSMD;
+	if (info->var.bits_per_pixel >= 2)
+		lcdcon |= LCDCON_GSEN;
+
+	/* LCDCON must only be changed while the LCD is disabled */
+	regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
+	writel(lcdcon, cfb->base + CLPS711X_LCDCON);
+	regmap_update_bits(cfb->syscon, SYSCON_OFFSET,
+			   SYSCON1_LCDEN, SYSCON1_LCDEN);
+
+	return 0;
+}
+
+static int clps711x_fb_blank(int blank, struct fb_info *info)
+{
+	/* Return happy */
+	return 0;
+}
+
+static struct fb_ops clps711x_fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_setcolreg	= clps711x_fb_setcolreg,
+	.fb_check_var	= clps711x_fb_check_var,
+	.fb_set_par	= clps711x_fb_set_par,
+	.fb_blank	= clps711x_fb_blank,
+	.fb_fillrect	= sys_fillrect,
+	.fb_copyarea	= sys_copyarea,
+	.fb_imageblit	= sys_imageblit,
+};
+
+static int clps711x_lcd_check_fb(struct lcd_device *lcddev, struct fb_info *fi)
+{
+	struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
+
+	return (!fi || fi->par = cfb) ? 1 : 0;
+}
+
+static int clps711x_lcd_get_power(struct lcd_device *lcddev)
+{
+	struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
+
+	if (!IS_ERR_OR_NULL(cfb->lcd_pwr))
+		if (!regulator_is_enabled(cfb->lcd_pwr))
+			return FB_BLANK_NORMAL;
+
+	return FB_BLANK_UNBLANK;
+}
+
+static int clps711x_lcd_set_power(struct lcd_device *lcddev, int blank)
+{
+	struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
+
+	if (!IS_ERR_OR_NULL(cfb->lcd_pwr)) {
+		if (blank = FB_BLANK_UNBLANK) {
+			if (!regulator_is_enabled(cfb->lcd_pwr))
+				return regulator_enable(cfb->lcd_pwr);
+		} else {
+			if (regulator_is_enabled(cfb->lcd_pwr))
+				return regulator_disable(cfb->lcd_pwr);
+		}
+	}
+
+	return 0;
+}
+
+static struct lcd_ops clps711x_lcd_ops = {
+	.check_fb	= clps711x_lcd_check_fb,
+	.get_power	= clps711x_lcd_get_power,
+	.set_power	= clps711x_lcd_set_power,
+};
+
+static int clps711x_fb_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *disp, *np = dev->of_node;
+	struct clps711x_fb_info *cfb;
+	struct lcd_device *lcd;
+	struct fb_info *info;
+	struct resource *res;
+	int ret = -ENOENT;
+	u32 val;
+
+	if (fb_get_options(CLPS711X_FB_NAME, NULL))
+		return -ENODEV;
+
+	info = framebuffer_alloc(sizeof(*cfb), dev);
+	if (!info)
+		return -ENOMEM;
+
+	cfb = info->par;
+	platform_set_drvdata(pdev, info);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		goto out_fb_release;
+	cfb->base = devm_ioremap(dev, res->start, resource_size(res));
+	if (!cfb->base) {
+		ret = -ENOMEM;
+		goto out_fb_release;
+	}
+
+	info->fix.mmio_start = res->start;
+	info->fix.mmio_len = resource_size(res);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	info->screen_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(info->screen_base)) {
+		ret = PTR_ERR(info->screen_base);
+		goto out_fb_release;
+	}
+
+	/* Physical address should be aligned to 256 MiB */
+	if (res->start & 0x0fffffff) {
+		ret = -EINVAL;
+		goto out_fb_release;
+	}
+
+	info->apertures = alloc_apertures(1);
+	if (!info->apertures) {
+		ret = -ENOMEM;
+		goto out_fb_release;
+	}
+
+	cfb->buffsize = resource_size(res);
+	info->fix.smem_start = res->start;
+	info->apertures->ranges[0].base = info->fix.smem_start;
+	info->apertures->ranges[0].size = cfb->buffsize;
+
+	cfb->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(cfb->clk)) {
+		ret = PTR_ERR(cfb->clk);
+		goto out_fb_release;
+	}
+
+	cfb->syscon +		syscon_regmap_lookup_by_compatible("cirrus,clps711x-syscon1");
+	if (IS_ERR(cfb->syscon)) {
+		ret = PTR_ERR(cfb->syscon);
+		goto out_fb_release;
+	}
+
+	disp = of_parse_phandle(np, "display", 0);
+	if (!disp) {
+		dev_err(&pdev->dev, "No display defined\n");
+		ret = -ENODATA;
+		goto out_fb_release;
+	}
+
+	ret = of_get_fb_videomode(disp, &cfb->mode, OF_USE_NATIVE_MODE);
+	if (ret)
+		goto out_fb_release;
+
+	of_property_read_u32(disp, "ac-prescale", &cfb->ac_prescale);
+	cfb->cmap_invert = of_property_read_bool(disp, "cmap-invert");
+
+	ret = of_property_read_u32(disp, "bits-per-pixel",
+				   &info->var.bits_per_pixel);
+	if (ret)
+		goto out_fb_release;
+
+	/* Force disable LCD on any mismatch */
+	if (info->fix.smem_start != (readb(cfb->base + CLPS711X_FBADDR) << 28))
+		regmap_update_bits(cfb->syscon, SYSCON_OFFSET,
+				   SYSCON1_LCDEN, 0);
+
+	ret = regmap_read(cfb->syscon, SYSCON_OFFSET, &val);
+	if (ret)
+		goto out_fb_release;
+
+	if (!(val & SYSCON1_LCDEN)) {
+		/* Setup start FB address */
+		writeb(info->fix.smem_start >> 28, cfb->base + CLPS711X_FBADDR);
+		/* Clean FB memory */
+		memset(info->screen_base, 0, cfb->buffsize);
+	}
+
+	cfb->lcd_pwr = devm_regulator_get(dev, "lcd");
+	if (PTR_ERR(cfb->lcd_pwr) = -EPROBE_DEFER) {
+		ret = -EPROBE_DEFER;
+		goto out_fb_release;
+	}
+
+	info->fbops = &clps711x_fb_ops;
+	info->flags = FBINFO_DEFAULT;
+	info->var.activate = FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
+	info->var.height = -1;
+	info->var.width = -1;
+	info->var.vmode = FB_VMODE_NONINTERLACED;
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.accel = FB_ACCEL_NONE;
+	strlcpy(info->fix.id, CLPS711X_FB_NAME, sizeof(info->fix.id));
+	fb_videomode_to_var(&info->var, &cfb->mode);
+
+	ret = fb_alloc_cmap(&info->cmap, BIT(CLPS711X_FB_BPP_MAX), 0);
+	if (ret)
+		goto out_fb_release;
+
+	ret = fb_set_var(info, &info->var);
+	if (ret)
+		goto out_fb_dealloc_cmap;
+
+	ret = register_framebuffer(info);
+	if (ret)
+		goto out_fb_dealloc_cmap;
+
+	lcd = devm_lcd_device_register(dev, "clps711x-lcd", dev, cfb,
+				       &clps711x_lcd_ops);
+	if (!IS_ERR(lcd))
+		return 0;
+	
+	ret = PTR_ERR(lcd);
+	unregister_framebuffer(info);
+
+out_fb_dealloc_cmap:
+	regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
+	fb_dealloc_cmap(&info->cmap);
+
+out_fb_release:
+	framebuffer_release(info);
+
+	return ret;
+}
+
+static int clps711x_fb_remove(struct platform_device *pdev)
+{
+	struct fb_info *info = platform_get_drvdata(pdev);
+	struct clps711x_fb_info *cfb = info->par;
+
+	regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
+
+	unregister_framebuffer(info);
+	fb_dealloc_cmap(&info->cmap);
+	framebuffer_release(info);
+
+	return 0;
+}
+
+static const struct of_device_id clps711x_fb_dt_ids[] = {
+	{ .compatible = "cirrus,clps711x-fb", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, clps711x_fb_dt_ids);
+
+static struct platform_driver clps711x_fb_driver = {
+	.driver	= {
+		.name		= CLPS711X_FB_NAME,
+		.owner		= THIS_MODULE,
+		.of_match_table	= clps711x_fb_dt_ids,
+	},
+	.probe	= clps711x_fb_probe,
+	.remove	= clps711x_fb_remove,
+};
+module_platform_driver(clps711x_fb_driver);
+
+MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
+MODULE_DESCRIPTION("Cirrus Logic CLPS711X FB driver");
+MODULE_LICENSE("GPL");
-- 
1.8.5.5


^ permalink raw reply related

* [PATCH v2 2/2] video: clps711x: Add bindings documentation for CLPS711X framebuffer
From: Alexander Shiyan @ 2014-06-19 16:21 UTC (permalink / raw)
  To: linux-fbdev-u79uwXL29TY76Z2rM5mHXA
  Cc: Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Arnd Bergmann,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Alexander Shiyan

Add OF document for Cirrus Logic CLPS711X framebuffer driver.

Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
---
 .../bindings/video/cirrus,clps711x-fb.txt          | 47 ++++++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/cirrus,clps711x-fb.txt

diff --git a/Documentation/devicetree/bindings/video/cirrus,clps711x-fb.txt b/Documentation/devicetree/bindings/video/cirrus,clps711x-fb.txt
new file mode 100644
index 0000000..6fc3c6a
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/cirrus,clps711x-fb.txt
@@ -0,0 +1,47 @@
+* Currus Logic CLPS711X Framebuffer
+
+Required properties:
+- compatible: Shall contain "cirrus,clps711x-fb".
+- reg       : Physical base address and length of the controller's registers +
+              location and size of the framebuffer memory.
+- clocks    : phandle + clock specifier pair of the FB reference clock.
+- display   : phandle to a display node as described in
+              Documentation/devicetree/bindings/video/display-timing.txt.
+              Additionally, the display node has to define properties:
+  - bits-per-pixel: Bits per pixel.
+  - ac-prescale   : LCD AC bias frequency. This frequency is the required
+                    AC bias frequency for a given manufacturer's LCD plate.
+  - cmap-invert   : Invert the color levels (Optional).
+
+Optional properties:
+- lcd-supply: Regulator for LCD supply voltage.
+
+Example:
+	fb: fb@800002c0 {
+		compatible = "cirrus,ep7312-fb", "cirrus,clps711x-fb";
+		reg = <0x800002c0 0xd44>, <0x60000000 0xc000>;
+		clocks = <&clks 2>;
+		lcd-supply = <&reg5v0>;
+		display = <&display>;
+	};
+
+	display: display {
+		model = "320x240x4";
+		native-mode = <&timing0>;
+		bits-per-pixel = <4>;
+		ac-prescale = <17>;
+
+		display-timings {
+			timing0: 320x240 {
+				hactive = <320>;
+				hback-porch = <0>;
+				hfront-porch = <0>;
+				hsync-len = <0>;
+				vactive = <240>;
+				vback-porch = <0>;
+				vfront-porch = <0>;
+				vsync-len = <0>;
+				clock-frequency = <6500000>;
+			};
+		};
+	};
-- 
1.8.5.5


^ permalink raw reply related

* Re: [PATCH 1/1] video: omapdss: Fix potential null pointer dereference
From: Sachin Kamat @ 2014-06-20  9:21 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1401445595-22884-1-git-send-email-sachin.kamat@linaro.org>

On Fri, May 30, 2014 at 3:56 PM, Sachin Kamat <sachin.kamat@linaro.org> wrote:
> kmalloc can return null. Add a check to avoid potential null
> pointer dereference error when the pointer is accessed later.
>
> Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
> ---
>  drivers/video/fbdev/omap2/dss/omapdss-boot-init.c |    8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
> index 99af9e88b2d8..2f0822ee3ff9 100644
> --- a/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
> +++ b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
> @@ -121,9 +121,11 @@ static void __init omapdss_add_to_list(struct device_node *node, bool root)
>  {
>         struct dss_conv_node *n = kmalloc(sizeof(struct dss_conv_node),
>                 GFP_KERNEL);
> -       n->node = node;
> -       n->root = root;
> -       list_add(&n->list, &dss_conv_list);
> +       if (n) {
> +               n->node = node;
> +               n->root = root;
> +               list_add(&n->list, &dss_conv_list);
> +       }
>  }
>
>  static bool __init omapdss_list_contains(const struct device_node *node)
> --
> 1.7.9.5
>
>

Gentle ping..

-- 
Regards,
Sachin.

^ permalink raw reply

* Re: [PATCH v7 1/2] video: ARM CLCD: Add DT support
From: Mark Rutland @ 2014-06-20 17:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1403018494-10264-1-git-send-email-pawel.moll@arm.com>

Hi Pawel,

On Tue, Jun 17, 2014 at 04:21:33PM +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>
> ---
> Changes since v6:
> - replaced in-node device-timing subnode with the standard
>   video interface bindings (as in: ports & endpoints); only
>   "panel-dpi" compatible panels are supported in the driver
> 
> 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        | 102 ++++++++
>  drivers/video/fbdev/Kconfig                        |   1 +
>  drivers/video/fbdev/amba-clcd.c                    | 268 +++++++++++++++++++++
>  3 files changed, 371 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..54124c6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/video/arm,pl11x.txt
> @@ -0,0 +1,102 @@
> +* 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"

s/clocks-names/clock-names/

> +
> +- 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

The name is confusing: this is a base _and_ size.

When should this be used, and what is valid to point it at?

How does this play with memory carveouts (CMA, reserved-memory)?

> +- max-memory-bandwidth: maximum bandwidth in bytes per second that the
> +	cell's memory interface can handle

When should I set this, given it is optional?

> +
> +Required sub-nodes:
> +
> +- port: describes LCD panel signals, following the common binding
> +	for video transmitter interfaces; see
> +	Documentation/devicetree/bindings/media/video-interfaces.txt;
> +	when it is a TFT panel, the port's endpoint must define the
> +	following property:
> +
> +	- arm,pl11x,tft-r0g0b0-pads: 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>;

I'm somewhat lost trying to figure out this mapping. Am I not looking at
this in the right way, or is there any documentation which makes this
clearer?

Thanks,
Mark.

^ 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