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/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c |   71 ++++++++++++++++++++++++++++++++---
 1 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
index 46ace54..e66df80 100644
--- a/kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
+++ b/kernel/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
@@ -246,6 +246,8 @@
 	struct phy *dcphy;
 	union phy_configure_opts phy_opts;
 
+	bool disable_hold_mode;
+	bool auto_calc_mode;
 	bool c_option;
 	bool scrambling_en;
 	unsigned int slice_width;
@@ -270,7 +272,7 @@
 	u32 lanes;
 	u32 format;
 	unsigned long mode_flags;
-
+	u64 mipi_pixel_rate;
 	const struct dw_mipi_dsi2_plat_data *pdata;
 	struct rockchip_drm_sub_dev sub_dev;
 
@@ -609,9 +611,8 @@
 
 static void dw_mipi_dsi2_phy_ratio_cfg(struct dw_mipi_dsi2 *dsi2)
 {
-	struct drm_display_mode *mode = &dsi2->mode;
 	u64 sys_clk = clk_get_rate(dsi2->sys_clk);
-	u64 pixel_clk, ipi_clk, phy_hsclk;
+	u64 ipi_clk, phy_hsclk;
 	u64 tmp;
 
 	/*
@@ -625,8 +626,9 @@
 		phy_hsclk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_hs_rate * MSEC_PER_SEC, 16);
 
 	/* IPI_RATIO_MAN_CFG = PHY_HSTX_CLK / IPI_CLK */
-	pixel_clk = mode->crtc_clock * MSEC_PER_SEC;
-	ipi_clk = pixel_clk / 4;
+	ipi_clk = dsi2->mipi_pixel_rate;
+	if (!sys_clk || !ipi_clk)
+		return;
 
 	tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, ipi_clk);
 	regmap_write(dsi2->regmap, DSI2_PHY_IPI_RATIO_MAN_CFG,
@@ -666,6 +668,10 @@
 {
 	dw_mipi_dsi2_phy_mode_cfg(dsi2);
 	dw_mipi_dsi2_phy_clk_mode_cfg(dsi2);
+
+	if (dsi2->auto_calc_mode)
+		return;
+
 	dw_mipi_dsi2_phy_ratio_cfg(dsi2);
 	dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(dsi2);
 
@@ -733,6 +739,9 @@
 	regmap_write(dsi2->regmap, DSI2_IPI_PIX_PKT_CFG, MAX_PIX_PKT(val));
 
 	dw_mipi_dsi2_ipi_color_coding_cfg(dsi2);
+
+	if (dsi2->auto_calc_mode)
+		return;
 
 	/*
 	 * if the controller is intended to operate in data stream mode,
@@ -807,7 +816,7 @@
 
 	/* there may be some timeout registers may be configured if desired */
 
-	dw_mipi_dsi2_work_mode(dsi2, MANUAL_MODE_EN);
+	dw_mipi_dsi2_work_mode(dsi2, dsi2->auto_calc_mode ? 0 : MANUAL_MODE_EN);
 	dw_mipi_dsi2_phy_init(dsi2);
 	dw_mipi_dsi2_tx_option_set(dsi2);
 	dw_mipi_dsi2_irq_enable(dsi2, 1);
@@ -830,7 +839,19 @@
 
 static void dw_mipi_dsi2_enable(struct dw_mipi_dsi2 *dsi2)
 {
+	u32 mode;
+	int ret;
+
 	dw_mipi_dsi2_ipi_set(dsi2);
+
+	if (dsi2->auto_calc_mode) {
+		regmap_write(dsi2->regmap, DSI2_MODE_CTRL, AUTOCALC_MODE);
+		ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
+					       mode, mode == IDLE_MODE,
+					       1000, MODE_STATUS_TIMEOUT_US);
+		if (ret < 0)
+			dev_err(dsi2->dev, "auto calculation training failed\n");
+	}
 
 	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO)
 		dw_mipi_dsi2_set_vid_mode(dsi2);
@@ -841,6 +862,31 @@
 		dw_mipi_dsi2_enable(dsi2->slave);
 }
 
