bcm27xx: add support for linux v5.15
[openwrt/staging/wigyori.git] / target / linux / bcm27xx / patches-5.15 / 950-0590-drm-vc4-Move-HDMI-reset-to-pm_resume.patch
1 From 740955399f42caa6406761975656b8aa5b88a39c Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Thu, 25 Nov 2021 14:46:55 +0000
4 Subject: [PATCH] drm/vc4: Move HDMI reset to pm_resume
5
6 Pi0-3 have power domains attached to the pm_runtime hooks
7 for the HDMI block. Initialisation done in the reset called
8 from bind is therefore lost if all users of the domain are
9 suspended.
10 The VEC shares the same lowest level clock/power gating as
11 the HDMI block, so whilst that is enabled the block is never
12 actually powered down, but if it isn't enabled then we lose
13 the state.
14
15 Reset and initialise the HDMI block from pm_resume.
16
17 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
18 ---
19 drivers/gpu/drm/vc4/vc4_hdmi.c | 61 ++++++++++++++++++-----------
20 drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 4 +-
21 2 files changed, 41 insertions(+), 24 deletions(-)
22
23 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
24 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
25 @@ -2194,7 +2194,6 @@ static int vc4_hdmi_cec_init(struct vc4_
26 struct platform_device *pdev = vc4_hdmi->pdev;
27 struct device *dev = &pdev->dev;
28 unsigned long flags;
29 - u32 value;
30 int ret;
31
32 if (!of_find_property(dev->of_node, "interrupts", NULL)) {
33 @@ -2213,15 +2212,6 @@ static int vc4_hdmi_cec_init(struct vc4_
34 cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector);
35 cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info);
36
37 - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
38 - value = HDMI_READ(HDMI_CEC_CNTRL_1);
39 - /* Set the logical address to Unregistered */
40 - value |= VC4_HDMI_CEC_ADDR_MASK;
41 - HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
42 - spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
43 -
44 - vc4_hdmi_cec_update_clk_div(vc4_hdmi);
45 -
46 if (vc4_hdmi->variant->external_irq_controller) {
47 ret = request_threaded_irq(platform_get_irq_byname(pdev, "cec-rx"),
48 vc4_cec_irq_handler_rx_bare,
49 @@ -2284,6 +2274,29 @@ static void vc4_hdmi_cec_exit(struct vc4
50
51 cec_unregister_adapter(vc4_hdmi->cec_adap);
52 }
53 +
54 +static int vc4_hdmi_cec_resume(struct vc4_hdmi *vc4_hdmi)
55 +{
56 + unsigned long flags;
57 + u32 value;
58 +
59 + spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
60 + value = HDMI_READ(HDMI_CEC_CNTRL_1);
61 + /* Set the logical address to Unregistered */
62 + value |= VC4_HDMI_CEC_ADDR_MASK;
63 + HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
64 + spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
65 +
66 + vc4_hdmi_cec_update_clk_div(vc4_hdmi);
67 +
68 + if (!vc4_hdmi->variant->external_irq_controller) {
69 + spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
70 + HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff);
71 + spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
72 + }
73 +
74 + return 0;
75 +}
76 #else
77 static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
78 {
79 @@ -2292,6 +2305,10 @@ static int vc4_hdmi_cec_init(struct vc4_
80
81 static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi) {};
82
83 +static void vc4_hdmi_cec_resume(struct vc4_hdmi *vc4_hdmi)
84 +{
85 + return 0;
86 +}
87 #endif
88
89 static int vc4_hdmi_build_regset(struct vc4_hdmi *vc4_hdmi,
90 @@ -2526,6 +2543,15 @@ static int vc4_hdmi_runtime_resume(struc
91 if (ret)
92 return ret;
93
94 + if (vc4_hdmi->variant->reset)
95 + vc4_hdmi->variant->reset(vc4_hdmi);
96 +
97 + ret = vc4_hdmi_cec_resume(vc4_hdmi);
98 + if (ret) {
99 + clk_disable_unprepare(vc4_hdmi->hsm_clock);
100 + return ret;
101 + }
102 +
103 return 0;
104 }
105
106 @@ -2616,20 +2642,11 @@ static int vc4_hdmi_bind(struct device *
107 if (ret)
108 goto err_put_ddc;
109
110 - /*
111 - * We need to have the device powered up at this point to call
112 - * our reset hook and for the CEC init.
113 - */
114 - ret = vc4_hdmi_runtime_resume(dev);
115 - if (ret)
116 - goto err_put_ddc;
117 -
118 - pm_runtime_get_noresume(dev);
119 - pm_runtime_set_active(dev);
120 pm_runtime_enable(dev);
121
122 - if (vc4_hdmi->variant->reset)
123 - vc4_hdmi->variant->reset(vc4_hdmi);
124 + ret = pm_runtime_resume_and_get(dev);
125 + if (ret)
126 + goto err_put_ddc;
127
128 if ((of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi0") ||
129 of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi1")) &&
130 --- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
131 +++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
132 @@ -417,7 +417,7 @@ static inline u32 vc4_hdmi_read(struct v
133 const struct vc4_hdmi_variant *variant = hdmi->variant;
134 void __iomem *base;
135
136 - WARN_ON(!pm_runtime_active(&hdmi->pdev->dev));
137 + WARN_ON(pm_runtime_status_suspended(&hdmi->pdev->dev));
138
139 if (reg >= variant->num_registers) {
140 dev_warn(&hdmi->pdev->dev,
141 @@ -447,7 +447,7 @@ static inline void vc4_hdmi_write(struct
142
143 lockdep_assert_held(&hdmi->hw_lock);
144
145 - WARN_ON(!pm_runtime_active(&hdmi->pdev->dev));
146 + WARN_ON(pm_runtime_status_suspended(&hdmi->pdev->dev));
147
148 if (reg >= variant->num_registers) {
149 dev_warn(&hdmi->pdev->dev,