[PATCH] media: tc358746: add support for 8/10/12/14-bit RAW Bayer formats

Matthias Fend posted 1 patch 11 months, 2 weeks ago
drivers/media/i2c/tc358746.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
[PATCH] media: tc358746: add support for 8/10/12/14-bit RAW Bayer formats
Posted by Matthias Fend 11 months, 2 weeks ago
The TC358746 supports RAW formats with 8, 10, 12, and 14-bit depths. Since
pixel data is transported transparently without modifying the pixel
arrangement, all Bayer patterns (RGGB, BGGR, GRBG, GBRG) are supported.

Signed-off-by: Matthias Fend <matthias.fend@emfend.at>
---
 drivers/media/i2c/tc358746.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/tc358746.c b/drivers/media/i2c/tc358746.c
index 389582420ba7..5eccd4ffd84d 100644
--- a/drivers/media/i2c/tc358746.c
+++ b/drivers/media/i2c/tc358746.c
@@ -202,6 +202,15 @@ enum {
 	PDFORMAT_YUV444,
 };
 
+#define TC358746_FORMAT_RAW(_bpp, _code)		\
+{							\
+	.code = _code,					\
+	.bus_width = _bpp,				\
+	.bpp = _bpp,					\
+	.pdformat = PDFORMAT_RAW##_bpp,			\
+	.pdataf = PDATAF_MODE0, /* don't care */	\
+}
+
 /* Check tc358746_src_mbus_code() if you add new formats */
 static const struct tc358746_format tc358746_formats[] = {
 	{
@@ -230,7 +239,23 @@ static const struct tc358746_format tc358746_formats[] = {
 		.bpp = 20,
 		.pdformat = PDFORMAT_YUV422_10BIT,
 		.pdataf = PDATAF_MODE0, /* don't care */
-	}
+	},
+	TC358746_FORMAT_RAW(8, MEDIA_BUS_FMT_SBGGR8_1X8),
+	TC358746_FORMAT_RAW(8, MEDIA_BUS_FMT_SGBRG8_1X8),
+	TC358746_FORMAT_RAW(8, MEDIA_BUS_FMT_SGRBG8_1X8),
+	TC358746_FORMAT_RAW(8, MEDIA_BUS_FMT_SRGGB8_1X8),
+	TC358746_FORMAT_RAW(10, MEDIA_BUS_FMT_SBGGR10_1X10),
+	TC358746_FORMAT_RAW(10, MEDIA_BUS_FMT_SGBRG10_1X10),
+	TC358746_FORMAT_RAW(10, MEDIA_BUS_FMT_SGRBG10_1X10),
+	TC358746_FORMAT_RAW(10, MEDIA_BUS_FMT_SRGGB10_1X10),
+	TC358746_FORMAT_RAW(12, MEDIA_BUS_FMT_SBGGR12_1X12),
+	TC358746_FORMAT_RAW(12, MEDIA_BUS_FMT_SGBRG12_1X12),
+	TC358746_FORMAT_RAW(12, MEDIA_BUS_FMT_SGRBG12_1X12),
+	TC358746_FORMAT_RAW(12, MEDIA_BUS_FMT_SRGGB12_1X12),
+	TC358746_FORMAT_RAW(14, MEDIA_BUS_FMT_SBGGR14_1X14),
+	TC358746_FORMAT_RAW(14, MEDIA_BUS_FMT_SGBRG14_1X14),
+	TC358746_FORMAT_RAW(14, MEDIA_BUS_FMT_SGRBG14_1X14),
+	TC358746_FORMAT_RAW(14, MEDIA_BUS_FMT_SRGGB14_1X14),
 };
 
 /* Get n-th format for pad */
-- 
2.34.1
Re: [PATCH] media: tc358746: add support for 8/10/12/14-bit RAW Bayer formats
Posted by Marco Felsch 11 months, 2 weeks ago
On 25-01-07, Matthias Fend wrote:
> The TC358746 supports RAW formats with 8, 10, 12, and 14-bit depths. Since
> pixel data is transported transparently without modifying the pixel
> arrangement, all Bayer patterns (RGGB, BGGR, GRBG, GBRG) are supported.
> 
> Signed-off-by: Matthias Fend <matthias.fend@emfend.at>

Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
[PATCH] media: tc358746: improve calculation of the D-PHY timing registers
Posted by Matthias Fend 11 months, 2 weeks ago
When calculating D-PHY registers, using data rates that are not multiples
of 16 can lead to precision loss in division operations. This can result in
register values that produce timing violations against the MIPI standard.

