From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lokesh Vutla Date: Mon, 10 Feb 2020 09:50:17 +0530 Subject: [PATCH 09/11] video: omap: add support for DM/DTS In-Reply-To: <20200209184745.20473-10-dariobin@libero.it> References: <20200209184745.20473-1-dariobin@libero.it> <20200209184745.20473-10-dariobin@libero.it> Message-ID: <10388464-133e-2c22-96fd-3e10ec293516@ti.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 > 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); 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