Re: [EXT] Re: [PATCH v2 12/15] drm/mxsfb: Improve the axi clock usage

2019-08-14 Thread Robert Chiras
Hi Stefan,

On Mi, 2019-08-14 at 13:06 +0200, Stefan Agner wrote:
> On 2019-08-14 12:48, Robert Chiras wrote:
> > 
> > Currently, the enable of the axi clock return status is ignored,
> > causing
> > issues when the enable fails then we try to disable it. Therefore,
> > it is
> > better to check the return status and disable it only when enable
> > succeeded.
> Is this actually the case in real world sometimes? Why is it failing?
When I noticed that fail, we had some restrictions in SCU firmware, so
that the clock cannot be enabled if the power domain was down. Still,
at that time I noticed it is redundant to have functions that checks if
a clock is NULL or not, since the clk_* functions are already doing
this.
> 
> I guess if we do this in one place, we should do it in all places
> (e.g.
> also in mxsfb_crtc_enable, mxsfb_plane_atomic_update..)
I add specific checks only in the vblank functions, because those
functions can be called before calling the pipe enable/disable
functions which enables the spefic power domain and, at this point, the
clock enable/disable calls should not fail.
> 
> --
> Stefan
> 
> > 
> > Also, remove the helper functions around clk_axi, since we can
> > directly
> > use the clk API function for enable/disable the clock. Those
> > functions
> > are already checking for NULL clk and returning 0 if that's the
> > case.
> 
> > 
> > 
> > Signed-off-by: Robert Chiras 
> > Acked-by: Leonard Crestez 
> > ---
> >  drivers/gpu/drm/mxsfb/mxsfb_crtc.c |  8 
> >  drivers/gpu/drm/mxsfb/mxsfb_drv.c  | 32 +-
> > --
> >  drivers/gpu/drm/mxsfb/mxsfb_drv.h  |  3 ---
> >  3 files changed, 17 insertions(+), 26 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> > b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> > index a4ba368..e727f5e 100644
> > --- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> > +++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> > @@ -408,7 +408,7 @@ void mxsfb_crtc_enable(struct mxsfb_drm_private
> > *mxsfb)
> >  {
> >   dma_addr_t paddr;
> > 
> > - mxsfb_enable_axi_clk(mxsfb);
> > + clk_prepare_enable(mxsfb->clk_axi);
> >   writel(0, mxsfb->base + LCDC_CTRL);
> >   mxsfb_crtc_mode_set_nofb(mxsfb);
> > 
> > @@ -425,7 +425,7 @@ void mxsfb_crtc_enable(struct mxsfb_drm_private
> > *mxsfb)
> >  void mxsfb_crtc_disable(struct mxsfb_drm_private *mxsfb)
> >  {
> >   mxsfb_disable_controller(mxsfb);
> > - mxsfb_disable_axi_clk(mxsfb);
> > + clk_disable_unprepare(mxsfb->clk_axi);
> >  }
> > 
> >  void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
> > @@ -451,8 +451,8 @@ void mxsfb_plane_atomic_update(struct
> > mxsfb_drm_private *mxsfb,
> > 
> >   paddr = mxsfb_get_fb_paddr(mxsfb);
> >   if (paddr) {
> > - mxsfb_enable_axi_clk(mxsfb);
> > + clk_prepare_enable(mxsfb->clk_axi);
> >   writel(paddr, mxsfb->base + mxsfb->devdata-
> > >next_buf);
> > - mxsfb_disable_axi_clk(mxsfb);
> > + clk_disable_unprepare(mxsfb->clk_axi);
> >   }
> >  }
> > diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> > b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> > index 6dae2bd..694b287 100644
> > --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> > +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> > @@ -97,18 +97,6 @@ drm_pipe_to_mxsfb_drm_private(struct
> > drm_simple_display_pipe *pipe)
> >   return container_of(pipe, struct mxsfb_drm_private, pipe);
> >  }
> > 
> > -void mxsfb_enable_axi_clk(struct mxsfb_drm_private *mxsfb)
> > -{
> > - if (mxsfb->clk_axi)
> > - clk_prepare_enable(mxsfb->clk_axi);
> > -}
> > -
> > -void mxsfb_disable_axi_clk(struct mxsfb_drm_private *mxsfb)
> > -{
> > - if (mxsfb->clk_axi)
> > - clk_disable_unprepare(mxsfb->clk_axi);
> > -}
> > -
> >  /**
> >   * mxsfb_atomic_helper_check - validate state object
> >   * @dev: DRM device
> > @@ -229,25 +217,31 @@ static void mxsfb_pipe_update(struct
> > drm_simple_display_pipe *pipe,
> >  static int mxsfb_pipe_enable_vblank(struct drm_simple_display_pipe
> > *pipe)
> >  {
> >   struct mxsfb_drm_private *mxsfb =
> > drm_pipe_to_mxsfb_drm_private(pipe);
> > + int ret = 0;
> > +
> > + ret = clk_prepare_enable(mxsfb->clk_axi);
> > + if (ret)
> > + return ret;
> > 
> >   /* Clear and enable VBLANK IRQ */
> > - mxsfb_enable_axi_clk(mxsfb);
> >   writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 +
> > REG_CLR);
> >   writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1
> > + REG_SET);
> > - mxsfb_disable_axi_clk(mxsfb);
> > + clk_disable_unprepare(mxsfb->clk_axi);
> > 
> > - return 0;
> > + return ret;
> >  }
> > 
> >  static void mxsfb_pipe_disable_vblank(struct
> > drm_simple_display_pipe *pipe)
> >  {
> >   struct mxsfb_drm_private *mxsfb =
> > drm_pipe_to_mxsfb_drm_private(pipe);
> > 
> > + if (clk_prepare_enable(mxsfb->clk_axi))
> > + return;
> > +
> >   /* Disable and clear VBLANK IRQ */
> > -  

Re: [PATCH v2 12/15] drm/mxsfb: Improve the axi clock usage

2019-08-14 Thread Stefan Agner
On 2019-08-14 12:48, Robert Chiras wrote:
> Currently, the enable of the axi clock return status is ignored, causing
> issues when the enable fails then we try to disable it. Therefore, it is
> better to check the return status and disable it only when enable
> succeeded.

Is this actually the case in real world sometimes? Why is it failing?

I guess if we do this in one place, we should do it in all places (e.g.
also in mxsfb_crtc_enable, mxsfb_plane_atomic_update..)

--
Stefan

> Also, remove the helper functions around clk_axi, since we can directly
> use the clk API function for enable/disable the clock. Those functions
> are already checking for NULL clk and returning 0 if that's the case.


> 
> Signed-off-by: Robert Chiras 
> Acked-by: Leonard Crestez 
> ---
>  drivers/gpu/drm/mxsfb/mxsfb_crtc.c |  8 
>  drivers/gpu/drm/mxsfb/mxsfb_drv.c  | 32 +---
>  drivers/gpu/drm/mxsfb/mxsfb_drv.h  |  3 ---
>  3 files changed, 17 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> index a4ba368..e727f5e 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> @@ -408,7 +408,7 @@ void mxsfb_crtc_enable(struct mxsfb_drm_private *mxsfb)
>  {
>   dma_addr_t paddr;
>  
> - mxsfb_enable_axi_clk(mxsfb);
> + clk_prepare_enable(mxsfb->clk_axi);
>   writel(0, mxsfb->base + LCDC_CTRL);
>   mxsfb_crtc_mode_set_nofb(mxsfb);
>  
> @@ -425,7 +425,7 @@ void mxsfb_crtc_enable(struct mxsfb_drm_private *mxsfb)
>  void mxsfb_crtc_disable(struct mxsfb_drm_private *mxsfb)
>  {
>   mxsfb_disable_controller(mxsfb);
> - mxsfb_disable_axi_clk(mxsfb);
> + clk_disable_unprepare(mxsfb->clk_axi);
>  }
>  
>  void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
> @@ -451,8 +451,8 @@ void mxsfb_plane_atomic_update(struct
> mxsfb_drm_private *mxsfb,
>  
>   paddr = mxsfb_get_fb_paddr(mxsfb);
>   if (paddr) {
> - mxsfb_enable_axi_clk(mxsfb);
> + clk_prepare_enable(mxsfb->clk_axi);
>   writel(paddr, mxsfb->base + mxsfb->devdata->next_buf);
> - mxsfb_disable_axi_clk(mxsfb);
> + clk_disable_unprepare(mxsfb->clk_axi);
>   }
>  }
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> index 6dae2bd..694b287 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> @@ -97,18 +97,6 @@ drm_pipe_to_mxsfb_drm_private(struct
> drm_simple_display_pipe *pipe)
>   return container_of(pipe, struct mxsfb_drm_private, pipe);
>  }
>  
> -void mxsfb_enable_axi_clk(struct mxsfb_drm_private *mxsfb)
> -{
> - if (mxsfb->clk_axi)
> - clk_prepare_enable(mxsfb->clk_axi);
> -}
> -
> -void mxsfb_disable_axi_clk(struct mxsfb_drm_private *mxsfb)
> -{
> - if (mxsfb->clk_axi)
> - clk_disable_unprepare(mxsfb->clk_axi);
> -}
> -
>  /**
>   * mxsfb_atomic_helper_check - validate state object
>   * @dev: DRM device
> @@ -229,25 +217,31 @@ static void mxsfb_pipe_update(struct
> drm_simple_display_pipe *pipe,
>  static int mxsfb_pipe_enable_vblank(struct drm_simple_display_pipe *pipe)
>  {
>   struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
> + int ret = 0;
> +
> + ret = clk_prepare_enable(mxsfb->clk_axi);
> + if (ret)
> + return ret;
>  
>   /* Clear and enable VBLANK IRQ */
> - mxsfb_enable_axi_clk(mxsfb);
>   writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
>   writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_SET);
> - mxsfb_disable_axi_clk(mxsfb);
> + clk_disable_unprepare(mxsfb->clk_axi);
>  
> - return 0;
> + return ret;
>  }
>  
>  static void mxsfb_pipe_disable_vblank(struct drm_simple_display_pipe *pipe)
>  {
>   struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
>  
> + if (clk_prepare_enable(mxsfb->clk_axi))
> + return;
> +
>   /* Disable and clear VBLANK IRQ */
> - mxsfb_enable_axi_clk(mxsfb);
>   writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR);
>   writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
> - mxsfb_disable_axi_clk(mxsfb);
> + clk_disable_unprepare(mxsfb->clk_axi);
>  }
>  
>  static struct drm_simple_display_pipe_funcs mxsfb_funcs = {
> @@ -413,7 +407,7 @@ static irqreturn_t mxsfb_irq_handler(int irq, void *data)
>   struct mxsfb_drm_private *mxsfb = drm->dev_private;
>   u32 reg;
>  
> - mxsfb_enable_axi_clk(mxsfb);
> + clk_prepare_enable(mxsfb->clk_axi);
>  
>   reg = readl(mxsfb->base + LCDC_CTRL1);
>  
> @@ -422,7 +416,7 @@ static irqreturn_t mxsfb_irq_handler(int irq, void *data)
>  
>   writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
>  
> - mxsfb_disable_axi_clk(mxsfb);
> + clk_disable_unprepare(mxsfb->clk_axi);
>  

[PATCH v2 12/15] drm/mxsfb: Improve the axi clock usage

2019-08-14 Thread Robert Chiras
Currently, the enable of the axi clock return status is ignored, causing
issues when the enable fails then we try to disable it. Therefore, it is
better to check the return status and disable it only when enable
succeeded.
Also, remove the helper functions around clk_axi, since we can directly
use the clk API function for enable/disable the clock. Those functions
are already checking for NULL clk and returning 0 if that's the case.

Signed-off-by: Robert Chiras 
Acked-by: Leonard Crestez 
---
 drivers/gpu/drm/mxsfb/mxsfb_crtc.c |  8 
 drivers/gpu/drm/mxsfb/mxsfb_drv.c  | 32 +---
 drivers/gpu/drm/mxsfb/mxsfb_drv.h  |  3 ---
 3 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c 
b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
index a4ba368..e727f5e 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
@@ -408,7 +408,7 @@ void mxsfb_crtc_enable(struct mxsfb_drm_private *mxsfb)
 {
dma_addr_t paddr;
 
-   mxsfb_enable_axi_clk(mxsfb);
+   clk_prepare_enable(mxsfb->clk_axi);
writel(0, mxsfb->base + LCDC_CTRL);
mxsfb_crtc_mode_set_nofb(mxsfb);
 
@@ -425,7 +425,7 @@ void mxsfb_crtc_enable(struct mxsfb_drm_private *mxsfb)
 void mxsfb_crtc_disable(struct mxsfb_drm_private *mxsfb)
 {
mxsfb_disable_controller(mxsfb);
-   mxsfb_disable_axi_clk(mxsfb);
+   clk_disable_unprepare(mxsfb->clk_axi);
 }
 
 void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
@@ -451,8 +451,8 @@ void mxsfb_plane_atomic_update(struct mxsfb_drm_private 
*mxsfb,
 
paddr = mxsfb_get_fb_paddr(mxsfb);
if (paddr) {
-   mxsfb_enable_axi_clk(mxsfb);
+   clk_prepare_enable(mxsfb->clk_axi);
writel(paddr, mxsfb->base + mxsfb->devdata->next_buf);
-   mxsfb_disable_axi_clk(mxsfb);
+   clk_disable_unprepare(mxsfb->clk_axi);
}
 }
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c 
b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index 6dae2bd..694b287 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -97,18 +97,6 @@ drm_pipe_to_mxsfb_drm_private(struct drm_simple_display_pipe 
*pipe)
return container_of(pipe, struct mxsfb_drm_private, pipe);
 }
 
-void mxsfb_enable_axi_clk(struct mxsfb_drm_private *mxsfb)
-{
-   if (mxsfb->clk_axi)
-   clk_prepare_enable(mxsfb->clk_axi);
-}
-
-void mxsfb_disable_axi_clk(struct mxsfb_drm_private *mxsfb)
-{
-   if (mxsfb->clk_axi)
-   clk_disable_unprepare(mxsfb->clk_axi);
-}
-
 /**
  * mxsfb_atomic_helper_check - validate state object
  * @dev: DRM device
@@ -229,25 +217,31 @@ static void mxsfb_pipe_update(struct 
drm_simple_display_pipe *pipe,
 static int mxsfb_pipe_enable_vblank(struct drm_simple_display_pipe *pipe)
 {
struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
+   int ret = 0;
+
+   ret = clk_prepare_enable(mxsfb->clk_axi);
+   if (ret)
+   return ret;
 
/* Clear and enable VBLANK IRQ */
-   mxsfb_enable_axi_clk(mxsfb);
writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_SET);
-   mxsfb_disable_axi_clk(mxsfb);
+   clk_disable_unprepare(mxsfb->clk_axi);
 
