Re: [PATCH v8 3/3] drm: rcar-du: rzg2l_mipi_dsi: Enhance device lanes check

2022-10-15 Thread Laurent Pinchart
Hi Biju,

Thank you for the patch.

On Tue, Sep 20, 2022 at 11:55:01AM +0100, Biju Das wrote:
> Enhance device lanes check by reading TXSETR register at probe(),
> and enforced in rzg2l_mipi_dsi_host_attach().
> 
> As per HW manual, we can read TXSETR register only after
> DPHY initialization.
> 
> Suggested-by: Laurent Pinchart 
> Signed-off-by: Biju Das 

Reviewed-by: Laurent Pinchart 

> ---
> v8:
>  * New patch.
> ---
>  drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c | 122 ---
>  1 file changed, 88 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c 
> b/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
> index 8579208db218..aa95b85a2964 100644
> --- a/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
> +++ b/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
> @@ -171,6 +171,11 @@ static void rzg2l_mipi_dsi_link_write(struct 
> rzg2l_mipi_dsi *dsi, u32 reg, u32 d
>   iowrite32(data, dsi->mmio + LINK_REG_OFFSET + reg);
>  }
>  
> +static u32 rzg2l_mipi_dsi_phy_read(struct rzg2l_mipi_dsi *dsi, u32 reg)
> +{
> + return ioread32(dsi->mmio + reg);
> +}
> +
>  static u32 rzg2l_mipi_dsi_link_read(struct rzg2l_mipi_dsi *dsi, u32 reg)
>  {
>   return ioread32(dsi->mmio + LINK_REG_OFFSET + reg);
> @@ -180,19 +185,11 @@ static u32 rzg2l_mipi_dsi_link_read(struct 
> rzg2l_mipi_dsi *dsi, u32 reg)
>   * Hardware Setup
>   */
>  
> -static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi,
> -   const struct drm_display_mode *mode)
> +static int rzg2l_mipi_dsi_dphy_init(struct rzg2l_mipi_dsi *dsi,
> + unsigned long hsfreq)
>  {
>   const struct rzg2l_mipi_dsi_timings *dphy_timings;
> - unsigned long hsfreq;
> - unsigned int i, bpp;
> - u32 txsetr;
> - u32 clstptsetr;
> - u32 lptrnstsetr;
> - u32 clkkpt;
> - u32 clkbfht;
> - u32 clkstpt;
> - u32 golpbkt;
> + unsigned int i;
>   u32 dphyctrl0;
>   u32 dphytim0;
>   u32 dphytim1;
> @@ -200,19 +197,6 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi 
> *dsi,
>   u32 dphytim3;
>   int ret;
>  
> - /*
> -  * Relationship between hsclk and vclk must follow
> -  * vclk * bpp = hsclk * 8 * lanes
> -  * where vclk: video clock (Hz)
> -  *   bpp: video pixel bit depth
> -  *   hsclk: DSI HS Byte clock frequency (Hz)
> -  *   lanes: number of data lanes
> -  *
> -  * hsclk(bit) = hsclk(byte) * 8
> -  */
> - bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> - hsfreq = (mode->clock * bpp * 8) / (8 * dsi->lanes);
> -
>   /* All DSI global operation timings are set with recommended setting */
>   for (i = 0; i < ARRAY_SIZE(rzg2l_mipi_dsi_global_timings); ++i) {
>   dphy_timings = _mipi_dsi_global_timings[i];
> @@ -220,12 +204,6 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi 
> *dsi,
>   break;
>   }
>  
> - ret = pm_runtime_resume_and_get(dsi->dev);
> - if (ret < 0)
> - return ret;
> -
> - clk_set_rate(dsi->vclk, mode->clock * 1000);
> -
>   /* Initializing DPHY before accessing LINK */
>   dphyctrl0 = DSIDPHYCTRL0_CAL_EN_HSRX_OFS | DSIDPHYCTRL0_CMN_MASTER_EN |
>   DSIDPHYCTRL0_RE_VDD_DETVCCQLV18 | DSIDPHYCTRL0_EN_BGR;
> @@ -259,10 +237,62 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi 
> *dsi,
>  
>   ret = reset_control_deassert(dsi->rstc);
>   if (ret < 0)
> - goto err_pm_put;
> + return ret;
>  
>   udelay(1);
>  
> + return 0;
> +}
> +
> +static void rzg2l_mipi_dsi_dphy_exit(struct rzg2l_mipi_dsi *dsi)
> +{
> + u32 dphyctrl0;
> +
> + dphyctrl0 = rzg2l_mipi_dsi_phy_read(dsi, DSIDPHYCTRL0);
> +
> + dphyctrl0 &= ~(DSIDPHYCTRL0_EN_LDO1200 | DSIDPHYCTRL0_EN_BGR);
> + rzg2l_mipi_dsi_phy_write(dsi, DSIDPHYCTRL0, dphyctrl0);
> +
> + reset_control_assert(dsi->rstc);
> +}
> +
> +static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi,
> +   const struct drm_display_mode *mode)
> +{
> + unsigned long hsfreq;
> + unsigned int bpp;
> + u32 txsetr;
> + u32 clstptsetr;
> + u32 lptrnstsetr;
> + u32 clkkpt;
> + u32 clkbfht;
> + u32 clkstpt;
> + u32 golpbkt;
> + int ret;
> +
> + /*
> +  * Relationship between hsclk and vclk must follow
> +  * vclk * bpp = hsclk * 8 * lanes
> +  * where vclk: video clock (Hz)
> +  *   bpp: video pixel bit depth
> +  *   hsclk: DSI HS Byte clock frequency (Hz)
> +  *   lanes: number of data lanes
> +  *
> +  * hsclk(bit) = hsclk(byte) * 8
> +  */
> + bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> + hsfreq = (mode->clock * bpp * 8) / (8 * dsi->lanes);
> +
> + ret = pm_runtime_resume_and_get(dsi->dev);
> + if (ret < 0)
> + return ret;
> +
> + clk_set_rate(dsi->vclk, mode->clock * 1000);
> +
> + ret = 

[PATCH v8 3/3] drm: rcar-du: rzg2l_mipi_dsi: Enhance device lanes check

2022-09-20 Thread Biju Das
Enhance device lanes check by reading TXSETR register at probe(),
and enforced in rzg2l_mipi_dsi_host_attach().

As per HW manual, we can read TXSETR register only after
DPHY initialization.

Suggested-by: Laurent Pinchart 
Signed-off-by: Biju Das 
---
v8:
 * New patch.
---
 drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c | 122 ---
 1 file changed, 88 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c 
b/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
index 8579208db218..aa95b85a2964 100644
--- a/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
+++ b/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
@@ -171,6 +171,11 @@ static void rzg2l_mipi_dsi_link_write(struct 
rzg2l_mipi_dsi *dsi, u32 reg, u32 d
iowrite32(data, dsi->mmio + LINK_REG_OFFSET + reg);
 }
 
+static u32 rzg2l_mipi_dsi_phy_read(struct rzg2l_mipi_dsi *dsi, u32 reg)
+{
+   return ioread32(dsi->mmio + reg);
+}
+
 static u32 rzg2l_mipi_dsi_link_read(struct rzg2l_mipi_dsi *dsi, u32 reg)
 {
return ioread32(dsi->mmio + LINK_REG_OFFSET + reg);
@@ -180,19 +185,11 @@ static u32 rzg2l_mipi_dsi_link_read(struct rzg2l_mipi_dsi 
*dsi, u32 reg)
  * Hardware Setup
  */
 
-static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi,
- const struct drm_display_mode *mode)
+static int rzg2l_mipi_dsi_dphy_init(struct rzg2l_mipi_dsi *dsi,
+   unsigned long hsfreq)
 {
const struct rzg2l_mipi_dsi_timings *dphy_timings;
-   unsigned long hsfreq;
-   unsigned int i, bpp;
-   u32 txsetr;
-   u32 clstptsetr;
-   u32 lptrnstsetr;
-   u32 clkkpt;
-   u32 clkbfht;
-   u32 clkstpt;
-   u32 golpbkt;
+   unsigned int i;
u32 dphyctrl0;
u32 dphytim0;
u32 dphytim1;
@@ -200,19 +197,6 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi 
*dsi,
u32 dphytim3;
int ret;
 
-   /*
-* Relationship between hsclk and vclk must follow
-* vclk * bpp = hsclk * 8 * lanes
-* where vclk: video clock (Hz)
-*   bpp: video pixel bit depth
-*   hsclk: DSI HS Byte clock frequency (Hz)
-*   lanes: number of data lanes
-*
-* hsclk(bit) = hsclk(byte) * 8
-*/
-   bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
-   hsfreq = (mode->clock * bpp * 8) / (8 * dsi->lanes);
-
/* All DSI global operation timings are set with recommended setting */
for (i = 0; i < ARRAY_SIZE(rzg2l_mipi_dsi_global_timings); ++i) {
dphy_timings = _mipi_dsi_global_timings[i];
@@ -220,12 +204,6 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi 
*dsi,
break;
}
 
-   ret = pm_runtime_resume_and_get(dsi->dev);
-   if (ret < 0)
-   return ret;
-
-   clk_set_rate(dsi->vclk, mode->clock * 1000);
-
/* Initializing DPHY before accessing LINK */
dphyctrl0 = DSIDPHYCTRL0_CAL_EN_HSRX_OFS | DSIDPHYCTRL0_CMN_MASTER_EN |
DSIDPHYCTRL0_RE_VDD_DETVCCQLV18 | DSIDPHYCTRL0_EN_BGR;
@@ -259,10 +237,62 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi 
*dsi,
 
ret = reset_control_deassert(dsi->rstc);
if (ret < 0)
-   goto err_pm_put;
+   return ret;
 
udelay(1);
 
+   return 0;
+}
+
+static void rzg2l_mipi_dsi_dphy_exit(struct rzg2l_mipi_dsi *dsi)
+{
+   u32 dphyctrl0;
+
+   dphyctrl0 = rzg2l_mipi_dsi_phy_read(dsi, DSIDPHYCTRL0);
+
+   dphyctrl0 &= ~(DSIDPHYCTRL0_EN_LDO1200 | DSIDPHYCTRL0_EN_BGR);
+   rzg2l_mipi_dsi_phy_write(dsi, DSIDPHYCTRL0, dphyctrl0);
+
+   reset_control_assert(dsi->rstc);
+}
+
+static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi,
+ const struct drm_display_mode *mode)
+{
+   unsigned long hsfreq;
+   unsigned int bpp;
+   u32 txsetr;
+   u32 clstptsetr;
+   u32 lptrnstsetr;
+   u32 clkkpt;
+   u32 clkbfht;
+   u32 clkstpt;
+   u32 golpbkt;
+   int ret;
+
+   /*
+* Relationship between hsclk and vclk must follow
+* vclk * bpp = hsclk * 8 * lanes
+* where vclk: video clock (Hz)
+*   bpp: video pixel bit depth
+*   hsclk: DSI HS Byte clock frequency (Hz)
+*   lanes: number of data lanes
+*
+* hsclk(bit) = hsclk(byte) * 8
+*/
+   bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
+   hsfreq = (mode->clock * bpp * 8) / (8 * dsi->lanes);
+
+   ret = pm_runtime_resume_and_get(dsi->dev);
+   if (ret < 0)
+   return ret;
+
+   clk_set_rate(dsi->vclk, mode->clock * 1000);
+
+   ret = rzg2l_mipi_dsi_dphy_init(dsi, hsfreq);
+   if (ret < 0)
+   goto err_phy;
+
/* Enable Data lanes and Clock lanes */
txsetr = TXSETR_DLEN | TXSETR_NUMLANEUSE(dsi->lanes - 1) | TXSETR_CLEN;
rzg2l_mipi_dsi_link_write(dsi,