From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 03 Jan 2024 09:43:39 +0000
Subject: [PATCH] update kernel to 5.10.198

---
 kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c |   96 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c b/kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c
index 5734902..8776401 100644
--- a/kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c
+++ b/kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c
@@ -11,6 +11,82 @@
 
 #include "maxim4c_api.h"
 
+static int maxim4c_txphy_init_timing(maxim4c_t *maxim4c)
+{
+	struct i2c_client *client = maxim4c->client;
+	int ret = 0;
+	u16 reg_addr = 0;
+	u8 reg_mask;
+	u8 timing;
+	u8 phy_idx = 0;
+
+	if (!maxim4c->mipi_txphy.timing_override_en)
+		return 0;
+
+	timing = ((maxim4c->mipi_txphy.timing.t_hs_przero & 0x3) << 6 |
+		  (maxim4c->mipi_txphy.timing.t_hs_prep & 0x3) << 4 |
+		  (maxim4c->mipi_txphy.timing.t_clk_trail & 0x3) << 2 |
+		  (maxim4c->mipi_txphy.timing.t_clk_przero & 0x3) << 0);
+
+	ret |= maxim4c_i2c_write_byte(client, 0x08A1,
+				      MAXIM4C_I2C_REG_ADDR_16BITS, timing);
+
+	reg_mask = 0x0F;
+	timing = ((maxim4c->mipi_txphy.timing.t_lpx & 0x3) << 2 |
+		  (maxim4c->mipi_txphy.timing.t_hs_trail & 0x3) << 0);
+
+	ret |= maxim4c_i2c_update_byte(
+		client, 0x08A2, MAXIM4C_I2C_REG_ADDR_16BITS, reg_mask, timing);
+
+	reg_mask = (0x3 << 6);
+	timing = (maxim4c->mipi_txphy.timing.t_lpxesc & 0x3) << 6;
+	ret |= maxim4c_i2c_update_byte(
+		client, 0x08A5, MAXIM4C_I2C_REG_ADDR_16BITS, reg_mask, timing);
+
+	reg_mask = (0x7 << 5);
+	timing = (maxim4c->mipi_txphy.timing.t_lpxesc & 0x7) << 5;
+	ret |= maxim4c_i2c_update_byte(
+		client, 0x08A8, MAXIM4C_I2C_REG_ADDR_16BITS, reg_mask, timing);
+
+	for (phy_idx = 0; phy_idx < MAXIM4C_TXPHY_ID_MAX; phy_idx++) {
+		reg_mask = 0xFF;
+		reg_addr = 0x0905 + 0x40 * phy_idx;
+		timing = maxim4c->mipi_txphy.timing.csi2_t_pre;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       reg_mask, timing);
+
+		reg_addr = 0x0906 + 0x40 * phy_idx;
+		timing = maxim4c->mipi_txphy.timing.csi2_t_post;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       reg_mask, timing);
+
+		reg_addr = 0x0907 + 0x40 * phy_idx;
+		timing = maxim4c->mipi_txphy.timing.csi2_tx_gap;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       reg_mask, timing);
+
+		reg_addr = 0x0908 + 0x40 * phy_idx;
+		timing = maxim4c->mipi_txphy.timing.csi2_twakeup & 0xFF;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       reg_mask, timing);
+		timing = (maxim4c->mipi_txphy.timing.csi2_twakeup >> 8) & 0xFF;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr + 1,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       reg_mask, timing);
+		reg_mask = 0x7;
+		timing = (maxim4c->mipi_txphy.timing.csi2_twakeup >> 16) & 0x7;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr + 2,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       reg_mask, timing);
+	}
+
+	return ret;
+}
+
 static int maxim4c_txphy_auto_init_deskew(maxim4c_t *maxim4c)
 {
 	struct i2c_client *client = maxim4c->client;
@@ -182,6 +258,11 @@
 				reg_addr, MAXIM4C_I2C_REG_ADDR_16BITS,
 				0xf4);
 
+		reg_addr = 0x1C03 + 0x100 * phy_idx;
+		ret |= maxim4c_i2c_update_byte(client, reg_addr,
+					       MAXIM4C_I2C_REG_ADDR_16BITS,
+					       0x07, phy_cfg->ssc_ratio);
+
 		// Set dpll data rate
 		reg_addr = 0x0415 + 0x03 * phy_idx;
 		ret |= maxim4c_i2c_update_byte(client,
@@ -349,6 +430,12 @@
 				phy_cfg->clock_mode = value;
 			}
 
+			ret = of_property_read_u32(node, "ssc-ratio", &value);
+			if (ret == 0) {
+				dev_info(dev, "ssc-ratio property: %d", value);
+				phy_cfg->ssc_ratio = value;
+			}
+
 			sub_idx++;
 		}
 	}
@@ -510,6 +597,9 @@
 	// mipi txphy auto init deskew
 	ret |= maxim4c_txphy_auto_init_deskew(maxim4c);
 
+	// mipi txphy timing init
+	ret |= maxim4c_txphy_init_timing(maxim4c);
+
 	if (ret) {
 		dev_err(dev, "%s: txphy hw init error\n", __func__);
 		return ret;
@@ -529,6 +619,11 @@
 	mipi_txphy->force_clock_out_en = 1;
 	mipi_txphy->force_clk0_en = 0;
 	mipi_txphy->force_clk3_en = 0;
+	mipi_txphy->timing.t_lpx = 1;
+	mipi_txphy->timing.csi2_t_pre = 0x71;
+	mipi_txphy->timing.csi2_t_post = 0x19;
+	mipi_txphy->timing.csi2_tx_gap = 0x1C;
+	mipi_txphy->timing.csi2_twakeup = 0x100;
 
 	for (i = 0; i < MAXIM4C_TXPHY_ID_MAX; i++) {
 		phy_cfg = &mipi_txphy->phy_cfg[i];
@@ -541,6 +636,7 @@
 		phy_cfg->vc_ext_en = 0;
 		phy_cfg->clock_master = 0;
 		phy_cfg->clock_mode = MAXIM4C_TXPHY_DPLL_PREDEF;
+		phy_cfg->ssc_ratio = 0;
 	}
 }
 EXPORT_SYMBOL(maxim4c_mipi_txphy_data_init);

--
Gitblit v1.6.2