The HDMI PHY in the BCM2711 HDMI controller is significantly more
complicated to setup than in the older BCM283x SoCs.

Let's add hooks to enable and disable the PHY.

Signed-off-by: Maxime Ripard <max...@cerno.tech>
---
 drivers/gpu/drm/vc4/Makefile       |  1 +
 drivers/gpu/drm/vc4/vc4_hdmi.c     | 14 +++++++-------
 drivers/gpu/drm/vc4/vc4_hdmi.h     | 13 +++++++++++++
 drivers/gpu/drm/vc4/vc4_hdmi_phy.c | 25 +++++++++++++++++++++++++
 4 files changed, 46 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi_phy.c

diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
index b303703bc7f3..d0163e18e9ca 100644
--- a/drivers/gpu/drm/vc4/Makefile
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -12,6 +12,7 @@ vc4-y := \
        vc4_kms.o \
        vc4_gem.o \
        vc4_hdmi.o \
+       vc4_hdmi_phy.o \
        vc4_vec.o \
        vc4_hvs.o \
        vc4_irq.o \
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 80bc3dd9d4a8..068041145d1c 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -321,7 +321,9 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder 
*encoder)
 
        HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0);
 
-       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
+       if (vc4_hdmi->variant->phy_disable)
+               vc4_hdmi->variant->phy_disable(vc4_hdmi);
+
        HDMI_WRITE(HDMI_VID_CTL,
                   HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
 
@@ -381,12 +383,8 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
*encoder)
        if (vc4_hdmi->variant->reset)
                vc4_hdmi->variant->reset(vc4_hdmi);
 
-       /* PHY should be in reset, like
-        * vc4_hdmi_encoder_disable() does.
-        */
-       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
-
-       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0);
+       if (vc4_hdmi->variant->phy_init)
+               vc4_hdmi->variant->phy_init(vc4_hdmi, mode);
 
        if (debug_dump_regs) {
                struct drm_printer p = drm_info_printer(&vc4_hdmi->pdev->dev);
@@ -1433,6 +1431,8 @@ static const struct vc4_hdmi_variant bcm2835_variant = {
 
        .init_resources         = vc4_hdmi_init_resources,
        .reset                  = vc4_hdmi_reset,
+       .phy_init               = vc4_hdmi_phy_init,
+       .phy_disable            = vc4_hdmi_phy_disable,
 };
 
 static const struct of_device_id vc4_hdmi_dt_match[] = {
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index 17a30589f39c..32c80161c786 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -21,6 +21,8 @@ to_vc4_hdmi_encoder(struct drm_encoder *encoder)
        return container_of(encoder, struct vc4_hdmi_encoder, base.base);
 }
 
+struct drm_display_mode;
+
 struct vc4_hdmi;
 struct vc4_hdmi_register;
 
@@ -38,6 +40,13 @@ struct vc4_hdmi_variant {
 
        /* Callback to reset the HDMI block */
        void (*reset)(struct vc4_hdmi *vc4_hdmi);
+
+       /* Callback to initialize the PHY according to the mode */
+       void (*phy_init)(struct vc4_hdmi *vc4_hdmi,
+                        struct drm_display_mode *mode);
+
+       /* Callback to disable the PHY */
+       void (*phy_disable)(struct vc4_hdmi *vc4_hdmi);
 };
 
 /* HDMI audio information */
@@ -95,4 +104,8 @@ encoder_to_vc4_hdmi(struct drm_encoder *encoder)
        return container_of(_encoder, struct vc4_hdmi, encoder);
 }
 
+void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
+                      struct drm_display_mode *mode);
+void vc4_hdmi_phy_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
new file mode 100644
index 000000000000..5a1746877bb5
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2015 Broadcom
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdcl...@gmail.com>
+ */
+
+#include "vc4_hdmi.h"
+#include "vc4_hdmi_regs.h"
+
+void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, struct drm_display_mode 
*mode)
+{
+       /* PHY should be in reset, like
+        * vc4_hdmi_encoder_disable() does.
+        */
+
+       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
+       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0);
+}
+
+void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi)
+{
+       HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
+}
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to