1 From 9fe77147d40e0dc58e7297e79ba8b50e13b8269d Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Thu, 19 Dec 2019 16:53:33 +0100
4 Subject: [PATCH] drm/vc4: hdmi: Add PHY init and disable function
6 The HDMI PHY in the BCM2711 HDMI controller is significantly more
7 complicated to setup than in the older BCM283x SoCs.
9 Let's add hooks to enable and disable the PHY.
11 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
13 drivers/gpu/drm/vc4/Makefile | 1 +
14 drivers/gpu/drm/vc4/vc4_hdmi.c | 14 +++++++-------
15 drivers/gpu/drm/vc4/vc4_hdmi.h | 13 +++++++++++++
16 drivers/gpu/drm/vc4/vc4_hdmi_phy.c | 25 +++++++++++++++++++++++++
17 4 files changed, 46 insertions(+), 7 deletions(-)
18 create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi_phy.c
20 --- a/drivers/gpu/drm/vc4/Makefile
21 +++ b/drivers/gpu/drm/vc4/Makefile
22 @@ -13,6 +13,7 @@ vc4-y := \
30 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
31 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
32 @@ -324,7 +324,9 @@ static void vc4_hdmi_encoder_disable(str
34 HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0);
36 - HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
37 + if (vc4_hdmi->variant->phy_disable)
38 + vc4_hdmi->variant->phy_disable(vc4_hdmi);
40 HDMI_WRITE(HDMI_VID_CTL,
41 HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
43 @@ -384,12 +386,8 @@ static void vc4_hdmi_encoder_enable(stru
44 if (vc4_hdmi->variant->reset)
45 vc4_hdmi->variant->reset(vc4_hdmi);
47 - /* PHY should be in reset, like
48 - * vc4_hdmi_encoder_disable() does.
50 - HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
52 - HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0);
53 + if (vc4_hdmi->variant->phy_init)
54 + vc4_hdmi->variant->phy_init(vc4_hdmi, mode);
56 if (debug_dump_regs) {
57 struct drm_printer p = drm_info_printer(&vc4_hdmi->pdev->dev);
58 @@ -1429,6 +1427,8 @@ static const struct vc4_hdmi_variant bcm
60 .init_resources = vc4_hdmi_init_resources,
61 .reset = vc4_hdmi_reset,
62 + .phy_init = vc4_hdmi_phy_init,
63 + .phy_disable = vc4_hdmi_phy_disable,
66 static const struct of_device_id vc4_hdmi_dt_match[] = {
67 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
68 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
69 @@ -21,6 +21,8 @@ to_vc4_hdmi_encoder(struct drm_encoder *
70 return container_of(encoder, struct vc4_hdmi_encoder, base.base);
73 +struct drm_display_mode;
76 struct vc4_hdmi_register;
78 @@ -38,6 +40,13 @@ struct vc4_hdmi_variant {
80 /* Callback to reset the HDMI block */
81 void (*reset)(struct vc4_hdmi *vc4_hdmi);
83 + /* Callback to initialize the PHY according to the mode */
84 + void (*phy_init)(struct vc4_hdmi *vc4_hdmi,
85 + struct drm_display_mode *mode);
87 + /* Callback to disable the PHY */
88 + void (*phy_disable)(struct vc4_hdmi *vc4_hdmi);
91 /* HDMI audio information */
92 @@ -95,4 +104,8 @@ encoder_to_vc4_hdmi(struct drm_encoder *
93 return container_of(_encoder, struct vc4_hdmi, encoder);
96 +void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
97 + struct drm_display_mode *mode);
98 +void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
100 #endif /* _VC4_HDMI_H_ */
102 +++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
104 +// SPDX-License-Identifier: GPL-2.0
106 + * Copyright (C) 2015 Broadcom
107 + * Copyright (c) 2014 The Linux Foundation. All rights reserved.
108 + * Copyright (C) 2013 Red Hat
109 + * Author: Rob Clark <robdclark@gmail.com>
112 +#include "vc4_hdmi.h"
113 +#include "vc4_hdmi_regs.h"
115 +void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, struct drm_display_mode *mode)
117 + /* PHY should be in reset, like
118 + * vc4_hdmi_encoder_disable() does.
121 + HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
122 + HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0);
125 +void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi)
127 + HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);