Linux clock framework development
 help / color / mirror / Atom feed
* Re: [PATCH v5 0/6] Add SiFive FU740 PCIe host controller driver support
From: Greentime Hu @ 2021-04-12  2:37 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Palmer Dabbelt
  Cc: jh80.chung, Zong Li, robh+dt, vidyas, alex.dewar90, Erik Danie,
	Linux Kernel Mailing List, linux-clk, linux-pci, linux-riscv,
	Michael Turquette, Albert Ou, Stephen Boyd, hayashi.kunihiko, hes,
	khilman, Philipp Zabel, Bjorn Helgaas, Bjorn Helgaas, devicetree,
	Paul Walmsley
In-Reply-To: <161795835843.16967.18210803147557738620.b4-ty@arm.com>

Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> 於 2021年4月9日 週五 下午4:54寫道:
>
> On Tue, 6 Apr 2021 17:26:28 +0800, Greentime Hu wrote:
> > This patchset includes SiFive FU740 PCIe host controller driver. We also
> > add pcie_aux clock and pcie_power_on_reset controller to prci driver for
> > PCIe driver to use it.
> >
> > This is tested with e1000e: Intel(R) PRO/1000 Network Card, AMD Radeon R5
> > 230 graphics card and SP M.2 PCIe Gen 3 SSD in SiFive Unmatched based on
> > v5.11 Linux kernel.
> >
> > [...]
>
> Applied to pci/dwc [dropped patch 6], thanks!
>
> [1/6] clk: sifive: Add pcie_aux clock in prci driver for PCIe driver
>       https://git.kernel.org/lpieralisi/pci/c/f3ce593b1a
> [2/6] clk: sifive: Use reset-simple in prci driver for PCIe driver
>       https://git.kernel.org/lpieralisi/pci/c/0a78fcfd3d
> [3/6] MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver
>       https://git.kernel.org/lpieralisi/pci/c/8bb1c66a90
> [4/6] dt-bindings: PCI: Add SiFive FU740 PCIe host controller
>       https://git.kernel.org/lpieralisi/pci/c/b86d55c107
> [5/6] PCI: fu740: Add SiFive FU740 PCIe host controller driver
>       https://git.kernel.org/lpieralisi/pci/c/327c333a79
>
> Thanks,
> Lorenzo

Hi Palmer,

Since the PCIE driver has been applied, would you please pick patch 6
to RISC-V for-next tree?
Thank you. :)

^ permalink raw reply

* Re: [PATCH 0/2] fdt: translate address if #size-cells = <0>
From: Dario Binacchi @ 2021-04-11 19:30 UTC (permalink / raw)
  To: Tero Kristo, Rob Herring, Tony Lindgren
  Cc: linux-kernel@vger.kernel.org, Bin Meng, Frank Rowand,
	Michael Turquette, Stephen Boyd, devicetree, linux-clk,
	linux-omap
In-Reply-To: <8f232b81-4c83-54db-bcbd-2cae78ede814@kernel.org>