An example:
cfg->hs_clk_rate = 294MHz
hf_clk = 18

If the desired value in cfg->init is 100us, which is the minimum allowed
value, then the LINEINITCNT register is calculated as 1799. But since the
actual clock is 18.375MHz instead of 18MHz, this setting results in a time
that is shorter than 100us and thus violates the standard. The correct
value for LINEINITCNT would be 1837.

Improve the precision of calculations by using Hz instead of MHz as unit.

Signed-off-by: Matthias Fend <matthias.fend@emfend.at>
---
 drivers/media/i2c/tc358746.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/media/i2c/tc358746.c b/drivers/media/i2c/tc358746.c
index 5eccd4ffd84d..883ca40709a9 100644
--- a/drivers/media/i2c/tc358746.c
+++ b/drivers/media/i2c/tc358746.c
@@ -485,24 +485,20 @@ static int tc358746_apply_misc_config(struct tc358746 *tc358746)
 	return err;
 }
 
-/* Use MHz as base so the div needs no u64 */
-static u32 tc358746_cfg_to_cnt(unsigned int cfg_val,
-			       unsigned int clk_mhz,
-			       unsigned int time_base)
+static u32 tc358746_cfg_to_cnt(unsigned long cfg_val, unsigned long clk_hz,
+			       unsigned long long time_base)
 {
-	return DIV_ROUND_UP(cfg_val * clk_mhz, time_base);
+	return div64_u64((u64)cfg_val * clk_hz + time_base - 1, time_base);
 }
 
-static u32 tc358746_ps_to_cnt(unsigned int cfg_val,
-			      unsigned int clk_mhz)
+static u32 tc358746_ps_to_cnt(unsigned long cfg_val, unsigned long clk_hz)
 {
-	return tc358746_cfg_to_cnt(cfg_val, clk_mhz, USEC_PER_SEC);
+	return tc358746_cfg_to_cnt(cfg_val, clk_hz, PSEC_PER_SEC);
 }
 
-static u32 tc358746_us_to_cnt(unsigned int cfg_val,
-			      unsigned int clk_mhz)
+static u32 tc358746_us_to_cnt(unsigned long cfg_val, unsigned long clk_hz)
 {
-	return tc358746_cfg_to_cnt(cfg_val, clk_mhz, 1);
+	return tc358746_cfg_to_cnt(cfg_val, clk_hz, USEC_PER_SEC);
 }
 
 static int tc358746_apply_dphy_config(struct tc358746 *tc358746)
@@ -517,7 +513,6 @@ static int tc358746_apply_dphy_config(struct tc358746 *tc358746)
 
 	/* The hs_byte_clk is also called SYSCLK in the excel sheet */
 	hs_byte_clk = cfg->hs_clk_rate / 8;
-	hs_byte_clk /= HZ_PER_MHZ;
 	hf_clk = hs_byte_clk / 2;
 
 	val = tc358746_us_to_cnt(cfg->init, hf_clk) - 1;
-- 
2.34.1
Re: [PATCH] media: tc358746: improve calculation of the D-PHY timing registers
Posted by Marco Felsch 11 months, 2 weeks ago
On 25-01-07, Matthias Fend wrote:
> When calculating D-PHY registers, using data rates that are not multiples
> of 16 can lead to precision loss in division operations. This can result in
> register values that produce timing violations against the MIPI standard.
> 
> An example:
> cfg->hs_clk_rate = 294MHz
> hf_clk = 18
> 
> If the desired value in cfg->init is 100us, which is the minimum allowed
> value, then the LINEINITCNT register is calculated as 1799. But since the
> actual clock is 18.375MHz instead of 18MHz, this setting results in a time
> that is shorter than 100us and thus violates the standard. The correct
> value for LINEINITCNT would be 1837.
> 
> Improve the precision of calculations by using Hz instead of MHz as unit.
> 
> Signed-off-by: Matthias Fend <matthias.fend@emfend.at>

Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>