All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
To: Maxime Ripard <maxime@cerno.tech>
Cc: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>,
	Eric Anholt <eric@anholt.net>,
	DRI Development <dri-devel@lists.freedesktop.org>,
	linux-rpi-kernel@lists.infradead.org,
	bcm-kernel-feedback-list@broadcom.com,
	linux-arm-kernel@lists.infradead.org,
	LKML <linux-kernel@vger.kernel.org>,
	Tim Gover <tim.gover@raspberrypi.com>,
	Phil Elwell <phil@raspberrypi.com>
Subject: Re: [PATCH v4 74/78] drm/vc4: hdmi: Support the BCM2711 HDMI controllers
Date: Tue, 28 Jul 2020 16:21:56 +0100	[thread overview]
Message-ID: <CAPY8ntA0UixNWc27-x0Y5AG_pXvzh=5spHwQ5poYLEqDzSS0WA@mail.gmail.com> (raw)
In-Reply-To: <37e2291033dc5f012248efc641ca796101470b45.1594230107.git-series.maxime@cerno.tech>

Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard <maxime@cerno.tech> wrote:
>
> Now that the driver is ready for it, let's bring in the HDMI controllers
> variants for the BCM2711.
>
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>

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

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c      | 278 +++++++++++++++++-
>  drivers/gpu/drm/vc4/vc4_hdmi.h      |  36 ++-
>  drivers/gpu/drm/vc4/vc4_hdmi_phy.c  | 480 +++++++++++++++++++++++++++++-
>  drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 201 ++++++++++++-
>  drivers/gpu/drm/vc4/vc4_regs.h      |   2 +-
>  5 files changed, 997 insertions(+)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 37463b016b47..d5ba0b1b73a9 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -43,6 +43,7 @@
>  #include <linux/of_platform.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/rational.h>
> +#include <linux/reset.h>
>  #include <sound/dmaengine_pcm.h>
>  #include <sound/pcm_drm_eld.h>
>  #include <sound/pcm_params.h>
> @@ -53,6 +54,31 @@
>  #include "vc4_hdmi_regs.h"
>  #include "vc4_regs.h"
>
> +#define VC5_HDMI_HORZA_HFP_SHIFT               16
> +#define VC5_HDMI_HORZA_HFP_MASK                        VC4_MASK(28, 16)
> +#define VC5_HDMI_HORZA_VPOS                    BIT(15)
> +#define VC5_HDMI_HORZA_HPOS                    BIT(14)
> +#define VC5_HDMI_HORZA_HAP_SHIFT               0
> +#define VC5_HDMI_HORZA_HAP_MASK                        VC4_MASK(13, 0)
> +
> +#define VC5_HDMI_HORZB_HBP_SHIFT               16
> +#define VC5_HDMI_HORZB_HBP_MASK                        VC4_MASK(26, 16)
> +#define VC5_HDMI_HORZB_HSP_SHIFT               0
> +#define VC5_HDMI_HORZB_HSP_MASK                        VC4_MASK(10, 0)
> +
> +#define VC5_HDMI_VERTA_VSP_SHIFT               24
> +#define VC5_HDMI_VERTA_VSP_MASK                        VC4_MASK(28, 24)
> +#define VC5_HDMI_VERTA_VFP_SHIFT               16
> +#define VC5_HDMI_VERTA_VFP_MASK                        VC4_MASK(22, 16)
> +#define VC5_HDMI_VERTA_VAL_SHIFT               0
> +#define VC5_HDMI_VERTA_VAL_MASK                        VC4_MASK(12, 0)
> +
> +#define VC5_HDMI_VERTB_VSPO_SHIFT              16
> +#define VC5_HDMI_VERTB_VSPO_MASK               VC4_MASK(29, 16)
> +
> +# define VC4_HD_M_SW_RST                       BIT(2)
> +# define VC4_HD_M_ENABLE                       BIT(0)
> +
>  #define CEC_CLOCK_FREQ 40000
>
>  static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
> @@ -82,6 +108,16 @@ static void vc4_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
>         HDMI_WRITE(HDMI_SW_RESET_CONTROL, 0);
>  }
>
> +static void vc5_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
> +{
> +       reset_control_reset(vc4_hdmi->reset);
> +
> +       HDMI_WRITE(HDMI_DVP_CTL, 0);
> +
> +       HDMI_WRITE(HDMI_CLOCK_STOP,
> +                  HDMI_READ(HDMI_CLOCK_STOP) | VC4_DVP_HT_CLOCK_STOP_PIXEL);
> +}
> +
>  static enum drm_connector_status
>  vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> @@ -391,6 +427,45 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
>         HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
>  }
>
> +static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
> +{
> +       u32 csc_ctl;
> +
> +       csc_ctl = 0x07; /* RGB_CONVERT_MODE = custom matrix, || USE_RGB_TO_YCBCR */
> +
> +       if (enable) {
> +               /* CEA VICs other than #1 requre limited range RGB
> +                * output unless overridden by an AVI infoframe.
> +                * Apply a colorspace conversion to squash 0-255 down
> +                * to 16-235.  The matrix here is:
> +                *
> +                * [ 0.8594 0      0      16]
> +                * [ 0      0.8594 0      16]
> +                * [ 0      0      0.8594 16]
> +                * [ 0      0      0       1]
> +                * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
> +                */
> +               HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x1b80);
> +               HDMI_WRITE(HDMI_CSC_14_13, (0x0400 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_22_21, (0x1b80 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_24_23, (0x0400 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_34_33, (0x0400 << 16) | 0x1b80);
> +       } else {
> +               /* Still use the matrix for full range, but make it unity.
> +                * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
> +                */
> +               HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x2000);
> +               HDMI_WRITE(HDMI_CSC_14_13, (0x0000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_22_21, (0x2000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_24_23, (0x0000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_34_33, (0x0000 << 16) | 0x2000);
> +       }
> +
> +       HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
> +}
> +
>  static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
>                                  struct drm_display_mode *mode)
>  {
> @@ -435,6 +510,53 @@ static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
>         HDMI_WRITE(HDMI_VERTB0, vertb_even);
>         HDMI_WRITE(HDMI_VERTB1, vertb);
>  }
> +static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
> +                                struct drm_display_mode *mode)
> +{
> +       bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
> +       bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
> +       bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
> +       u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
> +       u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
> +                                  VC5_HDMI_VERTA_VSP) |
> +                    VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
> +                                  VC5_HDMI_VERTA_VFP) |
> +                    VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL));
> +       u32 vertb = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
> +                    VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
> +                                  VC4_HDMI_VERTB_VBP));
> +       u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
> +                         VC4_SET_FIELD(mode->crtc_vtotal -
> +                                       mode->crtc_vsync_end -
> +                                       interlaced,
> +                                       VC4_HDMI_VERTB_VBP));
> +
> +       HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021);
> +       HDMI_WRITE(HDMI_HORZA,
> +                  (vsync_pos ? VC5_HDMI_HORZA_VPOS : 0) |
> +                  (hsync_pos ? VC5_HDMI_HORZA_HPOS : 0) |
> +                  VC4_SET_FIELD(mode->hdisplay * pixel_rep,
> +                                VC5_HDMI_HORZA_HAP) |
> +                  VC4_SET_FIELD((mode->hsync_start -
> +                                 mode->hdisplay) * pixel_rep,
> +                                VC5_HDMI_HORZA_HFP));
> +
> +       HDMI_WRITE(HDMI_HORZB,
> +                  VC4_SET_FIELD((mode->htotal -
> +                                 mode->hsync_end) * pixel_rep,
> +                                VC5_HDMI_HORZB_HBP) |
> +                  VC4_SET_FIELD((mode->hsync_end -
> +                                 mode->hsync_start) * pixel_rep,
> +                                VC5_HDMI_HORZB_HSP));
> +
> +       HDMI_WRITE(HDMI_VERTA0, verta);
> +       HDMI_WRITE(HDMI_VERTA1, verta);
> +
> +       HDMI_WRITE(HDMI_VERTB0, vertb_even);
> +       HDMI_WRITE(HDMI_VERTB1, vertb);
> +
> +       HDMI_WRITE(HDMI_CLOCK_STOP, 0);
> +}
>
>  static void vc4_hdmi_recenter_fifo(struct vc4_hdmi *vc4_hdmi)
>  {
> @@ -645,6 +767,18 @@ static u32 vc4_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
>         return channel_map;
>  }
>
> +static u32 vc5_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
> +{
> +       int i;
> +       u32 channel_map = 0;
> +
> +       for (i = 0; i < 8; i++) {
> +               if (channel_mask & BIT(i))
> +                       channel_map |= i << (4 * i);
> +       }
> +       return channel_map;
> +}
> +
>  /* HDMI audio codec callbacks */
>  static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *vc4_hdmi)
>  {
> @@ -1377,6 +1511,98 @@ static int vc4_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
>         return 0;
>  }
>
> +static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
> +{
> +       struct platform_device *pdev = vc4_hdmi->pdev;
> +       struct device *dev = &pdev->dev;
> +       struct resource *res;
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->hdmicore_regs = devm_ioremap(dev, res->start,
> +                                              resource_size(res));
> +       if (IS_ERR(vc4_hdmi->hdmicore_regs))
> +               return PTR_ERR(vc4_hdmi->hdmicore_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hd");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->hd_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->hd_regs))
> +               return PTR_ERR(vc4_hdmi->hd_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cec");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->cec_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->cec_regs))
> +               return PTR_ERR(vc4_hdmi->cec_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csc");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->csc_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->csc_regs))
> +               return PTR_ERR(vc4_hdmi->csc_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dvp");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->dvp_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->dvp_regs))
> +               return PTR_ERR(vc4_hdmi->dvp_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->phy_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->phy_regs))
> +               return PTR_ERR(vc4_hdmi->phy_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "packet");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->ram_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->ram_regs))
> +               return PTR_ERR(vc4_hdmi->ram_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rm");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->rm_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->rm_regs))
> +               return PTR_ERR(vc4_hdmi->rm_regs);
> +
> +       vc4_hdmi->hsm_clock = devm_clk_get(dev, "hdmi");
> +       if (IS_ERR(vc4_hdmi->hsm_clock)) {
> +               DRM_ERROR("Failed to get HDMI state machine clock\n");
> +               return PTR_ERR(vc4_hdmi->hsm_clock);
> +       }
> +
> +       vc4_hdmi->audio_clock = devm_clk_get(dev, "clk-108M");
> +       if (IS_ERR(vc4_hdmi->audio_clock)) {
> +               DRM_ERROR("Failed to get 108MHz clock\n");
> +               return PTR_ERR(vc4_hdmi->audio_clock);
> +       }
> +
> +       vc4_hdmi->reset = devm_reset_control_get(dev, NULL);
> +       if (IS_ERR(vc4_hdmi->reset)) {
> +               DRM_ERROR("Failed to get HDMI reset line\n");
> +               return PTR_ERR(vc4_hdmi->reset);
> +       }
> +
> +       return 0;
> +}
> +
>  static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
>  {
>         const struct vc4_hdmi_variant *variant = of_device_get_match_data(dev);
> @@ -1547,8 +1773,60 @@ static const struct vc4_hdmi_variant bcm2835_variant = {
>         .channel_map            = vc4_hdmi_channel_map,
>  };
>
> +static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = {
> +       .encoder_type           = VC4_ENCODER_TYPE_HDMI0,
> +       .debugfs_name           = "hdmi0_regs",
> +       .card_name              = "vc4-hdmi-0",
> +       .max_pixel_clock        = 297000000,
> +       .registers              = vc5_hdmi_hdmi0_fields,
> +       .num_registers          = ARRAY_SIZE(vc5_hdmi_hdmi0_fields),
> +       .phy_lane_mapping       = {
> +               PHY_LANE_0,
> +               PHY_LANE_1,
> +               PHY_LANE_2,
> +               PHY_LANE_CK,
> +       },
> +
> +       .init_resources         = vc5_hdmi_init_resources,
> +       .csc_setup              = vc5_hdmi_csc_setup,
> +       .reset                  = vc5_hdmi_reset,
> +       .set_timings            = vc5_hdmi_set_timings,
> +       .phy_init               = vc5_hdmi_phy_init,
> +       .phy_disable            = vc5_hdmi_phy_disable,
> +       .phy_rng_enable         = vc5_hdmi_phy_rng_enable,
> +       .phy_rng_disable        = vc5_hdmi_phy_rng_disable,
> +       .channel_map            = vc5_hdmi_channel_map,
> +};
> +
> +static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = {
> +       .encoder_type           = VC4_ENCODER_TYPE_HDMI1,
> +       .debugfs_name           = "hdmi1_regs",
> +       .card_name              = "vc4-hdmi-1",
> +       .max_pixel_clock        = 297000000,
> +       .registers              = vc5_hdmi_hdmi1_fields,
> +       .num_registers          = ARRAY_SIZE(vc5_hdmi_hdmi1_fields),
> +       .phy_lane_mapping       = {
> +               PHY_LANE_1,
> +               PHY_LANE_0,
> +               PHY_LANE_CK,
> +               PHY_LANE_2,
> +       },
> +
> +       .init_resources         = vc5_hdmi_init_resources,
> +       .csc_setup              = vc5_hdmi_csc_setup,
> +       .reset                  = vc5_hdmi_reset,
> +       .set_timings            = vc5_hdmi_set_timings,
> +       .phy_init               = vc5_hdmi_phy_init,
> +       .phy_disable            = vc5_hdmi_phy_disable,
> +       .phy_rng_enable         = vc5_hdmi_phy_rng_enable,
> +       .phy_rng_disable        = vc5_hdmi_phy_rng_disable,
> +       .channel_map            = vc5_hdmi_channel_map,
> +};
> +
>  static const struct of_device_id vc4_hdmi_dt_match[] = {
>         { .compatible = "brcm,bcm2835-hdmi", .data = &bcm2835_variant },
> +       { .compatible = "brcm,bcm2711-hdmi0", .data = &bcm2711_hdmi0_variant },
> +       { .compatible = "brcm,bcm2711-hdmi1", .data = &bcm2711_hdmi1_variant },
>         {}
>  };
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index 34138e0dd4a6..0806c6d9f24e 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -26,6 +26,13 @@ struct drm_display_mode;
>  struct vc4_hdmi;
>  struct vc4_hdmi_register;
>
> +enum vc4_hdmi_phy_channel {
> +       PHY_LANE_0 = 0,
> +       PHY_LANE_1,
> +       PHY_LANE_2,
> +       PHY_LANE_CK,
> +};
> +
>  struct vc4_hdmi_variant {
>         /* Encoder Type for that controller */
>         enum vc4_encoder_type encoder_type;
> @@ -48,6 +55,13 @@ struct vc4_hdmi_variant {
>         /* Number of registers on that variant */
>         unsigned int num_registers;
>
> +       /* BCM2711 Only.
> +        * The variants don't map the lane in the same order in the
> +        * PHY, so this is an array mapping the HDMI channel (index)
> +        * to the PHY lane (value).
> +        */
> +       enum vc4_hdmi_phy_channel phy_lane_mapping[4];
> +
>         /* Callback to get the resources (memory region, interrupts,
>          * clocks, etc) for that variant.
>          */
> @@ -108,6 +122,20 @@ struct vc4_hdmi {
>         struct i2c_adapter *ddc;
>         void __iomem *hdmicore_regs;
>         void __iomem *hd_regs;
> +
> +       /* VC5 Only */
> +       void __iomem *cec_regs;
> +       /* VC5 Only */
> +       void __iomem *csc_regs;
> +       /* VC5 Only */
> +       void __iomem *dvp_regs;
> +       /* VC5 Only */
> +       void __iomem *phy_regs;
> +       /* VC5 Only */
> +       void __iomem *ram_regs;
> +       /* VC5 Only */
> +       void __iomem *rm_regs;
> +
>         int hpd_gpio;
>         bool hpd_active_low;
>
> @@ -120,6 +148,8 @@ struct vc4_hdmi {
>         struct clk *hsm_clock;
>         struct clk *audio_clock;
>
> +       struct reset_control *reset;
> +
>         struct debugfs_regset32 hdmi_regset;
>         struct debugfs_regset32 hd_regset;
>  };
> @@ -144,4 +174,10 @@ void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
>  void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
>  void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
>
> +void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
> +                      struct drm_display_mode *mode);
> +void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
> +void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
> +void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
> +
>  #endif /* _VC4_HDMI_H_ */
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> index 93287e24d7d1..4d36f8c33401 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> @@ -10,6 +10,123 @@
>  #include "vc4_regs.h"
>  #include "vc4_hdmi_regs.h"
>
> +#define VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB   BIT(5)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB        BIT(4)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_TX_CK_RESET  BIT(3)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_TX_2_RESET   BIT(2)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_TX_1_RESET   BIT(1)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_TX_0_RESET   BIT(0)
> +
> +#define VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN     BIT(4)
> +
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP_SHIFT    29
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP_MASK     VC4_MASK(31, 29)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV_SHIFT   24
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV_MASK    VC4_MASK(28, 24)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP_SHIFT    21
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP_MASK     VC4_MASK(23, 21)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV_SHIFT   16
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV_MASK    VC4_MASK(20, 16)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP_SHIFT    13
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP_MASK     VC4_MASK(15, 13)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV_SHIFT   8
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV_MASK    VC4_MASK(12, 8)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP_SHIFT   5
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP_MASK    VC4_MASK(7, 5)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV_SHIFT  0
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV_MASK   VC4_MASK(4, 0)
> +
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2_SHIFT      15
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2_MASK       VC4_MASK(19, 15)
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1_SHIFT      10
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1_MASK       VC4_MASK(14, 10)
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0_SHIFT      5
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0_MASK       VC4_MASK(9, 5)
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK_SHIFT         0
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK_MASK          VC4_MASK(4, 0)
> +
> +#define VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN_SHIFT           16
> +#define VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN_MASK            VC4_MASK(19, 16)
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2_SHIFT  12
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2_MASK   VC4_MASK(15, 12)
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1_SHIFT  8
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1_MASK   VC4_MASK(11, 8)
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0_SHIFT  4
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0_MASK   VC4_MASK(7, 4)
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK_SHIFT     0
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK_MASK      VC4_MASK(3, 0)
> +
> +#define VC4_HDMI_TX_PHY_CTL_3_RP_SHIFT                 17
> +#define VC4_HDMI_TX_PHY_CTL_3_RP_MASK                  VC4_MASK(19, 17)
> +#define VC4_HDMI_TX_PHY_CTL_3_RZ_SHIFT                 12
> +#define VC4_HDMI_TX_PHY_CTL_3_RZ_MASK                  VC4_MASK(16, 12)
> +#define VC4_HDMI_TX_PHY_CTL_3_CP1_SHIFT                        10
> +#define VC4_HDMI_TX_PHY_CTL_3_CP1_MASK                 VC4_MASK(11, 10)
> +#define VC4_HDMI_TX_PHY_CTL_3_CP_SHIFT                 8
> +#define VC4_HDMI_TX_PHY_CTL_3_CP_MASK                  VC4_MASK(9, 8)
> +#define VC4_HDMI_TX_PHY_CTL_3_CZ_SHIFT                 6
> +#define VC4_HDMI_TX_PHY_CTL_3_CZ_MASK                  VC4_MASK(7, 6)
> +#define VC4_HDMI_TX_PHY_CTL_3_ICP_SHIFT                        0
> +#define VC4_HDMI_TX_PHY_CTL_3_ICP_MASK                 VC4_MASK(5, 0)
> +
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_MASH11_MODE          BIT(13)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VC_RANGE_EN          BIT(12)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_EMULATE_VC_LOW       BIT(11)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_EMULATE_VC_HIGH      BIT(10)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL_SHIFT                9
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL_MASK         VC4_MASK(9, 9)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_FB_DIV2          BIT(8)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_POST_DIV2                BIT(7)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_CONT_EN          BIT(6)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_ENA_VCO_CLK          BIT(5)
> +
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_CPP_SHIFT                    16
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_CPP_MASK                     VC4_MASK(27, 16)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY_SHIFT     14
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY_MASK      VC4_MASK(15, 14)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_ENABLE          BIT(13)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL_SHIFT           11
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL_MASK            VC4_MASK(12, 11)
> +
> +#define VC4_HDMI_TX_PHY_CLK_DIV_VCO_SHIFT              8
> +#define VC4_HDMI_TX_PHY_CLK_DIV_VCO_MASK               VC4_MASK(15, 8)
> +
> +#define VC4_HDMI_TX_PHY_PLL_CFG_PDIV_SHIFT             0
> +#define VC4_HDMI_TX_PHY_PLL_CFG_PDIV_MASK              VC4_MASK(3, 0)
> +
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL_MASK VC4_MASK(13, 12)
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL_SHIFT        12
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL_MASK  VC4_MASK(9, 8)
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL_SHIFT 8
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL_MASK  VC4_MASK(5, 4)
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL_SHIFT 4
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL_MASK  VC4_MASK(1, 0)
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL_SHIFT 0
> +
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_MASK                VC4_MASK(27, 0)
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_SHIFT       0
> +
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_MASK                VC4_MASK(27, 0)
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_SHIFT       0
> +
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD_MASK VC4_MASK(31, 16)
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD_SHIFT        16
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD_MASK   VC4_MASK(15, 0)
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD_SHIFT  0
> +
> +#define VC4_HDMI_RM_CONTROL_EN_FREEZE_COUNTERS         BIT(19)
> +#define VC4_HDMI_RM_CONTROL_EN_LOAD_INTEGRATOR         BIT(17)
> +#define VC4_HDMI_RM_CONTROL_FREE_RUN                   BIT(4)
> +
> +#define VC4_HDMI_RM_OFFSET_ONLY                                BIT(31)
> +#define VC4_HDMI_RM_OFFSET_OFFSET_SHIFT                        0
> +#define VC4_HDMI_RM_OFFSET_OFFSET_MASK                 VC4_MASK(30, 0)
> +
> +#define VC4_HDMI_RM_FORMAT_SHIFT_SHIFT                 24
> +#define VC4_HDMI_RM_FORMAT_SHIFT_MASK                  VC4_MASK(25, 24)
> +
> +#define OSCILLATOR_FREQUENCY   54000000
> +
>  void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, struct drm_display_mode *mode)
>  {
>         /* PHY should be in reset, like
> @@ -38,3 +155,366 @@ void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi)
>                    HDMI_READ(HDMI_TX_PHY_CTL_0) |
>                    VC4_HDMI_TX_PHY_RNG_PWRDN);
>  }
> +
> +static unsigned long long
> +phy_get_vco_freq(unsigned long long clock, u8 *vco_sel, u8 *vco_div)
> +{
> +       unsigned long long vco_freq = clock;
> +       unsigned int _vco_div = 0;
> +       unsigned int _vco_sel = 0;
> +
> +       while (vco_freq < 3000000000ULL) {
> +               _vco_div++;
> +               vco_freq = clock * _vco_div * 10;
> +       }
> +
> +       if (vco_freq > 4500000000ULL)
> +               _vco_sel = 1;
> +
> +       *vco_sel = _vco_sel;
> +       *vco_div = _vco_div;
> +
> +       return vco_freq;
> +}
> +
> +static u8 phy_get_cp_current(unsigned long vco_freq)
> +{
> +       if (vco_freq < 3700000000ULL)
> +               return 0x1c;
> +
> +       return 0x18;
> +}
> +
> +static u32 phy_get_rm_offset(unsigned long long vco_freq)
> +{
> +       unsigned long long fref = OSCILLATOR_FREQUENCY;
> +       u64 offset = 0;
> +
> +       /* RM offset is stored as 9.22 format */
> +       offset = vco_freq * 2;
> +       offset = offset << 22;
> +       do_div(offset, fref);
> +       offset >>= 2;
> +
> +       return offset;
> +}
> +
> +static u8 phy_get_vco_gain(unsigned long long vco_freq)
> +{
> +       if (vco_freq < 3350000000ULL)
> +               return 0xf;
> +
> +       if (vco_freq < 3700000000ULL)
> +               return 0xc;
> +
> +       if (vco_freq < 4050000000ULL)
> +               return 0x6;
> +
> +       if (vco_freq < 4800000000ULL)
> +               return 0x5;
> +
> +       if (vco_freq < 5200000000ULL)
> +               return 0x7;
> +
> +       return 0x2;
> +}
> +
> +struct phy_lane_settings {
> +       struct {
> +               u8 preemphasis;
> +               u8 main_driver;
> +       } amplitude;
> +
> +       u8 res_sel_data;
> +       u8 term_res_sel_data;
> +};
> +
> +struct phy_settings {
> +       unsigned long long min_rate;
> +       unsigned long long max_rate;
> +       struct phy_lane_settings channel[3];
> +       struct phy_lane_settings clock;
> +};
> +
> +static const struct phy_settings vc5_hdmi_phy_settings[] = {
> +       {
> +               0, 50000000,
> +               {
> +                       {{0x0, 0x0A}, 0x12, 0x0},
> +                       {{0x0, 0x0A}, 0x12, 0x0},
> +                       {{0x0, 0x0A}, 0x12, 0x0}
> +               },
> +               {{0x0, 0x0A}, 0x18, 0x0},
> +       },
> +       {
> +               50000001, 75000000,
> +               {
> +                       {{0x0, 0x09}, 0x12, 0x0},
> +                       {{0x0, 0x09}, 0x12, 0x0},
> +                       {{0x0, 0x09}, 0x12, 0x0}
> +               },
> +               {{0x0, 0x0C}, 0x18, 0x3},
> +       },
> +       {
> +               75000001,   165000000,
> +               {
> +                       {{0x0, 0x09}, 0x12, 0x0},
> +                       {{0x0, 0x09}, 0x12, 0x0},
> +                       {{0x0, 0x09}, 0x12, 0x0}
> +               },
> +               {{0x0, 0x0C}, 0x18, 0x3},
> +       },
> +       {
> +               165000001,  250000000,
> +               {
> +                       {{0x0, 0x0F}, 0x12, 0x1},
> +                       {{0x0, 0x0F}, 0x12, 0x1},
> +                       {{0x0, 0x0F}, 0x12, 0x1}
> +               },
> +               {{0x0, 0x0C}, 0x18, 0x3},
> +       },
> +       {
> +               250000001,  340000000,
> +               {
> +                       {{0x2, 0x0D}, 0x12, 0x1},
> +                       {{0x2, 0x0D}, 0x12, 0x1},
> +                       {{0x2, 0x0D}, 0x12, 0x1}
> +               },
> +               {{0x0, 0x0C}, 0x18, 0xF},
> +       },
> +       {
> +               340000001,  450000000,
> +               {
> +                       {{0x0, 0x1B}, 0x12, 0xF},
> +                       {{0x0, 0x1B}, 0x12, 0xF},
> +                       {{0x0, 0x1B}, 0x12, 0xF}
> +               },
> +               {{0x0, 0x0A}, 0x12, 0xF},
> +       },
> +       {
> +               450000001,  600000000,
> +               {
> +                       {{0x0, 0x1C}, 0x12, 0xF},
> +                       {{0x0, 0x1C}, 0x12, 0xF},
> +                       {{0x0, 0x1C}, 0x12, 0xF}
> +               },
> +               {{0x0, 0x0B}, 0x13, 0xF},
> +       },
> +};
> +
> +static const struct phy_settings *phy_get_settings(unsigned long long tmds_rate)
> +{
> +       unsigned int count = ARRAY_SIZE(vc5_hdmi_phy_settings);
> +       unsigned int i;
> +
> +       for (i = 0; i < count; i++) {
> +               const struct phy_settings *s = &vc5_hdmi_phy_settings[i];
> +
> +               if (tmds_rate >= s->min_rate && tmds_rate <= s->max_rate)
> +                       return s;
> +       }
> +
> +       /*
> +        * If the pixel clock exceeds our max setting, try the max
> +        * setting anyway.
> +        */
> +       return &vc5_hdmi_phy_settings[count - 1];
> +}
> +
> +static const struct phy_lane_settings *
> +phy_get_channel_settings(enum vc4_hdmi_phy_channel chan,
> +                        unsigned long long tmds_rate)
> +{
> +       const struct phy_settings *settings = phy_get_settings(tmds_rate);
> +
> +       if (chan == PHY_LANE_CK)
> +               return &settings->clock;
> +
> +       return &settings->channel[chan];
> +}
> +
> +static void vc5_hdmi_reset_phy(struct vc4_hdmi *vc4_hdmi)
> +{
> +       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0x0f);
> +       HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL, BIT(10));
> +}
> +
> +void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, struct drm_display_mode *mode)
> +{
> +       const struct phy_lane_settings *chan0_settings, *chan1_settings, *chan2_settings, *clock_settings;
> +       const struct vc4_hdmi_variant *variant = vc4_hdmi->variant;
> +       unsigned long long pixel_freq = mode->clock * 1000;
> +       unsigned long long vco_freq;
> +       unsigned char word_sel;
> +       u8 vco_sel, vco_div;
> +
> +       vco_freq = phy_get_vco_freq(pixel_freq, &vco_sel, &vco_div);
> +
> +       vc5_hdmi_reset_phy(vc4_hdmi);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
> +                  VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_RESET_CTL) &
> +                  ~VC4_HDMI_TX_PHY_RESET_CTL_TX_0_RESET &
> +                  ~VC4_HDMI_TX_PHY_RESET_CTL_TX_1_RESET &
> +                  ~VC4_HDMI_TX_PHY_RESET_CTL_TX_2_RESET &
> +                  ~VC4_HDMI_TX_PHY_RESET_CTL_TX_CK_RESET);
> +
> +       HDMI_WRITE(HDMI_RM_CONTROL,
> +                  HDMI_READ(HDMI_RM_CONTROL) |
> +                  VC4_HDMI_RM_CONTROL_EN_FREEZE_COUNTERS |
> +                  VC4_HDMI_RM_CONTROL_EN_LOAD_INTEGRATOR |
> +                  VC4_HDMI_RM_CONTROL_FREE_RUN);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1,
> +                  (HDMI_READ(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1) &
> +                   ~VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_MASK) |
> +                  VC4_SET_FIELD(0, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2,
> +                  (HDMI_READ(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2) &
> +                   ~VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_MASK) |
> +                  VC4_SET_FIELD(0, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT));
> +
> +       HDMI_WRITE(HDMI_RM_OFFSET,
> +                  VC4_SET_FIELD(phy_get_rm_offset(vco_freq),
> +                                VC4_HDMI_RM_OFFSET_OFFSET) |
> +                  VC4_HDMI_RM_OFFSET_ONLY);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CLK_DIV,
> +                  VC4_SET_FIELD(vco_div, VC4_HDMI_TX_PHY_CLK_DIV_VCO));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4,
> +                  VC4_SET_FIELD(0xe147, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD) |
> +                  VC4_SET_FIELD(0xe14, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CTL_0,
> +                  VC4_HDMI_TX_PHY_PLL_CTL_0_ENA_VCO_CLK |
> +                  VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_CONT_EN |
> +                  VC4_HDMI_TX_PHY_PLL_CTL_0_MASH11_MODE |
> +                  VC4_SET_FIELD(vco_sel, VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CTL_1,
> +                  HDMI_READ(HDMI_TX_PHY_PLL_CTL_1) |
> +                  VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_ENABLE |
> +                  VC4_SET_FIELD(3, VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL) |
> +                  VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY) |
> +                  VC4_SET_FIELD(0x8a, VC4_HDMI_TX_PHY_PLL_CTL_1_CPP));
> +
> +       HDMI_WRITE(HDMI_RM_FORMAT,
> +                  HDMI_READ(HDMI_RM_FORMAT) |
> +                  VC4_SET_FIELD(2, VC4_HDMI_RM_FORMAT_SHIFT));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CFG,
> +                  HDMI_READ(HDMI_TX_PHY_PLL_CFG) |
> +                  VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_PLL_CFG_PDIV));
> +
> +       if (pixel_freq >= 340000000)
> +               word_sel = 3;
> +       else
> +               word_sel = 0;
> +       HDMI_WRITE(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, word_sel);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CTL_3,
> +                  VC4_SET_FIELD(phy_get_cp_current(vco_freq),
> +                                VC4_HDMI_TX_PHY_CTL_3_ICP) |
> +                  VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_CTL_3_CP) |
> +                  VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_CTL_3_CP1) |
> +                  VC4_SET_FIELD(3, VC4_HDMI_TX_PHY_CTL_3_CZ) |
> +                  VC4_SET_FIELD(4, VC4_HDMI_TX_PHY_CTL_3_RP) |
> +                  VC4_SET_FIELD(6, VC4_HDMI_TX_PHY_CTL_3_RZ));
> +
> +       chan0_settings =
> +               phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_0],
> +                                        pixel_freq);
> +       chan1_settings =
> +               phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_1],
> +                                        pixel_freq);
> +       chan2_settings =
> +               phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_2],
> +                                        pixel_freq);
> +       clock_settings =
> +               phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_CK],
> +                                        pixel_freq);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CTL_0,
> +                  VC4_SET_FIELD(chan0_settings->amplitude.preemphasis,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP) |
> +                  VC4_SET_FIELD(chan0_settings->amplitude.main_driver,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV) |
> +                  VC4_SET_FIELD(chan1_settings->amplitude.preemphasis,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP) |
> +                  VC4_SET_FIELD(chan1_settings->amplitude.main_driver,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV) |
> +                  VC4_SET_FIELD(chan2_settings->amplitude.preemphasis,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP) |
> +                  VC4_SET_FIELD(chan2_settings->amplitude.main_driver,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV) |
> +                  VC4_SET_FIELD(clock_settings->amplitude.preemphasis,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP) |
> +                  VC4_SET_FIELD(clock_settings->amplitude.main_driver,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CTL_1,
> +                  HDMI_READ(HDMI_TX_PHY_CTL_1) |
> +                  VC4_SET_FIELD(chan0_settings->res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0) |
> +                  VC4_SET_FIELD(chan1_settings->res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1) |
> +                  VC4_SET_FIELD(chan2_settings->res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2) |
> +                  VC4_SET_FIELD(clock_settings->res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CTL_2,
> +                  VC4_SET_FIELD(chan0_settings->term_res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0) |
> +                  VC4_SET_FIELD(chan1_settings->term_res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1) |
> +                  VC4_SET_FIELD(chan2_settings->term_res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2) |
> +                  VC4_SET_FIELD(clock_settings->term_res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK) |
> +                  VC4_SET_FIELD(phy_get_vco_gain(vco_freq),
> +                                VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CHANNEL_SWAP,
> +                  VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_0],
> +                                VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL) |
> +                  VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_1],
> +                                VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL) |
> +                  VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_2],
> +                                VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL) |
> +                  VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_CK],
> +                                VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_RESET_CTL) &
> +                  ~(VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB |
> +                    VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_RESET_CTL) |
> +                  VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB |
> +                  VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB);
> +}
> +
> +void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi) {
> +       vc5_hdmi_reset_phy(vc4_hdmi);
> +}
> +
> +void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi)
> +{
> +       HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) &
> +                  ~VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
> +}
> +
> +void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi)
> +{
> +       HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) |
> +                  VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
> index bc47cc9bc883..a5f1354e3e06 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
> @@ -9,6 +9,12 @@ enum vc4_hdmi_regs {
>         VC4_INVALID = 0,
>         VC4_HDMI,
>         VC4_HD,
> +       VC5_CEC,
> +       VC5_CSC,
> +       VC5_DVP,
> +       VC5_PHY,
> +       VC5_RAM,
> +       VC5_RM,
>  };
>
>  enum vc4_hdmi_field {
> @@ -36,6 +42,7 @@ enum vc4_hdmi_field {
>         HDMI_CEC_TX_DATA_2,
>         HDMI_CEC_TX_DATA_3,
>         HDMI_CEC_TX_DATA_4,
> +       HDMI_CLOCK_STOP,
>         HDMI_CORE_REV,
>         HDMI_CRP_CFG,
>         HDMI_CSC_12_11,
> @@ -52,6 +59,7 @@ enum vc4_hdmi_field {
>          */
>         HDMI_CTS_0,
>         HDMI_CTS_1,
> +       HDMI_DVP_CTL,
>         HDMI_FIFO_CTL,
>         HDMI_FRAME_COUNT,
>         HDMI_HORZA,
> @@ -84,10 +92,27 @@ enum vc4_hdmi_field {
>         HDMI_RAM_PACKET_CONFIG,
>         HDMI_RAM_PACKET_START,
>         HDMI_RAM_PACKET_STATUS,
> +       HDMI_RM_CONTROL,
> +       HDMI_RM_FORMAT,
> +       HDMI_RM_OFFSET,
>         HDMI_SCHEDULER_CONTROL,
>         HDMI_SW_RESET_CONTROL,
> +       HDMI_TX_PHY_CHANNEL_SWAP,
> +       HDMI_TX_PHY_CLK_DIV,
>         HDMI_TX_PHY_CTL_0,
> +       HDMI_TX_PHY_CTL_1,
> +       HDMI_TX_PHY_CTL_2,
> +       HDMI_TX_PHY_CTL_3,
> +       HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1,
> +       HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2,
> +       HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4,
> +       HDMI_TX_PHY_PLL_CFG,
> +       HDMI_TX_PHY_PLL_CTL_0,
> +       HDMI_TX_PHY_PLL_CTL_1,
> +       HDMI_TX_PHY_POWERDOWN_CTL,
>         HDMI_TX_PHY_RESET_CTL,
> +       HDMI_TX_PHY_TMDS_CLK_WORD_SEL,
> +       HDMI_VEC_INTERFACE_XBAR,
>         HDMI_VERTA0,
>         HDMI_VERTA1,
>         HDMI_VERTB0,
> @@ -110,6 +135,12 @@ struct vc4_hdmi_register {
>
>  #define VC4_HD_REG(reg, offset)                _VC4_REG(VC4_HD, reg, offset)
>  #define VC4_HDMI_REG(reg, offset)      _VC4_REG(VC4_HDMI, reg, offset)
> +#define VC5_CEC_REG(reg, offset)       _VC4_REG(VC5_CEC, reg, offset)
> +#define VC5_CSC_REG(reg, offset)       _VC4_REG(VC5_CSC, reg, offset)
> +#define VC5_DVP_REG(reg, offset)       _VC4_REG(VC5_DVP, reg, offset)
> +#define VC5_PHY_REG(reg, offset)       _VC4_REG(VC5_PHY, reg, offset)
> +#define VC5_RAM_REG(reg, offset)       _VC4_REG(VC5_RAM, reg, offset)
> +#define VC5_RM_REG(reg, offset)                _VC4_REG(VC5_RM, reg, offset)
>
>  static const struct vc4_hdmi_register vc4_hdmi_fields[] = {
>         VC4_HD_REG(HDMI_M_CTL, 0x000c),
> @@ -172,6 +203,158 @@ static const struct vc4_hdmi_register vc4_hdmi_fields[] = {
>         VC4_HDMI_REG(HDMI_RAM_PACKET_START, 0x0400),
>  };
>
> +static const struct vc4_hdmi_register vc5_hdmi_hdmi0_fields[] = {
> +       VC4_HD_REG(HDMI_DVP_CTL, 0x0000),
> +       VC4_HD_REG(HDMI_MAI_CTL, 0x0010),
> +       VC4_HD_REG(HDMI_MAI_THR, 0x0014),
> +       VC4_HD_REG(HDMI_MAI_FMT, 0x0018),
> +       VC4_HD_REG(HDMI_MAI_DATA, 0x001c),
> +       VC4_HD_REG(HDMI_MAI_SMP, 0x0020),
> +       VC4_HD_REG(HDMI_VID_CTL, 0x0044),
> +       VC4_HD_REG(HDMI_FRAME_COUNT, 0x0060),
> +
> +       VC4_HDMI_REG(HDMI_FIFO_CTL, 0x074),
> +       VC4_HDMI_REG(HDMI_AUDIO_PACKET_CONFIG, 0x0b8),
> +       VC4_HDMI_REG(HDMI_RAM_PACKET_CONFIG, 0x0bc),
> +       VC4_HDMI_REG(HDMI_RAM_PACKET_STATUS, 0x0c4),
> +       VC4_HDMI_REG(HDMI_CRP_CFG, 0x0c8),
> +       VC4_HDMI_REG(HDMI_CTS_0, 0x0cc),
> +       VC4_HDMI_REG(HDMI_CTS_1, 0x0d0),
> +       VC4_HDMI_REG(HDMI_SCHEDULER_CONTROL, 0x0e0),
> +       VC4_HDMI_REG(HDMI_HORZA, 0x0e4),
> +       VC4_HDMI_REG(HDMI_HORZB, 0x0e8),
> +       VC4_HDMI_REG(HDMI_VERTA0, 0x0ec),
> +       VC4_HDMI_REG(HDMI_VERTB0, 0x0f0),
> +       VC4_HDMI_REG(HDMI_VERTA1, 0x0f4),
> +       VC4_HDMI_REG(HDMI_VERTB1, 0x0f8),
> +       VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c),
> +       VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
> +       VC4_HDMI_REG(HDMI_HOTPLUG, 0x1a8),
> +
> +       VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
> +       VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0),
> +
> +       VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000),
> +       VC5_PHY_REG(HDMI_TX_PHY_POWERDOWN_CTL, 0x004),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_0, 0x008),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_1, 0x00c),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_2, 0x010),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_3, 0x014),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_0, 0x01c),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_1, 0x020),
> +       VC5_PHY_REG(HDMI_TX_PHY_CLK_DIV, 0x028),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CFG, 0x034),
> +       VC5_PHY_REG(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, 0x044),
> +       VC5_PHY_REG(HDMI_TX_PHY_CHANNEL_SWAP, 0x04c),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1, 0x050),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2, 0x054),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4, 0x05c),
> +
> +       VC5_RM_REG(HDMI_RM_CONTROL, 0x000),
> +       VC5_RM_REG(HDMI_RM_OFFSET, 0x018),
> +       VC5_RM_REG(HDMI_RM_FORMAT, 0x01c),
> +
> +       VC5_RAM_REG(HDMI_RAM_PACKET_START, 0x000),
> +
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_1, 0x010),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_2, 0x014),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_3, 0x018),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_4, 0x01c),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_5, 0x020),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_1, 0x028),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_2, 0x02c),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_3, 0x030),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_4, 0x034),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_1, 0x038),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_2, 0x03c),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_3, 0x040),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_4, 0x044),
> +
> +       VC5_CSC_REG(HDMI_CSC_CTL, 0x000),
> +       VC5_CSC_REG(HDMI_CSC_12_11, 0x004),
> +       VC5_CSC_REG(HDMI_CSC_14_13, 0x008),
> +       VC5_CSC_REG(HDMI_CSC_22_21, 0x00c),
> +       VC5_CSC_REG(HDMI_CSC_24_23, 0x010),
> +       VC5_CSC_REG(HDMI_CSC_32_31, 0x014),
> +       VC5_CSC_REG(HDMI_CSC_34_33, 0x018),
> +};
> +
> +static const struct vc4_hdmi_register vc5_hdmi_hdmi1_fields[] = {
> +       VC4_HD_REG(HDMI_DVP_CTL, 0x0000),
> +       VC4_HD_REG(HDMI_MAI_CTL, 0x0030),
> +       VC4_HD_REG(HDMI_MAI_THR, 0x0034),
> +       VC4_HD_REG(HDMI_MAI_FMT, 0x0038),
> +       VC4_HD_REG(HDMI_MAI_DATA, 0x003c),
> +       VC4_HD_REG(HDMI_MAI_SMP, 0x0040),
> +       VC4_HD_REG(HDMI_VID_CTL, 0x0048),
> +       VC4_HD_REG(HDMI_FRAME_COUNT, 0x0064),
> +
> +       VC4_HDMI_REG(HDMI_FIFO_CTL, 0x074),
> +       VC4_HDMI_REG(HDMI_AUDIO_PACKET_CONFIG, 0x0b8),
> +       VC4_HDMI_REG(HDMI_RAM_PACKET_CONFIG, 0x0bc),
> +       VC4_HDMI_REG(HDMI_RAM_PACKET_STATUS, 0x0c4),
> +       VC4_HDMI_REG(HDMI_CRP_CFG, 0x0c8),
> +       VC4_HDMI_REG(HDMI_CTS_0, 0x0cc),
> +       VC4_HDMI_REG(HDMI_CTS_1, 0x0d0),
> +       VC4_HDMI_REG(HDMI_SCHEDULER_CONTROL, 0x0e0),
> +       VC4_HDMI_REG(HDMI_HORZA, 0x0e4),
> +       VC4_HDMI_REG(HDMI_HORZB, 0x0e8),
> +       VC4_HDMI_REG(HDMI_VERTA0, 0x0ec),
> +       VC4_HDMI_REG(HDMI_VERTB0, 0x0f0),
> +       VC4_HDMI_REG(HDMI_VERTA1, 0x0f4),
> +       VC4_HDMI_REG(HDMI_VERTB1, 0x0f8),
> +       VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c),
> +       VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
> +       VC4_HDMI_REG(HDMI_HOTPLUG, 0x1a8),
> +
> +       VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
> +       VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0),
> +
> +       VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000),
> +       VC5_PHY_REG(HDMI_TX_PHY_POWERDOWN_CTL, 0x004),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_0, 0x008),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_1, 0x00c),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_2, 0x010),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_3, 0x014),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_0, 0x01c),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_1, 0x020),
> +       VC5_PHY_REG(HDMI_TX_PHY_CLK_DIV, 0x028),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CFG, 0x034),
> +       VC5_PHY_REG(HDMI_TX_PHY_CHANNEL_SWAP, 0x04c),
> +       VC5_PHY_REG(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, 0x044),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1, 0x050),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2, 0x054),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4, 0x05c),
> +
> +       VC5_RM_REG(HDMI_RM_CONTROL, 0x000),
> +       VC5_RM_REG(HDMI_RM_OFFSET, 0x018),
> +       VC5_RM_REG(HDMI_RM_FORMAT, 0x01c),
> +
> +       VC5_RAM_REG(HDMI_RAM_PACKET_START, 0x000),
> +
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_1, 0x010),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_2, 0x014),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_3, 0x018),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_4, 0x01c),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_5, 0x020),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_1, 0x028),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_2, 0x02c),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_3, 0x030),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_4, 0x034),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_1, 0x038),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_2, 0x03c),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_3, 0x040),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_4, 0x044),
> +
> +       VC5_CSC_REG(HDMI_CSC_CTL, 0x000),
> +       VC5_CSC_REG(HDMI_CSC_12_11, 0x004),
> +       VC5_CSC_REG(HDMI_CSC_14_13, 0x008),
> +       VC5_CSC_REG(HDMI_CSC_22_21, 0x00c),
> +       VC5_CSC_REG(HDMI_CSC_24_23, 0x010),
> +       VC5_CSC_REG(HDMI_CSC_32_31, 0x014),
> +       VC5_CSC_REG(HDMI_CSC_34_33, 0x018),
> +};
> +
>  static inline
>  void __iomem *__vc4_hdmi_get_field_base(struct vc4_hdmi *hdmi,
>                                         enum vc4_hdmi_regs reg)
> @@ -183,6 +366,24 @@ void __iomem *__vc4_hdmi_get_field_base(struct vc4_hdmi *hdmi,
>         case VC4_HDMI:
>                 return hdmi->hdmicore_regs;
>
> +       case VC5_CSC:
> +               return hdmi->csc_regs;
> +
> +       case VC5_CEC:
> +               return hdmi->cec_regs;
> +
> +       case VC5_DVP:
> +               return hdmi->dvp_regs;
> +
> +       case VC5_PHY:
> +               return hdmi->phy_regs;
> +
> +       case VC5_RAM:
> +               return hdmi->ram_regs;
> +
> +       case VC5_RM:
> +               return hdmi->rm_regs;
> +
>         default:
>                 return NULL;
>         }
> diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
> index 30af52b406f1..be2c32a519b3 100644
> --- a/drivers/gpu/drm/vc4/vc4_regs.h
> +++ b/drivers/gpu/drm/vc4/vc4_regs.h
> @@ -744,6 +744,8 @@
>  # define VC4_HD_CSC_CTL_RGB2YCC                        BIT(1)
>  # define VC4_HD_CSC_CTL_ENABLE                 BIT(0)
>
> +# define VC4_DVP_HT_CLOCK_STOP_PIXEL           BIT(1)
> +
>  /* HVS display list information. */
>  #define HVS_BOOTLOADER_DLIST_END                32
>
> --
> git-series 0.9.1

