[U-Boot] [PATCH v3 2/4] rockchip: video: Add mipi display support for rk3288

Simon Glass sjg at chromium.org
Wed May 3 02:37:01 UTC 2017


Hi Eric,

On 2 May 2017 at 03:05, Eric Gao <eric.gao at rock-chips.com> wrote:
> Because rk3288 and rk3399 use the same mipi dsi controller and phy with
> only a few difference in grf register. So we share the mipi driver, and
> handle the difference.
>
> Signed-off-by: Eric Gao <eric.gao at rock-chips.com>
> Reviewed-by: Simon Glass <sjg at chromium.org>
>
> ---
>
> Changes in v3:
> -Add Reviewer.
>
> Changes in v2:
> -Modify some variate's type for compatibility between arm64 and arm32
> machine.
>
> Changes in v1:
> -Make a different configuration for rk3288.
>
>  drivers/video/rockchip/rk_mipi.c | 68 ++++++++++++++++++++++++++++++++--------
>  1 file changed, 55 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/video/rockchip/rk_mipi.c b/drivers/video/rockchip/rk_mipi.c
> index ab131cd..be30f90 100644
> --- a/drivers/video/rockchip/rk_mipi.c
> +++ b/drivers/video/rockchip/rk_mipi.c
> @@ -20,9 +20,13 @@
>  #include <linux/kernel.h>
>  #include <asm/arch/clock.h>
>  #include <asm/arch/cru_rk3399.h>
> -#include <asm/arch/grf_rk3399.h>
>  #include <asm/arch/rockchip_mipi_dsi.h>
> -#include <dt-bindings/clock/rk3288-cru.h>
> +
> +#ifdef CONFIG_ROCKCHIP_RK3399
> +       #include <asm/arch/grf_rk3399.h>
> +#elif CONFIG_ROCKCHIP_RK3288
> +       #include <asm/arch/grf_rk3288.h>
> +#endif

We need to avoid these SoC-specific #ifdefs in drivers.

Please see below.

