2020-04-24 06:39:00

by 赵军奎

[permalink] [raw]
Subject: [PATCH v2] drm/arm: fixes pixel clock enabled with wrong format

The pixel clock is still enabled when the format is wrong.
no error branch handle, and also some register is not set
in this case, e.g: HDLCD_REG_<color>_SELECT. Maybe we
should disable this clock and throw an warn message when
this happened.
With this change, the code maybe a bit more readable.

Signed-off-by: Bernard Zhao <[email protected]>

Changes since V1:
*add format error handle, if format is not correct, throw
an warning message and disable this clock.

Link for V1:
*https://lore.kernel.org/patchwork/patch/1228501/
---
drivers/gpu/drm/arm/hdlcd_crtc.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index af67fefed38d..f3945dee2b7d 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -96,7 +96,7 @@ static int hdlcd_set_pxl_fmt(struct drm_crtc *crtc)
}

if (WARN_ON(!format))
- return 0;
+ return -EINVAL;

/* HDLCD uses 'bytes per pixel', zero means 1 byte */
btpp = (format->bits_per_pixel + 7) / 8;
@@ -125,7 +125,7 @@ static int hdlcd_set_pxl_fmt(struct drm_crtc *crtc)
return 0;
}

-static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
+static int hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
{
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
struct drm_display_mode *m = &crtc->state->adjusted_mode;
@@ -162,9 +162,10 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)

err = hdlcd_set_pxl_fmt(crtc);
if (err)
- return;
+ return err;

clk_set_rate(hdlcd->clk, m->crtc_clock * 1000);
+ return 0;
}

static void hdlcd_crtc_atomic_enable(struct drm_crtc *crtc,
@@ -173,7 +174,11 @@ static void hdlcd_crtc_atomic_enable(struct drm_crtc *crtc,
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);

clk_prepare_enable(hdlcd->clk);
- hdlcd_crtc_mode_set_nofb(crtc);
+ if (hdlcd_crtc_mode_set_nofb(crtc)) {
+ DRM_DEBUG_KMS("Invalid format, pixel clock enable failed!\n");
+ clk_disable_unprepare(hdlcd->clk);
+ return;
+ }
hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1);
drm_crtc_vblank_on(crtc);
}
--
2.26.2


2020-04-24 11:05:23

by Emil Velikov

[permalink] [raw]
Subject: Re: [PATCH v2] drm/arm: fixes pixel clock enabled with wrong format

Hi Bernard,

On Fri, 24 Apr 2020 at 08:15, Bernard Zhao <[email protected]> wrote:
>
> The pixel clock is still enabled when the format is wrong.
> no error branch handle, and also some register is not set
> in this case, e.g: HDLCD_REG_<color>_SELECT. Maybe we
> should disable this clock and throw an warn message when
> this happened.
> With this change, the code maybe a bit more readable.
>
> Signed-off-by: Bernard Zhao <[email protected]>
>
> Changes since V1:
> *add format error handle, if format is not correct, throw
> an warning message and disable this clock.
>
> Link for V1:
> *https://lore.kernel.org/patchwork/patch/1228501/
> ---
> drivers/gpu/drm/arm/hdlcd_crtc.c | 13 +++++++++----
> 1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
> index af67fefed38d..f3945dee2b7d 100644
> --- a/drivers/gpu/drm/arm/hdlcd_crtc.c
> +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
> @@ -96,7 +96,7 @@ static int hdlcd_set_pxl_fmt(struct drm_crtc *crtc)
> }
>
> if (WARN_ON(!format))
> - return 0;
> + return -EINVAL;
>
> /* HDLCD uses 'bytes per pixel', zero means 1 byte */
> btpp = (format->bits_per_pixel + 7) / 8;
> @@ -125,7 +125,7 @@ static int hdlcd_set_pxl_fmt(struct drm_crtc *crtc)
> return 0;
> }
>
> -static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
> +static int hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
> {
> struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
> struct drm_display_mode *m = &crtc->state->adjusted_mode;
> @@ -162,9 +162,10 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
>
> err = hdlcd_set_pxl_fmt(crtc);
> if (err)
> - return;
> + return err;
>
> clk_set_rate(hdlcd->clk, m->crtc_clock * 1000);
> + return 0;
> }
>
> static void hdlcd_crtc_atomic_enable(struct drm_crtc *crtc,
> @@ -173,7 +174,11 @@ static void hdlcd_crtc_atomic_enable(struct drm_crtc *crtc,
> struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
>
> clk_prepare_enable(hdlcd->clk);
> - hdlcd_crtc_mode_set_nofb(crtc);
> + if (hdlcd_crtc_mode_set_nofb(crtc)) {
> + DRM_DEBUG_KMS("Invalid format, pixel clock enable failed!\n");
> + clk_disable_unprepare(hdlcd->clk);
> + return;
> + }
This doesn't seem right. As far as I can tell, the state must be
checked in the .atomic_check since .atomic_enable, intentionally,
"cannot" fail.

HTH
Emil


> hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1);
> drm_crtc_vblank_on(crtc);
> }
> --
> 2.26.2
>
> _______________________________________________
> dri-devel mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

