Hi Yannick

On 4/6/22 10:41, Yannick Fertre wrote:
> Register mapping & pixel formats depend on version of ltdc
> display controller.
> 
> Signed-off-by: Yannick Fertre <[email protected]>
> ---
> 
>  drivers/video/stm32/stm32_ltdc.c | 245 +++++++++++++++++++++++++++----
>  1 file changed, 216 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/video/stm32/stm32_ltdc.c 
> b/drivers/video/stm32/stm32_ltdc.c
> index e741e74739..60bfd2390d 100644
> --- a/drivers/video/stm32/stm32_ltdc.c
> +++ b/drivers/video/stm32/stm32_ltdc.c
> @@ -25,8 +25,114 @@ struct stm32_ltdc_priv {
>       void __iomem *regs;
>       enum video_log2_bpp l2bpp;
>       u32 bg_col_argb;
> +     const u32 *layer_regs;
> +     const u32 *pix_fmt_hw;
>       u32 crop_x, crop_y, crop_w, crop_h;
>       u32 alpha;
> +     u32 hw_version;
> +};
> +
> +/* Layer register offsets */
> +static const u32 layer_regs_a0[] = {
> +     0x80,   /* L1 configuration 0 */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x84,   /* L1 control register */
> +     0x88,   /* L1 window horizontal position configuration */
> +     0x8c,   /* L1 window vertical position configuration */
> +     0x90,   /* L1 color keying configuration */
> +     0x94,   /* L1 pixel format configuration */
> +     0x98,   /* L1 constant alpha configuration */
> +     0x9c,   /* L1 default color configuration */
> +     0xa0,   /* L1 blending factors configuration */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0xac,   /* L1 color frame buffer address */
> +     0xb0,   /* L1 color frame buffer length */
> +     0xb4,   /* L1 color frame buffer line number */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0xc4,   /* L1 CLUT write */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00    /* not available */
> +};
> +
> +static const u32 layer_regs_a1[] = {
> +     0x80,   /* L1 configuration 0 */
> +     0x84,   /* L1 configuration 1 */
> +     0x00,   /* L1 reload control */
> +     0x88,   /* L1 control register */
> +     0x8c,   /* L1 window horizontal position configuration */
> +     0x90,   /* L1 window vertical position configuration */
> +     0x94,   /* L1 color keying configuration */
> +     0x98,   /* L1 pixel format configuration */
> +     0x9c,   /* L1 constant alpha configuration */
> +     0xa0,   /* L1 default color configuration */
> +     0xa4,   /* L1 blending factors configuration */
> +     0xa8,   /* L1 burst length configuration */
> +     0x00,   /* not available */
> +     0xac,   /* L1 color frame buffer address */
> +     0xb0,   /* L1 color frame buffer length */
> +     0xb4,   /* L1 color frame buffer line number */
> +     0xb8,   /* L1 auxiliary frame buffer address 0 */
> +     0xbc,   /* L1 auxiliary frame buffer address 1 */
> +     0xc0,   /* L1 auxiliary frame buffer length */
> +     0xc4,   /* L1 auxiliary frame buffer line number */
> +     0xc8,   /* L1 CLUT write */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00,   /* not available */
> +     0x00    /* not available */
> +};
> +
> +static const u32 layer_regs_a2[] = {
> +     0x100,  /* L1 configuration 0 */
> +     0x104,  /* L1 configuration 1 */
> +     0x108,  /* L1 reload control */
> +     0x10c,  /* L1 control register */
> +     0x110,  /* L1 window horizontal position configuration */
> +     0x114,  /* L1 window vertical position configuration */
> +     0x118,  /* L1 color keying configuration */
> +     0x11c,  /* L1 pixel format configuration */
> +     0x120,  /* L1 constant alpha configuration */
> +     0x124,  /* L1 default color configuration */
> +     0x128,  /* L1 blending factors configuration */
> +     0x12c,  /* L1 burst length configuration */
> +     0x130,  /* L1 planar configuration */
> +     0x134,  /* L1 color frame buffer address */
> +     0x138,  /* L1 color frame buffer length */
> +     0x13c,  /* L1 color frame buffer line number */
> +     0x140,  /* L1 auxiliary frame buffer address 0 */
> +     0x144,  /* L1 auxiliary frame buffer address 1 */
> +     0x148,  /* L1 auxiliary frame buffer length */
> +     0x14c,  /* L1 auxiliary frame buffer line number */
> +     0x150,  /* L1 CLUT write */
> +     0x154,  /* not available */
> +     0x158,  /* not available */
> +     0x15c,  /* not available */
> +     0x160,  /* not available */
> +     0x164,  /* not available */
> +     0x168,  /* not available */
> +     0x16c,  /* L1 Conversion YCbCr RGB 0 */
> +     0x170,  /* L1 Conversion YCbCr RGB 1 */
> +     0x174,  /* L1 Flexible Pixel Format 0 */
> +     0x178   /* L1 Flexible Pixel Format 1 */
>  };
>  
>  /* LTDC main registers */
> @@ -49,26 +155,32 @@ struct stm32_ltdc_priv {
>  #define LTDC_CPSR    0x44    /* Current Position Status */
>  #define LTDC_CDSR    0x48    /* Current Display Status */
>  
> -/* LTDC layer 1 registers */
> -#define LTDC_L1LC1R  0x80    /* L1 Layer Configuration 1 */
> -#define LTDC_L1LC2R  0x84    /* L1 Layer Configuration 2 */
> -#define LTDC_L1CR    0x84    /* L1 Control */
> -#define LTDC_L1WHPCR 0x88    /* L1 Window Hor Position Config */
> -#define LTDC_L1WVPCR 0x8C    /* L1 Window Vert Position Config */
> -#define LTDC_L1CKCR  0x90    /* L1 Color Keying Configuration */
> -#define LTDC_L1PFCR  0x94    /* L1 Pixel Format Configuration */
> -#define LTDC_L1CACR  0x98    /* L1 Constant Alpha Config */
> -#define LTDC_L1DCCR  0x9C    /* L1 Default Color Configuration */
> -#define LTDC_L1BFCR  0xA0    /* L1 Blend Factors Configuration */
> -#define LTDC_L1FBBCR 0xA4    /* L1 FrameBuffer Bus Control */
> -#define LTDC_L1AFBCR 0xA8    /* L1 AuxFB Control */
> -#define LTDC_L1CFBAR 0xAC    /* L1 Color FrameBuffer Address */
> -#define LTDC_L1CFBLR 0xB0    /* L1 Color FrameBuffer Length */
> -#define LTDC_L1CFBLNR        0xB4    /* L1 Color FrameBuffer Line Nb */
> -#define LTDC_L1AFBAR 0xB8    /* L1 AuxFB Address */
> -#define LTDC_L1AFBLR 0xBC    /* L1 AuxFB Length */
> -#define LTDC_L1AFBLNR        0xC0    /* L1 AuxFB Line Number */
> -#define LTDC_L1CLUTWR        0xC4    /* L1 CLUT Write */
> +/* Layer register offsets */
> +#define LTDC_L1C0R   (priv->layer_regs[0])   /* L1 configuration 0 */
> +#define LTDC_L1C1R   (priv->layer_regs[1])   /* L1 configuration 1 */
> +#define LTDC_L1RCR   (priv->layer_regs[2])   /* L1 reload control */
> +#define LTDC_L1CR    (priv->layer_regs[3])   /* L1 control register */
> +#define LTDC_L1WHPCR (priv->layer_regs[4])   /* L1 window horizontal 
> position configuration */
> +#define LTDC_L1WVPCR (priv->layer_regs[5])   /* L1 window vertical position 
> configuration */
> +#define LTDC_L1CKCR  (priv->layer_regs[6])   /* L1 color keying 
> configuration */
> +#define LTDC_L1PFCR  (priv->layer_regs[7])   /* L1 pixel format 
> configuration */
> +#define LTDC_L1CACR  (priv->layer_regs[8])   /* L1 constant alpha 
> configuration */
> +#define LTDC_L1DCCR  (priv->layer_regs[9])   /* L1 default color 
> configuration */
> +#define LTDC_L1BFCR  (priv->layer_regs[10])  /* L1 blending factors 
> configuration */
> +#define LTDC_L1BLCR  (priv->layer_regs[11])  /* L1 burst length 
> configuration */
> +#define LTDC_L1PCR   (priv->layer_regs[12])  /* L1 planar configuration */
> +#define LTDC_L1CFBAR (priv->layer_regs[13])  /* L1 color frame buffer 
> address */
> +#define LTDC_L1CFBLR (priv->layer_regs[14])  /* L1 color frame buffer length 
> */
> +#define LTDC_L1CFBLNR        (priv->layer_regs[15])  /* L1 color frame 
> buffer line number */
> +#define LTDC_L1AFBA0R        (priv->layer_regs[16])  /* L1 auxiliary frame 
> buffer address 0 */
> +#define LTDC_L1AFBA1R        (priv->layer_regs[17])  /* L1 auxiliary frame 
> buffer address 1 */
> +#define LTDC_L1AFBLR (priv->layer_regs[18])  /* L1 auxiliary frame buffer 
> length */
> +#define LTDC_L1AFBLNR        (priv->layer_regs[19])  /* L1 auxiliary frame 
> buffer line number */
> +#define LTDC_L1CLUTWR        (priv->layer_regs[20])  /* L1 CLUT write */
> +#define LTDC_L1CYR0R (priv->layer_regs[27])  /* L1 Conversion YCbCr RGB 0 */
> +#define LTDC_L1CYR1R (priv->layer_regs[28])  /* L1 Conversion YCbCr RGB 1 */
> +#define LTDC_L1FPF0R (priv->layer_regs[29])  /* L1 Flexible Pixel Format 0 */
> +#define LTDC_L1FPF1R (priv->layer_regs[30])  /* L1 Flexible Pixel Format 1 */
>  
>  /* Bit definitions */
>  #define SSCR_VSH     GENMASK(10, 0)  /* Vertical Synchronization Height */
> @@ -144,15 +256,60 @@ struct stm32_ltdc_priv {
>  #define BF2_1PAXCA   0x007           /* 1 - (Pixel Alpha x Constant Alpha) */
>  #define BF2_1CA              0x005           /* 1 - Constant Alpha */
>  
> +#define NB_PF                8               /* Max nb of HW pixel format */
> +
> +#define HWVER_10200 0x010200
> +#define HWVER_10300 0x010300
> +#define HWVER_20101 0x020101
> +#define HWVER_40100 0x040100
> +
>  enum stm32_ltdc_pix_fmt {
> -     PF_ARGB8888 = 0,
> -     PF_RGB888,
> -     PF_RGB565,
> -     PF_ARGB1555,
> -     PF_ARGB4444,
> -     PF_L8,
> -     PF_AL44,
> -     PF_AL88
> +     PF_ARGB8888 = 0,        /* ARGB [32 bits] */
> +     PF_ABGR8888,            /* ABGR [32 bits] */
> +     PF_BGRA8888,            /* BGRA [32 bits] */
> +     PF_RGBA8888,            /* RGBA [32 bits] */
> +     PF_RGB888,              /* RGB [24 bits] */
> +     PF_BGR565,              /* RGB [16 bits] */
> +     PF_RGB565,              /* RGB [16 bits] */
> +     PF_ARGB1555,            /* ARGB A:1 bit RGB:15 bits [16 bits] */
> +     PF_ARGB4444,            /* ARGB A:4 bits R/G/B: 4 bits each [16 bits] */
> +     PF_AL44,                /* Alpha:4 bits + indexed 4 bits [8 bits] */
> +     PF_AL88,                /* Alpha:8 bits + indexed 8 bits [16 bits] */
> +     PF_L8,                  /* Indexed 8 bits [8 bits] */
> +     PF_NONE
> +};
> +
> +static const enum stm32_ltdc_pix_fmt pix_fmt_a0[NB_PF] = {
> +     PF_ARGB8888,            /* 0x00 */
> +     PF_RGB888,              /* 0x01 */
> +     PF_RGB565,              /* 0x02 */
> +     PF_ARGB1555,            /* 0x03 */
> +     PF_ARGB4444,            /* 0x04 */
> +     PF_L8,                  /* 0x05 */
> +     PF_AL44,                /* 0x06 */
> +     PF_AL88                 /* 0x07 */
> +};
> +
> +static const enum stm32_ltdc_pix_fmt pix_fmt_a1[NB_PF] = {
> +     PF_ARGB8888,            /* 0x00 */
> +     PF_RGB888,              /* 0x01 */
> +     PF_RGB565,              /* 0x02 */
> +     PF_RGBA8888,            /* 0x03 */
> +     PF_AL44,                /* 0x04 */
> +     PF_L8,                  /* 0x05 */
> +     PF_ARGB1555,            /* 0x06 */
> +     PF_ARGB4444             /* 0x07 */
> +};
> +
> +static const enum stm32_ltdc_pix_fmt pix_fmt_a2[NB_PF] = {
> +     PF_ARGB8888,            /* 0x00 */
> +     PF_ABGR8888,            /* 0x01 */
> +     PF_RGBA8888,            /* 0x02 */
> +     PF_BGRA8888,            /* 0x03 */
> +     PF_RGB565,              /* 0x04 */
> +     PF_BGR565,              /* 0x05 */
> +     PF_RGB888,              /* 0x06 */
> +     PF_NONE                 /* 0x07 (flexible pixel format) */
>  };
>  
>  /* TODO add more color format support */
> @@ -306,7 +463,16 @@ static void stm32_ltdc_set_layer1(struct stm32_ltdc_priv 
> *priv, ulong fb_addr)
>  
>       /* Pixel format */
>       format = stm32_ltdc_get_pixel_format(priv->l2bpp);
> -     clrsetbits_le32(regs + LTDC_L1PFCR, LXPFCR_PF, format);
> +     for (val = 0; val < NB_PF; val++)
> +             if (priv->pix_fmt_hw[val] == format)
> +                     break;
> +
> +     if (val >= NB_PF) {
> +             log_err("invalid pixel format\n");
> +             return;
> +     }
> +
> +     clrsetbits_le32(regs + LTDC_L1PFCR, LXPFCR_PF, val);
>  
>       /* Constant alpha value */
>       clrsetbits_le32(regs + LTDC_L1CACR, LXCACR_CONSTA, priv->alpha);
> @@ -359,6 +525,27 @@ static int stm32_ltdc_probe(struct udevice *dev)
>               return ret;
>       }
>  
> +     priv->hw_version = readl(priv->regs + LTDC_IDR);
> +     debug("%s: LTDC hardware 0x%x\n", __func__, priv->hw_version);
> +
> +     switch (priv->hw_version) {
> +     case HWVER_10200:
> +     case HWVER_10300:
> +             priv->layer_regs = layer_regs_a0;
> +             priv->pix_fmt_hw = pix_fmt_a0;
> +             break;
> +     case HWVER_20101:
> +             priv->layer_regs = layer_regs_a1;
> +             priv->pix_fmt_hw = pix_fmt_a1;
> +             break;
> +     case HWVER_40100:
> +             priv->layer_regs = layer_regs_a2;
> +             priv->pix_fmt_hw = pix_fmt_a2;
> +             break;
> +     default:
> +             return -ENODEV;
> +     }
> +
>       ret = uclass_first_device_err(UCLASS_PANEL, &panel);
>       if (ret) {
>               if (ret != -ENODEV)

Reviewed-by: Patrice Chotard <[email protected]>

Thanks
Patrice

Reply via email to