WARNING: multiple messages have this Message-ID (diff)
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
To: Maxime Ripard <maxime@cerno.tech>
Cc: Tim Gover <tim.gover@raspberrypi.com>,
	LKML <linux-kernel@vger.kernel.org>,
	DRI Development <dri-devel@lists.freedesktop.org>,
	Eric Anholt <eric@anholt.net>,
	bcm-kernel-feedback-list@broadcom.com,
	Nicolas Saenz Julienne <nsaenzjulienne@suse.de>,
	Phil Elwell <phil@raspberrypi.com>,
	linux-arm-kernel@lists.infradead.org,
	linux-rpi-kernel@lists.infradead.org
Subject: Re: [PATCH v4 74/78] drm/vc4: hdmi: Support the BCM2711 HDMI controllers
Date: Tue, 28 Jul 2020 16:21:56 +0100	[thread overview]
Message-ID: <CAPY8ntA0UixNWc27-x0Y5AG_pXvzh=5spHwQ5poYLEqDzSS0WA@mail.gmail.com> (raw)
In-Reply-To: <37e2291033dc5f012248efc641ca796101470b45.1594230107.git-series.maxime@cerno.tech>

Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard <maxime@cerno.tech> wrote:
>
> Now that the driver is ready for it, let's bring in the HDMI controllers
> variants for the BCM2711.
>
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>

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

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c      | 278 +++++++++++++++++-
>  drivers/gpu/drm/vc4/vc4_hdmi.h      |  36 ++-
>  drivers/gpu/drm/vc4/vc4_hdmi_phy.c  | 480 +++++++++++++++++++++++++++++-
>  drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 201 ++++++++++++-
>  drivers/gpu/drm/vc4/vc4_regs.h      |   2 +-
>  5 files changed, 997 insertions(+)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 37463b016b47..d5ba0b1b73a9 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -43,6 +43,7 @@
>  #include <linux/of_platform.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/rational.h>
> +#include <linux/reset.h>
>  #include <sound/dmaengine_pcm.h>
>  #include <sound/pcm_drm_eld.h>
>  #include <sound/pcm_params.h>
> @@ -53,6 +54,31 @@
>  #include "vc4_hdmi_regs.h"
>  #include "vc4_regs.h"
>
> +#define VC5_HDMI_HORZA_HFP_SHIFT               16
> +#define VC5_HDMI_HORZA_HFP_MASK                        VC4_MASK(28, 16)
> +#define VC5_HDMI_HORZA_VPOS                    BIT(15)
> +#define VC5_HDMI_HORZA_HPOS                    BIT(14)
> +#define VC5_HDMI_HORZA_HAP_SHIFT               0
> +#define VC5_HDMI_HORZA_HAP_MASK                        VC4_MASK(13, 0)
> +
> +#define VC5_HDMI_HORZB_HBP_SHIFT               16
> +#define VC5_HDMI_HORZB_HBP_MASK                        VC4_MASK(26, 16)
> +#define VC5_HDMI_HORZB_HSP_SHIFT               0
> +#define VC5_HDMI_HORZB_HSP_MASK                        VC4_MASK(10, 0)
> +
> +#define VC5_HDMI_VERTA_VSP_SHIFT               24
> +#define VC5_HDMI_VERTA_VSP_MASK                        VC4_MASK(28, 24)
> +#define VC5_HDMI_VERTA_VFP_SHIFT               16
> +#define VC5_HDMI_VERTA_VFP_MASK                        VC4_MASK(22, 16)
> +#define VC5_HDMI_VERTA_VAL_SHIFT               0
> +#define VC5_HDMI_VERTA_VAL_MASK                        VC4_MASK(12, 0)
> +
> +#define VC5_HDMI_VERTB_VSPO_SHIFT              16
> +#define VC5_HDMI_VERTB_VSPO_MASK               VC4_MASK(29, 16)
> +
> +# define VC4_HD_M_SW_RST                       BIT(2)
> +# define VC4_HD_M_ENABLE                       BIT(0)
> +
>  #define CEC_CLOCK_FREQ 40000
>
>  static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
> @@ -82,6 +108,16 @@ static void vc4_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
>         HDMI_WRITE(HDMI_SW_RESET_CONTROL, 0);
>  }
>
> +static void vc5_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
> +{
> +       reset_control_reset(vc4_hdmi->reset);
> +
> +       HDMI_WRITE(HDMI_DVP_CTL, 0);
> +
> +       HDMI_WRITE(HDMI_CLOCK_STOP,
> +                  HDMI_READ(HDMI_CLOCK_STOP) | VC4_DVP_HT_CLOCK_STOP_PIXEL);
> +}
> +
>  static enum drm_connector_status
>  vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> @@ -391,6 +427,45 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
>         HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
>  }
>
> +static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
> +{
> +       u32 csc_ctl;
> +
> +       csc_ctl = 0x07; /* RGB_CONVERT_MODE = custom matrix, || USE_RGB_TO_YCBCR */
> +
> +       if (enable) {
> +               /* CEA VICs other than #1 requre limited range RGB
> +                * output unless overridden by an AVI infoframe.
> +                * Apply a colorspace conversion to squash 0-255 down
> +                * to 16-235.  The matrix here is:
> +                *
> +                * [ 0.8594 0      0      16]
> +                * [ 0      0.8594 0      16]
> +                * [ 0      0      0.8594 16]
> +                * [ 0      0      0       1]
> +                * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
> +                */
> +               HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x1b80);
> +               HDMI_WRITE(HDMI_CSC_14_13, (0x0400 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_22_21, (0x1b80 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_24_23, (0x0400 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_34_33, (0x0400 << 16) | 0x1b80);
> +       } else {
> +               /* Still use the matrix for full range, but make it unity.
> +                * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
> +                */
> +               HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x2000);
> +               HDMI_WRITE(HDMI_CSC_14_13, (0x0000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_22_21, (0x2000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_24_23, (0x0000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_34_33, (0x0000 << 16) | 0x2000);
> +       }
> +
> +       HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
> +}
> +
>  static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
>                                  struct drm_display_mode *mode)
>  {
> @@ -435,6 +510,53 @@ static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
>         HDMI_WRITE(HDMI_VERTB0, vertb_even);
>         HDMI_WRITE(HDMI_VERTB1, vertb);
>  }
> +static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
> +                                struct drm_display_mode *mode)
> +{
> +       bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
> +       bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
> +       bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
> +       u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
> +       u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
> +                                  VC5_HDMI_VERTA_VSP) |
> +                    VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
> +                                  VC5_HDMI_VERTA_VFP) |
> +                    VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL));
> +       u32 vertb = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
> +                    VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
> +                                  VC4_HDMI_VERTB_VBP));
> +       u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
> +                         VC4_SET_FIELD(mode->crtc_vtotal -
> +                                       mode->crtc_vsync_end -
> +                                       interlaced,
> +                                       VC4_HDMI_VERTB_VBP));
> +
> +       HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021);
> +       HDMI_WRITE(HDMI_HORZA,
> +                  (vsync_pos ? VC5_HDMI_HORZA_VPOS : 0) |
> +                  (hsync_pos ? VC5_HDMI_HORZA_HPOS : 0) |
> +                  VC4_SET_FIELD(mode->hdisplay * pixel_rep,
> +                                VC5_HDMI_HORZA_HAP) |
> +                  VC4_SET_FIELD((mode->hsync_start -
> +                                 mode->hdisplay) * pixel_rep,
> +                                VC5_HDMI_HORZA_HFP));
> +
> +       HDMI_WRITE(HDMI_HORZB,
> +                  VC4_SET_FIELD((mode->htotal -
> +                                 mode->hsync_end) * pixel_rep,
> +                                VC5_HDMI_HORZB_HBP) |
> +                  VC4_SET_FIELD((mode->hsync_end -
> +                                 mode->hsync_start) * pixel_rep,
> +                                VC5_HDMI_HORZB_HSP));
> +
> +       HDMI_WRITE(HDMI_VERTA0, verta);
> +       HDMI_WRITE(HDMI_VERTA1, verta);
> +
> +       HDMI_WRITE(HDMI_VERTB0, vertb_even);
> +       HDMI_WRITE(HDMI_VERTB1, vertb);
> +
> +       HDMI_WRITE(HDMI_CLOCK_STOP, 0);
> +}
>
>  static void vc4_hdmi_recenter_fifo(struct vc4_hdmi *vc4_hdmi)
>  {
> @@ -645,6 +767,18 @@ static u32 vc4_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
>         return channel_map;
>  }
>
> +static u32 vc5_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
> +{
> +       int i;
> +       u32 channel_map = 0;
> +
> +       for (i = 0; i < 8; i++) {
> +               if (channel_mask & BIT(i))
> +                       channel_map |= i << (4 * i);
> +       }
> +       return channel_map;
> +}
> +
>  /* HDMI audio codec callbacks */
>  static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *vc4_hdmi)
>  {
> @@ -1377,6 +1511,98 @@ static int vc4_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
>         return 0;
>  }
>
> +static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
> +{
> +       struct platform_device *pdev = vc4_hdmi->pdev;
> +       struct device *dev = &pdev->dev;
> +       struct resource *res;
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->hdmicore_regs = devm_ioremap(dev, res->start,
> +                                              resource_size(res));
> +       if (IS_ERR(vc4_hdmi->hdmicore_regs))
> +               return PTR_ERR(vc4_hdmi->hdmicore_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hd");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->hd_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->hd_regs))
> +               return PTR_ERR(vc4_hdmi->hd_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cec");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->cec_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->cec_regs))
> +               return PTR_ERR(vc4_hdmi->cec_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csc");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->csc_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->csc_regs))
> +               return PTR_ERR(vc4_hdmi->csc_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dvp");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->dvp_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->dvp_regs))
> +               return PTR_ERR(vc4_hdmi->dvp_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->phy_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->phy_regs))
> +               return PTR_ERR(vc4_hdmi->phy_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "packet");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->ram_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->ram_regs))
> +               return PTR_ERR(vc4_hdmi->ram_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rm");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->rm_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->rm_regs))
> +               return PTR_ERR(vc4_hdmi->rm_regs);
> +
> +       vc4_hdmi->hsm_clock = devm_clk_get(dev, "hdmi");
> +       if (IS_ERR(vc4_hdmi->hsm_clock)) {
> +               DRM_ERROR("Failed to get HDMI state machine clock\n");
> +               return PTR_ERR(vc4_hdmi->hsm_clock);
> +       }
> +
> +       vc4_hdmi->audio_clock = devm_clk_get(dev, "clk-108M");
> +       if (IS_ERR(vc4_hdmi->audio_clock)) {
> +               DRM_ERROR("Failed to get 108MHz clock\n");
> +               return PTR_ERR(vc4_hdmi->audio_clock);
> +       }
> +
> +       vc4_hdmi->reset = devm_reset_control_get(dev, NULL);
> +       if (IS_ERR(vc4_hdmi->reset)) {
> +               DRM_ERROR("Failed to get HDMI reset line\n");
> +               return PTR_ERR(vc4_hdmi->reset);
> +       }
> +
> +       return 0;
> +}
> +
>  static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
>  {
>         const struct vc4_hdmi_variant *variant = of_device_get_match_data(dev);
> @@ -1547,8 +1773,60 @@ static const struct vc4_hdmi_variant bcm2835_variant = {
>         .channel_map            = vc4_hdmi_channel_map,
>  };
>
> +static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = {
> +       .encoder_type           = VC4_ENCODER_TYPE_HDMI0,
> +       .debugfs_name           = "hdmi0_regs",
> +       .card_name              = "vc4-hdmi-0",
> +       .max_pixel_clock        = 297000000,
> +       .registers              = vc5_hdmi_hdmi0_fields,
> +       .num_registers          = ARRAY_SIZE(vc5_hdmi_hdmi0_fields),
> +       .phy_lane_mapping       = {
> +               PHY_LANE_0,
> +               PHY_LANE_1,
> +               PHY_LANE_2,
> +               PHY_LANE_CK,
> +       },
> +
> +       .init_resources         = vc5_hdmi_init_resources,
> +       .csc_setup              = vc5_hdmi_csc_setup,
> +       .reset                  = vc5_hdmi_reset,
> +       .set_timings            = vc5_hdmi_set_timings,
> +       .phy_init               = vc5_hdmi_phy_init,
> +       .phy_disable            = vc5_hdmi_phy_disable,
> +       .phy_rng_enable         = vc5_hdmi_phy_rng_enable,
> +       .phy_rng_disable        = vc5_hdmi_phy_rng_disable,
> +       .channel_map            = vc5_hdmi_channel_map,
> +};
> +
> +static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = {
> +       .encoder_type           = VC4_ENCODER_TYPE_HDMI1,
> +       .debugfs_name           = "hdmi1_regs",
> +       .card_name              = "vc4-hdmi-1",
> +       .max_pixel_clock        = 297000000,
> +       .registers              = vc5_hdmi_hdmi1_fields,
> +       .num_registers          = ARRAY_SIZE(vc5_hdmi_hdmi1_fields),
> +       .phy_lane_mapping       = {
> +               PHY_LANE_1,
> +               PHY_LANE_0,
> +               PHY_LANE_CK,
> +               PHY_LANE_2,
> +       },
> +
> +       .init_resources         = vc5_hdmi_init_resources,
> +       .csc_setup              = vc5_hdmi_csc_setup,
> +       .reset                  = vc5_hdmi_reset,
> +       .set_timings            = vc5_hdmi_set_timings,
> +       .phy_init               = vc5_hdmi_phy_init,
> +       .phy_disable            = vc5_hdmi_phy_disable,
> +       .phy_rng_enable         = vc5_hdmi_phy_rng_enable,
> +       .phy_rng_disable        = vc5_hdmi_phy_rng_disable,
> +       .channel_map            = vc5_hdmi_channel_map,
> +};
> +
>  static const struct of_device_id vc4_hdmi_dt_match[] = {
>         { .compatible = "brcm,bcm2835-hdmi", .data = &bcm2835_variant },
> +       { .compatible = "brcm,bcm2711-hdmi0", .data = &bcm2711_hdmi0_variant },
> +       { .compatible = "brcm,bcm2711-hdmi1", .data = &bcm2711_hdmi1_variant },
>         {}
>  };
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index 34138e0dd4a6..0806c6d9f24e 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -26,6 +26,13 @@ struct drm_display_mode;
>  struct vc4_hdmi;
>  struct vc4_hdmi_register;
>
> +enum vc4_hdmi_phy_channel {
> +       PHY_LANE_0 = 0,
> +       PHY_LANE_1,
> +       PHY_LANE_2,
> +       PHY_LANE_CK,
> +};
> +
>  struct vc4_hdmi_variant {
>         /* Encoder Type for that controller */
>         enum vc4_encoder_type encoder_type;
> @@ -48,6 +55,13 @@ struct vc4_hdmi_variant {
>         /* Number of registers on that variant */
>         unsigned int num_registers;
>
> +       /* BCM2711 Only.
> +        * The variants don't map the lane in the same order in the
> +        * PHY, so this is an array mapping the HDMI channel (index)
> +        * to the PHY lane (value).
> +        */
> +       enum vc4_hdmi_phy_channel phy_lane_mapping[4];
> +
>         /* Callback to get the resources (memory region, interrupts,
>          * clocks, etc) for that variant.
>          */
> @@ -108,6 +122,20 @@ struct vc4_hdmi {
>         struct i2c_adapter *ddc;
>         void __iomem *hdmicore_regs;
>         void __iomem *hd_regs;
> +
> +       /* VC5 Only */
> +       void __iomem *cec_regs;
> +       /* VC5 Only */
> +       void __iomem *csc_regs;
> +       /* VC5 Only */
> +       void __iomem *dvp_regs;
> +       /* VC5 Only */
> +       void __iomem *phy_regs;
> +       /* VC5 Only */
> +       void __iomem *ram_regs;
> +       /* VC5 Only */
> +       void __iomem *rm_regs;
> +
>         int hpd_gpio;
>         bool hpd_active_low;
>
> @@ -120,6 +148,8 @@ struct vc4_hdmi {
>         struct clk *hsm_clock;
>         struct clk *audio_clock;
>
> +       struct reset_control *reset;
> +
>         struct debugfs_regset32 hdmi_regset;
>         struct debugfs_regset32 hd_regset;
>  };
> @@ -144,4 +174,10 @@ void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
>  void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
>  void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
>
> +void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
> +                      struct drm_display_mode *mode);
> +void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
> +void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
> +void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
> +
>  #endif /* _VC4_HDMI_H_ */
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> index 93287e24d7d1..4d36f8c33401 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> @@ -10,6 +10,123 @@
>  #include "vc4_regs.h"
>  #include "vc4_hdmi_regs.h"
>
> +#define VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB   BIT(5)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB        BIT(4)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_TX_CK_RESET  BIT(3)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_TX_2_RESET   BIT(2)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_TX_1_RESET   BIT(1)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_TX_0_RESET   BIT(0)
> +
> +#define VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN     BIT(4)
> +
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP_SHIFT    29
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP_MASK     VC4_MASK(31, 29)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV_SHIFT   24
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV_MASK    VC4_MASK(28, 24)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP_SHIFT    21
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP_MASK     VC4_MASK(23, 21)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV_SHIFT   16
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV_MASK    VC4_MASK(20, 16)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP_SHIFT    13
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP_MASK     VC4_MASK(15, 13)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV_SHIFT   8
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV_MASK    VC4_MASK(12, 8)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP_SHIFT   5
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP_MASK    VC4_MASK(7, 5)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV_SHIFT  0
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV_MASK   VC4_MASK(4, 0)
> +
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2_SHIFT      15
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2_MASK       VC4_MASK(19, 15)
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1_SHIFT      10
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1_MASK       VC4_MASK(14, 10)
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0_SHIFT      5
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0_MASK       VC4_MASK(9, 5)
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK_SHIFT         0
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK_MASK          VC4_MASK(4, 0)
> +
> +#define VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN_SHIFT           16
> +#define VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN_MASK            VC4_MASK(19, 16)
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2_SHIFT  12
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2_MASK   VC4_MASK(15, 12)
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1_SHIFT  8
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1_MASK   VC4_MASK(11, 8)
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0_SHIFT  4
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0_MASK   VC4_MASK(7, 4)
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK_SHIFT     0
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK_MASK      VC4_MASK(3, 0)
> +
> +#define VC4_HDMI_TX_PHY_CTL_3_RP_SHIFT                 17
> +#define VC4_HDMI_TX_PHY_CTL_3_RP_MASK                  VC4_MASK(19, 17)
> +#define VC4_HDMI_TX_PHY_CTL_3_RZ_SHIFT                 12
> +#define VC4_HDMI_TX_PHY_CTL_3_RZ_MASK                  VC4_MASK(16, 12)
> +#define VC4_HDMI_TX_PHY_CTL_3_CP1_SHIFT                        10
> +#define VC4_HDMI_TX_PHY_CTL_3_CP1_MASK                 VC4_MASK(11, 10)
> +#define VC4_HDMI_TX_PHY_CTL_3_CP_SHIFT                 8
> +#define VC4_HDMI_TX_PHY_CTL_3_CP_MASK                  VC4_MASK(9, 8)
> +#define VC4_HDMI_TX_PHY_CTL_3_CZ_SHIFT                 6
> +#define VC4_HDMI_TX_PHY_CTL_3_CZ_MASK                  VC4_MASK(7, 6)
> +#define VC4_HDMI_TX_PHY_CTL_3_ICP_SHIFT                        0
> +#define VC4_HDMI_TX_PHY_CTL_3_ICP_MASK                 VC4_MASK(5, 0)
> +
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_MASH11_MODE          BIT(13)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VC_RANGE_EN          BIT(12)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_EMULATE_VC_LOW       BIT(11)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_EMULATE_VC_HIGH      BIT(10)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL_SHIFT                9
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL_MASK         VC4_MASK(9, 9)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_FB_DIV2          BIT(8)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_POST_DIV2                BIT(7)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_CONT_EN          BIT(6)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_ENA_VCO_CLK          BIT(5)
> +
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_CPP_SHIFT                    16
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_CPP_MASK                     VC4_MASK(27, 16)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY_SHIFT     14
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY_MASK      VC4_MASK(15, 14)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_ENABLE          BIT(13)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL_SHIFT           11
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL_MASK            VC4_MASK(12, 11)
> +
> +#define VC4_HDMI_TX_PHY_CLK_DIV_VCO_SHIFT              8
> +#define VC4_HDMI_TX_PHY_CLK_DIV_VCO_MASK               VC4_MASK(15, 8)
> +
> +#define VC4_HDMI_TX_PHY_PLL_CFG_PDIV_SHIFT             0
> +#define VC4_HDMI_TX_PHY_PLL_CFG_PDIV_MASK              VC4_MASK(3, 0)
> +
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL_MASK VC4_MASK(13, 12)
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL_SHIFT        12
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL_MASK  VC4_MASK(9, 8)
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL_SHIFT 8
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL_MASK  VC4_MASK(5, 4)
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL_SHIFT 4
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL_MASK  VC4_MASK(1, 0)
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL_SHIFT 0
> +
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_MASK                VC4_MASK(27, 0)
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_SHIFT       0
> +
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_MASK                VC4_MASK(27, 0)
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_SHIFT       0
> +
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD_MASK VC4_MASK(31, 16)
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD_SHIFT        16
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD_MASK   VC4_MASK(15, 0)
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD_SHIFT  0
> +
> +#define VC4_HDMI_RM_CONTROL_EN_FREEZE_COUNTERS         BIT(19)
> +#define VC4_HDMI_RM_CONTROL_EN_LOAD_INTEGRATOR         BIT(17)
> +#define VC4_HDMI_RM_CONTROL_FREE_RUN                   BIT(4)
> +
> +#define VC4_HDMI_RM_OFFSET_ONLY                                BIT(31)
> +#define VC4_HDMI_RM_OFFSET_OFFSET_SHIFT                        0
> +#define VC4_HDMI_RM_OFFSET_OFFSET_MASK                 VC4_MASK(30, 0)
> +
> +#define VC4_HDMI_RM_FORMAT_SHIFT_SHIFT                 24
> +#define VC4_HDMI_RM_FORMAT_SHIFT_MASK                  VC4_MASK(25, 24)
> +
> +#define OSCILLATOR_FREQUENCY   54000000
> +
>  void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, struct drm_display_mode *mode)
>  {
>         /* PHY should be in reset, like
> @@ -38,3 +155,366 @@ void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi)
>                    HDMI_READ(HDMI_TX_PHY_CTL_0) |
>                    VC4_HDMI_TX_PHY_RNG_PWRDN);
>  }
> +
> +static unsigned long long
> +phy_get_vco_freq(unsigned long long clock, u8 *vco_sel, u8 *vco_div)
> +{
> +       unsigned long long vco_freq = clock;
> +       unsigned int _vco_div = 0;
> +       unsigned int _vco_sel = 0;
> +
> +       while (vco_freq < 3000000000ULL) {
> +               _vco_div++;
> +               vco_freq = clock * _vco_div * 10;
> +       }
> +
> +       if (vco_freq > 4500000000ULL)
> +               _vco_sel = 1;
> +
> +       *vco_sel = _vco_sel;
> +       *vco_div = _vco_div;
> +
> +       return vco_freq;
> +}
> +
> +static u8 phy_get_cp_current(unsigned long vco_freq)
> +{
> +       if (vco_freq < 3700000000ULL)
> +               return 0x1c;
> +
> +       return 0x18;
> +}
> +
> +static u32 phy_get_rm_offset(unsigned long long vco_freq)
> +{
> +       unsigned long long fref = OSCILLATOR_FREQUENCY;
> +       u64 offset = 0;
> +
> +       /* RM offset is stored as 9.22 format */
> +       offset = vco_freq * 2;
> +       offset = offset << 22;
> +       do_div(offset, fref);
> +       offset >>= 2;
> +
> +       return offset;
> +}
> +
> +static u8 phy_get_vco_gain(unsigned long long vco_freq)
> +{
> +       if (vco_freq < 3350000000ULL)
> +               return 0xf;
> +
> +       if (vco_freq < 3700000000ULL)
> +               return 0xc;
> +
> +       if (vco_freq < 4050000000ULL)
> +               return 0x6;
> +
> +       if (vco_freq < 4800000000ULL)
> +               return 0x5;
> +
> +       if (vco_freq < 5200000000ULL)
> +               return 0x7;
> +
> +       return 0x2;
> +}
> +
> +struct phy_lane_settings {
> +       struct {
> +               u8 preemphasis;
> +               u8 main_driver;
> +       } amplitude;
> +
> +       u8 res_sel_data;
> +       u8 term_res_sel_data;
> +};
> +
> +struct phy_settings {
> +       unsigned long long min_rate;
> +       unsigned long long max_rate;
> +       struct phy_lane_settings channel[3];
> +       struct phy_lane_settings clock;
> +};
> +
> +static const struct phy_settings vc5_hdmi_phy_settings[] = {
> +       {
> +               0, 50000000,
> +               {
> +                       {{0x0, 0x0A}, 0x12, 0x0},
> +                       {{0x0, 0x0A}, 0x12, 0x0},
> +                       {{0x0, 0x0A}, 0x12, 0x0}
> +               },
> +               {{0x0, 0x0A}, 0x18, 0x0},
> +       },
> +       {
> +               50000001, 75000000,
> +               {
> +                       {{0x0, 0x09}, 0x12, 0x0},
> +                       {{0x0, 0x09}, 0x12, 0x0},
> +                       {{0x0, 0x09}, 0x12, 0x0}
> +               },
> +               {{0x0, 0x0C}, 0x18, 0x3},
> +       },
> +       {
> +               75000001,   165000000,
> +               {
> +                       {{0x0, 0x09}, 0x12, 0x0},
> +                       {{0x0, 0x09}, 0x12, 0x0},
> +                       {{0x0, 0x09}, 0x12, 0x0}
> +               },
> +               {{0x0, 0x0C}, 0x18, 0x3},
> +       },
> +       {
> +               165000001,  250000000,
> +               {
> +                       {{0x0, 0x0F}, 0x12, 0x1},
> +                       {{0x0, 0x0F}, 0x12, 0x1},
> +                       {{0x0, 0x0F}, 0x12, 0x1}
> +               },
> +               {{0x0, 0x0C}, 0x18, 0x3},
> +       },
> +       {
> +               250000001,  340000000,
> +               {
> +                       {{0x2, 0x0D}, 0x12, 0x1},
> +                       {{0x2, 0x0D}, 0x12, 0x1},
> +                       {{0x2, 0x0D}, 0x12, 0x1}
> +               },
> +               {{0x0, 0x0C}, 0x18, 0xF},
> +       },
> +       {
> +               340000001,  450000000,
> +               {
> +                       {{0x0, 0x1B}, 0x12, 0xF},
> +                       {{0x0, 0x1B}, 0x12, 0xF},
> +                       {{0x0, 0x1B}, 0x12, 0xF}
> +               },
> +               {{0x0, 0x0A}, 0x12, 0xF},
> +       },
> +       {
> +               450000001,  600000000,
> +               {
> +                       {{0x0, 0x1C}, 0x12, 0xF},
> +                       {{0x0, 0x1C}, 0x12, 0xF},
> +                       {{0x0, 0x1C}, 0x12, 0xF}
> +               },
> +               {{0x0, 0x0B}, 0x13, 0xF},
> +       },
> +};
> +
> +static const struct phy_settings *phy_get_settings(unsigned long long tmds_rate)
> +{
> +       unsigned int count = ARRAY_SIZE(vc5_hdmi_phy_settings);
> +       unsigned int i;
> +
> +       for (i = 0; i < count; i++) {
> +               const struct phy_settings *s = &vc5_hdmi_phy_settings[i];
> +
> +               if (tmds_rate >= s->min_rate && tmds_rate <= s->max_rate)
> +                       return s;
> +       }
> +
> +       /*
> +        * If the pixel clock exceeds our max setting, try the max
> +        * setting anyway.
> +        */
> +       return &vc5_hdmi_phy_settings[count - 1];
> +}
> +
> +static const struct phy_lane_settings *
> +phy_get_channel_settings(enum vc4_hdmi_phy_channel chan,
> +                        unsigned long long tmds_rate)
> +{
> +       const struct phy_settings *settings = phy_get_settings(tmds_rate);
> +
> +       if (chan == PHY_LANE_CK)
> +               return &settings->clock;
> +
> +       return &settings->channel[chan];
> +}
> +
> +static void vc5_hdmi_reset_phy(struct vc4_hdmi *vc4_hdmi)
> +{
> +       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0x0f);
> +       HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL, BIT(10));
> +}
> +
> +void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, struct drm_display_mode *mode)
> +{
> +       const struct phy_lane_settings *chan0_settings, *chan1_settings, *chan2_settings, *clock_settings;
> +       const struct vc4_hdmi_variant *variant = vc4_hdmi->variant;
> +       unsigned long long pixel_freq = mode->clock * 1000;
> +       unsigned long long vco_freq;
> +       unsigned char word_sel;
> +       u8 vco_sel, vco_div;
> +
> +       vco_freq = phy_get_vco_freq(pixel_freq, &vco_sel, &vco_div);
> +
> +       vc5_hdmi_reset_phy(vc4_hdmi);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
> +                  VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_RESET_CTL) &
> +                  ~VC4_HDMI_TX_PHY_RESET_CTL_TX_0_RESET &
> +                  ~VC4_HDMI_TX_PHY_RESET_CTL_TX_1_RESET &
> +                  ~VC4_HDMI_TX_PHY_RESET_CTL_TX_2_RESET &
> +                  ~VC4_HDMI_TX_PHY_RESET_CTL_TX_CK_RESET);
> +
> +       HDMI_WRITE(HDMI_RM_CONTROL,
> +                  HDMI_READ(HDMI_RM_CONTROL) |
> +                  VC4_HDMI_RM_CONTROL_EN_FREEZE_COUNTERS |
> +                  VC4_HDMI_RM_CONTROL_EN_LOAD_INTEGRATOR |
> +                  VC4_HDMI_RM_CONTROL_FREE_RUN);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1,
> +                  (HDMI_READ(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1) &
> +                   ~VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_MASK) |
> +                  VC4_SET_FIELD(0, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2,
> +                  (HDMI_READ(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2) &
> +                   ~VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_MASK) |
> +                  VC4_SET_FIELD(0, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT));
> +
> +       HDMI_WRITE(HDMI_RM_OFFSET,
> +                  VC4_SET_FIELD(phy_get_rm_offset(vco_freq),
> +                                VC4_HDMI_RM_OFFSET_OFFSET) |
> +                  VC4_HDMI_RM_OFFSET_ONLY);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CLK_DIV,
> +                  VC4_SET_FIELD(vco_div, VC4_HDMI_TX_PHY_CLK_DIV_VCO));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4,
> +                  VC4_SET_FIELD(0xe147, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD) |
> +                  VC4_SET_FIELD(0xe14, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CTL_0,
> +                  VC4_HDMI_TX_PHY_PLL_CTL_0_ENA_VCO_CLK |
> +                  VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_CONT_EN |
> +                  VC4_HDMI_TX_PHY_PLL_CTL_0_MASH11_MODE |
> +                  VC4_SET_FIELD(vco_sel, VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CTL_1,
> +                  HDMI_READ(HDMI_TX_PHY_PLL_CTL_1) |
> +                  VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_ENABLE |
> +                  VC4_SET_FIELD(3, VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL) |
> +                  VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY) |
> +                  VC4_SET_FIELD(0x8a, VC4_HDMI_TX_PHY_PLL_CTL_1_CPP));
> +
> +       HDMI_WRITE(HDMI_RM_FORMAT,
> +                  HDMI_READ(HDMI_RM_FORMAT) |
> +                  VC4_SET_FIELD(2, VC4_HDMI_RM_FORMAT_SHIFT));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CFG,
> +                  HDMI_READ(HDMI_TX_PHY_PLL_CFG) |
> +                  VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_PLL_CFG_PDIV));
> +
> +       if (pixel_freq >= 340000000)
> +               word_sel = 3;
> +       else
> +               word_sel = 0;
> +       HDMI_WRITE(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, word_sel);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CTL_3,
> +                  VC4_SET_FIELD(phy_get_cp_current(vco_freq),
> +                                VC4_HDMI_TX_PHY_CTL_3_ICP) |
> +                  VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_CTL_3_CP) |
> +                  VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_CTL_3_CP1) |
> +                  VC4_SET_FIELD(3, VC4_HDMI_TX_PHY_CTL_3_CZ) |
> +                  VC4_SET_FIELD(4, VC4_HDMI_TX_PHY_CTL_3_RP) |
> +                  VC4_SET_FIELD(6, VC4_HDMI_TX_PHY_CTL_3_RZ));
> +
> +       chan0_settings =
> +               phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_0],
> +                                        pixel_freq);
> +       chan1_settings =
> +               phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_1],
> +                                        pixel_freq);
> +       chan2_settings =
> +               phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_2],
> +                                        pixel_freq);
> +       clock_settings =
> +               phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_CK],
> +                                        pixel_freq);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CTL_0,
> +                  VC4_SET_FIELD(chan0_settings->amplitude.preemphasis,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP) |
> +                  VC4_SET_FIELD(chan0_settings->amplitude.main_driver,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV) |
> +                  VC4_SET_FIELD(chan1_settings->amplitude.preemphasis,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP) |
> +                  VC4_SET_FIELD(chan1_settings->amplitude.main_driver,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV) |
> +                  VC4_SET_FIELD(chan2_settings->amplitude.preemphasis,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP) |
> +                  VC4_SET_FIELD(chan2_settings->amplitude.main_driver,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV) |
> +                  VC4_SET_FIELD(clock_settings->amplitude.preemphasis,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP) |
> +                  VC4_SET_FIELD(clock_settings->amplitude.main_driver,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CTL_1,
> +                  HDMI_READ(HDMI_TX_PHY_CTL_1) |
> +                  VC4_SET_FIELD(chan0_settings->res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0) |
> +                  VC4_SET_FIELD(chan1_settings->res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1) |
> +                  VC4_SET_FIELD(chan2_settings->res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2) |
> +                  VC4_SET_FIELD(clock_settings->res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CTL_2,
> +                  VC4_SET_FIELD(chan0_settings->term_res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0) |
> +                  VC4_SET_FIELD(chan1_settings->term_res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1) |
> +                  VC4_SET_FIELD(chan2_settings->term_res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2) |
> +                  VC4_SET_FIELD(clock_settings->term_res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK) |
> +                  VC4_SET_FIELD(phy_get_vco_gain(vco_freq),
> +                                VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CHANNEL_SWAP,
> +                  VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_0],
> +                                VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL) |
> +                  VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_1],
> +                                VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL) |
> +                  VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_2],
> +                                VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL) |
> +                  VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_CK],
> +                                VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_RESET_CTL) &
> +                  ~(VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB |
> +                    VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_RESET_CTL) |
> +                  VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB |
> +                  VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB);
> +}
> +
> +void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi) {
> +       vc5_hdmi_reset_phy(vc4_hdmi);
> +}
> +
> +void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi)
> +{
> +       HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) &
> +                  ~VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
> +}
> +
> +void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi)
> +{
> +       HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) |
> +                  VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
> index bc47cc9bc883..a5f1354e3e06 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
> @@ -9,6 +9,12 @@ enum vc4_hdmi_regs {
>         VC4_INVALID = 0,
>         VC4_HDMI,
>         VC4_HD,
> +       VC5_CEC,
> +       VC5_CSC,
> +       VC5_DVP,
> +       VC5_PHY,
> +       VC5_RAM,
> +       VC5_RM,
>  };
>
>  enum vc4_hdmi_field {
> @@ -36,6 +42,7 @@ enum vc4_hdmi_field {
>         HDMI_CEC_TX_DATA_2,
>         HDMI_CEC_TX_DATA_3,
>         HDMI_CEC_TX_DATA_4,
> +       HDMI_CLOCK_STOP,
>         HDMI_CORE_REV,
>         HDMI_CRP_CFG,
>         HDMI_CSC_12_11,
> @@ -52,6 +59,7 @@ enum vc4_hdmi_field {
>          */
>         HDMI_CTS_0,
>         HDMI_CTS_1,
> +       HDMI_DVP_CTL,
>         HDMI_FIFO_CTL,
>         HDMI_FRAME_COUNT,
>         HDMI_HORZA,
> @@ -84,10 +92,27 @@ enum vc4_hdmi_field {
>         HDMI_RAM_PACKET_CONFIG,
>         HDMI_RAM_PACKET_START,
>         HDMI_RAM_PACKET_STATUS,
> +       HDMI_RM_CONTROL,
> +       HDMI_RM_FORMAT,
> +       HDMI_RM_OFFSET,
>         HDMI_SCHEDULER_CONTROL,
>         HDMI_SW_RESET_CONTROL,
> +       HDMI_TX_PHY_CHANNEL_SWAP,
> +       HDMI_TX_PHY_CLK_DIV,
>         HDMI_TX_PHY_CTL_0,
> +       HDMI_TX_PHY_CTL_1,
> +       HDMI_TX_PHY_CTL_2,
> +       HDMI_TX_PHY_CTL_3,
> +       HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1,
> +       HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2,
> +       HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4,
> +       HDMI_TX_PHY_PLL_CFG,
> +       HDMI_TX_PHY_PLL_CTL_0,
> +       HDMI_TX_PHY_PLL_CTL_1,
> +       HDMI_TX_PHY_POWERDOWN_CTL,
>         HDMI_TX_PHY_RESET_CTL,
> +       HDMI_TX_PHY_TMDS_CLK_WORD_SEL,
> +       HDMI_VEC_INTERFACE_XBAR,
>         HDMI_VERTA0,
>         HDMI_VERTA1,
>         HDMI_VERTB0,
> @@ -110,6 +135,12 @@ struct vc4_hdmi_register {
>
>  #define VC4_HD_REG(reg, offset)                _VC4_REG(VC4_HD, reg, offset)
>  #define VC4_HDMI_REG(reg, offset)      _VC4_REG(VC4_HDMI, reg, offset)
> +#define VC5_CEC_REG(reg, offset)       _VC4_REG(VC5_CEC, reg, offset)
> +#define VC5_CSC_REG(reg, offset)       _VC4_REG(VC5_CSC, reg, offset)
> +#define VC5_DVP_REG(reg, offset)       _VC4_REG(VC5_DVP, reg, offset)
> +#define VC5_PHY_REG(reg, offset)       _VC4_REG(VC5_PHY, reg, offset)
> +#define VC5_RAM_REG(reg, offset)       _VC4_REG(VC5_RAM, reg, offset)
> +#define VC5_RM_REG(reg, offset)                _VC4_REG(VC5_RM, reg, offset)
>
>  static const struct vc4_hdmi_register vc4_hdmi_fields[] = {
>         VC4_HD_REG(HDMI_M_CTL, 0x000c),
> @@ -172,6 +203,158 @@ static const struct vc4_hdmi_register vc4_hdmi_fields[] = {
>         VC4_HDMI_REG(HDMI_RAM_PACKET_START, 0x0400),
>  };
>
> +static const struct vc4_hdmi_register vc5_hdmi_hdmi0_fields[] = {
> +       VC4_HD_REG(HDMI_DVP_CTL, 0x0000),
> +       VC4_HD_REG(HDMI_MAI_CTL, 0x0010),
> +       VC4_HD_REG(HDMI_MAI_THR, 0x0014),
> +       VC4_HD_REG(HDMI_MAI_FMT, 0x0018),
> +       VC4_HD_REG(HDMI_MAI_DATA, 0x001c),
> +       VC4_HD_REG(HDMI_MAI_SMP, 0x0020),
> +       VC4_HD_REG(HDMI_VID_CTL, 0x0044),
> +       VC4_HD_REG(HDMI_FRAME_COUNT, 0x0060),
> +
> +       VC4_HDMI_REG(HDMI_FIFO_CTL, 0x074),
> +       VC4_HDMI_REG(HDMI_AUDIO_PACKET_CONFIG, 0x0b8),
> +       VC4_HDMI_REG(HDMI_RAM_PACKET_CONFIG, 0x0bc),
> +       VC4_HDMI_REG(HDMI_RAM_PACKET_STATUS, 0x0c4),
> +       VC4_HDMI_REG(HDMI_CRP_CFG, 0x0c8),
> +       VC4_HDMI_REG(HDMI_CTS_0, 0x0cc),
> +       VC4_HDMI_REG(HDMI_CTS_1, 0x0d0),
> +       VC4_HDMI_REG(HDMI_SCHEDULER_CONTROL, 0x0e0),
> +       VC4_HDMI_REG(HDMI_HORZA, 0x0e4),
> +       VC4_HDMI_REG(HDMI_HORZB, 0x0e8),
> +       VC4_HDMI_REG(HDMI_VERTA0, 0x0ec),
> +       VC4_HDMI_REG(HDMI_VERTB0, 0x0f0),
> +       VC4_HDMI_REG(HDMI_VERTA1, 0x0f4),
> +       VC4_HDMI_REG(HDMI_VERTB1, 0x0f8),
> +       VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c),
> +       VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
> +       VC4_HDMI_REG(HDMI_HOTPLUG, 0x1a8),
> +
> +       VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
> +       VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0),
> +
> +       VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000),
> +       VC5_PHY_REG(HDMI_TX_PHY_POWERDOWN_CTL, 0x004),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_0, 0x008),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_1, 0x00c),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_2, 0x010),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_3, 0x014),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_0, 0x01c),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_1, 0x020),
> +       VC5_PHY_REG(HDMI_TX_PHY_CLK_DIV, 0x028),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CFG, 0x034),
> +       VC5_PHY_REG(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, 0x044),
> +       VC5_PHY_REG(HDMI_TX_PHY_CHANNEL_SWAP, 0x04c),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1, 0x050),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2, 0x054),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4, 0x05c),
> +
> +       VC5_RM_REG(HDMI_RM_CONTROL, 0x000),
> +       VC5_RM_REG(HDMI_RM_OFFSET, 0x018),
> +       VC5_RM_REG(HDMI_RM_FORMAT, 0x01c),
> +
> +       VC5_RAM_REG(HDMI_RAM_PACKET_START, 0x000),
> +
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_1, 0x010),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_2, 0x014),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_3, 0x018),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_4, 0x01c),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_5, 0x020),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_1, 0x028),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_2, 0x02c),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_3, 0x030),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_4, 0x034),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_1, 0x038),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_2, 0x03c),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_3, 0x040),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_4, 0x044),
> +
> +       VC5_CSC_REG(HDMI_CSC_CTL, 0x000),
> +       VC5_CSC_REG(HDMI_CSC_12_11, 0x004),
> +       VC5_CSC_REG(HDMI_CSC_14_13, 0x008),
> +       VC5_CSC_REG(HDMI_CSC_22_21, 0x00c),
> +       VC5_CSC_REG(HDMI_CSC_24_23, 0x010),
> +       VC5_CSC_REG(HDMI_CSC_32_31, 0x014),
> +       VC5_CSC_REG(HDMI_CSC_34_33, 0x018),
> +};
> +
> +static const struct vc4_hdmi_register vc5_hdmi_hdmi1_fields[] = {
> +       VC4_HD_REG(HDMI_DVP_CTL, 0x0000),
> +       VC4_HD_REG(HDMI_MAI_CTL, 0x0030),
> +       VC4_HD_REG(HDMI_MAI_THR, 0x0034),
> +       VC4_HD_REG(HDMI_MAI_FMT, 0x0038),
> +       VC4_HD_REG(HDMI_MAI_DATA, 0x003c),
> +       VC4_HD_REG(HDMI_MAI_SMP, 0x0040),
> +       VC4_HD_REG(HDMI_VID_CTL, 0x0048),
> +       VC4_HD_REG(HDMI_FRAME_COUNT, 0x0064),
> +
> +       VC4_HDMI_REG(HDMI_FIFO_CTL, 0x074),
> +       VC4_HDMI_REG(HDMI_AUDIO_PACKET_CONFIG, 0x0b8),
> +       VC4_HDMI_REG(HDMI_RAM_PACKET_CONFIG, 0x0bc),
> +       VC4_HDMI_REG(HDMI_RAM_PACKET_STATUS, 0x0c4),
> +       VC4_HDMI_REG(HDMI_CRP_CFG, 0x0c8),
> +       VC4_HDMI_REG(HDMI_CTS_0, 0x0cc),
> +       VC4_HDMI_REG(HDMI_CTS_1, 0x0d0),
> +       VC4_HDMI_REG(HDMI_SCHEDULER_CONTROL, 0x0e0),
> +       VC4_HDMI_REG(HDMI_HORZA, 0x0e4),
> +       VC4_HDMI_REG(HDMI_HORZB, 0x0e8),
> +       VC4_HDMI_REG(HDMI_VERTA0, 0x0ec),
> +       VC4_HDMI_REG(HDMI_VERTB0, 0x0f0),
> +       VC4_HDMI_REG(HDMI_VERTA1, 0x0f4),
> +       VC4_HDMI_REG(HDMI_VERTB1, 0x0f8),
> +       VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c),
> +       VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
> +       VC4_HDMI_REG(HDMI_HOTPLUG, 0x1a8),
> +
> +       VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
> +       VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0),
> +
> +       VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000),
> +       VC5_PHY_REG(HDMI_TX_PHY_POWERDOWN_CTL, 0x004),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_0, 0x008),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_1, 0x00c),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_2, 0x010),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_3, 0x014),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_0, 0x01c),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_1, 0x020),
> +       VC5_PHY_REG(HDMI_TX_PHY_CLK_DIV, 0x028),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CFG, 0x034),
> +       VC5_PHY_REG(HDMI_TX_PHY_CHANNEL_SWAP, 0x04c),
> +       VC5_PHY_REG(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, 0x044),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1, 0x050),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2, 0x054),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4, 0x05c),
> +
> +       VC5_RM_REG(HDMI_RM_CONTROL, 0x000),
> +       VC5_RM_REG(HDMI_RM_OFFSET, 0x018),
> +       VC5_RM_REG(HDMI_RM_FORMAT, 0x01c),
> +
> +       VC5_RAM_REG(HDMI_RAM_PACKET_START, 0x000),
> +
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_1, 0x010),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_2, 0x014),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_3, 0x018),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_4, 0x01c),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_5, 0x020),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_1, 0x028),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_2, 0x02c),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_3, 0x030),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_4, 0x034),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_1, 0x038),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_2, 0x03c),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_3, 0x040),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_4, 0x044),
> +
> +       VC5_CSC_REG(HDMI_CSC_CTL, 0x000),
> +       VC5_CSC_REG(HDMI_CSC_12_11, 0x004),
> +       VC5_CSC_REG(HDMI_CSC_14_13, 0x008),
> +       VC5_CSC_REG(HDMI_CSC_22_21, 0x00c),
> +       VC5_CSC_REG(HDMI_CSC_24_23, 0x010),
> +       VC5_CSC_REG(HDMI_CSC_32_31, 0x014),
> +       VC5_CSC_REG(HDMI_CSC_34_33, 0x018),
> +};
> +
>  static inline
>  void __iomem *__vc4_hdmi_get_field_base(struct vc4_hdmi *hdmi,
>                                         enum vc4_hdmi_regs reg)
> @@ -183,6 +366,24 @@ void __iomem *__vc4_hdmi_get_field_base(struct vc4_hdmi *hdmi,
>         case VC4_HDMI:
>                 return hdmi->hdmicore_regs;
>
> +       case VC5_CSC:
> +               return hdmi->csc_regs;
> +
> +       case VC5_CEC:
> +               return hdmi->cec_regs;
> +
> +       case VC5_DVP:
> +               return hdmi->dvp_regs;
> +
> +       case VC5_PHY:
> +               return hdmi->phy_regs;
> +
> +       case VC5_RAM:
> +               return hdmi->ram_regs;
> +
> +       case VC5_RM:
> +               return hdmi->rm_regs;
> +
>         default:
>                 return NULL;
>         }
> diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
> index 30af52b406f1..be2c32a519b3 100644
> --- a/drivers/gpu/drm/vc4/vc4_regs.h
> +++ b/drivers/gpu/drm/vc4/vc4_regs.h
> @@ -744,6 +744,8 @@
>  # define VC4_HD_CSC_CTL_RGB2YCC                        BIT(1)
>  # define VC4_HD_CSC_CTL_ENABLE                 BIT(0)
>
> +# define VC4_DVP_HT_CLOCK_STOP_PIXEL           BIT(1)
> +
>  /* HVS display list information. */
>  #define HVS_BOOTLOADER_DLIST_END                32
>
> --
> git-series 0.9.1

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

