From nobody Sat Feb 7 11:31:13 2026 Received: from lelvem-ot02.ext.ti.com (lelvem-ot02.ext.ti.com [198.47.23.235]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8092379C0 for ; Fri, 2 May 2025 03:35:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.235 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746156919; cv=none; b=bRL4ldmqHA0meKuvUtMJ0odvbxrwDdQnIyIhPSc47h/PdHQKkUFRUyDmSJQta5owSz9OIm0wbb88w3CBajEyhoPym6MC8nC1zTWvUkDOKWP0HKUXhg38hY68gb04xTGq5d5c9m08Mz95yE5NPX9N/q8LBYKWSNLk2HI4I8+dq40= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746156919; c=relaxed/simple; bh=/AqwtxrtSX92HB+ltd96zxBnqRXnaKye3tK5eqTrdl4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=lN8V54M5OVyCkCCt0BtsoSZHT56XMFQLPmhf3xpKirMF7TdCpYaY9iwPwr5h1dfF+EsmpDVbgaHS1xBHgITk9YUA9Xqc1BDWtjkeXkpKrL3f/5Te/ner0iSSl2zPKHCvR7UYhl5CaQwf7hL9/109hucTNE4oyafE4RFnYJQvcV0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=DWGmmypD; arc=none smtp.client-ip=198.47.23.235 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="DWGmmypD" Received: from fllv0034.itg.ti.com ([10.64.40.246]) by lelvem-ot02.ext.ti.com (8.15.2/8.15.2) with ESMTPS id 5423YsRC321198 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 1 May 2025 22:34:54 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1746156894; bh=5KWOJEGKQS82scl1TDsAbW4xFotjv57FL8CFCVogxNw=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=DWGmmypDzhWwsACSHz2wQpcp+1odtFj88Y2PF/HDMlhQAQYqzcxDzQMu2jb5GkQbB NFTSbS0UtMPfli63YJkgbOM6cnCuBiUwPPl3sxg8WJ+6xKTWDl9ypm8sUQsnPOkAst NtXTFaAReXDL4r2HYWjUwWHs1OGQeVmt7LMVWY0A= Received: from DLEE100.ent.ti.com (dlee100.ent.ti.com [157.170.170.30]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 5423Ys19055232 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 1 May 2025 22:34:54 -0500 Received: from DLEE115.ent.ti.com (157.170.170.26) by DLEE100.ent.ti.com (157.170.170.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 1 May 2025 22:34:53 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DLEE115.ent.ti.com (157.170.170.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 1 May 2025 22:34:53 -0500 Received: from localhost (ti.dhcp.ti.com [172.24.227.95] (may be forged)) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 5423Yrhn061439; Thu, 1 May 2025 22:34:53 -0500 From: Devarsh Thakkar To: , , , , CC: , , , , , , , Subject: [PATCH v3 1/2] phy: cadence: cdns-dphy: Fix PLL lock and O_CMN_READY polling Date: Fri, 2 May 2025 09:04:50 +0530 Message-ID: <20250502033451.2291330-2-devarsht@ti.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20250502033451.2291330-1-devarsht@ti.com> References: <20250502033451.2291330-1-devarsht@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" PLL lockup and O_CMN_READY assertion can only happen after common state machine gets enabled (by programming DPHY_CMN_SSM register), but driver was polling them before the common state machine was enabled. To fix this : - Add new function callbacks for polling on PLL lock and O_CMN_READY assertion. - As state machine and clocks get enabled in power_on callback only, move the clock related programming part from configure callback to power_on callback and poll for the PLL lockup and O_CMN_READY assertion after state machine gets enabled. - The configure callback only saves the PLL configuration received from the client driver which will be applied later on in power_on callback. - Add checks to ensure configure is called before power_on and state machine is in disabled state before power_on callback is called. - Disable state machine in power_off so that client driver can re-configure the PLL by following up a power_off, configure, power_on sequence. Cc: stable@vger.kernel.org Fixes: 7a343c8bf4b5 ("phy: Add Cadence D-PHY support") Signed-off-by: Devarsh Thakkar --- V3: - Move out clock programming logic to power_on as PLL polling and enable can happen only after SSM enable - Disable state machine on power off V2:=20 - Return error code on polling timeout - Moved out calibration logic to separate patch drivers/phy/cadence/cdns-dphy.c | 109 +++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 24 deletions(-) diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dph= y.c index ed87a3970f83..a94109a63788 100644 --- a/drivers/phy/cadence/cdns-dphy.c +++ b/drivers/phy/cadence/cdns-dphy.c @@ -79,6 +79,7 @@ struct cdns_dphy_cfg { u8 pll_ipdiv; u8 pll_opdiv; u16 pll_fbdiv; + u64 hs_clk_rate; unsigned int nlanes; }; =20 @@ -99,6 +100,8 @@ struct cdns_dphy_ops { void (*set_pll_cfg)(struct cdns_dphy *dphy, const struct cdns_dphy_cfg *cfg); unsigned long (*get_wakeup_time_ns)(struct cdns_dphy *dphy); + int (*wait_for_pll_lock)(struct cdns_dphy *dphy); + int (*wait_for_cmn_ready)(struct cdns_dphy *dphy); }; =20 struct cdns_dphy { @@ -108,6 +111,8 @@ struct cdns_dphy { struct clk *pll_ref_clk; const struct cdns_dphy_ops *ops; struct phy *phy; + bool is_configured; + bool is_powered; }; =20 /* Order of bands is important since the index is the band number. */ @@ -191,6 +196,26 @@ static unsigned long cdns_dphy_get_wakeup_time_ns(stru= ct cdns_dphy *dphy) return dphy->ops->get_wakeup_time_ns(dphy); } =20 +static int cdns_dphy_wait_for_pll_lock(struct cdns_dphy *dphy) +{ + int ret =3D 0; + + if (dphy->ops->wait_for_pll_lock) + ret =3D dphy->ops->wait_for_pll_lock(dphy); + + return ret; +} + +static int cdns_dphy_wait_for_cmn_ready(struct cdns_dphy *dphy) +{ + int ret =3D 0; + + if (dphy->ops->wait_for_cmn_ready) + ret =3D dphy->ops->wait_for_cmn_ready(dphy); + + return ret; +} + static unsigned long cdns_dphy_ref_get_wakeup_time_ns(struct cdns_dphy *dp= hy) { /* Default wakeup time is 800 ns (in a simulated environment). */ @@ -232,7 +257,6 @@ static unsigned long cdns_dphy_j721e_get_wakeup_time_ns= (struct cdns_dphy *dphy) static void cdns_dphy_j721e_set_pll_cfg(struct cdns_dphy *dphy, const struct cdns_dphy_cfg *cfg) { - u32 status; =20 /* * set the PWM and PLL Byteclk divider settings to recommended values @@ -249,13 +273,6 @@ static void cdns_dphy_j721e_set_pll_cfg(struct cdns_dp= hy *dphy, =20 writel(DPHY_TX_J721E_WIZ_LANE_RSTB, dphy->regs + DPHY_TX_J721E_WIZ_RST_CTRL); - - readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_PLL_CTRL, status, - (status & DPHY_TX_WIZ_PLL_LOCK), 0, POLL_TIMEOUT_US); - - readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_STATUS, status, - (status & DPHY_TX_WIZ_O_CMN_READY), 0, - POLL_TIMEOUT_US); } =20 static void cdns_dphy_j721e_set_psm_div(struct cdns_dphy *dphy, u8 div) @@ -263,6 +280,23 @@ static void cdns_dphy_j721e_set_psm_div(struct cdns_dp= hy *dphy, u8 div) writel(div, dphy->regs + DPHY_TX_J721E_WIZ_PSM_FREQ); } =20 +static int cdns_dphy_j721e_wait_for_pll_lock(struct cdns_dphy *dphy) +{ + u32 status; + + return readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_PLL_CTRL, status, + status & DPHY_TX_WIZ_PLL_LOCK, 0, POLL_TIMEOUT_US); +} + +static int cdns_dphy_j721e_wait_for_cmn_ready(struct cdns_dphy *dphy) +{ + u32 status; + + return readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_STATUS, status, + status & DPHY_TX_WIZ_O_CMN_READY, 0, + POLL_TIMEOUT_US); +} + /* * This is the reference implementation of DPHY hooks. Specific integratio= n of * this IP may have to re-implement some of them depending on how they dec= ided @@ -278,6 +312,8 @@ static const struct cdns_dphy_ops j721e_dphy_ops =3D { .get_wakeup_time_ns =3D cdns_dphy_j721e_get_wakeup_time_ns, .set_pll_cfg =3D cdns_dphy_j721e_set_pll_cfg, .set_psm_div =3D cdns_dphy_j721e_set_psm_div, + .wait_for_pll_lock =3D cdns_dphy_j721e_wait_for_pll_lock, + .wait_for_cmn_ready =3D cdns_dphy_j721e_wait_for_cmn_ready, }; =20 static int cdns_dphy_config_from_opts(struct phy *phy, @@ -298,6 +334,7 @@ static int cdns_dphy_config_from_opts(struct phy *phy, return ret; =20 opts->wakeup =3D cdns_dphy_get_wakeup_time_ns(dphy) / 1000; + cfg->hs_clk_rate =3D opts->hs_clk_rate; =20 return 0; } @@ -334,13 +371,23 @@ static int cdns_dphy_validate(struct phy *phy, enum p= hy_mode mode, int submode, static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *= opts) { struct cdns_dphy *dphy =3D phy_get_drvdata(phy); - struct cdns_dphy_cfg cfg =3D { 0 }; - int ret, band_ctrl; - unsigned int reg; + int ret =3D 0; =20 - ret =3D cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg); - if (ret) - return ret; + ret =3D cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &dphy->cfg); + if (!ret) + dphy->is_configured =3D true; + + return ret; +} + +static int cdns_dphy_power_on(struct phy *phy) +{ + struct cdns_dphy *dphy =3D phy_get_drvdata(phy); + int ret =3D 0, band_ctrl; + u32 reg; + + if (!dphy->is_configured || dphy->is_powered) + return -EINVAL; =20 /* * Configure the internal PSM clk divider so that the DPHY has a @@ -363,9 +410,9 @@ static int cdns_dphy_configure(struct phy *phy, union p= hy_configure_opts *opts) * Configure the DPHY PLL that will be used to generate the TX byte * clk. */ - cdns_dphy_set_pll_cfg(dphy, &cfg); + cdns_dphy_set_pll_cfg(dphy, &dphy->cfg); =20 - band_ctrl =3D cdns_dphy_tx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate); + band_ctrl =3D cdns_dphy_tx_get_band_ctrl(dphy->cfg.hs_clk_rate); if (band_ctrl < 0) return band_ctrl; =20 @@ -373,19 +420,26 @@ static int cdns_dphy_configure(struct phy *phy, union= phy_configure_opts *opts) FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND, band_ctrl); writel(reg, dphy->regs + DPHY_BAND_CFG); =20 - return 0; -} + /* Start TX state machine. */ + writel(DPHY_CMN_SSM_EN | DPHY_CMN_TX_MODE_EN, + dphy->regs + DPHY_CMN_SSM); =20 -static int cdns_dphy_power_on(struct phy *phy) -{ - struct cdns_dphy *dphy =3D phy_get_drvdata(phy); + ret =3D cdns_dphy_wait_for_pll_lock(dphy); + if (ret) { + dev_err(&dphy->phy->dev, "Failed to lock PLL with err %d\n", ret); + return ret; + } + + ret =3D cdns_dphy_wait_for_cmn_ready(dphy); + if (ret) { + dev_err(&dphy->phy->dev, "O_CMN_READY signal failed to assert with err %= d\n", ret); + return ret; + } =20 clk_prepare_enable(dphy->psm_clk); clk_prepare_enable(dphy->pll_ref_clk); =20 - /* Start TX state machine. */ - writel(DPHY_CMN_SSM_EN | DPHY_CMN_TX_MODE_EN, - dphy->regs + DPHY_CMN_SSM); + dphy->is_powered =3D true; =20 return 0; } @@ -393,10 +447,17 @@ static int cdns_dphy_power_on(struct phy *phy) static int cdns_dphy_power_off(struct phy *phy) { struct cdns_dphy *dphy =3D phy_get_drvdata(phy); + u32 reg; =20 clk_disable_unprepare(dphy->pll_ref_clk); clk_disable_unprepare(dphy->psm_clk); =20 + /* Stop TX state machine. */ + reg =3D readl(dphy->regs + DPHY_CMN_SSM); + writel(reg & ~DPHY_CMN_SSM_EN, dphy->regs + DPHY_CMN_SSM); + + dphy->is_powered =3D false; + return 0; } =20 --=20 2.39.1 From nobody Sat Feb 7 11:31:13 2026 Received: from lelvem-ot02.ext.ti.com (lelvem-ot02.ext.ti.com [198.47.23.235]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1A0DE19A298 for ; Fri, 2 May 2025 03:35:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.235 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746156923; cv=none; b=uTInn98iNOmsXGX0morspoLBF/dtybDfBI4iCbpRPoEgA6zcBaKFrYkK3Ly4i3u0hq/8Cy0CFJRbm/1YRpQX44e+mPDK0+Tjp9q+XLuE0t8UHv+tfy+rIdTPiNjHuS8M+KCVNWpgAIFbkgOFhXTkvSoIaZaKoYXAhbCXuMtAPOE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746156923; c=relaxed/simple; bh=3pqxnDd0wiWjKQ8tgXkTad2HoxDq5oBkl1gCQk0eiA0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QwE/u9n6WzBPEb2qWER/lDfVuSDzBkFwtCTqTUQAcUbXZz51TzgD2MoeCW4zOVHnaHEmuE9j3haP6UWm9R9BTucXQLVqMfVieUu++DNP9FIIb7phWZpPY9JdeHM9C+WC6olYb5YhxFxC8seQ/mZuN+IHxZRQkE5bF0RlZ+6xx8k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=VXToTxlb; arc=none smtp.client-ip=198.47.23.235 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="VXToTxlb" Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelvem-ot02.ext.ti.com (8.15.2/8.15.2) with ESMTPS id 5423Yt6O321202 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 1 May 2025 22:34:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1746156895; bh=cEgO4eAPfutv/3K+LNFMnA8RlsrtrLzPkE7YS2j0A3I=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=VXToTxlbZO3RwHHQQHoWZ3QhDkynaJ5pVciRQiwR2suit5ii/vGiuUb2Nk6ab15Yz jje0XRgSj+P6Baw4SaUY0YmpDw3VhCGK8/JoltPlwyZ4eYI1lhh3H/cmLpdaXWSOcq cmsR45j9dCzbXlnViHWNka9jUQucXpEA4sfN+VFI= Received: from DFLE112.ent.ti.com (dfle112.ent.ti.com [10.64.6.33]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 5423YtC1024701 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 1 May 2025 22:34:55 -0500 Received: from DFLE114.ent.ti.com (10.64.6.35) by DFLE112.ent.ti.com (10.64.6.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 1 May 2025 22:34:55 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DFLE114.ent.ti.com (10.64.6.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 1 May 2025 22:34:55 -0500 Received: from localhost (ti.dhcp.ti.com [172.24.227.95] (may be forged)) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 5423YshE061455; Thu, 1 May 2025 22:34:54 -0500 From: Devarsh Thakkar To: , , , , CC: , , , , , , , Subject: [PATCH v3 2/2] phy: cadence: cdns-dphy: Update calibration wait time for startup state machine Date: Fri, 2 May 2025 09:04:51 +0530 Message-ID: <20250502033451.2291330-3-devarsht@ti.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20250502033451.2291330-1-devarsht@ti.com> References: <20250502033451.2291330-1-devarsht@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" Do read-modify-write so that we re-use the characterized reset value as specified in TRM [1] to program calibration wait time which defines number of cycles to wait for after startup state machine is in bandgap enable state. This fixes PLL lock timeout error faced while using RPi DSI Panel on TI's AM62L and J721E SoC [2]. [1] AM62P TRM (Section ): https://www.ti.com/lit/pdf/spruj83 [2]: Link: https://gist.github.com/devarsht/89e4830e886774fcd50aa6e29cce3a79 Cc: stable@vger.kernel.org Fixes: 7a343c8bf4b5 ("phy: Add Cadence D-PHY support") Signed-off-by: Devarsh Thakkar --- V3: Do read-modify-write to preserve reset value for calibration wait time V2: Introduced this as as separate patch drivers/phy/cadence/cdns-dphy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dph= y.c index a94109a63788..2e28c56c4bdd 100644 --- a/drivers/phy/cadence/cdns-dphy.c +++ b/drivers/phy/cadence/cdns-dphy.c @@ -30,6 +30,7 @@ =20 #define DPHY_CMN_SSM DPHY_PMA_CMN(0x20) #define DPHY_CMN_SSM_EN BIT(0) +#define DPHY_CMN_SSM_CAL_WAIT_TIME GENMASK(8, 1) #define DPHY_CMN_TX_MODE_EN BIT(9) =20 #define DPHY_CMN_PWM DPHY_PMA_CMN(0x40) @@ -421,7 +422,8 @@ static int cdns_dphy_power_on(struct phy *phy) writel(reg, dphy->regs + DPHY_BAND_CFG); =20 /* Start TX state machine. */ - writel(DPHY_CMN_SSM_EN | DPHY_CMN_TX_MODE_EN, + reg =3D readl(dphy->regs + DPHY_CMN_SSM); + writel((reg & DPHY_CMN_SSM_CAL_WAIT_TIME) | DPHY_CMN_SSM_EN | DPHY_CMN_TX= _MODE_EN, dphy->regs + DPHY_CMN_SSM); =20 ret =3D cdns_dphy_wait_for_pll_lock(dphy); --=20 2.39.1