From 506966f9ffe70479617de1044cd602f04c14f776 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megi@xff.cz>
Date: Thu, 26 May 2022 20:11:10 +0200
Subject: [PATCH 353/389] media: i2c: imx258: Fix smaller formats corruption
 issues

I've messed up MIPI data rate settings. Unmess them.

Also DIG_CROP_X_OFFSET was causing corruption issues with
smaller, binned/scaled formats.

Signed-off-by: Ondrej Jirman <megi@xff.cz>
---
 drivers/media/i2c/imx258.c | 123 ++++++++++++++++++-------------------
 1 file changed, 60 insertions(+), 63 deletions(-)

diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index 9bc948038459..83068d1033ea 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -171,35 +171,6 @@ struct imx258_mode {
 	struct imx258_reg_list reg_list;
 };
 
-/* 4032*3024 needs 1267Mbps/lane, 4 lanes */
-static const struct imx258_reg mipi_data_rate_1267mbps[] = {
-	REG8(IVTPXCK_DIV, 5),
-	REG8(IVTSYCK_DIV, 2),
-	REG8(PREPLLCK_VT_DIV, 4),
-	REG16(PLL_IVT_MPY, 208), // 1296 MHz
-	REG8(IOPPXCK_DIV, 10), // or 8
-	REG8(IOPSYCK_DIV, 1),
-	REG8(PREPLLCK_OP_DIV, 2),
-	REG16(PLL_IOP_MPY, 216),
-	REG8(PLL_MULT_DRIV, 0),
-	REG16(REQ_LINK_BIT_RATE_MBPS_H, 4992),
-	REG16(REQ_LINK_BIT_RATE_MBPS_L, 0),
-};
-
-static const struct imx258_reg mipi_data_rate_640mbps[] = {
-	REG8(IVTPXCK_DIV, 5),
-	REG8(IVTSYCK_DIV, 2),
-	REG8(PREPLLCK_VT_DIV, 4),
-	REG16(PLL_IVT_MPY, 107),
-	REG8(IOPPXCK_DIV, 10),
-	REG8(IOPSYCK_DIV, 1),
-	REG8(PREPLLCK_OP_DIV, 2),
-	REG16(PLL_IOP_MPY, 216),
-	REG8(PLL_MULT_DRIV, 0),
-	REG16(REQ_LINK_BIT_RATE_MBPS_H, 2568),
-	REG16(REQ_LINK_BIT_RATE_MBPS_L, 0),
-};
-
 static const struct imx258_reg common_regs[] = {
 	REG8(EXCK_FREQ, 24),
 	REG8(EXCK_FREQ+1, 0),
@@ -502,7 +473,7 @@ static const struct imx258_reg mode_4208x3118_regs[] = {
 };
 
 static const struct imx258_reg mode_4032x3024_regs[] = {
-	REG16(CSI_DT_FMT, 0x0a0a), // 2570
+	REG16(CSI_DT_FMT, 0x0a0a),
 	REG8(CSI_LANE_MODE, 0x03),
 	REG16(LINE_LENGTH_PCK, 5352),
 	REG16(FRM_LENGTH_LINES, 3224),
@@ -548,7 +519,7 @@ static const struct imx258_reg mode_2104_1560_regs[] = {
 	REG8(BINNING_TYPE_V, 0x12),
 	REG8(SCALE_MODE, 1),
 	REG16(SCALE_M, 32),
-	REG16(DIG_CROP_X_OFFSET, 2),
+	REG16(DIG_CROP_X_OFFSET, 0),
 	REG16(DIG_CROP_Y_OFFSET, 0),
 	REG16(DIG_CROP_IMAGE_WIDTH, 4208),
 	REG16(DIG_CROP_IMAGE_HEIGHT, 1560),
@@ -578,7 +549,7 @@ static const struct imx258_reg mode_1048_780_regs[] = {
 	REG8(BINNING_TYPE_V, 0x14),
 	REG8(SCALE_MODE, 0x01),
 	REG16(SCALE_M, 64),
-	REG16(DIG_CROP_X_OFFSET, 6),
+	REG16(DIG_CROP_X_OFFSET, 0),
 	REG16(DIG_CROP_Y_OFFSET, 0),
 	REG16(DIG_CROP_IMAGE_WIDTH, 4192),
 	REG16(DIG_CROP_IMAGE_HEIGHT, 780),
@@ -599,47 +570,60 @@ static const char * const imx258_test_pattern_menu[] = {
 	"Pseudorandom Sequence (PN9)",
 };
 
-/* Configurations for supported link frequencies */
-#define IMX258_LINK_FREQ_634MHZ	633600000ULL
-#define IMX258_LINK_FREQ_320MHZ	320000000ULL
-
 enum {
-	IMX258_LINK_FREQ_1267MBPS,
-	IMX258_LINK_FREQ_640MBPS,
+	IMX258_LINK_FREQ_1224MBPS,
+	IMX258_LINK_FREQ_642MBPS,
 };
 
-/*
- * pixel_rate = link_freq * data-rate * nr_of_lanes / bits_per_sample
- * data rate => double data rate; number of lanes => 4; bits per pixel => 10
- */
-static u64 link_freq_to_pixel_rate(u64 f)
-{
-	f *= 2 * 4;
-	do_div(f, 10);
-
-	return f;
-}
-
 /* Menu items for LINK_FREQ V4L2 control */
 static const s64 link_freq_menu_items[] = {
-	IMX258_LINK_FREQ_634MHZ,
-	IMX258_LINK_FREQ_320MHZ,
+	612000000ULL,
+	321000000ULL,
+};
+
+/* 4032*3024 needs 1224 Mbps/lane, 4 lanes */
+static const struct imx258_reg mipi_data_rate_1224mbps[] = {
+	REG8(IVTPXCK_DIV, 5),
+	REG8(IVTSYCK_DIV, 2),
+	REG8(PREPLLCK_VT_DIV, 4),
+	REG16(PLL_IVT_MPY, 204), // 1224 MHz
+	REG8(IOPPXCK_DIV, 10), // or 8
+	REG8(IOPSYCK_DIV, 1),
+	REG8(PREPLLCK_OP_DIV, 2),
+	REG16(PLL_IOP_MPY, 216),
+	REG8(PLL_MULT_DRIV, 0),
+	REG16(REQ_LINK_BIT_RATE_MBPS_H, 1224*4),
+	REG16(REQ_LINK_BIT_RATE_MBPS_L, 0),
+};
+
+static const struct imx258_reg mipi_data_rate_642mbps[] = {
+	REG8(IVTPXCK_DIV, 5),
+	REG8(IVTSYCK_DIV, 2),
+	REG8(PREPLLCK_VT_DIV, 4),
+	REG16(PLL_IVT_MPY, 107),
+	REG8(IOPPXCK_DIV, 10),
+	REG8(IOPSYCK_DIV, 1),
+	REG8(PREPLLCK_OP_DIV, 2),
+	REG16(PLL_IOP_MPY, 216),
+	REG8(PLL_MULT_DRIV, 0),
+	REG16(REQ_LINK_BIT_RATE_MBPS_H, 2568),
+	REG16(REQ_LINK_BIT_RATE_MBPS_L, 0),
 };
 
 /* Link frequency configs */
 static const struct imx258_link_freq_config link_freq_configs[] = {
-	[IMX258_LINK_FREQ_1267MBPS] = {
+	[IMX258_LINK_FREQ_1224MBPS] = {
 		.pixels_per_line = IMX258_PPL_DEFAULT,
 		.reg_list = {
-			.num_of_regs = ARRAY_SIZE(mipi_data_rate_1267mbps),
-			.regs = mipi_data_rate_1267mbps,
+			.num_of_regs = ARRAY_SIZE(mipi_data_rate_1224mbps),
+			.regs = mipi_data_rate_1224mbps,
 		}
 	},
-	[IMX258_LINK_FREQ_640MBPS] = {
+	[IMX258_LINK_FREQ_642MBPS] = {
 		.pixels_per_line = IMX258_PPL_DEFAULT,
 		.reg_list = {
-			.num_of_regs = ARRAY_SIZE(mipi_data_rate_640mbps),
-			.regs = mipi_data_rate_640mbps,
+			.num_of_regs = ARRAY_SIZE(mipi_data_rate_642mbps),
+			.regs = mipi_data_rate_642mbps,
 		}
 	},
 };
@@ -655,7 +639,7 @@ static const struct imx258_mode supported_modes[] = {
 			.num_of_regs = ARRAY_SIZE(mode_4208x3118_regs),
 			.regs = mode_4208x3118_regs,
 		},
-		.link_freq_index = IMX258_LINK_FREQ_1267MBPS,
+		.link_freq_index = IMX258_LINK_FREQ_1224MBPS,
 	},
 	{
 		.width = 4032,
@@ -666,7 +650,7 @@ static const struct imx258_mode supported_modes[] = {
 			.num_of_regs = ARRAY_SIZE(mode_4032x3024_regs),
 			.regs = mode_4032x3024_regs,
 		},
-		.link_freq_index = IMX258_LINK_FREQ_1267MBPS,
+		.link_freq_index = IMX258_LINK_FREQ_1224MBPS,
 	},
 	{
 		.width = 2104,
@@ -677,7 +661,7 @@ static const struct imx258_mode supported_modes[] = {
 			.num_of_regs = ARRAY_SIZE(mode_2104_1560_regs),
 			.regs = mode_2104_1560_regs,
 		},
-		.link_freq_index = IMX258_LINK_FREQ_640MBPS,
+		.link_freq_index = IMX258_LINK_FREQ_642MBPS,
 	},
 	{
 		.width = 1048,
@@ -688,10 +672,22 @@ static const struct imx258_mode supported_modes[] = {
 			.num_of_regs = ARRAY_SIZE(mode_1048_780_regs),
 			.regs = mode_1048_780_regs,
 		},
-		.link_freq_index = IMX258_LINK_FREQ_640MBPS,
+		.link_freq_index = IMX258_LINK_FREQ_642MBPS,
 	},
 };
 
+/*
+ * pixel_rate = link_freq * data-rate * nr_of_lanes / bits_per_sample
+ * data rate => double data rate; number of lanes => 4; bits per pixel => 10
+ */
+static u64 link_freq_to_pixel_rate(u64 f)
+{
+	f *= 2 * 4;
+	do_div(f, 10);
+
+	return f;
+}
+
 /* regulator supplies */
 static const char * const imx258_supply_names[] = {
 	"vana", /* Analog (2.8V) supply */
@@ -1328,7 +1324,8 @@ static int imx258_init_controls(struct imx258 *imx258)
 		imx258->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 
 	pixel_rate_max = link_freq_to_pixel_rate(link_freq_menu_items[0]);
-	pixel_rate_min = link_freq_to_pixel_rate(link_freq_menu_items[1]);
+	pixel_rate_min = link_freq_to_pixel_rate(
+		link_freq_menu_items[ARRAY_SIZE(link_freq_menu_items) - 1]);
 	/* By default, PIXEL_RATE is read only */
 	imx258->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
 				V4L2_CID_PIXEL_RATE,
-- 
2.35.3

