Re: [PATCH v2 03/11] clk: qcom: gdsc: add support for clocks tied to the GDSC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Tue, 1 Mar 2022 at 09:42, Prasad Malisetty <quic_pmaliset@xxxxxxxxxxx> wrote:
> I discussed with internal team. setting gcc_pcie_n_pipe_clk src in pcie
> driver doesn't have any relation with gdsc.
>
> But we are making sure that gcc_pcie_n_pipe_clk src is bi_tcxo before
> enabling the clocks and switching to pipe_clk src after PHY is enalbe.
>
> During suspend switching back to bi_tcxo as we enabling the clock as
> part of resume.

So... I assume that if we implement the enable/disable() ops in a way
similar to clk_rcg2_shared_ops, we can drop all manual handling of
pipe_clk sources.

Bjorn, Taniya WDYT?

>
>   Hi Taniya,
>
> Please provide your inputs.
>
> Thanks
>
> -Prasad
> On 2/12/2022 1:22 AM, Dmitry Baryshkov wrote:
> > On 05/02/2022 01:05, Bjorn Andersson wrote:
> >> On Fri 04 Feb 08:46 CST 2022, Dmitry Baryshkov wrote:
> >>
> >>> On newer Qualcomm platforms GCC_PCIE_n_PIPE_CLK_SRC should be
> >>> controlled
> >>> together with the PCIE_n_GDSC. The clock should be fed from the TCXO
> >>> before switching the GDSC off and can be fed from PCIE_n_PIPE_CLK once
> >>> the GDSC is on.
> >>>
> >>> Since commit aa9c0df98c29 ("PCI: qcom: Switch pcie_1_pipe_clk_src after
> >>> PHY init in SC7280") PCIe controller driver tries to manage this on
> >>> it's
> >>> own, resulting in the non-optimal code. Furthermore, if the any of the
> >>> drivers will have the same requirements, the code would have to be
> >>> dupliacted there.
> >>>
> >>> Move handling of such clocks to the GDSC code, providing special GDSC
> >>> type.
> >>>
> >>
> >> As discussed on IRC, I'm inclined not to take this, because looks to me
> >> to be the same situation that we have with all GDSCs in SM8350 and
> >> onwards - that some clocks must be parked on a safe parent before the
> >> associated GDSC can be toggled.
> >>
> >> Prasad, please advice on what the actual requirements are wrt the
> >> gcc_pipe_clk_src. When does it need to provide a valid signal and when
> >> does it need to be parked?
> >
> > [Excuse me for the duplicate, Prasad's email was bouncing]
> >
> > Prasad, any comments?
> >
> >>
> >> Regards,
> >> Bjorn
> >>
> >>> Cc: Prasad Malisetty <pmaliset@xxxxxxxxxxxxxx>
> >>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx>
> >>> ---
> >>>   drivers/clk/qcom/gdsc.c | 41
> >>> +++++++++++++++++++++++++++++++++++++++++
> >>>   drivers/clk/qcom/gdsc.h | 14 ++++++++++++++
> >>>   2 files changed, 55 insertions(+)
> >>>
> >>> diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
> >>> index 7e1dd8ccfa38..9913d1b70947 100644
> >>> --- a/drivers/clk/qcom/gdsc.c
> >>> +++ b/drivers/clk/qcom/gdsc.c
> >>> @@ -45,6 +45,7 @@
> >>>   #define TIMEOUT_US        500
> >>>     #define domain_to_gdsc(domain) container_of(domain, struct gdsc,
> >>> pd)
> >>> +#define domain_to_pipe_clk_gdsc(domain) container_of(domain, struct
> >>> pipe_clk_gdsc, base.pd)
> >>>     enum gdsc_status {
> >>>       GDSC_OFF,
> >>> @@ -549,3 +550,43 @@ int gdsc_gx_do_nothing_enable(struct
> >>> generic_pm_domain *domain)
> >>>       return 0;
> >>>   }
> >>>   EXPORT_SYMBOL_GPL(gdsc_gx_do_nothing_enable);
> >>> +
> >>> +/*
> >>> + * Special operations for GDSCs with attached pipe clocks.
> >>> + * The clock should be parked to safe source (tcxo) before turning
> >>> off the GDSC
> >>> + * and can be switched on as soon as the GDSC is on.
> >>> + *
> >>> + * We remove respective clock sources from clocks map and handle
> >>> them manually.
> >>> + */
> >>> +int gdsc_pipe_enable(struct generic_pm_domain *domain)
> >>> +{
> >>> +    struct pipe_clk_gdsc *sc = domain_to_pipe_clk_gdsc(domain);
> >>> +    int i, ret;
> >>> +
> >>> +    ret = gdsc_enable(domain);
> >>> +    if (ret)
> >>> +        return ret;
> >>> +
> >>> +    for (i = 0; i< sc->num_clocks; i++)
> >>> +        regmap_update_bits(sc->base.regmap, sc->clocks[i].reg,
> >>> +                BIT(sc->clocks[i].shift + sc->clocks[i].width) -
> >>> BIT(sc->clocks[i].shift),
> >>> +                sc->clocks[i].on_value << sc->clocks[i].shift);
> >>> +
> >>> +    return 0;
> >>> +}
> >>> +EXPORT_SYMBOL_GPL(gdsc_pipe_enable);
> >>> +
> >>> +int gdsc_pipe_disable(struct generic_pm_domain *domain)
> >>> +{
> >>> +    struct pipe_clk_gdsc *sc = domain_to_pipe_clk_gdsc(domain);
> >>> +    int i;
> >>> +
> >>> +    for (i = sc->num_clocks - 1; i >= 0; i--)
> >>> +        regmap_update_bits(sc->base.regmap, sc->clocks[i].reg,
> >>> +                BIT(sc->clocks[i].shift + sc->clocks[i].width) -
> >>> BIT(sc->clocks[i].shift),
> >>> +                sc->clocks[i].off_value << sc->clocks[i].shift);
> >>> +
> >>> +    /* In case of an error do not try turning the clocks again. We
> >>> can not be sure about the GDSC state. */
> >>> +    return gdsc_disable(domain);
> >>> +}
> >>> +EXPORT_SYMBOL_GPL(gdsc_pipe_disable);
> >>> diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
> >>> index d7cc4c21a9d4..b1a2f0abe41c 100644
> >>> --- a/drivers/clk/qcom/gdsc.h
> >>> +++ b/drivers/clk/qcom/gdsc.h
> >>> @@ -68,11 +68,25 @@ struct gdsc_desc {
> >>>       size_t num;
> >>>   };
> >>>   +struct pipe_clk_gdsc {
> >>> +    struct gdsc base;
> >>> +    int num_clocks;
> >>> +    struct {
> >>> +        u32 reg;
> >>> +        u32 shift;
> >>> +        u32 width;
> >>> +        u32 off_value;
> >>> +        u32 on_value;
> >>> +    } clocks[];
> >>> +};
> >>> +
> >>>   #ifdef CONFIG_QCOM_GDSC
> >>>   int gdsc_register(struct gdsc_desc *desc, struct
> >>> reset_controller_dev *,
> >>>             struct regmap *);
> >>>   void gdsc_unregister(struct gdsc_desc *desc);
> >>>   int gdsc_gx_do_nothing_enable(struct generic_pm_domain *domain);
> >>> +int gdsc_pipe_enable(struct generic_pm_domain *domain);
> >>> +int gdsc_pipe_disable(struct generic_pm_domain *domain);
> >>>   #else
> >>>   static inline int gdsc_register(struct gdsc_desc *desc,
> >>>                   struct reset_controller_dev *rcdev,
> >>> --
> >>> 2.34.1
> >>>
> >
> >



-- 
With best wishes
Dmitry



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [Linux for Sparc]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux