Skip to content

Commit 1db1cfa

Browse files
smazurov911gt3
andauthored
media: rockchip: hdmirx: add DT-driven edid-version + set 600M for OPi5U (#488)
* media: rockchip: hdmirx: add edid version to disable NV24 Add two new EDID variants (HDMIRX_EDID_340M_NV12 = 3 and HDMIRX_EDID_600M_NV12 = 4) that omit the YCbCr 4:4:4 (NV24) capability bit and let the driver fix up the EDID checksum accordingly. Read the selected variant from the new `edid-version` DT property on the hdmirx_ctrler node so per-board defaults can be chosen without requiring userspace to poke the edid sysfs file at boot. This is a direct prerequisite for board DTS files that want to advertise a default EDID other than the hard-coded 340MHz variant. Signed-off-by: jensen <jensenhuang@friendlyarm.com> [smazurov@gmail.com: cherry-picked unmodified from friendlyarm/kernel-rockchip commit ee391fb22 on branch nanopi6-v6.1.y. Applies cleanly on top of armbian/linux-rockchip rk-6.1-rkr5.1 (with offsets, due to subsequent unrelated drift). Tested on Orange Pi 5 Ultra (RK3588) with both 1080p60 and 4K60 HDMI sources; required by the companion DTS patch which sets edid-version = <2> for OPi5U.] Tested-by: Stepan Mazurov <smazurov@gmail.com> Signed-off-by: Stepan Mazurov <smazurov@gmail.com> * arm64: dts: rockchip: opi5-ultra: default hdmirx edid-version to 600M Set edid-version = <2> (HDMIRX_EDID_600M) on the hdmirx_ctrler node so the default EDID advertised to upstream HDMI sources includes the TMDS-up-to-600MHz block (covering 4K@60 modes), instead of the driver's built-in HDMIRX_EDID_340M default which advertises only up to TMDS 340MHz (1080p60 / 4K@30). Symptom without this property on Orange Pi 5 Ultra: a 4K-capable HDMI source (tested with a Linux desktop pushing 3840x2160@60 from a discrete GPU) cycles indefinitely between TMDS-valid and TMDS-invalid states. The hdmirx PHY rejects the source's 4K stream because the EDID the source read did not advertise 4K support, yet the source insists on 4K based on its own display configuration. Writing "2" to /sys/devices/platform/fdee0000.hdmirx-controller/hdmirx/hdmirx/edid at runtime resolves the symptom immediately and stably; this DTS change makes the runtime fix the default at boot. The Rock 5B+ and NanoPC-T6 board DTS files already set similar edid-version properties; Orange Pi 5 Ultra was missing the equivalent. Depends on the rk_hdmirx driver reading edid-version from DT (prerequisite patch: cherry-pick of friendlyarm/kernel-rockchip commit ee391fb22 in the companion patch). Tested-by: Stepan Mazurov <smazurov@gmail.com> Signed-off-by: Stepan Mazurov <smazurov@gmail.com> --------- Signed-off-by: jensen <jensenhuang@friendlyarm.com> Signed-off-by: Stepan Mazurov <smazurov@gmail.com> Co-authored-by: jensen <jensenhuang@friendlyarm.com>
1 parent 6475fed commit 1db1cfa

2 files changed

Lines changed: 43 additions & 6 deletions

File tree

arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-ultra.dts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,6 +1400,7 @@
14001400
/* Should work with at least 128MB cma reserved above. */
14011401
&hdmirx_ctrler {
14021402
#sound-dai-cells = <1>;
1403+
edid-version = <2>;
14031404
/* Effective level used to trigger HPD: 0-low, 1-high */
14041405
hpd-trigger-level = <1>;
14051406
hdmirx-det-gpios = <&gpio3 RK_PD3 GPIO_ACTIVE_LOW>;

drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ enum hdmirx_edid_version {
148148
HDMIRX_EDID_USER = 0,
149149
HDMIRX_EDID_340M = 1,
150150
HDMIRX_EDID_600M = 2,
151+
HDMIRX_EDID_340M_NV12 = 3,
152+
HDMIRX_EDID_600M_NV12 = 4,
151153
};
152154

153155
struct hdmirx_reg_table {
@@ -4003,7 +4005,6 @@ static int hdmirx_parse_dt(struct rk_hdmirx_dev *hdmirx_dev)
40034005
return PTR_ERR(hdmirx_dev->rst_biu);
40044006
}
40054007

4006-
40074008
hdmirx_dev->hdmirx_det_gpio = devm_gpiod_get_optional(dev,
40084009
"hdmirx-det", GPIOD_IN);
40094010
if (IS_ERR(hdmirx_dev->hdmirx_det_gpio)) {
@@ -4039,6 +4040,8 @@ static int hdmirx_parse_dt(struct rk_hdmirx_dev *hdmirx_dev)
40394040
if (of_property_read_bool(np, "cec-enable"))
40404041
hdmirx_dev->cec_enable = true;
40414042

4043+
of_property_read_u32(np, "edid-version", &hdmirx_dev->edid_version);
4044+
40424045
ret = of_reserved_mem_device_init(dev);
40434046
if (ret)
40444047
dev_warn(dev, "No reserved memory for HDMIRX, use default CMA\n");
@@ -4098,19 +4101,51 @@ static int hdmirx_power_on(struct rk_hdmirx_dev *hdmirx_dev)
40984101
return 0;
40994102
}
41004103

4104+
static void hdmirx_fixup_edid(struct rk_hdmirx_dev *hdmirx_dev,
4105+
u8 *edid, int edid_len)
4106+
{
4107+
int i;
4108+
u8 sum;
4109+
4110+
/* CTA Extension data format */
4111+
#define EDID_CEA_YCRCB444 (1 << 5)
4112+
4113+
if (hdmirx_dev->edid_version == HDMIRX_EDID_340M ||
4114+
hdmirx_dev->edid_version == HDMIRX_EDID_600M)
4115+
edid[131] |= EDID_CEA_YCRCB444;
4116+
else
4117+
edid[131] &= ~EDID_CEA_YCRCB444;
4118+
4119+
/* update checksum */
4120+
for (i = 0, sum = 0; i < edid_len - 1; i++)
4121+
sum += edid[i];
4122+
4123+
edid[i] = 0x100 - sum;
4124+
}
4125+
41014126
static void hdmirx_edid_init_config(struct rk_hdmirx_dev *hdmirx_dev)
41024127
{
41034128
int ret;
41044129
struct v4l2_edid def_edid;
4130+
u8 *edid_data;
4131+
int edid_len;
41054132

41064133
/* disable hpd and write edid */
41074134
def_edid.pad = 0;
41084135
def_edid.start_block = 0;
41094136
def_edid.blocks = EDID_NUM_BLOCKS_MAX;
4110-
if (hdmirx_dev->edid_version == HDMIRX_EDID_600M)
4111-
def_edid.edid = edid_init_data_600M;
4112-
else
4113-
def_edid.edid = edid_init_data_340M;
4137+
4138+
if (hdmirx_dev->edid_version == HDMIRX_EDID_600M ||
4139+
hdmirx_dev->edid_version == HDMIRX_EDID_600M_NV12) {
4140+
edid_data = edid_init_data_600M;
4141+
edid_len = sizeof(edid_init_data_600M);
4142+
} else {
4143+
edid_data = edid_init_data_340M;
4144+
edid_len = sizeof(edid_init_data_340M);
4145+
}
4146+
hdmirx_fixup_edid(hdmirx_dev, edid_data, edid_len);
4147+
4148+
def_edid.edid = edid_data;
41144149
ret = hdmirx_write_edid(hdmirx_dev, &def_edid, false);
41154150
if (ret)
41164151
dev_err(hdmirx_dev->dev, "%s write edid failed!\n", __func__);
@@ -4244,7 +4279,8 @@ static ssize_t edid_store(struct device *dev,
42444279
if (kstrtoint(buf, 10, &edid))
42454280
return -EINVAL;
42464281

4247-
if (edid != HDMIRX_EDID_340M && edid != HDMIRX_EDID_600M)
4282+
if (edid != HDMIRX_EDID_340M && edid != HDMIRX_EDID_340M_NV12 &&
4283+
edid != HDMIRX_EDID_600M && edid != HDMIRX_EDID_600M_NV12)
42484284
return count;
42494285

42504286
if (hdmirx_dev->edid_version != edid) {

0 commit comments

Comments
 (0)