[v4,28/78] drm/vc4: encoder: Add finer-grained encoder callbacks
diff mbox series

Message ID 5fadf9256d130d447e3c66a0c86ceeba05c47fa4.1594230107.git-series.maxime@cerno.tech
State New
Headers show
Series
  • drm/vc4: Support BCM2711 Display Pipeline
Related show

Commit Message

Maxime Ripard July 8, 2020, 5:41 p.m. UTC
In the BCM2711, the setup of the HVS, pixelvalve and HDMI controller
requires very precise ordering and timing that the regular atomic callbacks
don't provide. Let's add new callbacks on top of the regular ones to be
able to split the configuration as needed.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 19 +++++++++++++++++++
 drivers/gpu/drm/vc4/vc4_drv.h  |  7 +++++++
 2 files changed, 26 insertions(+)

Comments

Dave Stevenson July 28, 2020, 11:25 a.m. UTC | #1
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard <maxime@cerno.tech> wrote:
>
> In the BCM2711, the setup of the HVS, pixelvalve and HDMI controller
> requires very precise ordering and timing that the regular atomic callbacks
> don't provide. Let's add new callbacks on top of the regular ones to be
> able to split the configuration as needed.
>
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>

Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 19 +++++++++++++++++++
>  drivers/gpu/drm/vc4/vc4_drv.h  |  7 +++++++
>  2 files changed, 26 insertions(+)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index b7b0e19e2fe1..d0b326e1df0a 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -389,6 +389,8 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
>  {
>         struct drm_device *dev = crtc->dev;
>         struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +       struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
> +       struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
>         int ret;
>
>         require_hvs_enabled(dev);
> @@ -401,10 +403,16 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
>         ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
>         WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
>
> +       if (vc4_encoder->post_crtc_disable)
> +               vc4_encoder->post_crtc_disable(encoder);
> +
>         CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
>
>         vc4_hvs_atomic_disable(crtc, old_state);
>
> +       if (vc4_encoder->post_crtc_powerdown)
> +               vc4_encoder->post_crtc_powerdown(encoder);
> +
>         /*
>          * Make sure we issue a vblank event after disabling the CRTC if
>          * someone was waiting it.
> @@ -424,6 +432,8 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
>  {
>         struct drm_device *dev = crtc->dev;
>         struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +       struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
> +       struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
>
>         require_hvs_enabled(dev);
>
> @@ -434,15 +444,24 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
>
>         vc4_hvs_atomic_enable(crtc, old_state);
>
> +       if (vc4_encoder->pre_crtc_configure)
> +               vc4_encoder->pre_crtc_configure(encoder);
> +
>         vc4_crtc_config_pv(crtc);
>
>         CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
>
> +       if (vc4_encoder->pre_crtc_enable)
> +               vc4_encoder->pre_crtc_enable(encoder);
> +
>         /* When feeding the transposer block the pixelvalve is unneeded and
>          * should not be enabled.
>          */
>         CRTC_WRITE(PV_V_CONTROL,
>                    CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
> +
> +       if (vc4_encoder->post_crtc_enable)
> +               vc4_encoder->post_crtc_enable(encoder);
>  }
>
>  static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc,
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> index dfcc684f5d28..251fcc35530c 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.h
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -439,6 +439,13 @@ struct vc4_encoder {
>         struct drm_encoder base;
>         enum vc4_encoder_type type;
>         u32 clock_select;
> +
> +       void (*pre_crtc_configure)(struct drm_encoder *encoder);
> +       void (*pre_crtc_enable)(struct drm_encoder *encoder);
> +       void (*post_crtc_enable)(struct drm_encoder *encoder);
> +
> +       void (*post_crtc_disable)(struct drm_encoder *encoder);
> +       void (*post_crtc_powerdown)(struct drm_encoder *encoder);
>  };
>
>  static inline struct vc4_encoder *
> --
> git-series 0.9.1

Patch
diff mbox series

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index b7b0e19e2fe1..d0b326e1df0a 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -389,6 +389,8 @@  static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
 {
 	struct drm_device *dev = crtc->dev;
 	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
+	struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
 	int ret;
 
 	require_hvs_enabled(dev);
@@ -401,10 +403,16 @@  static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
 	ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
 	WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
 
+	if (vc4_encoder->post_crtc_disable)
+		vc4_encoder->post_crtc_disable(encoder);
+
 	CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
 
 	vc4_hvs_atomic_disable(crtc, old_state);
 
+	if (vc4_encoder->post_crtc_powerdown)
+		vc4_encoder->post_crtc_powerdown(encoder);
+
 	/*
 	 * Make sure we issue a vblank event after disabling the CRTC if
 	 * someone was waiting it.
@@ -424,6 +432,8 @@  static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
 {
 	struct drm_device *dev = crtc->dev;
 	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
+	struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
 
 	require_hvs_enabled(dev);
 
@@ -434,15 +444,24 @@  static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
 
 	vc4_hvs_atomic_enable(crtc, old_state);
 
+	if (vc4_encoder->pre_crtc_configure)
+		vc4_encoder->pre_crtc_configure(encoder);
+
 	vc4_crtc_config_pv(crtc);
 
 	CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
 
+	if (vc4_encoder->pre_crtc_enable)
+		vc4_encoder->pre_crtc_enable(encoder);
+
 	/* When feeding the transposer block the pixelvalve is unneeded and
 	 * should not be enabled.
 	 */
 	CRTC_WRITE(PV_V_CONTROL,
 		   CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
+
+	if (vc4_encoder->post_crtc_enable)
+		vc4_encoder->post_crtc_enable(encoder);
 }
 
 static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index dfcc684f5d28..251fcc35530c 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -439,6 +439,13 @@  struct vc4_encoder {
 	struct drm_encoder base;
 	enum vc4_encoder_type type;
 	u32 clock_select;
+
+	void (*pre_crtc_configure)(struct drm_encoder *encoder);
+	void (*pre_crtc_enable)(struct drm_encoder *encoder);
+	void (*post_crtc_enable)(struct drm_encoder *encoder);
+
+	void (*post_crtc_disable)(struct drm_encoder *encoder);
+	void (*post_crtc_powerdown)(struct drm_encoder *encoder);
 };
 
 static inline struct vc4_encoder *