WARNING: multiple messages have this Message-ID (diff)
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
To: Maxime Ripard <maxime@cerno.tech>
Cc: Tim Gover <tim.gover@raspberrypi.com>,
	LKML <linux-kernel@vger.kernel.org>,
	DRI Development <dri-devel@lists.freedesktop.org>,
	bcm-kernel-feedback-list@broadcom.com,
	Nicolas Saenz Julienne <nsaenzjulienne@suse.de>,
	Phil Elwell <phil@raspberrypi.com>,
	linux-arm-kernel@lists.infradead.org,
	linux-rpi-kernel@lists.infradead.org
Subject: Re: [PATCH v4 74/78] drm/vc4: hdmi: Support the BCM2711 HDMI controllers
Date: Tue, 28 Jul 2020 16:21:56 +0100	[thread overview]
Message-ID: <CAPY8ntA0UixNWc27-x0Y5AG_pXvzh=5spHwQ5poYLEqDzSS0WA@mail.gmail.com> (raw)
In-Reply-To: <37e2291033dc5f012248efc641ca796101470b45.1594230107.git-series.maxime@cerno.tech>

Hi Maxime

On Wed, 8 Jul 2020 at 18:44, Maxime Ripard <maxime@cerno.tech> wrote:
>
> Now that the driver is ready for it, let's bring in the HDMI controllers
> variants for the BCM2711.
>
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>

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

> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c      | 278 +++++++++++++++++-
>  drivers/gpu/drm/vc4/vc4_hdmi.h      |  36 ++-
>  drivers/gpu/drm/vc4/vc4_hdmi_phy.c  | 480 +++++++++++++++++++++++++++++-
>  drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 201 ++++++++++++-
>  drivers/gpu/drm/vc4/vc4_regs.h      |   2 +-
>  5 files changed, 997 insertions(+)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 37463b016b47..d5ba0b1b73a9 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -43,6 +43,7 @@
>  #include <linux/of_platform.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/rational.h>
> +#include <linux/reset.h>
>  #include <sound/dmaengine_pcm.h>
>  #include <sound/pcm_drm_eld.h>
>  #include <sound/pcm_params.h>
> @@ -53,6 +54,31 @@
>  #include "vc4_hdmi_regs.h"
>  #include "vc4_regs.h"
>
> +#define VC5_HDMI_HORZA_HFP_SHIFT               16
> +#define VC5_HDMI_HORZA_HFP_MASK                        VC4_MASK(28, 16)
> +#define VC5_HDMI_HORZA_VPOS                    BIT(15)
> +#define VC5_HDMI_HORZA_HPOS                    BIT(14)
> +#define VC5_HDMI_HORZA_HAP_SHIFT               0
> +#define VC5_HDMI_HORZA_HAP_MASK                        VC4_MASK(13, 0)
> +
> +#define VC5_HDMI_HORZB_HBP_SHIFT               16
> +#define VC5_HDMI_HORZB_HBP_MASK                        VC4_MASK(26, 16)
> +#define VC5_HDMI_HORZB_HSP_SHIFT               0
> +#define VC5_HDMI_HORZB_HSP_MASK                        VC4_MASK(10, 0)
> +
> +#define VC5_HDMI_VERTA_VSP_SHIFT               24
> +#define VC5_HDMI_VERTA_VSP_MASK                        VC4_MASK(28, 24)
> +#define VC5_HDMI_VERTA_VFP_SHIFT               16
> +#define VC5_HDMI_VERTA_VFP_MASK                        VC4_MASK(22, 16)
> +#define VC5_HDMI_VERTA_VAL_SHIFT               0
> +#define VC5_HDMI_VERTA_VAL_MASK                        VC4_MASK(12, 0)
> +
> +#define VC5_HDMI_VERTB_VSPO_SHIFT              16
> +#define VC5_HDMI_VERTB_VSPO_MASK               VC4_MASK(29, 16)
> +
> +# define VC4_HD_M_SW_RST                       BIT(2)
> +# define VC4_HD_M_ENABLE                       BIT(0)
> +
>  #define CEC_CLOCK_FREQ 40000
>
>  static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
> @@ -82,6 +108,16 @@ static void vc4_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
>         HDMI_WRITE(HDMI_SW_RESET_CONTROL, 0);
>  }
>
> +static void vc5_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
> +{
> +       reset_control_reset(vc4_hdmi->reset);
> +
> +       HDMI_WRITE(HDMI_DVP_CTL, 0);
> +
> +       HDMI_WRITE(HDMI_CLOCK_STOP,
> +                  HDMI_READ(HDMI_CLOCK_STOP) | VC4_DVP_HT_CLOCK_STOP_PIXEL);
> +}
> +
>  static enum drm_connector_status
>  vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> @@ -391,6 +427,45 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
>         HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
>  }
>
> +static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
> +{
> +       u32 csc_ctl;
> +
> +       csc_ctl = 0x07; /* RGB_CONVERT_MODE = custom matrix, || USE_RGB_TO_YCBCR */
> +
> +       if (enable) {
> +               /* CEA VICs other than #1 requre limited range RGB
> +                * output unless overridden by an AVI infoframe.
> +                * Apply a colorspace conversion to squash 0-255 down
> +                * to 16-235.  The matrix here is:
> +                *
> +                * [ 0.8594 0      0      16]
> +                * [ 0      0.8594 0      16]
> +                * [ 0      0      0.8594 16]
> +                * [ 0      0      0       1]
> +                * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
> +                */
> +               HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x1b80);
> +               HDMI_WRITE(HDMI_CSC_14_13, (0x0400 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_22_21, (0x1b80 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_24_23, (0x0400 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_34_33, (0x0400 << 16) | 0x1b80);
> +       } else {
> +               /* Still use the matrix for full range, but make it unity.
> +                * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
> +                */
> +               HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x2000);
> +               HDMI_WRITE(HDMI_CSC_14_13, (0x0000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_22_21, (0x2000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_24_23, (0x0000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
> +               HDMI_WRITE(HDMI_CSC_34_33, (0x0000 << 16) | 0x2000);
> +       }
> +
> +       HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
> +}
> +
>  static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
>                                  struct drm_display_mode *mode)
>  {
> @@ -435,6 +510,53 @@ static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
>         HDMI_WRITE(HDMI_VERTB0, vertb_even);
>         HDMI_WRITE(HDMI_VERTB1, vertb);
>  }
> +static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
> +                                struct drm_display_mode *mode)
> +{
> +       bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
> +       bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
> +       bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
> +       u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
> +       u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
> +                                  VC5_HDMI_VERTA_VSP) |
> +                    VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
> +                                  VC5_HDMI_VERTA_VFP) |
> +                    VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL));
> +       u32 vertb = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
> +                    VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
> +                                  VC4_HDMI_VERTB_VBP));
> +       u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
> +                         VC4_SET_FIELD(mode->crtc_vtotal -
> +                                       mode->crtc_vsync_end -
> +                                       interlaced,
> +                                       VC4_HDMI_VERTB_VBP));
> +
> +       HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021);
> +       HDMI_WRITE(HDMI_HORZA,
> +                  (vsync_pos ? VC5_HDMI_HORZA_VPOS : 0) |
> +                  (hsync_pos ? VC5_HDMI_HORZA_HPOS : 0) |
> +                  VC4_SET_FIELD(mode->hdisplay * pixel_rep,
> +                                VC5_HDMI_HORZA_HAP) |
> +                  VC4_SET_FIELD((mode->hsync_start -
> +                                 mode->hdisplay) * pixel_rep,
> +                                VC5_HDMI_HORZA_HFP));
> +
> +       HDMI_WRITE(HDMI_HORZB,
> +                  VC4_SET_FIELD((mode->htotal -
> +                                 mode->hsync_end) * pixel_rep,
> +                                VC5_HDMI_HORZB_HBP) |
> +                  VC4_SET_FIELD((mode->hsync_end -
> +                                 mode->hsync_start) * pixel_rep,
> +                                VC5_HDMI_HORZB_HSP));
> +
> +       HDMI_WRITE(HDMI_VERTA0, verta);
> +       HDMI_WRITE(HDMI_VERTA1, verta);
> +
> +       HDMI_WRITE(HDMI_VERTB0, vertb_even);
> +       HDMI_WRITE(HDMI_VERTB1, vertb);
> +
> +       HDMI_WRITE(HDMI_CLOCK_STOP, 0);
> +}
>
>  static void vc4_hdmi_recenter_fifo(struct vc4_hdmi *vc4_hdmi)
>  {
> @@ -645,6 +767,18 @@ static u32 vc4_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
>         return channel_map;
>  }
>
> +static u32 vc5_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
> +{
> +       int i;
> +       u32 channel_map = 0;
> +
> +       for (i = 0; i < 8; i++) {
> +               if (channel_mask & BIT(i))
> +                       channel_map |= i << (4 * i);
> +       }
> +       return channel_map;
> +}
> +
>  /* HDMI audio codec callbacks */
>  static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *vc4_hdmi)
>  {
> @@ -1377,6 +1511,98 @@ static int vc4_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
>         return 0;
>  }
>
> +static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
> +{
> +       struct platform_device *pdev = vc4_hdmi->pdev;
> +       struct device *dev = &pdev->dev;
> +       struct resource *res;
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->hdmicore_regs = devm_ioremap(dev, res->start,
> +                                              resource_size(res));
> +       if (IS_ERR(vc4_hdmi->hdmicore_regs))
> +               return PTR_ERR(vc4_hdmi->hdmicore_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hd");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->hd_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->hd_regs))
> +               return PTR_ERR(vc4_hdmi->hd_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cec");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->cec_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->cec_regs))
> +               return PTR_ERR(vc4_hdmi->cec_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csc");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->csc_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->csc_regs))
> +               return PTR_ERR(vc4_hdmi->csc_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dvp");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->dvp_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->dvp_regs))
> +               return PTR_ERR(vc4_hdmi->dvp_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->phy_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->phy_regs))
> +               return PTR_ERR(vc4_hdmi->phy_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "packet");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->ram_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->ram_regs))
> +               return PTR_ERR(vc4_hdmi->ram_regs);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rm");
> +       if (!res)
> +               return -ENODEV;
> +
> +       vc4_hdmi->rm_regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (IS_ERR(vc4_hdmi->rm_regs))
> +               return PTR_ERR(vc4_hdmi->rm_regs);
> +
> +       vc4_hdmi->hsm_clock = devm_clk_get(dev, "hdmi");
> +       if (IS_ERR(vc4_hdmi->hsm_clock)) {
> +               DRM_ERROR("Failed to get HDMI state machine clock\n");
> +               return PTR_ERR(vc4_hdmi->hsm_clock);
> +       }
> +
> +       vc4_hdmi->audio_clock = devm_clk_get(dev, "clk-108M");
> +       if (IS_ERR(vc4_hdmi->audio_clock)) {
> +               DRM_ERROR("Failed to get 108MHz clock\n");
> +               return PTR_ERR(vc4_hdmi->audio_clock);
> +       }
> +
> +       vc4_hdmi->reset = devm_reset_control_get(dev, NULL);
> +       if (IS_ERR(vc4_hdmi->reset)) {
> +               DRM_ERROR("Failed to get HDMI reset line\n");
> +               return PTR_ERR(vc4_hdmi->reset);
> +       }
> +
> +       return 0;
> +}
> +
>  static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
>  {
>         const struct vc4_hdmi_variant *variant = of_device_get_match_data(dev);
> @@ -1547,8 +1773,60 @@ static const struct vc4_hdmi_variant bcm2835_variant = {
>         .channel_map            = vc4_hdmi_channel_map,
>  };
>
> +static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = {
> +       .encoder_type           = VC4_ENCODER_TYPE_HDMI0,
> +       .debugfs_name           = "hdmi0_regs",
> +       .card_name              = "vc4-hdmi-0",
> +       .max_pixel_clock        = 297000000,
> +       .registers              = vc5_hdmi_hdmi0_fields,
> +       .num_registers          = ARRAY_SIZE(vc5_hdmi_hdmi0_fields),
> +       .phy_lane_mapping       = {
> +               PHY_LANE_0,
> +               PHY_LANE_1,
> +               PHY_LANE_2,
> +               PHY_LANE_CK,
> +       },
> +
> +       .init_resources         = vc5_hdmi_init_resources,
> +       .csc_setup              = vc5_hdmi_csc_setup,
> +       .reset                  = vc5_hdmi_reset,
> +       .set_timings            = vc5_hdmi_set_timings,
> +       .phy_init               = vc5_hdmi_phy_init,
> +       .phy_disable            = vc5_hdmi_phy_disable,
> +       .phy_rng_enable         = vc5_hdmi_phy_rng_enable,
> +       .phy_rng_disable        = vc5_hdmi_phy_rng_disable,
> +       .channel_map            = vc5_hdmi_channel_map,
> +};
> +
> +static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = {
> +       .encoder_type           = VC4_ENCODER_TYPE_HDMI1,
> +       .debugfs_name           = "hdmi1_regs",
> +       .card_name              = "vc4-hdmi-1",
> +       .max_pixel_clock        = 297000000,
> +       .registers              = vc5_hdmi_hdmi1_fields,
> +       .num_registers          = ARRAY_SIZE(vc5_hdmi_hdmi1_fields),
> +       .phy_lane_mapping       = {
> +               PHY_LANE_1,
> +               PHY_LANE_0,
> +               PHY_LANE_CK,
> +               PHY_LANE_2,
> +       },
> +
> +       .init_resources         = vc5_hdmi_init_resources,
> +       .csc_setup              = vc5_hdmi_csc_setup,
> +       .reset                  = vc5_hdmi_reset,
> +       .set_timings            = vc5_hdmi_set_timings,
> +       .phy_init               = vc5_hdmi_phy_init,
> +       .phy_disable            = vc5_hdmi_phy_disable,
> +       .phy_rng_enable         = vc5_hdmi_phy_rng_enable,
> +       .phy_rng_disable        = vc5_hdmi_phy_rng_disable,
> +       .channel_map            = vc5_hdmi_channel_map,
> +};
> +
>  static const struct of_device_id vc4_hdmi_dt_match[] = {
>         { .compatible = "brcm,bcm2835-hdmi", .data = &bcm2835_variant },
> +       { .compatible = "brcm,bcm2711-hdmi0", .data = &bcm2711_hdmi0_variant },
> +       { .compatible = "brcm,bcm2711-hdmi1", .data = &bcm2711_hdmi1_variant },
>         {}
>  };
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
> index 34138e0dd4a6..0806c6d9f24e 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
> @@ -26,6 +26,13 @@ struct drm_display_mode;
>  struct vc4_hdmi;
>  struct vc4_hdmi_register;
>
> +enum vc4_hdmi_phy_channel {
> +       PHY_LANE_0 = 0,
> +       PHY_LANE_1,
> +       PHY_LANE_2,
> +       PHY_LANE_CK,
> +};
> +
>  struct vc4_hdmi_variant {
>         /* Encoder Type for that controller */
>         enum vc4_encoder_type encoder_type;
> @@ -48,6 +55,13 @@ struct vc4_hdmi_variant {
>         /* Number of registers on that variant */
>         unsigned int num_registers;
>
> +       /* BCM2711 Only.
> +        * The variants don't map the lane in the same order in the
> +        * PHY, so this is an array mapping the HDMI channel (index)
> +        * to the PHY lane (value).
> +        */
> +       enum vc4_hdmi_phy_channel phy_lane_mapping[4];
> +
>         /* Callback to get the resources (memory region, interrupts,
>          * clocks, etc) for that variant.
>          */
> @@ -108,6 +122,20 @@ struct vc4_hdmi {
>         struct i2c_adapter *ddc;
>         void __iomem *hdmicore_regs;
>         void __iomem *hd_regs;
> +
> +       /* VC5 Only */
> +       void __iomem *cec_regs;
> +       /* VC5 Only */
> +       void __iomem *csc_regs;
> +       /* VC5 Only */
> +       void __iomem *dvp_regs;
> +       /* VC5 Only */
> +       void __iomem *phy_regs;
> +       /* VC5 Only */
> +       void __iomem *ram_regs;
> +       /* VC5 Only */
> +       void __iomem *rm_regs;
> +
>         int hpd_gpio;
>         bool hpd_active_low;
>
> @@ -120,6 +148,8 @@ struct vc4_hdmi {
>         struct clk *hsm_clock;
>         struct clk *audio_clock;
>
> +       struct reset_control *reset;
> +
>         struct debugfs_regset32 hdmi_regset;
>         struct debugfs_regset32 hd_regset;
>  };
> @@ -144,4 +174,10 @@ void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
>  void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
>  void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
>
> +void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
> +                      struct drm_display_mode *mode);
> +void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
> +void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
> +void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
> +
>  #endif /* _VC4_HDMI_H_ */
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> index 93287e24d7d1..4d36f8c33401 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
> @@ -10,6 +10,123 @@
>  #include "vc4_regs.h"
>  #include "vc4_hdmi_regs.h"
>
> +#define VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB   BIT(5)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB        BIT(4)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_TX_CK_RESET  BIT(3)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_TX_2_RESET   BIT(2)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_TX_1_RESET   BIT(1)
> +#define VC4_HDMI_TX_PHY_RESET_CTL_TX_0_RESET   BIT(0)
> +
> +#define VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN     BIT(4)
> +
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP_SHIFT    29
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP_MASK     VC4_MASK(31, 29)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV_SHIFT   24
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV_MASK    VC4_MASK(28, 24)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP_SHIFT    21
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP_MASK     VC4_MASK(23, 21)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV_SHIFT   16
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV_MASK    VC4_MASK(20, 16)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP_SHIFT    13
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP_MASK     VC4_MASK(15, 13)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV_SHIFT   8
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV_MASK    VC4_MASK(12, 8)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP_SHIFT   5
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP_MASK    VC4_MASK(7, 5)
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV_SHIFT  0
> +#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV_MASK   VC4_MASK(4, 0)
> +
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2_SHIFT      15
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2_MASK       VC4_MASK(19, 15)
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1_SHIFT      10
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1_MASK       VC4_MASK(14, 10)
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0_SHIFT      5
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0_MASK       VC4_MASK(9, 5)
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK_SHIFT         0
> +#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK_MASK          VC4_MASK(4, 0)
> +
> +#define VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN_SHIFT           16
> +#define VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN_MASK            VC4_MASK(19, 16)
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2_SHIFT  12
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2_MASK   VC4_MASK(15, 12)
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1_SHIFT  8
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1_MASK   VC4_MASK(11, 8)
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0_SHIFT  4
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0_MASK   VC4_MASK(7, 4)
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK_SHIFT     0
> +#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK_MASK      VC4_MASK(3, 0)
> +
> +#define VC4_HDMI_TX_PHY_CTL_3_RP_SHIFT                 17
> +#define VC4_HDMI_TX_PHY_CTL_3_RP_MASK                  VC4_MASK(19, 17)
> +#define VC4_HDMI_TX_PHY_CTL_3_RZ_SHIFT                 12
> +#define VC4_HDMI_TX_PHY_CTL_3_RZ_MASK                  VC4_MASK(16, 12)
> +#define VC4_HDMI_TX_PHY_CTL_3_CP1_SHIFT                        10
> +#define VC4_HDMI_TX_PHY_CTL_3_CP1_MASK                 VC4_MASK(11, 10)
> +#define VC4_HDMI_TX_PHY_CTL_3_CP_SHIFT                 8
> +#define VC4_HDMI_TX_PHY_CTL_3_CP_MASK                  VC4_MASK(9, 8)
> +#define VC4_HDMI_TX_PHY_CTL_3_CZ_SHIFT                 6
> +#define VC4_HDMI_TX_PHY_CTL_3_CZ_MASK                  VC4_MASK(7, 6)
> +#define VC4_HDMI_TX_PHY_CTL_3_ICP_SHIFT                        0
> +#define VC4_HDMI_TX_PHY_CTL_3_ICP_MASK                 VC4_MASK(5, 0)
> +
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_MASH11_MODE          BIT(13)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VC_RANGE_EN          BIT(12)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_EMULATE_VC_LOW       BIT(11)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_EMULATE_VC_HIGH      BIT(10)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL_SHIFT                9
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL_MASK         VC4_MASK(9, 9)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_FB_DIV2          BIT(8)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_POST_DIV2                BIT(7)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_CONT_EN          BIT(6)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_0_ENA_VCO_CLK          BIT(5)
> +
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_CPP_SHIFT                    16
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_CPP_MASK                     VC4_MASK(27, 16)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY_SHIFT     14
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY_MASK      VC4_MASK(15, 14)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_ENABLE          BIT(13)
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL_SHIFT           11
> +#define VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL_MASK            VC4_MASK(12, 11)
> +
> +#define VC4_HDMI_TX_PHY_CLK_DIV_VCO_SHIFT              8
> +#define VC4_HDMI_TX_PHY_CLK_DIV_VCO_MASK               VC4_MASK(15, 8)
> +
> +#define VC4_HDMI_TX_PHY_PLL_CFG_PDIV_SHIFT             0
> +#define VC4_HDMI_TX_PHY_PLL_CFG_PDIV_MASK              VC4_MASK(3, 0)
> +
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL_MASK VC4_MASK(13, 12)
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL_SHIFT        12
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL_MASK  VC4_MASK(9, 8)
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL_SHIFT 8
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL_MASK  VC4_MASK(5, 4)
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL_SHIFT 4
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL_MASK  VC4_MASK(1, 0)
> +#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL_SHIFT 0
> +
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_MASK                VC4_MASK(27, 0)
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_SHIFT       0
> +
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_MASK                VC4_MASK(27, 0)
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_SHIFT       0
> +
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD_MASK VC4_MASK(31, 16)
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD_SHIFT        16
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD_MASK   VC4_MASK(15, 0)
> +#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD_SHIFT  0
> +
> +#define VC4_HDMI_RM_CONTROL_EN_FREEZE_COUNTERS         BIT(19)
> +#define VC4_HDMI_RM_CONTROL_EN_LOAD_INTEGRATOR         BIT(17)
> +#define VC4_HDMI_RM_CONTROL_FREE_RUN                   BIT(4)
> +
> +#define VC4_HDMI_RM_OFFSET_ONLY                                BIT(31)
> +#define VC4_HDMI_RM_OFFSET_OFFSET_SHIFT                        0
> +#define VC4_HDMI_RM_OFFSET_OFFSET_MASK                 VC4_MASK(30, 0)
> +
> +#define VC4_HDMI_RM_FORMAT_SHIFT_SHIFT                 24
> +#define VC4_HDMI_RM_FORMAT_SHIFT_MASK                  VC4_MASK(25, 24)
> +
> +#define OSCILLATOR_FREQUENCY   54000000
> +
>  void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, struct drm_display_mode *mode)
>  {
>         /* PHY should be in reset, like
> @@ -38,3 +155,366 @@ void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi)
>                    HDMI_READ(HDMI_TX_PHY_CTL_0) |
>                    VC4_HDMI_TX_PHY_RNG_PWRDN);
>  }
> +
> +static unsigned long long
> +phy_get_vco_freq(unsigned long long clock, u8 *vco_sel, u8 *vco_div)
> +{
> +       unsigned long long vco_freq = clock;
> +       unsigned int _vco_div = 0;
> +       unsigned int _vco_sel = 0;
> +
> +       while (vco_freq < 3000000000ULL) {
> +               _vco_div++;
> +               vco_freq = clock * _vco_div * 10;
> +       }
> +
> +       if (vco_freq > 4500000000ULL)
> +               _vco_sel = 1;
> +
> +       *vco_sel = _vco_sel;
> +       *vco_div = _vco_div;
> +
> +       return vco_freq;
> +}
> +
> +static u8 phy_get_cp_current(unsigned long vco_freq)
> +{
> +       if (vco_freq < 3700000000ULL)
> +               return 0x1c;
> +
> +       return 0x18;
> +}
> +
> +static u32 phy_get_rm_offset(unsigned long long vco_freq)
> +{
> +       unsigned long long fref = OSCILLATOR_FREQUENCY;
> +       u64 offset = 0;
> +
> +       /* RM offset is stored as 9.22 format */
> +       offset = vco_freq * 2;
> +       offset = offset << 22;
> +       do_div(offset, fref);
> +       offset >>= 2;
> +
> +       return offset;
> +}
> +
> +static u8 phy_get_vco_gain(unsigned long long vco_freq)
> +{
> +       if (vco_freq < 3350000000ULL)
> +               return 0xf;
> +
> +       if (vco_freq < 3700000000ULL)
> +               return 0xc;
> +
> +       if (vco_freq < 4050000000ULL)
> +               return 0x6;
> +
> +       if (vco_freq < 4800000000ULL)
> +               return 0x5;
> +
> +       if (vco_freq < 5200000000ULL)
> +               return 0x7;
> +
> +       return 0x2;
> +}
> +
> +struct phy_lane_settings {
> +       struct {
> +               u8 preemphasis;
> +               u8 main_driver;
> +       } amplitude;
> +
> +       u8 res_sel_data;
> +       u8 term_res_sel_data;
> +};
> +
> +struct phy_settings {
> +       unsigned long long min_rate;
> +       unsigned long long max_rate;
> +       struct phy_lane_settings channel[3];
> +       struct phy_lane_settings clock;
> +};
> +
> +static const struct phy_settings vc5_hdmi_phy_settings[] = {
> +       {
> +               0, 50000000,
> +               {
> +                       {{0x0, 0x0A}, 0x12, 0x0},
> +                       {{0x0, 0x0A}, 0x12, 0x0},
> +                       {{0x0, 0x0A}, 0x12, 0x0}
> +               },
> +               {{0x0, 0x0A}, 0x18, 0x0},
> +       },
> +       {
> +               50000001, 75000000,
> +               {
> +                       {{0x0, 0x09}, 0x12, 0x0},
> +                       {{0x0, 0x09}, 0x12, 0x0},
> +                       {{0x0, 0x09}, 0x12, 0x0}
> +               },
> +               {{0x0, 0x0C}, 0x18, 0x3},
> +       },
> +       {
> +               75000001,   165000000,
> +               {
> +                       {{0x0, 0x09}, 0x12, 0x0},
> +                       {{0x0, 0x09}, 0x12, 0x0},
> +                       {{0x0, 0x09}, 0x12, 0x0}
> +               },
> +               {{0x0, 0x0C}, 0x18, 0x3},
> +       },
> +       {
> +               165000001,  250000000,
> +               {
> +                       {{0x0, 0x0F}, 0x12, 0x1},
> +                       {{0x0, 0x0F}, 0x12, 0x1},
> +                       {{0x0, 0x0F}, 0x12, 0x1}
> +               },
> +               {{0x0, 0x0C}, 0x18, 0x3},
> +       },
> +       {
> +               250000001,  340000000,
> +               {
> +                       {{0x2, 0x0D}, 0x12, 0x1},
> +                       {{0x2, 0x0D}, 0x12, 0x1},
> +                       {{0x2, 0x0D}, 0x12, 0x1}
> +               },
> +               {{0x0, 0x0C}, 0x18, 0xF},
> +       },
> +       {
> +               340000001,  450000000,
> +               {
> +                       {{0x0, 0x1B}, 0x12, 0xF},
> +                       {{0x0, 0x1B}, 0x12, 0xF},
> +                       {{0x0, 0x1B}, 0x12, 0xF}
> +               },
> +               {{0x0, 0x0A}, 0x12, 0xF},
> +       },
> +       {
> +               450000001,  600000000,
> +               {
> +                       {{0x0, 0x1C}, 0x12, 0xF},
> +                       {{0x0, 0x1C}, 0x12, 0xF},
> +                       {{0x0, 0x1C}, 0x12, 0xF}
> +               },
> +               {{0x0, 0x0B}, 0x13, 0xF},
> +       },
> +};
> +
> +static const struct phy_settings *phy_get_settings(unsigned long long tmds_rate)
> +{
> +       unsigned int count = ARRAY_SIZE(vc5_hdmi_phy_settings);
> +       unsigned int i;
> +
> +       for (i = 0; i < count; i++) {
> +               const struct phy_settings *s = &vc5_hdmi_phy_settings[i];
> +
> +               if (tmds_rate >= s->min_rate && tmds_rate <= s->max_rate)
> +                       return s;
> +       }
> +
> +       /*
> +        * If the pixel clock exceeds our max setting, try the max
> +        * setting anyway.
> +        */
> +       return &vc5_hdmi_phy_settings[count - 1];
> +}
> +
> +static const struct phy_lane_settings *
> +phy_get_channel_settings(enum vc4_hdmi_phy_channel chan,
> +                        unsigned long long tmds_rate)
> +{
> +       const struct phy_settings *settings = phy_get_settings(tmds_rate);
> +
> +       if (chan == PHY_LANE_CK)
> +               return &settings->clock;
> +
> +       return &settings->channel[chan];
> +}
> +
> +static void vc5_hdmi_reset_phy(struct vc4_hdmi *vc4_hdmi)
> +{
> +       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0x0f);
> +       HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL, BIT(10));
> +}
> +
> +void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, struct drm_display_mode *mode)
> +{
> +       const struct phy_lane_settings *chan0_settings, *chan1_settings, *chan2_settings, *clock_settings;
> +       const struct vc4_hdmi_variant *variant = vc4_hdmi->variant;
> +       unsigned long long pixel_freq = mode->clock * 1000;
> +       unsigned long long vco_freq;
> +       unsigned char word_sel;
> +       u8 vco_sel, vco_div;
> +
> +       vco_freq = phy_get_vco_freq(pixel_freq, &vco_sel, &vco_div);
> +
> +       vc5_hdmi_reset_phy(vc4_hdmi);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
> +                  VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_RESET_CTL) &
> +                  ~VC4_HDMI_TX_PHY_RESET_CTL_TX_0_RESET &
> +                  ~VC4_HDMI_TX_PHY_RESET_CTL_TX_1_RESET &
> +                  ~VC4_HDMI_TX_PHY_RESET_CTL_TX_2_RESET &
> +                  ~VC4_HDMI_TX_PHY_RESET_CTL_TX_CK_RESET);
> +
> +       HDMI_WRITE(HDMI_RM_CONTROL,
> +                  HDMI_READ(HDMI_RM_CONTROL) |
> +                  VC4_HDMI_RM_CONTROL_EN_FREEZE_COUNTERS |
> +                  VC4_HDMI_RM_CONTROL_EN_LOAD_INTEGRATOR |
> +                  VC4_HDMI_RM_CONTROL_FREE_RUN);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1,
> +                  (HDMI_READ(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1) &
> +                   ~VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_MASK) |
> +                  VC4_SET_FIELD(0, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2,
> +                  (HDMI_READ(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2) &
> +                   ~VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_MASK) |
> +                  VC4_SET_FIELD(0, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT));
> +
> +       HDMI_WRITE(HDMI_RM_OFFSET,
> +                  VC4_SET_FIELD(phy_get_rm_offset(vco_freq),
> +                                VC4_HDMI_RM_OFFSET_OFFSET) |
> +                  VC4_HDMI_RM_OFFSET_ONLY);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CLK_DIV,
> +                  VC4_SET_FIELD(vco_div, VC4_HDMI_TX_PHY_CLK_DIV_VCO));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4,
> +                  VC4_SET_FIELD(0xe147, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD) |
> +                  VC4_SET_FIELD(0xe14, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CTL_0,
> +                  VC4_HDMI_TX_PHY_PLL_CTL_0_ENA_VCO_CLK |
> +                  VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_CONT_EN |
> +                  VC4_HDMI_TX_PHY_PLL_CTL_0_MASH11_MODE |
> +                  VC4_SET_FIELD(vco_sel, VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CTL_1,
> +                  HDMI_READ(HDMI_TX_PHY_PLL_CTL_1) |
> +                  VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_ENABLE |
> +                  VC4_SET_FIELD(3, VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL) |
> +                  VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY) |
> +                  VC4_SET_FIELD(0x8a, VC4_HDMI_TX_PHY_PLL_CTL_1_CPP));
> +
> +       HDMI_WRITE(HDMI_RM_FORMAT,
> +                  HDMI_READ(HDMI_RM_FORMAT) |
> +                  VC4_SET_FIELD(2, VC4_HDMI_RM_FORMAT_SHIFT));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_PLL_CFG,
> +                  HDMI_READ(HDMI_TX_PHY_PLL_CFG) |
> +                  VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_PLL_CFG_PDIV));
> +
> +       if (pixel_freq >= 340000000)
> +               word_sel = 3;
> +       else
> +               word_sel = 0;
> +       HDMI_WRITE(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, word_sel);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CTL_3,
> +                  VC4_SET_FIELD(phy_get_cp_current(vco_freq),
> +                                VC4_HDMI_TX_PHY_CTL_3_ICP) |
> +                  VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_CTL_3_CP) |
> +                  VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_CTL_3_CP1) |
> +                  VC4_SET_FIELD(3, VC4_HDMI_TX_PHY_CTL_3_CZ) |
> +                  VC4_SET_FIELD(4, VC4_HDMI_TX_PHY_CTL_3_RP) |
> +                  VC4_SET_FIELD(6, VC4_HDMI_TX_PHY_CTL_3_RZ));
> +
> +       chan0_settings =
> +               phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_0],
> +                                        pixel_freq);
> +       chan1_settings =
> +               phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_1],
> +                                        pixel_freq);
> +       chan2_settings =
> +               phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_2],
> +                                        pixel_freq);
> +       clock_settings =
> +               phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_CK],
> +                                        pixel_freq);
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CTL_0,
> +                  VC4_SET_FIELD(chan0_settings->amplitude.preemphasis,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP) |
> +                  VC4_SET_FIELD(chan0_settings->amplitude.main_driver,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV) |
> +                  VC4_SET_FIELD(chan1_settings->amplitude.preemphasis,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP) |
> +                  VC4_SET_FIELD(chan1_settings->amplitude.main_driver,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV) |
> +                  VC4_SET_FIELD(chan2_settings->amplitude.preemphasis,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP) |
> +                  VC4_SET_FIELD(chan2_settings->amplitude.main_driver,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV) |
> +                  VC4_SET_FIELD(clock_settings->amplitude.preemphasis,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP) |
> +                  VC4_SET_FIELD(clock_settings->amplitude.main_driver,
> +                                VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CTL_1,
> +                  HDMI_READ(HDMI_TX_PHY_CTL_1) |
> +                  VC4_SET_FIELD(chan0_settings->res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0) |
> +                  VC4_SET_FIELD(chan1_settings->res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1) |
> +                  VC4_SET_FIELD(chan2_settings->res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2) |
> +                  VC4_SET_FIELD(clock_settings->res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CTL_2,
> +                  VC4_SET_FIELD(chan0_settings->term_res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0) |
> +                  VC4_SET_FIELD(chan1_settings->term_res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1) |
> +                  VC4_SET_FIELD(chan2_settings->term_res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2) |
> +                  VC4_SET_FIELD(clock_settings->term_res_sel_data,
> +                                VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK) |
> +                  VC4_SET_FIELD(phy_get_vco_gain(vco_freq),
> +                                VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_CHANNEL_SWAP,
> +                  VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_0],
> +                                VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL) |
> +                  VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_1],
> +                                VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL) |
> +                  VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_2],
> +                                VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL) |
> +                  VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_CK],
> +                                VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_RESET_CTL) &
> +                  ~(VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB |
> +                    VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB));
> +
> +       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_RESET_CTL) |
> +                  VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB |
> +                  VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB);
> +}
> +
> +void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi) {
> +       vc5_hdmi_reset_phy(vc4_hdmi);
> +}
> +
> +void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi)
> +{
> +       HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) &
> +                  ~VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
> +}
> +
> +void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi)
> +{
> +       HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
> +                  HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) |
> +                  VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
> index bc47cc9bc883..a5f1354e3e06 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
> @@ -9,6 +9,12 @@ enum vc4_hdmi_regs {
>         VC4_INVALID = 0,
>         VC4_HDMI,
>         VC4_HD,
> +       VC5_CEC,
> +       VC5_CSC,
> +       VC5_DVP,
> +       VC5_PHY,
> +       VC5_RAM,
> +       VC5_RM,
>  };
>
>  enum vc4_hdmi_field {
> @@ -36,6 +42,7 @@ enum vc4_hdmi_field {
>         HDMI_CEC_TX_DATA_2,
>         HDMI_CEC_TX_DATA_3,
>         HDMI_CEC_TX_DATA_4,
> +       HDMI_CLOCK_STOP,
>         HDMI_CORE_REV,
>         HDMI_CRP_CFG,
>         HDMI_CSC_12_11,
> @@ -52,6 +59,7 @@ enum vc4_hdmi_field {
>          */
>         HDMI_CTS_0,
>         HDMI_CTS_1,
> +       HDMI_DVP_CTL,
>         HDMI_FIFO_CTL,
>         HDMI_FRAME_COUNT,
>         HDMI_HORZA,
> @@ -84,10 +92,27 @@ enum vc4_hdmi_field {
>         HDMI_RAM_PACKET_CONFIG,
>         HDMI_RAM_PACKET_START,
>         HDMI_RAM_PACKET_STATUS,
> +       HDMI_RM_CONTROL,
> +       HDMI_RM_FORMAT,
> +       HDMI_RM_OFFSET,
>         HDMI_SCHEDULER_CONTROL,
>         HDMI_SW_RESET_CONTROL,
> +       HDMI_TX_PHY_CHANNEL_SWAP,
> +       HDMI_TX_PHY_CLK_DIV,
>         HDMI_TX_PHY_CTL_0,
> +       HDMI_TX_PHY_CTL_1,
> +       HDMI_TX_PHY_CTL_2,
> +       HDMI_TX_PHY_CTL_3,
> +       HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1,
> +       HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2,
> +       HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4,
> +       HDMI_TX_PHY_PLL_CFG,
> +       HDMI_TX_PHY_PLL_CTL_0,
> +       HDMI_TX_PHY_PLL_CTL_1,
> +       HDMI_TX_PHY_POWERDOWN_CTL,
>         HDMI_TX_PHY_RESET_CTL,
> +       HDMI_TX_PHY_TMDS_CLK_WORD_SEL,
> +       HDMI_VEC_INTERFACE_XBAR,
>         HDMI_VERTA0,
>         HDMI_VERTA1,
>         HDMI_VERTB0,
> @@ -110,6 +135,12 @@ struct vc4_hdmi_register {
>
>  #define VC4_HD_REG(reg, offset)                _VC4_REG(VC4_HD, reg, offset)
>  #define VC4_HDMI_REG(reg, offset)      _VC4_REG(VC4_HDMI, reg, offset)
> +#define VC5_CEC_REG(reg, offset)       _VC4_REG(VC5_CEC, reg, offset)
> +#define VC5_CSC_REG(reg, offset)       _VC4_REG(VC5_CSC, reg, offset)
> +#define VC5_DVP_REG(reg, offset)       _VC4_REG(VC5_DVP, reg, offset)
> +#define VC5_PHY_REG(reg, offset)       _VC4_REG(VC5_PHY, reg, offset)
> +#define VC5_RAM_REG(reg, offset)       _VC4_REG(VC5_RAM, reg, offset)
> +#define VC5_RM_REG(reg, offset)                _VC4_REG(VC5_RM, reg, offset)
>
>  static const struct vc4_hdmi_register vc4_hdmi_fields[] = {
>         VC4_HD_REG(HDMI_M_CTL, 0x000c),
> @@ -172,6 +203,158 @@ static const struct vc4_hdmi_register vc4_hdmi_fields[] = {
>         VC4_HDMI_REG(HDMI_RAM_PACKET_START, 0x0400),
>  };
>
> +static const struct vc4_hdmi_register vc5_hdmi_hdmi0_fields[] = {
> +       VC4_HD_REG(HDMI_DVP_CTL, 0x0000),
> +       VC4_HD_REG(HDMI_MAI_CTL, 0x0010),
> +       VC4_HD_REG(HDMI_MAI_THR, 0x0014),
> +       VC4_HD_REG(HDMI_MAI_FMT, 0x0018),
> +       VC4_HD_REG(HDMI_MAI_DATA, 0x001c),
> +       VC4_HD_REG(HDMI_MAI_SMP, 0x0020),
> +       VC4_HD_REG(HDMI_VID_CTL, 0x0044),
> +       VC4_HD_REG(HDMI_FRAME_COUNT, 0x0060),
> +
> +       VC4_HDMI_REG(HDMI_FIFO_CTL, 0x074),
> +       VC4_HDMI_REG(HDMI_AUDIO_PACKET_CONFIG, 0x0b8),
> +       VC4_HDMI_REG(HDMI_RAM_PACKET_CONFIG, 0x0bc),
> +       VC4_HDMI_REG(HDMI_RAM_PACKET_STATUS, 0x0c4),
> +       VC4_HDMI_REG(HDMI_CRP_CFG, 0x0c8),
> +       VC4_HDMI_REG(HDMI_CTS_0, 0x0cc),
> +       VC4_HDMI_REG(HDMI_CTS_1, 0x0d0),
> +       VC4_HDMI_REG(HDMI_SCHEDULER_CONTROL, 0x0e0),
> +       VC4_HDMI_REG(HDMI_HORZA, 0x0e4),
> +       VC4_HDMI_REG(HDMI_HORZB, 0x0e8),
> +       VC4_HDMI_REG(HDMI_VERTA0, 0x0ec),
> +       VC4_HDMI_REG(HDMI_VERTB0, 0x0f0),
> +       VC4_HDMI_REG(HDMI_VERTA1, 0x0f4),
> +       VC4_HDMI_REG(HDMI_VERTB1, 0x0f8),
> +       VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c),
> +       VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
> +       VC4_HDMI_REG(HDMI_HOTPLUG, 0x1a8),
> +
> +       VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
> +       VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0),
> +
> +       VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000),
> +       VC5_PHY_REG(HDMI_TX_PHY_POWERDOWN_CTL, 0x004),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_0, 0x008),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_1, 0x00c),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_2, 0x010),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_3, 0x014),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_0, 0x01c),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_1, 0x020),
> +       VC5_PHY_REG(HDMI_TX_PHY_CLK_DIV, 0x028),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CFG, 0x034),
> +       VC5_PHY_REG(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, 0x044),
> +       VC5_PHY_REG(HDMI_TX_PHY_CHANNEL_SWAP, 0x04c),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1, 0x050),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2, 0x054),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4, 0x05c),
> +
> +       VC5_RM_REG(HDMI_RM_CONTROL, 0x000),
> +       VC5_RM_REG(HDMI_RM_OFFSET, 0x018),
> +       VC5_RM_REG(HDMI_RM_FORMAT, 0x01c),
> +
> +       VC5_RAM_REG(HDMI_RAM_PACKET_START, 0x000),
> +
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_1, 0x010),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_2, 0x014),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_3, 0x018),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_4, 0x01c),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_5, 0x020),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_1, 0x028),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_2, 0x02c),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_3, 0x030),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_4, 0x034),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_1, 0x038),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_2, 0x03c),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_3, 0x040),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_4, 0x044),
> +
> +       VC5_CSC_REG(HDMI_CSC_CTL, 0x000),
> +       VC5_CSC_REG(HDMI_CSC_12_11, 0x004),
> +       VC5_CSC_REG(HDMI_CSC_14_13, 0x008),
> +       VC5_CSC_REG(HDMI_CSC_22_21, 0x00c),
> +       VC5_CSC_REG(HDMI_CSC_24_23, 0x010),
> +       VC5_CSC_REG(HDMI_CSC_32_31, 0x014),
> +       VC5_CSC_REG(HDMI_CSC_34_33, 0x018),
> +};
> +
> +static const struct vc4_hdmi_register vc5_hdmi_hdmi1_fields[] = {
> +       VC4_HD_REG(HDMI_DVP_CTL, 0x0000),
> +       VC4_HD_REG(HDMI_MAI_CTL, 0x0030),
> +       VC4_HD_REG(HDMI_MAI_THR, 0x0034),
> +       VC4_HD_REG(HDMI_MAI_FMT, 0x0038),
> +       VC4_HD_REG(HDMI_MAI_DATA, 0x003c),
> +       VC4_HD_REG(HDMI_MAI_SMP, 0x0040),
> +       VC4_HD_REG(HDMI_VID_CTL, 0x0048),
> +       VC4_HD_REG(HDMI_FRAME_COUNT, 0x0064),
> +
> +       VC4_HDMI_REG(HDMI_FIFO_CTL, 0x074),
> +       VC4_HDMI_REG(HDMI_AUDIO_PACKET_CONFIG, 0x0b8),
> +       VC4_HDMI_REG(HDMI_RAM_PACKET_CONFIG, 0x0bc),
> +       VC4_HDMI_REG(HDMI_RAM_PACKET_STATUS, 0x0c4),
> +       VC4_HDMI_REG(HDMI_CRP_CFG, 0x0c8),
> +       VC4_HDMI_REG(HDMI_CTS_0, 0x0cc),
> +       VC4_HDMI_REG(HDMI_CTS_1, 0x0d0),
> +       VC4_HDMI_REG(HDMI_SCHEDULER_CONTROL, 0x0e0),
> +       VC4_HDMI_REG(HDMI_HORZA, 0x0e4),
> +       VC4_HDMI_REG(HDMI_HORZB, 0x0e8),
> +       VC4_HDMI_REG(HDMI_VERTA0, 0x0ec),
> +       VC4_HDMI_REG(HDMI_VERTB0, 0x0f0),
> +       VC4_HDMI_REG(HDMI_VERTA1, 0x0f4),
> +       VC4_HDMI_REG(HDMI_VERTB1, 0x0f8),
> +       VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c),
> +       VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
> +       VC4_HDMI_REG(HDMI_HOTPLUG, 0x1a8),
> +
> +       VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
> +       VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0),
> +
> +       VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000),
> +       VC5_PHY_REG(HDMI_TX_PHY_POWERDOWN_CTL, 0x004),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_0, 0x008),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_1, 0x00c),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_2, 0x010),
> +       VC5_PHY_REG(HDMI_TX_PHY_CTL_3, 0x014),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_0, 0x01c),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_1, 0x020),
> +       VC5_PHY_REG(HDMI_TX_PHY_CLK_DIV, 0x028),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CFG, 0x034),
> +       VC5_PHY_REG(HDMI_TX_PHY_CHANNEL_SWAP, 0x04c),
> +       VC5_PHY_REG(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, 0x044),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1, 0x050),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2, 0x054),
> +       VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4, 0x05c),
> +
> +       VC5_RM_REG(HDMI_RM_CONTROL, 0x000),
> +       VC5_RM_REG(HDMI_RM_OFFSET, 0x018),
> +       VC5_RM_REG(HDMI_RM_FORMAT, 0x01c),
> +
> +       VC5_RAM_REG(HDMI_RAM_PACKET_START, 0x000),
> +
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_1, 0x010),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_2, 0x014),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_3, 0x018),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_4, 0x01c),
> +       VC5_CEC_REG(HDMI_CEC_CNTRL_5, 0x020),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_1, 0x028),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_2, 0x02c),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_3, 0x030),
> +       VC5_CEC_REG(HDMI_CEC_TX_DATA_4, 0x034),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_1, 0x038),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_2, 0x03c),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_3, 0x040),
> +       VC5_CEC_REG(HDMI_CEC_RX_DATA_4, 0x044),
> +
> +       VC5_CSC_REG(HDMI_CSC_CTL, 0x000),
> +       VC5_CSC_REG(HDMI_CSC_12_11, 0x004),
> +       VC5_CSC_REG(HDMI_CSC_14_13, 0x008),
> +       VC5_CSC_REG(HDMI_CSC_22_21, 0x00c),
> +       VC5_CSC_REG(HDMI_CSC_24_23, 0x010),
> +       VC5_CSC_REG(HDMI_CSC_32_31, 0x014),
> +       VC5_CSC_REG(HDMI_CSC_34_33, 0x018),
> +};
> +
>  static inline
>  void __iomem *__vc4_hdmi_get_field_base(struct vc4_hdmi *hdmi,
>                                         enum vc4_hdmi_regs reg)
> @@ -183,6 +366,24 @@ void __iomem *__vc4_hdmi_get_field_base(struct vc4_hdmi *hdmi,
>         case VC4_HDMI:
>                 return hdmi->hdmicore_regs;
>
> +       case VC5_CSC:
> +               return hdmi->csc_regs;
> +
> +       case VC5_CEC:
> +               return hdmi->cec_regs;
> +
> +       case VC5_DVP:
> +               return hdmi->dvp_regs;
> +
> +       case VC5_PHY:
> +               return hdmi->phy_regs;
> +
> +       case VC5_RAM:
> +               return hdmi->ram_regs;
> +
> +       case VC5_RM:
> +               return hdmi->rm_regs;
> +
>         default:
>                 return NULL;
>         }
> diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
> index 30af52b406f1..be2c32a519b3 100644
> --- a/drivers/gpu/drm/vc4/vc4_regs.h
> +++ b/drivers/gpu/drm/vc4/vc4_regs.h
> @@ -744,6 +744,8 @@
>  # define VC4_HD_CSC_CTL_RGB2YCC                        BIT(1)
>  # define VC4_HD_CSC_CTL_ENABLE                 BIT(0)
>
> +# define VC4_DVP_HT_CLOCK_STOP_PIXEL           BIT(1)
> +
>  /* HVS display list information. */
>  #define HVS_BOOTLOADER_DLIST_END                32
>
> --
> git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2020-07-28 15:22 UTC|newest]

