[PATCH 09/11] video: omap: add support for DM/DTS

Lokesh Vutla lokeshvutla at ti.com
Mon Feb 10 05:20:17 CET 2020



On 10/02/20 12:17 AM, Dario Binacchi wrote:
> 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

Nice..!!

> 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>;
> 			};
> 		};
> 	};

Are these bindings same as Linux kernel?

> 
> Signed-off-by: Dario Binacchi <dariobin at libero.it>
> Tested-by: Dario Binacchi <dariobin at libero.it>
> ---
> 
>  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 <oe5hpm at oevsv.at>
>   * B&R Industrial Automation GmbH - http://www.br-automation.com
> + * Copyright (C) 2020 Dario Binacchi <dariobin at libero.it>
>   *
>   * 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 <common.h>
> +#include <dm.h>
>  #include <asm/io.h>
>  #include <asm/arch/hardware.h>
>  #include <asm/arch/omap.h>
>  #include <asm/arch/clock.h>
>  #include <asm/arch/sys_proto.h>
> +#include <asm/utils.h>
>  #include <linux/err.h>
>  #include <lcd.h>
> +#include <video.h>
>  #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);

You are using an api specific to SoC. This driver will fail to build if
ARCH_OMAP2PLUS is not selected. Can you move this clock enabling sequence to
arch/arm/mach-omap2/?

Also can you create a Kconfig symbol for CONFIG_AM335X_LCD?

Thanks and regards,
Lokesh



More information about the U-Boot mailing list