2020-04-24 11:11:54

by Liviu Dudau

[permalink] [raw]
Subject: Re: [PATCH v2] drm/arm: fixes pixel clock enabled with wrong format

Hi Bernand,

On Thu, Apr 23, 2020 at 11:35:51PM -0700, Bernard Zhao wrote:
> The pixel clock is still enabled when the format is wrong.
> no error branch handle, and also some register is not set
> in this case, e.g: HDLCD_REG_<color>_SELECT. Maybe we
> should disable this clock and throw an warn message when
> this happened.
> With this change, the code maybe a bit more readable.
>
> Signed-off-by: Bernard Zhao <[email protected]>
>
> Changes since V1:
> *add format error handle, if format is not correct, throw
> an warning message and disable this clock.
>
> Link for V1:
> *https://lore.kernel.org/patchwork/patch/1228501/
> ---
> drivers/gpu/drm/arm/hdlcd_crtc.c | 13 +++++++++----
> 1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
> index af67fefed38d..f3945dee2b7d 100644
> --- a/drivers/gpu/drm/arm/hdlcd_crtc.c
> +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
> @@ -96,7 +96,7 @@ static int hdlcd_set_pxl_fmt(struct drm_crtc *crtc)
> }
>
> if (WARN_ON(!format))
> - return 0;
> + return -EINVAL;

That is the right fix!

>
> /* HDLCD uses 'bytes per pixel', zero means 1 byte */
> btpp = (format->bits_per_pixel + 7) / 8;
> @@ -125,7 +125,7 @@ static int hdlcd_set_pxl_fmt(struct drm_crtc *crtc)
> return 0;
> }
>
> -static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
> +static int hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)

But this is not. We don't need to propagate the error further, just ....

> {
> struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
> struct drm_display_mode *m = &crtc->state->adjusted_mode;
> @@ -162,9 +162,10 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
>
> err = hdlcd_set_pxl_fmt(crtc);
> if (err)
> - return;

... return here so that we don't call clk_set_rate();

Best regards,
Liviu

> + return err;
>
> clk_set_rate(hdlcd->clk, m->crtc_clock * 1000);
> + return 0;
> }
>
> static void hdlcd_crtc_atomic_enable(struct drm_crtc *crtc,
> @@ -173,7 +174,11 @@ static void hdlcd_crtc_atomic_enable(struct drm_crtc *crtc,
> struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
>
> clk_prepare_enable(hdlcd->clk);
> - hdlcd_crtc_mode_set_nofb(crtc);
> + if (hdlcd_crtc_mode_set_nofb(crtc)) {
> + DRM_DEBUG_KMS("Invalid format, pixel clock enable failed!\n");
> + clk_disable_unprepare(hdlcd->clk);
> + return;
> + }
> hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1);
> drm_crtc_vblank_on(crtc);
> }
> --
> 2.26.2
>

--
====================
| I would like to |
| fix the world, |
| but they're not |
| giving me the |
\ source code! /
---------------
¯\_(ツ)_/¯