-   return 0;
+   return ret;
 }
 
 static void mxsfb_pipe_disable_vblank(struct drm_simple_display_pipe *pipe)
 {
struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
 
+   if (clk_prepare_enable(mxsfb->clk_axi))
+   return;
+
/* Disable and clear VBLANK IRQ */
-   mxsfb_enable_axi_clk(mxsfb);
writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR);
writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
-   mxsfb_disable_axi_clk(mxsfb);
+   clk_disable_unprepare(mxsfb->clk_axi);
 }
 
 static struct drm_simple_display_pipe_funcs mxsfb_funcs = {
@@ -413,7 +407,7 @@ static irqreturn_t mxsfb_irq_handler(int irq, void *data)
struct mxsfb_drm_private *mxsfb = drm->dev_private;
u32 reg;
 
-   mxsfb_enable_axi_clk(mxsfb);
+   clk_prepare_enable(mxsfb->clk_axi);
 
reg = readl(mxsfb->base + LCDC_CTRL1);
 
@@ -422,7 +416,7 @@ static irqreturn_t mxsfb_irq_handler(int irq, void *data)
 
writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
 
-   mxsfb_disable_axi_clk(mxsfb);
+   clk_disable_unprepare(mxsfb->clk_axi);
 
return IRQ_HANDLED;
 }
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.h 
b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
index 8fb65d3..d6df8fe 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.h
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
@@ -37,9 +37,6 @@ struct mxsfb_drm_private {
 int mxsfb_setup_crtc(struct drm_device *dev);
 int mxsfb_create_output(struct drm_device *dev);
 
-void mxsfb_enable_axi_clk(struct