[v3,055/105] drm/vc4: hvs: Introduce a function to get the assigned FIFO
diff mbox series

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

Commit Message

Maxime Ripard May 27, 2020, 3:48 p.m. UTC
At boot time, if we detect that a pixelvalve has been enabled, we need to
be able to retrieve the HVS channel it has been assigned to so that we can
disable that channel too. Let's create that function that returns the FIFO
or an error from a given output.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/gpu/drm/vc4/vc4_drv.h |  1 +-
 drivers/gpu/drm/vc4/vc4_hvs.c | 51 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 52 insertions(+)

Comments

Maxime Ripard June 3, 2020, 9:43 a.m. UTC | #1
Hi Eric,

On Wed, May 27, 2020 at 12:40:02PM -0700, Eric Anholt wrote:
> On Wed, May 27, 2020 at 8:50 AM Maxime Ripard <maxime@cerno.tech> wrote:
> >
> > At boot time, if we detect that a pixelvalve has been enabled, we need to
> > be able to retrieve the HVS channel it has been assigned to so that we can
> > disable that channel too. Let's create that function that returns the FIFO
> > or an error from a given output.
> >
> > Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> > ---
> 
> > +int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output)
> > +{
> > +       struct vc4_dev *vc4 = to_vc4_dev(dev);
> > +       u32 reg;
> > +       int ret;
> > +
> > +       switch (output) {
> > +       case 0:
> > +               return 0;
> > +
> > +       case 1:
> > +               return 1;
> > +
> > +       case 2:
> > +               reg = HVS_READ(SCALER_DISPECTRL);
> > +               ret = FIELD_GET(SCALER_DISPECTRL_DSP2_MUX_MASK, reg);
> > +               if (ret == 0)
> > +                       return 2;
> > +
> > +               return 0;
> > +
> > +       case 3:
> > +               reg = HVS_READ(SCALER_DISPCTRL);
> > +               ret = FIELD_GET(SCALER_DISPCTRL_DSP3_MUX_MASK, reg);
> > +               if (ret == 3)
> > +                       return -EPIPE;
> > +
> > +               return ret;
> > +
> > +       case 4:
> > +               reg = HVS_READ(SCALER_DISPEOLN);
> > +               ret = FIELD_GET(SCALER_DISPEOLN_DSP4_MUX_MASK, reg);
> > +               if (ret == 3)
> > +                       return -EPIPE;
> > +
> > +               return ret;
> > +
> > +       case 5:
> > +               reg = HVS_READ(SCALER_DISPDITHER);
> > +               ret = FIELD_GET(SCALER_DISPDITHER_DSP5_MUX_MASK, reg);
> > +               if (ret == 3)
> > +                       return -EPIPE;
> 
> Oh, FIELD_GET is new to me.  Looks like we should replace
> VC4_GET_FIELD usage with just using that header, and also
> VC4_SET_FIELD with WARN_ON(!FIELD_FIT()); FIELD_PREP.
>
> Could you follow up with that?

I will :)

> Other than that, 54-67 r-b.

Thanks!
Maxime

Patch
diff mbox series

diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index d51b695732e0..99001f8783aa 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -880,6 +880,7 @@  void vc4_irq_reset(struct drm_device *dev);
 /* vc4_hvs.c */
 extern struct platform_driver vc4_hvs_driver;
 void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int output);
+int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output);
 int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state);
 void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state);
 void vc4_hvs_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state);
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index 1785c49534cf..56657959778f 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -19,6 +19,7 @@ 
  * each CRTC.
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/component.h>
 #include <linux/platform_device.h>
@@ -196,6 +197,56 @@  static void vc4_hvs_update_gamma_lut(struct drm_crtc *crtc)
 	vc4_hvs_lut_load(crtc);
 }
 
+int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	u32 reg;
+	int ret;
+
+	switch (output) {
+	case 0:
+		return 0;
+
+	case 1:
+		return 1;
+
+	case 2:
+		reg = HVS_READ(SCALER_DISPECTRL);
+		ret = FIELD_GET(SCALER_DISPECTRL_DSP2_MUX_MASK, reg);
+		if (ret == 0)
+			return 2;
+
+		return 0;
+
+	case 3:
+		reg = HVS_READ(SCALER_DISPCTRL);
+		ret = FIELD_GET(SCALER_DISPCTRL_DSP3_MUX_MASK, reg);
+		if (ret == 3)
+			return -EPIPE;
+
+		return ret;
+
+	case 4:
+		reg = HVS_READ(SCALER_DISPEOLN);
+		ret = FIELD_GET(SCALER_DISPEOLN_DSP4_MUX_MASK, reg);
+		if (ret == 3)
+			return -EPIPE;
+
+		return ret;
+
+	case 5:
+		reg = HVS_READ(SCALER_DISPDITHER);
+		ret = FIELD_GET(SCALER_DISPDITHER_DSP5_MUX_MASK, reg);
+		if (ret == 3)
+			return -EPIPE;
+
+		return ret;
+
+	default:
+		return -EPIPE;
+	}
+}
+
 static int vc4_hvs_init_channel(struct vc4_dev *vc4, struct drm_crtc *crtc,
 				struct drm_display_mode *mode, bool oneshot)
 {