From 58ca4dfe8929a0fbee364bf23bedd93e259354fd Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Thu, 16 Nov 2023 07:00:30 +0000 Subject: [PATCH] drm/rockchip: dsi2: support Auto-Calculation mode the dsi2 controller can be select work in Munual or Automatic mode, by writing in MANUAL_MODE_CFG register. the Auto-Calculation mode has the following advantages: 1.Eliminates the need for the user to configure a set of registers 2.Makes the configuration routine easier, and the controller is less prone to undesired behaviors 3.Allows IPI frames to change dynamically with the controller adapting the output frames Change-Id: I00dfad82f9d5aa27abc4a2b99471ae4d6412d1b0 Signed-off-by: Guochun Huang --- .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c index 65a5d75c2e31..e66df80980f4 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c @@ -247,6 +247,7 @@ struct dw_mipi_dsi2 { union phy_configure_opts phy_opts; bool disable_hold_mode; + bool auto_calc_mode; bool c_option; bool scrambling_en; unsigned int slice_width; @@ -667,6 +668,10 @@ static void dw_mipi_dsi2_phy_init(struct dw_mipi_dsi2 *dsi2) { 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); @@ -735,6 +740,9 @@ static void dw_mipi_dsi2_ipi_set(struct dw_mipi_dsi2 *dsi2) 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, * no more steps are required. @@ -808,7 +816,7 @@ static void dw_mipi_dsi2_pre_enable(struct dw_mipi_dsi2 *dsi2) /* 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); @@ -831,8 +839,20 @@ static void dw_mipi_dsi2_pre_enable(struct dw_mipi_dsi2 *dsi2) 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); else @@ -1194,6 +1214,7 @@ static int dw_mipi_dsi2_dual_channel_probe(struct dw_mipi_dsi2 *dsi2) 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; @@ -1669,6 +1690,9 @@ static int dw_mipi_dsi2_probe(struct platform_device *pdev) 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;