> Il 09/04/2021 12:32 Tero Kristo <kristo@kernel.org> ha scritto:
> 
>  
> On 08/04/2021 23:24, Dario Binacchi wrote:
> > 
> >> Il 07/04/2021 15:21 Tero Kristo <kristo@kernel.org> ha scritto:
> >>
> >>   
> >> On 07/04/2021 15:52, Rob Herring wrote:
> >>> On Wed, Apr 7, 2021 at 2:07 AM Dario Binacchi <dariobin@libero.it> wrote:
> >>>>
> >>>>
> >>>>> Il 07/04/2021 03:16 Rob Herring <robh+dt@kernel.org> ha scritto:
> >>>>>
> >>>>>
> >>>>> On Tue, Apr 6, 2021 at 5:02 PM Dario Binacchi <dariobin@libero.it> wrote:
> >>>>>>
> >>>>>>
> >>>>>>> Il 06/04/2021 16:06 Rob Herring <robh+dt@kernel.org> ha scritto:
> >>>>>>>
> >>>>>>>
> >>>>>>> On Fri, Apr 2, 2021 at 2:21 PM Dario Binacchi <dariobin@libero.it> wrote:
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> The series comes from my commit in U-boot
> >>>>>>>> d64b9cdcd4 ("fdt: translate address if #size-cells = <0>")
> >>>>>>>> and from the subsequent exchange of emails at the end of which I was
> >>>>>>>> suggested to send the patch to the linux kernel
> >>>>>>>> (https://patchwork.ozlabs.org/project/uboot/patch/1614324949-61314-1-git-send-email-bmeng.cn@gmail.com/).
> >>>>>>>
> >>>>>>> It's 'ranges' that determines translatable which is missing from the
> >>>>>>> DT. This should have not had a 0 size either though maybe we could
> >>>>>>> support that.
> >>>>>>
> >>>>>> I have replied to the email you sent to the u-boot mailing list
> >>>>>>
> >>>>>>>
> >>>>>>> Does the DT have to be updated anyways for your spread spectrum support?
> >>>>>>
> >>>>>> The spread spectrum support patch does not need this patch to work. They belong
> >>>>>> to two different series.
> >>>>>
> >>>>> That's not what I asked. Is the spread spectrum support forcing a DT
> >>>>> update for users?
> >>>>
> >>>> Yes, the deltam and modfreq registers must be added to the DPLL clocks.
> >>>
> >>> That's a shame given this dts has been mostly untouched since 2013.
> >>>
> >>
> >> I think technically it would be possible to map these registers within
> >> the driver also, seeing there are like a handful of the DPLLs for both
> >> am3/am4 which are impacted. Just add a new compatible or something, or
> >> alternatively parse the register addresses and populate the
> >> deltam/modfreq registers based on that.
> > 
> > I have not added new compatibles, but I have added the offset of the delta and modfreq
> > registers to the data structures used by the DPLL drivers and I have set them in the
> > related setup functions.
> > https://lore.kernel.org/patchwork/patch/1406590/
> 
> True, I just said that technically it would be possible to add this data 
> within the driver itself to avoid modifying DT if that would be preferred.

In the review of the series no one asked not to change the device tree but it is also true 
that no review has been made on the patch 'clk: ti: add am33xx / am43xx spread spectrum clock support',
the one to be applied on the drivers that support the SSC.
I take this opportunity to ask you if you can kindly review that patch.

> 
> > 
> >>
> >>>>> If the DT has to be changed anyways (not really
> >>>>> great policy), then you could fix this in the DT at the same time.
> >>>>
> >>>> I could put the fix to the device tree in that series, although I wouldn't
> >>>> create a single patch to fix and add the SSC registers. First the size-cells = <0>
> >>>> fix patch and then the SSC patch.
> >>>> Do you agree?
> >>>
> >>> By at the same time, I really just meant within 1 release.
> >>>
> >>> But I'd like to hear TI maintainers' thoughts on this.
> >>
> >> I did post a comment on patch #1 questioning the approach from TI clock
> >> driver perspective, imho I can't see why these two patches would be
> >> needed right now.
> 
> Fix to above, it was patch #2 I was referring to.
> 
> > 
> > Because U-boot maintainers asked me after I sent them my patch on this issue.
> > I believe that the email exchange that took place in the U-boot (https://patchwork.ozlabs.org/project/uboot/patch/1614324949-61314-1-git-send-email-bmeng.cn@gmail.com/)
> > and Linux kernel mailing lists showed that:
> > - The patch 'fdt: translate address if # size-cells = <0>' is wrong (U-boot has accepted
> >    it, and it will have to be reverted).
> > - However, the same patch highlighted that it is wrong to use the size-cells = <0> property
> >    in the prcm_clocks and scm_clocks nodes of device tree.
> > - Rob agrees that in the case of the am3xx this is the right choice:
> 
> Well, I don't quite like where this is ending at. Basically you are just 
> modifying the am3/am4 DTs adding a size spec for every clock node. This 
> leaves the omap3/omap4/omap5/dra7 in the old format. Should someone 
> convert those also? Has anybody tested what happens with the u-boot 
> change on those platforms? Or with the kernel change proposed for the TI 
> clock driver?
> 
> Also, none of this changes the fact that imho patch #2 in this series is 
> wrong and should be fixed. Doing ioremap for every clock node is at 
> least costly (dra7xx has some 180 clock nodes based on quick grep) and 
> also potentially breaks things (you get extremely fragmented iomappings, 
> and some of them might even get rejected because you end up in the same 
> 4K page), and should be avoided.

You are right, and in fact in my previous email, I proposed only to change the 
ti_clk_get_reg_addr() from:
- if (of_property_read_u32_index (node, "reg", index, & val)) {
+ if (of_property_read_u32_index (node, "reg", index * 2, & val)) {
following the change of size-cells from 0 to 1 in the DTS, without ioremap.

> If things would be fixed properly, we would get rid of the clock nodes 
> from the DT completely and just leave the clock providers in place; 
> clocks would be specified via something like 'clocks = <&prcm 
> AM3_ADC_TSC_FCK>;' 

In which node of the device tree should the 'clocks = <&prcm AM3_ADC_TSC_FCK>;'
property be found?
Could you please briefly describe how the device tree would change?
The clock nodes would be removed but I am not clear how the rest of the device 
tree would change.
Would this solution only impact the device trees and the code of the am3 / am4 
architectures?

Thanks and regards,
Dario

> similar to what is done with the clkctrl entries, and 
> rest of the clock data would be built-in to the clock driver. This would 
> completely get rid of any future compatibility issues and the need to 
> tweak the DT if some clock driver would need modifications to support 
> some new feature.
> 
> -Tero
> 
> > diff --git a/arch/arm/boot/dts/am33xx-l4.dtsi b/arch/arm/boot/dts/am33xx-l4.dtsi
> > index 1fb22088caeb..59b0a0cf211e 100644
> > --- a/arch/arm/boot/dts/am33xx-l4.dtsi
> > +++ b/arch/arm/boot/dts/am33xx-l4.dtsi
> > @@ -110,7 +110,8 @@
> >   
> >                                  prcm_clocks: clocks {
> >                                          #address-cells = <1>;
> > -                                       #size-cells = <0>;
> > +                                       #size-cells = <1>;
> > +                                       ranges = <0 0 0x2000>;
> >                                  };
> >   
> >                                  prcm_clockdomains: clockdomains {
> > @@ -320,7 +321,8 @@
> >   
> >                                          scm_clocks: clocks {
> >                                                  #address-cells = <1>;
> > -                                               #size-cells = <0>;
> > +                                               #size-cells = <1>;
> > +                                               ranges = <0 0 0x800>;
> >                                          };
> >                                  };
> > 
> > --- a/arch/arm/boot/dts/am33xx-clocks.dtsi
> > +++ b/arch/arm/boot/dts/am33xx-clocks.dtsi
> > @@ -10,7 +10,7 @@
> >                  compatible = "ti,mux-clock";
> >                  clocks = <&virt_19200000_ck>, <&virt_24000000_ck>, <&virt_25000000_ck>, <&virt_26000000_ck>;
> >                  ti,bit-shift = <22>;
> > -               reg = <0x0040>;
> > +               reg = <0x0040 0x4>;
> >          };
> >   
> >          adc_tsc_fck: adc_tsc_fck {
> > @@ -98,7 +98,7 @@
> >                  compatible = "ti,gate-clock";
> >                  clocks = <&l4ls_gclk>;
> >                  ti,bit-shift = <0>;
> > -               reg = <0x0664>;
> > +               reg = <0x0664 0x04>;
> >          };
> > [...]
> > 
> > - U-boot rightly wants to use the same device tree as the Kernel.
> > - IMHO, if I'm not missing something, I think using a #size-cells = <1>; for clocks
> >    it requires only one code change in the ti_clk_get_reg_addr():
> > 
> > --- a/drivers/clk/ti/clk.c
> > +++ b/drivers/clk/ti/clk.c
> > @@ -265,9 +265,27 @@ int __init ti_clk_retry_init(struct device_node *node, void *user,
> >   int ti_clk_get_reg_addr(struct device_node *node, int index,
> >                          struct clk_omap_reg *reg)
> > 
> > -       if (of_property_read_u32_index(node, "reg", index, &val)) {
> > +       if (of_property_read_u32_index(node, "reg", index * 2, &val)) {
> > 
> >     The other changes to develop affect device trees of architectures which, like am3, currently
> >     use #size-cells = <0>.
> > 
> > IMHO, all this would lead to an improvement of the device trees with minimal impact on the code.
> > It would benefit U-boot, which would not have to develop special platform code and any new
> > architectures that would inherit from these DTs.
> > 
> > If you think it might be worth it, I am available to develop this patch.
> > 
> > Thanks and regards,
> > Dario
> > 
> >>
> >> -Tero

^ permalink raw reply

* [GIT PULL] Rockchip clock changes for 5.13
From: Heiko Stuebner @ 2021-04-11  9:42 UTC (permalink / raw)
  To: mturquette, Stephen Boyd; +Cc: linux-clk, linux-rockchip

Hi Mike, Stephen,

please find below Rockchip clock changes for 5.13

Please pull, thanks
Heiko

The following changes since commit a38fd8748464831584a19438cbb3082b5a2dab15:

  Linux 5.12-rc2 (2021-03-05 17:33:41 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v5.13-rockchip-clocks

for you to fetch changes up to 40f29839d8bef5aecaa772afa8e5f2ff8434b49f:

  clk: rockchip: drop MODULE_ALIAS from rk3399 clock controller (2021-03-21 11:13:30 +0100)

----------------------------------------------------------------
Support for the clock controller on the new rk3568
and some cleanups for rk3399 modularization.

----------------------------------------------------------------
Elaine Zhang (4):
      clk: rockchip: add dt-binding header for rk3568
      dt-binding: clock: Document rockchip, rk3568-cru bindings
      clk: rockchip: support more core div setting
      clk: rockchip: add clock controller for rk3568

Heiko Stuebner (2):
      clk: rockchip: drop parenthesis from ARM || COMPILE_TEST depends
      clk: rockchip: drop MODULE_ALIAS from rk3399 clock controller

 .../bindings/clock/rockchip,rk3568-cru.yaml        |   60 +
 drivers/clk/rockchip/Kconfig                       |   29 +-
 drivers/clk/rockchip/Makefile                      |    1 +
 drivers/clk/rockchip/clk-cpu.c                     |   53 +-
 drivers/clk/rockchip/clk-px30.c                    |    7 +-
 drivers/clk/rockchip/clk-rk3036.c                  |    7 +-
 drivers/clk/rockchip/clk-rk3128.c                  |    7 +-
 drivers/clk/rockchip/clk-rk3188.c                  |   14 +-
 drivers/clk/rockchip/clk-rk3228.c                  |    7 +-
 drivers/clk/rockchip/clk-rk3288.c                  |    7 +-
 drivers/clk/rockchip/clk-rk3308.c                  |    7 +-
 drivers/clk/rockchip/clk-rk3328.c                  |    7 +-
 drivers/clk/rockchip/clk-rk3368.c                  |   14 +-
 drivers/clk/rockchip/clk-rk3399.c                  |   15 +-
 drivers/clk/rockchip/clk-rk3568.c                  | 1725 ++++++++++++++++++++
 drivers/clk/rockchip/clk-rv1108.c                  |    7 +-
 drivers/clk/rockchip/clk.h                         |   54 +-
 include/dt-bindings/clock/rk3568-cru.h             |  926 +++++++++++
 18 files changed, 2857 insertions(+), 90 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3568-cru.yaml
 create mode 100644 drivers/clk/rockchip/clk-rk3568.c
 create mode 100644 include/dt-bindings/clock/rk3568-cru.h




^ permalink raw reply

* [PATCH v13 3/4] staging: mt7621-dts: use valid vendor 'mediatek' instead of invalid 'mtk'
From: Sergio Paracuellos @ 2021-04-10  5:50 UTC (permalink / raw)
  To: sboyd
  Cc: robh+dt, john, tsbogend, gregkh, linux-clk, devicetree,
	linux-mips, devel, neil, linux-kernel
In-Reply-To: <20210410055059.13518-1-sergio.paracuellos@gmail.com>

Vendor listed for mediatek in kernel vendor file 'vendor-prefixes.yaml'
contains 'mediatek' as a valid vendor string. Some nodes in the device
tree are using an invalid vendor string vfor 'mtk' instead. Fix all of
them in dts file. Update also ralink mt7621 related code to properly
match new strings. Even there are used in the device tree there are
some strings that are not referred anywhere but have been also updated
with new vendor name. These are 'mtk,mt7621-wdt', 'mtk,mt7621-nand',
'mtk,mt7621-mc', and 'mtk,mt7621-cpc'.

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
 arch/mips/ralink/mt7621.c              |  6 +++---
 drivers/staging/mt7621-dts/mt7621.dtsi | 12 ++++++------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index 6b3db98894cb..f82ad2a621f6 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -136,8 +136,8 @@ static void __init mt7621_memory_detect(void)
 
 void __init ralink_of_remap(void)
 {
-	rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc");
-	rt_memc_membase = plat_of_remap_node("mtk,mt7621-memc");
+	rt_sysc_membase = plat_of_remap_node("mediatek,mt7621-sysc");
+	rt_memc_membase = plat_of_remap_node("mediatek,mt7621-memc");
 
 	if (!rt_sysc_membase || !rt_memc_membase)
 		panic("Failed to remap core resources");
@@ -205,7 +205,7 @@ void __init prom_soc_init(struct ralink_soc_info *soc_info)
 
 	if (n0 == MT7621_CHIP_NAME0 && n1 == MT7621_CHIP_NAME1) {
 		name = "MT7621";
-		soc_info->compatible = "mtk,mt7621-soc";
+		soc_info->compatible = "mediatek,mt7621-soc";
 	} else {
 		panic("mt7621: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
 	}
diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi
index b68183e7e6ad..f0c9ae757bcd 100644
--- a/drivers/staging/mt7621-dts/mt7621.dtsi
+++ b/drivers/staging/mt7621-dts/mt7621.dtsi
@@ -56,7 +56,7 @@ palmbus: palmbus@1E000000 {
 		#size-cells = <1>;
 
 		sysc: sysc@0 {
-			compatible = "mtk,mt7621-sysc", "syscon";
+			compatible = "mediatek,mt7621-sysc", "syscon";
 			reg = <0x0 0x100>;
 			#clock-cells = <1>;
 			ralink,memctl = <&memc>;
@@ -66,7 +66,7 @@ sysc: sysc@0 {
 		};
 
 		wdt: wdt@100 {
-			compatible = "mtk,mt7621-wdt";
+			compatible = "mediatek,mt7621-wdt";
 			reg = <0x100 0x100>;
 		};
 
@@ -123,17 +123,17 @@ i2s: i2s@a00 {
 		};
 
 		memc: memc@5000 {
-			compatible = "mtk,mt7621-memc", "syscon";
+			compatible = "mediatek,mt7621-memc", "syscon";
 			reg = <0x5000 0x1000>;
 		};
 
 		cpc: cpc@1fbf0000 {
-			     compatible = "mtk,mt7621-cpc";
+			     compatible = "mediatek,mt7621-cpc";
 			     reg = <0x1fbf0000 0x8000>;
 		};
 
 		mc: mc@1fbf8000 {
-			    compatible = "mtk,mt7621-mc";
+			    compatible = "mediatek,mt7621-mc";
 			    reg = <0x1fbf8000 0x8000>;
 		};
 
@@ -361,7 +361,7 @@ timer {
 	nand: nand@1e003000 {
 		status = "disabled";
 
-		compatible = "mtk,mt7621-nand";
+		compatible = "mediatek,mt7621-nand";
 		bank-width = <2>;
 		reg = <0x1e003000 0x800
 			0x1e003800 0x800>;
-- 
2.25.1


^ permalink raw reply related

* [PATCH v13 4/4] MAINTAINERS: add MT7621 CLOCK maintainer
From: Sergio Paracuellos @ 2021-04-10  5:50 UTC (permalink / raw)
  To: sboyd
  Cc: robh+dt, john, tsbogend, gregkh, linux-clk, devicetree,
	linux-mips, devel, neil, linux-kernel
In-Reply-To: <20210410055059.13518-1-sergio.paracuellos@gmail.com>

Adding myself as maintainer for mt7621 clock driver.

Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4d68184d3f76..02986055fdbc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11484,6 +11484,12 @@ L:	linux-wireless@vger.kernel.org
 S:	Maintained
 F:	drivers/net/wireless/mediatek/mt7601u/
 
+MEDIATEK MT7621 CLOCK DRIVER
+M:	Sergio Paracuellos <sergio.paracuellos@gmail.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/clock/mediatek,mt7621-sysc.yaml
+F:	drivers/clk/ralink/clk-mt7621.c
+
 MEDIATEK MT7621/28/88 I2C DRIVER
 M:	Stefan Roese <sr@denx.de>
 L:	linux-i2c@vger.kernel.org
-- 
2.25.1


^ permalink raw reply related

* [PATCH v13 1/4] clk: ralink: add clock driver for mt7621 SoC
From: Sergio Paracuellos @ 2021-04-10  5:50 UTC (permalink / raw)
  To: sboyd
  Cc: robh+dt, john, tsbogend, gregkh, linux-clk, devicetree,
	linux-mips, devel, neil, linux-kernel
In-Reply-To: <20210410055059.13518-1-sergio.paracuellos@gmail.com>

The documentation for this SOC only talks about two
registers regarding to the clocks:
* SYSC_REG_CPLL_CLKCFG0 - provides some information about
boostrapped refclock. PLL and dividers used for CPU and some
sort of BUS.
* SYSC_REG_CPLL_CLKCFG1 - a banch of gates to enable/disable
clocks for all or some ip cores.

Looking into driver code, and some openWRT patched there are
another frequencies which are used in some drivers (uart, sd...).
According to all of this information the clock plan for this
SoC is set as follows:
- Main top clock "xtal" from where all the rest of the world is
derived.
- CPU clock "cpu" derived from "xtal" frequencies and a bunch of
register reads and predividers.
- BUS clock "bus" derived from "cpu" and with (cpu / 4) MHz.
- Fixed clocks from "xtal":
    * "50m": 50 MHz.
    * "125m": 125 MHz.
    * "150m": 150 MHz.
    * "250m": 250 MHz.
    * "270m": 270 MHz.

We also have a buch of gate clocks with their parents:
  * "hsdma": "150m"
  * "fe": "250m"
  * "sp_divtx": "270m"
  * "timer": "50m"
  * "pcm": "270m"
  * "pio": "50m"
  * "gdma": "bus"
  * "nand": "125m"
  * "i2c": "50m"
  * "i2s": "270m"
  * "spi": "bus"
  * "uart1": "50m"
  * "uart2": "50m"
  * "uart3": "50m"
  * "eth": "50m"
  * "pcie0": "125m"
  * "pcie1": "125m"
  * "pcie2": "125m"
  * "crypto": "250m"
  * "shxc": "50m"

With this information the clk driver will provide clock and gates
functionality from a a set of hardcoded clocks allowing to define
a nice device tree without fixed clocks.

Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
 drivers/clk/Kconfig             |   1 +
 drivers/clk/Makefile            |   1 +
 drivers/clk/ralink/Kconfig      |  11 +
 drivers/clk/ralink/Makefile     |   2 +
 drivers/clk/ralink/clk-mt7621.c | 495 ++++++++++++++++++++++++++++++++
 5 files changed, 510 insertions(+)
 create mode 100644 drivers/clk/ralink/Kconfig
 create mode 100644 drivers/clk/ralink/Makefile
 create mode 100644 drivers/clk/ralink/clk-mt7621.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 1d1891b9cad2..e80918be8e9c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -390,6 +390,7 @@ source "drivers/clk/meson/Kconfig"
 source "drivers/clk/mstar/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/qcom/Kconfig"
+source "drivers/clk/ralink/Kconfig"
 source "drivers/clk/renesas/Kconfig"
 source "drivers/clk/rockchip/Kconfig"
 source "drivers/clk/samsung/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 9b582b3fca34..5f06879d7fe9 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -100,6 +100,7 @@ obj-$(CONFIG_COMMON_CLK_NXP)		+= nxp/
 obj-$(CONFIG_MACH_PISTACHIO)		+= pistachio/
 obj-$(CONFIG_COMMON_CLK_PXA)		+= pxa/
 obj-$(CONFIG_COMMON_CLK_QCOM)		+= qcom/
+obj-y					+= ralink/
 obj-y					+= renesas/
 obj-$(CONFIG_ARCH_ROCKCHIP)		+= rockchip/
 obj-$(CONFIG_COMMON_CLK_SAMSUNG)	+= samsung/
diff --git a/drivers/clk/ralink/Kconfig b/drivers/clk/ralink/Kconfig
new file mode 100644
index 000000000000..6580d5edc676
--- /dev/null
+++ b/drivers/clk/ralink/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# MediaTek Mt7621 Clock Driver
+#
+config CLK_MT7621
+	bool "Clock driver for MediaTek MT7621"
+	depends on SOC_MT7621 || COMPILE_TEST
+	default SOC_MT7621
+	select MFD_SYSCON
+	help
+	  This driver supports MediaTek MT7621 basic clocks.
diff --git a/drivers/clk/ralink/Makefile b/drivers/clk/ralink/Makefile
new file mode 100644
index 000000000000..cf6f9216379d
--- /dev/null
+++ b/drivers/clk/ralink/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_CLK_MT7621) += clk-mt7621.o
diff --git a/drivers/clk/ralink/clk-mt7621.c b/drivers/clk/ralink/clk-mt7621.c
new file mode 100644
index 000000000000..857da1e274be
--- /dev/null
+++ b/drivers/clk/ralink/clk-mt7621.c
@@ -0,0 +1,495 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek MT7621 Clock Driver
+ * Author: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <dt-bindings/clock/mt7621-clk.h>
+
+/* Configuration registers */
+#define SYSC_REG_SYSTEM_CONFIG0         0x10
+#define SYSC_REG_SYSTEM_CONFIG1         0x14
+#define SYSC_REG_CLKCFG0		0x2c
+#define SYSC_REG_CLKCFG1		0x30
+#define SYSC_REG_CUR_CLK_STS		0x44
+#define MEMC_REG_CPU_PLL		0x648
+
+#define XTAL_MODE_SEL_MASK		GENMASK(8, 6)
+#define CPU_CLK_SEL_MASK		GENMASK(31, 30)
+#define CUR_CPU_FDIV_MASK		GENMASK(12, 8)
+#define CUR_CPU_FFRAC_MASK		GENMASK(4, 0)
+#define CPU_PLL_PREDIV_MASK		GENMASK(13, 12)
+#define CPU_PLL_FBDIV_MASK		GENMASK(10, 4)
+
+struct mt7621_clk_priv {
+	struct regmap *sysc;
+	struct regmap *memc;
+};
+
+struct mt7621_clk {
+	struct clk_hw hw;
+	struct mt7621_clk_priv *priv;
+};
+
+struct mt7621_fixed_clk {
+	u8 idx;
+	const char *name;
+	const char *parent_name;
+	unsigned long rate;
+	struct clk_hw *hw;
+};
+
+struct mt7621_gate {
+	u8 idx;
+	const char *name;
+	const char *parent_name;
+	struct mt7621_clk_priv *priv;
+	u32 bit_idx;
+	struct clk_hw hw;
+};
+
+#define GATE(_id, _name, _pname, _shift)	\
+	{					\
+		.idx		= _id,		\
+		.name		= _name,	\
+		.parent_name	= _pname,	\
+		.bit_idx	= _shift	\
+	}
+
+static struct mt7621_gate mt7621_gates[] = {
+	GATE(MT7621_CLK_HSDMA, "hsdma", "150m", BIT(5)),
+	GATE(MT7621_CLK_FE, "fe", "250m", BIT(6)),
+	GATE(MT7621_CLK_SP_DIVTX, "sp_divtx", "270m", BIT(7)),
+	GATE(MT7621_CLK_TIMER, "timer", "50m", BIT(8)),
+	GATE(MT7621_CLK_PCM, "pcm", "270m", BIT(11)),
+	GATE(MT7621_CLK_PIO, "pio", "50m", BIT(13)),
+	GATE(MT7621_CLK_GDMA, "gdma", "bus", BIT(14)),
+	GATE(MT7621_CLK_NAND, "nand", "125m", BIT(15)),
+	GATE(MT7621_CLK_I2C, "i2c", "50m", BIT(16)),
+	GATE(MT7621_CLK_I2S, "i2s", "270m", BIT(17)),
+	GATE(MT7621_CLK_SPI, "spi", "bus", BIT(18)),
+	GATE(MT7621_CLK_UART1, "uart1", "50m", BIT(19)),
+	GATE(MT7621_CLK_UART2, "uart2", "50m", BIT(20)),
+	GATE(MT7621_CLK_UART3, "uart3", "50m", BIT(21)),
+	GATE(MT7621_CLK_ETH, "eth", "50m", BIT(23)),
+	GATE(MT7621_CLK_PCIE0, "pcie0", "125m", BIT(24)),
+	GATE(MT7621_CLK_PCIE1, "pcie1", "125m", BIT(25)),
+	GATE(MT7621_CLK_PCIE2, "pcie2", "125m", BIT(26)),
+	GATE(MT7621_CLK_CRYPTO, "crypto", "250m", BIT(29)),
+	GATE(MT7621_CLK_SHXC, "shxc", "50m", BIT(30))
+};
+
+static inline struct mt7621_gate *to_mt7621_gate(struct clk_hw *hw)
+{
+	return container_of(hw, struct mt7621_gate, hw);
+}
+
+static int mt7621_gate_enable(struct clk_hw *hw)
+{
+	struct mt7621_gate *clk_gate = to_mt7621_gate(hw);
+	struct regmap *sysc = clk_gate->priv->sysc;
+
+	return regmap_update_bits(sysc, SYSC_REG_CLKCFG1,
+				  clk_gate->bit_idx, clk_gate->bit_idx);
+}
+
+static void mt7621_gate_disable(struct clk_hw *hw)
+{
+	struct mt7621_gate *clk_gate = to_mt7621_gate(hw);
+	struct regmap *sysc = clk_gate->priv->sysc;
+
+	regmap_update_bits(sysc, SYSC_REG_CLKCFG1, clk_gate->bit_idx, 0);
+}
+
+static int mt7621_gate_is_enabled(struct clk_hw *hw)
+{
+	struct mt7621_gate *clk_gate = to_mt7621_gate(hw);
+	struct regmap *sysc = clk_gate->priv->sysc;
+	u32 val;
+
+	if (regmap_read(sysc, SYSC_REG_CLKCFG1, &val))
+		return 0;
+
+	return val & BIT(clk_gate->bit_idx);
+}
+
+static const struct clk_ops mt7621_gate_ops = {
+	.enable = mt7621_gate_enable,
+	.disable = mt7621_gate_disable,
+	.is_enabled = mt7621_gate_is_enabled,
+};
+
+static int mt7621_gate_ops_init(struct device *dev,
+				struct mt7621_gate *sclk)
+{
+	struct clk_init_data init = {
+		/*
+		 * Until now no clock driver existed so
+		 * these SoC drivers are not prepared
+		 * yet for the clock. We don't want kernel to
+		 * disable anything so we add CLK_IS_CRITICAL
+		 * flag here.
+		 */
+		.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+		.num_parents = 1,
+		.parent_names = &sclk->parent_name,
+		.ops = &mt7621_gate_ops,
+		.name = sclk->name,
+	};
+
+	sclk->hw.init = &init;
+	return devm_clk_hw_register(dev, &sclk->hw);
+}
+
+static int mt7621_register_gates(struct device *dev,
+				 struct clk_hw_onecell_data *clk_data,
+				 struct mt7621_clk_priv *priv)
+{
+	struct clk_hw **hws = clk_data->hws;
+	struct mt7621_gate *sclk;
+	int ret, i;
+
+	for (i = 0; i < ARRAY_SIZE(mt7621_gates); i++) {
+		sclk = &mt7621_gates[i];
+		sclk->priv = priv;
+		ret = mt7621_gate_ops_init(dev, sclk);
+		if (ret) {
+			dev_err(dev, "Couldn't register clock %s\n", sclk->name);
+			goto err_clk_unreg;
+		}
+
+		hws[sclk->idx] = &sclk->hw;
+	}
+
+	return 0;
+
+err_clk_unreg:
+	while (--i >= 0) {
+		sclk = &mt7621_gates[i];
+		clk_hw_unregister(&sclk->hw);
+	}
+	return ret;
+}
+
+#define FIXED(_id, _name, _rate)		\
+	{					\
+		.idx		= _id,		\
+		.name		= _name,	\
+		.parent_name	= "xtal",	\
+		.rate		= _rate		\
+	}
+
+static struct mt7621_fixed_clk mt7621_fixed_clks[] = {
+	FIXED(MT7621_CLK_50M, "50m", 50000000),
+	FIXED(MT7621_CLK_125M, "125m", 125000000),
+	FIXED(MT7621_CLK_150M, "150m", 150000000),
+	FIXED(MT7621_CLK_250M, "250m", 250000000),
+	FIXED(MT7621_CLK_270M, "270m", 270000000),
+};
+
+static int mt7621_register_fixed_clocks(struct device *dev,
+					struct clk_hw_onecell_data *clk_data)
+{
+	struct clk_hw **hws = clk_data->hws;
+	struct mt7621_fixed_clk *sclk;
+	int ret, i;
+
+	for (i = 0; i < ARRAY_SIZE(mt7621_fixed_clks); i++) {
+		sclk = &mt7621_fixed_clks[i];
+		sclk->hw = clk_hw_register_fixed_rate(dev, sclk->name,
+						      sclk->parent_name, 0,
+						      sclk->rate);
+		if (IS_ERR(sclk->hw)) {
+			dev_err(dev, "Couldn't register clock %s\n", sclk->name);
+			ret = PTR_ERR(sclk->hw);
+			goto err_clk_unreg;
+		}
+
+		hws[sclk->idx] = sclk->hw;
+	}
+
+	return 0;
+
+err_clk_unreg:
+	while (--i >= 0) {
+		sclk = &mt7621_fixed_clks[i];
+		clk_hw_unregister_fixed_rate(sclk->hw);
+	}
+	return ret;
+}
+
+static inline struct mt7621_clk *to_mt7621_clk(struct clk_hw *hw)
+{
+	return container_of(hw, struct mt7621_clk, hw);
+}
+
+static unsigned long mt7621_xtal_recalc_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	struct mt7621_clk *clk = to_mt7621_clk(hw);
+	struct regmap *sysc = clk->priv->sysc;
+	u32 val;
+
+	regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG0, &val);
+	val = FIELD_GET(XTAL_MODE_SEL_MASK, val);
+
+	if (val <= 2)
+		return 20000000;
+	if (val <= 5)
+		return 40000000;
+
+	return 25000000;
+}
+
+static unsigned long mt7621_cpu_recalc_rate(struct clk_hw *hw,
+					    unsigned long xtal_clk)
+{
+	static const u32 prediv_tbl[] = { 0, 1, 2, 2 };
+	struct mt7621_clk *clk = to_mt7621_clk(hw);
+	struct regmap *sysc = clk->priv->sysc;
+	struct regmap *memc = clk->priv->memc;
+	u32 clkcfg, clk_sel, curclk, ffiv, ffrac;
+	u32 pll, prediv, fbdiv;
+	unsigned long cpu_clk;
+
+	regmap_read(sysc, SYSC_REG_CLKCFG0, &clkcfg);
+	clk_sel = FIELD_GET(CPU_CLK_SEL_MASK, clkcfg);
+
+	regmap_read(sysc, SYSC_REG_CUR_CLK_STS, &curclk);
+	ffiv = FIELD_GET(CUR_CPU_FDIV_MASK, curclk);
+	ffrac = FIELD_GET(CUR_CPU_FFRAC_MASK, curclk);
+
+	switch (clk_sel) {
+	case 0:
+		cpu_clk = 500000000;
+		break;
+	case 1:
+		regmap_read(memc, MEMC_REG_CPU_PLL, &pll);
+		fbdiv = FIELD_GET(CPU_PLL_FBDIV_MASK, pll);
+		prediv = FIELD_GET(CPU_PLL_PREDIV_MASK, pll);
+		cpu_clk = ((fbdiv + 1) * xtal_clk) >> prediv_tbl[prediv];
+		break;
+	default:
+		cpu_clk = xtal_clk;
+	}
+
+	return cpu_clk / ffiv * ffrac;
+}
+
+static unsigned long mt7621_bus_recalc_rate(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	return parent_rate / 4;
+}
+
+#define CLK_BASE(_name, _parent, _recalc) {				\
+	.init = &(struct clk_init_data) {				\
+		.name = _name,						\
+		.ops = &(const struct clk_ops) {			\
+			.recalc_rate = _recalc,				\
+		},							\
+		.parent_data = &(const struct clk_parent_data) {	\
+			.name = _parent,				\
+			.fw_name = _parent				\
+		},							\
+		.num_parents = _parent ? 1 : 0				\
+	},								\
+}
+
+static struct mt7621_clk mt7621_clks_base[] = {
+	{ CLK_BASE("xtal", NULL, mt7621_xtal_recalc_rate) },
+	{ CLK_BASE("cpu", "xtal", mt7621_cpu_recalc_rate) },
+	{ CLK_BASE("bus", "cpu", mt7621_bus_recalc_rate) },
+};
+
+static struct clk_hw *mt7621_clk_early[MT7621_CLK_MAX];
+
+static int mt7621_register_early_clocks(struct device_node *np,
+					struct clk_hw_onecell_data *clk_data,
+					struct mt7621_clk_priv *priv)
+{
+	struct clk_hw **hws = clk_data->hws;
+	struct mt7621_clk *sclk;
+	int ret, i, j;
+
+	for (i = 0; i < ARRAY_SIZE(mt7621_clks_base); i++) {
+		sclk = &mt7621_clks_base[i];
+		sclk->priv = priv;
+		ret = of_clk_hw_register(np, &sclk->hw);
+		if (ret) {
+			pr_err("Couldn't register top clock %i\n", i);
+			goto err_clk_unreg;
+		}
+
+		hws[i] = &sclk->hw;
+		mt7621_clk_early[i] = &sclk->hw;
+	}
+
+	for (j = i; j < MT7621_CLK_MAX; j++)
+		mt7621_clk_early[j] = ERR_PTR(-EPROBE_DEFER);
+
+	return 0;
+
+err_clk_unreg:
+	while (--i >= 0) {
+		sclk = &mt7621_clks_base[i];
+		clk_hw_unregister(&sclk->hw);
+	}
+	return ret;
+}
+
+static void __init mt7621_clk_init(struct device_node *node)
+{
+	struct mt7621_clk_priv *priv;
+	struct clk_hw_onecell_data *clk_data;
+	int ret, i, count;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return;
+
+	priv->sysc = syscon_node_to_regmap(node);
+	if (IS_ERR(priv->sysc)) {
+		pr_err("Could not get sysc syscon regmap\n");
+		goto free_clk_priv;
+	}
+
+	priv->memc = syscon_regmap_lookup_by_phandle(node, "ralink,memctl");
+	if (IS_ERR(priv->memc)) {
+		pr_err("Could not get memc syscon regmap\n");
+		goto free_clk_priv;
+	}
+
+	count = ARRAY_SIZE(mt7621_clks_base) +
+		ARRAY_SIZE(mt7621_fixed_clks) + ARRAY_SIZE(mt7621_gates);
+	clk_data = kzalloc(struct_size(clk_data, hws, count), GFP_KERNEL);
+	if (!clk_data)
+		goto free_clk_priv;
+
+	ret = mt7621_register_early_clocks(node, clk_data, priv);
+	if (ret) {
+		pr_err("Couldn't register top clocks\n");
+		goto free_clk_data;
+	}
+
+	clk_data->num = count;
+
+	ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+	if (ret) {
+		pr_err("Couldn't add clk hw provider\n");
+		goto unreg_clk_top;
+	}
+
+	return;
+
+unreg_clk_top:
+	for (i = 0; i < ARRAY_SIZE(mt7621_clks_base); i++) {
+		struct mt7621_clk *sclk = &mt7621_clks_base[i];
+
+		clk_hw_unregister(&sclk->hw);
+	}
+
+free_clk_data:
+	kfree(clk_data);
+
+free_clk_priv:
+	kfree(priv);
+}
+CLK_OF_DECLARE_DRIVER(mt7621_clk, "mediatek,mt7621-sysc", mt7621_clk_init);
+
+static int mt7621_clk_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct clk_hw_onecell_data *clk_data;
+	struct device *dev = &pdev->dev;
+	struct mt7621_clk_priv *priv;
+	int ret, i, count;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->sysc = syscon_node_to_regmap(np);
+	if (IS_ERR(priv->sysc)) {
+		ret = PTR_ERR(priv->sysc);
+		dev_err(dev, "Could not get sysc syscon regmap\n");
+		return ret;
+	}
+
+	priv->memc = syscon_regmap_lookup_by_phandle(np, "ralink,memctl");
+	if (IS_ERR(priv->memc)) {
+		ret = PTR_ERR(priv->memc);
+		dev_err(dev, "Could not get memc syscon regmap\n");
+		return ret;
+	}
+
+	count = ARRAY_SIZE(mt7621_clks_base) +
+		ARRAY_SIZE(mt7621_fixed_clks) + ARRAY_SIZE(mt7621_gates);
+	clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count),
+				GFP_KERNEL);
+	if (!clk_data)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(mt7621_clks_base); i++)
+		clk_data->hws[i] = mt7621_clk_early[i];
+
+	ret = mt7621_register_fixed_clocks(dev, clk_data);
+	if (ret) {
+		dev_err(dev, "Couldn't register fixed clocks\n");
+		return ret;
+	}
+
+	ret = mt7621_register_gates(dev, clk_data, priv);
+	if (ret) {
+		dev_err(dev, "Couldn't register fixed clock gates\n");
+		goto unreg_clk_fixed;
+	}
+
+	clk_data->num = count;
+
+	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+	if (ret) {
+		dev_err(dev, "Couldn't add clk hw provider\n");
+		goto unreg_clk_gates;
+	}
+
+	return 0;
+
+unreg_clk_gates:
+	for (i = 0; i < ARRAY_SIZE(mt7621_gates); i++) {
+		struct mt7621_gate *sclk = &mt7621_gates[i];
+
+		clk_hw_unregister(&sclk->hw);
+	}
+
+unreg_clk_fixed:
+	for (i = 0; i < ARRAY_SIZE(mt7621_fixed_clks); i++) {
+		struct mt7621_fixed_clk *sclk = &mt7621_fixed_clks[i];
+
+		clk_hw_unregister_fixed_rate(sclk->hw);
+	}
+
+	return ret;
+}
+
+static const struct of_device_id mt7621_clk_of_match[] = {
+	{ .compatible = "mediatek,mt7621-sysc" },
+	{}
+};
+
+static struct platform_driver mt7621_clk_driver = {
+	.probe = mt7621_clk_probe,
+	.driver = {
+		.name = "mt7621-clk",
+		.of_match_table = mt7621_clk_of_match,
+	},
+};
+builtin_platform_driver(mt7621_clk_driver);
-- 
2.25.1


^ permalink raw reply related

* [PATCH v13 2/4] staging: mt7621-dts: make use of new 'mt7621-clk'
From: Sergio Paracuellos @ 2021-04-10  5:50 UTC (permalink / raw)
  To: sboyd
  Cc: robh+dt, john, tsbogend, gregkh, linux-clk, devicetree,
	linux-mips, devel, neil, linux-kernel
In-Reply-To: <20210410055059.13518-1-sergio.paracuellos@gmail.com>

Clocks for SoC mt7621 have been properly integrated so there is
no need to declare fixed clocks at all in the device tree. Remove
all of them, add new device tree nodes for mt7621-clk and update
the rest of the nodes to use them.

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
 drivers/staging/mt7621-dts/gbpc1.dts   | 11 ----
 drivers/staging/mt7621-dts/mt7621.dtsi | 74 ++++++++++++--------------
 2 files changed, 33 insertions(+), 52 deletions(-)

diff --git a/drivers/staging/mt7621-dts/gbpc1.dts b/drivers/staging/mt7621-dts/gbpc1.dts
index a7c0d3115d72..7716d0efe524 100644
--- a/drivers/staging/mt7621-dts/gbpc1.dts
+++ b/drivers/staging/mt7621-dts/gbpc1.dts
@@ -100,17 +100,6 @@ partition@50000 {
 	};
 };
 
-&sysclock {
-			compatible = "fixed-clock";
-			/* This is normally 1/4 of cpuclock */
-			clock-frequency = <225000000>;
-};
-
-&cpuclock {
-			compatible = "fixed-clock";
-			clock-frequency = <900000000>;
-};
-
 &pcie {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pcie_pins>;
diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi
index 16fc94f65486..b68183e7e6ad 100644
--- a/drivers/staging/mt7621-dts/mt7621.dtsi
+++ b/drivers/staging/mt7621-dts/mt7621.dtsi
@@ -1,5 +1,6 @@
 #include <dt-bindings/interrupt-controller/mips-gic.h>
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/mt7621-clk.h>
 
 / {
 	#address-cells = <1>;
@@ -27,27 +28,6 @@ aliases {
 		serial0 = &uartlite;
 	};
 
-	cpuclock: cpuclock@0 {
-		#clock-cells = <0>;
-		compatible = "fixed-clock";
-
-		/* FIXME: there should be way to detect this */
-		clock-frequency = <880000000>;
-	};
-
-	sysclock: sysclock@0 {
-		#clock-cells = <0>;
-		compatible = "fixed-clock";
-
-		/* This is normally 1/4 of cpuclock */
-		clock-frequency = <220000000>;
-	};
-
-	mmc_clock: mmc_clock@0 {
-		#clock-cells = <0>;
-		compatible = "fixed-clock";
-		clock-frequency = <48000000>;
-	};
 
 	mmc_fixed_3v3: fixedregulator@0 {
 		compatible = "regulator-fixed";
@@ -76,8 +56,13 @@ palmbus: palmbus@1E000000 {
 		#size-cells = <1>;
 
 		sysc: sysc@0 {
-			compatible = "mtk,mt7621-sysc";
+			compatible = "mtk,mt7621-sysc", "syscon";
 			reg = <0x0 0x100>;
+			#clock-cells = <1>;
+			ralink,memctl = <&memc>;
+			clock-output-names = "xtal", "cpu", "bus",
+					     "50m", "125m", "150m",
+					     "250m", "270m";
 		};
 
 		wdt: wdt@100 {
@@ -101,8 +86,8 @@ i2c: i2c@900 {
 			compatible = "mediatek,mt7621-i2c";
 			reg = <0x900 0x100>;
 
-			clocks = <&sysclock>;
-
+			clocks = <&sysc MT7621_CLK_I2C>;
+			clock-names = "i2c";
 			resets = <&rstctrl 16>;
 			reset-names = "i2c";
 
@@ -119,8 +104,8 @@ i2s: i2s@a00 {
 			compatible = "mediatek,mt7621-i2s";
 			reg = <0xa00 0x100>;
 
-			clocks = <&sysclock>;
-
+			clocks = <&sysc MT7621_CLK_I2S>;
+			clock-names = "i2s";
 			resets = <&rstctrl 17>;
 			reset-names = "i2s";
 
@@ -138,7 +123,7 @@ i2s: i2s@a00 {
 		};
 
 		memc: memc@5000 {
-			compatible = "mtk,mt7621-memc";
+			compatible = "mtk,mt7621-memc", "syscon";
 			reg = <0x5000 0x1000>;
 		};
 
@@ -156,8 +141,8 @@ uartlite: uartlite@c00 {
 			compatible = "ns16550a";
 			reg = <0xc00 0x100>;
 
-			clocks = <&sysclock>;
-			clock-frequency = <50000000>;
+			clocks = <&sysc MT7621_CLK_UART1>;
+			clock-names = "uart1";
 
 			interrupt-parent = <&gic>;
 			interrupts = <GIC_SHARED 26 IRQ_TYPE_LEVEL_HIGH>;
@@ -173,7 +158,8 @@ spi0: spi@b00 {
 			compatible = "ralink,mt7621-spi";
 			reg = <0xb00 0x100>;
 
-			clocks = <&sysclock>;
+			clocks = <&sysc MT7621_CLK_SPI>;
+			clock-names = "spi";
 
 			resets = <&rstctrl 18>;
 			reset-names = "spi";
@@ -189,6 +175,8 @@ gdma: gdma@2800 {
 			compatible = "ralink,rt3883-gdma";
 			reg = <0x2800 0x800>;
 
+			clocks = <&sysc MT7621_CLK_GDMA>;
+			clock-names = "gdma";
 			resets = <&rstctrl 14>;
 			reset-names = "dma";
 
@@ -206,6 +194,8 @@ hsdma: hsdma@7000 {
 			compatible = "mediatek,mt7621-hsdma";
 			reg = <0x7000 0x1000>;
 
+			clocks = <&sysc MT7621_CLK_HSDMA>;
+			clock-names = "hsdma";
 			resets = <&rstctrl 5>;
 			reset-names = "hsdma";
 
@@ -311,11 +301,6 @@ rstctrl: rstctrl {
 		#reset-cells = <1>;
 	};
 
-	clkctrl: clkctrl {
-		compatible = "ralink,rt2880-clock";
-		#clock-cells = <1>;
-	};
-
 	sdhci: sdhci@1E130000 {
 		status = "disabled";
 
@@ -334,7 +319,8 @@ sdhci: sdhci@1E130000 {
 		pinctrl-0 = <&sdhci_pins>;
 		pinctrl-1 = <&sdhci_pins>;
 
-		clocks = <&mmc_clock &mmc_clock>;
+		clocks = <&sysc MT7621_CLK_SHXC>,
+			 <&sysc MT7621_CLK_50M>;
 		clock-names = "source", "hclk";
 
 		interrupt-parent = <&gic>;
@@ -349,7 +335,7 @@ xhci: xhci@1E1C0000 {
 		       0x1e1d0700 0x0100>;
 		reg-names = "mac", "ippc";
 
-		clocks = <&sysclock>;
+		clocks = <&sysc MT7621_CLK_XTAL>;
 		clock-names = "sys_ck";
 
 		interrupt-parent = <&gic>;
@@ -368,7 +354,7 @@ gic: interrupt-controller@1fbc0000 {
 		timer {
 			compatible = "mti,gic-timer";
 			interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
-			clocks = <&cpuclock>;
+			clocks = <&sysc MT7621_CLK_CPU>;
 		};
 	};
 
@@ -381,6 +367,9 @@ nand: nand@1e003000 {
 			0x1e003800 0x800>;
 		#address-cells = <1>;
 		#size-cells = <1>;
+
+		clocks = <&sysc MT7621_CLK_NAND>;
+		clock-names = "nand";
 	};
 
 	ethsys: syscon@1e000000 {
@@ -394,8 +383,9 @@ ethernet: ethernet@1e100000 {
 		compatible = "mediatek,mt7621-eth";
 		reg = <0x1e100000 0x10000>;
 
-		clocks = <&sysclock>;
-		clock-names = "ethif";
+		clocks = <&sysc MT7621_CLK_FE>,
+			 <&sysc MT7621_CLK_ETH>;
+		clock-names = "fe", "ethif";
 
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -521,7 +511,9 @@ GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH
 
 		resets = <&rstctrl 24 &rstctrl 25 &rstctrl 26>;
 		reset-names = "pcie0", "pcie1", "pcie2";
-		clocks = <&clkctrl 24 &clkctrl 25 &clkctrl 26>;
+		clocks = <&sysc MT7621_CLK_PCIE0>,
+			 <&sysc MT7621_CLK_PCIE1>,
+			 <&sysc MT7621_CLK_PCIE2>;
 		clock-names = "pcie0", "pcie1", "pcie2";
 		phys = <&pcie0_phy 1>, <&pcie2_phy 0>;
 		phy-names = "pcie-phy0", "pcie-phy2";
-- 
2.25.1


^ permalink raw reply related

* [PATCH v13 0/4] MIPS: ralink: add CPU clock detection and clock driver for MT7621
From: Sergio Paracuellos @ 2021-04-10  5:50 UTC (permalink / raw)
  To: sboyd
  Cc: robh+dt, john, tsbogend, gregkh, linux-clk, devicetree,
	linux-mips, devel, neil, linux-kernel

This patchset ports CPU clock detection for MT7621 from OpenWrt
and adds a complete clock plan for the mt7621 SOC.

The documentation for this SOC only talks about two registers
regarding to the clocks:
* SYSC_REG_CPLL_CLKCFG0 - provides some information about boostrapped
refclock. PLL and dividers used for CPU and some sort of BUS (AHB?).
* SYSC_REG_CPLL_CLKCFG1 - a banch of gates to enable/disable clocks for
all or some ip cores.

Registers needed for this driver to work are in two already mapped areas
in its platform's device tree. These are 'sysc' and 'memc' nodes. Most
of other drivers just make use of platform operations defined in
'asm/mach-ralink/ralink_regs.h' but this can be avoided declaring this
two nodes to be accesible through syscon. Main registers for the clocks
are in the sysc control node so this node is merged with clock properties
and will also be the clock provider for the SoC.

No documentation about a probably existent set of dividers for each ip
core is included in the datasheets. So we cannot make anything better,
AFAICT.

Looking into driver code, and some openWRT patched there are
another frequences which are used in some drivers (uart, sd...).
According to all of this information the clock plan for this
SoC is set as follows:
 - Main top clock "xtal" from where all the rest of the world is
   derived.
 - CPU clock "cpu" derived from "xtal" frequencies and a bunch of
   register reads and predividers.
 - BUS clock "bus" derived from "cpu" and with (cpu / 4) MHz.
 - Fixed clocks from "xtal":
    * "50m": 50 MHz.
    * "125m": 125 MHz.
    * "150m": 150 MHz.
    * "250m": 250 MHz.
    * "270m": 270 MHz.

We also have a buch of gate clocks with their parents:
 - "hsdma": "150m"
 - "fe": "250m"
 - "sp_divtx": "270m"
 - "timer": "50m"
 - "pcm": "270m"
 - "pio": "50m"
 - "gdma": "bus"
 - "nand": "125m"
 - "i2c": "50m"
 - "i2s": "270m"
 - "spi": "bus"
 - "uart1": "50m"
 - "uart2": "50m"
 - "uart3": "50m"
 - "eth": "50m"
 - "pcie0": "125m"
 - "pcie1": "125m"
 - "pcie2": "125m"
 - "crypto": "250m"
 - "shxc": "50m"

There was a previous attempt of doing this here[0] but the author
(Chuanhong Guo) did not wanted to make assumptions of a clock plan
for the platform that time. It seems that now he has a better idea of
how the clocks are dispossed for this SoC so he share code[1] where
some frequencies and clock parents for the gates are coded from a
real mediatek private clock plan.
                                                
I do really want this to be upstreamed so according to the comments
in previous attempt[0] from Oleksij Rempel and the frequencies in
code[1] I have tried to do this by myself.

All of this patches have been tested in a GNUBee PC1 resulting in a
working platform.

Changes in v13:
 - Rebase this series on top of linux-next 'next-20210409'.
 - Drop empty line in Kconfig.
 - Directly return -ENOMEM 'mt7621_clk_probe' instead of assign to
   ret and return ret when devm_kzalloc fails.
 - Review functions and move all remaining 'sclk' declarations to the
   top to avoid to declare it twice for success and error paths.

Changes in v12:
 - First to patches of previous v11 series has already merged so this
   new seres only have remaining four patches.
 - Add Acked-by from Thomas Bogendoerfer for patch 3/4.
 - Drop menu from Kconfig and only maintain CLK_MT7621 option.
 - Remove comma from sentinel so it's a compile error if
   another element is added after.
 - Use CLK_IS_CRITICAL with a comment when gates are registered and
   drop 'mt7621_prepare_enable_clocks' function.
 - Move 'sclk' declaration to the top of the mt7621_register_early_clocks
   function to avoid to declare it twice for success and error paths.
 - Use devm_* APIs instead of directly use kzalloc and simplify error
   path.

Changes in v11:
 - Collect Rob's Reviewed-by in bindings documentation patch.
 - Fix MAINTAINERS patch using file 'mediatek,mt7621-sysc.yaml'
   for documentation bindings.

Changes in v10:
 - Merge clock properties into 'sysc' system control node making
   this node a clock provider.
 - Update driver to use 'mediatek,mt7621-sysc' as compatible string.
 - Update documentation bindings and its related filename to 
   'mediatek,mt7621-sysc.yaml'.
 - Make use of 'linux/bitfields.h' header to avoid some preprocesor
   shift definitions and just use bit masks decreasing a bit LOC.

Changes in v9:
 - Set two missing ret values to its related PTR_ERR in function
   'mt7621_clk_probe' (also related with [3]).
 - Select MFC_SYSCON in Kconfig.

Changes in v8:
 - Fix kernel test robot complain about the use of 'ret' variable
   initialized: see [3]

Changes in v7:
 - Make use of CLK_OF_DECLARE_DRIVER instead of CLK_OF_DECLARE and
   register there only the top clocks that are needed in 'of_clk_init'.
   The rest of the clocks (fixed and gates) are now registered using
   a platform driver. Because we have avoid architecture dependent stuff
   now this has sense because we can enable this driver for COMPILE_TEST.
 - Convert fixed clocks and gates related function to receive a 'struct
   device' pointer instead of 'struct device_node' one.
 - Make use of dev_ APIS in stuff related with platform driver instead
   of use device_node related stuff. 
 - Add new static global 'mt7621_clk_early' to store pointers to clk_hw
   registered at 'of_clk_init' stage. Make use of this in platform device
   probe function to properly copy this into the new required 'clk_data'
   to provide a properly hierarchy clock structure.
 - Rename 'mt7621_register_top_clocks' function into a more accurate 
   name now which is 'mt7621_register_early_clocks'.
 - Enable driver for COMPILE_TEST.

Changes in v6:
 - Rewrite bindings to properly access the registers needed for the driver
   making use of syscon for two different areas: 'sysc' and 'memc'. With
   this changes architecture dependent include 'asm/mach-ralink/ralink_regs.h'
   is not needed anymore because we access this two syscons using a phandle
   through kernel's regmap APIs. Explanation of this two areas is in [2].
 - Add new 'mt7621_clk_priv' struct to store there pointers to regmap handlers
   to be able to use regmap operations from normal clock api functions. Add
   this pointer in 'mt7621_clk' and 'mt7621_clk_gate' before register its
   related clocks to make things work.
 - Add Greg's Acked-by in patches 4 and 5.
 - Rebase this series on the top of linux-next tag 'next-20210215'.

v5 RESEND notes:
 - I am resending this as I was told to do that.
 - Please, take into account Rob's comments to DT node patch and my
   reply with explanation about how are the current device tree nodes
   for this architecture being used in [2].

Changes in v5:
 - Avoid the use of syscon. All drivers of this platform are just using
   platform operations defined in 'asm/mach-ralink/ralink_regs.h'. We also
   need them for some PLL registers that are not in the sys control area.
   Hence, since we must use this dependency avoid to define clock driver
   as a child of the sysc node in the device tree and follow current
   platform code style.
 - Update bindings documentation to don't refer the syscon and make
   remove 'clock-output-names' property from required ones.
 - Use 'asm/mach-ralink/ralink_regs.h' platform read and write operations
   instead of regmap from the syscon node.
 - Remove 'mt7621_clk_provider' and directly declare 'clk_hw_onecell_data'
   pointer in 'mt7621_clk_init' and pass from there into different register
   functions. Remove pointers to 'mt7621_clk_provider' in the rest fo structs
   used in this driver.
 - Remove MHZ macro and just pass values directly in hertzs.
 - Avoid 'CLK_IGNORE_UNUSED' flag for gates and add a new function called
   'mt7621_prepare_enable_clocks' to prepare all of them to make clocks
   referenced and don't affect current driver code.
 - Remove COMPILE_TEST from Kconfig because of the use of especific arch
   stuff.
 - Fix commit message where a typo for "frequencies" word was present.
 - Make use of parent_clk_data in 'CLK_BASE' macro.
 - Remove MODULE_* macros from code since this is not a module.
 - Remove not needed includes.
 - Hardcode "xtal" as parent in FIXED macro.
 - Change 'else if' clause into 'if' clause since a return statement was
   being used in 'mt7621_xtal_recalc_rate'.

 NOTES:
   - Driver is still being declared using 'CLK_OF_DECLARE' for all the  
     clocks. I have explored the possibility to make some of them available
     afterwards using 'CLK_OF_DECLARE_DRIVER' for top clocks and the rest
     using a platform driver. The resulting code was uglier since we only want
     to use the same device tree node and the top clocks must be copied again
     for the new platform register stuff to properly have a good hierarchy.
     New globals needs to be introduced and in this particular case I don't
     really see the benefits of doing in this way. I am totally ok to have all
     the clocks registered at early stage since from other drivers perspective
     we only really need to enable gates. So, I prefer to have them in that
     way if it is not a real problem, of course.

Changes in v4:
 - Add Acked-by from Rob Herring for binding headers (PATCH 1/6).
 - Convert bindings to not use syscon phandle and declare clock as
   a child of the syscon node. Update device tree and binding doc
   accordly.
 - Make use of 'syscon_node_to_regmap' in driver code instead of
   get this using the phandle function.
 - Properly unregister clocks for the error path of the function
   'mt7621_clk_init'.
 - Include ARRAY_SIZE of fixed clocks in the 'count' to kzalloc
   of 'clk_data'.
 - Add new patch changing invalid vendor 'mtk' in favour of 'mediatek'
   which is the one listed in 'vendor-prefixes.yaml'. Update mt7621 code
   accordly. I have added this patch inside this series because clk
   binding is referring syscon node and the string for that node was
   with not listed vendor. Hence update and have all of this correct
   in the same series.

Changes in v3:
 - Fix compilation warnings reported by kernel test robot because of
   ignoring return values of 'of_clk_hw_register' in functions
   'mt7621_register_top_clocks' and 'mt7621_gate_ops_init'.
 - Fix dts file and binding documentation 'clock-output-names'.

Changes in v2:
 - Remove the following patches:
   * dt: bindings: add mt7621-pll device tree binding documentation.
   * MIPS: ralink: add clock device providing cpu/ahb/apb clock for mt7621.
 - Move all relevant clock code to 'drivers/clk/ralink/clk-mt7621.c' and
   unify there previous 'mt7621-pll' and 'mt7621-clk' into a unique driver
   and binding 'mt7621-clk'.
 - Driver is not a platform driver anymore and now make use of 'CLK_OF_DECLARE'
   because we need clocks available in 'plat_time_init' before setting up
   the timer for the GIC.
 - Use new fixed clocks as parents for different gates and deriving from 'xtal'
   using frequencies in[1].
 - Adapt dts file and bindings header and documentation for new changes.
 - Change MAINTAINERS file to only contains clk-mt7621.c code and
   mediatek,mt7621-clk.yaml file.

[0]: https://www.lkml.org/lkml/2019/7/23/1044
[1]: https://github.com/981213/linux/commit/2eca1f045e4c3db18c941135464c0d7422ad8133
[2]: https://lkml.org/lkml/2020/12/20/47
[3]: http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2021-February/150772.html

Sergio Paracuellos (4):
  clk: ralink: add clock driver for mt7621 SoC
  staging: mt7621-dts: make use of new 'mt7621-clk'
  staging: mt7621-dts: use valid vendor 'mediatek' instead of invalid
    'mtk'
  MAINTAINERS: add MT7621 CLOCK maintainer

 MAINTAINERS                            |   6 +
 arch/mips/ralink/mt7621.c              |   6 +-
 drivers/clk/Kconfig                    |   1 +
 drivers/clk/Makefile                   |   1 +
 drivers/clk/ralink/Kconfig             |  11 +
 drivers/clk/ralink/Makefile            |   2 +
 drivers/clk/ralink/clk-mt7621.c        | 495 +++++++++++++++++++++++++
 drivers/staging/mt7621-dts/gbpc1.dts   |  11 -
 drivers/staging/mt7621-dts/mt7621.dtsi |  82 ++--
 9 files changed, 556 insertions(+), 59 deletions(-)
 create mode 100644 drivers/clk/ralink/Kconfig
 create mode 100644 drivers/clk/ralink/Makefile
 create mode 100644 drivers/clk/ralink/clk-mt7621.c

-- 
2.25.1


^ permalink raw reply

* Re: [GIT PULL] clk fixes for v5.12-rc6
From: pr-tracker-bot @ 2021-04-10  3:04 UTC (permalink / raw)
  To: Stephen Boyd; +Cc: Linus Torvalds, Michael Turquette, linux-clk, linux-kernel
In-Reply-To: <20210410014603.3762887-1-sboyd@kernel.org>

The pull request you sent on Fri,  9 Apr 2021 18:46:03 -0700:

> https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git tags/clk-fixes-for-linus

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/d4961772226de3b48a395a26c076d450d7044c76

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html

^ permalink raw reply

* [GIT PULL] clk fixes for v5.12-rc6
From: Stephen Boyd @ 2021-04-10  1:46 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Michael Turquette, linux-clk, linux-kernel

The following changes since commit 148ddaa89d4a0a927c4353398096cc33687755c1:

  clk: qcom: gcc-sc7180: Use floor ops for the correct sdcc1 clk (2021-03-13 13:00:05 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git tags/clk-fixes-for-linus

for you to fetch changes up to 50ce6826a48f119baf2794fa384a64efe9bd84a5:

  clk: fixed: fix double free in resource managed fixed-factor clock (2021-04-07 16:01:25 -0700)

----------------------------------------------------------------
Here's the latest pile of clk driver and clk framework fixes for this
release.

 - Two clk framework fixes for a long standing issue in
   clk_notifier_{register,unregister}() where we used a
   pointer that was for a struct containing a list head
   when there was no container struct

 - A compile warning fix for socfpga that's good to have

 - A double free problem with devm registered fixed factor clks

 - One last fix to the Qualcomm camera clk driver to use the
   right clk ops so clks don't get stuck and stop working
   because the firmware takes them for a ride.

----------------------------------------------------------------
Dmitry Baryshkov (1):
      clk: fixed: fix double free in resource managed fixed-factor clock

Krzysztof Kozlowski (1):
      clk: socfpga: fix iomem pointer cast on 64-bit

Lukasz Bartosik (2):
      clk: fix invalid usage of list cursor in register
      clk: fix invalid usage of list cursor in unregister

Taniya Das (1):
      clk: qcom: camcc: Update the clock ops for the SC7180

 drivers/clk/clk-fixed-factor.c  |  9 +++++++-
 drivers/clk/clk.c               | 47 +++++++++++++++++---------------------
 drivers/clk/qcom/camcc-sc7180.c | 50 ++++++++++++++++++++---------------------
 drivers/clk/socfpga/clk-gate.c  |  2 +-
 4 files changed, 55 insertions(+), 53 deletions(-)

-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git

^ permalink raw reply

* Re: [PATCH v10 8/9] dt-bindings: add documentation of xilinx clocking wizard
From: Stephen Boyd @ 2021-04-09 23:32 UTC (permalink / raw)
  To: Michal Simek, Rob Herring, Shubhrajyoti Datta
  Cc: Shubhrajyoti Datta,
	OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, linux-clk,
	Greg Kroah-Hartman, Mike Turquette, git, Miquel Raynal, devel
In-Reply-To: <14254feb-ddbd-068d-74a4-61407177336d@xilinx.com>

Quoting Michal Simek (2021-04-08 03:40:29)
> 
> 
> On 4/8/21 12:26 PM, Shubhrajyoti Datta wrote:
> > On Sun, Mar 7, 2021 at 1:50 AM Rob Herring <robh@kernel.org> wrote:
> >>
> >> On Wed, Feb 24, 2021 at 06:40:40PM +0530, Shubhrajyoti Datta wrote:
> >>> Add the devicetree binding for the xilinx clocking wizard.
> >>>
> >>> Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
> >>> ---
> >>>  v6:
> >>>  Fix a yaml warning
> >>>  v7:
> >>>  Add vendor prefix speed-grade
> >>>  v8:
> >>>  Fix the warnings
> >>>  v10:
> >>>  Add nr-outputs
> >>>
> >>>  .../bindings/clock/xlnx,clocking-wizard.yaml       | 72 ++++++++++++++++++++++
> >>>  1 file changed, 72 insertions(+)
> >>>  create mode 100644 Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
> >>> new file mode 100644
> >>> index 0000000..280eb09
> >>> --- /dev/null
> >>> +++ b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
> >>> @@ -0,0 +1,72 @@
> >>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> >>> +%YAML 1.2
> >>> +---
> >>> +$id: "http://devicetree.org/schemas/clock/xlnx,clocking-wizard.yaml#"
> >>> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> >>> +
> >>> +title: Xilinx clocking wizard
> >>> +
> >>> +maintainers:
> >>> +  - Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
> >>> +
> >>> +description:
> >>> +  The clocking wizard is a soft ip clocking block of Xilinx versal. It
> >>> +  reads required input clock frequencies from the devicetree and acts as clock
> >>> +  clock output.
> >>> +
> >>> +properties:
> >>> +  compatible:
> >>> +    const: xlnx,clocking-wizard
> >>
> >> Not very specific. Only 1 version of this h/w?
> > 
> > Will fix in next version
> >>
> >>> +
> >>> +  reg:
> >>> +    maxItems: 1
> >>> +
> >>> +  "#clock-cells":
> >>> +    const: 1
> >>> +
> >>> +  clocks:
> >>> +    items:
> >>> +      - description: clock input
> >>> +      - description: axi clock
> >>> +
> >>> +  clock-names:
> >>> +    items:
> >>> +      - const: clk_in1
> >>> +      - const: s_axi_aclk
> >>> +
> >>> +
> >>> +  xlnx,speed-grade:
> >>> +    $ref: /schemas/types.yaml#/definitions/uint32
> >>> +    enum: [1, 2, 3]
> >>> +    description:
> >>> +      Speed grade of the device. Higher the speed grade faster is the FPGA device.
> >>
> >> How does one decide what value?
> > This is a property of the FPGA fabric.
> > So  hdf/xsa  should tell that
> 
> Shubhrajyoti: Rob likely doesn't know what hdf/xsa is that's why it is
> better to avoid it.
> 
> fpgas/pl part of SoC are tested for performance and different chips have
> different speed grades. This is done for every chip and some chips are
> faster/slower. Based on this speed grade is labeled. And there is no way
> how to find at run time which speed grade your device has. That's why
> there is a need to have property to identify this.
> 
> In designed tools it is your responsibility to select proper chip based
> on your order and then this value is propagated in Xilinx standard way
> via device tree generator to fill the right value for this property.

The OPP framework and binding has support for speed grades via the
'supported-hw' property. I expect this speed-grade property could be
dropped and an opp table could be assigned to the clk controller node
for this speed grade by the DT author. Unfortunate that it isn't burned
somewhere into the device so that software can pick the right frequency
limits that way.

^ permalink raw reply

* Re: [GIT PULL] clk: samsung: Updates for v5.13
From: Stephen Boyd @ 2021-04-09 23:23 UTC (permalink / raw)
  To: Michael Turquette, Sylwester Nawrocki
  Cc: Chanwoo Choi, linux-clk, Bartlomiej Zolnierkiewicz,
	linux-samsung-soc
In-Reply-To: <915aada1-34ff-4419-2352-c99b3de5f368@samsung.com>

Quoting Sylwester Nawrocki (2021-04-09 11:22:27)
> Hi Stephen, Mike,
> 
> 
> The following changes since commit a38fd8748464831584a19438cbb3082b5a2dab15:
> 
>   Linux 5.12-rc2 (2021-03-05 17:33:41 -0800)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git tags/clk-v5.13-samsung
> 
> for you to fetch changes up to 7f32917642c7ea486c1bae5dfdebeeb56c35b29b:
> 
>   clk: samsung: Remove redundant dev_err calls (2021-04-08 19:35:26 +0200)
> 
> ----------------------------------------------------------------

Thanks. Pulled into clk-next

^ permalink raw reply

* Re: [PATCH v2 1/1] kernel.h: Split out panic and oops helpers
From: Thomas Bogendoerfer @ 2021-04-09 22:39 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Alexander Lobakin, Wei Liu, Rasmus Villemoes, Arnd Bergmann,
	Bjorn Andersson, Christian Brauner, Andrew Morton, Kees Cook,
	Mike Rapoport, Corey Minyard, Michael Ellerman, Vasily Gorbik,
	Jason J. Herne, Joerg Roedel, Michael Kelley, Joe Perches,
	Florian Fainelli, Krzysztof Kozlowski, Greg Kroah-Hartman,
	Scott Branden, Olof Johansson, Mihai Carabas, Wang Wenhu,
	Marek Czerski, Hongbo Yao, Mathieu Poirier, Vineeth Vijayan,
	Heiko Carstens, Peter Oberparleiter, Alexander Egorenkov,
	Tetsuo Handa, Vlastimil Babka, Paul E. McKenney,
	Steven Rostedt (VMware), linux-alpha, linux-kernel,
	linux-arm-kernel, linux-mips, linux-parisc, linuxppc-dev,
	linux-s390, sparclinux, linux-um, linux-hyperv, xen-devel,
	linux-xtensa, openipmi-developer, linux-clk, linux-edac,
	coresight, linux-leds, bcm-kernel-feedback-list, netdev, linux-pm,
	linux-remoteproc, linux-staging, dri-devel, linux-fbdev,
	linux-arch, kexec, rcu, linux-fsdevel, Richard Henderson,
	Ivan Kokshaysky, Matt Turner, Catalin Marinas, Will Deacon,
	James E.J. Bottomley, Helge Deller, Benjamin Herrenschmidt,
	Paul Mackerras, Christian Borntraeger, David S. Miller, Jeff Dike,
	Richard Weinberger, Anton Ivanov, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, x86, H. Peter Anvin, K. Y. Srinivasan,
	Haiyang Zhang, Stephen Hemminger, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Chris Zankel, Max Filippov, Corey Minyard,
	Paul Walmsley, Michael Turquette, Stephen Boyd, Dinh Nguyen,
	Mauro Carvalho Chehab, Tony Luck, James Morse, Robert Richter,
	Suzuki K Poulose, Mike Leach, Leo Yan, Alexander Shishkin,
	Pavel Machek, Alex Elder, Jakub Kicinski, Sebastian Reichel,
	Ohad Ben-Cohen, Jens Frederich, Daniel Drake, Jon Nettleton,
	Eric Biederman, Josh Triplett, Mathieu Desnoyers, Lai Jiangshan,
	Joel Fernandes, Luis Chamberlain, Iurii Zaikin, Mike Rapoport
In-Reply-To: <20210409100250.25922-1-andriy.shevchenko@linux.intel.com>

On Fri, Apr 09, 2021 at 01:02:50PM +0300, Andy Shevchenko wrote:
> kernel.h is being used as a dump for all kinds of stuff for a long time.
> Here is the attempt to start cleaning it up by splitting out panic and
> oops helpers.
> 
> There are several purposes of doing this:
> - dropping dependency in bug.h
> - dropping a loop by moving out panic_notifier.h
> - unload kernel.h from something which has its own domain
> 
> At the same time convert users tree-wide to use new headers, although
> for the time being include new header back to kernel.h to avoid twisted
> indirected includes for existing users.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Acked-by: Mike Rapoport <rppt@linux.ibm.com>
> Acked-by: Corey Minyard <cminyard@mvista.com>
> Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> Acked-by: Kees Cook <keescook@chromium.org>
> Acked-by: Wei Liu <wei.liu@kernel.org>
> Acked-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> ---
> v2:
>  - fixed all errors with allmodconfig on x86_64 (Andrew)
>  - checked with allyesconfig on x86_64
>  - additionally grepped source code for panic notifier list usage
>    and converted all users
>  - elaborated commit message (Luis)
>  - collected given tags (incl. Andrew's SoB, see below)
> 
> I added Andrew's SoB since part of the fixes I took from him. Andrew,
> feel free to amend or tell me how you want me to do.
> 
>  arch/mips/kernel/relocate.c                   |  1 +
>  arch/mips/sgi-ip22/ip22-reset.c               |  1 +
>  arch/mips/sgi-ip32/ip32-reset.c               |  1 +

Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

^ permalink raw reply

* Re: [PATCH v2 1/1] kernel.h: Split out panic and oops helpers
From: Helge Deller @ 2021-04-09 19:41 UTC (permalink / raw)
  To: Andy Shevchenko, Thomas Bogendoerfer, Alexander Lobakin, Wei Liu,
	Rasmus Villemoes, Arnd Bergmann, Bjorn Andersson,
	Christian Brauner, Andrew Morton, Kees Cook, Mike Rapoport,
	Corey Minyard, Michael Ellerman, Vasily Gorbik, Jason J. Herne,
	Joerg Roedel, Michael Kelley, Joe Perches, Florian Fainelli,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Scott Branden,
	Olof Johansson, Mihai Carabas, Wang Wenhu, Marek Czerski,
	Hongbo Yao, Mathieu Poirier, Vineeth Vijayan, Heiko Carstens,
	Peter Oberparleiter, Alexander Egorenkov, Tetsuo Handa,
	Vlastimil Babka, Paul E. McKenney, Steven Rostedt (VMware),
	linux-alpha, linux-kernel, linux-arm-kernel, linux-mips,
	linux-parisc, linuxppc-dev, linux-s390, sparclinux, linux-um,
	linux-hyperv, xen-devel, linux-xtensa, openipmi-developer,
	linux-clk, linux-edac, coresight, linux-leds,
	bcm-kernel-feedback-list, netdev, linux-pm, linux-remoteproc,
	linux-staging, dri-devel, linux-fbdev, linux-arch, kexec, rcu,
	linux-fsdevel
  Cc: Richard Henderson, Ivan Kokshaysky, Matt Turner, Catalin Marinas,
	Will Deacon, James E.J. Bottomley, Benjamin Herrenschmidt,
	Paul Mackerras, Christian Borntraeger, David S. Miller, Jeff Dike,
	Richard Weinberger, Anton Ivanov, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, x86, H. Peter Anvin, K. Y. Srinivasan,
	Haiyang Zhang, Stephen Hemminger, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Chris Zankel, Max Filippov, Corey Minyard,
	Paul Walmsley, Michael Turquette, Stephen Boyd, Dinh Nguyen,
	Mauro Carvalho Chehab, Tony Luck, James Morse, Robert Richter,
	Suzuki K Poulose, Mike Leach, Leo Yan, Alexander Shishkin,
	Pavel Machek, Alex Elder, Jakub Kicinski, Sebastian Reichel,
	Ohad Ben-Cohen, Jens Frederich, Daniel Drake, Jon Nettleton,
	Eric Biederman, Josh Triplett, Mathieu Desnoyers, Lai Jiangshan,
	Joel Fernandes, Luis Chamberlain, Iurii Zaikin, Mike Rapoport
In-Reply-To: <20210409100250.25922-1-andriy.shevchenko@linux.intel.com>

On 4/9/21 12:02 PM, Andy Shevchenko wrote:
> kernel.h is being used as a dump for all kinds of stuff for a long time.
> Here is the attempt to start cleaning it up by splitting out panic and
> oops helpers.
>
> There are several purposes of doing this:
> - dropping dependency in bug.h
> - dropping a loop by moving out panic_notifier.h
> - unload kernel.h from something which has its own domain
>
> At the same time convert users tree-wide to use new headers, although
> for the time being include new header back to kernel.h to avoid twisted
> indirected includes for existing users.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Acked-by: Mike Rapoport <rppt@linux.ibm.com>
> Acked-by: Corey Minyard <cminyard@mvista.com>
> Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> Acked-by: Kees Cook <keescook@chromium.org>
> Acked-by: Wei Liu <wei.liu@kernel.org>
> Acked-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

Acked-by: Helge Deller <deller@gmx.de> # parisc

Helge

^ permalink raw reply

* [PATCH v12 4/4] MAINTAINERS: add MT7621 CLOCK maintainer
From: Sergio Paracuellos @ 2021-04-09 19:20 UTC (permalink / raw)
  To: sboyd
  Cc: robh+dt, john, tsbogend, gregkh, linux-clk, devicetree,
	linux-mips, devel, neil, linux-kernel
In-Reply-To: <20210409192024.10024-1-sergio.paracuellos@gmail.com>

Adding myself as maintainer for mt7621 clock driver.

Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 809a68af5efd..ecad5d972122 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11288,6 +11288,12 @@ L:	linux-wireless@vger.kernel.org
 S:	Maintained
 F:	drivers/net/wireless/mediatek/mt7601u/
 
+MEDIATEK MT7621 CLOCK DRIVER
+M:	Sergio Paracuellos <sergio.paracuellos@gmail.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/clock/mediatek,mt7621-sysc.yaml
+F:	drivers/clk/ralink/clk-mt7621.c
+
 MEDIATEK MT7621/28/88 I2C DRIVER
 M:	Stefan Roese <sr@denx.de>
 L:	linux-i2c@vger.kernel.org
-- 
2.25.1


^ permalink raw reply related

* [PATCH v12 3/4] staging: mt7621-dts: use valid vendor 'mediatek' instead of invalid 'mtk'
From: Sergio Paracuellos @ 2021-04-09 19:20 UTC (permalink / raw)
  To: sboyd
  Cc: robh+dt, john, tsbogend, gregkh, linux-clk, devicetree,
	linux-mips, devel, neil, linux-kernel
In-Reply-To: <20210409192024.10024-1-sergio.paracuellos@gmail.com>

Vendor listed for mediatek in kernel vendor file 'vendor-prefixes.yaml'
contains 'mediatek' as a valid vendor string. Some nodes in the device
tree are using an invalid vendor string vfor 'mtk' instead. Fix all of
them in dts file. Update also ralink mt7621 related code to properly
match new strings. Even there are used in the device tree there are
some strings that are not referred anywhere but have been also updated
with new vendor name. These are 'mtk,mt7621-wdt', 'mtk,mt7621-nand',
'mtk,mt7621-mc', and 'mtk,mt7621-cpc'.

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
 arch/mips/ralink/mt7621.c              |  6 +++---
 drivers/staging/mt7621-dts/mt7621.dtsi | 12 ++++++------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index ca0ac607b0f3..5d74fc1c96ac 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -112,8 +112,8 @@ phys_addr_t mips_cpc_default_phys_base(void)
 
 void __init ralink_of_remap(void)
 {
-	rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc");
-	rt_memc_membase = plat_of_remap_node("mtk,mt7621-memc");
+	rt_sysc_membase = plat_of_remap_node("mediatek,mt7621-sysc");
+	rt_memc_membase = plat_of_remap_node("mediatek,mt7621-memc");
 
 	if (!rt_sysc_membase || !rt_memc_membase)
 		panic("Failed to remap core resources");
@@ -181,7 +181,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
 
 	if (n0 == MT7621_CHIP_NAME0 && n1 == MT7621_CHIP_NAME1) {
 		name = "MT7621";
-		soc_info->compatible = "mtk,mt7621-soc";
+		soc_info->compatible = "mediatek,mt7621-soc";
 	} else {
 		panic("mt7621: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
 	}
diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi
index b68183e7e6ad..f0c9ae757bcd 100644
--- a/drivers/staging/mt7621-dts/mt7621.dtsi
+++ b/drivers/staging/mt7621-dts/mt7621.dtsi
@@ -56,7 +56,7 @@ palmbus: palmbus@1E000000 {
 		#size-cells = <1>;
 
 		sysc: sysc@0 {
-			compatible = "mtk,mt7621-sysc", "syscon";
+			compatible = "mediatek,mt7621-sysc", "syscon";
 			reg = <0x0 0x100>;
 			#clock-cells = <1>;
 			ralink,memctl = <&memc>;
@@ -66,7 +66,7 @@ sysc: sysc@0 {
 		};
 
 		wdt: wdt@100 {
-			compatible = "mtk,mt7621-wdt";
+			compatible = "mediatek,mt7621-wdt";
 			reg = <0x100 0x100>;
 		};
 
@@ -123,17 +123,17 @@ i2s: i2s@a00 {
 		};
 
 		memc: memc@5000 {
-			compatible = "mtk,mt7621-memc", "syscon";
+			compatible = "mediatek,mt7621-memc", "syscon";
 			reg = <0x5000 0x1000>;
 		};
 
 		cpc: cpc@1fbf0000 {
-			     compatible = "mtk,mt7621-cpc";
+			     compatible = "mediatek,mt7621-cpc";
 			     reg = <0x1fbf0000 0x8000>;
 		};
 
 		mc: mc@1fbf8000 {
-			    compatible = "mtk,mt7621-mc";
+			    compatible = "mediatek,mt7621-mc";
 			    reg = <0x1fbf8000 0x8000>;
 		};
 
@@ -361,7 +361,7 @@ timer {
 	nand: nand@1e003000 {
 		status = "disabled";
 
-		compatible = "mtk,mt7621-nand";
+		compatible = "mediatek,mt7621-nand";
 		bank-width = <2>;
 		reg = <0x1e003000 0x800
 			0x1e003800 0x800>;
-- 
2.25.1


^ permalink raw reply related

* [PATCH v12 2/4] staging: mt7621-dts: make use of new 'mt7621-clk'
From: Sergio Paracuellos @ 2021-04-09 19:20 UTC (permalink / raw)
  To: sboyd
  Cc: robh+dt, john, tsbogend, gregkh, linux-clk, devicetree,
	linux-mips, devel, neil, linux-kernel
In-Reply-To: <20210409192024.10024-1-sergio.paracuellos@gmail.com>

Clocks for SoC mt7621 have been properly integrated so there is
no need to declare fixed clocks at all in the device tree. Remove
all of them, add new device tree nodes for mt7621-clk and update
the rest of the nodes to use them.

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
 drivers/staging/mt7621-dts/gbpc1.dts   | 11 ----
 drivers/staging/mt7621-dts/mt7621.dtsi | 74 ++++++++++++--------------
 2 files changed, 33 insertions(+), 52 deletions(-)

diff --git a/drivers/staging/mt7621-dts/gbpc1.dts b/drivers/staging/mt7621-dts/gbpc1.dts
index a7c0d3115d72..7716d0efe524 100644
--- a/drivers/staging/mt7621-dts/gbpc1.dts
+++ b/drivers/staging/mt7621-dts/gbpc1.dts
@@ -100,17 +100,6 @@ partition@50000 {
 	};
 };
 
-&sysclock {
-			compatible = "fixed-clock";
-			/* This is normally 1/4 of cpuclock */
-			clock-frequency = <225000000>;
-};
-
-&cpuclock {
-			compatible = "fixed-clock";
-			clock-frequency = <900000000>;
-};
-
 &pcie {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pcie_pins>;
diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi
index 16fc94f65486..b68183e7e6ad 100644
--- a/drivers/staging/mt7621-dts/mt7621.dtsi
+++ b/drivers/staging/mt7621-dts/mt7621.dtsi
@@ -1,5 +1,6 @@
 #include <dt-bindings/interrupt-controller/mips-gic.h>
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/mt7621-clk.h>
 
 / {
 	#address-cells = <1>;
@@ -27,27 +28,6 @@ aliases {
 		serial0 = &uartlite;
 	};
 
-	cpuclock: cpuclock@0 {
-		#clock-cells = <0>;
-		compatible = "fixed-clock";
-
-		/* FIXME: there should be way to detect this */
-		clock-frequency = <880000000>;
-	};
-
-	sysclock: sysclock@0 {
-		#clock-cells = <0>;
-		compatible = "fixed-clock";
-
-		/* This is normally 1/4 of cpuclock */
-		clock-frequency = <220000000>;
-	};
-
-	mmc_clock: mmc_clock@0 {
-		#clock-cells = <0>;
-		compatible = "fixed-clock";
-		clock-frequency = <48000000>;
-	};
 
 	mmc_fixed_3v3: fixedregulator@0 {
 		compatible = "regulator-fixed";
@@ -76,8 +56,13 @@ palmbus: palmbus@1E000000 {
 		#size-cells = <1>;
 
 		sysc: sysc@0 {
-			compatible = "mtk,mt7621-sysc";
+			compatible = "mtk,mt7621-sysc", "syscon";
 			reg = <0x0 0x100>;
+			#clock-cells = <1>;
+			ralink,memctl = <&memc>;
+			clock-output-names = "xtal", "cpu", "bus",
+					     "50m", "125m", "150m",
+					     "250m", "270m";
 		};
 
 		wdt: wdt@100 {
@@ -101,8 +86,8 @@ i2c: i2c@900 {
 			compatible = "mediatek,mt7621-i2c";
 			reg = <0x900 0x100>;
 
-			clocks = <&sysclock>;
-
+			clocks = <&sysc MT7621_CLK_I2C>;
+			clock-names = "i2c";
 			resets = <&rstctrl 16>;
 			reset-names = "i2c";
 
@@ -119,8 +104,8 @@ i2s: i2s@a00 {
 			compatible = "mediatek,mt7621-i2s";
 			reg = <0xa00 0x100>;
 
-			clocks = <&sysclock>;
-
+			clocks = <&sysc MT7621_CLK_I2S>;
+			clock-names = "i2s";
 			resets = <&rstctrl 17>;
 			reset-names = "i2s";
 
@@ -138,7 +123,7 @@ i2s: i2s@a00 {
 		};
 
 		memc: memc@5000 {
-			compatible = "mtk,mt7621-memc";
+			compatible = "mtk,mt7621-memc", "syscon";
 			reg = <0x5000 0x1000>;
 		};
 
@@ -156,8 +141,8 @@ uartlite: uartlite@c00 {
 			compatible = "ns16550a";
 			reg = <0xc00 0x100>;
 
-			clocks = <&sysclock>;
-			clock-frequency = <50000000>;
+			clocks = <&sysc MT7621_CLK_UART1>;
+			clock-names = "uart1";
 
 			interrupt-parent = <&gic>;
 			interrupts = <GIC_SHARED 26 IRQ_TYPE_LEVEL_HIGH>;
@@ -173,7 +158,8 @@ spi0: spi@b00 {
 			compatible = "ralink,mt7621-spi";
 			reg = <0xb00 0x100>;
 
-			clocks = <&sysclock>;
+			clocks = <&sysc MT7621_CLK_SPI>;
+			clock-names = "spi";
 
 			resets = <&rstctrl 18>;
 			reset-names = "spi";
@@ -189,6 +175,8 @@ gdma: gdma@2800 {
 			compatible = "ralink,rt3883-gdma";
 			reg = <0x2800 0x800>;
 
+			clocks = <&sysc MT7621_CLK_GDMA>;
+			clock-names = "gdma";
 			resets = <&rstctrl 14>;
 			reset-names = "dma";
 
@@ -206,6 +194,8 @@ hsdma: hsdma@7000 {
 			compatible = "mediatek,mt7621-hsdma";
 			reg = <0x7000 0x1000>;
 
+			clocks = <&sysc MT7621_CLK_HSDMA>;
+			clock-names = "hsdma";
 			resets = <&rstctrl 5>;
 			reset-names = "hsdma";
 
@@ -311,11 +301,6 @@ rstctrl: rstctrl {
 		#reset-cells = <1>;
 	};
 
-	clkctrl: clkctrl {
-		compatible = "ralink,rt2880-clock";
-		#clock-cells = <1>;
-	};
-
 	sdhci: sdhci@1E130000 {
 		status = "disabled";
 
@@ -334,7 +319,8 @@ sdhci: sdhci@1E130000 {
 		pinctrl-0 = <&sdhci_pins>;
 		pinctrl-1 = <&sdhci_pins>;
 
-		clocks = <&mmc_clock &mmc_clock>;
+		clocks = <&sysc MT7621_CLK_SHXC>,
+			 <&sysc MT7621_CLK_50M>;
 		clock-names = "source", "hclk";
 
 		interrupt-parent = <&gic>;
@@ -349,7 +335,7 @@ xhci: xhci@1E1C0000 {
 		       0x1e1d0700 0x0100>;
 		reg-names = "mac", "ippc";
 
-		clocks = <&sysclock>;
+		clocks = <&sysc MT7621_CLK_XTAL>;
 		clock-names = "sys_ck";
 
 		interrupt-parent = <&gic>;
@@ -368,7 +354,7 @@ gic: interrupt-controller@1fbc0000 {
 		timer {
 			compatible = "mti,gic-timer";
 			interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
-			clocks = <&cpuclock>;
+			clocks = <&sysc MT7621_CLK_CPU>;
 		};
 	};
 
@@ -381,6 +367,9 @@ nand: nand@1e003000 {
 			0x1e003800 0x800>;
 		#address-cells = <1>;
 		#size-cells = <1>;
+
+		clocks = <&sysc MT7621_CLK_NAND>;
+		clock-names = "nand";
 	};
 
 	ethsys: syscon@1e000000 {
@@ -394,8 +383,9 @@ ethernet: ethernet@1e100000 {
 		compatible = "mediatek,mt7621-eth";
 		reg = <0x1e100000 0x10000>;
 
-		clocks = <&sysclock>;
-		clock-names = "ethif";
+		clocks = <&sysc MT7621_CLK_FE>,
+			 <&sysc MT7621_CLK_ETH>;
+		clock-names = "fe", "ethif";
 
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -521,7 +511,9 @@ GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH
 
 		resets = <&rstctrl 24 &rstctrl 25 &rstctrl 26>;
 		reset-names = "pcie0", "pcie1", "pcie2";
-		clocks = <&clkctrl 24 &clkctrl 25 &clkctrl 26>;
+		clocks = <&sysc MT7621_CLK_PCIE0>,
+			 <&sysc MT7621_CLK_PCIE1>,
+			 <&sysc MT7621_CLK_PCIE2>;
 		clock-names = "pcie0", "pcie1", "pcie2";
 		phys = <&pcie0_phy 1>, <&pcie2_phy 0>;
 		phy-names = "pcie-phy0", "pcie-phy2";
-- 
2.25.1


^ permalink raw reply related

* [PATCH v12 1/4] clk: ralink: add clock driver for mt7621 SoC
From: Sergio Paracuellos @ 2021-04-09 19:20 UTC (permalink / raw)
  To: sboyd
  Cc: robh+dt, john, tsbogend, gregkh, linux-clk, devicetree,
	linux-mips, devel, neil, linux-kernel
In-Reply-To: <20210409192024.10024-1-sergio.paracuellos@gmail.com>

The documentation for this SOC only talks about two
registers regarding to the clocks:
* SYSC_REG_CPLL_CLKCFG0 - provides some information about
boostrapped refclock. PLL and dividers used for CPU and some
sort of BUS.
* SYSC_REG_CPLL_CLKCFG1 - a banch of gates to enable/disable
clocks for all or some ip cores.

Looking into driver code, and some openWRT patched there are
another frequencies which are used in some drivers (uart, sd...).
According to all of this information the clock plan for this
SoC is set as follows:
- Main top clock "xtal" from where all the rest of the world is
derived.
- CPU clock "cpu" derived from "xtal" frequencies and a bunch of
register reads and predividers.
- BUS clock "bus" derived from "cpu" and with (cpu / 4) MHz.
- Fixed clocks from "xtal":
    * "50m": 50 MHz.
    * "125m": 125 MHz.
    * "150m": 150 MHz.
    * "250m": 250 MHz.
    * "270m": 270 MHz.

We also have a buch of gate clocks with their parents:
  * "hsdma": "150m"
  * "fe": "250m"
  * "sp_divtx": "270m"
  * "timer": "50m"
  * "pcm": "270m"
  * "pio": "50m"
  * "gdma": "bus"
  * "nand": "125m"
  * "i2c": "50m"
  * "i2s": "270m"
  * "spi": "bus"
  * "uart1": "50m"
  * "uart2": "50m"
  * "uart3": "50m"
  * "eth": "50m"
  * "pcie0": "125m"
  * "pcie1": "125m"
  * "pcie2": "125m"
  * "crypto": "250m"
  * "shxc": "50m"

With this information the clk driver will provide clock and gates
functionality from a a set of hardcoded clocks allowing to define
a nice device tree without fixed clocks.

Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
 drivers/clk/Kconfig             |   1 +
 drivers/clk/Makefile            |   1 +
 drivers/clk/ralink/Kconfig      |  12 +
 drivers/clk/ralink/Makefile     |   2 +
 drivers/clk/ralink/clk-mt7621.c | 499 ++++++++++++++++++++++++++++++++
 5 files changed, 515 insertions(+)
 create mode 100644 drivers/clk/ralink/Kconfig
 create mode 100644 drivers/clk/ralink/Makefile
 create mode 100644 drivers/clk/ralink/clk-mt7621.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 7c5dc348c16f..70b23da997bf 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -382,6 +382,7 @@ source "drivers/clk/mediatek/Kconfig"
 source "drivers/clk/meson/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/qcom/Kconfig"
+source "drivers/clk/ralink/Kconfig"
 source "drivers/clk/renesas/Kconfig"
 source "drivers/clk/rockchip/Kconfig"
 source "drivers/clk/samsung/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 5325847469e9..1b35ad852721 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -98,6 +98,7 @@ obj-$(CONFIG_COMMON_CLK_NXP)		+= nxp/
 obj-$(CONFIG_MACH_PISTACHIO)		+= pistachio/
 obj-$(CONFIG_COMMON_CLK_PXA)		+= pxa/
 obj-$(CONFIG_COMMON_CLK_QCOM)		+= qcom/
+obj-y					+= ralink/
 obj-y					+= renesas/
 obj-$(CONFIG_ARCH_ROCKCHIP)		+= rockchip/
 obj-$(CONFIG_COMMON_CLK_SAMSUNG)	+= samsung/
diff --git a/drivers/clk/ralink/Kconfig b/drivers/clk/ralink/Kconfig
new file mode 100644
index 000000000000..edee32afdeaa
--- /dev/null
+++ b/drivers/clk/ralink/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# MediaTek Mt7621 Clock Driver
+#
+
+config CLK_MT7621
+	bool "Clock driver for MediaTek MT7621"
+	depends on SOC_MT7621 || COMPILE_TEST
+	default SOC_MT7621
+	select MFD_SYSCON
+	help
+	  This driver supports MediaTek MT7621 basic clocks.
diff --git a/drivers/clk/ralink/Makefile b/drivers/clk/ralink/Makefile
new file mode 100644
index 000000000000..cf6f9216379d
--- /dev/null
+++ b/drivers/clk/ralink/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_CLK_MT7621) += clk-mt7621.o
diff --git a/drivers/clk/ralink/clk-mt7621.c b/drivers/clk/ralink/clk-mt7621.c
new file mode 100644
index 000000000000..823638a7f485
--- /dev/null
+++ b/drivers/clk/ralink/clk-mt7621.c
@@ -0,0 +1,499 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek MT7621 Clock Driver
+ * Author: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <dt-bindings/clock/mt7621-clk.h>
+
+/* Configuration registers */
+#define SYSC_REG_SYSTEM_CONFIG0         0x10
+#define SYSC_REG_SYSTEM_CONFIG1         0x14
+#define SYSC_REG_CLKCFG0		0x2c
+#define SYSC_REG_CLKCFG1		0x30
+#define SYSC_REG_CUR_CLK_STS		0x44
+#define MEMC_REG_CPU_PLL		0x648
+
+#define XTAL_MODE_SEL_MASK		GENMASK(8, 6)
+#define CPU_CLK_SEL_MASK		GENMASK(31, 30)
+#define CUR_CPU_FDIV_MASK		GENMASK(12, 8)
+#define CUR_CPU_FFRAC_MASK		GENMASK(4, 0)
+#define CPU_PLL_PREDIV_MASK		GENMASK(13, 12)
+#define CPU_PLL_FBDIV_MASK		GENMASK(10, 4)
+
+struct mt7621_clk_priv {
+	struct regmap *sysc;
+	struct regmap *memc;
+};
+
+struct mt7621_clk {
+	struct clk_hw hw;
+	struct mt7621_clk_priv *priv;
+};
+
+struct mt7621_fixed_clk {
+	u8 idx;
+	const char *name;
+	const char *parent_name;
+	unsigned long rate;
+	struct clk_hw *hw;
+};
+
+struct mt7621_gate {
+	u8 idx;
+	const char *name;
+	const char *parent_name;
+	struct mt7621_clk_priv *priv;
+	u32 bit_idx;
+	struct clk_hw hw;
+};
+
+#define GATE(_id, _name, _pname, _shift)	\
+	{					\
+		.idx		= _id,		\
+		.name		= _name,	\
+		.parent_name	= _pname,	\
+		.bit_idx	= _shift	\
+	}
+
+static struct mt7621_gate mt7621_gates[] = {
+	GATE(MT7621_CLK_HSDMA, "hsdma", "150m", BIT(5)),
+	GATE(MT7621_CLK_FE, "fe", "250m", BIT(6)),
+	GATE(MT7621_CLK_SP_DIVTX, "sp_divtx", "270m", BIT(7)),
+	GATE(MT7621_CLK_TIMER, "timer", "50m", BIT(8)),
+	GATE(MT7621_CLK_PCM, "pcm", "270m", BIT(11)),
+	GATE(MT7621_CLK_PIO, "pio", "50m", BIT(13)),
+	GATE(MT7621_CLK_GDMA, "gdma", "bus", BIT(14)),
+	GATE(MT7621_CLK_NAND, "nand", "125m", BIT(15)),
+	GATE(MT7621_CLK_I2C, "i2c", "50m", BIT(16)),
+	GATE(MT7621_CLK_I2S, "i2s", "270m", BIT(17)),
+	GATE(MT7621_CLK_SPI, "spi", "bus", BIT(18)),
+	GATE(MT7621_CLK_UART1, "uart1", "50m", BIT(19)),
+	GATE(MT7621_CLK_UART2, "uart2", "50m", BIT(20)),
+	GATE(MT7621_CLK_UART3, "uart3", "50m", BIT(21)),
+	GATE(MT7621_CLK_ETH, "eth", "50m", BIT(23)),
+	GATE(MT7621_CLK_PCIE0, "pcie0", "125m", BIT(24)),
+	GATE(MT7621_CLK_PCIE1, "pcie1", "125m", BIT(25)),
+	GATE(MT7621_CLK_PCIE2, "pcie2", "125m", BIT(26)),
+	GATE(MT7621_CLK_CRYPTO, "crypto", "250m", BIT(29)),
+	GATE(MT7621_CLK_SHXC, "shxc", "50m", BIT(30))
+};
+
+static inline struct mt7621_gate *to_mt7621_gate(struct clk_hw *hw)
+{
+	return container_of(hw, struct mt7621_gate, hw);
+}
+
+static int mt7621_gate_enable(struct clk_hw *hw)
+{
+	struct mt7621_gate *clk_gate = to_mt7621_gate(hw);
+	struct regmap *sysc = clk_gate->priv->sysc;
+
+	return regmap_update_bits(sysc, SYSC_REG_CLKCFG1,
+				  clk_gate->bit_idx, clk_gate->bit_idx);
+}
+
+static void mt7621_gate_disable(struct clk_hw *hw)
+{
+	struct mt7621_gate *clk_gate = to_mt7621_gate(hw);
+	struct regmap *sysc = clk_gate->priv->sysc;
+
+	regmap_update_bits(sysc, SYSC_REG_CLKCFG1, clk_gate->bit_idx, 0);
+}
+
+static int mt7621_gate_is_enabled(struct clk_hw *hw)
+{
+	struct mt7621_gate *clk_gate = to_mt7621_gate(hw);
+	struct regmap *sysc = clk_gate->priv->sysc;
+	u32 val;
+
+	if (regmap_read(sysc, SYSC_REG_CLKCFG1, &val))
+		return 0;
+
+	return val & BIT(clk_gate->bit_idx);
+}
+
+static const struct clk_ops mt7621_gate_ops = {
+	.enable = mt7621_gate_enable,
+	.disable = mt7621_gate_disable,
+	.is_enabled = mt7621_gate_is_enabled,
+};
+
+static int mt7621_gate_ops_init(struct device *dev,
+				struct mt7621_gate *sclk)
+{
+	struct clk_init_data init = {
+		/*
+		 * Until now no clock driver existed so
+		 * these SoC drivers are not prepared
+		 * yet for the clock. We don't want kernel to
+		 * disable anything so we add CLK_IS_CRITICAL
+		 * flag here.
+		 */
+		.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+		.num_parents = 1,
+		.parent_names = &sclk->parent_name,
+		.ops = &mt7621_gate_ops,
+		.name = sclk->name,
+	};
+
+	sclk->hw.init = &init;
+	return devm_clk_hw_register(dev, &sclk->hw);
+}
+
+static int mt7621_register_gates(struct device *dev,
+				 struct clk_hw_onecell_data *clk_data,
+				 struct mt7621_clk_priv *priv)
+{
+	struct clk_hw **hws = clk_data->hws;
+	int ret, i;
+
+	for (i = 0; i < ARRAY_SIZE(mt7621_gates); i++) {
+		struct mt7621_gate *sclk = &mt7621_gates[i];
+
+		sclk->priv = priv;
+		ret = mt7621_gate_ops_init(dev, sclk);
+		if (ret) {
+			dev_err(dev, "Couldn't register clock %s\n", sclk->name);
+			goto err_clk_unreg;
+		}
+
+		hws[sclk->idx] = &sclk->hw;
+	}
+
+	return 0;
+
+err_clk_unreg:
+	while (--i >= 0) {
+		struct mt7621_gate *sclk = &mt7621_gates[i];
+
+		clk_hw_unregister(&sclk->hw);
+	}
+	return ret;
+}
+
+#define FIXED(_id, _name, _rate)		\
+	{					\
+		.idx		= _id,		\
+		.name		= _name,	\
+		.parent_name	= "xtal",	\
+		.rate		= _rate		\
+	}
+
+static struct mt7621_fixed_clk mt7621_fixed_clks[] = {
+	FIXED(MT7621_CLK_50M, "50m", 50000000),
+	FIXED(MT7621_CLK_125M, "125m", 125000000),
+	FIXED(MT7621_CLK_150M, "150m", 150000000),
+	FIXED(MT7621_CLK_250M, "250m", 250000000),
+	FIXED(MT7621_CLK_270M, "270m", 270000000),
+};
+
+static int mt7621_register_fixed_clocks(struct device *dev,
+					struct clk_hw_onecell_data *clk_data)
+{
+	struct clk_hw **hws = clk_data->hws;
+	int ret, i;
+
+	for (i = 0; i < ARRAY_SIZE(mt7621_fixed_clks); i++) {
+		struct mt7621_fixed_clk *sclk = &mt7621_fixed_clks[i];
+
+		sclk->hw = clk_hw_register_fixed_rate(dev, sclk->name,
+						      sclk->parent_name, 0,
+						      sclk->rate);
+		if (IS_ERR(sclk->hw)) {
+			dev_err(dev, "Couldn't register clock %s\n", sclk->name);
+			ret = PTR_ERR(sclk->hw);
+			goto err_clk_unreg;
+		}
+
+		hws[sclk->idx] = sclk->hw;
+	}
+
+	return 0;
+
+err_clk_unreg:
+	while (--i >= 0) {
+		struct mt7621_fixed_clk *sclk = &mt7621_fixed_clks[i];
+
+		clk_hw_unregister_fixed_rate(sclk->hw);
+	}
+	return ret;
+}
+
+static inline struct mt7621_clk *to_mt7621_clk(struct clk_hw *hw)
+{
+	return container_of(hw, struct mt7621_clk, hw);
+}
+
+static unsigned long mt7621_xtal_recalc_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	struct mt7621_clk *clk = to_mt7621_clk(hw);
+	struct regmap *sysc = clk->priv->sysc;
+	u32 val;
+
+	regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG0, &val);
+	val = FIELD_GET(XTAL_MODE_SEL_MASK, val);
+
+	if (val <= 2)
+		return 20000000;
+	if (val <= 5)
+		return 40000000;
+
+	return 25000000;
+}
+
+static unsigned long mt7621_cpu_recalc_rate(struct clk_hw *hw,
+					    unsigned long xtal_clk)
+{
+	static const u32 prediv_tbl[] = { 0, 1, 2, 2 };
+	struct mt7621_clk *clk = to_mt7621_clk(hw);
+	struct regmap *sysc = clk->priv->sysc;
+	struct regmap *memc = clk->priv->memc;
+	u32 clkcfg, clk_sel, curclk, ffiv, ffrac;
+	u32 pll, prediv, fbdiv;
+	unsigned long cpu_clk;
+
+	regmap_read(sysc, SYSC_REG_CLKCFG0, &clkcfg);
+	clk_sel = FIELD_GET(CPU_CLK_SEL_MASK, clkcfg);
+
+	regmap_read(sysc, SYSC_REG_CUR_CLK_STS, &curclk);
+	ffiv = FIELD_GET(CUR_CPU_FDIV_MASK, curclk);
+	ffrac = FIELD_GET(CUR_CPU_FFRAC_MASK, curclk);
+
+	switch (clk_sel) {
+	case 0:
+		cpu_clk = 500000000;
+		break;
+	case 1:
+		regmap_read(memc, MEMC_REG_CPU_PLL, &pll);
+		fbdiv = FIELD_GET(CPU_PLL_FBDIV_MASK, pll);
+		prediv = FIELD_GET(CPU_PLL_PREDIV_MASK, pll);
+		cpu_clk = ((fbdiv + 1) * xtal_clk) >> prediv_tbl[prediv];
+		break;
+	default:
+		cpu_clk = xtal_clk;
+	}
+
+	return cpu_clk / ffiv * ffrac;
+}
+
+static unsigned long mt7621_bus_recalc_rate(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	return parent_rate / 4;
+}
+
+#define CLK_BASE(_name, _parent, _recalc) {				\
+	.init = &(struct clk_init_data) {				\
+		.name = _name,						\
+		.ops = &(const struct clk_ops) {			\
+			.recalc_rate = _recalc,				\
+		},							\
+		.parent_data = &(const struct clk_parent_data) {	\
+			.name = _parent,				\
+			.fw_name = _parent				\
+		},							\
+		.num_parents = _parent ? 1 : 0				\
+	},								\
+}
+
+static struct mt7621_clk mt7621_clks_base[] = {
+	{ CLK_BASE("xtal", NULL, mt7621_xtal_recalc_rate) },
+	{ CLK_BASE("cpu", "xtal", mt7621_cpu_recalc_rate) },
+	{ CLK_BASE("bus", "cpu", mt7621_bus_recalc_rate) },
+};
+
+static struct clk_hw *mt7621_clk_early[MT7621_CLK_MAX];
+
+static int mt7621_register_early_clocks(struct device_node *np,
+					struct clk_hw_onecell_data *clk_data,
+					struct mt7621_clk_priv *priv)
+{
+	struct clk_hw **hws = clk_data->hws;
+	struct mt7621_clk *sclk;
+	int ret, i, j;
+
+	for (i = 0; i < ARRAY_SIZE(mt7621_clks_base); i++) {
+		sclk = &mt7621_clks_base[i];
+		sclk->priv = priv;
+		ret = of_clk_hw_register(np, &sclk->hw);
+		if (ret) {
+			pr_err("Couldn't register top clock %i\n", i);
+			goto err_clk_unreg;
+		}
+
+		hws[i] = &sclk->hw;
+		mt7621_clk_early[i] = &sclk->hw;
+	}
+
+	for (j = i; j < MT7621_CLK_MAX; j++)
+		mt7621_clk_early[j] = ERR_PTR(-EPROBE_DEFER);
+
+	return 0;
+
+err_clk_unreg:
+	while (--i >= 0) {
+		sclk = &mt7621_clks_base[i];
+		clk_hw_unregister(&sclk->hw);
+	}
+	return ret;
+}
+
+static void __init mt7621_clk_init(struct device_node *node)
+{
+	struct mt7621_clk_priv *priv;
+	struct clk_hw_onecell_data *clk_data;
+	int ret, i, count;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return;
+
+	priv->sysc = syscon_node_to_regmap(node);
+	if (IS_ERR(priv->sysc)) {
+		pr_err("Could not get sysc syscon regmap\n");
+		goto free_clk_priv;
+	}
+
+	priv->memc = syscon_regmap_lookup_by_phandle(node, "ralink,memctl");
+	if (IS_ERR(priv->memc)) {
+		pr_err("Could not get memc syscon regmap\n");
+		goto free_clk_priv;
+	}
+
+	count = ARRAY_SIZE(mt7621_clks_base) +
+		ARRAY_SIZE(mt7621_fixed_clks) + ARRAY_SIZE(mt7621_gates);
+	clk_data = kzalloc(struct_size(clk_data, hws, count), GFP_KERNEL);
+	if (!clk_data)
+		goto free_clk_priv;
+
+	ret = mt7621_register_early_clocks(node, clk_data, priv);
+	if (ret) {
+		pr_err("Couldn't register top clocks\n");
+		goto free_clk_data;
+	}
+
+	clk_data->num = count;
+
+	ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+	if (ret) {
+		pr_err("Couldn't add clk hw provider\n");
+		goto unreg_clk_top;
+	}
+
+	return;
+
+unreg_clk_top:
+	for (i = 0; i < ARRAY_SIZE(mt7621_clks_base); i++) {
+		struct mt7621_clk *sclk = &mt7621_clks_base[i];
+
+		clk_hw_unregister(&sclk->hw);
+	}
+
+free_clk_data:
+	kfree(clk_data);
+
+free_clk_priv:
+	kfree(priv);
+}
+CLK_OF_DECLARE_DRIVER(mt7621_clk, "mediatek,mt7621-sysc", mt7621_clk_init);
+
+static int mt7621_clk_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct clk_hw_onecell_data *clk_data;
+	struct device *dev = &pdev->dev;
+	struct mt7621_clk_priv *priv;
+	int ret, i, count;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->sysc = syscon_node_to_regmap(np);
+	if (IS_ERR(priv->sysc)) {
+		ret = PTR_ERR(priv->sysc);
+		dev_err(dev, "Could not get sysc syscon regmap\n");
+		return ret;
+	}
+
+	priv->memc = syscon_regmap_lookup_by_phandle(np, "ralink,memctl");
+	if (IS_ERR(priv->memc)) {
+		ret = PTR_ERR(priv->memc);
+		dev_err(dev, "Could not get memc syscon regmap\n");
+		return ret;
+	}
+
+	count = ARRAY_SIZE(mt7621_clks_base) +
+		ARRAY_SIZE(mt7621_fixed_clks) + ARRAY_SIZE(mt7621_gates);
+	clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count),
+				GFP_KERNEL);
+	if (!clk_data) {
+		ret = -ENOMEM;
+		return ret;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(mt7621_clks_base); i++)
+		clk_data->hws[i] = mt7621_clk_early[i];
+
+	ret = mt7621_register_fixed_clocks(dev, clk_data);
+	if (ret) {
+		dev_err(dev, "Couldn't register fixed clocks\n");
+		return ret;
+	}
+
+	ret = mt7621_register_gates(dev, clk_data, priv);
+	if (ret) {
+		dev_err(dev, "Couldn't register fixed clock gates\n");
+		goto unreg_clk_fixed;
+	}
+
+	clk_data->num = count;
+
+	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+	if (ret) {
+		dev_err(dev, "Couldn't add clk hw provider\n");
+		goto unreg_clk_gates;
+	}
+
+	return 0;
+
+unreg_clk_gates:
+	for (i = 0; i < ARRAY_SIZE(mt7621_gates); i++) {
+		struct mt7621_gate *sclk = &mt7621_gates[i];
+
+		clk_hw_unregister(&sclk->hw);
+	}
+
+unreg_clk_fixed:
+	for (i = 0; i < ARRAY_SIZE(mt7621_fixed_clks); i++) {
+		struct mt7621_fixed_clk *sclk = &mt7621_fixed_clks[i];
+
+		clk_hw_unregister_fixed_rate(sclk->hw);
+	}
+
+	return ret;
+}
+
+static const struct of_device_id mt7621_clk_of_match[] = {
+	{ .compatible = "mediatek,mt7621-sysc" },
+	{}
+};
+
+static struct platform_driver mt7621_clk_driver = {
+	.probe = mt7621_clk_probe,
+	.driver = {
+		.name = "mt7621-clk",
+		.of_match_table = mt7621_clk_of_match,
+	},
+};
+builtin_platform_driver(mt7621_clk_driver);
-- 
2.25.1


^ permalink raw reply related

* [PATCH v12 0/4] MIPS: ralink: add CPU clock detection and clock driver for MT7621
From: Sergio Paracuellos @ 2021-04-09 19:20 UTC (permalink / raw)
  To: sboyd
  Cc: robh+dt, john, tsbogend, gregkh, linux-clk, devicetree,
	linux-mips, devel, neil, linux-kernel

This patchset ports CPU clock detection for MT7621 from OpenWrt
and adds a complete clock plan for the mt7621 SOC.

The documentation for this SOC only talks about two registers
regarding to the clocks:
* SYSC_REG_CPLL_CLKCFG0 - provides some information about boostrapped
refclock. PLL and dividers used for CPU and some sort of BUS (AHB?).
* SYSC_REG_CPLL_CLKCFG1 - a banch of gates to enable/disable clocks for
all or some ip cores.

Registers needed for this driver to work are in two already mapped areas
in its platform's device tree. These are 'sysc' and 'memc' nodes. Most
of other drivers just make use of platform operations defined in
'asm/mach-ralink/ralink_regs.h' but this can be avoided declaring this
two nodes to be accesible through syscon. Main registers for the clocks
are in the sysc control node so this node is merged with clock properties
and will also be the clock provider for the SoC.

No documentation about a probably existent set of dividers for each ip
core is included in the datasheets. So we cannot make anything better,
AFAICT.

Looking into driver code, and some openWRT patched there are
another frequences which are used in some drivers (uart, sd...).
According to all of this information the clock plan for this
SoC is set as follows:
 - Main top clock "xtal" from where all the rest of the world is
   derived.
 - CPU clock "cpu" derived from "xtal" frequencies and a bunch of
   register reads and predividers.
 - BUS clock "bus" derived from "cpu" and with (cpu / 4) MHz.
 - Fixed clocks from "xtal":
    * "50m": 50 MHz.
    * "125m": 125 MHz.
    * "150m": 150 MHz.
    * "250m": 250 MHz.
    * "270m": 270 MHz.

We also have a buch of gate clocks with their parents:
 - "hsdma": "150m"
 - "fe": "250m"
 - "sp_divtx": "270m"
 - "timer": "50m"
 - "pcm": "270m"
 - "pio": "50m"
 - "gdma": "bus"
 - "nand": "125m"
 - "i2c": "50m"
 - "i2s": "270m"
 - "spi": "bus"
 - "uart1": "50m"
 - "uart2": "50m"
 - "uart3": "50m"
 - "eth": "50m"
 - "pcie0": "125m"
 - "pcie1": "125m"
 - "pcie2": "125m"
 - "crypto": "250m"
 - "shxc": "50m"

There was a previous attempt of doing this here[0] but the author
(Chuanhong Guo) did not wanted to make assumptions of a clock plan
for the platform that time. It seems that now he has a better idea of
how the clocks are dispossed for this SoC so he share code[1] where
some frequencies and clock parents for the gates are coded from a
real mediatek private clock plan.
                                                
I do really want this to be upstreamed so according to the comments
in previous attempt[0] from Oleksij Rempel and the frequencies in
code[1] I have tried to do this by myself.

All of this patches have been tested in a GNUBee PC1 resulting in a
working platform.

Changes in v12:
 - First to patches of previous v11 series has already merged so this
   new seres only have remaining four patches.
 - Add Acked-by from Thomas Bogendoerfer for patch 3/4.
 - Drop menu from Kconfig and only maintain CLK_MT7621 option.
 - Remove comma from sentinel so it's a compile error if
   another element is added after.
 - Use CLK_IS_CRITICAL with a comment when gates are registered and
   drop 'mt7621_prepare_enable_clocks' function.
 - Move sclk declaration to the top of the mt7621_register_early_clocks
   function to avoid to declare it twice for success and error paths.
 - Use devm_* APIs instead of directly use kzalloc and simplify error
   path.

Changes in v11:
 - Collect Rob's Reviewed-by in bindings documentation patch.
 - Fix MAINTAINERS patch using file 'mediatek,mt7621-sysc.yaml'
   for documentation bindings.

Changes in v10:
 - Merge clock properties into 'sysc' system control node making
   this node a clock provider.
 - Update driver to use 'mediatek,mt7621-sysc' as compatible string.
 - Update documentation bindings and its related filename to 
   'mediatek,mt7621-sysc.yaml'.
 - Make use of 'linux/bitfields.h' header to avoid some preprocesor
   shift definitions and just use bit masks decreasing a bit LOC.

Changes in v9:
 - Set two missing ret values to its related PTR_ERR in function
   'mt7621_clk_probe' (also related with [3]).
 - Select MFC_SYSCON in Kconfig.

Changes in v8:
 - Fix kernel test robot complain about the use of 'ret' variable
   initialized: see [3]

Changes in v7:
 - Make use of CLK_OF_DECLARE_DRIVER instead of CLK_OF_DECLARE and
   register there only the top clocks that are needed in 'of_clk_init'.
   The rest of the clocks (fixed and gates) are now registered using
   a platform driver. Because we have avoid architecture dependent stuff
   now this has sense because we can enable this driver for COMPILE_TEST.
 - Convert fixed clocks and gates related function to receive a 'struct
   device' pointer instead of 'struct device_node' one.
 - Make use of dev_ APIS in stuff related with platform driver instead
   of use device_node related stuff. 
 - Add new static global 'mt7621_clk_early' to store pointers to clk_hw
   registered at 'of_clk_init' stage. Make use of this in platform device
   probe function to properly copy this into the new required 'clk_data'
   to provide a properly hierarchy clock structure.
 - Rename 'mt7621_register_top_clocks' function into a more accurate 
   name now which is 'mt7621_register_early_clocks'.
 - Enable driver for COMPILE_TEST.

Changes in v6:
 - Rewrite bindings to properly access the registers needed for the driver
   making use of syscon for two different areas: 'sysc' and 'memc'. With
   this changes architecture dependent include 'asm/mach-ralink/ralink_regs.h'
   is not needed anymore because we access this two syscons using a phandle
   through kernel's regmap APIs. Explanation of this two areas is in [2].
 - Add new 'mt7621_clk_priv' struct to store there pointers to regmap handlers
   to be able to use regmap operations from normal clock api functions. Add
   this pointer in 'mt7621_clk' and 'mt7621_clk_gate' before register its
   related clocks to make things work.
 - Add Greg's Acked-by in patches 4 and 5.
 - Rebase this series on the top of linux-next tag 'next-20210215'.

v5 RESEND notes:
 - I am resending this as I was told to do that.
 - Please, take into account Rob's comments to DT node patch and my
   reply with explanation about how are the current device tree nodes
   for this architecture being used in [2].

Changes in v5:
 - Avoid the use of syscon. All drivers of this platform are just using
   platform operations defined in 'asm/mach-ralink/ralink_regs.h'. We also
   need them for some PLL registers that are not in the sys control area.
   Hence, since we must use this dependency avoid to define clock driver
   as a child of the sysc node in the device tree and follow current
   platform code style.
 - Update bindings documentation to don't refer the syscon and make
   remove 'clock-output-names' property from required ones.
 - Use 'asm/mach-ralink/ralink_regs.h' platform read and write operations
   instead of regmap from the syscon node.
 - Remove 'mt7621_clk_provider' and directly declare 'clk_hw_onecell_data'
   pointer in 'mt7621_clk_init' and pass from there into different register
   functions. Remove pointers to 'mt7621_clk_provider' in the rest fo structs
   used in this driver.
 - Remove MHZ macro and just pass values directly in hertzs.
 - Avoid 'CLK_IGNORE_UNUSED' flag for gates and add a new function called
   'mt7621_prepare_enable_clocks' to prepare all of them to make clocks
   referenced and don't affect current driver code.
 - Remove COMPILE_TEST from Kconfig because of the use of especific arch
   stuff.
 - Fix commit message where a typo for "frequencies" word was present.
 - Make use of parent_clk_data in 'CLK_BASE' macro.
 - Remove MODULE_* macros from code since this is not a module.
 - Remove not needed includes.
 - Hardcode "xtal" as parent in FIXED macro.
 - Change 'else if' clause into 'if' clause since a return statement was
   being used in 'mt7621_xtal_recalc_rate'.

 NOTES:
   - Driver is still being declared using 'CLK_OF_DECLARE' for all the  
     clocks. I have explored the possibility to make some of them available
     afterwards using 'CLK_OF_DECLARE_DRIVER' for top clocks and the rest
     using a platform driver. The resulting code was uglier since we only want
     to use the same device tree node and the top clocks must be copied again
     for the new platform register stuff to properly have a good hierarchy.
     New globals needs to be introduced and in this particular case I don't
     really see the benefits of doing in this way. I am totally ok to have all
     the clocks registered at early stage since from other drivers perspective
     we only really need to enable gates. So, I prefer to have them in that
     way if it is not a real problem, of course.

Changes in v4:
 - Add Acked-by from Rob Herring for binding headers (PATCH 1/6).
 - Convert bindings to not use syscon phandle and declare clock as
   a child of the syscon node. Update device tree and binding doc
   accordly.
 - Make use of 'syscon_node_to_regmap' in driver code instead of
   get this using the phandle function.
 - Properly unregister clocks for the error path of the function
   'mt7621_clk_init'.
 - Include ARRAY_SIZE of fixed clocks in the 'count' to kzalloc
   of 'clk_data'.
 - Add new patch changing invalid vendor 'mtk' in favour of 'mediatek'
   which is the one listed in 'vendor-prefixes.yaml'. Update mt7621 code
   accordly. I have added this patch inside this series because clk
   binding is referring syscon node and the string for that node was
   with not listed vendor. Hence update and have all of this correct
   in the same series.

Changes in v3:
 - Fix compilation warnings reported by kernel test robot because of
   ignoring return values of 'of_clk_hw_register' in functions
   'mt7621_register_top_clocks' and 'mt7621_gate_ops_init'.
 - Fix dts file and binding documentation 'clock-output-names'.

Changes in v2:
 - Remove the following patches:
   * dt: bindings: add mt7621-pll device tree binding documentation.
   * MIPS: ralink: add clock device providing cpu/ahb/apb clock for mt7621.
 - Move all relevant clock code to 'drivers/clk/ralink/clk-mt7621.c' and
   unify there previous 'mt7621-pll' and 'mt7621-clk' into a unique driver
   and binding 'mt7621-clk'.
 - Driver is not a platform driver anymore and now make use of 'CLK_OF_DECLARE'
   because we need clocks available in 'plat_time_init' before setting up
   the timer for the GIC.
 - Use new fixed clocks as parents for different gates and deriving from 'xtal'
   using frequencies in[1].
 - Adapt dts file and bindings header and documentation for new changes.
 - Change MAINTAINERS file to only contains clk-mt7621.c code and
   mediatek,mt7621-clk.yaml file.

[0]: https://www.lkml.org/lkml/2019/7/23/1044
[1]: https://github.com/981213/linux/commit/2eca1f045e4c3db18c941135464c0d7422ad8133
[2]: https://lkml.org/lkml/2020/12/20/47
[3]: http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2021-February/150772.html

Sergio Paracuellos (4):
  clk: ralink: add clock driver for mt7621 SoC
  staging: mt7621-dts: make use of new 'mt7621-clk'
  staging: mt7621-dts: use valid vendor 'mediatek' instead of invalid
    'mtk'
  MAINTAINERS: add MT7621 CLOCK maintainer

 MAINTAINERS                            |   6 +
 arch/mips/ralink/mt7621.c              |   6 +-
 drivers/clk/Kconfig                    |   1 +
 drivers/clk/Makefile                   |   1 +
 drivers/clk/ralink/Kconfig             |  12 +
 drivers/clk/ralink/Makefile            |   2 +
 drivers/clk/ralink/clk-mt7621.c        | 499 +++++++++++++++++++++++++
 drivers/staging/mt7621-dts/gbpc1.dts   |  11 -
 drivers/staging/mt7621-dts/mt7621.dtsi |  82 ++--
 9 files changed, 561 insertions(+), 59 deletions(-)
 create mode 100644 drivers/clk/ralink/Kconfig
 create mode 100644 drivers/clk/ralink/Makefile
 create mode 100644 drivers/clk/ralink/clk-mt7621.c

-- 
2.25.1


^ permalink raw reply

* Re: [PATCH v11 3/6] clk: ralink: add clock driver for mt7621 SoC
From: Sergio Paracuellos @ 2021-04-09 18:34 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Rob Herring, John Crispin, Thomas Bogendoerfer, Greg KH,
	open list:COMMON CLK FRAMEWORK,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:MIPS, open list:STAGING SUBSYSTEM, NeilBrown,
	linux-kernel
In-Reply-To: <161799206350.3790633.14908755786674195715@swboyd.mtv.corp.google.com>

Hi,

On Fri, Apr 9, 2021 at 8:14 PM Stephen Boyd <sboyd@kernel.org> wrote:
>
> Quoting Sergio Paracuellos (2021-03-08 21:22:23)
> > diff --git a/drivers/clk/ralink/Kconfig b/drivers/clk/ralink/Kconfig
> > new file mode 100644
> > index 000000000000..3e3f5cb9ad88
> > --- /dev/null
> > +++ b/drivers/clk/ralink/Kconfig
> > @@ -0,0 +1,15 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +#
> > +# MediaTek Mt7621 Clock Driver
> > +#
> > +menu "Clock driver for Mediatek mt7621 SoC"
> > +       depends on SOC_MT7621 || COMPILE_TEST
>
> Do we need a menu and a config that says the same thing? Maybe the menu
> can be dropped?

Ok, I will drop the menu from this Kconfig.

>
> > +
> > +config CLK_MT7621
> > +       bool "Clock driver for MediaTek MT7621"
> > +       depends on SOC_MT7621 || COMPILE_TEST
> > +       default SOC_MT7621
> > +       select MFD_SYSCON
> > +       help
> > +         This driver supports MediaTek MT7621 basic clocks.
> > +endmenu
> > diff --git a/drivers/clk/ralink/Makefile b/drivers/clk/ralink/Makefile
> > new file mode 100644
> > index 000000000000..cf6f9216379d
> > --- /dev/null
> > +++ b/drivers/clk/ralink/Makefile
> > @@ -0,0 +1,2 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +obj-$(CONFIG_CLK_MT7621) += clk-mt7621.o
> > diff --git a/drivers/clk/ralink/clk-mt7621.c b/drivers/clk/ralink/clk-mt7621.c
> > new file mode 100644
> > index 000000000000..6aea5accd51c
> > --- /dev/null
> > +++ b/drivers/clk/ralink/clk-mt7621.c
> > @@ -0,0 +1,528 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Mediatek MT7621 Clock Driver
> > + * Author: Sergio Paracuellos <sergio.paracuellos@gmail.com>
> > + */
> > +
> > +#include <linux/bitfield.h>
> > +#include <linux/bitops.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/clk.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +#include <linux/slab.h>
> > +#include <dt-bindings/clock/mt7621-clk.h>
> > +
> > +/* Configuration registers */
> > +#define SYSC_REG_SYSTEM_CONFIG0         0x10
> > +#define SYSC_REG_SYSTEM_CONFIG1         0x14
> > +#define SYSC_REG_CLKCFG0               0x2c
> > +#define SYSC_REG_CLKCFG1               0x30
> > +#define SYSC_REG_CUR_CLK_STS           0x44
> > +#define MEMC_REG_CPU_PLL               0x648
> > +
> > +#define XTAL_MODE_SEL_MASK             GENMASK(8, 6)
> > +#define CPU_CLK_SEL_MASK               GENMASK(31, 30)
> > +#define CUR_CPU_FDIV_MASK              GENMASK(12, 8)
> > +#define CUR_CPU_FFRAC_MASK             GENMASK(4, 0)
> > +#define CPU_PLL_PREDIV_MASK            GENMASK(13, 12)
> > +#define CPU_PLL_FBDIV_MASK             GENMASK(10, 4)
> > +
> > +struct mt7621_clk_priv {
> > +       struct regmap *sysc;
> > +       struct regmap *memc;
> > +};
> > +
> > +struct mt7621_clk {
> > +       struct clk_hw hw;
> > +       struct mt7621_clk_priv *priv;
> > +};
> > +
> > +struct mt7621_fixed_clk {
> > +       u8 idx;
> > +       const char *name;
> > +       const char *parent_name;
> > +       unsigned long rate;
> > +       struct clk_hw *hw;
> > +};
> > +
> > +struct mt7621_gate {
> > +       u8 idx;
> > +       const char *name;
> > +       const char *parent_name;
> > +       struct mt7621_clk_priv *priv;
> > +       u32 bit_idx;
> > +       struct clk_hw hw;
> > +};
> > +
> > +#define GATE(_id, _name, _pname, _shift)       \
> > +       {                                       \
> > +               .idx            = _id,          \
> > +               .name           = _name,        \
> > +               .parent_name    = _pname,       \
> > +               .bit_idx        = _shift        \
> > +       }
> > +
> > +static struct mt7621_gate mt7621_gates[] = {
> > +       GATE(MT7621_CLK_HSDMA, "hsdma", "150m", BIT(5)),
> > +       GATE(MT7621_CLK_FE, "fe", "250m", BIT(6)),
> > +       GATE(MT7621_CLK_SP_DIVTX, "sp_divtx", "270m", BIT(7)),
> > +       GATE(MT7621_CLK_TIMER, "timer", "50m", BIT(8)),
> > +       GATE(MT7621_CLK_PCM, "pcm", "270m", BIT(11)),
> > +       GATE(MT7621_CLK_PIO, "pio", "50m", BIT(13)),
> > +       GATE(MT7621_CLK_GDMA, "gdma", "bus", BIT(14)),
> > +       GATE(MT7621_CLK_NAND, "nand", "125m", BIT(15)),
> > +       GATE(MT7621_CLK_I2C, "i2c", "50m", BIT(16)),
> > +       GATE(MT7621_CLK_I2S, "i2s", "270m", BIT(17)),
> > +       GATE(MT7621_CLK_SPI, "spi", "bus", BIT(18)),
> > +       GATE(MT7621_CLK_UART1, "uart1", "50m", BIT(19)),
> > +       GATE(MT7621_CLK_UART2, "uart2", "50m", BIT(20)),
> > +       GATE(MT7621_CLK_UART3, "uart3", "50m", BIT(21)),
> > +       GATE(MT7621_CLK_ETH, "eth", "50m", BIT(23)),
> > +       GATE(MT7621_CLK_PCIE0, "pcie0", "125m", BIT(24)),
> > +       GATE(MT7621_CLK_PCIE1, "pcie1", "125m", BIT(25)),
> > +       GATE(MT7621_CLK_PCIE2, "pcie2", "125m", BIT(26)),
> > +       GATE(MT7621_CLK_CRYPTO, "crypto", "250m", BIT(29)),
> > +       GATE(MT7621_CLK_SHXC, "shxc", "50m", BIT(30))
> > +};
> > +
> > +static inline struct mt7621_gate *to_mt7621_gate(struct clk_hw *hw)
> > +{
> > +       return container_of(hw, struct mt7621_gate, hw);
> > +}
> > +
> > +static int mt7621_gate_enable(struct clk_hw *hw)
> > +{
> > +       struct mt7621_gate *clk_gate = to_mt7621_gate(hw);
> > +       struct regmap *sysc = clk_gate->priv->sysc;
> > +
> > +       return regmap_update_bits(sysc, SYSC_REG_CLKCFG1,
> > +                                 clk_gate->bit_idx, clk_gate->bit_idx);
> > +}
> > +
> > +static void mt7621_gate_disable(struct clk_hw *hw)
> > +{
> > +       struct mt7621_gate *clk_gate = to_mt7621_gate(hw);
> > +       struct regmap *sysc = clk_gate->priv->sysc;
> > +
> > +       regmap_update_bits(sysc, SYSC_REG_CLKCFG1, clk_gate->bit_idx, 0);
> > +}
> > +
> > +static int mt7621_gate_is_enabled(struct clk_hw *hw)
> > +{
> > +       struct mt7621_gate *clk_gate = to_mt7621_gate(hw);
> > +       struct regmap *sysc = clk_gate->priv->sysc;
> > +       u32 val;
> > +
> > +       if (regmap_read(sysc, SYSC_REG_CLKCFG1, &val))
> > +               return 0;
> > +
> > +       return val & BIT(clk_gate->bit_idx);
> > +}
> > +
> > +static const struct clk_ops mt7621_gate_ops = {
> > +       .enable = mt7621_gate_enable,
> > +       .disable = mt7621_gate_disable,
> > +       .is_enabled = mt7621_gate_is_enabled,
> > +};
> > +
> > +static int mt7621_gate_ops_init(struct device *dev,
> > +                               struct mt7621_gate *sclk)
> > +{
> > +       struct clk_init_data init = {
> > +               .flags = CLK_SET_RATE_PARENT,
> > +               .num_parents = 1,
> > +               .parent_names = &sclk->parent_name,
> > +               .ops = &mt7621_gate_ops,
> > +               .name = sclk->name,
> > +       };
> > +
> > +       sclk->hw.init = &init;
> > +       return devm_clk_hw_register(dev, &sclk->hw);
> > +}
> > +
> > +static int mt7621_register_gates(struct device *dev,
> > +                                struct clk_hw_onecell_data *clk_data,
> > +                                struct mt7621_clk_priv *priv)
> > +{
> > +       struct clk_hw **hws = clk_data->hws;
> > +       int ret, i;
> > +
> > +       for (i = 0; i < ARRAY_SIZE(mt7621_gates); i++) {
> > +               struct mt7621_gate *sclk = &mt7621_gates[i];
> > +
> > +               sclk->priv = priv;
> > +               ret = mt7621_gate_ops_init(dev, sclk);
> > +               if (ret) {
> > +                       dev_err(dev, "Couldn't register clock %s\n", sclk->name);
> > +                       goto err_clk_unreg;
> > +               }
> > +
> > +               hws[sclk->idx] = &sclk->hw;
> > +       }
> > +
> > +       return 0;
> > +
> > +err_clk_unreg:
> > +       while (--i >= 0) {
> > +               struct mt7621_gate *sclk = &mt7621_gates[i];
> > +
> > +               clk_hw_unregister(&sclk->hw);
> > +       }
> > +       return ret;
> > +}
> > +
> > +#define FIXED(_id, _name, _rate)               \
> > +       {                                       \
> > +               .idx            = _id,          \
> > +               .name           = _name,        \
> > +               .parent_name    = "xtal",       \
> > +               .rate           = _rate         \
> > +       }
> > +
> > +static struct mt7621_fixed_clk mt7621_fixed_clks[] = {
> > +       FIXED(MT7621_CLK_50M, "50m", 50000000),
> > +       FIXED(MT7621_CLK_125M, "125m", 125000000),
> > +       FIXED(MT7621_CLK_150M, "150m", 150000000),
> > +       FIXED(MT7621_CLK_250M, "250m", 250000000),
> > +       FIXED(MT7621_CLK_270M, "270m", 270000000),
> > +};
> > +
> > +static int mt7621_register_fixed_clocks(struct device *dev,
> > +                                       struct clk_hw_onecell_data *clk_data)
> > +{
> > +       struct clk_hw **hws = clk_data->hws;
> > +       int ret, i;
> > +
> > +       for (i = 0; i < ARRAY_SIZE(mt7621_fixed_clks); i++) {
> > +               struct mt7621_fixed_clk *sclk = &mt7621_fixed_clks[i];
> > +
> > +               sclk->hw = clk_hw_register_fixed_rate(dev, sclk->name,
> > +                                                     sclk->parent_name, 0,
> > +                                                     sclk->rate);
> > +               if (IS_ERR(sclk->hw)) {
> > +                       dev_err(dev, "Couldn't register clock %s\n", sclk->name);
> > +                       ret = PTR_ERR(sclk->hw);
> > +                       goto err_clk_unreg;
> > +               }
> > +
> > +               hws[sclk->idx] = sclk->hw;
> > +       }
> > +
> > +       return 0;
> > +
> > +err_clk_unreg:
> > +       while (--i >= 0) {
> > +               struct mt7621_fixed_clk *sclk = &mt7621_fixed_clks[i];
> > +
> > +               clk_hw_unregister_fixed_rate(sclk->hw);
> > +       }
> > +       return ret;
> > +}
> > +
> > +static inline struct mt7621_clk *to_mt7621_clk(struct clk_hw *hw)
> > +{
> > +       return container_of(hw, struct mt7621_clk, hw);
> > +}
> > +
> > +static unsigned long mt7621_xtal_recalc_rate(struct clk_hw *hw,
> > +                                            unsigned long parent_rate)
> > +{
> > +       struct mt7621_clk *clk = to_mt7621_clk(hw);
> > +       struct regmap *sysc = clk->priv->sysc;
> > +       u32 val;
> > +
> > +       regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG0, &val);
> > +       val = FIELD_GET(XTAL_MODE_SEL_MASK, val);
> > +
> > +       if (val <= 2)
> > +               return 20000000;
> > +       if (val <= 5)
> > +               return 40000000;
> > +
> > +       return 25000000;
> > +}
> > +
> > +static unsigned long mt7621_cpu_recalc_rate(struct clk_hw *hw,
> > +                                           unsigned long xtal_clk)
> > +{
> > +       static const u32 prediv_tbl[] = { 0, 1, 2, 2 };
> > +       struct mt7621_clk *clk = to_mt7621_clk(hw);
> > +       struct regmap *sysc = clk->priv->sysc;
> > +       struct regmap *memc = clk->priv->memc;
> > +       u32 clkcfg, clk_sel, curclk, ffiv, ffrac;
> > +       u32 pll, prediv, fbdiv;
> > +       unsigned long cpu_clk;
> > +
> > +       regmap_read(sysc, SYSC_REG_CLKCFG0, &clkcfg);
> > +       clk_sel = FIELD_GET(CPU_CLK_SEL_MASK, clkcfg);
> > +
> > +       regmap_read(sysc, SYSC_REG_CUR_CLK_STS, &curclk);
> > +       ffiv = FIELD_GET(CUR_CPU_FDIV_MASK, curclk);
> > +       ffrac = FIELD_GET(CUR_CPU_FFRAC_MASK, curclk);
> > +
> > +       switch (clk_sel) {
> > +       case 0:
> > +               cpu_clk = 500000000;
> > +               break;
> > +       case 1:
> > +               regmap_read(memc, MEMC_REG_CPU_PLL, &pll);
> > +               fbdiv = FIELD_GET(CPU_PLL_FBDIV_MASK, pll);
> > +               prediv = FIELD_GET(CPU_PLL_PREDIV_MASK, pll);
> > +               cpu_clk = ((fbdiv + 1) * xtal_clk) >> prediv_tbl[prediv];
> > +               break;
> > +       default:
> > +               cpu_clk = xtal_clk;
> > +       }
> > +
> > +       return cpu_clk / ffiv * ffrac;
> > +}
> > +
> > +static unsigned long mt7621_bus_recalc_rate(struct clk_hw *hw,
> > +                                           unsigned long parent_rate)
> > +{
> > +       return parent_rate / 4;
> > +}
> > +
> > +#define CLK_BASE(_name, _parent, _recalc) {                            \
> > +       .init = &(struct clk_init_data) {                               \
> > +               .name = _name,                                          \
> > +               .ops = &(const struct clk_ops) {                        \
> > +                       .recalc_rate = _recalc,                         \
> > +               },                                                      \
> > +               .parent_data = &(const struct clk_parent_data) {        \
> > +                       .name = _parent,                                \
> > +                       .fw_name = _parent                              \
> > +               },                                                      \
> > +               .num_parents = _parent ? 1 : 0                          \
> > +       },                                                              \
> > +}
> > +
> > +static struct mt7621_clk mt7621_clks_base[] = {
> > +       { CLK_BASE("xtal", NULL, mt7621_xtal_recalc_rate) },
> > +       { CLK_BASE("cpu", "xtal", mt7621_cpu_recalc_rate) },
> > +       { CLK_BASE("bus", "cpu", mt7621_bus_recalc_rate) },
> > +};
> > +
> > +static struct clk_hw *mt7621_clk_early[MT7621_CLK_MAX];
> > +
> > +static int mt7621_register_early_clocks(struct device_node *np,
> > +                                       struct clk_hw_onecell_data *clk_data,
> > +                                       struct mt7621_clk_priv *priv)
> > +{
> > +       struct clk_hw **hws = clk_data->hws;
> > +       int ret, i, j;
> > +
> > +       for (i = 0; i < ARRAY_SIZE(mt7621_clks_base); i++) {
> > +               struct mt7621_clk *sclk = &mt7621_clks_base[i];
> > +
> > +               sclk->priv = priv;
> > +               ret = of_clk_hw_register(np, &sclk->hw);
> > +               if (ret) {
> > +                       pr_err("Couldn't register top clock %i\n", i);
> > +                       goto err_clk_unreg;
> > +               }
> > +
> > +               hws[i] = &sclk->hw;
> > +               mt7621_clk_early[i] = &sclk->hw;
> > +       }
> > +
> > +       for (j = i; j < MT7621_CLK_MAX; j++)
> > +               mt7621_clk_early[j] = ERR_PTR(-EPROBE_DEFER);
> > +
> > +       return 0;
> > +
> > +err_clk_unreg:
> > +       while (--i >= 0) {
> > +               struct mt7621_clk *sclk = &mt7621_clks_base[i];
>
> Please move sclk to the toplevel of this function instead of having it
> twice.

Ok, no problem at all. I'll move this to void to declare twice in
success and error paths.

>
> > +
> > +               clk_hw_unregister(&sclk->hw);
> > +       }
> > +       return ret;
> > +}
> > +
> > +static int mt7621_prepare_enable_clocks(struct clk_hw_onecell_data *clk_data)
> > +{
> > +       int ret, i;
> > +
> > +       for (i = 0; i < MT7621_CLK_MAX; i++) {
> > +               ret = clk_prepare_enable(clk_data->hws[i]->clk);
>
> Are these critical clks? Why not use the CLK_IS_CRITICAL flag?

Well, Not calling clk_prepare_enable here makes the kernel to disable
all of the stuff is not being requested. Since until now no clock
driver existed, some SoC drivers  were not prepared for the clock. So,
if you prefer to avoid disabling stuff using this flag I think I can
just remove this enable_clocks function and set the flags for all the
clocks when registering them.

> > +               if (ret) {
> > +                       pr_err("failed to enable clk: %d\n", ret);
> > +                       goto err_clk_disable;
> > +               }
> > +       }
> > +
> > +       return 0;
> > +
> > +err_clk_disable:
> > +       while (--i >= 0)
> > +               clk_disable_unprepare(clk_data->hws[i]->clk);
> > +       return ret;
> > +}
> > +
> > +static void __init mt7621_clk_init(struct device_node *node)
> > +{
> > +       struct mt7621_clk_priv *priv;
> > +       struct clk_hw_onecell_data *clk_data;
> > +       int ret, i, count;
> > +
> > +       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
> > +       if (!priv)
> > +               return;
> > +
> > +       priv->sysc = syscon_node_to_regmap(node);
> > +       if (IS_ERR(priv->sysc)) {
> > +               pr_err("Could not get sysc syscon regmap\n");
> > +               goto free_clk_priv;
> > +       }
> > +
> > +       priv->memc = syscon_regmap_lookup_by_phandle(node, "ralink,memctl");
> > +       if (IS_ERR(priv->memc)) {
> > +               pr_err("Could not get memc syscon regmap\n");
> > +               goto free_clk_priv;
> > +       }
> > +
> > +       count = ARRAY_SIZE(mt7621_clks_base) +
> > +               ARRAY_SIZE(mt7621_fixed_clks) + ARRAY_SIZE(mt7621_gates);
> > +       clk_data = kzalloc(struct_size(clk_data, hws, count), GFP_KERNEL);
> > +       if (!clk_data)
> > +               goto free_clk_priv;
> > +
> > +       ret = mt7621_register_early_clocks(node, clk_data, priv);
> > +       if (ret) {
> > +               pr_err("Couldn't register top clocks\n");
> > +               goto free_clk_data;
> > +       }
> > +
> > +       clk_data->num = count;
> > +
> > +       ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
> > +       if (ret) {
> > +               pr_err("Couldn't add clk hw provider\n");
> > +               goto unreg_clk_top;
> > +       }
> > +
> > +       return;
> > +
> > +unreg_clk_top:
> > +       for (i = 0; i < ARRAY_SIZE(mt7621_clks_base); i++) {
> > +               struct mt7621_clk *sclk = &mt7621_clks_base[i];
> > +
> > +               clk_hw_unregister(&sclk->hw);
> > +       }
> > +
> > +free_clk_data:
> > +       kfree(clk_data);
> > +
> > +free_clk_priv:
> > +       kfree(priv);
> > +}
> > +CLK_OF_DECLARE_DRIVER(mt7621_clk, "mediatek,mt7621-sysc", mt7621_clk_init);
> > +
> > +static int mt7621_clk_probe(struct platform_device *pdev)
> > +{
> > +       struct device_node *np = pdev->dev.of_node;
> > +       struct clk_hw_onecell_data *clk_data;
> > +       struct device *dev = &pdev->dev;
> > +       struct mt7621_clk_priv *priv;
> > +       int ret, i, count;
> > +
> > +       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
>
> Can we use devm_* APIs here?

Ok, I will.

>
> > +       if (!priv)
> > +               return -ENOMEM;
> > +
> > +       priv->sysc = syscon_node_to_regmap(np);
> > +       if (IS_ERR(priv->sysc)) {
> > +               ret = PTR_ERR(priv->sysc);
> > +               dev_err(dev, "Could not get sysc syscon regmap\n");
> > +               goto free_clk_priv;
> > +       }
> > +
> > +       priv->memc = syscon_regmap_lookup_by_phandle(np, "ralink,memctl");
> > +       if (IS_ERR(priv->memc)) {
> > +               ret = PTR_ERR(priv->memc);
> > +               dev_err(dev, "Could not get memc syscon regmap\n");
> > +               goto free_clk_priv;
> > +       }
> > +
> > +       count = ARRAY_SIZE(mt7621_clks_base) +
> > +               ARRAY_SIZE(mt7621_fixed_clks) + ARRAY_SIZE(mt7621_gates);
> > +       clk_data = kzalloc(struct_size(clk_data, hws, count), GFP_KERNEL);
> > +       if (!clk_data) {
> > +               ret = -ENOMEM;
> > +               goto free_clk_priv;
> > +       }
> > +
> > +       for (i = 0; i < ARRAY_SIZE(mt7621_clks_base); i++)
> > +               clk_data->hws[i] = mt7621_clk_early[i];
> > +
> > +       ret = mt7621_register_fixed_clocks(dev, clk_data);
> > +       if (ret) {
> > +               dev_err(dev, "Couldn't register fixed clocks\n");
> > +               goto free_clk_data;
> > +       }
> > +
> > +       ret = mt7621_register_gates(dev, clk_data, priv);
> > +       if (ret) {
> > +               dev_err(dev, "Couldn't register fixed clock gates\n");
> > +               goto unreg_clk_fixed;
> > +       }
> > +
> > +       clk_data->num = count;
> > +
> > +       ret = mt7621_prepare_enable_clocks(clk_data);
> > +       if (ret) {
> > +               dev_err(dev, "Couldn't register fixed clock gates\n");
>
> This isn't registering fixed clock gates though?

Copy paste is a bad thing ;). Will fix this.

>
> > +               goto unreg_clk_gates;
> > +       }
> > +
> > +       ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
> > +       if (ret) {
> > +               dev_err(dev, "Couldn't add clk hw provider\n");
> > +               goto disable_clks;
> > +       }
> > +
> > +       return 0;
> > +
> > +disable_clks:
> > +       for (i = 0; i < MT7621_CLK_MAX; i++)
> > +               clk_disable_unprepare(clk_data->hws[i]->clk);
> > +
> > +unreg_clk_gates:
> > +       for (i = 0; i < ARRAY_SIZE(mt7621_gates); i++) {
> > +               struct mt7621_gate *sclk = &mt7621_gates[i];
> > +
> > +               clk_hw_unregister(&sclk->hw);
> > +       }
> > +
> > +unreg_clk_fixed:
> > +       for (i = 0; i < ARRAY_SIZE(mt7621_fixed_clks); i++) {
> > +               struct mt7621_fixed_clk *sclk = &mt7621_fixed_clks[i];
> > +
> > +               clk_hw_unregister_fixed_rate(sclk->hw);
> > +       }
> > +
> > +free_clk_data:
> > +       kfree(clk_data);
> > +
> > +free_clk_priv:
> > +       kfree(priv);
> > +
> > +       return ret;
> > +}
> > +
> > +static const struct of_device_id mt7621_clk_of_match[] = {
> > +       { .compatible = "mediatek,mt7621-sysc" },
> > +       {},
>
> Nitpick: Drop the comma on the sentinel so it's a compile error if
> another element is added after.

True, will drop in next version.

>
> > +};
> > +
> > +static struct platform_driver mt7621_clk_driver = {
> > +       .probe = mt7621_clk_probe,
> > +       .driver = {
> > +               .name = "mt7621-clk",
> > +               .of_match_table = mt7621_clk_of_match,
> > +       },
> > +};
> > +builtin_platform_driver(mt7621_clk_driver);

Thanks for the review. I will resend this fixed during this weekend.

Best regards,
    Sergio Paracuellos

^ permalink raw reply

* Re: [PATCH v11 0/6] MIPS: ralink: add CPU clock detection and clock driver for MT7621
From: Stephen Boyd @ 2021-04-09 18:31 UTC (permalink / raw)
  To: Sergio Paracuellos
  Cc: Rob Herring, John Crispin, Thomas Bogendoerfer, Greg KH,
	COMMON CLK FRAMEWORK,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS  <devicetree@vger.kernel.org>, open list:MIPS  <linux-mips@vger.kernel.org>, open list:STAGING SUBSYSTEM  <devel@driverdev.osuosl.org>, NeilBrown <neil@brown.name>, linux-kernel
In-Reply-To: <CAMhs-H98xzfK4W9KGSKR0QPtm42_K6Y5PzWiA3c-Pugau7oxyQ@mail.gmail.com>

Quoting Sergio Paracuellos (2021-04-09 11:25:24)
> Hi Stephen,
> 
> On Fri, Apr 9, 2021 at 8:17 PM Stephen Boyd <sboyd@kernel.org> wrote:
> >
> > Quoting Sergio Paracuellos (2021-03-23 01:13:22)
> > > On Tue, Mar 9, 2021 at 6:22 AM Sergio Paracuellos
> > > <sergio.paracuellos@gmail.com> wrote:
> > > >
> > > > Changes in v11:
> > > >  - Collect Rob's Reviewed-by in bindings documentation patch.
> > > >  - Fix MAINTAINERS patch using file 'mediatek,mt7621-sysc.yaml'
> > > >    for documentation bindings.
> > >
> > > Something still missing or something that is needed to be fixed to get
> > > this series applied through your tree?
> > >
> > > Thanks in advance for your time.
> > >
> >
> > Sorry I missed this series. I thought it was going through another tree.
> > It can merge through clk tree. Just a few nits on the clk driver patch
> > but otherwise I've merged the first two patches. If you resend in the
> > next few days it would be great. Thanks.
> 
> I will hopefully do during this weekend. Since you already merge the
> first two patches, the remaining four should be sent as v12, right?

Yes. I'll push it out to kernel.org shortly.

^ permalink raw reply

* Re: [PATCH][V2] clk: uniphier: Fix potential infinite loop
From: Masahiro Yamada @ 2021-04-09 18:28 UTC (permalink / raw)
  To: Colin King
  Cc: Michael Turquette, Stephen Boyd, linux-clk, linux-arm-kernel,
	kernel-janitors, Linux Kernel Mailing List
In-Reply-To: <20210409090104.629722-2-colin.king@canonical.com>

On Fri, Apr 9, 2021 at 6:01 PM Colin King <colin.king@canonical.com> wrote:
>
> From: Colin Ian King <colin.king@canonical.com>
>
> The for-loop iterates with a u8 loop counter i and compares this
> with the loop upper limit of num_parents that is an int type.
> There is a potential infinite loop if num_parents is larger than
> the u8 loop counter. Fix this by making the loop counter the same
> type as num_parents.  Also make num_parents an unsigned int to
> match the return type of the call to clk_hw_get_num_parents.
>
> Addresses-Coverity: ("Infinite loop")
> Fixes: 734d82f4a678 ("clk: uniphier: add core support code for UniPhier clock driver")
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> ---
>
> V2: Make num_parents an unsigned int to match return type of
>     clk_hw_get_num_parents().

Reviewed-by: Masahiro Yamada <masahiroy@kernel.org>




> ---
>  drivers/clk/uniphier/clk-uniphier-mux.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/clk/uniphier/clk-uniphier-mux.c b/drivers/clk/uniphier/clk-uniphier-mux.c
> index 462c84321b2d..1998e9d4cfc0 100644
> --- a/drivers/clk/uniphier/clk-uniphier-mux.c
> +++ b/drivers/clk/uniphier/clk-uniphier-mux.c
> @@ -31,10 +31,10 @@ static int uniphier_clk_mux_set_parent(struct clk_hw *hw, u8 index)
>  static u8 uniphier_clk_mux_get_parent(struct clk_hw *hw)
>  {
>         struct uniphier_clk_mux *mux = to_uniphier_clk_mux(hw);
> -       int num_parents = clk_hw_get_num_parents(hw);
> +       unsigned int num_parents = clk_hw_get_num_parents(hw);
>         int ret;
>         unsigned int val;
> -       u8 i;
> +       unsigned int i;
>
>         ret = regmap_read(mux->regmap, mux->reg, &val);
>         if (ret)
> --
> 2.30.2
>


-- 
Best Regards
Masahiro Yamada

^ permalink raw reply

* Re: [PATCH v2 -next 3/3] clk: qcom: apss-ipq-pll: Add missing MODULE_DEVICE_TABLE
From: Stephen Boyd @ 2021-04-09 18:28 UTC (permalink / raw)
  To: Chen Hui, agross, bjorn.andersson, georgi.djakov, mani,
	mturquette, sivaprak
  Cc: linux-arm-msm, linux-clk, linux-kernel
In-Reply-To: <20210409082352.233810-4-clare.chenhui@huawei.com>

Quoting Chen Hui (2021-04-09 01:23:52)
> CONFIG_IPQ_APSS_PLL is tristate option and therefore this driver can
> be compiled as a module. This patch adds missing MODULE_DEVICE_TABLE
> definition which generates correct modalias for automatic loading of
> this driver when it is built as an external module.
> 
> Fixes: ecd2bacfbbc4 ("clk: qcom: Add ipq apss pll driver")
> Signed-off-by: Chen Hui <clare.chenhui@huawei.com>
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> ---

Applied to clk-next

^ permalink raw reply

* Re: [PATCH v2 -next 2/3] clk: qcom: a53-pll: Add missing MODULE_DEVICE_TABLE
From: Stephen Boyd @ 2021-04-09 18:28 UTC (permalink / raw)
  To: Chen Hui, agross, bjorn.andersson, georgi.djakov, mani,
	mturquette, sivaprak
  Cc: linux-arm-msm, linux-clk, linux-kernel
In-Reply-To: <20210409082352.233810-3-clare.chenhui@huawei.com>

Quoting Chen Hui (2021-04-09 01:23:51)
> CONFIG_QCOM_A53PLL is tristate option and therefore this driver can be
> compiled as a module. This patch adds missing MODULE_DEVICE_TABLE
> definition which generates correct modalias for automatic loading of
> this driver when it is built as an external module.
> 
> Fixes: 0c6ab1b8f894 ("clk: qcom: Add A53 PLL support")
> Signed-off-by: Chen Hui <clare.chenhui@huawei.com>
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> ---

Applied to clk-next

^ permalink raw reply

* Re: [PATCH v2 -next 1/3] clk: qcom: a7-pll: Add missing MODULE_DEVICE_TABLE
From: Stephen Boyd @ 2021-04-09 18:28 UTC (permalink / raw)
  To: Chen Hui, agross, bjorn.andersson, georgi.djakov, mani,
	mturquette, sivaprak
  Cc: linux-arm-msm, linux-clk, linux-kernel
In-Reply-To: <20210409082352.233810-2-clare.chenhui@huawei.com>

Quoting Chen Hui (2021-04-09 01:23:50)
> CONFIG_QCOM_A7PLL is tristate option and therefore this driver can be
> compiled as a module. This patch adds missing MODULE_DEVICE_TABLE
> definition which generates correct modalias for automatic loading of
> this driver when it is built as an external module.
> 
> Fixes: 5a5223ffd7ef ("clk: qcom: Add A7 PLL support")
> Signed-off-by: Chen Hui <clare.chenhui@huawei.com>
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> ---

Applied to clk-next

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox