media: i2c/platform: add V4L2_SET_EDID_HPD_LOW_JIFFIES define

HDMI receivers need to pull the HPD pin low for at least 100 ms to
indicate that a new EDID is available. In practice, HZ / 7 is a good
value for that as this gives enough slack for video sources to detect
this situation. Due to clock frequency differences and imprecise
video source implementations using exactly 100 ms (or even a bit more)
may still cause this to be missed by the video source.

Over many years HZ / 7 (143 ms) has proven to be a good safe value
for this.

Add a new #define to v4l2-dv-timings.h and modify the various drivers
that do this to use this define. Most already used HZ / 7, but some
were a bit longer.

Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
Hans Verkuil 2026-09-10 11:26:06 +02:00
parent 9ff738f930
commit c9c245a186
7 changed files with 26 additions and 10 deletions

View File

@ -2451,7 +2451,7 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
cec_s_phys_addr(state->cec_adap, parent_pa, false);
/* enable hotplug after 143 ms */
schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 7);
schedule_delayed_work(&state->delayed_work_enable_hotplug, V4L2_SET_EDID_HPD_LOW_JIFFIES);
return 0;
}

View File

@ -747,8 +747,9 @@ static int edid_write_vga_segment(struct v4l2_subdev *sd)
return -EIO;
}
/* enable hotplug after 200 ms */
schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 5);
/* enable hotplug after 143 ms */
schedule_delayed_work(&state->delayed_work_enable_hotplug,
V4L2_SET_EDID_HPD_LOW_JIFFIES);
return 0;
}
@ -830,8 +831,9 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port)
}
cec_s_phys_addr(state->cec_adap, parent_pa, false);
/* enable hotplug after 200 ms */
schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 5);
/* enable hotplug after 143 ms */
schedule_delayed_work(&state->delayed_work_enable_hotplug,
V4L2_SET_EDID_HPD_LOW_JIFFIES);
return 0;
}

View File

@ -760,7 +760,7 @@ static void it6625_disable_hpd(struct it6625 *it6625)
static void it6625_enable_hpd(struct it6625 *it6625)
{
schedule_delayed_work(&it6625->hpd_delayed_work, HZ / 7);
schedule_delayed_work(&it6625->hpd_delayed_work, V4L2_SET_EDID_HPD_LOW_JIFFIES);
}
static void it6625_hpd_delayed_work(struct work_struct *work)

View File

@ -453,7 +453,7 @@ static void tc358743_enable_edid(struct v4l2_subdev *sd)
/* Enable hotplug after 143 ms. DDC access to EDID is also enabled when
* hotplug is enabled. See register DDC_CTL */
schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 7);
schedule_delayed_work(&state->delayed_work_enable_hotplug, V4L2_SET_EDID_HPD_LOW_JIFFIES);
tc358743_enable_interrupts(sd, true);
tc358743_s_ctrl_detect_tx_5v(sd);

View File

@ -590,7 +590,7 @@ static void tda1997x_enable_edid(struct v4l2_subdev *sd)
v4l2_dbg(1, debug, sd, "%s\n", __func__);
/* Enable hotplug after 143ms */
schedule_delayed_work(&state->delayed_work_enable_hpd, HZ / 7);
schedule_delayed_work(&state->delayed_work_enable_hpd, V4L2_SET_EDID_HPD_LOW_JIFFIES);
}
/* -----------------------------------------------------------------------------

View File

@ -515,9 +515,9 @@ static void hdmirx_hpd_ctrl(struct snps_hdmirx_dev *hdmirx_dev, bool en)
hdmirx_writel(hdmirx_dev, CORE_CONFIG,
hdmirx_dev->hpd_trigger_level_high ? en : !en);
/* 100ms delay as per HDMI spec + extra 50ms to cover internal delay */
/* 100ms delay as per HDMI spec + extra 43ms to cover internal delay */
if (!en)
msleep(100 + 50);
msleep(jiffies_to_msecs(V4L2_SET_EDID_HPD_LOW_JIFFIES));
}
static void hdmirx_write_edid_data(struct snps_hdmirx_dev *hdmirx_dev,

View File

@ -252,6 +252,20 @@ v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi,
const struct hdmi_vendor_infoframe *hdmi,
unsigned int height);
/*
* The time in milliseconds that the HPD should be pulled low when writing
* a new EDID. This will tell the HDMI source that the EDID was changed and
* that it has to be re-read.
*
* The source is supposed to re-read the EDID if the HPD is low for more than
* 100 ms, but in practice the sink should pull it low for a bit longer due
* to clock differences and imprecise video source implementations.
*
* Practice has shown that setting the delay to HZ / 7 (approx 143 ms) works
* well.
*/
#define V4L2_SET_EDID_HPD_LOW_JIFFIES (HZ / 7)
unsigned int v4l2_num_edid_blocks(const u8 *edid, unsigned int max_blocks);
u16 v4l2_get_edid_phys_addr(const u8 *edid, unsigned int size,
unsigned int *offset);