* [PATCH 0/4] media: tc358743: Additional link freq, and better validation
@ 2025-06-11 18:37 Dave Stevenson
2025-06-11 18:37 ` [PATCH 1/4] media: tc358743: Add support for 972Mbit/s link freq Dave Stevenson
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Dave Stevenson @ 2025-06-11 18:37 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab
Cc: Maxime Ripard, Philipp Zabel, linux-media, linux-kernel,
Dave Stevenson
I've had these patches on our Raspberry Pi downstream kernel since
I tried upstreaming them back in 2017 [1].
Maxime's asked me to repost them as he's trying to use tc358743 with
mainline in RGB mode[2], and is hitting exactly the problems I had
written them to solve.
The issue from that series of get_mbus_config passing the number of
active data lanes has been resolved.
With regard updating the FIFO trigger level, from the previous
discussions[3]:
- Cisco's use doesn't use OF and therefore is unaffected.
- Philipp's original use case was only 720p60 and 1080p60 UYVY at
594Mbps.
Both those modes still work with the updated trigger level, but
I'm happy to revise and only use the new trigger level with the
972Mbps data rate if that is deemed necessary.
The final two patches are new but relatively trivial.
The first makes probe fails if the hardware isn't present, and the
second reports the right colorspace for the format.
Hopefully that all makes sense.
Dave
[1] https://lore.kernel.org/linux-media/cover.1505826082.git.dave.stevenson@raspberrypi.org/
[2] https://lore.kernel.org/linux-media/20250606-roaring-blue-bat-a8b2aa@houat/
[3] https://www.spinics.net/lists/linux-media/msg116360.html
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
Dave Stevenson (4):
media: tc358743: Add support for 972Mbit/s link freq
media: tc358743: Increase FIFO trigger level to 374
media: tc358743: Check I2C succeeded during probe
media: tc358743: Return an appropriate colorspace from tc358743_set_fmt
drivers/media/i2c/tc358743.c | 134 ++++++++++++++++++++++++++++---------------
1 file changed, 87 insertions(+), 47 deletions(-)
---
base-commit: 8d441742cb6a1f1cf1d8f2c73339af27dddb7cf0
change-id: 20250611-media-tc358743-07de40a814bc
Best regards,
--
Dave Stevenson <dave.stevenson@raspberrypi.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] media: tc358743: Add support for 972Mbit/s link freq
2025-06-11 18:37 [PATCH 0/4] media: tc358743: Additional link freq, and better validation Dave Stevenson
@ 2025-06-11 18:37 ` Dave Stevenson
2025-06-11 18:37 ` [PATCH 2/4] media: tc358743: Increase FIFO trigger level to 374 Dave Stevenson
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Dave Stevenson @ 2025-06-11 18:37 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab
Cc: Maxime Ripard, Philipp Zabel, linux-media, linux-kernel,
Dave Stevenson
Adds register setups for running the CSI lanes at 972Mbit/s,
which allows 1080P50 UYVY down 2 lanes.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/tc358743.c | 48 +++++++++++++++++++++++++++++++-------------
1 file changed, 34 insertions(+), 14 deletions(-)
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 3d6703b75bfa..b87db3de20db 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1993,6 +1993,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
/*
* The CSI bps per lane must be between 62.5 Mbps and 1 Gbps.
* The default is 594 Mbps for 4-lane 1080p60 or 2-lane 720p60.
+ * 972 Mbps allows 1080P50 UYVY over 2-lane.
*/
bps_pr_lane = 2 * endpoint.link_frequencies[0];
if (bps_pr_lane < 62500000U || bps_pr_lane > 1000000000U) {
@@ -2006,23 +2007,42 @@ static int tc358743_probe_of(struct tc358743_state *state)
state->pdata.refclk_hz * state->pdata.pll_prd;
/*
- * FIXME: These timings are from REF_02 for 594 Mbps per lane (297 MHz
- * link frequency). In principle it should be possible to calculate
+ * FIXME: These timings are from REF_02 for 594 or 972 Mbps per lane
+ * (297 MHz or 486 MHz link frequency).
+ * In principle it should be possible to calculate
* them based on link frequency and resolution.
*/
- if (bps_pr_lane != 594000000U)
+ switch (bps_pr_lane) {
+ default:
dev_warn(dev, "untested bps per lane: %u bps\n", bps_pr_lane);
- state->pdata.lineinitcnt = 0xe80;
- state->pdata.lptxtimecnt = 0x003;
- /* tclk-preparecnt: 3, tclk-zerocnt: 20 */
- state->pdata.tclk_headercnt = 0x1403;
- state->pdata.tclk_trailcnt = 0x00;
- /* ths-preparecnt: 3, ths-zerocnt: 1 */
- state->pdata.ths_headercnt = 0x0103;
- state->pdata.twakeup = 0x4882;
- state->pdata.tclk_postcnt = 0x008;
- state->pdata.ths_trailcnt = 0x2;
- state->pdata.hstxvregcnt = 0;
+ fallthrough;
+ case 594000000U:
+ state->pdata.lineinitcnt = 0xe80;
+ state->pdata.lptxtimecnt = 0x003;
+ /* tclk-preparecnt: 3, tclk-zerocnt: 20 */
+ state->pdata.tclk_headercnt = 0x1403;
+ state->pdata.tclk_trailcnt = 0x00;
+ /* ths-preparecnt: 3, ths-zerocnt: 1 */
+ state->pdata.ths_headercnt = 0x0103;
+ state->pdata.twakeup = 0x4882;
+ state->pdata.tclk_postcnt = 0x008;
+ state->pdata.ths_trailcnt = 0x2;
+ state->pdata.hstxvregcnt = 0;
+ break;
+ case 972000000U:
+ state->pdata.lineinitcnt = 0x1b58;
+ state->pdata.lptxtimecnt = 0x007;
+ /* tclk-preparecnt: 6, tclk-zerocnt: 40 */
+ state->pdata.tclk_headercnt = 0x2806;
+ state->pdata.tclk_trailcnt = 0x00;
+ /* ths-preparecnt: 6, ths-zerocnt: 8 */
+ state->pdata.ths_headercnt = 0x0806;
+ state->pdata.twakeup = 0x4268;
+ state->pdata.tclk_postcnt = 0x008;
+ state->pdata.ths_trailcnt = 0x5;
+ state->pdata.hstxvregcnt = 0;
+ break;
+ }
state->reset_gpio = devm_gpiod_get_optional(dev, "reset",
GPIOD_OUT_LOW);
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] media: tc358743: Increase FIFO trigger level to 374
2025-06-11 18:37 [PATCH 0/4] media: tc358743: Additional link freq, and better validation Dave Stevenson
2025-06-11 18:37 ` [PATCH 1/4] media: tc358743: Add support for 972Mbit/s link freq Dave Stevenson
@ 2025-06-11 18:37 ` Dave Stevenson
2025-06-11 18:37 ` [PATCH 3/4] media: tc358743: Check I2C succeeded during probe Dave Stevenson
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Dave Stevenson @ 2025-06-11 18:37 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab
Cc: Maxime Ripard, Philipp Zabel, linux-media, linux-kernel,
Dave Stevenson
The existing fixed value of 16 worked for UYVY 720P60 over
2 lanes at 594MHz, or UYVY 1080P60 over 4 lanes. (RGB888
1080P60 needs 6 lanes at 594MHz).
It doesn't allow for lower resolutions to work as the FIFO
underflows.
374 is required for 1080P24 or 1080P30 UYVY over 2 lanes @
972Mbit/s, but >374 means that the FIFO underflows on 1080P50
UYVY over 2 lanes @ 972Mbit/s.
Whilst it would be nice to compute it, the required information
isn't published by Toshiba.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/tc358743.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index b87db3de20db..ddba8c392ead 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1972,8 +1972,19 @@ static int tc358743_probe_of(struct tc358743_state *state)
state->pdata.refclk_hz = clk_get_rate(refclk);
state->pdata.ddc5v_delay = DDC5V_DELAY_100_MS;
state->pdata.enable_hdcp = false;
- /* A FIFO level of 16 should be enough for 2-lane 720p60 at 594 MHz. */
- state->pdata.fifo_level = 16;
+ /*
+ * Ideally the FIFO trigger level should be set based on the input and
+ * output data rates, but the calculations required are buried in
+ * Toshiba's register settings spreadsheet.
+ * A value of 16 works with a 594Mbps data rate for 720p60 (using 2
+ * lanes) and 1080p60 (using 4 lanes), but fails when the data rate
+ * is increased, or a lower pixel clock is used that result in CSI
+ * reading out faster than the data is arriving.
+ *
+ * A value of 374 works with both those modes at 594Mbps, and with most
+ * modes on 972Mbps.
+ */
+ state->pdata.fifo_level = 374;
/*
* The PLL input clock is obtained by dividing refclk by pll_prd.
* It must be between 6 MHz and 40 MHz, lower frequency is better.
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] media: tc358743: Check I2C succeeded during probe
2025-06-11 18:37 [PATCH 0/4] media: tc358743: Additional link freq, and better validation Dave Stevenson
2025-06-11 18:37 ` [PATCH 1/4] media: tc358743: Add support for 972Mbit/s link freq Dave Stevenson
2025-06-11 18:37 ` [PATCH 2/4] media: tc358743: Increase FIFO trigger level to 374 Dave Stevenson
@ 2025-06-11 18:37 ` Dave Stevenson
2025-06-11 18:37 ` [PATCH 4/4] media: tc358743: Return an appropriate colorspace from tc358743_set_fmt Dave Stevenson
2025-06-12 12:54 ` [PATCH 0/4] media: tc358743: Additional link freq, and better validation Maxime Ripard
4 siblings, 0 replies; 6+ messages in thread
From: Dave Stevenson @ 2025-06-11 18:37 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab
Cc: Maxime Ripard, Philipp Zabel, linux-media, linux-kernel,
Dave Stevenson
The probe for the TC358743 reads the CHIPID register from
the device and compares it to the expected value of 0.
If the I2C request fails then that also returns 0, so
the driver loads thinking that the device is there.
Generally I2C communications are reliable so there is
limited need to check the return value on every transfer,
therefore only amend the one read during probe to check
for I2C errors.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/tc358743.c | 27 +++++++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index ddba8c392ead..4d3dc61a9b8b 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -114,7 +114,7 @@ static inline struct tc358743_state *to_state(struct v4l2_subdev *sd)
/* --------------- I2C --------------- */
-static void i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
+static int i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
{
struct tc358743_state *state = to_state(sd);
struct i2c_client *client = state->i2c_client;
@@ -140,6 +140,7 @@ static void i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
v4l2_err(sd, "%s: reading register 0x%x from 0x%x failed: %d\n",
__func__, reg, client->addr, err);
}
+ return err != ARRAY_SIZE(msgs);
}
static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
@@ -196,15 +197,24 @@ static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
}
}
-static noinline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n)
+static noinline u32 i2c_rdreg_err(struct v4l2_subdev *sd, u16 reg, u32 n,
+ int *err)
{
+ int error;
__le32 val = 0;
- i2c_rd(sd, reg, (u8 __force *)&val, n);
+ error = i2c_rd(sd, reg, (u8 __force *)&val, n);
+ if (err)
+ *err = error;
return le32_to_cpu(val);
}
+static inline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n)
+{
+ return i2c_rdreg_err(sd, reg, n, NULL);
+}
+
static noinline void i2c_wrreg(struct v4l2_subdev *sd, u16 reg, u32 val, u32 n)
{
__le32 raw = cpu_to_le32(val);
@@ -233,6 +243,13 @@ static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg)
return i2c_rdreg(sd, reg, 2);
}
+static int i2c_rd16_err(struct v4l2_subdev *sd, u16 reg, u16 *value)
+{
+ int err;
+ *value = i2c_rdreg_err(sd, reg, 2, &err);
+ return err;
+}
+
static void i2c_wr16(struct v4l2_subdev *sd, u16 reg, u16 val)
{
i2c_wrreg(sd, reg, val, 2);
@@ -2092,6 +2109,7 @@ static int tc358743_probe(struct i2c_client *client)
struct tc358743_platform_data *pdata = client->dev.platform_data;
struct v4l2_subdev *sd;
u16 irq_mask = MASK_HDMI_MSK | MASK_CSI_MSK;
+ u16 chipid;
int err;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -2123,7 +2141,8 @@ static int tc358743_probe(struct i2c_client *client)
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
/* i2c access */
- if ((i2c_rd16(sd, CHIPID) & MASK_CHIPID) != 0) {
+ if (i2c_rd16_err(sd, CHIPID, &chipid) ||
+ (chipid & MASK_CHIPID) != 0) {
v4l2_info(sd, "not a TC358743 on address 0x%x\n",
client->addr << 1);
return -ENODEV;
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] media: tc358743: Return an appropriate colorspace from tc358743_set_fmt
2025-06-11 18:37 [PATCH 0/4] media: tc358743: Additional link freq, and better validation Dave Stevenson
` (2 preceding siblings ...)
2025-06-11 18:37 ` [PATCH 3/4] media: tc358743: Check I2C succeeded during probe Dave Stevenson
@ 2025-06-11 18:37 ` Dave Stevenson
2025-06-12 12:54 ` [PATCH 0/4] media: tc358743: Additional link freq, and better validation Maxime Ripard
4 siblings, 0 replies; 6+ messages in thread
From: Dave Stevenson @ 2025-06-11 18:37 UTC (permalink / raw)
To: Hans Verkuil, Mauro Carvalho Chehab
Cc: Maxime Ripard, Philipp Zabel, linux-media, linux-kernel,
Dave Stevenson
When calling tc358743_set_fmt, the code was calling tc358743_get_fmt
to choose a valid format. However that sets the colorspace
based on information read back from the chip, not the colour
format requested.
The result was that if you called try or set format for UYVY
when the current format was RGB3 then you would get told SRGB,
and try RGB3 when current was UYVY and you would get told
SMPTE170M.
The value programmed in the VI_REP register for the colorspace
is always set by this driver, therefore there is no need to read
back the value, and never set to REC709.
Return the colorspace based on the format set/tried instead.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/tc358743.c | 44 +++++++++++++++++---------------------------
1 file changed, 17 insertions(+), 27 deletions(-)
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 4d3dc61a9b8b..37ebc760f73b 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1708,12 +1708,23 @@ static int tc358743_enum_mbus_code(struct v4l2_subdev *sd,
return 0;
}
+static u32 tc358743_g_colorspace(u32 code)
+{
+ switch (code) {
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ return V4L2_COLORSPACE_SRGB;
+ case MEDIA_BUS_FMT_UYVY8_1X16:
+ return V4L2_COLORSPACE_SMPTE170M;
+ default:
+ return 0;
+ }
+}
+
static int tc358743_get_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *format)
{
struct tc358743_state *state = to_state(sd);
- u8 vi_rep = i2c_rd8(sd, VI_REP);
if (format->pad != 0)
return -EINVAL;
@@ -1723,23 +1734,7 @@ static int tc358743_get_fmt(struct v4l2_subdev *sd,
format->format.height = state->timings.bt.height;
format->format.field = V4L2_FIELD_NONE;
- switch (vi_rep & MASK_VOUT_COLOR_SEL) {
- case MASK_VOUT_COLOR_RGB_FULL:
- case MASK_VOUT_COLOR_RGB_LIMITED:
- format->format.colorspace = V4L2_COLORSPACE_SRGB;
- break;
- case MASK_VOUT_COLOR_601_YCBCR_LIMITED:
- case MASK_VOUT_COLOR_601_YCBCR_FULL:
- format->format.colorspace = V4L2_COLORSPACE_SMPTE170M;
- break;
- case MASK_VOUT_COLOR_709_YCBCR_FULL:
- case MASK_VOUT_COLOR_709_YCBCR_LIMITED:
- format->format.colorspace = V4L2_COLORSPACE_REC709;
- break;
- default:
- format->format.colorspace = 0;
- break;
- }
+ format->format.colorspace = tc358743_g_colorspace(format->format.code);
return 0;
}
@@ -1753,19 +1748,14 @@ static int tc358743_set_fmt(struct v4l2_subdev *sd,
u32 code = format->format.code; /* is overwritten by get_fmt */
int ret = tc358743_get_fmt(sd, sd_state, format);
- format->format.code = code;
+ if (code == MEDIA_BUS_FMT_RGB888_1X24 ||
+ code == MEDIA_BUS_FMT_UYVY8_1X16)
+ format->format.code = code;
+ format->format.colorspace = tc358743_g_colorspace(format->format.code);
if (ret)
return ret;
- switch (code) {
- case MEDIA_BUS_FMT_RGB888_1X24:
- case MEDIA_BUS_FMT_UYVY8_1X16:
- break;
- default:
- return -EINVAL;
- }
-
if (format->which == V4L2_SUBDEV_FORMAT_TRY)
return 0;
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/4] media: tc358743: Additional link freq, and better validation
2025-06-11 18:37 [PATCH 0/4] media: tc358743: Additional link freq, and better validation Dave Stevenson
` (3 preceding siblings ...)
2025-06-11 18:37 ` [PATCH 4/4] media: tc358743: Return an appropriate colorspace from tc358743_set_fmt Dave Stevenson
@ 2025-06-12 12:54 ` Maxime Ripard
4 siblings, 0 replies; 6+ messages in thread
From: Maxime Ripard @ 2025-06-12 12:54 UTC (permalink / raw)
To: Dave Stevenson
Cc: linux-kernel, linux-media, Hans Verkuil, Mauro Carvalho Chehab,
Maxime Ripard, Maxime Ripard, Philipp Zabel
On Wed, 11 Jun 2025 19:37:12 +0100, Dave Stevenson wrote:
> I've had these patches on our Raspberry Pi downstream kernel since
> I tried upstreaming them back in 2017 [1].
> Maxime's asked me to repost them as he's trying to use tc358743 with
> mainline in RGB mode[2], and is hitting exactly the problems I had
> written them to solve.
>
> [ ... ]
Tested-by: Maxime Ripard <mripard@kernel.org>
Thanks!
Maxime
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-06-12 12:54 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-11 18:37 [PATCH 0/4] media: tc358743: Additional link freq, and better validation Dave Stevenson
2025-06-11 18:37 ` [PATCH 1/4] media: tc358743: Add support for 972Mbit/s link freq Dave Stevenson
2025-06-11 18:37 ` [PATCH 2/4] media: tc358743: Increase FIFO trigger level to 374 Dave Stevenson
2025-06-11 18:37 ` [PATCH 3/4] media: tc358743: Check I2C succeeded during probe Dave Stevenson
2025-06-11 18:37 ` [PATCH 4/4] media: tc358743: Return an appropriate colorspace from tc358743_set_fmt Dave Stevenson
2025-06-12 12:54 ` [PATCH 0/4] media: tc358743: Additional link freq, and better validation Maxime Ripard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).