bcm27xx: update 6.1 patches from RPi foundation
[openwrt/staging/xback.git] / target / linux / bcm27xx / patches-6.1 / 950-0545-vc4-hdmi-Always-enable-GCP-with-AVMUTE-cleared.patch
1 From 3bd2ed90a679b87d4dc3fe0a70a83c323df915de Mon Sep 17 00:00:00 2001
2 From: Dom Cobley <popcornmix@gmail.com>
3 Date: Wed, 11 Jan 2023 17:30:58 +0000
4 Subject: [PATCH] vc4/hdmi: Always enable GCP with AVMUTE cleared
5
6 See: https://forum.libreelec.tv/thread/24780-le-10-0-1-rpi4-no-picture-after-update-from-le-10-0-0
7
8 Issue is some displays go blank at the point of firmware to kms handover.
9 Plugging/unplugging hdmi cable, power cycling display, or switching standby off/on
10 typically resolve this case.
11
12 Finally managed to find a display that suffers from this, and track down the issue.
13
14 The firmware uses AVMUTE in normal operation. It will set AVMUTE before disabling hdmi
15 clocks and phy. It will clear AVMUTE after clocks and phy are set up for a new hdmi mode.
16
17 But with the hdmi handover from firmware to kms, AVMUTE will be set by firmware.
18
19 kms driver typically has no GCP packet (except for deep colour modes).
20 The spec isn't clear on whether to consider the AVMUTE as continuing indefinitely
21 in the absense of a GCP packet, or to consider that state to have ended.
22
23 Most displays behave as we want, but there are a number (from mutiple manufacturers)
24 which need to see AVMUTE cleared before displaying a picture.
25
26 Lets just always enable GCP packet with AVMUTE cleared. That resolves the issue on
27 problematic displays.
28
29 From HDMI 1.4 spec:
30 A CD field of zero (Color Depth not indicated) shall be used whenever the Sink does
31 not indicate support for Deep Color. This value may also be used in Deep Color mode
32 to transmit a GCP indicating only non-Deep Color information (e.g. AVMUTE).
33
34 So use CD=0 where we were previously not enabling a GCP.
35
36 Signed-off-by: Dom Cobley <popcornmix@gmail.com>
37 ---
38 drivers/gpu/drm/vc4/vc4_hdmi.c | 18 +++++++++---------
39 1 file changed, 9 insertions(+), 9 deletions(-)
40
41 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
42 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
43 @@ -107,6 +107,10 @@
44 #define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_1_SHIFT 8
45 #define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_1_MASK VC4_MASK(15, 8)
46
47 +#define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_MASK VC4_MASK(7, 0)
48 +#define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_SET_AVMUTE BIT(0)
49 +#define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_CLEAR_AVMUTE BIT(4)
50 +
51 # define VC4_HD_M_SW_RST BIT(2)
52 # define VC4_HD_M_ENABLE BIT(0)
53
54 @@ -1559,7 +1563,6 @@ static void vc5_hdmi_set_timings(struct
55 VC4_HDMI_VERTB_VBP));
56 unsigned long flags;
57 unsigned char gcp;
58 - bool gcp_en;
59 u32 reg;
60 int idx;
61
62 @@ -1594,16 +1597,13 @@ static void vc5_hdmi_set_timings(struct
63 switch (vc4_state->output_bpc) {
64 case 12:
65 gcp = 6;
66 - gcp_en = true;
67 break;
68 case 10:
69 gcp = 5;
70 - gcp_en = true;
71 break;
72 case 8:
73 default:
74 - gcp = 4;
75 - gcp_en = false;
76 + gcp = 0;
77 break;
78 }
79
80 @@ -1612,8 +1612,7 @@ static void vc5_hdmi_set_timings(struct
81 * doesn't signal in GCP.
82 */
83 if (vc4_state->output_format == VC4_HDMI_OUTPUT_YUV422) {
84 - gcp = 4;
85 - gcp_en = false;
86 + gcp = 0;
87 }
88
89 reg = HDMI_READ(HDMI_DEEP_COLOR_CONFIG_1);
90 @@ -1626,11 +1625,12 @@ static void vc5_hdmi_set_timings(struct
91 reg = HDMI_READ(HDMI_GCP_WORD_1);
92 reg &= ~VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_1_MASK;
93 reg |= VC4_SET_FIELD(gcp, VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_1);
94 + reg &= ~VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_MASK;
95 + reg |= VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_CLEAR_AVMUTE;
96 HDMI_WRITE(HDMI_GCP_WORD_1, reg);
97
98 reg = HDMI_READ(HDMI_GCP_CONFIG);
99 - reg &= ~VC5_HDMI_GCP_CONFIG_GCP_ENABLE;
100 - reg |= gcp_en ? VC5_HDMI_GCP_CONFIG_GCP_ENABLE : 0;
101 + reg |= VC5_HDMI_GCP_CONFIG_GCP_ENABLE;
102 HDMI_WRITE(HDMI_GCP_CONFIG, reg);
103
104 reg = HDMI_READ(HDMI_MISC_CONTROL);