+static void dw_mipi_dsi2_get_mipi_pixel_clk(struct dw_mipi_dsi2 *dsi2,
+					    struct rockchip_crtc_state *s)
+{
+	struct drm_display_mode *mode = &dsi2->mode;
+	u8 k = dsi2->slave ? 2 : 1;
+
+	/* 1.When MIPI works in uncompressed mode:
+	 * (Video Timing Pixel Rate)/(4)=(MIPI Pixel ClockxK)=(dclk_out×K)=dclk_core
+	 * 2.When MIPI works in compressed mode:
+	 * MIPI Pixel Clock = cds_clk / 2
+	 * MIPI is configured as double channel display mode, K=2, otherwise K=1.
+	 */
+	if (dsi2->dsc_enable) {
+		dsi2->mipi_pixel_rate = s->dsc_cds_clk_rate / 2;
+		if (dsi2->slave)
+			dsi2->slave->mipi_pixel_rate = dsi2->mipi_pixel_rate;
+
+		return;
+	}
+
+	dsi2->mipi_pixel_rate = (mode->crtc_clock * MSEC_PER_SEC) / (4 * k);
+	if (dsi2->slave)
+		dsi2->slave->mipi_pixel_rate = dsi2->mipi_pixel_rate;
+}
+
 static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2,
 					 struct drm_atomic_state *state)
 {
@@ -848,6 +894,7 @@
 	struct drm_connector *connector;
 	struct drm_connector_state *conn_state;
 	struct drm_crtc_state *crtc_state;
+	struct rockchip_crtc_state *vcstate;
 	const struct drm_display_mode *adjusted_mode;
 	struct drm_display_mode *mode = &dsi2->mode;
 
@@ -865,6 +912,7 @@
 		return -ENODEV;
 	}
 
+	vcstate = to_rockchip_crtc_state(crtc_state);
 	adjusted_mode = &crtc_state->adjusted_mode;
 	drm_mode_copy(mode, adjusted_mode);
 
@@ -873,6 +921,8 @@
 
 	if (dsi2->slave)
 		drm_mode_copy(&dsi2->slave->mode, mode);
+
+	dw_mipi_dsi2_get_mipi_pixel_clk(dsi2, vcstate);
 
 	return 0;
 }
@@ -954,7 +1004,7 @@
 	if (!(dsi2->mode_flags & MIPI_DSI_MODE_VIDEO)) {
 		s->output_flags |= ROCKCHIP_OUTPUT_MIPI_DS_MODE;
 		s->soft_te = dsi2->te_gpio ? true : false;
-		s->hold_mode = true;
+		s->hold_mode = dsi2->disable_hold_mode ? false : true;
 	}
 
 	if (dsi2->slave) {
@@ -1164,6 +1214,7 @@
 		dsi2->slave->master = dsi2;
 		dsi2->lanes /= 2;
 
+		dsi2->slave->auto_calc_mode = dsi2->auto_calc_mode;
 		dsi2->slave->lanes = dsi2->lanes;
 		dsi2->slave->channel = dsi2->channel;
 		dsi2->slave->format = dsi2->format;
@@ -1639,6 +1690,12 @@
 	dsi2->pdata = of_device_get_match_data(dev);
 	platform_set_drvdata(pdev, dsi2);
 
+	if (device_property_read_bool(dev, "auto-calculation-mode"))
+		dsi2->auto_calc_mode = true;
+
+	if (device_property_read_bool(dev, "disable-hold-mode"))
+		dsi2->disable_hold_mode = true;
+
 	if (device_property_read_bool(dev, "dual-connector-split")) {
 		dsi2->dual_connector_split = true;
 

--
Gitblit v1.6.2