From patchwork Thu Dec 30 09:24:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajeev Nandan X-Patchwork-Id: 529296 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 06EB0C433FE for ; Thu, 30 Dec 2021 09:25:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238181AbhL3JZY (ORCPT ); Thu, 30 Dec 2021 04:25:24 -0500 Received: from alexa-out.qualcomm.com ([129.46.98.28]:21057 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238173AbhL3JZX (ORCPT ); Thu, 30 Dec 2021 04:25:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1640856323; x=1672392323; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=M9srDHgF2HXjdAEDI9jfUw9b/BSChoOvhhcJFE1IyQk=; b=JY+qGtRuB7YFfnUElTxdfhyj5zTVW7yVQetMFuUbsgSnfl1jxBQSs4bK R/7KiG79RcILmg6hNgrcCFDOm+yZHesbt45urhLY4SsSB15w6rkTU7gNE p/PrsEJaPIBVfbmqXlTsIh0vY4tdwt6C4b08/bhLg5rEVHLhFxkfsTkIa E=; Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 30 Dec 2021 01:25:23 -0800 X-QCInternal: smtphost Received: from ironmsg01-blr.qualcomm.com ([10.86.208.130]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/AES256-SHA; 30 Dec 2021 01:25:21 -0800 X-QCInternal: smtphost Received: from rajeevny-linux.qualcomm.com ([10.204.66.121]) by ironmsg01-blr.qualcomm.com with ESMTP; 30 Dec 2021 14:55:02 +0530 Received: by rajeevny-linux.qualcomm.com (Postfix, from userid 2363605) id 1F7FB21A28; Thu, 30 Dec 2021 14:55:00 +0530 (IST) From: Rajeev Nandan To: dri-devel@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, devicetree@vger.kernel.org Cc: Rajeev Nandan , linux-kernel@vger.kernel.org, sean@poorly.run, robdclark@gmail.com, robh+dt@kernel.org, robh@kernel.org, quic_abhinavk@quicinc.com, quic_kalyant@quicinc.com, quic_mkrishn@quicinc.com, jonathan@marek.ca, dmitry.baryshkov@linaro.org, airlied@linux.ie, daniel@ffwll.ch, swboyd@chromium.org Subject: [v1 1/2] dt-bindings: msm/dsi: Add 10nm dsi phy tuning properties Date: Thu, 30 Dec 2021 14:54:35 +0530 Message-Id: <1640856276-14697-2-git-send-email-quic_rajeevny@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1640856276-14697-1-git-send-email-quic_rajeevny@quicinc.com> References: <1640856276-14697-1-git-send-email-quic_rajeevny@quicinc.com> Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add 10nm dsi phy tuning properties for phy drive strength and phy drive level adjustemnt. Signed-off-by: Rajeev Nandan --- .../devicetree/bindings/display/msm/dsi-phy-10nm.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml index 4399715..9406982 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml @@ -35,6 +35,18 @@ properties: Connected to DSI0_MIPI_DSI_PLL_VDDA0P9 pin for sc7180 target and connected to VDDA_MIPI_DSI_0_PLL_0P9 pin for sdm845 target + phy-drive-strength-cfg: + type: array + description: + Register values of DSIPHY_RESCODE_OFFSET_TOP and DSIPHY_RESCODE_OFFSET_BOT + for all five lanes to adjust the phy drive strength. + + phy-drive-level-cfg: + type: array + description: + Register values of DSIPHY_RESCODE_OFFSET_TOP for all five lanes to adjust + phy drive level/amplitude. + required: - compatible - reg @@ -64,5 +76,12 @@ examples: clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, <&rpmhcc RPMH_CXO_CLK>; clock-names = "iface", "ref"; + + phy-drive-strength-cfg = [00 00 + 00 00 + 00 00 + 00 00 + 00 00]; + phy-drive-level-cfg = [59 59 59 59 59]; }; ... From patchwork Thu Dec 30 09:24:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajeev Nandan X-Patchwork-Id: 529297 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 63363C433FE for ; Thu, 30 Dec 2021 09:25:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238149AbhL3JZU (ORCPT ); Thu, 30 Dec 2021 04:25:20 -0500 Received: from alexa-out.qualcomm.com ([129.46.98.28]:21057 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238109AbhL3JZU (ORCPT ); Thu, 30 Dec 2021 04:25:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1640856320; x=1672392320; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=cJT0mRgNSm3r1hN5CeIpBXvKOVR2ymfeBG+t0V3+HQA=; b=GKkxkytsA4mCNUNstVWPLtQh3SBCbyaWQHCd8UjOyeKxuUKP7YP/3maB YjvOU+YiVJJ31Pd7KuzVoRLEwgdmyQ3kWzcNn7LpkeEF/jOD4cAlNTViR Eox3RREjfSarYOWpIuoCdo7e2QPw7U3jK4E1/EmeEOwuj/3Wa6W+V5Xoz g=; Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 30 Dec 2021 01:25:19 -0800 X-QCInternal: smtphost Received: from ironmsg01-blr.qualcomm.com ([10.86.208.130]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/AES256-SHA; 30 Dec 2021 01:25:18 -0800 X-QCInternal: smtphost Received: from rajeevny-linux.qualcomm.com ([10.204.66.121]) by ironmsg01-blr.qualcomm.com with ESMTP; 30 Dec 2021 14:55:11 +0530 Received: by rajeevny-linux.qualcomm.com (Postfix, from userid 2363605) id CDBA921A28; Thu, 30 Dec 2021 14:55:09 +0530 (IST) From: Rajeev Nandan To: dri-devel@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, devicetree@vger.kernel.org Cc: Rajeev Nandan , linux-kernel@vger.kernel.org, sean@poorly.run, robdclark@gmail.com, robh+dt@kernel.org, robh@kernel.org, quic_abhinavk@quicinc.com, quic_kalyant@quicinc.com, quic_mkrishn@quicinc.com, jonathan@marek.ca, dmitry.baryshkov@linaro.org, airlied@linux.ie, daniel@ffwll.ch, swboyd@chromium.org Subject: [v1 2/2] drm/msm/dsi: Add 10nm dsi phy tuning configuration support Date: Thu, 30 Dec 2021 14:54:36 +0530 Message-Id: <1640856276-14697-3-git-send-email-quic_rajeevny@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1640856276-14697-1-git-send-email-quic_rajeevny@quicinc.com> References: <1640856276-14697-1-git-send-email-quic_rajeevny@quicinc.com> Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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. As per the MSM DSI PHY (10nm) tuning guideline, the drive strength can be adjusted using DSIPHY_RESCODE_OFFSET_TOP & DSIPHY_RESCODE_OFFSET_BOT registers, and the drive level can be adjusted using DSIPHY_CMN_VREG_CTRL register. Add DSI PHY tuning support for 10nm PHY. This can be extended to other DSI PHY versions if needed. Signed-off-by: Rajeev Nandan --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 55 ++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 23 +++++++++++++ drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 31 +++++++++++++---- 3 files changed, 103 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 8c65ef6..bf630b7 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -669,10 +669,42 @@ static int dsi_phy_get_id(struct msm_dsi_phy *phy) return -EINVAL; } +static int dsi_phy_parse_dt_per_lane_cfgs(struct platform_device *pdev, + struct dsi_phy_per_lane_cfgs *cfg, + char *property) +{ + int i = 0, j = 0; + const u8 *data; + u32 len = 0; + + data = of_get_property(pdev->dev.of_node, property, &len); + if (!data) { + DRM_DEV_ERROR(&pdev->dev, "couldn't find %s property\n", property); + return -EINVAL; + } + + if (len != DSI_LANE_MAX * cfg->count_per_lane) { + DRM_DEV_ERROR(&pdev->dev, "incorrect phy %s settings, exp=%d, act=%d\n", + property, (DSI_LANE_MAX * cfg->count_per_lane), len); + return -EINVAL; + } + + for (i = 0; i < DSI_LANE_MAX; i++) { + for (j = 0; j < cfg->count_per_lane; j++) { + cfg->val[i][j] = *data; + data++; + } + } + + return 0; +} + static int dsi_phy_driver_probe(struct platform_device *pdev) { struct msm_dsi_phy *phy; struct device *dev = &pdev->dev; + struct dsi_phy_per_lane_cfgs *strength; + struct dsi_phy_per_lane_cfgs *level; u32 phy_type; int ret; @@ -707,6 +739,29 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) if (!of_property_read_u32(dev->of_node, "phy-type", &phy_type)) phy->cphy_mode = (phy_type == PHY_TYPE_CPHY); + /* dsi phy tuning configurations */ + if (phy->cfg->drive_strength_cfg_count) { + strength = &phy->tuning_cfg.drive_strength; + strength->count_per_lane = phy->cfg->drive_strength_cfg_count; + ret = dsi_phy_parse_dt_per_lane_cfgs(pdev, strength, + "phy-drive-strength-cfg"); + if (ret) { + DRM_DEV_ERROR(dev, "failed to parse PHY drive strength cfg, %d\n", ret); + goto fail; + } + } + + if (phy->cfg->drive_level_cfg_count) { + level = &phy->tuning_cfg.drive_level; + level->count_per_lane = phy->cfg->drive_level_cfg_count; + ret = dsi_phy_parse_dt_per_lane_cfgs(pdev, level, + "phy-drive-level-cfg"); + if (ret) { + DRM_DEV_ERROR(dev, "failed to parse PHY drive level cfg, %d\n", ret); + goto fail; + } + } + phy->base = msm_ioremap_size(pdev, "dsi_phy", "DSI_PHY", &phy->base_size); if (IS_ERR(phy->base)) { DRM_DEV_ERROR(dev, "%s: failed to map phy base\n", __func__); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index b91303a..9ff733a 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -39,6 +39,10 @@ struct msm_dsi_phy_cfg { const int quirks; bool has_phy_regulator; bool has_phy_lane; + + /* phy tuning config counts per lane */ + u32 drive_strength_cfg_count; + u32 drive_level_cfg_count; }; extern const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs; @@ -81,6 +85,24 @@ struct msm_dsi_dphy_timing { #define DSI_PIXEL_PLL_CLK 1 #define NUM_PROVIDED_CLKS 2 +#define DSI_LANE_MAX 5 +#define DSI_MAX_SETTINGS 8 + +/** + * struct dsi_phy_per_lane_cfgs - Holds register values for PHY parameters + * @val: Register values for all lanes + * @count_per_lane: Number of values per lane. + */ +struct dsi_phy_per_lane_cfgs { + u8 val[DSI_LANE_MAX][DSI_MAX_SETTINGS]; + u32 count_per_lane; +}; + +struct msm_dsi_phy_tuning_cfg { + struct dsi_phy_per_lane_cfgs drive_strength; + struct dsi_phy_per_lane_cfgs drive_level; +}; + struct msm_dsi_phy { struct platform_device *pdev; void __iomem *base; @@ -98,6 +120,7 @@ struct msm_dsi_phy { struct msm_dsi_dphy_timing timing; const struct msm_dsi_phy_cfg *cfg; + struct msm_dsi_phy_tuning_cfg tuning_cfg; enum msm_dsi_phy_usecase usecase; bool regulator_ldo_mode; 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..ac974c06 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,20 @@ 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 */ + if (phy->cfg->drive_strength_cfg_count) { + dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_TOP_CTRL(i), + phy->tuning_cfg.drive_strength.val[i][0]); + dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_BOT_CTRL(i), + phy->tuning_cfg.drive_strength.val[i][1]); + } else { + 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); + } + dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(i), tx_dctrl[i]); } @@ -834,8 +844,13 @@ 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 */ + if (phy->cfg->drive_level_cfg_count) { + dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_VREG_CTRL, + phy->tuning_cfg.drive_level.val[0][0]); + } else { + dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_VREG_CTRL, 0x59); + } /* Configure PHY lane swap (TODO: we need to calculate this) */ dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CFG0, 0x21); @@ -941,6 +956,8 @@ const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = { .max_pll_rate = 3500000000UL, .io_start = { 0xae94400, 0xae96400 }, .num_dsi_phy = 2, + .drive_strength_cfg_count = 2, + .drive_level_cfg_count = 1, }; const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs = { @@ -963,4 +980,6 @@ const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs = { .io_start = { 0xc994400, 0xc996400 }, .num_dsi_phy = 2, .quirks = DSI_PHY_10NM_QUIRK_OLD_TIMINGS, + .drive_strength_cfg_count = 2, + .drive_level_cfg_count = 1, };