>
>  DECLARE_GLOBAL_DATA_PTR;
>
> @@ -41,7 +45,11 @@ DECLARE_GLOBAL_DATA_PTR;
>   */
>  struct rk_mipi_priv {
>         void __iomem *regs;
> +       #ifdef CONFIG_ROCKCHIP_RK3399
>         struct rk3399_grf_regs *grf;
> +       #elif CONFIG_ROCKCHIP_RK3288
> +       struct rk3288_grf *grf;
> +       #endif
>         struct udevice *panel;
>         struct mipi_dsi *dsi;
>         u32 ref_clk;
> @@ -76,13 +84,13 @@ static int rk_mipi_read_timing(struct udevice *dev,
>   *        use define in rk_mipi.h directly for this parameter
>   *  @val: value that will be write to specified bits of register
>   */
> -static void rk_mipi_dsi_write(u32 regs, u32 reg, u32 val)
> +static void rk_mipi_dsi_write(void __iomem *regs, u32 reg, u32 val)
>  {
>         u32 dat;
>         u32 mask;
>         u32 offset = (reg >> OFFSET_SHIFT) & 0xff;
>         u32 bits = (reg >> BITS_SHIFT) & 0xff;
> -       u64 addr = (reg >> ADDR_SHIFT) + regs;
> +       void __iomem *addr = (reg >> ADDR_SHIFT) + regs;
>
>         /* Mask for specifiled bits,the corresponding bits will be clear */
>         mask = ~((0xffffffff << offset) & (0xffffffff >> (32 - offset - bits)));
> @@ -108,7 +116,7 @@ static int rk_mipi_dsi_enable(struct udevice *dev,
>         int node, timing_node;
>         int val;
>         struct rk_mipi_priv *priv = dev_get_priv(dev);
> -       u64 regs = (u64)priv->regs;
> +       void __iomem *regs = priv->regs;
>         struct display_plat *disp_uc_plat = dev_get_uclass_platdata(dev);
>         u32 txbyte_clk = priv->txbyte_clk;
>         u32 txesc_clk = priv->txesc_clk;
> @@ -118,18 +126,33 @@ static int rk_mipi_dsi_enable(struct udevice *dev,
>         /* Select the video source */
>         switch (disp_uc_plat->source_id) {
>         case VOP_B:
> +               #ifdef CONFIG_ROCKCHIP_RK3399
>                 rk_clrsetreg(&priv->grf->soc_con20, GRF_DSI0_VOP_SEL_MASK,

We need some sort of API to call to handle this.

We really need a grf driver with a call like setup_vop() with the
parameters you need to tell it what to do. Then you can implement that
function in two grf drivers, one for each SoC.

Since grf is already a syscon, I think we should add operations to the
syscon interface.

In fact perhaps just one operation added to syscon_ops would be
enough? We could use ioctl, a bit like the generic file operation in
unix user space.

int (*ioctl)(struct udevice *dev, ulong request, void *buf, int size);

Then you can define the operations that are permitted, like
IOCTL_SETUP_VOP in your rockchip.h header file, or similar.


> -                            GRF_DSI0_VOP_SEL_B << GRF_DSI0_VOP_SEL_SHIFT);
> -                break;
> +                            GRF_DSI0_VOP_SEL_B
> +                            << GRF_DSI0_VOP_SEL_SHIFT);
> +               #elif CONFIG_ROCKCHIP_RK3288
> +               rk_clrsetreg(&priv->grf->soc_con6, RK3288_DSI0_LCDC_SEL_MASK,
> +                            RK3288_DSI0_LCDC_SEL_BIG
> +                            << RK3288_DSI0_LCDC_SEL_SHIFT);
> +               #endif
> +               break;
>         case VOP_L:
> +               #ifdef CONFIG_ROCKCHIP_RK3399
>                 rk_clrsetreg(&priv->grf->soc_con20, GRF_DSI0_VOP_SEL_MASK,
> -                            GRF_DSI0_VOP_SEL_L << GRF_DSI0_VOP_SEL_SHIFT);
> -                break;
> +                            GRF_DSI0_VOP_SEL_L
> +                            << GRF_DSI0_VOP_SEL_SHIFT);
> +               #elif CONFIG_ROCKCHIP_RK3288
> +               rk_clrsetreg(&priv->grf->soc_con6, RK3288_DSI0_LCDC_SEL_MASK,
> +                            RK3288_DSI0_LCDC_SEL_LIT
> +                            << RK3288_DSI0_LCDC_SEL_SHIFT);
> +               #endif
> +               break;
>         default:
>                  debug("%s: Invalid VOP id\n", __func__);
>                  return -EINVAL;
>         }
>
> +       #ifdef CONFIG_ROCKCHIP_RK3399
>         /* Set Controller as TX mode */
>         val = GRF_DPHY_TX0_RXMODE_DIS << GRF_DPHY_TX0_RXMODE_SHIFT;
>         rk_clrsetreg(&priv->grf->soc_con22, GRF_DPHY_TX0_RXMODE_MASK, val);
> @@ -142,6 +165,24 @@ static int rk_mipi_dsi_enable(struct udevice *dev,
>         val |= GRF_DPHY_TX0_TURNREQUEST_DIS << GRF_DPHY_TX0_TURNREQUEST_SHIFT;
>         rk_clrsetreg(&priv->grf->soc_con22, GRF_DPHY_TX0_TURNREQUEST_MASK, val);
>
> +       #elif CONFIG_ROCKCHIP_RK3288
> +       /* Set Controller as TX mode */
> +       val = RK3288_DPHY_TX0_RXMODE_DIS << RK3288_DPHY_TX0_RXMODE_SHIFT;
> +       rk_clrsetreg(&priv->grf->soc_con8, RK3288_DPHY_TX0_RXMODE_MASK, val);
> +
> +       /* Exit tx stop mode */
> +       val |= RK3288_DPHY_TX0_TXSTOPMODE_EN
> +              << RK3288_DPHY_TX0_TXSTOPMODE_SHIFT;
> +       rk_clrsetreg(&priv->grf->soc_con8,
> +                    RK3288_DPHY_TX0_TXSTOPMODE_MASK, val);
> +
> +       /* Disable turnequest */
> +       val |= RK3288_DPHY_TX0_TURNREQUEST_EN
> +              << RK3288_DPHY_TX0_TURNREQUEST_SHIFT;
> +       rk_clrsetreg(&priv->grf->soc_con8,
> +                    RK3288_DPHY_TX0_TURNREQUEST_MASK, val);
> +       #endif
> +
>         /* Set Display timing parameter */
>         rk_mipi_dsi_write(regs, VID_HSA_TIME, timing->hsync_len.typ);
>         rk_mipi_dsi_write(regs, VID_HBP_TIME, timing->hback_porch.typ);
> @@ -224,7 +265,7 @@ static int rk_mipi_dsi_enable(struct udevice *dev,
>  }
>
>  /* rk mipi dphy write function. It is used to write test data to dphy */
> -static void rk_mipi_phy_write(u32 regs, unsigned char test_code,
> +static void rk_mipi_phy_write(void __iomem *regs, unsigned char test_code,
>                               unsigned char *test_data, unsigned char size)
>  {
>         int i = 0;
> @@ -253,7 +294,7 @@ static int rk_mipi_phy_enable(struct udevice *dev)
>  {
>         int i;
>         struct rk_mipi_priv *priv = dev_get_priv(dev);
> -       u64 regs = (u64)priv->regs;
> +       void __iomem *regs = priv->regs;
>         u64 fbdiv;
>         u64 prediv = 1;
>         u32 max_fbdiv = 512;
> @@ -437,13 +478,13 @@ static int rk_mipi_ofdata_to_platdata(struct udevice *dev)
>
>         priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
>         if (priv->grf <= 0) {
> -               debug("%s: Get syscon grf failed (ret=%d)\n",
> +               debug("%s: Get syscon grf failed (ret=%p)\n",
>                       __func__, priv->grf);
>                 return  -ENXIO;
>         }
>         priv->regs = (void *)dev_get_addr(dev);
>         if (priv->regs <= 0) {
> -               debug("%s: Get MIPI dsi address failed (ret=%d)\n", __func__,
> +               debug("%s: Get MIPI dsi address failed (ret=%p)\n", __func__,
>                       priv->regs);
>                 return  -ENXIO;
>         }
> @@ -477,6 +518,7 @@ static const struct dm_display_ops rk_mipi_dsi_ops = {
>
>  static const struct udevice_id rk_mipi_dsi_ids[] = {
>         { .compatible = "rockchip,rk3399_mipi_dsi" },
> +       { .compatible = "rockchip,rk3288_mipi_dsi" },
>         { }
>  };
>
> --
> 1.9.1
>
>

Regards,
Simon


More information about the U-Boot mailing list