[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