From patchwork Sun Feb 9 18:47:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 236075 List-Id: U-Boot discussion From: dariobin at libero.it (Dario Binacchi) Date: Sun, 9 Feb 2020 19:47:34 +0100 Subject: [PATCH 01/11] video: omap: use BIT() macro In-Reply-To: <20200209184745.20473-1-dariobin@libero.it> References: <20200209184745.20473-1-dariobin@libero.it> Message-ID: <20200209184745.20473-2-dariobin@libero.it> Use the standard BIT() macro for bitfield definitions. Signed-off-by: Dario Binacchi Reviewed-by: Lokesh Vutla --- drivers/video/am335x-fb.c | 16 ++++++++-------- drivers/video/am335x-fb.h | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c index 51c1af587f..18e3bd1f35 100644 --- a/drivers/video/am335x-fb.c +++ b/drivers/video/am335x-fb.c @@ -27,11 +27,11 @@ /* LCD Control Register */ #define LCD_CLK_DIVISOR(x) ((x) << 8) -#define LCD_RASTER_MODE 0x01 +#define LCD_RASTER_MODE BIT(0) /* LCD Clock Enable Register */ -#define LCD_CORECLKEN (0x01 << 0) -#define LCD_LIDDCLKEN (0x01 << 1) -#define LCD_DMACLKEN (0x01 << 2) +#define LCD_CORECLKEN BIT(0) +#define LCD_LIDDCLKEN BIT(1) +#define LCD_DMACLKEN BIT(2) /* LCD DMA Control Register */ #define LCD_DMA_BURST_SIZE(x) ((x) << 4) #define LCD_DMA_BURST_1 0x0 @@ -57,11 +57,11 @@ #define LCD_HFPMSB(x) ((((x)-1) & 0x300) >> 8) #define LCD_INVMASK(x) ((x) & 0x3F00000) /* LCD Raster Ctrl Register */ -#define LCD_TFT_24BPP_MODE (1 << 25) -#define LCD_TFT_24BPP_UNPACK (1 << 26) +#define LCD_TFT_24BPP_MODE BIT(25) +#define LCD_TFT_24BPP_UNPACK BIT(26) #define LCD_PALMODE_RAWDATA (0x02 << 20) -#define LCD_TFT_MODE (0x01 << 7) -#define LCD_RASTER_ENABLE (0x01 << 0) +#define LCD_TFT_MODE BIT(7) +#define LCD_RASTER_ENABLE BIT(0) /* Macro definitions */ diff --git a/drivers/video/am335x-fb.h b/drivers/video/am335x-fb.h index f5883c02dd..ad9b015e09 100644 --- a/drivers/video/am335x-fb.h +++ b/drivers/video/am335x-fb.h @@ -7,7 +7,7 @@ #ifndef AM335X_FB_H #define AM335X_FB_H -#define HSVS_CONTROL (0x01 << 25) /* +#define HSVS_CONTROL BIT(25) /* * 0 = lcd_lp and lcd_fp are driven on * opposite edges of pixel clock than * the lcd_pixel_o @@ -17,7 +17,7 @@ * Matrix displays the edge timing is * fixed */ -#define HSVS_RISEFALL (0x01 << 24) /* +#define HSVS_RISEFALL BIT(24) /* * 0 = lcd_lp and lcd_fp are driven on * the rising edge of pixel clock (bit * 25 must be set to 1) @@ -25,19 +25,19 @@ * the falling edge of pixel clock (bit * 25 must be set to 1) */ -#define DE_INVERT (0x01 << 23) /* +#define DE_INVERT BIT(23) /* * 0 = DE is low-active * 1 = DE is high-active */ -#define PXCLK_INVERT (0x01 << 22) /* +#define PXCLK_INVERT BIT(22) /* * 0 = pix-clk is high-active * 1 = pic-clk is low-active */ -#define HSYNC_INVERT (0x01 << 21) /* +#define HSYNC_INVERT BIT(21) /* * 0 = HSYNC is active high * 1 = HSYNC is avtive low */ -#define VSYNC_INVERT (0x01 << 20) /* +#define VSYNC_INVERT BIT(20) /* * 0 = VSYNC is active high * 1 = VSYNC is active low */ From patchwork Sun Feb 9 18:47:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 236076 List-Id: U-Boot discussion From: dariobin at libero.it (Dario Binacchi) Date: Sun, 9 Feb 2020 19:47:35 +0100 Subject: [PATCH 02/11] video: omap: add missing bitfield masks In-Reply-To: <20200209184745.20473-1-dariobin@libero.it> References: <20200209184745.20473-1-dariobin@libero.it> Message-ID: <20200209184745.20473-3-dariobin@libero.it> Add, if missing, the bitfield masks in the setting macros of the LCD controller registers. Signed-off-by: Dario Binacchi --- drivers/video/am335x-fb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c index 18e3bd1f35..ed445546ec 100644 --- a/drivers/video/am335x-fb.c +++ b/drivers/video/am335x-fb.c @@ -26,14 +26,14 @@ #define LCDC_FMAX 200000000 /* LCD Control Register */ -#define LCD_CLK_DIVISOR(x) ((x) << 8) +#define LCD_CLK_DIVISOR(x) (((x) & 0xFF) << 8) #define LCD_RASTER_MODE BIT(0) /* LCD Clock Enable Register */ #define LCD_CORECLKEN BIT(0) #define LCD_LIDDCLKEN BIT(1) #define LCD_DMACLKEN BIT(2) /* LCD DMA Control Register */ -#define LCD_DMA_BURST_SIZE(x) ((x) << 4) +#define LCD_DMA_BURST_SIZE(x) (((x) & 0x07) << 4) #define LCD_DMA_BURST_1 0x0 #define LCD_DMA_BURST_2 0x1 #define LCD_DMA_BURST_4 0x2 @@ -46,9 +46,9 @@ #define LCD_HORLSB(x) (((((x) >> 4)-1) & 0x3F) << 4) #define LCD_HORMSB(x) (((((x) >> 4)-1) & 0x40) >> 4) /* LCD Timing_1 Register */ -#define LCD_VBP(x) ((x) << 24) -#define LCD_VFP(x) ((x) << 16) -#define LCD_VSW(x) (((x)-1) << 10) +#define LCD_VBP(x) (((x) & 0xFF) << 24) +#define LCD_VFP(x) (((x) & 0xFF) << 16) +#define LCD_VSW(x) ((((x) - 1) & 0x3F) << 10) #define LCD_VERLSB(x) (((x)-1) & 0x3FF) /* LCD Timing_2 Register */ #define LCD_HSWMSB(x) ((((x)-1) & 0x3C0) << 21) From patchwork Sun Feb 9 18:47:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 236077 List-Id: U-Boot discussion From: dariobin at libero.it (Dario Binacchi) Date: Sun, 9 Feb 2020 19:47:36 +0100 Subject: [PATCH 03/11] video: omap: fix coding style on use of spaces In-Reply-To: <20200209184745.20473-1-dariobin@libero.it> References: <20200209184745.20473-1-dariobin@libero.it> Message-ID: <20200209184745.20473-4-dariobin@libero.it> Use one space around (on each side of) the binary '-' operator. Signed-off-by: Dario Binacchi --- drivers/video/am335x-fb.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c index ed445546ec..17476f5b72 100644 --- a/drivers/video/am335x-fb.c +++ b/drivers/video/am335x-fb.c @@ -40,21 +40,21 @@ #define LCD_DMA_BURST_8 0x3 #define LCD_DMA_BURST_16 0x4 /* LCD Timing_0 Register */ -#define LCD_HBPLSB(x) ((((x)-1) & 0xFF) << 24) -#define LCD_HFPLSB(x) ((((x)-1) & 0xFF) << 16) -#define LCD_HSWLSB(x) ((((x)-1) & 0x3F) << 10) -#define LCD_HORLSB(x) (((((x) >> 4)-1) & 0x3F) << 4) -#define LCD_HORMSB(x) (((((x) >> 4)-1) & 0x40) >> 4) +#define LCD_HBPLSB(x) ((((x) - 1) & 0xFF) << 24) +#define LCD_HFPLSB(x) ((((x) - 1) & 0xFF) << 16) +#define LCD_HSWLSB(x) ((((x) - 1) & 0x3F) << 10) +#define LCD_HORLSB(x) (((((x) >> 4) - 1) & 0x3F) << 4) +#define LCD_HORMSB(x) (((((x) >> 4) - 1) & 0x40) >> 4) /* LCD Timing_1 Register */ #define LCD_VBP(x) (((x) & 0xFF) << 24) #define LCD_VFP(x) (((x) & 0xFF) << 16) #define LCD_VSW(x) ((((x) - 1) & 0x3F) << 10) -#define LCD_VERLSB(x) (((x)-1) & 0x3FF) +#define LCD_VERLSB(x) (((x) - 1) & 0x3FF) /* LCD Timing_2 Register */ -#define LCD_HSWMSB(x) ((((x)-1) & 0x3C0) << 21) -#define LCD_VERMSB(x) ((((x)-1) & 0x400) << 16) -#define LCD_HBPMSB(x) ((((x)-1) & 0x300) >> 4) -#define LCD_HFPMSB(x) ((((x)-1) & 0x300) >> 8) +#define LCD_HSWMSB(x) ((((x) - 1) & 0x3C0) << 21) +#define LCD_VERMSB(x) ((((x) - 1) & 0x400) << 16) +#define LCD_HBPMSB(x) ((((x) - 1) & 0x300) >> 4) +#define LCD_HFPMSB(x) ((((x) - 1) & 0x300) >> 8) #define LCD_INVMASK(x) ((x) & 0x3F00000) /* LCD Raster Ctrl Register */ #define LCD_TFT_24BPP_MODE BIT(25) From patchwork Sun Feb 9 18:47:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 236078 List-Id: U-Boot discussion From: dariobin at libero.it (Dario Binacchi) Date: Sun, 9 Feb 2020 19:47:37 +0100 Subject: [PATCH 04/11] video: omap: fix bitfields order In-Reply-To: <20200209184745.20473-1-dariobin@libero.it> References: <20200209184745.20473-1-dariobin@libero.it> Message-ID: <20200209184745.20473-5-dariobin@libero.it> Arrange the bitfields of each register in the ascending order. Signed-off-by: Dario Binacchi --- drivers/video/am335x-fb.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c index 17476f5b72..2facac986a 100644 --- a/drivers/video/am335x-fb.c +++ b/drivers/video/am335x-fb.c @@ -26,8 +26,8 @@ #define LCDC_FMAX 200000000 /* LCD Control Register */ -#define LCD_CLK_DIVISOR(x) (((x) & 0xFF) << 8) #define LCD_RASTER_MODE BIT(0) +#define LCD_CLK_DIVISOR(x) (((x) & 0xFF) << 8) /* LCD Clock Enable Register */ #define LCD_CORECLKEN BIT(0) #define LCD_LIDDCLKEN BIT(1) @@ -40,29 +40,28 @@ #define LCD_DMA_BURST_8 0x3 #define LCD_DMA_BURST_16 0x4 /* LCD Timing_0 Register */ -#define LCD_HBPLSB(x) ((((x) - 1) & 0xFF) << 24) -#define LCD_HFPLSB(x) ((((x) - 1) & 0xFF) << 16) -#define LCD_HSWLSB(x) ((((x) - 1) & 0x3F) << 10) -#define LCD_HORLSB(x) (((((x) >> 4) - 1) & 0x3F) << 4) #define LCD_HORMSB(x) (((((x) >> 4) - 1) & 0x40) >> 4) +#define LCD_HORLSB(x) (((((x) >> 4) - 1) & 0x3F) << 4) +#define LCD_HSWLSB(x) ((((x) - 1) & 0x3F) << 10) +#define LCD_HFPLSB(x) ((((x) - 1) & 0xFF) << 16) +#define LCD_HBPLSB(x) ((((x) - 1) & 0xFF) << 24) /* LCD Timing_1 Register */ -#define LCD_VBP(x) (((x) & 0xFF) << 24) -#define LCD_VFP(x) (((x) & 0xFF) << 16) -#define LCD_VSW(x) ((((x) - 1) & 0x3F) << 10) #define LCD_VERLSB(x) (((x) - 1) & 0x3FF) +#define LCD_VSW(x) ((((x) - 1) & 0x3F) << 10) +#define LCD_VFP(x) (((x) & 0xFF) << 16) +#define LCD_VBP(x) (((x) & 0xFF) << 24) /* LCD Timing_2 Register */ -#define LCD_HSWMSB(x) ((((x) - 1) & 0x3C0) << 21) -#define LCD_VERMSB(x) ((((x) - 1) & 0x400) << 16) -#define LCD_HBPMSB(x) ((((x) - 1) & 0x300) >> 4) #define LCD_HFPMSB(x) ((((x) - 1) & 0x300) >> 8) +#define LCD_HBPMSB(x) ((((x) - 1) & 0x300) >> 4) #define LCD_INVMASK(x) ((x) & 0x3F00000) +#define LCD_VERMSB(x) ((((x) - 1) & 0x400) << 16) +#define LCD_HSWMSB(x) ((((x) - 1) & 0x3C0) << 21) /* LCD Raster Ctrl Register */ +#define LCD_RASTER_ENABLE BIT(0) +#define LCD_TFT_MODE BIT(7) +#define LCD_PALMODE_RAWDATA (0x02 << 20) #define LCD_TFT_24BPP_MODE BIT(25) #define LCD_TFT_24BPP_UNPACK BIT(26) -#define LCD_PALMODE_RAWDATA (0x02 << 20) -#define LCD_TFT_MODE BIT(7) -#define LCD_RASTER_ENABLE BIT(0) - /* Macro definitions */ #define FBSIZE(x) ((x->hactive * x->vactive * x->bpp) >> 3) From patchwork Sun Feb 9 18:47:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 236080 List-Id: U-Boot discussion From: dariobin at libero.it (Dario Binacchi) Date: Sun, 9 Feb 2020 19:47:38 +0100 Subject: [PATCH 05/11] video: omap: rename LCD controller registers In-Reply-To: <20200209184745.20473-1-dariobin@libero.it> References: <20200209184745.20473-1-dariobin@libero.it> Message-ID: <20200209184745.20473-6-dariobin@libero.it> Add more clarity by prefixing the name of the register to the bitfields. Signed-off-by: Dario Binacchi --- drivers/video/am335x-fb.c | 107 +++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c index 2facac986a..02299107af 100644 --- a/drivers/video/am335x-fb.c +++ b/drivers/video/am335x-fb.c @@ -26,42 +26,42 @@ #define LCDC_FMAX 200000000 /* LCD Control Register */ -#define LCD_RASTER_MODE BIT(0) -#define LCD_CLK_DIVISOR(x) (((x) & 0xFF) << 8) +#define LCDC_CTRL_RASTER_MODE BIT(0) +#define LCDC_CTRL_CLK_DIVISOR(x) (((x) & 0xFF) << 8) /* LCD Clock Enable Register */ -#define LCD_CORECLKEN BIT(0) -#define LCD_LIDDCLKEN BIT(1) -#define LCD_DMACLKEN BIT(2) +#define LCDC_CLKC_ENABLE_CORECLKEN BIT(0) +#define LCDC_CLKC_ENABLE_LIDDCLKEN BIT(1) +#define LCDC_CLKC_ENABLE_DMACLKEN BIT(2) /* LCD DMA Control Register */ -#define LCD_DMA_BURST_SIZE(x) (((x) & 0x07) << 4) -#define LCD_DMA_BURST_1 0x0 -#define LCD_DMA_BURST_2 0x1 -#define LCD_DMA_BURST_4 0x2 -#define LCD_DMA_BURST_8 0x3 -#define LCD_DMA_BURST_16 0x4 +#define LCDC_DMA_CTRL_BURST_SIZE(x) (((x) & 0x07) << 4) +#define LCDC_DMA_CTRL_BURST_1 0x0 +#define LCDC_DMA_CTRL_BURST_2 0x1 +#define LCDC_DMA_CTRL_BURST_4 0x2 +#define LCDC_DMA_CTRL_BURST_8 0x3 +#define LCDC_DMA_CTRL_BURST_16 0x4 /* LCD Timing_0 Register */ -#define LCD_HORMSB(x) (((((x) >> 4) - 1) & 0x40) >> 4) -#define LCD_HORLSB(x) (((((x) >> 4) - 1) & 0x3F) << 4) -#define LCD_HSWLSB(x) ((((x) - 1) & 0x3F) << 10) -#define LCD_HFPLSB(x) ((((x) - 1) & 0xFF) << 16) -#define LCD_HBPLSB(x) ((((x) - 1) & 0xFF) << 24) +#define LCDC_RASTER_TIMING_0_HORMSB(x) (((((x) >> 4) - 1) & 0x40) >> 4) +#define LCDC_RASTER_TIMING_0_HORLSB(x) (((((x) >> 4) - 1) & 0x3F) << 4) +#define LCDC_RASTER_TIMING_0_HSWLSB(x) ((((x) - 1) & 0x3F) << 10) +#define LCDC_RASTER_TIMING_0_HFPLSB(x) ((((x) - 1) & 0xFF) << 16) +#define LCDC_RASTER_TIMING_0_HBPLSB(x) ((((x) - 1) & 0xFF) << 24) /* LCD Timing_1 Register */ -#define LCD_VERLSB(x) (((x) - 1) & 0x3FF) -#define LCD_VSW(x) ((((x) - 1) & 0x3F) << 10) -#define LCD_VFP(x) (((x) & 0xFF) << 16) -#define LCD_VBP(x) (((x) & 0xFF) << 24) +#define LCDC_RASTER_TIMING_1_VERLSB(x) (((x) - 1) & 0x3FF) +#define LCDC_RASTER_TIMING_1_VSW(x) ((((x) - 1) & 0x3F) << 10) +#define LCDC_RASTER_TIMING_1_VFP(x) (((x) & 0xFF) << 16) +#define LCDC_RASTER_TIMING_1_VBP(x) (((x) & 0xFF) << 24) /* LCD Timing_2 Register */ -#define LCD_HFPMSB(x) ((((x) - 1) & 0x300) >> 8) -#define LCD_HBPMSB(x) ((((x) - 1) & 0x300) >> 4) -#define LCD_INVMASK(x) ((x) & 0x3F00000) -#define LCD_VERMSB(x) ((((x) - 1) & 0x400) << 16) -#define LCD_HSWMSB(x) ((((x) - 1) & 0x3C0) << 21) +#define LCDC_RASTER_TIMING_2_HFPMSB(x) ((((x) - 1) & 0x300) >> 8) +#define LCDC_RASTER_TIMING_2_HBPMSB(x) ((((x) - 1) & 0x300) >> 4) +#define LCDC_RASTER_TIMING_2_INVMASK(x) ((x) & 0x3F00000) +#define LCDC_RASTER_TIMING_2_VERMSB(x) ((((x) - 1) & 0x400) << 16) +#define LCDC_RASTER_TIMING_2_HSWMSB(x) ((((x) - 1) & 0x3C0) << 21) /* LCD Raster Ctrl Register */ -#define LCD_RASTER_ENABLE BIT(0) -#define LCD_TFT_MODE BIT(7) -#define LCD_PALMODE_RAWDATA (0x02 << 20) -#define LCD_TFT_24BPP_MODE BIT(25) -#define LCD_TFT_24BPP_UNPACK BIT(26) +#define LCDC_RASTER_CTRL_ENABLE BIT(0) +#define LCDC_RASTER_CTRL_TFT_MODE BIT(7) +#define LCDC_RASTER_CTRL_PALMODE_RAWDATA (0x02 << 20) +#define LCDC_RASTER_CTRL_TFT_24BPP_MODE BIT(25) +#define LCDC_RASTER_CTRL_TFT_24BPP_UNPACK BIT(26) /* Macro definitions */ #define FBSIZE(x) ((x->hactive * x->vactive * x->bpp) >> 3) @@ -131,10 +131,10 @@ int am335xfb_init(struct am335x_lcdpanel *panel) case 16: break; case 32: - raster_ctrl |= LCD_TFT_24BPP_UNPACK; + raster_ctrl |= LCDC_RASTER_CTRL_TFT_24BPP_UNPACK; /* fallthrough */ case 24: - raster_ctrl |= LCD_TFT_24BPP_MODE; + raster_ctrl |= LCDC_RASTER_CTRL_TFT_24BPP_MODE; break; default: pr_err("am335x-fb: invalid bpp value: %d\n", panel->bpp); @@ -198,34 +198,35 @@ int am335xfb_init(struct am335x_lcdpanel *panel) debug("am335x-fb: wait for stable power ...\n"); mdelay(panel->pup_delay); - lcdhw->clkc_enable = LCD_CORECLKEN | LCD_LIDDCLKEN | LCD_DMACLKEN; + lcdhw->clkc_enable = LCDC_CLKC_ENABLE_CORECLKEN | + LCDC_CLKC_ENABLE_LIDDCLKEN | LCDC_CLKC_ENABLE_DMACLKEN; lcdhw->raster_ctrl = 0; - lcdhw->ctrl = LCD_CLK_DIVISOR(best_d) | LCD_RASTER_MODE; + lcdhw->ctrl = LCDC_CTRL_CLK_DIVISOR(best_d) | LCDC_CTRL_RASTER_MODE; lcdhw->lcddma_fb0_base = gd->fb_base; lcdhw->lcddma_fb0_ceiling = gd->fb_base + FBSIZE(panel); lcdhw->lcddma_fb1_base = gd->fb_base; lcdhw->lcddma_fb1_ceiling = gd->fb_base + FBSIZE(panel); - lcdhw->lcddma_ctrl = LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16); - - lcdhw->raster_timing0 = LCD_HORLSB(panel->hactive) | - LCD_HORMSB(panel->hactive) | - LCD_HFPLSB(panel->hfp) | - LCD_HBPLSB(panel->hbp) | - LCD_HSWLSB(panel->hsw); - lcdhw->raster_timing1 = LCD_VBP(panel->vbp) | - LCD_VFP(panel->vfp) | - LCD_VSW(panel->vsw) | - LCD_VERLSB(panel->vactive); - lcdhw->raster_timing2 = LCD_HSWMSB(panel->hsw) | - LCD_VERMSB(panel->vactive) | - LCD_INVMASK(panel->pol) | - LCD_HBPMSB(panel->hbp) | - LCD_HFPMSB(panel->hfp) | + lcdhw->lcddma_ctrl = LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_16); + + lcdhw->raster_timing0 = LCDC_RASTER_TIMING_0_HORLSB(panel->hactive) | + LCDC_RASTER_TIMING_0_HORMSB(panel->hactive) | + LCDC_RASTER_TIMING_0_HFPLSB(panel->hfp) | + LCDC_RASTER_TIMING_0_HBPLSB(panel->hbp) | + LCDC_RASTER_TIMING_0_HSWLSB(panel->hsw); + lcdhw->raster_timing1 = LCDC_RASTER_TIMING_1_VBP(panel->vbp) | + LCDC_RASTER_TIMING_1_VFP(panel->vfp) | + LCDC_RASTER_TIMING_1_VSW(panel->vsw) | + LCDC_RASTER_TIMING_1_VERLSB(panel->vactive); + lcdhw->raster_timing2 = LCDC_RASTER_TIMING_2_HSWMSB(panel->hsw) | + LCDC_RASTER_TIMING_2_VERMSB(panel->vactive) | + LCDC_RASTER_TIMING_2_INVMASK(panel->pol) | + LCDC_RASTER_TIMING_2_HBPMSB(panel->hbp) | + LCDC_RASTER_TIMING_2_HFPMSB(panel->hfp) | 0x0000FF00; /* clk cycles for ac-bias */ lcdhw->raster_ctrl = raster_ctrl | - LCD_PALMODE_RAWDATA | - LCD_TFT_MODE | - LCD_RASTER_ENABLE; + LCDC_RASTER_CTRL_PALMODE_RAWDATA | + LCDC_RASTER_CTRL_TFT_MODE | + LCDC_RASTER_CTRL_ENABLE; debug("am335x-fb: waiting picture to be stable.\n."); mdelay(panel->pon_delay); From patchwork Sun Feb 9 18:47:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 236079 List-Id: U-Boot discussion From: dariobin at libero.it (Dario Binacchi) Date: Sun, 9 Feb 2020 19:47:39 +0100 Subject: [PATCH 06/11] video: omap: fix debug message In-Reply-To: <20200209184745.20473-1-dariobin@libero.it> References: <20200209184745.20473-1-dariobin@libero.it> Message-ID: <20200209184745.20473-7-dariobin@libero.it> "DISP" -> "DIV" Signed-off-by: Dario Binacchi Reviewed-by: Lokesh Vutla --- drivers/video/am335x-fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c index 02299107af..779032396e 100644 --- a/drivers/video/am335x-fb.c +++ b/drivers/video/am335x-fb.c @@ -179,7 +179,7 @@ int am335xfb_init(struct am335x_lcdpanel *panel) } } } - debug("%s: PLL: best error %d Hz (M %d, N %d, DISP %d)\n", + debug("%s: PLL: best error %d Hz (M %d, N %d, DIV %d)\n", __func__, err_r, dpll_disp.m, dpll_disp.n, best_d); do_setup_dpll(&dpll_disp_regs, &dpll_disp); From patchwork Sun Feb 9 18:47:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 236081 List-Id: U-Boot discussion From: dariobin at libero.it (Dario Binacchi) Date: Sun, 9 Feb 2020 19:47:40 +0100 Subject: [PATCH 07/11] video: omap: add loop exit conditions to the dpll setup In-Reply-To: <20200209184745.20473-1-dariobin@libero.it> References: <20200209184745.20473-1-dariobin@libero.it> Message-ID: <20200209184745.20473-8-dariobin@libero.it> In case of null error, round rate is equal to target rate, so it is useless to continue to search the DPLL setup parameters to get the desidered pixel clock rate. Signed-off-by: Dario Binacchi Reviewed-by: Lokesh Vutla --- drivers/video/am335x-fb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c index 779032396e..bb89cb515d 100644 --- a/drivers/video/am335x-fb.c +++ b/drivers/video/am335x-fb.c @@ -160,7 +160,7 @@ int am335xfb_init(struct am335x_lcdpanel *panel) err = panel->pxl_clk; err_r = err; - for (d = 2; d < 255; d++) { + for (d = 2; err_r && d < 255; d++) { for (m = 2; m < 2047; m++) { if ((V_OSCK * m) < (panel->pxl_clk * d)) continue; @@ -176,6 +176,8 @@ int am335xfb_init(struct am335x_lcdpanel *panel) dpll_disp.m = m; dpll_disp.n = n; best_d = d; + if (err_r == 0) + break; } } } From patchwork Sun Feb 9 18:47:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 236082 List-Id: U-Boot discussion From: dariobin at libero.it (Dario Binacchi) Date: Sun, 9 Feb 2020 19:47:41 +0100 Subject: [PATCH 08/11] video: omap: create two routines to set the pixel clock rate In-Reply-To: <20200209184745.20473-1-dariobin@libero.it> References: <20200209184745.20473-1-dariobin@libero.it> Message-ID: <20200209184745.20473-9-dariobin@libero.it> Created in preparation to support driver-model, they can also be called from legacy code. In this way, code duplication is avoided. Signed-off-by: Dario Binacchi --- drivers/video/am335x-fb.c | 130 ++++++++++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 33 deletions(-) diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c index bb89cb515d..e53c1d276e 100644 --- a/drivers/video/am335x-fb.c +++ b/drivers/video/am335x-fb.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "am335x-fb.h" @@ -26,6 +27,7 @@ #define LCDC_FMAX 200000000 /* LCD Control Register */ +#define LCDC_CTRL_CLK_DIVISOR_MASK (0x0000FF00) #define LCDC_CTRL_RASTER_MODE BIT(0) #define LCDC_CTRL_CLK_DIVISOR(x) (((x) & 0xFF) << 8) /* LCD Clock Enable Register */ @@ -98,10 +100,95 @@ struct am335x_lcdhw { unsigned int clkc_reset; /* 0x70 */ }; +struct dpll_data { + unsigned long rounded_rate; + u16 rounded_m; + u8 rounded_n; + u8 rounded_div; +}; + static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE; DECLARE_GLOBAL_DATA_PTR; +/** + * am335x_dpll_round_rate() - Round a target rate for an OMAP DPLL + * + * @dpll_data: struct dpll_data pointer for the DPLL + * @rate: New DPLL clock rate + * @return rounded rate and the computed m, n and div values in the dpll_data + * structure, or -ve error code. + */ +static ulong am335x_dpll_round_rate(struct dpll_data *dd, ulong rate) +{ + unsigned int m, n, d; + unsigned long rounded_rate; + int err, err_r; + + dd->rounded_rate = -EFAULT; + err = rate; + err_r = err; + + for (d = 2; err && d < 255; d++) { + for (m = 2; m < 2047; m++) { + if ((V_OSCK * m) < (rate * d)) + continue; + + n = (V_OSCK * m) / (rate * d); + if (n > 127) + break; + + if (((V_OSCK * m) / n) > LCDC_FMAX) + break; + + rounded_rate = (V_OSCK * m) / n / d; + err = abs(rounded_rate - rate); + if (err < err_r) { + err_r = err; + dd->rounded_rate = rounded_rate; + dd->rounded_m = m; + dd->rounded_n = n; + dd->rounded_div = d; + if (err == 0) + break; + } + } + } + + debug("DPLL display: best error %d Hz (M %d, N %d, DIV %d)\n", + err_r, dd->rounded_m, dd->rounded_n, dd->rounded_div); + + return dd->rounded_rate; +} + +/** + * am335x_fb_set_pixel_clk_rate() - Set pixel clock rate. + * + * @am335x_lcdhw: Base address of the LCD controller registers. + * @rate: New clock rate in Hz. + * @return new rate, or -ve error code. + */ +static ulong am335x_fb_set_pixel_clk_rate(struct am335x_lcdhw *regs, ulong rate) +{ + struct dpll_params dpll_disp = { 1, 0, 1, -1, -1, -1, -1 }; + struct dpll_data dd; + ulong round_rate; + u32 reg; + + round_rate = am335x_dpll_round_rate(&dd, rate); + if (IS_ERR_VALUE(round_rate)) + return round_rate; + + dpll_disp.m = dd.rounded_m; + dpll_disp.n = dd.rounded_n; + do_setup_dpll(&dpll_disp_regs, &dpll_disp); + + reg = readl(®s->ctrl) & ~LCDC_CTRL_CLK_DIVISOR_MASK; + reg |= LCDC_CTRL_CLK_DIVISOR(dd.rounded_div); + writel(reg, ®s->ctrl); + return round_rate; +} + int lcd_get_size(int *line_length) { *line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; @@ -111,11 +198,9 @@ int lcd_get_size(int *line_length) int am335xfb_init(struct am335x_lcdpanel *panel) { u32 raster_ctrl = 0; - struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL; - struct dpll_params dpll_disp = { 1, 0, 1, -1, -1, -1, -1 }; - unsigned int m, n, d, best_d = 2; - int err = 0, err_r = 0; + ulong rate; + u32 reg; if (gd->fb_base == 0) { printf("ERROR: no valid fb_base stored in GLOBAL_DATA_PTR!\n"); @@ -156,34 +241,9 @@ int am335xfb_init(struct am335x_lcdpanel *panel) debug("using frambuffer at 0x%08x with size %d.\n", (unsigned int)gd->fb_base, FBSIZE(panel)); - /* setup display pll for requested clock frequency */ - err = panel->pxl_clk; - err_r = err; - - for (d = 2; err_r && d < 255; d++) { - for (m = 2; m < 2047; m++) { - if ((V_OSCK * m) < (panel->pxl_clk * d)) - continue; - n = (V_OSCK * m) / (panel->pxl_clk * d); - if (n > 127) - break; - if (((V_OSCK * m) / n) > LCDC_FMAX) - break; - - err = abs((V_OSCK * m) / n / d - panel->pxl_clk); - if (err < err_r) { - err_r = err; - dpll_disp.m = m; - dpll_disp.n = n; - best_d = d; - if (err_r == 0) - break; - } - } - } - debug("%s: PLL: best error %d Hz (M %d, N %d, DIV %d)\n", - __func__, err_r, dpll_disp.m, dpll_disp.n, best_d); - do_setup_dpll(&dpll_disp_regs, &dpll_disp); + rate = am335x_fb_set_pixel_clk_rate(lcdhw, panel->pxl_clk); + if (IS_ERR_VALUE(rate)) + return rate; /* clock source for LCDC from dispPLL M2 */ writel(0x0, &cmdpll->clklcdcpixelclk); @@ -203,7 +263,11 @@ int am335xfb_init(struct am335x_lcdpanel *panel) lcdhw->clkc_enable = LCDC_CLKC_ENABLE_CORECLKEN | LCDC_CLKC_ENABLE_LIDDCLKEN | LCDC_CLKC_ENABLE_DMACLKEN; lcdhw->raster_ctrl = 0; - lcdhw->ctrl = LCDC_CTRL_CLK_DIVISOR(best_d) | LCDC_CTRL_RASTER_MODE; + + reg = lcdhw->ctrl & LCDC_CTRL_CLK_DIVISOR_MASK; + reg |= LCDC_CTRL_RASTER_MODE; + lcdhw->ctrl = reg; + lcdhw->lcddma_fb0_base = gd->fb_base; lcdhw->lcddma_fb0_ceiling = gd->fb_base + FBSIZE(panel); lcdhw->lcddma_fb1_base = gd->fb_base; From patchwork Sun Feb 9 18:47:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 236083 List-Id: U-Boot discussion From: dariobin at libero.it (Dario Binacchi) Date: Sun, 9 Feb 2020 19:47:42 +0100 Subject: [PATCH 09/11] video: omap: add support for DM/DTS In-Reply-To: <20200209184745.20473-1-dariobin@libero.it> References: <20200209184745.20473-1-dariobin@libero.it> Message-ID: <20200209184745.20473-10-dariobin@libero.it> Update the driver to support the device tree and the driver model. Timings and panel parameters are now loaded from the device tree. The DM code replaces the am335x_lcdpanel structure with tilcdc_panel_info taken from the linux kernel, as well the management of additional parameters not covered in the legacy code. In addition, the am335x_lcdpanel structure contains parameters and operations that were probably a requirement of the board for which this driver was developed and which, however, were not developed in the linux kernel. All this led to rewrite th DM controller initialization code, except for the pixel clock setting that is executed in a function created in a previous patch with code taken from the legacy am335xfb_init. The patch has been tested on a custom board with the following DT configuration: panel { compatible = "ti,tilcdc,panel"; pinctrl-names = "default"; pinctrl-0 = <&lcd_enable_pins>; enable-gpios = <&gpio0 31 0>; backlight = <&backlight>; status = "okay"; u-boot,dm-pre-reloc; panel-info { ac-bias = <255>; ac-bias-intrpt = <0>; dma-burst-sz = <16>; bpp = <16>; fdd = <0x80>; sync-edge = <0>; sync-ctrl = <1>; raster-order = <0>; fifo-th = <0>; }; display-timings { native-mode = <&timing0>; timing0: 800x480 { hactive = <800>; vactive = <480>; hback-porch = <46>; hfront-porch = <210>; hsync-len = <20>; vback-porch = <23>; vfront-porch = <22>; vsync-len = <10>; clock-frequency = <33000000>; hsync-active = <0>; vsync-active = <0>; }; }; }; Signed-off-by: Dario Binacchi Tested-by: Dario Binacchi --- drivers/video/am335x-fb.c | 346 ++++++++++++++++++++++++++++++++++++-- drivers/video/am335x-fb.h | 4 + 2 files changed, 340 insertions(+), 10 deletions(-) diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c index e53c1d276e..e8bd9c6464 100644 --- a/drivers/video/am335x-fb.c +++ b/drivers/video/am335x-fb.c @@ -2,6 +2,7 @@ /* * Copyright (C) 2013-2018 Hannes Schmelzer * B&R Industrial Automation GmbH - http://www.br-automation.com + * Copyright (C) 2020 Dario Binacchi * * minimal framebuffer driver for TI's AM335x SoC to be compatible with * Wolfgang Denk's LCD-Framework (CONFIG_LCD, common/lcd.c) @@ -11,19 +12,18 @@ * - starts output DMA from gd->fb_base buffer */ #include +#include #include #include #include #include #include +#include #include #include +#include #include "am335x-fb.h" -#if !defined(LCD_CNTL_BASE) -#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!" -#endif - #define LCDC_FMAX 200000000 /* LCD Control Register */ @@ -41,6 +41,7 @@ #define LCDC_DMA_CTRL_BURST_4 0x2 #define LCDC_DMA_CTRL_BURST_8 0x3 #define LCDC_DMA_CTRL_BURST_16 0x4 +#define LCDC_DMA_CTRL_FIFO_TH(x) (((x) & 0x07) << 8) /* LCD Timing_0 Register */ #define LCDC_RASTER_TIMING_0_HORMSB(x) (((((x) >> 4) - 1) & 0x40) >> 4) #define LCDC_RASTER_TIMING_0_HORLSB(x) (((((x) >> 4) - 1) & 0x3F) << 4) @@ -55,19 +56,26 @@ /* LCD Timing_2 Register */ #define LCDC_RASTER_TIMING_2_HFPMSB(x) ((((x) - 1) & 0x300) >> 8) #define LCDC_RASTER_TIMING_2_HBPMSB(x) ((((x) - 1) & 0x300) >> 4) -#define LCDC_RASTER_TIMING_2_INVMASK(x) ((x) & 0x3F00000) +#define LCDC_RASTER_TIMING_2_ACB(x) (((x) & 0xFF) << 8) +#define LCDC_RASTER_TIMING_2_ACBI(x) (((x) & 0x0F) << 16) +#define LCDC_RASTER_TIMING_2_VSYNC_INVERT BIT(20) +#define LCDC_RASTER_TIMING_2_HSYNC_INVERT BIT(21) +#define LCDC_RASTER_TIMING_2_PXCLK_INVERT BIT(22) +#define LCDC_RASTER_TIMING_2_DE_INVERT BIT(23) +#define LCDC_RASTER_TIMING_2_HSVS_RISEFALL BIT(24) +#define LCDC_RASTER_TIMING_2_HSVS_CONTROL BIT(25) #define LCDC_RASTER_TIMING_2_VERMSB(x) ((((x) - 1) & 0x400) << 16) #define LCDC_RASTER_TIMING_2_HSWMSB(x) ((((x) - 1) & 0x3C0) << 21) /* LCD Raster Ctrl Register */ #define LCDC_RASTER_CTRL_ENABLE BIT(0) #define LCDC_RASTER_CTRL_TFT_MODE BIT(7) +#define LCDC_RASTER_CTRL_DATA_ORDER BIT(8) +#define LCDC_RASTER_CTRL_REQDLY(x) (((x) & 0xFF) << 12) #define LCDC_RASTER_CTRL_PALMODE_RAWDATA (0x02 << 20) +#define LCDC_RASTER_CTRL_TFT_ALT_ENABLE BIT(23) #define LCDC_RASTER_CTRL_TFT_24BPP_MODE BIT(25) #define LCDC_RASTER_CTRL_TFT_24BPP_UNPACK BIT(26) -/* Macro definitions */ -#define FBSIZE(x) ((x->hactive * x->vactive * x->bpp) >> 3) - struct am335x_lcdhw { unsigned int pid; /* 0x00 */ unsigned int ctrl; /* 0x04 */ @@ -107,8 +115,6 @@ struct dpll_data { u8 rounded_div; }; -static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE; - DECLARE_GLOBAL_DATA_PTR; /** @@ -189,6 +195,19 @@ static ulong am335x_fb_set_pixel_clk_rate(struct am335x_lcdhw *regs, ulong rate) return round_rate; } +#if !defined(CONFIG_DM_VIDEO) + +#if !defined(LCD_CNTL_BASE) +#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!" +#endif + +/* Macro definitions */ +#define FBSIZE(x) (((x)->hactive * (x)->vactive * (x)->bpp) >> 3) + +#define LCDC_RASTER_TIMING_2_INVMASK(x) ((x) & 0x3F00000) + +static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE; + int lcd_get_size(int *line_length) { *line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; @@ -299,3 +318,310 @@ int am335xfb_init(struct am335x_lcdpanel *panel) return 0; } + +#else /* CONFIG_DM_VIDEO */ + +#define FBSIZE(t, p) (((t)->hactive.typ * (t)->vactive.typ * (p)->bpp) >> 3) + +enum { + LCD_MAX_WIDTH = 2048, + LCD_MAX_HEIGHT = 2048, + LCD_MAX_LOG2_BPP = VIDEO_BPP32, +}; + +/** + * tilcdc_panel_info: Panel parameters + * + * @ac_bias: AC Bias Pin Frequency + * @ac_bias_intrpt: AC Bias Pin Transitions per Interrupt + * @dma_burst_sz: DMA burst size + * @bpp: Bits per pixel + * @fdd: FIFO DMA Request Delay + * @tft_alt_mode: TFT Alternative Signal Mapping (Only for active) + * @invert_pxl_clk: Invert pixel clock + * @sync_edge: Horizontal and Vertical Sync Edge: 0=rising 1=falling + * @sync_ctrl: Horizontal and Vertical Sync: Control: 0=ignore + * @raster_order: Raster Data Order Select: 1=Most-to-least 0=Least-to-most + * @fifo_th: DMA FIFO threshold + */ +struct tilcdc_panel_info { + u32 ac_bias; + u32 ac_bias_intrpt; + u32 dma_burst_sz; + u32 bpp; + u32 fdd; + bool tft_alt_mode; + bool invert_pxl_clk; + u32 sync_edge; + u32 sync_ctrl; + u32 raster_order; + u32 fifo_th; +}; + +struct am335x_fb_priv { + struct am335x_lcdhw *regs; + struct tilcdc_panel_info panel; + struct display_timing timing; +}; + +static int am335x_fb_remove(struct udevice *dev) +{ + struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev); + + uc_plat->base -= 0x20; + uc_plat->size += 0x20; + return 0; +} + +static int am335x_fb_probe(struct udevice *dev) +{ + struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev); + struct video_priv *uc_priv = dev_get_uclass_priv(dev); + struct am335x_fb_priv *priv = dev_get_priv(dev); + struct am335x_lcdhw *regs = priv->regs; + struct tilcdc_panel_info *panel = &priv->panel; + struct display_timing *timing = &priv->timing; + struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL; + struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER; + u32 *const clk_domains[] = { 0 }; + u32 *const clk_modules[] = { + &cmper->lcdclkctrl, + &cmper->lcdcclkstctrl, + 0 + }; + u32 reg; + + /* Before relocation we don't need to do anything */ + if (!(gd->flags & GD_FLG_RELOC)) + return 0; + + do_enable_clocks(clk_domains, clk_modules, 1); + + am335x_fb_set_pixel_clk_rate(regs, timing->pixelclock.typ); + + /* clock source for LCDC from dispPLL M2 */ + writel(0, &cmdpll->clklcdcpixelclk); + + /* palette default entry */ + memset((void *)uc_plat->base, 0, 0x20); + *(unsigned int *)uc_plat->base = 0x4000; + /* point fb behind palette */ + uc_plat->base += 0x20; + uc_plat->size -= 0x20; + + writel(LCDC_CLKC_ENABLE_CORECLKEN | LCDC_CLKC_ENABLE_LIDDCLKEN | + LCDC_CLKC_ENABLE_DMACLKEN, ®s->clkc_enable); + writel(0, ®s->raster_ctrl); + + reg = readl(®s->ctrl) & LCDC_CTRL_CLK_DIVISOR_MASK; + reg |= LCDC_CTRL_RASTER_MODE; + writel(reg, ®s->ctrl); + + writel(uc_plat->base, ®s->lcddma_fb0_base); + writel(uc_plat->base + FBSIZE(timing, panel), + ®s->lcddma_fb0_ceiling); + writel(uc_plat->base, ®s->lcddma_fb1_base); + writel(uc_plat->base + FBSIZE(timing, panel), + ®s->lcddma_fb1_ceiling); + + reg = LCDC_DMA_CTRL_FIFO_TH(panel->fifo_th); + switch (panel->dma_burst_sz) { + case 1: + reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_1); + break; + case 2: + reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_2); + break; + case 4: + reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_4); + break; + case 8: + reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_8); + break; + case 16: + reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_16); + break; + } + + writel(reg, ®s->lcddma_ctrl); + + writel(LCDC_RASTER_TIMING_0_HORLSB(timing->hactive.typ) | + LCDC_RASTER_TIMING_0_HORMSB(timing->hactive.typ) | + LCDC_RASTER_TIMING_0_HFPLSB(timing->hfront_porch.typ) | + LCDC_RASTER_TIMING_0_HBPLSB(timing->hback_porch.typ) | + LCDC_RASTER_TIMING_0_HSWLSB(timing->hsync_len.typ), + ®s->raster_timing0); + + writel(LCDC_RASTER_TIMING_1_VBP(timing->vback_porch.typ) | + LCDC_RASTER_TIMING_1_VFP(timing->vfront_porch.typ) | + LCDC_RASTER_TIMING_1_VSW(timing->vsync_len.typ) | + LCDC_RASTER_TIMING_1_VERLSB(timing->vactive.typ), + ®s->raster_timing1); + + reg = LCDC_RASTER_TIMING_2_ACB(panel->ac_bias) | + LCDC_RASTER_TIMING_2_ACBI(panel->ac_bias_intrpt) | + LCDC_RASTER_TIMING_2_HSWMSB(timing->hsync_len.typ) | + LCDC_RASTER_TIMING_2_VERMSB(timing->vactive.typ) | + LCDC_RASTER_TIMING_2_HBPMSB(timing->hback_porch.typ) | + LCDC_RASTER_TIMING_2_HFPMSB(timing->hfront_porch.typ); + + if (timing->flags & DISPLAY_FLAGS_VSYNC_LOW) + reg |= LCDC_RASTER_TIMING_2_VSYNC_INVERT; + + if (timing->flags & DISPLAY_FLAGS_HSYNC_LOW) + reg |= LCDC_RASTER_TIMING_2_HSYNC_INVERT; + + if (panel->invert_pxl_clk) + reg |= LCDC_RASTER_TIMING_2_PXCLK_INVERT; + + if (panel->sync_edge) + reg |= LCDC_RASTER_TIMING_2_HSVS_RISEFALL; + + if (panel->sync_ctrl) + reg |= LCDC_RASTER_TIMING_2_HSVS_CONTROL; + + writel(reg, ®s->raster_timing2); + + reg = LCDC_RASTER_CTRL_PALMODE_RAWDATA | LCDC_RASTER_CTRL_TFT_MODE | + LCDC_RASTER_CTRL_ENABLE | LCDC_RASTER_CTRL_REQDLY(panel->fdd); + + if (panel->tft_alt_mode) + reg |= LCDC_RASTER_CTRL_TFT_ALT_ENABLE; + + if (panel->bpp == 24) + reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE; + else if (panel->bpp == 32) + reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE | + LCDC_RASTER_CTRL_TFT_24BPP_UNPACK; + + if (panel->raster_order) + reg |= LCDC_RASTER_CTRL_DATA_ORDER; + + writel(reg, ®s->raster_ctrl); + + uc_priv->xsize = timing->hactive.typ; + uc_priv->ysize = timing->vactive.typ; + uc_priv->bpix = log_2_n_round_up(panel->bpp); + return 0; +} + +static int am335x_fb_ofdata_to_platdata(struct udevice *dev) +{ + struct am335x_fb_priv *priv = dev_get_priv(dev); + struct tilcdc_panel_info *panel = &priv->panel; + struct display_timing *timing = &priv->timing; + ofnode node; + int err; + + node = ofnode_by_compatible(ofnode_null(), "ti,am33xx-tilcdc"); + if (!ofnode_valid(node)) { + dev_err(dev, "missing 'ti,am33xx-tilcdc' node\n"); + return -ENXIO; + } + + priv->regs = (struct am335x_lcdhw *)ofnode_get_addr(node); + dev_dbg(dev, "LCD: base address=0x%x\n", (unsigned int)priv->regs); + + err = ofnode_decode_display_timing(dev_ofnode(dev), 0, timing); + if (err) { + dev_err(dev, "failed to get display timing\n"); + return err; + } + + if (timing->pixelclock.typ > (LCDC_FMAX / 2)) { + dev_err(dev, "invalid display clock-frequency: %d Hz\n", + timing->pixelclock.typ); + return -EINVAL; + } + + if (timing->hactive.typ > LCD_MAX_WIDTH) + timing->hactive.typ = LCD_MAX_WIDTH; + + if (timing->vactive.typ > LCD_MAX_HEIGHT) + timing->vactive.typ = LCD_MAX_HEIGHT; + + node = ofnode_find_subnode(dev_ofnode(dev), "panel-info"); + if (!ofnode_valid(node)) { + dev_err(dev, "missing 'panel-info' node\n"); + return -ENXIO; + } + + err |= ofnode_read_u32(node, "ac-bias", &panel->ac_bias); + err |= ofnode_read_u32(node, "ac-bias-intrpt", &panel->ac_bias_intrpt); + err |= ofnode_read_u32(node, "dma-burst-sz", &panel->dma_burst_sz); + err |= ofnode_read_u32(node, "bpp", &panel->bpp); + err |= ofnode_read_u32(node, "fdd", &panel->fdd); + err |= ofnode_read_u32(node, "sync-edge", &panel->sync_edge); + err |= ofnode_read_u32(node, "sync-ctrl", &panel->sync_ctrl); + err |= ofnode_read_u32(node, "raster-order", &panel->raster_order); + err |= ofnode_read_u32(node, "fifo-th", &panel->fifo_th); + if (err) { + dev_err(dev, "failed to get panel info\n"); + return err; + } + + switch (panel->bpp) { + case 16: + case 24: + case 32: + break; + default: + dev_err(dev, "invalid seting, bpp: %d\n", panel->bpp); + return -EINVAL; + } + + switch (panel->dma_burst_sz) { + case 1: + case 2: + case 4: + case 8: + case 16: + break; + default: + dev_err(dev, "invalid setting, dma-burst-sz: %d\n", + panel->dma_burst_sz); + return -EINVAL; + } + + /* optional */ + panel->tft_alt_mode = ofnode_read_bool(node, "tft-alt-mode"); + panel->invert_pxl_clk = ofnode_read_bool(node, "invert-pxl-clk"); + + dev_dbg(dev, "LCD: %dx%d, bpp=%d, clk=%d Hz\n", timing->hactive.typ, + timing->vactive.typ, panel->bpp, timing->pixelclock.typ); + dev_dbg(dev, " hbp=%d, hfp=%d, hsw=%d\n", timing->hback_porch.typ, + timing->hfront_porch.typ, timing->hsync_len.typ); + dev_dbg(dev, " vbp=%d, vfp=%d, vsw=%d\n", timing->vback_porch.typ, + timing->vfront_porch.typ, timing->vsync_len.typ); + + return 0; +} + +static int am335x_fb_bind(struct udevice *dev) +{ + struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev); + + uc_plat->size = ((LCD_MAX_WIDTH * LCD_MAX_HEIGHT * + (1 << LCD_MAX_LOG2_BPP)) >> 3) + 0x20; + + dev_dbg(dev, "frame buffer size 0x%x\n", uc_plat->size); + return 0; +} + +static const struct udevice_id am335x_fb_ids[] = { + { .compatible = "ti,tilcdc,panel" }, + { } +}; + +U_BOOT_DRIVER(am335x_fb) = { + .name = "am335x_fb", + .id = UCLASS_VIDEO, + .of_match = am335x_fb_ids, + .bind = am335x_fb_bind, + .ofdata_to_platdata = am335x_fb_ofdata_to_platdata, + .probe = am335x_fb_probe, + .remove = am335x_fb_remove, + .priv_auto_alloc_size = sizeof(struct am335x_fb_priv), +}; + +#endif /* CONFIG_DM_VIDEO */ diff --git a/drivers/video/am335x-fb.h b/drivers/video/am335x-fb.h index ad9b015e09..7e7ec02ea6 100644 --- a/drivers/video/am335x-fb.h +++ b/drivers/video/am335x-fb.h @@ -7,6 +7,8 @@ #ifndef AM335X_FB_H #define AM335X_FB_H +#if !defined(CONFIG_DM_VIDEO) + #define HSVS_CONTROL BIT(25) /* * 0 = lcd_lp and lcd_fp are driven on * opposite edges of pixel clock than @@ -68,4 +70,6 @@ struct am335x_lcdpanel { int am335xfb_init(struct am335x_lcdpanel *panel); +#endif /* CONFIG_DM_VIDEO */ + #endif /* AM335X_FB_H */ From patchwork Sun Feb 9 18:47:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 236084 List-Id: U-Boot discussion From: dariobin at libero.it (Dario Binacchi) Date: Sun, 9 Feb 2020 19:47:43 +0100 Subject: [PATCH 10/11] arm: fdt: omap: update dts panel node In-Reply-To: <20200209184745.20473-1-dariobin@libero.it> References: <20200209184745.20473-1-dariobin@libero.it> Message-ID: <20200209184745.20473-11-dariobin@libero.it> Add the "u-boot,dm-pre-reloc" property to the "ti,tilcdc,panel" compatible node. In this way the video-uclass module can allocate the amount of memory needed to be assigned to the frame buffer. Signed-off-by: Dario Binacchi --- arch/arm/dts/am335x-brppt1-mmc.dts | 2 ++ arch/arm/dts/am335x-brppt1-nand.dts | 2 ++ arch/arm/dts/am335x-brppt1-spi.dts | 2 ++ arch/arm/dts/am335x-brsmarc1.dts | 1 + arch/arm/dts/am335x-brxre1.dts | 2 ++ arch/arm/dts/am335x-evm.dts | 1 + arch/arm/dts/am335x-evmsk.dts | 1 + arch/arm/dts/am335x-guardian.dts | 1 + arch/arm/dts/am335x-pdu001.dts | 1 + arch/arm/dts/am335x-pxm50.dts | 1 + arch/arm/dts/am335x-rut.dts | 1 + arch/arm/dts/da850-evm.dts | 1 + 12 files changed, 16 insertions(+) diff --git a/arch/arm/dts/am335x-brppt1-mmc.dts b/arch/arm/dts/am335x-brppt1-mmc.dts index 9be34d9da0..6f919711f0 100644 --- a/arch/arm/dts/am335x-brppt1-mmc.dts +++ b/arch/arm/dts/am335x-brppt1-mmc.dts @@ -53,6 +53,8 @@ bkl-pwm = <&pwmbacklight>; bkl-tps = <&tps_bl>; + u-boot,dm-pre-reloc; + panel-info { ac-bias = <255>; ac-bias-intrpt = <0>; diff --git a/arch/arm/dts/am335x-brppt1-nand.dts b/arch/arm/dts/am335x-brppt1-nand.dts index 11bd5c551c..9d4340f591 100644 --- a/arch/arm/dts/am335x-brppt1-nand.dts +++ b/arch/arm/dts/am335x-brppt1-nand.dts @@ -53,6 +53,8 @@ bkl-pwm = <&pwmbacklight>; bkl-tps = <&tps_bl>; + u-boot,dm-pre-reloc; + panel-info { ac-bias = <255>; ac-bias-intrpt = <0>; diff --git a/arch/arm/dts/am335x-brppt1-spi.dts b/arch/arm/dts/am335x-brppt1-spi.dts index 01ab74be5e..c078af8fba 100644 --- a/arch/arm/dts/am335x-brppt1-spi.dts +++ b/arch/arm/dts/am335x-brppt1-spi.dts @@ -54,6 +54,8 @@ bkl-pwm = <&pwmbacklight>; bkl-tps = <&tps_bl>; + u-boot,dm-pre-reloc; + panel-info { ac-bias = <255>; ac-bias-intrpt = <0>; diff --git a/arch/arm/dts/am335x-brsmarc1.dts b/arch/arm/dts/am335x-brsmarc1.dts index a63fc2da22..7e9516e8f8 100644 --- a/arch/arm/dts/am335x-brsmarc1.dts +++ b/arch/arm/dts/am335x-brsmarc1.dts @@ -59,6 +59,7 @@ /*backlight = <&tps_bl>; */ compatible = "ti,tilcdc,panel"; status = "okay"; + u-boot,dm-pre-reloc; panel-info { ac-bias = <255>; diff --git a/arch/arm/dts/am335x-brxre1.dts b/arch/arm/dts/am335x-brxre1.dts index 33d8ab78d8..6091a12fb7 100644 --- a/arch/arm/dts/am335x-brxre1.dts +++ b/arch/arm/dts/am335x-brxre1.dts @@ -79,6 +79,8 @@ backlight = <&tps_bl>; + u-boot,dm-pre-reloc; + panel-info { ac-bias = <255>; ac-bias-intrpt = <0>; diff --git a/arch/arm/dts/am335x-evm.dts b/arch/arm/dts/am335x-evm.dts index 0bda4d4429..60e4991658 100644 --- a/arch/arm/dts/am335x-evm.dts +++ b/arch/arm/dts/am335x-evm.dts @@ -109,6 +109,7 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&lcd_pins_s0>; + u-boot,dm-pre-reloc; panel-info { ac-bias = <255>; ac-bias-intrpt = <0>; diff --git a/arch/arm/dts/am335x-evmsk.dts b/arch/arm/dts/am335x-evmsk.dts index 5762967cf7..3d713a6b88 100644 --- a/arch/arm/dts/am335x-evmsk.dts +++ b/arch/arm/dts/am335x-evmsk.dts @@ -172,6 +172,7 @@ pinctrl-0 = <&lcd_pins_default>; pinctrl-1 = <&lcd_pins_sleep>; status = "okay"; + u-boot,dm-pre-reloc; panel-info { ac-bias = <255>; ac-bias-intrpt = <0>; diff --git a/arch/arm/dts/am335x-guardian.dts b/arch/arm/dts/am335x-guardian.dts index 5ed2133e78..9e2b9d6b48 100644 --- a/arch/arm/dts/am335x-guardian.dts +++ b/arch/arm/dts/am335x-guardian.dts @@ -67,6 +67,7 @@ pinctrl-names = "default", "sleep"; pinctrl-0 = <&lcd_pins_default &lcd_disen_pins>; pinctrl-1 = <&lcd_pins_sleep>; + u-boot,dm-pre-reloc; display-timings { 320x240 { diff --git a/arch/arm/dts/am335x-pdu001.dts b/arch/arm/dts/am335x-pdu001.dts index ae43d61f4e..13085a7884 100644 --- a/arch/arm/dts/am335x-pdu001.dts +++ b/arch/arm/dts/am335x-pdu001.dts @@ -54,6 +54,7 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&lcd_pins_s0>; + u-boot,dm-pre-reloc; panel-info { ac-bias = <255>; ac-bias-intrpt = <0>; diff --git a/arch/arm/dts/am335x-pxm50.dts b/arch/arm/dts/am335x-pxm50.dts index f4e66d29d5..25601c2655 100644 --- a/arch/arm/dts/am335x-pxm50.dts +++ b/arch/arm/dts/am335x-pxm50.dts @@ -23,6 +23,7 @@ pinctrl-0 = <&lcd_pins_s0>; enable-gpios = <&gpio3 15 0>; status = "okay"; + u-boot,dm-pre-reloc; panel-info { ac-bias = <255>; diff --git a/arch/arm/dts/am335x-rut.dts b/arch/arm/dts/am335x-rut.dts index 145247344f..1617c57235 100644 --- a/arch/arm/dts/am335x-rut.dts +++ b/arch/arm/dts/am335x-rut.dts @@ -91,6 +91,7 @@ pinctrl-names = "default"; pinctrl-0 = <&lcd_pins_s0>; status = "okay"; + u-boot,dm-pre-reloc; /* FORMIKE_KWH043ST20_F01 */ panel-info { diff --git a/arch/arm/dts/da850-evm.dts b/arch/arm/dts/da850-evm.dts index f04bc3e153..2e1cf35c8d 100644 --- a/arch/arm/dts/da850-evm.dts +++ b/arch/arm/dts/da850-evm.dts @@ -53,6 +53,7 @@ */ status = "okay"; enable-gpios = <&gpio 40 GPIO_ACTIVE_HIGH>; /* lcd_panel_pwr */ + u-boot,dm-pre-reloc; panel-info { ac-bias = <255>; From patchwork Sun Feb 9 18:47:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 236085 List-Id: U-Boot discussion From: dariobin at libero.it (Dario Binacchi) Date: Sun, 9 Feb 2020 19:47:44 +0100 Subject: [PATCH 11/11] fdt: video: omap: add framebuffer and panel bindings In-Reply-To: <20200209184745.20473-1-dariobin@libero.it> References: <20200209184745.20473-1-dariobin@libero.it> Message-ID: <20200209184745.20473-12-dariobin@libero.it> Add device-tree binding documentation for ti framebuffer and generic panel output driver. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass --- .../video/tilcdc/panel.txt | 66 +++++++++++++++ .../video/tilcdc/tilcdc.txt | 82 +++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 doc/device-tree-bindings/video/tilcdc/panel.txt create mode 100644 doc/device-tree-bindings/video/tilcdc/tilcdc.txt diff --git a/doc/device-tree-bindings/video/tilcdc/panel.txt b/doc/device-tree-bindings/video/tilcdc/panel.txt new file mode 100644 index 0000000000..808216310e --- /dev/null +++ b/doc/device-tree-bindings/video/tilcdc/panel.txt @@ -0,0 +1,66 @@ +Device-Tree bindings for tilcdc DRM generic panel output driver + +Required properties: + - compatible: value should be "ti,tilcdc,panel". + - panel-info: configuration info to configure LCDC correctly for the panel + - ac-bias: AC Bias Pin Frequency + - ac-bias-intrpt: AC Bias Pin Transitions per Interrupt + - dma-burst-sz: DMA burst size + - bpp: Bits per pixel + - fdd: FIFO DMA Request Delay + - sync-edge: Horizontal and Vertical Sync Edge: 0=rising 1=falling + - sync-ctrl: Horizontal and Vertical Sync: Control: 0=ignore + - raster-order: Raster Data Order Select: 1=Most-to-least 0=Least-to-most + - fifo-th: DMA FIFO threshold + - display-timings: typical videomode of lcd panel. Multiple video modes + can be listed if the panel supports multiple timings, but the 'native-mode' + should be the preferred/default resolution. Refer to + Documentation/devicetree/bindings/display/panel/display-timing.txt for display + timing binding details. + +Optional properties: +- backlight: phandle of the backlight device attached to the panel +- enable-gpios: GPIO pin to enable or disable the panel + +Recommended properties: + - pinctrl-names, pinctrl-0: the pincontrol settings to configure + muxing properly for pins that connect to TFP410 device + +Example: + + /* Settings for CDTech_S035Q01 / LCD3 cape: */ + lcd3 { + compatible = "ti,tilcdc,panel"; + pinctrl-names = "default"; + pinctrl-0 = <&bone_lcd3_cape_lcd_pins>; + backlight = <&backlight>; + enable-gpios = <&gpio3 19 0>; + + panel-info { + ac-bias = <255>; + ac-bias-intrpt = <0>; + dma-burst-sz = <16>; + bpp = <16>; + fdd = <0x80>; + sync-edge = <0>; + sync-ctrl = <1>; + raster-order = <0>; + fifo-th = <0>; + }; + display-timings { + native-mode = <&timing0>; + timing0: 320x240 { + hactive = <320>; + vactive = <240>; + hback-porch = <21>; + hfront-porch = <58>; + hsync-len = <47>; + vback-porch = <11>; + vfront-porch = <23>; + vsync-len = <2>; + clock-frequency = <8000000>; + hsync-active = <0>; + vsync-active = <0>; + }; + }; + }; diff --git a/doc/device-tree-bindings/video/tilcdc/tilcdc.txt b/doc/device-tree-bindings/video/tilcdc/tilcdc.txt new file mode 100644 index 0000000000..7bf1bb4448 --- /dev/null +++ b/doc/device-tree-bindings/video/tilcdc/tilcdc.txt @@ -0,0 +1,82 @@ +Device-Tree bindings for tilcdc DRM driver + +Required properties: + - compatible: value should be one of the following: + - "ti,am33xx-tilcdc" for AM335x based boards + - "ti,da850-tilcdc" for DA850/AM18x/OMAP-L138 based boards + - interrupts: the interrupt number + - reg: base address and size of the LCDC device + +Recommended properties: + - ti,hwmods: Name of the hwmod associated to the LCDC + +Optional properties: + - max-bandwidth: The maximum pixels per second that the memory + interface / lcd controller combination can sustain + - max-width: The maximum horizontal pixel width supported by + the lcd controller. + - max-pixelclock: The maximum pixel clock that can be supported + by the lcd controller in KHz. + - blue-and-red-wiring: Recognized values "straight" or "crossed". + This property deals with the LCDC revision 2 (found on AM335x) + color errata [1]. + - "straight" indicates normal wiring that supports RGB565, + BGR888, and XBGR8888 color formats. + - "crossed" indicates wiring that has blue and red wires + crossed. This setup supports BGR565, RGB888 and XRGB8888 + formats. + - If the property is not present or its value is not recognized + the legacy mode is assumed. This configuration supports RGB565, + RGB888 and XRGB8888 formats. However, depending on wiring, the red + and blue colors are swapped in either 16 or 24-bit color modes. + +Optional nodes: + + - port/ports: to describe a connection to an external encoder. The + binding follows Documentation/devicetree/bindings/graph.txt and + supports a single port with a single endpoint. + + - See also Documentation/devicetree/bindings/display/tilcdc/panel.txt and + Documentation/devicetree/bindings/display/tilcdc/tfp410.txt for connecting + tfp410 DVI encoder or lcd panel to lcdc + +[1] There is an errata about AM335x color wiring. For 16-bit color mode + the wires work as they should (LCD_DATA[0:4] is for Blue[3:7]), + but for 24 bit color modes the wiring of blue and red components is + crossed and LCD_DATA[0:4] is for Red[3:7] and LCD_DATA[11:15] is + for Blue[3-7]. For more details see section 3.1.1 in AM335x + Silicon Errata: + http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sprz360 + +Example: + + fb: fb at 4830e000 { + compatible = "ti,am33xx-tilcdc", "ti,da850-tilcdc"; + reg = <0x4830e000 0x1000>; + interrupt-parent = <&intc>; + interrupts = <36>; + ti,hwmods = "lcdc"; + + blue-and-red-wiring = "crossed"; + + port { + lcdc_0: endpoint at 0 { + remote-endpoint = <&hdmi_0>; + }; + }; + }; + + tda19988: tda19988 { + compatible = "nxp,tda998x"; + reg = <0x70>; + + pinctrl-names = "default", "off"; + pinctrl-0 = <&nxp_hdmi_bonelt_pins>; + pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; + + port { + hdmi_0: endpoint at 0 { + remote-endpoint = <&lcdc_0>; + }; + }; + };