Hi Eric, On 2 May 2017 at 03:05, Eric Gao <eric....@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....@rock-chips.com> > Reviewed-by: Simon Glass <s...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot