[PATCH 1/3] phy: stm32-usbphyc: add counter of PLL consumer
Patrick DELAUNAY
patrick.delaunay at foss.st.com
Mon May 9 16:37:38 CEST 2022
Hi Sean,
On 5/8/22 20:21, Sean Anderson wrote:
> On 4/26/22 8:37 AM, Patrick Delaunay wrote:
>> Add the counter of the PLL user n_pll_cons managed by the 2 functions
>> stm32_usbphyc_pll_enable / stm32_usbphyc_pll_disable.
>>
>> This counter allow to remove the function stm32_usbphyc_is_init
>> and it is a preliminary step for ck_usbo_48m introduction.
>
> Is it necessary to disable this clock before booting to Linux? If it
> isn't,
> then perhaps it is simpler to just not disable the clock.
>
> --Sean
No, it is not necessary, we only need to enable the clock for the first
user.
I copy the clock behavior from kernel,
but I agree that can be simpler.
Amelie any notice about this point ?
Do you prefer that I kept the behavior - same as kernel driver - or I
simplify the U-Boot driver ?
Patrick
>
>> Signed-off-by: Patrick Delaunay <patrick.delaunay at foss.st.com>
>> ---
>>
>> drivers/phy/phy-stm32-usbphyc.c | 76 +++++++++++++++++++++------------
>> 1 file changed, 48 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/phy/phy-stm32-usbphyc.c
>> b/drivers/phy/phy-stm32-usbphyc.c
>> index 9c1dcfae52..16c8799eca 100644
>> --- a/drivers/phy/phy-stm32-usbphyc.c
>> +++ b/drivers/phy/phy-stm32-usbphyc.c
>> @@ -65,6 +65,7 @@ struct stm32_usbphyc {
>> bool init;
>> bool powered;
>> } phys[MAX_PHYS];
>> + int n_pll_cons;
>> };
>> static void stm32_usbphyc_get_pll_params(u32 clk_rate,
>> @@ -124,18 +125,6 @@ static int stm32_usbphyc_pll_init(struct
>> stm32_usbphyc *usbphyc)
>> return 0;
>> }
>> -static bool stm32_usbphyc_is_init(struct stm32_usbphyc *usbphyc)
>> -{
>> - int i;
>> -
>> - for (i = 0; i < MAX_PHYS; i++) {
>> - if (usbphyc->phys[i].init)
>> - return true;
>> - }
>> -
>> - return false;
>> -}
>> -
>> static bool stm32_usbphyc_is_powered(struct stm32_usbphyc *usbphyc)
>> {
>> int i;
>> @@ -148,18 +137,17 @@ static bool stm32_usbphyc_is_powered(struct
>> stm32_usbphyc *usbphyc)
>> return false;
>> }
>> -static int stm32_usbphyc_phy_init(struct phy *phy)
>> +static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc)
>> {
>> - struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
>> - struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
>> bool pllen = readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN ?
>> true : false;
>> int ret;
>> - dev_dbg(phy->dev, "phy ID = %lu\n", phy->id);
>> - /* Check if one phy port has already configured the pll */
>> - if (pllen && stm32_usbphyc_is_init(usbphyc))
>> - goto initialized;
>> + /* Check if one consumer has already configured the pll */
>> + if (pllen && usbphyc->n_pll_cons) {
>> + usbphyc->n_pll_cons++;
>> + return 0;
>> + }
>> if (usbphyc->vdda1v1) {
>> ret = regulator_set_enable(usbphyc->vdda1v1, true);
>> @@ -190,23 +178,19 @@ static int stm32_usbphyc_phy_init(struct phy *phy)
>> if (!(readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN))
>> return -EIO;
>> -initialized:
>> - usbphyc_phy->init = true;
>> + usbphyc->n_pll_cons++;
>> return 0;
>> }
>> -static int stm32_usbphyc_phy_exit(struct phy *phy)
>> +static int stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc)
>> {
>> - struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
>> - struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
>> int ret;
>> - dev_dbg(phy->dev, "phy ID = %lu\n", phy->id);
>> - usbphyc_phy->init = false;
>> + usbphyc->n_pll_cons--;
>> - /* Check if other phy port requires pllen */
>> - if (stm32_usbphyc_is_init(usbphyc))
>> + /* Check if other consumer requires pllen */
>> + if (usbphyc->n_pll_cons)
>> return 0;
>> clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
>> @@ -235,6 +219,42 @@ static int stm32_usbphyc_phy_exit(struct phy *phy)
>> return 0;
>> }
>> +static int stm32_usbphyc_phy_init(struct phy *phy)
>> +{
>> + struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
>> + struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
>> + int ret;
>> +
>> + dev_dbg(phy->dev, "phy ID = %lu\n", phy->id);
>> + if (usbphyc_phy->init)
>> + return 0;
>> +
>> + ret = stm32_usbphyc_pll_enable(usbphyc);
>> + if (ret)
>> + return log_ret(ret);
>> +
>> + usbphyc_phy->init = true;
>> +
>> + return 0;
>> +}
>> +
>> +static int stm32_usbphyc_phy_exit(struct phy *phy)
>> +{
>> + struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
>> + struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
>> + int ret;
>> +
>> + dev_dbg(phy->dev, "phy ID = %lu\n", phy->id);
>> + if (!usbphyc_phy->init)
>> + return 0;
>> +
>> + ret = stm32_usbphyc_pll_disable(usbphyc);
>> +
>> + usbphyc_phy->init = false;
>> +
>> + return log_ret(ret);
>> +}
>> +
>> static int stm32_usbphyc_phy_power_on(struct phy *phy)
>> {
>> struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
>>
>
More information about the U-Boot
mailing list