Thread overview: 432+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20200709070649epcas1p13664bacc66a0f73443bf4d3e8940f933@epcas1p1.samsung.com>
2020-07-08 17:41 ` [PATCH v4 00/78] drm/vc4: Support BCM2711 Display Pipeline Maxime Ripard
2020-07-08 17:41   ` Maxime Ripard
2020-07-08 17:41   ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 01/78] dt-bindings: display: Add support for the BCM2711 HVS Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 02/78] drm/vc4: Add support for the BCM2711 HVS5 Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 03/78] drm/vc4: hvs: Boost the core clock during modeset Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-09-01 11:21     ` Chanwoo Choi
2020-09-01 11:21       ` Chanwoo Choi
2020-09-01 11:21       ` Chanwoo Choi
2020-09-01 11:48       ` Chanwoo Choi
2020-09-01 11:48         ` Chanwoo Choi
2020-09-01 11:48         ` Chanwoo Choi
2020-09-02 14:48       ` Maxime Ripard
2020-09-02 14:48         ` Maxime Ripard
2020-09-02 14:48         ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 04/78] drm/vc4: plane: Change LBM alignment constraint on LBM Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 05/78] drm/vc4: plane: Optimize the LBM allocation size Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 06/78] drm/vc4: plane: Create more planes Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 07/78] drm/vc4: crtc: Deal with different number of pixel per clock Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 08/78] drm/vc4: crtc: Use a shared interrupt Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 09/78] drm/vc4: crtc: Move the cob allocation outside of bind Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 10/78] drm/vc4: crtc: Rename HVS channel to output Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28  9:48     ` Dave Stevenson
2020-07-28  9:48       ` Dave Stevenson
2020-07-28  9:48       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 11/78] drm/vc4: crtc: Use local chan variable Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28  9:50     ` Dave Stevenson
2020-07-28  9:50       ` Dave Stevenson
2020-07-28  9:50       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 12/78] drm/vc4: crtc: Enable and disable the PV in atomic_enable / disable Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28  9:57     ` Dave Stevenson
2020-07-28  9:57       ` Dave Stevenson
2020-07-28  9:57       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 13/78] drm/vc4: kms: Convert to for_each_new_crtc_state Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-29 15:02     ` Dave Stevenson
2020-07-29 15:02       ` Dave Stevenson
2020-07-29 15:02       ` Dave Stevenson
2020-09-02 17:59       ` Maxime Ripard
2020-09-02 17:59         ` Maxime Ripard
2020-09-02 17:59         ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 14/78] drm/vc4: crtc: Assign output to channel automatically Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-29 14:31     ` Dave Stevenson
2020-07-29 14:31       ` Dave Stevenson
2020-07-29 14:31       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 15/78] drm/vc4: crtc: Add FIFO depth to vc4_crtc_data Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 16/78] drm/vc4: crtc: Add function to compute FIFO level bits Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 17/78] drm/vc4: crtc: Rename HDMI encoder type to HDMI0 Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 18/78] drm/vc4: crtc: Add HDMI1 encoder type Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 19/78] drm/vc4: crtc: Disable color management for HVS5 Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 20/78] drm/vc4: crtc: Turn pixelvalve reset into a function Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 21/78] drm/vc4: crtc: Move PV dump to config_pv Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28 10:30     ` Dave Stevenson
2020-07-28 10:30       ` Dave Stevenson
2020-07-28 10:30       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 22/78] drm/vc4: crtc: Move HVS init and close to a function Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28 10:31     ` Dave Stevenson
2020-07-28 10:31       ` Dave Stevenson
2020-07-28 10:31       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 23/78] drm/vc4: crtc: Move the HVS gamma LUT setup to our init function Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-29 14:42     ` Dave Stevenson
2020-07-29 14:42       ` Dave Stevenson
2020-07-29 14:42       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 24/78] drm/vc4: hvs: Make sure our channel is reset Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28 10:37     ` Dave Stevenson
2020-07-28 10:37       ` Dave Stevenson
2020-07-28 10:37       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 25/78] drm/vc4: crtc: Remove mode_set_nofb Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28 10:38     ` Dave Stevenson
2020-07-28 10:38       ` Dave Stevenson
2020-07-28 10:38       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 26/78] drm/vc4: crtc: Remove redundant pixelvalve reset Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28 10:39     ` Dave Stevenson
2020-07-28 10:39       ` Dave Stevenson
2020-07-28 10:39       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 27/78] drm/vc4: crtc: Move HVS channel init before the PV initialisation Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28 10:40     ` Dave Stevenson
2020-07-28 10:40       ` Dave Stevenson
2020-07-28 10:40       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 28/78] drm/vc4: encoder: Add finer-grained encoder callbacks Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28 11:25     ` Dave Stevenson
2020-07-28 11:25       ` Dave Stevenson
2020-07-28 11:25       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 29/78] drm/vc4: crtc: Add a delay after disabling the PixelValve output Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-29 14:09     ` Dave Stevenson
2020-07-29 14:09       ` Dave Stevenson
2020-07-29 14:09       ` Dave Stevenson
2020-07-29 14:42       ` Maxime Ripard
2020-07-29 14:42         ` Maxime Ripard
2020-07-29 14:42         ` Maxime Ripard
2020-07-29 14:45         ` Dave Stevenson
2020-07-29 14:45           ` Dave Stevenson
2020-07-29 14:45           ` Dave Stevenson
2020-07-29 15:50         ` Stefan Wahren
2020-07-29 15:50           ` Stefan Wahren
2020-07-29 15:50           ` Stefan Wahren
2020-08-25 15:06           ` Maxime Ripard
2020-08-25 15:06             ` Maxime Ripard
2020-08-25 15:06             ` Maxime Ripard
2020-08-25 21:30             ` Stefan Wahren
2020-08-25 21:30               ` Stefan Wahren
2020-08-25 21:30               ` Stefan Wahren
2020-09-01  9:58               ` Maxime Ripard
2020-09-01  9:58                 ` Maxime Ripard
2020-09-01  9:58                 ` Maxime Ripard
2020-09-01 16:31                 ` Stefan Wahren
2020-09-01 16:31                   ` Stefan Wahren
2020-09-01 16:31                   ` Stefan Wahren
2020-09-02 15:08                   ` Maxime Ripard
2020-09-02 15:08                     ` Maxime Ripard
2020-09-02 15:08                     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 30/78] drm/vc4: crtc: Clear the PixelValve FIFO on disable Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28 11:40     ` Dave Stevenson
2020-07-28 11:40       ` Dave Stevenson
2020-07-28 11:40       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 31/78] drm/vc4: crtc: Clear the PixelValve FIFO during configuration Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28 11:41     ` Dave Stevenson
2020-07-28 11:41       ` Dave Stevenson
2020-07-28 11:41       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 32/78] drm/vc4: hvs: Make the stop_channel function public Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 33/78] drm/vc4: hvs: Introduce a function to get the assigned FIFO Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 34/78] drm/vc4: crtc: Move the CRTC disable out Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 35/78] drm/vc4: drv: Disable the CRTC at boot time Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 36/78] dt-bindings: display: vc4: pv: Add BCM2711 pixel valves Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 37/78] drm/vc4: crtc: Add BCM2711 pixelvalves Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 38/78] drm/vc4: hdmi: Use debugfs private field Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 39/78] drm/vc4: hdmi: Move structure to header Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 40/78] drm/vc4: hdmi: rework connectors and encoders Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28 11:58     ` Dave Stevenson
2020-07-28 11:58       ` Dave Stevenson
2020-07-28 11:58       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 41/78] drm/vc4: hdmi: Remove DDC argument to connector_init Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 42/78] drm/vc4: hdmi: Rename hdmi to vc4_hdmi Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 43/78] drm/vc4: hdmi: Move accessors " Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 44/78] drm/vc4: hdmi: Use local vc4_hdmi directly Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 45/78] drm/vc4: hdmi: Add container_of macros for encoders and connectors Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 46/78] drm/vc4: hdmi: Pass vc4_hdmi to CEC code Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 47/78] drm/vc4: hdmi: Retrieve the vc4_hdmi at unbind using our device Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28 12:32     ` Dave Stevenson
2020-07-28 12:32       ` Dave Stevenson
2020-07-28 12:32       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 48/78] drm/vc4: hdmi: Remove vc4_dev hdmi pointer Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 49/78] drm/vc4: hdmi: Remove vc4_hdmi_connector Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41   ` [PATCH v4 50/78] drm/vc4: hdmi: Introduce resource init and variant Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28 12:37     ` Dave Stevenson
2020-07-28 12:37       ` Dave Stevenson
2020-07-28 12:37       ` Dave Stevenson
2020-07-08 17:41   ` [PATCH v4 51/78] drm/vc4: hdmi: Implement a register layout abstraction Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-08 17:41     ` Maxime Ripard
2020-07-28 12:59     ` Dave Stevenson
2020-07-28 12:59       ` Dave Stevenson
2020-07-28 12:59       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 52/78] drm/vc4: hdmi: Add reset callback Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 13:00     ` Dave Stevenson
2020-07-28 13:00       ` Dave Stevenson
2020-07-28 13:00       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 53/78] drm/vc4: hdmi: Add PHY init and disable function Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 13:03     ` Dave Stevenson
2020-07-28 13:03       ` Dave Stevenson
2020-07-28 13:03       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 54/78] drm/vc4: hdmi: Add PHY RNG enable / " Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 13:04     ` Dave Stevenson
2020-07-28 13:04       ` Dave Stevenson
2020-07-28 13:04       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 55/78] drm/vc4: hdmi: Add a CSC setup callback Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 13:12     ` Dave Stevenson
2020-07-28 13:12       ` Dave Stevenson
2020-07-28 13:12       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 56/78] drm/vc4: hdmi: Store the encoder type in the variant structure Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 13:18     ` Dave Stevenson
2020-07-28 13:18       ` Dave Stevenson
2020-07-28 13:18       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 57/78] drm/vc4: hdmi: Deal with multiple debugfs files Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 13:20     ` Dave Stevenson
2020-07-28 13:20       ` Dave Stevenson
2020-07-28 13:20       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 58/78] drm/vc4: hdmi: Move CEC init to its own function Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 13:23     ` Dave Stevenson
2020-07-28 13:23       ` Dave Stevenson
2020-07-28 13:23       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 59/78] drm/vc4: hdmi: Add CEC support flag Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 13:25     ` Dave Stevenson
2020-07-28 13:25       ` Dave Stevenson
2020-07-28 13:25       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 60/78] drm/vc4: hdmi: Remove unused CEC_CLOCK_DIV define Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 13:26     ` Dave Stevenson
2020-07-28 13:26       ` Dave Stevenson
2020-07-28 13:26       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 61/78] drm/vc4: hdmi: Rename drm_encoder pointer in mode_valid Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 14:45     ` Dave Stevenson
2020-07-28 14:45       ` Dave Stevenson
2020-07-28 14:45       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 62/78] drm/vc4: hdmi: Adjust HSM clock rate depending on pixel rate Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 14:56     ` Dave Stevenson
2020-07-28 14:56       ` Dave Stevenson
2020-07-28 14:56       ` Dave Stevenson
2020-09-01  4:36     ` Chanwoo Choi
2020-09-01  4:36       ` Chanwoo Choi
2020-09-01  4:36       ` Chanwoo Choi
2020-09-01  9:45       ` Maxime Ripard
2020-09-01  9:45         ` Maxime Ripard
2020-09-01  9:45         ` Maxime Ripard
2020-09-01 10:48         ` Chanwoo Choi
2020-09-01 10:48           ` Chanwoo Choi
2020-09-01 10:48           ` Chanwoo Choi
2020-07-08 17:42   ` [PATCH v4 63/78] drm/vc4: hdmi: Use clk_set_min_rate instead Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 14:57     ` Dave Stevenson
2020-07-28 14:57       ` Dave Stevenson
2020-07-28 14:57       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 64/78] drm/vc4: hdmi: Use reg-names to retrieve the HDMI audio registers Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42   ` [PATCH v4 65/78] drm/vc4: hdmi: Reset audio infoframe on encoder_enable if previously streaming Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42   ` [PATCH v4 66/78] drm/vc4: hdmi: Set the b-frame marker to the match ALSA's default Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42   ` [PATCH v4 67/78] drm/vc4: hdmi: Add audio-related callbacks Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42   ` [PATCH v4 68/78] drm/vc4: hdmi: Deal with multiple ALSA cards Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 15:00     ` Dave Stevenson
2020-07-28 15:00       ` Dave Stevenson
2020-07-28 15:00       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 69/78] drm/vc4: hdmi: Remove register dumps in enable Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 15:01     ` Dave Stevenson
2020-07-28 15:01       ` Dave Stevenson
2020-07-28 15:01       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 70/78] drm/vc4: hdmi: Always recenter the HDMI FIFO Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 15:03     ` Dave Stevenson
2020-07-28 15:03       ` Dave Stevenson
2020-07-28 15:03       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 71/78] drm/vc4: hdmi: Implement finer-grained hooks Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 15:04     ` Dave Stevenson
2020-07-28 15:04       ` Dave Stevenson
2020-07-28 15:04       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 72/78] drm/vc4: hdmi: Do the VID_CTL configuration at once Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 15:06     ` Dave Stevenson
2020-07-28 15:06       ` Dave Stevenson
2020-07-28 15:06       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 73/78] drm/vc4: hdmi: Switch to blank pixels when disabled Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 15:09     ` Dave Stevenson
2020-07-28 15:09       ` Dave Stevenson
2020-07-28 15:09       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 74/78] drm/vc4: hdmi: Support the BCM2711 HDMI controllers Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 15:21     ` Dave Stevenson [this message]
2020-07-28 15:21       ` Dave Stevenson
2020-07-28 15:21       ` Dave Stevenson
2020-07-08 17:42   ` [PATCH v4 75/78] dt-bindings: display: vc4: hdmi: Add BCM2711 HDMI controllers bindings Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-09-01  4:45     ` Chanwoo Choi
2020-09-01  4:45       ` Chanwoo Choi
2020-09-01  4:45       ` Chanwoo Choi
2020-09-01  9:52       ` Maxime Ripard
2020-09-01  9:52         ` Maxime Ripard
2020-09-01  9:52         ` Maxime Ripard
2020-07-08 17:42   ` [PATCH v4 76/78] dt-bindings: display: vc4: Document BCM2711 VC5 Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42   ` [PATCH v4 77/78] drm/vc4: drv: Support BCM2711 Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 15:30     ` Dave Stevenson
2020-07-28 15:30       ` Dave Stevenson
2020-07-28 15:30       ` Dave Stevenson
2020-09-01 10:19       ` Maxime Ripard
2020-09-01 10:19         ` Maxime Ripard
2020-09-01 10:19         ` Maxime Ripard
2020-07-08 17:42   ` [PATCH v4 78/78] ARM: dts: bcm2711: Enable the display pipeline Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-08 17:42     ` Maxime Ripard
2020-07-28 15:35     ` Dave Stevenson
2020-07-28 15:35       ` Dave Stevenson
2020-07-28 15:35       ` Dave Stevenson
2020-07-10  7:37   ` [PATCH v4 00/78] drm/vc4: Support BCM2711 Display Pipeline Jian-Hong Pan
2020-07-10  7:37     ` Jian-Hong Pan
2020-07-10  7:37     ` Jian-Hong Pan
2020-07-10  9:58   ` Stefan Wahren
2020-07-10  9:58     ` Stefan Wahren
2020-07-10  9:58     ` Stefan Wahren
2020-08-21  7:18   ` Hoegeun Kwon
2020-08-21  7:18     ` Hoegeun Kwon
2020-08-21  7:18     ` Hoegeun Kwon
2020-09-02 13:32     ` Maxime Ripard
2020-09-02 13:32       ` Maxime Ripard
2020-09-02 13:32       ` Maxime Ripard
2020-09-02 13:52       ` Maxime Ripard
2020-09-02 13:52         ` Maxime Ripard
2020-09-02 13:52         ` Maxime Ripard
2020-08-31  2:36   ` Chanwoo Choi
2020-08-31  2:36     ` Chanwoo Choi
2020-08-31  2:36     ` Chanwoo Choi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAPY8ntA0UixNWc27-x0Y5AG_pXvzh=5spHwQ5poYLEqDzSS0WA@mail.gmail.com' \
    --to=dave.stevenson@raspberrypi.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=eric@anholt.net \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    --cc=maxime@cerno.tech \
    --cc=nsaenzjulienne@suse.de \
    --cc=phil@raspberrypi.com \
    --cc=tim.gover@raspberrypi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.