Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/msm: dsi: fix PLL init in bonded mode

When in bonded DSI mode, only one PLL in one DSI PHY is used for both
DSI PHYs, meaning that parents of the secondary DSI PHY will use the
primary DSI PHY PLL as parent.

In this case the primary DSI PHY PLL will be set even if the primary
DSI PHY is not yet enabled. The DSI PHY code has support for this
particular use-case and will handle the fact the PLL was already
set when initializing the primary DSI PHY.

By introducing a protected variable pll_enable_cnt in the commit
cb55f39bf7b1 ("drm/msm/dsi/phy: Fix reading zero as PLL rates when unprepared"),
this variable is only initially set to 1 when the DSI PHY is initialized
making it impossible to set the PLL before, breaking the bonded DSI
use case by returning 0 when setting the PLL from the secondary DSI
PHY driver and skipping the correct clocks initialization.

But since it was already possible to set the PLL without enabling
the DSI PHY, just drop the pll_enable_cnt setting from the PHY
enable/disable and simply increment/decrement the pll_enable_cnt
variable from the dsi_pll_enable/disable_pll_bias to make sure any
PLL operation is done with the PLL BIAS enabled.

Fixes: cb55f39bf7b1 ("drm/msm/dsi/phy: Fix reading zero as PLL rates when unprepared")
Closes: https://lore.kernel.org/all/50a49d72-2b1e-471d-b0c4-d5a0b38b2a21@linaro.org/
Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/683688/
Link: https://lore.kernel.org/r/20251027-topic-sm8x50-fix-dsi-bonded-v1-1-a477cd3f907d@linaro.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>

authored by

Neil Armstrong and committed by
Dmitry Baryshkov
93c97bc8 00d5f097

+2 -17
-1
drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
··· 109 109 struct msm_dsi_dphy_timing timing; 110 110 const struct msm_dsi_phy_cfg *cfg; 111 111 void *tuning_cfg; 112 - void *pll_data; 113 112 114 113 enum msm_dsi_phy_usecase usecase; 115 114 bool regulator_ldo_mode;
+2 -16
drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
··· 426 426 u32 data; 427 427 428 428 spin_lock_irqsave(&pll->pll_enable_lock, flags); 429 - if (pll->pll_enable_cnt++) { 430 - spin_unlock_irqrestore(&pll->pll_enable_lock, flags); 431 - WARN_ON(pll->pll_enable_cnt == INT_MAX); 432 - return; 433 - } 429 + pll->pll_enable_cnt++; 430 + WARN_ON(pll->pll_enable_cnt == INT_MAX); 434 431 435 432 data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0); 436 433 data |= DSI_7nm_PHY_CMN_CTRL_0_PLL_SHUTDOWNB; ··· 873 876 spin_lock_init(&pll_7nm->pll_enable_lock); 874 877 875 878 pll_7nm->phy = phy; 876 - phy->pll_data = pll_7nm; 877 879 878 880 ret = pll_7nm_register(pll_7nm, phy->provided_clocks->hws); 879 881 if (ret) { ··· 961 965 u32 const delay_us = 5; 962 966 u32 const timeout_us = 1000; 963 967 struct msm_dsi_dphy_timing *timing = &phy->timing; 964 - struct dsi_pll_7nm *pll = phy->pll_data; 965 968 void __iomem *base = phy->base; 966 969 bool less_than_1500_mhz; 967 - unsigned long flags; 968 970 u32 vreg_ctrl_0, vreg_ctrl_1, lane_ctrl0; 969 971 u32 glbl_pemph_ctrl_0; 970 972 u32 glbl_str_swi_cal_sel_ctrl, glbl_hstx_str_ctrl_0; ··· 1084 1090 glbl_rescode_bot_ctrl = 0x3c; 1085 1091 } 1086 1092 1087 - spin_lock_irqsave(&pll->pll_enable_lock, flags); 1088 - pll->pll_enable_cnt = 1; 1089 1093 /* de-assert digital and pll power down */ 1090 1094 data = DSI_7nm_PHY_CMN_CTRL_0_DIGTOP_PWRDN_B | 1091 1095 DSI_7nm_PHY_CMN_CTRL_0_PLL_SHUTDOWNB; 1092 1096 writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0); 1093 - spin_unlock_irqrestore(&pll->pll_enable_lock, flags); 1094 1097 1095 1098 /* Assert PLL core reset */ 1096 1099 writel(0x00, base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL); ··· 1200 1209 1201 1210 static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy) 1202 1211 { 1203 - struct dsi_pll_7nm *pll = phy->pll_data; 1204 1212 void __iomem *base = phy->base; 1205 - unsigned long flags; 1206 1213 u32 data; 1207 1214 1208 1215 DBG(""); ··· 1227 1238 writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0); 1228 1239 writel(0, base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0); 1229 1240 1230 - spin_lock_irqsave(&pll->pll_enable_lock, flags); 1231 - pll->pll_enable_cnt = 0; 1232 1241 /* Turn off all PHY blocks */ 1233 1242 writel(0x00, base + REG_DSI_7nm_PHY_CMN_CTRL_0); 1234 - spin_unlock_irqrestore(&pll->pll_enable_lock, flags); 1235 1243 1236 1244 /* make sure phy is turned off */ 1237 1245 wmb();