2022-01-10 12:58:36

by Rajeev Nandan

[permalink] [raw]
Subject: [v2 0/3] drm/msm/dsi: Add 10nm dsi phy tuning configuration support

This series is to add DSI PHY tuning support in Qualcomm Snapdragon
SoCs with 10nm DSI PHY e.g. SC7180

In most cases the default values of DSI PHY tuning registers
should be sufficient as they are fully optimized. However, in
some cases (for example, where extreme board parasitics cause
the eye shape to degrade), the override bits can be used to
improve the signal quality.

Different DSI PHY versions have different configurations to adjust the
drive strength, drive level, de-emphasis, etc. The current series has only
those configuration options supported by 10nm PHY, e.g. drive strength and
drive level. The number of registers to configure the drive strength are
different for 7nm PHY. The design can be extended to other DSI PHY versions
if required, as each PHY version can have its callback to get the input
from DT and prepare register values.

Changes in v2:
- Addressed dt-bindings comments (Stephen Boyd, Dmitry Baryshkov)
- Split into generic code and 10nm-specific part (Dmitry Baryshkov)
- Fix the backward compatibility (Dmitry Baryshkov)

Rajeev Nandan (3):
dt-bindings: msm/dsi: Add 10nm dsi phy tuning properties
drm/msm/dsi: Add dsi phy tuning configuration support
drm/msm/dsi: Add 10nm dsi phy tuning configuration support

.../bindings/display/msm/dsi-phy-10nm.yaml | 33 ++++++++++++++
drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 3 ++
drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 16 +++++++
drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 51 +++++++++++++++++++---
4 files changed, 97 insertions(+), 6 deletions(-)

--
2.7.4



2022-01-10 13:00:06

by Rajeev Nandan

[permalink] [raw]
Subject: [v2 3/3] drm/msm/dsi: Add 10nm dsi phy tuning configuration support

The clock and data lanes of the DSI PHY have a calibration circuitry
feature. As per the MSM DSI PHY tuning guidelines, the drive strength
tuning can be done by adjusting rescode offset for hstop/hsbot, and
the drive level tuning can be done by adjusting the LDO output level
for the HSTX drive.

Signed-off-by: Rajeev Nandan <[email protected]>
---

Changes in v2:
- Split into generic code and 10nm-specific part (Dmitry Baryshkov)
- Fix the backward compatibility (Dmitry Baryshkov)

drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 51 ++++++++++++++++++++++++++----
1 file changed, 45 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
index d8128f5..40cd0f7 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
@@ -775,10 +775,13 @@ static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy)
dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG2(i), 0x0);
dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG3(i),
i == 4 ? 0x80 : 0x0);
- dsi_phy_write(lane_base +
- REG_DSI_10nm_PHY_LN_OFFSET_TOP_CTRL(i), 0x0);
- dsi_phy_write(lane_base +
- REG_DSI_10nm_PHY_LN_OFFSET_BOT_CTRL(i), 0x0);
+
+ /* platform specific dsi phy drive strength adjustment */
+ dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_TOP_CTRL(i),
+ phy->tuning_cfg.rescode_offset_top[i]);
+ dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_BOT_CTRL(i),
+ phy->tuning_cfg.rescode_offset_bot[i]);
+
dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(i),
tx_dctrl[i]);
}
@@ -834,8 +837,9 @@ static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy,
/* Select MS1 byte-clk */
dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_GLBL_CTRL, 0x10);

- /* Enable LDO */
- dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_VREG_CTRL, 0x59);
+ /* Enable LDO with platform specific drive level/amplitude adjustment */
+ dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_VREG_CTRL,
+ phy->tuning_cfg.vreg_ctrl);

/* Configure PHY lane swap (TODO: we need to calculate this) */
dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CFG0, 0x21);
@@ -922,6 +926,39 @@ static void dsi_10nm_phy_disable(struct msm_dsi_phy *phy)
DBG("DSI%d PHY disabled", phy->id);
}

+static void dsi_10nm_phy_tuning_cfg_init(struct msm_dsi_phy *phy)
+{
+ struct device *dev = &phy->pdev->dev;
+ u8 offset_top[DSI_LANE_MAX] = { 0 }; /* No offset */
+ u8 offset_bot[DSI_LANE_MAX] = { 0 }; /* No offset */
+ u8 ldo_level = 0x1; /* 400mV */
+ int ret, i;
+
+ /* Drive strength adjustment parameters */
+ ret = of_property_read_u8_array(dev->of_node, "phy-resocde-offset-top",
+ offset_top, DSI_LANE_MAX);
+ if (ret && ret != -EINVAL)
+ DRM_DEV_ERROR(dev, "failed to parse phy-resocde-offset-top, %d\n", ret);
+
+ for (i = 0; i < DSI_LANE_MAX; i++)
+ phy->tuning_cfg.rescode_offset_top[i] = 0x3f & offset_top[i];
+
+ ret = of_property_read_u8_array(dev->of_node, "phy-resocde-offset-bot",
+ offset_bot, DSI_LANE_MAX);
+ if (ret && ret != -EINVAL)
+ DRM_DEV_ERROR(dev, "failed to parse phy-resocde-offset-bot, %d\n", ret);
+
+ for (i = 0; i < DSI_LANE_MAX; i++)
+ phy->tuning_cfg.rescode_offset_bot[i] = 0x3f & offset_bot[i];
+
+ /* Drive level/amplitude adjustment parameters */
+ ret = of_property_read_u8(dev->of_node, "phy-drive-ldo-level", &ldo_level);
+ if (ret && ret != -EINVAL)
+ DRM_DEV_ERROR(dev, "failed to parse phy-drive-ldo-level, %d\n", ret);
+
+ phy->tuning_cfg.vreg_ctrl = 0x58 | (0x7 & ldo_level);
+}
+
const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = {
.has_phy_lane = true,
.reg_cfg = {
@@ -936,6 +973,7 @@ const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = {
.pll_init = dsi_pll_10nm_init,
.save_pll_state = dsi_10nm_pll_save_state,
.restore_pll_state = dsi_10nm_pll_restore_state,
+ .tuning_cfg_init = dsi_10nm_phy_tuning_cfg_init,
},
.min_pll_rate = 1000000000UL,
.max_pll_rate = 3500000000UL,
@@ -957,6 +995,7 @@ const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs = {
.pll_init = dsi_pll_10nm_init,
.save_pll_state = dsi_10nm_pll_save_state,
.restore_pll_state = dsi_10nm_pll_restore_state,
+ .tuning_cfg_init = dsi_10nm_phy_tuning_cfg_init,
},
.min_pll_rate = 1000000000UL,
.max_pll_rate = 3500000000UL,
--
2.7.4