Re: [PATCH v2 2/4] drm/msm/dsi/phy: Protect PHY_CMN_CLK_CFG1 against clock driver

From: Krzysztof Kozlowski
Date: Tue Feb 04 2025 - 04:21:37 EST


On 03/02/2025 18:41, Dmitry Baryshkov wrote:
> On Mon, Feb 03, 2025 at 06:29:19PM +0100, Krzysztof Kozlowski wrote:
>> PHY_CMN_CLK_CFG1 register is updated by the PHY driver and by a mux
>> clock from Common Clock Framework:
>> devm_clk_hw_register_mux_parent_hws(). There could be a path leading to
>> concurrent and conflicting updates between PHY driver and clock
>> framework, e.g. changing the mux and enabling PLL clocks.
>>
>> Add dedicated spinlock to be sure all PHY_CMN_CLK_CFG1 updates are
>> synchronized.
>>
>> Fixes: 1ef7c99d145c ("drm/msm/dsi: add support for 7nm DSI PHY/PLL")
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@xxxxxxxxxx>
>>
>> ---
>>
>> Changes in v2:
>> 1. Store BIT(4) and BIT(5) in local var in dsi_pll_enable_global_clk()
>> ---
>> drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 35 +++++++++++++++++++------------
>> 1 file changed, 22 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
>> index c164f845653816291ad96c863257f75462ef58e7..e26f53f7cde8f0f6419a633f5d39784dc2e5bb98 100644
>> --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
>> +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
>> @@ -83,6 +83,9 @@ struct dsi_pll_7nm {
>> /* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */
>> spinlock_t postdiv_lock;
>>
>> + /* protects REG_DSI_7nm_PHY_CMN_CLK_CFG1 register */
>> + spinlock_t pclk_mux_lock;
>> +
>> struct pll_7nm_cached_state cached_state;
>>
>> struct dsi_pll_7nm *slave;
>> @@ -381,22 +384,32 @@ static void dsi_pll_cmn_clk_cfg0_write(struct dsi_pll_7nm *pll, u32 val)
>> spin_unlock_irqrestore(&pll->postdiv_lock, flags);
>> }
>>
>> -static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll)
>> +static void dsi_pll_cmn_clk_cfg1_update(struct dsi_pll_7nm *pll, u32 mask,
>> + u32 val)
>> {
>> + unsigned long flags;
>> u32 data;
>>
>> + spin_lock_irqsave(&pll->pclk_mux_lock, flags);
>> data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
>> - writel(data & ~BIT(5), pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
>> + data &= ~mask;
>> + data |= val & mask;
>> +
>> + writel(data, pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
>> + spin_unlock_irqrestore(&pll->pclk_mux_lock, flags);
>> +}
>> +
>> +static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll)
>> +{
>> + dsi_pll_cmn_clk_cfg1_update(pll, BIT(5), 0);
>> }
>>
>> static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll)
>> {
>> - u32 data;
>> + u32 cfg_1 = BIT(5) | BIT(4);
>
> Please define these two bits too.

Why? They were not defined before. This only moving existing code.


Best regards,
Krzysztof