Skip to content

Commit 7fa846b

Browse files
popcornmixmripard
authored andcommitted
drm/vc4: hdmi: Always enable GCP with AVMUTE cleared
Issue is some displays go blank at the point of firmware to kms handover. Plugging/unplugging hdmi cable, power cycling display, or switching standby off/on typically resolve this case. Finally managed to find a display that suffers from this, and track down the issue. The firmware uses AVMUTE in normal operation. It will set AVMUTE before disabling hdmi clocks and phy. It will clear AVMUTE after clocks and phy are set up for a new hdmi mode. But with the hdmi handover from firmware to kms, AVMUTE will be set by firmware. kms driver typically has no GCP packet (except for deep colour modes). The spec isn't clear on whether to consider the AVMUTE as continuing indefinitely in the absence of a GCP packet, or to consider that state to have ended. Most displays behave as we want, but there are a number (from multiple manufacturers) which need to see AVMUTE cleared before displaying a picture. Lets just always enable GCP packet with AVMUTE cleared. That resolves the issue on problematic displays. From HDMI 1.4 spec: A CD field of zero (Color Depth not indicated) shall be used whenever the Sink does not indicate support for Deep Color. This value may also be used in Deep Color mode to transmit a GCP indicating only non-Deep Color information (e.g. AVMUTE). So use CD=0 where we were previously not enabling a GCP. Link: https://forum.libreelec.tv/thread/24780-le-10-0-1-rpi4-no-picture-after-update-from-le-10-0-0 Signed-off-by: Dom Cobley <[email protected]> Signed-off-by: Maxime Ripard <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 6b77b16 commit 7fa846b

File tree

1 file changed

+9
-9
lines changed

1 file changed

+9
-9
lines changed

drivers/gpu/drm/vc4/vc4_hdmi.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@
9797
#define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_1_SHIFT 8
9898
#define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_1_MASK VC4_MASK(15, 8)
9999

100+
#define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_MASK VC4_MASK(7, 0)
101+
#define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_SET_AVMUTE BIT(0)
102+
#define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_CLEAR_AVMUTE BIT(4)
103+
100104
# define VC4_HD_M_SW_RST BIT(2)
101105
# define VC4_HD_M_ENABLE BIT(0)
102106

@@ -1306,7 +1310,6 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
13061310
VC4_HDMI_VERTB_VBP));
13071311
unsigned long flags;
13081312
unsigned char gcp;
1309-
bool gcp_en;
13101313
u32 reg;
13111314
int idx;
13121315

@@ -1341,16 +1344,13 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
13411344
switch (vc4_state->output_bpc) {
13421345
case 12:
13431346
gcp = 6;
1344-
gcp_en = true;
13451347
break;
13461348
case 10:
13471349
gcp = 5;
1348-
gcp_en = true;
13491350
break;
13501351
case 8:
13511352
default:
1352-
gcp = 4;
1353-
gcp_en = false;
1353+
gcp = 0;
13541354
break;
13551355
}
13561356

@@ -1359,8 +1359,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
13591359
* doesn't signal in GCP.
13601360
*/
13611361
if (vc4_state->output_format == VC4_HDMI_OUTPUT_YUV422) {
1362-
gcp = 4;
1363-
gcp_en = false;
1362+
gcp = 0;
13641363
}
13651364

13661365
reg = HDMI_READ(HDMI_DEEP_COLOR_CONFIG_1);
@@ -1373,11 +1372,12 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
13731372
reg = HDMI_READ(HDMI_GCP_WORD_1);
13741373
reg &= ~VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_1_MASK;
13751374
reg |= VC4_SET_FIELD(gcp, VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_1);
1375+
reg &= ~VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_MASK;
1376+
reg |= VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_CLEAR_AVMUTE;
13761377
HDMI_WRITE(HDMI_GCP_WORD_1, reg);
13771378

13781379
reg = HDMI_READ(HDMI_GCP_CONFIG);
1379-
reg &= ~VC5_HDMI_GCP_CONFIG_GCP_ENABLE;
1380-
reg |= gcp_en ? VC5_HDMI_GCP_CONFIG_GCP_ENABLE : 0;
1380+
reg |= VC5_HDMI_GCP_CONFIG_GCP_ENABLE;
13811381
HDMI_WRITE(HDMI_GCP_CONFIG, reg);
13821382

13831383
reg = HDMI_READ(HDMI_MISC_CONTROL);

0 commit comments

Comments
 (0)