Message ID | 20210307141759.30426-1-paul@crapouillou.net |
---|---|
Headers | show |
Series | clk: Ingenic JZ4760(B) support | expand |
Hi Paul, On 2021/3/7 下午10:17, Paul Cercueil wrote: > Hi, > > Here are a set of patches to add support for the Ingenic JZ4760(B) SoCs. > > One thing to note is that the ingenic,jz4760-tcu is undocumented for now, > as I will update the TCU documentation in a different patchset. > > Zhou: the CGU code now supports overriding the PLL M/N/OD calc > algorithm, please tell me if it works for you. After set "od = 1;", the overriding works, but I think we still need some further improvements related to OD, because there is no OD bits in the I2S PLL, this will cause error in "ingenic_pll_recalc_rate()", and may cause "ingenic_pll_calc()" to also have error(if we will introduce support for non 1 od values). I think maybe we can add codes to detect if there is an "pll_od_encoding". If it is NULL, it means no OD bits, then do some corresponding processing( for example, setting corresponding variable to 1) to ensure proper calculation. Thanks and best regards! > Cheers, > -Paul > > Paul Cercueil (6): > dt-bindings: clock: ingenic: Add ingenic,jz4760{,b}-cgu compatibles > clk: Support bypassing dividers > clk: ingenic: Read bypass register only when there is one > clk: ingenic: Remove pll_info.no_bypass_bit > clk: ingenic: Support overriding PLLs M/N/OD calc algorithm > clk: ingenic: Add support for the JZ4760 > > .../bindings/clock/ingenic,cgu.yaml | 4 + > drivers/clk/ingenic/Kconfig | 10 + > drivers/clk/ingenic/Makefile | 1 + > drivers/clk/ingenic/cgu.c | 92 ++-- > drivers/clk/ingenic/cgu.h | 12 +- > drivers/clk/ingenic/jz4725b-cgu.c | 12 +- > drivers/clk/ingenic/jz4740-cgu.c | 12 +- > drivers/clk/ingenic/jz4760-cgu.c | 433 ++++++++++++++++++ > drivers/clk/ingenic/jz4770-cgu.c | 15 +- > drivers/clk/ingenic/tcu.c | 2 + > include/dt-bindings/clock/jz4760-cgu.h | 54 +++ > 11 files changed, 591 insertions(+), 56 deletions(-) > create mode 100644 drivers/clk/ingenic/jz4760-cgu.c > create mode 100644 include/dt-bindings/clock/jz4760-cgu.h >
Hi Paul, On 2021/3/7 下午10:17, Paul Cercueil wrote: > Hi, > > Here are a set of patches to add support for the Ingenic JZ4760(B) SoCs. > > One thing to note is that the ingenic,jz4760-tcu is undocumented for now, > as I will update the TCU documentation in a different patchset. > > Zhou: the CGU code now supports overriding the PLL M/N/OD calc > algorithm, please tell me if it works for you. Newly found two problems, the first problem is because I2S PLL does not have a stable bit, so we need to follow the bypass bit, which is only do corresponding processing when "stable_bit > = 0". The second problem is that the I2S PLL cannot switch the parent clock after using the PLL framework, so it cannot use SCLKA and MPLL as the parent clock (when trying to switch the parent clock, it will stuck and accompany "clk: failed to reparent i2s to mpll: -22"). > > Cheers, > -Paul > > Paul Cercueil (6): > dt-bindings: clock: ingenic: Add ingenic,jz4760{,b}-cgu compatibles > clk: Support bypassing dividers > clk: ingenic: Read bypass register only when there is one > clk: ingenic: Remove pll_info.no_bypass_bit > clk: ingenic: Support overriding PLLs M/N/OD calc algorithm > clk: ingenic: Add support for the JZ4760 > > .../bindings/clock/ingenic,cgu.yaml | 4 + > drivers/clk/ingenic/Kconfig | 10 + > drivers/clk/ingenic/Makefile | 1 + > drivers/clk/ingenic/cgu.c | 92 ++-- > drivers/clk/ingenic/cgu.h | 12 +- > drivers/clk/ingenic/jz4725b-cgu.c | 12 +- > drivers/clk/ingenic/jz4740-cgu.c | 12 +- > drivers/clk/ingenic/jz4760-cgu.c | 433 ++++++++++++++++++ > drivers/clk/ingenic/jz4770-cgu.c | 15 +- > drivers/clk/ingenic/tcu.c | 2 + > include/dt-bindings/clock/jz4760-cgu.h | 54 +++ > 11 files changed, 591 insertions(+), 56 deletions(-) > create mode 100644 drivers/clk/ingenic/jz4760-cgu.c > create mode 100644 include/dt-bindings/clock/jz4760-cgu.h >
Hi Paul, On 2021/3/7 下午10:17, Paul Cercueil wrote: > Hi, > > Here are a set of patches to add support for the Ingenic JZ4760(B) SoCs. > > One thing to note is that the ingenic,jz4760-tcu is undocumented for now, > as I will update the TCU documentation in a different patchset. > > Zhou: the CGU code now supports overriding the PLL M/N/OD calc > algorithm, please tell me if it works for you. The previously mentioned problems have all been solved, this proves that your patch is available for I2S PLL. I will improve and clean up the relevant code, then send it immediately after your patches is merged. Thanks and best regards! > Cheers, > -Paul > > Paul Cercueil (6): > dt-bindings: clock: ingenic: Add ingenic,jz4760{,b}-cgu compatibles > clk: Support bypassing dividers > clk: ingenic: Read bypass register only when there is one > clk: ingenic: Remove pll_info.no_bypass_bit > clk: ingenic: Support overriding PLLs M/N/OD calc algorithm > clk: ingenic: Add support for the JZ4760 > > .../bindings/clock/ingenic,cgu.yaml | 4 + > drivers/clk/ingenic/Kconfig | 10 + > drivers/clk/ingenic/Makefile | 1 + > drivers/clk/ingenic/cgu.c | 92 ++-- > drivers/clk/ingenic/cgu.h | 12 +- > drivers/clk/ingenic/jz4725b-cgu.c | 12 +- > drivers/clk/ingenic/jz4740-cgu.c | 12 +- > drivers/clk/ingenic/jz4760-cgu.c | 433 ++++++++++++++++++ > drivers/clk/ingenic/jz4770-cgu.c | 15 +- > drivers/clk/ingenic/tcu.c | 2 + > include/dt-bindings/clock/jz4760-cgu.h | 54 +++ > 11 files changed, 591 insertions(+), 56 deletions(-) > create mode 100644 drivers/clk/ingenic/jz4760-cgu.c > create mode 100644 include/dt-bindings/clock/jz4760-cgu.h >
Hi Paul, On 2021/3/7 下午10:17, Paul Cercueil wrote: > SoC-specific code can now provide a callback if they need to compute the > M/N/OD values in a specific way. > > Signed-off-by: Paul Cercueil <paul@crapouillou.net> > --- > drivers/clk/ingenic/cgu.c | 40 ++++++++++++++++++++++++++------------- > drivers/clk/ingenic/cgu.h | 3 +++ > 2 files changed, 30 insertions(+), 13 deletions(-) Tested-by: 周琰杰 (Zhou Yanjie)<zhouyanjie@wanyeetech.com> # on CU1000-neo/X1000E > diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c > index 58f7ab5cf0fe..266c7595d330 100644 > --- a/drivers/clk/ingenic/cgu.c > +++ b/drivers/clk/ingenic/cgu.c > @@ -119,28 +119,42 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) > n * od); > } > > -static unsigned long > -ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info, > - unsigned long rate, unsigned long parent_rate, > - unsigned *pm, unsigned *pn, unsigned *pod) > +static void > +ingenic_pll_calc_m_n_od(const struct ingenic_cgu_pll_info *pll_info, > + unsigned long rate, unsigned long parent_rate, > + unsigned int *pm, unsigned int *pn, unsigned int *pod) > { > - const struct ingenic_cgu_pll_info *pll_info; > - unsigned m, n, od; > - > - pll_info = &clk_info->pll; > - od = 1; > + unsigned int m, n, od = 1; > > /* > * The frequency after the input divider must be between 10 and 50 MHz. > * The highest divider yields the best resolution. > */ > n = parent_rate / (10 * MHZ); > - n = min_t(unsigned, n, 1 << clk_info->pll.n_bits); > - n = max_t(unsigned, n, pll_info->n_offset); > + n = min_t(unsigned int, n, 1 << pll_info->n_bits); > + n = max_t(unsigned int, n, pll_info->n_offset); > > m = (rate / MHZ) * od * n / (parent_rate / MHZ); > - m = min_t(unsigned, m, 1 << clk_info->pll.m_bits); > - m = max_t(unsigned, m, pll_info->m_offset); > + m = min_t(unsigned int, m, 1 << pll_info->m_bits); > + m = max_t(unsigned int, m, pll_info->m_offset); > + > + *pm = m; > + *pn = n; > + *pod = od; > +} > + > +static unsigned long > +ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info, > + unsigned long rate, unsigned long parent_rate, > + unsigned int *pm, unsigned int *pn, unsigned int *pod) > +{ > + const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll; > + unsigned int m, n, od; > + > + if (pll_info->calc_m_n_od) > + (*pll_info->calc_m_n_od)(pll_info, rate, parent_rate, &m, &n, &od); > + else > + ingenic_pll_calc_m_n_od(pll_info, rate, parent_rate, &m, &n, &od); > > if (pm) > *pm = m; > diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h > index 10521d1b7b12..bfc2b9c38a41 100644 > --- a/drivers/clk/ingenic/cgu.h > +++ b/drivers/clk/ingenic/cgu.h > @@ -55,6 +55,9 @@ struct ingenic_cgu_pll_info { > s8 bypass_bit; > u8 enable_bit; > u8 stable_bit; > + void (*calc_m_n_od)(const struct ingenic_cgu_pll_info *pll_info, > + unsigned long rate, unsigned long parent_rate, > + unsigned int *m, unsigned int *n, unsigned int *od); > }; > > /**