Basic support to ZTE ZX296702
Subsystems (6)
v4 cover Basic support to ZTE ZX296702
Rebase patches of v2 to 4.0-rc1. Ready for merge.
Change in v4 vs v3: Fix minor defconfig issue.
Jun Nie (7):
ARM: zx: add basic support for ZTE ZX296702
MAINTAINERS: add entry for ARM ZTE architecture
ARM: zx: add low level debug support for zx296702
ARM: dts: zx: add an initial zx296702 dts and doc
clk: zx: add clock support to zx296702
ARM: zx: enable SMP and hotplug for zx296702
ARM: zx: Add basic defconfig support for ZX296702
Documentation/devicetree/bindings/arm/zte.txt | 15 + .../devicetree/bindings/clock/zx296702-clk.txt | 35 ++ Documentation/devicetree/bindings/serial/pl011.txt | 2 +- .../devicetree/bindings/vendor-prefixes.txt | 1 + MAINTAINERS | 9 + arch/arm/Kconfig | 2 + arch/arm/Kconfig.debug | 14 + arch/arm/Makefile | 1 + arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/zx296702-ad1.dts | 48 ++ arch/arm/boot/dts/zx296702.dtsi | 139 +++++ arch/arm/configs/zx_defconfig | 130 ++++ arch/arm/include/debug/pl01x.S | 7 + arch/arm/mach-zx/Kconfig | 18 + arch/arm/mach-zx/Makefile | 2 + arch/arm/mach-zx/core.h | 19 + arch/arm/mach-zx/headsmp.S | 32 + arch/arm/mach-zx/platsmp.c | 189 ++++++ arch/arm/mach-zx/zx296702.c | 31 + drivers/clk/Makefile | 1 + drivers/clk/zte/Makefile | 2 + drivers/clk/zte/clk-pll.c | 180 ++++++ drivers/clk/zte/clk-zx296702.c | 658 +++++++++++++++++++++ drivers/clk/zte/clk.h | 30 + include/dt-bindings/clock/zx296702-clock.h | 162 +++++ 25 files changed, 1727 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/arm/zte.txt create mode 100644 Documentation/devicetree/bindings/clock/zx296702-clk.txt create mode 100644 arch/arm/boot/dts/zx296702-ad1.dts create mode 100644 arch/arm/boot/dts/zx296702.dtsi create mode 100644 arch/arm/configs/zx_defconfig create mode 100644 arch/arm/mach-zx/Kconfig create mode 100644 arch/arm/mach-zx/Makefile create mode 100644 arch/arm/mach-zx/core.h create mode 100644 arch/arm/mach-zx/headsmp.S create mode 100644 arch/arm/mach-zx/platsmp.c create mode 100644 arch/arm/mach-zx/zx296702.c create mode 100644 drivers/clk/zte/Makefile create mode 100644 drivers/clk/zte/clk-pll.c create mode 100644 drivers/clk/zte/clk-zx296702.c create mode 100644 drivers/clk/zte/clk.h create mode 100644 include/dt-bindings/clock/zx296702-clock.h
Signature · 1 line
1.9.1
PATCH v4 1/7 ARM: zx: add basic support for ZTE ZX296702
Add basic code for ZTE ZX296702 platform.
--- arch/arm/Kconfig | 2 ++ arch/arm/Makefile | 1 + arch/arm/mach-zx/Kconfig | 18 ++++++++++++++++++ arch/arm/mach-zx/Makefile | 1 + arch/arm/mach-zx/zx296702.c | 31 +++++++++++++++++++++++++++++++ 5 files changed, 53 insertions(+) create mode 100644 arch/arm/mach-zx/Kconfig create mode 100644 arch/arm/mach-zx/Makefile create mode 100644 arch/arm/mach-zx/zx296702.c
arch/arm/Kconfig +2 -0
@@ -948,6 +948,8 @@ source "arch/arm/mach-vt8500/Kconfig" source "arch/arm/mach-w90x900/Kconfig" +source "arch/arm/mach-zx/Kconfig" + source "arch/arm/mach-zynq/Kconfig" # Definitions to make life easier
arch/arm/Makefile +1 -0
@@ -204,6 +204,7 @@ machine-$(CONFIG_ARCH_VERSATILE) += versatile machine-$(CONFIG_ARCH_VEXPRESS) += vexpress machine-$(CONFIG_ARCH_VT8500) += vt8500 machine-$(CONFIG_ARCH_W90X900) += w90x900 +machine-$(CONFIG_ARCH_ZX) += zx machine-$(CONFIG_ARCH_ZYNQ) += zynq machine-$(CONFIG_PLAT_SPEAR) += spear
arch/arm/mach-zx/Kconfig new file +18 -0
@@ -0,0 +1,18 @@ +menuconfig ARCH_ZX + bool "ZTE ZX family" if ARCH_MULTI_V7 + help + Support for ZTE ZX-based family of processors. TV + set-top-box processor is supported. More will be + added soon. + +if ARCH_ZX + +config SOC_ZX296702 + bool "Enable support for ZX296702 SoC" + select ARM_GIC + select ARM_GLOBAL_TIMER + select HAVE_ARM_SCU if SMP + select HAVE_ARM_TWD if SMP + help + Support for ZTE ZX296702 SoC which is a dual core CortexA9MP +endif
arch/arm/mach-zx/Makefile new file +1 -0
@@ -0,0 +1 @@ +obj-$(CONFIG_SOC_ZX296702) += zx296702.o
arch/arm/mach-zx/zx296702.c new file +31 -0
@@ -0,0 +1,31 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <linux/of_address.h> +#include <linux/of_platform.h> + +static const char *zx296702_dt_compat[]__initconst = { +"zte,zx296702" , +NULL , +}; + +static void __init zx296702_init_machine (void ) +{ +of_platform_populate (NULL , of_default_bus_match_table,NULL ,NULL ); +} + +DT_MACHINE_START (ZX ,"ZTE ZX296702 (Device Tree)" ) + .init_machine = zx296702_init_machine, + .dt_compat = zx296702_dt_compat, + .l2c_aux_val = 0x30400000, + .l2c_aux_mask =0xfeffffff , +MACHINE_END
Signature · 1 line
1.9.1
Arnd Bergmann
maintainerPATCH v4 1/7 ARM: zx: add basic support for ZTE ZX296702
Quoted 3 lines · On Tuesday 28 April 2015 17:18:05 Jun Nie wrote:
Add basic code for ZTE ZX296702 platform.
Signed-off-by Jun Nie <[email protected]>
Hi Jun,
I've applied patches 1, 2, 3 and 6 to the next/soc branch now, but ended up modifying the first patch slightly, see the new version version below. Let's find a way to get the cache controller settings right without the override please.
Arnd
commit acede515b3a5997becc5736657e11f4f410a8235
Author: Jun Nie <[email protected]> Date: Tue Apr 28 17:18:05 2015 +0800
ARM: zx: add basic support for ZTE ZX296702
Add basic code for ZTE ZX296702 platform.
[arnd: removed unused zx296702_init_machine function, and changed
l2c aux val to default]
arch/arm/Kconfig +2 -0
@@ -989,6 +989,8 @@ source "arch/arm/mach-vt8500/Kconfig" source "arch/arm/mach-w90x900/Kconfig" +source "arch/arm/mach-zx/Kconfig" + source "arch/arm/mach-zynq/Kconfig" # Definitions to make life easier
arch/arm/Makefile +1 -0
@@ -207,6 +207,7 @@ machine-$(CONFIG_ARCH_VERSATILE) += versatile machine-$(CONFIG_ARCH_VEXPRESS) += vexpress machine-$(CONFIG_ARCH_VT8500) += vt8500 machine-$(CONFIG_ARCH_W90X900) += w90x900 +machine-$(CONFIG_ARCH_ZX) += zx machine-$(CONFIG_ARCH_ZYNQ) += zynq machine-$(CONFIG_PLAT_SPEAR) += spear
arch/arm/mach-zx/Kconfig new file +18 -0
@@ -0,0 +1,18 @@ +menuconfig ARCH_ZX + bool "ZTE ZX family" if ARCH_MULTI_V7 + help + Support for ZTE ZX-based family of processors. TV + set-top-box processor is supported. More will be + added soon. + +if ARCH_ZX + +config SOC_ZX296702 + def_bool y + select ARM_GIC + select ARM_GLOBAL_TIMER + select HAVE_ARM_SCU if SMP + select HAVE_ARM_TWD if SMP + help + Support for ZTE ZX296702 SoC which is a dual core CortexA9MP +endif
arch/arm/mach-zx/Makefile new file +1 -0
@@ -0,0 +1 @@ +obj-$(CONFIG_SOC_ZX296702) += zx296702.o
arch/arm/mach-zx/zx296702.c new file +25 -0
@@ -0,0 +1,25 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <linux/of_address.h> +#include <linux/of_platform.h> + +static const char *zx296702_dt_compat[]__initconst = { +"zte,zx296702" , +NULL , +}; + +DT_MACHINE_START (ZX ,"ZTE ZX296702 (Device Tree)" ) + .dt_compat = zx296702_dt_compat, + .l2c_aux_val = 0, + .l2c_aux_mask = ~0 , +MACHINE_END
PATCH v4 1/7 ARM: zx: add basic support for ZTE ZX296702
B.R.
Jun
2015-05-16 3:57 GMT+08:00 Arnd Bergmann <[email protected]>:
Quoted 5 lines · On Tuesday 28 April 2015 17:18:05 Jun Nie wrote:
Quoted 3 lines
Add basic code for ZTE ZX296702 platform.
Signed-off-by Jun Nie <[email protected]>
Quoted 9 lines
Hi Jun,
I've applied patches 1, 2, 3 and 6 to the next/soc branch now, but ended up modifying the first patch slightly, see the new version version below. Let's find a way to get the cache controller settings right without the override please.
Arnd
Thanks for help modifying. I test below patch and the cache change works well.
Jun
Quoted 102 lines
commit
acede515b3a5997becc5736657e11f4f410a8235Author: Jun Nie <[email protected]> Date: Tue Apr 28 17:18:05 2015 +0800ARM: zx: add basic support for ZTE ZX296702
Add basic code for ZTE ZX296702 platform.
[arnd: removed unused
zx296702_init_machinefunction, and changed
l2c aux val to default]Signed-off-by Jun Nie <[email protected]>Signed-off-by Arnd Bergmann <[email protected]>arch/arm/Kconfig +2
-0@@ -989,6 +989,8 @@ source "arch/arm/mach-vt8500/Kconfig" source "arch/arm/mach-w90x900/Kconfig" +source "arch/arm/mach-zx/Kconfig" + source "arch/arm/mach-zynq/Kconfig" # Definitions to make life easierarch/arm/Makefile +1
-0@@ -207,6 +207,7 @@ machine-$(CONFIG_ARCH_VERSATILE) += versatile machine-$(CONFIG_ARCH_VEXPRESS) += vexpress machine-$(CONFIG_ARCH_VT8500) += vt8500 machine-$(CONFIG_ARCH_W90X900) += w90x900 +machine-$(CONFIG_ARCH_ZX) += zx machine-$(CONFIG_ARCH_ZYNQ) += zynq machine-$(CONFIG_PLAT_SPEAR) += speararch/arm/mach-zx/Kconfig new file +18
-0@@ -0,0 +1,18 @@ +menuconfig ARCH_ZX + bool "ZTE ZX family" if ARCH_MULTI_V7 + help + Support for ZTE ZX-based family of processors. TV + set-top-box processor is supported. More will be + added soon. + +if ARCH_ZX + +config SOC_ZX296702 + def_bool y + select ARM_GIC + select ARM_GLOBAL_TIMER + select HAVE_ARM_SCU if SMP + select HAVE_ARM_TWD if SMP + help + Support for ZTE ZX296702 SoC which is a dual core CortexA9MP +endifarch/arm/mach-zx/Makefile new file +1
-0@@ -0,0 +1 @@ +obj-$(CONFIG_SOC_ZX296702) += zx296702.oarch/arm/mach-zx/zx296702.c new file +25
-0@@ -0,0 +1,25 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <linux/of_address.h> +#include <linux/of_platform.h> + +static const char *zx296702_dt_compat[]__initconst = { +"zte,zx296702" , +NULL , +}; + +DT_MACHINE_START (ZX ,"ZTE ZX296702 (Device Tree)" ) + .dt_compat = zx296702_dt_compat, + .l2c_aux_val = 0, + .l2c_aux_mask = ~0 , +MACHINE_END
PATCH v4 2/7 MAINTAINERS: add entry for ARM ZTE architecture
In reply to Jun NieAdd entry for ZTE ARM architecture
--- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+)
MAINTAINERS +9 -0
@@ -1602,6 +1602,15 @@ S: Maintained F: arch/arm/mach-pxa/z2.c F: arch/arm/mach-pxa/include/mach/z2.h +ARM/ZTE ARCHITECTURE +M: Jun Nie <[email protected]> +L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm/mach-zx/ +F: drivers/clk/zte/ +F: Documentation/devicetree/bindings/arm/zte.txt +F: Documentation/devicetree/bindings/clock/zx296702-clk.txt + ARM/ZYNQ ARCHITECTURE M: Michal Simek <[email protected]> R: S?ren Brinkmann <[email protected]>
Signature · 1 line
1.9.1
PATCH v4 3/7 ARM: zx: add low level debug support for zx296702
In reply to Jun NieUse the UART0 peripheral for low level debug. Only the UART port 0 is currently supported.
--- arch/arm/Kconfig.debug | 14 ++++++++++++++ arch/arm/include/debug/pl01x.S | 7 +++++++ 2 files changed, 21 insertions(+)
arch/arm/Kconfig.debug +14 -0
@@ -1157,6 +1157,18 @@ choice For more details about semihosting, please see chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd. + config DEBUG_ZTE_ZX + bool "Use ZTE ZX UART" + select DEBUG_UART_PL01X + depends on ARCH_ZX + help + Say Y here if you are enabling ZTE ZX296702 SOC and need + debug uart support. + + This option is preferred over the platform specific + options; the platform specific options are deprecated + and will be soon removed. + config DEBUG_LL_UART_8250 bool "Kernel low-level debugging via 8250 UART" help
@@ -1337,6 +1349,7 @@ config DEBUG_UART_PHYS default 0x02531000 if DEBUG_KEYSTONE_UART1 default 0x03010fe0 if ARCH_RPC default 0x07000000 if DEBUG_SUN9I_UART0 + default 0x09405000 if DEBUG_ZTE_ZX default 0x10009000 if DEBUG_REALVIEW_STD_PORT || \ DEBUG_VEXPRESS_UART0_CA9 default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT
@@ -1466,6 +1479,7 @@ config DEBUG_UART_VIRT default 0xfb009000 if DEBUG_REALVIEW_STD_PORT default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT default 0xfc40ab00 if DEBUG_BRCMSTB_UART + default 0xfc705000 if DEBUG_ZTE_ZX default 0xfcfe8600 if DEBUG_UART_BCM63XX default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX default 0xfd000000 if ARCH_SPEAR13XX
arch/arm/include/debug/pl01x.S +7 -0
@@ -12,6 +12,13 @@ */ #include <linux/amba/serial.h> +#ifdef CONFIG_DEBUG_ZTE_ZX +#undef UART01x_DR +#undef UART01x_FR +#define UART01x_DR 0x04 +#define UART01x_FR 0x14 +#endif + #ifdef CONFIG_DEBUG_UART_PHYS .macro addruart, rp, rv, tmp ldr \rp, =CONFIG_DEBUG_UART_PHYS
Signature · 1 line
1.9.1
PATCH v4 4/7 ARM: dts: zx: add an initial zx296702 dts and doc
In reply to Jun NieAdd initial dts file and document for ZX296702 and board ZX296702-AD1. More peripherals will be added later.
--- Documentation/devicetree/bindings/arm/zte.txt | 15 +++ .../devicetree/bindings/clock/zx296702-clk.txt | 35 ++++++ Documentation/devicetree/bindings/serial/pl011.txt | 2 +- .../devicetree/bindings/vendor-prefixes.txt | 1 + arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/zx296702-ad1.dts | 48 +++++++ arch/arm/boot/dts/zx296702.dtsi | 139 +++++++++++++++++++++ 7 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/arm/zte.txt create mode 100644 Documentation/devicetree/bindings/clock/zx296702-clk.txt create mode 100644 arch/arm/boot/dts/zx296702-ad1.dts create mode 100644 arch/arm/boot/dts/zx296702.dtsi
Documentation/devicetree/bindings/arm/zte.txt new file +15 -0
@@ -0,0 +1,15 @@ +ZTE platforms device tree bindings +--------------------------------------- + +- ZX296702 board: + Required root node properties: + - compatible = "zte,zx296702-ad1", "zte,zx296702" + +System management required properties: + - compatible = "zte,sysctrl" + +Low power management required properties: + - compatible = "zte,zx296702-pcu" + +Bus matrix required properties: + - compatible = "zte,zx-bus-matrix"
Documentation/devicetree/bindings/clock/zx296702-clk.txt new file +35 -0
@@ -0,0 +1,35 @@ +Device Tree Clock bindings for ZTE zx296702 + +This binding uses the common clock binding[1]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be one of the following: + "zte,zx296702-topcrm-clk": + zx296702 top clock selection, divider and gating + + "zte,zx296702-lsp0crpm-clk" and + "zte,zx296702-lsp1crpm-clk": + zx296702 device level clock selection and gating + +- reg: Address and length of the register set + +The clock consumer should specify the desired clock by having the clock +ID in its "clocks" phandle cell. See include/dt-bindings/clock/zx296702-clock.h +for the full list of zx296702 clock IDs. + + +topclk: topcrm at 0x09800000 { + compatible = "zte,zx296702-topcrm-clk"; + reg = <0x09800000 0x1000>; + #clock-cells = <1>; +}; + +uart0: serial at 0x09405000 { + compatible = "zte,zx296702-uart"; + reg = <0x09405000 0x1000>; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&lsp1clk ZX296702_UART0_PCLK>; + status = "disabled"; +};
Documentation/devicetree/bindings/serial/pl011.txt +1 -1
@@ -1,7 +1,7 @@ * ARM AMBA Primecell PL011 serial UART Required properties: -- compatible: must be "arm,primecell", "arm,pl011" +- compatible: must be "arm,primecell", "arm,pl011", "zte,zx296702-uart" - reg: exactly one register range with length 0x1000 - interrupts: exactly one interrupt specifier
Documentation/devicetree/bindings/vendor-prefixes.txt +1 -0
@@ -211,3 +211,4 @@ xillybus Xillybus Ltd. xlnx Xilinx zyxel ZyXEL Communications Corp. zarlink Zarlink Semiconductor +zte ZTE Corp.
arch/arm/boot/dts/Makefile +1 -0
@@ -660,6 +660,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt6592-evb.dtb \ mt8127-moose.dtb \ mt8135-evbp1.dtb +dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb endif always := $(dtb-y)
arch/arm/boot/dts/zx296702-ad1.dts new file +48 -0
48 lines not on this page · raw message
arch/arm/boot/dts/zx296702.dtsi new file +139 -0
139 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v4 4/7 ARM: dts: zx: add an initial zx296702 dts and doc
Quoted 4 lines · On Tuesday 28 April 2015 17:18:08 Jun Nie wrote:
Add initial dts file and document for ZX296702 and board ZX296702-AD1. More peripherals will be added later.
Signed-off-by Jun Nie <[email protected]>
Applied to next/dt, thanks!
Arnd
Arnd Bergmann
maintainerPATCH v4 4/7 ARM: dts: zx: add an initial zx296702 dts and doc
Quoted 9 lines · On Friday 15 May 2015 21:59:06 Arnd Bergmann wrote:
Quoted 4 lines · On Tuesday 28 April 2015 17:18:08 Jun Nie wrote:
Add initial dts file and document for ZX296702 and board ZX296702-AD1. More peripherals will be added later.
Signed-off-by Jun Nie <[email protected]>Applied to next/dt, thanks!
And removed again. I hadn't pushed it out to a public tree yet and found a build error in this.
Unfortunately, you are using a header file here that is only introduced by a patch that belongs to another subsystem maintainer.
Please try to get rid of that dependency, or submit this patch again for the following merge window once that driver has been merged upstream.
In a lot of cases, you can just use hardware numbers as identifiers instead of making up your own, to avoid having to use ugly header files that make life hard for us.
Arnd
PATCH v4 4/7 ARM: dts: zx: add an initial zx296702 dts and doc
B.R.
Jun
2015-05-16 4:19 GMT+08:00 Arnd Bergmann <[email protected]>:
Quoted 17 lines · On Friday 15 May 2015 21:59:06 Arnd Bergmann wrote:
Quoted 9 lines · On Tuesday 28 April 2015 17:18:08 Jun Nie wrote:
Quoted 4 lines
Add initial dts file and document for ZX296702 and board ZX296702-AD1. More peripherals will be added later.
Signed-off-by Jun Nie <[email protected]>Applied to next/dt, thanks!
And removed again. I hadn't pushed it out to a public tree yet and found a build error in this.
Unfortunately, you are using a header file here that is only introduced by a patch that belongs to another subsystem maintainer.
Quoted 8 lines
Please try to get rid of that dependency, or submit this patch again for the following merge window once that driver has been merged upstream.
In a lot of cases, you can just use hardware numbers as identifiers instead of making up your own, to avoid having to use ugly header files that make life hard for us.
Arnd
Hi Arnd,
I have to use macro in file "include/dt-bindings/clock/zx296702-clock.h" for clock id. Because it is hard to maintain the id as it is has nothing to do with hardware and I may add more clock later. I will post patch 4/5/7 after the dts patch merged. Thanks!
Jun
PATCH v4 4/7 ARM: dts: zx: add an initial zx296702 dts and doc
Quoted 29 lines · Jun Nie
B.R.
Jun2015-05-16 4:19 GMT+08:00 Arnd Bergmann <[email protected]>:
Quoted 24 lines · On Friday 15 May 2015 21:59:06 Arnd Bergmann wrote:
Quoted 9 lines · On Tuesday 28 April 2015 17:18:08 Jun Nie wrote:
Quoted 4 lines
Add initial dts file and document for ZX296702 and board ZX296702-AD1. More peripherals will be added later.
Signed-off-by Jun Nie <[email protected]>Applied to next/dt, thanks!
And removed again. I hadn't pushed it out to a public tree yet and found a build error in this.
Unfortunately, you are using a header file here that is only introduced by a patch that belongs to another subsystem maintainer.
Please try to get rid of that dependency, or submit this patch again for the following merge window once that driver has been merged upstream.
In a lot of cases, you can just use hardware numbers as identifiers instead of making up your own, to avoid having to use ugly header files that make life hard for us.
Quoted 7 lines
Quoted 1 line
Arnd
Hi Arnd,
I have to use macro in file "
include/dt-bindings/clock/zx296702-clock.h" for clock id. Because it is hard to maintain the id as it is has nothing to do with hardware
It's not true. The number has something to do with hardware. Ideally, the clock ID should be numbered according clock tree from root to leaf. The problem with zx296702 is that the reference manual doesn't give a full picture of the whole clock tree. And we have to number the clocks as much as we can at some level mapping the hardware clock tree.
Shawn
Quoted 9 lines
and I may add more clock later. I will post patch 4/5/7 after the dts patch merged. Thanks!
Jun
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v4 5/7 clk: zx: add clock support to zx296702
In reply to Jun NieIt adds a clock driver for zx296702 SoC to register the clock tree to Common Clock Framework. All the clocks of bus topology and some the peripheral clocks are ready with this commit. Some missing leaf clocks for peripherals will be added later when needed.
--- drivers/clk/Makefile | 1 + drivers/clk/zte/Makefile | 2 + drivers/clk/zte/clk-pll.c | 180 ++++++++ drivers/clk/zte/clk-zx296702.c | 658 +++++++++++++++++++++++++++++ drivers/clk/zte/clk.h | 30 ++ include/dt-bindings/clock/zx296702-clock.h | 162 +++++++ 6 files changed, 1033 insertions(+) create mode 100644 drivers/clk/zte/Makefile create mode 100644 drivers/clk/zte/clk-pll.c create mode 100644 drivers/clk/zte/clk-zx296702.c create mode 100644 drivers/clk/zte/clk.h create mode 100644 include/dt-bindings/clock/zx296702-clock.h
drivers/clk/Makefile +1 -0
@@ -72,4 +72,5 @@ obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ obj-$(CONFIG_X86) += x86/ +obj-$(CONFIG_ARCH_ZX) += zte/ obj-$(CONFIG_ARCH_ZYNQ) += zynq/
drivers/clk/zte/Makefile new file +2 -0
@@ -0,0 +1,2 @@ +obj-y := clk-pll.o +obj-$(CONFIG_SOC_ZX296702) += clk-zx296702.o
drivers/clk/zte/clk-pll.c new file +180 -0
180 lines not on this page · raw message
drivers/clk/zte/clk-zx296702.c new file +658 -0
658 lines not on this page · raw message
drivers/clk/zte/clk.h new file +30 -0
@@ -0,0 +1,30 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __ZTE_CLK_H +#define __ZTE_CLK_H + +struct zx_pll_config { +unsigned long rate; +u32 cfg0; +u32 cfg1; +}; + +struct clk_zx_pll { +struct clk_hw hw; +void __iomem *reg_base; +const struct zx_pll_config *lookup_table;/* order by rate asc */ +int count; +spinlock_t *lock; +}; + +struct clk *clk_register_zx_pll (const char *name,const char *parent_name, +unsigned long flags,void __iomem *reg_base, +const struct zx_pll_config *lookup_table,int count,spinlock_t *lock); +#endif
include/dt-bindings/clock/zx296702-clock.h new file +162 -0
162 lines not on this page · raw message
Signature · 1 line
1.9.1
Arnd Bergmann
maintainerPATCH v4 5/7 clk: zx: add clock support to zx296702
Quoted 19 lines · On Tuesday 28 April 2015 17:18:09 Jun Nie wrote:
include/dt-bindings/clock/zx296702-clock.h new file +12
-0@@ -0,0 +1,162 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __DT_BINDINGS_CLOCK_ZX296702_H +#define __DT_BINDINGS_CLOCK_ZX296702_H +
include/dt-bindings/clock/zx296702-clock.h line 22
Quoted 10 lines
include/dt-bindings/clock/zx296702-clock.h new file +10
-0+#define ZX296702_OSC 0 +#define ZX296702_PLL_A9 1 +#define ZX296702_PLL_A9_350M 2 +#define ZX296702_PLL_MAC_1000M 3 +#define ZX296702_PLL_MAC_333M 4 +#define ZX296702_PLL_MM0_1188M 5 +#define ZX296702_PLL_MM0_396M 6 +#define ZX296702_PLL_MM0_198M 7 +#define ZX296702_PLL_MM1_108M 8 +#define ZX296702_PLL_MM1_72M 9
No objections for this driver going through Mike's tree, but as I said if you want the dts file to be merged in the same merge window, it would be best to avoid the header file.
Arnd
PATCH v4 5/7 clk: zx: add clock support to zx296702
Quoted 26 lines · Arnd Bergmann
Quoted 25 lines · On Tuesday 28 April 2015 17:18:09 Jun Nie wrote:
include/dt-bindings/clock/zx296702-clock.h new file +19
-0@@ -0,0 +1,162 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __DT_BINDINGS_CLOCK_ZX296702_H +#define __DT_BINDINGS_CLOCK_ZX296702_H + +#define ZX296702_OSC 0 +#define ZX296702_PLL_A9 1 +#define ZX296702_PLL_A9_350M 2 +#define ZX296702_PLL_MAC_1000M 3 +#define ZX296702_PLL_MAC_333M 4 +#define ZX296702_PLL_MM0_1188M 5 +#define ZX296702_PLL_MM0_396M 6
Quoted 8 lines
include/dt-bindings/clock/zx296702-clock.h line 22
Quoted 4 lines
include/dt-bindings/clock/zx296702-clock.h new file +3
-0+#define ZX296702_PLL_MM0_198M 7 +#define ZX296702_PLL_MM1_108M 8 +#define ZX296702_PLL_MM1_72M 9No objections for this driver going through Mike's tree, but as I said if you want the dts file to be merged in the same merge window, it would be best to avoid the header file.
Alternatively, we can ask an ACK from Mike or Stephen on this patch, so that we can merge the whole series through arm-soc tree. As this patch adds a SoC specific clock driver and it's quite self-contained and shouldn't cause non-trivial merge conflicts, Mike/Stephen may be happy to give an ACK on it.
Shawn
Arnd Bergmann
maintainerPATCH v4 5/7 clk: zx: add clock support to zx296702
Quoted 36 lines · On Saturday 16 May 2015 21:07:57 Shawn Guo wrote:
Quoted 26 lines · Arnd Bergmann
Quoted 25 lines · On Tuesday 28 April 2015 17:18:09 Jun Nie wrote:
include/dt-bindings/clock/zx296702-clock.h new file +19
-0@@ -0,0 +1,162 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __DT_BINDINGS_CLOCK_ZX296702_H +#define __DT_BINDINGS_CLOCK_ZX296702_H + +#define ZX296702_OSC 0 +#define ZX296702_PLL_A9 1 +#define ZX296702_PLL_A9_350M 2 +#define ZX296702_PLL_MAC_1000M 3 +#define ZX296702_PLL_MAC_333M 4 +#define ZX296702_PLL_MM0_1188M 5 +#define ZX296702_PLL_MM0_396M 6Quoted 8 lines
include/dt-bindings/clock/zx296702-clock.h line 22
Quoted 4 lines
include/dt-bindings/clock/zx296702-clock.h new file +3
-0+#define ZX296702_PLL_MM0_198M 7 +#define ZX296702_PLL_MM1_108M 8 +#define ZX296702_PLL_MM1_72M 9No objections for this driver going through Mike's tree, but as I said if you want the dts file to be merged in the same merge window, it would be best to avoid the header file.
Quoted 6 lines
Alternatively, we can ask an ACK from Mike or Stephen on this patch, so that we can merge the whole series through arm-soc tree. As this patch adds a SoC specific clock driver and it's quite self-contained and shouldn't cause non-trivial merge conflicts, Mike/Stephen may be happy to give an ACK on it.
Yes, that would work too.
Arnd
PATCH v4 5/7 clk: zx: add clock support to zx296702
In reply to Jun NieB.R.
Jun
2015-04-28 17:18 GMT+08:00 Jun Nie <[email protected]>:
Quoted 5 lines
It adds a clock driver for zx296702 SoC to register the clock tree to Common Clock Framework. All the clocks of bus topology and some the peripheral clocks are ready with this commit. Some missing leaf clocks for peripherals will be added later when needed.
Mike & Stephen,
Could you help review and ack this patch? So that this patch set can be merged together in Arnd side.
Jun
Quoted 1,090 lines
Signed-off-by Jun Nie <[email protected]>--- drivers/clk/Makefile | 1 + drivers/clk/zte/Makefile | 2 + drivers/clk/zte/clk-pll.c | 180 ++++++++ drivers/clk/zte/clk-zx296702.c | 658 +++++++++++++++++++++++++++++ drivers/clk/zte/clk.h | 30 ++ include/dt-bindings/clock/zx296702-clock.h | 162 +++++++ 6 files changed, 1033 insertions(+) create mode 100644 drivers/clk/zte/Makefile create mode 100644 drivers/clk/zte/clk-pll.c create mode 100644 drivers/clk/zte/clk-zx296702.c create mode 100644 drivers/clk/zte/clk.h create mode 100644 include/dt-bindings/clock/zx296702-clock.hdrivers/clk/Makefile +1
-0@@ -72,4 +72,5 @@ obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ obj-$(CONFIG_X86) += x86/ +obj-$(CONFIG_ARCH_ZX) += zte/ obj-$(CONFIG_ARCH_ZYNQ) += zynq/drivers/clk/zte/Makefile new file +2
-0@@ -0,0 +1,2 @@ +obj-y := clk-pll.o +obj-$(CONFIG_SOC_ZX296702) += clk-zx296702.odrivers/clk/zte/clk-pll.c new file +180
-0@@ -0,0 +1,180 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/slab.h> +#include <linux/spinlock.h> + +#include "clk.h" + +#define to_clk_zx_pll (_hw) container_of(_hw, struct clk_zx_pll, hw) + +#define CFG0_CFG1_OFFSET 4 +#define LOCK_FLAG BIT(30) +#define POWER_DOWN BIT(31) + +static int rate_to_idx (struct clk_zx_pll *zx_pll,unsigned long rate) +{ +const struct zx_pll_config *config = zx_pll->lookup_table; +int i; + +for (i =0 ; i < zx_pll->count; i++) { +if (config[i].rate > rate) +return i >0 ? i -1 :0 ; + +if (config[i].rate == rate) +return i; + } + +return i -1 ; +} + +static int hw_to_idx (struct clk_zx_pll *zx_pll) +{ +const struct zx_pll_config *config = zx_pll->lookup_table; +u32 hw_cfg0, hw_cfg1; +int i; + + hw_cfg0 =readl_relaxed (zx_pll->reg_base); + hw_cfg1 =readl_relaxed (zx_pll->reg_base +CFG0_CFG1_OFFSET ); + +/* For matching the value in lookup table */ + hw_cfg0 &= ~LOCK_FLAG ; + hw_cfg0 |=POWER_DOWN ; + +for (i =0 ; i < zx_pll->count; i++) { +if (hw_cfg0 == config[i].cfg0 && hw_cfg1 == config[i].cfg1) +return i; + } + +return -1 ; +} + +static unsigned long zx_pll_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +struct clk_zx_pll *zx_pll =to_clk_zx_pll (hw); +int idx; + + idx =hw_to_idx (zx_pll); +if (unlikely (idx ==-1 )) +return 0 ; + +return zx_pll->lookup_table[idx].rate; +} + +static long zx_pll_round_rate (struct clk_hw *hw,unsigned long rate, +unsigned long *prate) +{ +struct clk_zx_pll *zx_pll =to_clk_zx_pll (hw); +int idx; + + idx =rate_to_idx (zx_pll, rate); + +return zx_pll->lookup_table[idx].rate; +} + +static int zx_pll_set_rate (struct clk_hw *hw,unsigned long rate, +unsigned long parent_rate) +{ +/* Assume current cpu is not running on current PLL */ +struct clk_zx_pll *zx_pll =to_clk_zx_pll (hw); +const struct zx_pll_config *config; +int idx; + + idx =rate_to_idx (zx_pll, rate); + config = &zx_pll->lookup_table[idx]; + +writel_relaxed (config->cfg0, zx_pll->reg_base); +writel_relaxed (config->cfg1, zx_pll->reg_base +CFG0_CFG1_OFFSET ); + +return 0 ; +} + +static int zx_pll_enable (struct clk_hw *hw) +{ +struct clk_zx_pll *zx_pll =to_clk_zx_pll (hw); +unsigned long timeout = jiffies +msecs_to_jiffies (500 ); +u32 reg; + + reg =readl_relaxed (zx_pll->reg_base); +writel_relaxed (reg & ~POWER_DOWN , zx_pll->reg_base); +while (!(readl_relaxed (zx_pll->reg_base) &LOCK_FLAG )) { +if (time_after (jiffies, timeout)) { +pr_err ("clk %s enable timeout\n" , +__clk_get_name (hw->clk)); +break ; + } + } + +return 0 ; +} + +static void zx_pll_disable (struct clk_hw *hw) +{ +struct clk_zx_pll *zx_pll =to_clk_zx_pll (hw); +u32 reg; + + reg =readl_relaxed (zx_pll->reg_base); +writel_relaxed (reg |POWER_DOWN , zx_pll->reg_base); +} + +static int zx_pll_is_enabled (struct clk_hw *hw) +{ +struct clk_zx_pll *zx_pll =to_clk_zx_pll (hw); +u32 reg; + + reg =readl_relaxed (zx_pll->reg_base); + +return !(reg &POWER_DOWN ); +} + +static const struct clk_ops zx_pll_ops = { + .recalc_rate = zx_pll_recalc_rate, + .round_rate = zx_pll_round_rate, + .set_rate = zx_pll_set_rate, + .enable = zx_pll_enable, + .disable = zx_pll_disable, + .is_enabled = zx_pll_is_enabled, +}; + +struct clk *clk_register_zx_pll (const char *name,const char *parent_name, +unsigned long flags,void __iomem *reg_base, +const struct zx_pll_config *lookup_table,int count,spinlock_t *lock) +{ +struct clk_zx_pll *zx_pll; +struct clk *clk; +struct clk_init_data init; + + zx_pll =kzalloc (sizeof (*zx_pll),GFP_KERNEL ); +if (!zx_pll) +return ERR_PTR (-ENOMEM ); + + init.name = name; + init.ops = &zx_pll_ops; + init.flags = flags; + init.parent_names = (parent_name ? &parent_name :NULL ); + init.num_parents = (parent_name ?1 :0 ); + + zx_pll->reg_base = reg_base; + zx_pll->lookup_table = lookup_table; + zx_pll->count = count; + zx_pll->lock = lock; + zx_pll->hw.init = &init; + + clk =clk_register (NULL , &zx_pll->hw); + +if (IS_ERR (clk)) +kfree (zx_pll); + +return clk; +}drivers/clk/zte/clk-zx296702.c new file +658
-0@@ -0,0 +1,658 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/of_address.h> +#include <dt-bindings/clock/zx296702-clock.h> +#include "clk.h" + +static DEFINE_SPINLOCK (reg_lock); + +static void __iomem *topcrm_base; +static void __iomem *lsp0crpm_base; +static void __iomem *lsp1crpm_base; + +static struct clk *topclk[ZX296702_TOPCLK_END ]; +static struct clk *lsp0clk[ZX296702_LSP0CLK_END ]; +static struct clk *lsp1clk[ZX296702_LSP1CLK_END ]; + +static struct clk_onecell_data topclk_data; +static struct clk_onecell_data lsp0clk_data; +static struct clk_onecell_data lsp1clk_data; + +#define CLK_MUX (topcrm_base + 0x04) +#define CLK_DIV (topcrm_base + 0x08) +#define CLK_EN0 (topcrm_base + 0x0c) +#define CLK_EN1 (topcrm_base + 0x10) +#define VOU_LOCAL_CLKEN (topcrm_base + 0x68) +#define VOU_LOCAL_CLKSEL (topcrm_base + 0x70) +#define VOU_LOCAL_DIV2_SET (topcrm_base + 0x74) +#define CLK_MUX1 (topcrm_base + 0x8c) + +#define CLK_SDMMC1 (lsp0crpm_base + 0x0c) + +#define CLK_UART0 (lsp1crpm_base + 0x20) +#define CLK_UART1 (lsp1crpm_base + 0x24) +#define CLK_SDMMC0 (lsp1crpm_base + 0x2c) + +static const struct zx_pll_config pll_a9_config[] = { + { .rate =700000000 , .cfg0 =0x800405d1 , .cfg1 =0x04555555 }, + { .rate =800000000 , .cfg0 =0x80040691 , .cfg1 =0x04aaaaaa }, + { .rate =900000000 , .cfg0 =0x80040791 , .cfg1 =0x04000000 }, + { .rate =1000000000 , .cfg0 =0x80040851 , .cfg1 =0x04555555 }, + { .rate =1100000000 , .cfg0 =0x80040911 , .cfg1 =0x04aaaaaa }, + { .rate =1200000000 , .cfg0 =0x80040a11 , .cfg1 =0x04000000 }, +}; + +static const struct clk_div_table main_hlk_div[] = { + { .val =1 , .div =2 , }, + { .val =3 , .div =4 , }, + {/* sentinel */ } +}; + +static const struct clk_div_table a9_as1_aclk_divider[] = { + { .val =0 , .div =1 , }, + { .val =1 , .div =2 , }, + { .val =3 , .div =4 , }, + {/* sentinel */ } +}; + +static const struct clk_div_table sec_wclk_divider[] = { + { .val =0 , .div =1 , }, + { .val =1 , .div =2 , }, + { .val =3 , .div =4 , }, + { .val =5 , .div =6 , }, + { .val =7 , .div =8 , }, + {/* sentinel */ } +}; + +static const char const *matrix_aclk_sel[] = { +"pll_mm0_198M" , +"osc" , +"clk_148M5" , +"pll_lsp_104M" , +}; + +static const char const *a9_wclk_sel[] = { +"pll_a9" , +"osc" , +"clk_500" , +"clk_250" , +}; + +static const char const *a9_as1_aclk_sel[] = { +"clk_250" , +"osc" , +"pll_mm0_396M" , +"pll_mac_333M" , +}; + +static const char const *a9_trace_clkin_sel[] = { +"clk_74M25" , +"pll_mm1_108M" , +"clk_125" , +"clk_148M5" , +}; + +static const char const *decppu_aclk_sel[] = { +"clk_250" , +"pll_mm0_198M" , +"pll_lsp_104M" , +"pll_audio_294M912" , +}; + +static const char const *vou_main_wclk_sel[] = { +"clk_148M5" , +"clk_74M25" , +"clk_27" , +"pll_mm1_54M" , +}; + +static const char const *vou_scaler_wclk_sel[] = { +"clk_250" , +"pll_mac_333M" , +"pll_audio_294M912" , +"pll_mm0_198M" , +}; + +static const char const *r2d_wclk_sel[] = { +"pll_audio_294M912" , +"pll_mac_333M" , +"pll_a9_350M" , +"pll_mm0_396M" , +}; + +static const char const *ddr_wclk_sel[] = { +"pll_mac_333M" , +"pll_ddr_266M" , +"pll_audio_294M912" , +"pll_mm0_198M" , +}; + +static const char const *nand_wclk_sel[] = { +"pll_lsp_104M" , +"osc" , +}; + +static const char const *lsp_26_wclk_sel[] = { +"pll_lsp_26M" , +"osc" , +}; + +static const char const *vl0_sel[] = { +"vou_main_channel_div" , +"vou_aux_channel_div" , +}; + +static const char const *hdmi_sel[] = { +"vou_main_channel_wclk" , +"vou_aux_channel_wclk" , +}; + +static const char const *sdmmc0_wclk_sel[] = { +"lsp1_104M_wclk" , +"lsp1_26M_wclk" , +}; + +static const char const *sdmmc1_wclk_sel[] = { +"lsp0_104M_wclk" , +"lsp0_26M_wclk" , +}; + +static const char const *uart_wclk_sel[] = { +"lsp1_104M_wclk" , +"lsp1_26M_wclk" , +}; + +static inline struct clk *zx_divtbl (const char *name,const char *parent, +void __iomem *reg,u8 shift,u8 width, +const struct clk_div_table *table) +{ +return clk_register_divider_table (NULL , name, parent,0 , reg, shift, + width,0 , table, ®_lock); +} + +static inline struct clk *zx_div (const char *name,const char *parent, +void __iomem *reg,u8 shift,u8 width) +{ +return clk_register_divider (NULL , name, parent,0 , + reg, shift, width,0 , ®_lock); +} + +static inline struct clk *zx_mux (const char *name,const char **parents, +int num_parents,void __iomem *reg,u8 shift,u8 width) +{ +return clk_register_mux (NULL , name, parents, num_parents, +0 , reg, shift, width,0 , ®_lock); +} + +static inline struct clk *zx_gate (const char *name,const char *parent, +void __iomem *reg,u8 shift) +{ +return clk_register_gate (NULL , name, parent,CLK_IGNORE_UNUSED , + reg, shift,0 , ®_lock); +} + +static void __init zx296702_top_clocks_init (struct device_node *np) +{ +struct clk **clk = topclk; +int i; + + topcrm_base =of_iomap (np,0 ); +WARN_ON (!topcrm_base); + + clk[ZX296702_OSC ] = +clk_register_fixed_rate (NULL ,"osc" ,NULL ,CLK_IS_ROOT , +30000000 ); + clk[ZX296702_PLL_A9 ] = +clk_register_zx_pll ("pll_a9" ,"osc" ,0 , topcrm_base + +0x01c , pll_a9_config, +ARRAY_SIZE (pll_a9_config), ®_lock); + +/* TODO: pll_a9_350M look like changeble follow a9 pll */ + clk[ZX296702_PLL_A9_350M ] = +clk_register_fixed_rate (NULL ,"pll_a9_350M" ,"osc" ,0 , +350000000 ); + clk[ZX296702_PLL_MAC_1000M ] = +clk_register_fixed_rate (NULL ,"pll_mac_1000M" ,"osc" ,0 , +1000000000 ); + clk[ZX296702_PLL_MAC_333M ] = +clk_register_fixed_rate (NULL ,"pll_mac_333M" ,"osc" ,0 , +333000000 ); + clk[ZX296702_PLL_MM0_1188M ] = +clk_register_fixed_rate (NULL ,"pll_mm0_1188M" ,"osc" ,0 , +1188000000 ); + clk[ZX296702_PLL_MM0_396M ] = +clk_register_fixed_rate (NULL ,"pll_mm0_396M" ,"osc" ,0 , +396000000 ); + clk[ZX296702_PLL_MM0_198M ] = +clk_register_fixed_rate (NULL ,"pll_mm0_198M" ,"osc" ,0 , +198000000 ); + clk[ZX296702_PLL_MM1_108M ] = +clk_register_fixed_rate (NULL ,"pll_mm1_108M" ,"osc" ,0 , +108000000 ); + clk[ZX296702_PLL_MM1_72M ] = +clk_register_fixed_rate (NULL ,"pll_mm1_72M" ,"osc" ,0 , +72000000 ); + clk[ZX296702_PLL_MM1_54M ] = +clk_register_fixed_rate (NULL ,"pll_mm1_54M" ,"osc" ,0 , +54000000 ); + clk[ZX296702_PLL_LSP_104M ] = +clk_register_fixed_rate (NULL ,"pll_lsp_104M" ,"osc" ,0 , +104000000 ); + clk[ZX296702_PLL_LSP_26M ] = +clk_register_fixed_rate (NULL ,"pll_lsp_26M" ,"osc" ,0 , +26000000 ); + clk[ZX296702_PLL_DDR_266M ] = +clk_register_fixed_rate (NULL ,"pll_ddr_266M" ,"osc" ,0 , +266000000 ); + clk[ZX296702_PLL_AUDIO_294M912 ] = +clk_register_fixed_rate (NULL ,"pll_audio_294M912" ,"osc" ,0 , +294912000 ); + +/* bus clock */ + clk[ZX296702_MATRIX_ACLK ] = +zx_mux ("matrix_aclk" , matrix_aclk_sel, +ARRAY_SIZE (matrix_aclk_sel),CLK_MUX ,2 ,2 ); + clk[ZX296702_MAIN_HCLK ] = +zx_divtbl ("main_hclk" ,"matrix_aclk" ,CLK_DIV ,0 ,2 , + main_hlk_div); + clk[ZX296702_MAIN_PCLK ] = +zx_divtbl ("main_pclk" ,"matrix_aclk" ,CLK_DIV ,2 ,2 , + main_hlk_div); + +/* cpu clock */ + clk[ZX296702_CLK_500 ] = +clk_register_fixed_factor (NULL ,"clk_500" ,"pll_mac_1000M" ,0 , +1 ,2 ); + clk[ZX296702_CLK_250 ] = +clk_register_fixed_factor (NULL ,"clk_250" ,"pll_mac_1000M" ,0 , +1 ,4 ); + clk[ZX296702_CLK_125 ] = +clk_register_fixed_factor (NULL ,"clk_125" ,"clk_250" ,0 ,1 ,2 ); + clk[ZX296702_CLK_148M5 ] = +clk_register_fixed_factor (NULL ,"clk_148M5" ,"pll_mm0_1188M" ,0 , +1 ,8 ); + clk[ZX296702_CLK_74M25 ] = +clk_register_fixed_factor (NULL ,"clk_74M25" ,"pll_mm0_1188M" ,0 , +1 ,16 ); + clk[ZX296702_A9_WCLK ] = +zx_mux ("a9_wclk" , a9_wclk_sel,ARRAY_SIZE (a9_wclk_sel),CLK_MUX , +0 ,2 ); + clk[ZX296702_A9_AS1_ACLK_MUX ] = +zx_mux ("a9_as1_aclk_mux" , a9_as1_aclk_sel, +ARRAY_SIZE (a9_as1_aclk_sel),CLK_MUX ,4 ,2 ); + clk[ZX296702_A9_TRACE_CLKIN_MUX ] = +zx_mux ("a9_trace_clkin_mux" , a9_trace_clkin_sel, +ARRAY_SIZE (a9_trace_clkin_sel),CLK_MUX1 ,0 ,2 ); + clk[ZX296702_A9_AS1_ACLK_DIV ] = +zx_divtbl ("a9_as1_aclk_div" ,"a9_as1_aclk_mux" ,CLK_DIV ,4 ,2 , + a9_as1_aclk_divider); + +/* multi-media clock */ + clk[ZX296702_CLK_2 ] = +clk_register_fixed_factor (NULL ,"clk_2" ,"pll_mm1_72M" ,0 , +1 ,36 ); + clk[ZX296702_CLK_27 ] = +clk_register_fixed_factor (NULL ,"clk_27" ,"pll_mm1_54M" ,0 , +1 ,2 ); + clk[ZX296702_DECPPU_ACLK_MUX ] = +zx_mux ("decppu_aclk_mux" , decppu_aclk_sel, +ARRAY_SIZE (decppu_aclk_sel),CLK_MUX ,6 ,2 ); + clk[ZX296702_PPU_ACLK_MUX ] = +zx_mux ("ppu_aclk_mux" , decppu_aclk_sel, +ARRAY_SIZE (decppu_aclk_sel),CLK_MUX ,8 ,2 ); + clk[ZX296702_MALI400_ACLK_MUX ] = +zx_mux ("mali400_aclk_mux" , decppu_aclk_sel, +ARRAY_SIZE (decppu_aclk_sel),CLK_MUX ,12 ,2 ); + clk[ZX296702_VOU_ACLK_MUX ] = +zx_mux ("vou_aclk_mux" , decppu_aclk_sel, +ARRAY_SIZE (decppu_aclk_sel),CLK_MUX ,10 ,2 ); + clk[ZX296702_VOU_MAIN_WCLK_MUX ] = +zx_mux ("vou_main_wclk_mux" , vou_main_wclk_sel, +ARRAY_SIZE (vou_main_wclk_sel),CLK_MUX ,14 ,2 ); + clk[ZX296702_VOU_AUX_WCLK_MUX ] = +zx_mux ("vou_aux_wclk_mux" , vou_main_wclk_sel, +ARRAY_SIZE (vou_main_wclk_sel),CLK_MUX ,16 ,2 ); + clk[ZX296702_VOU_SCALER_WCLK_MUX ] = +zx_mux ("vou_scaler_wclk_mux" , vou_scaler_wclk_sel, +ARRAY_SIZE (vou_scaler_wclk_sel),CLK_MUX , +18 ,2 ); + clk[ZX296702_R2D_ACLK_MUX ] = +zx_mux ("r2d_aclk_mux" , decppu_aclk_sel, +ARRAY_SIZE (decppu_aclk_sel),CLK_MUX ,20 ,2 ); + clk[ZX296702_R2D_WCLK_MUX ] = +zx_mux ("r2d_wclk_mux" , r2d_wclk_sel, +ARRAY_SIZE (r2d_wclk_sel),CLK_MUX ,22 ,2 ); + +/* other clock */ + clk[ZX296702_CLK_50 ] = +clk_register_fixed_factor (NULL ,"clk_50" ,"pll_mac_1000M" , +0 ,1 ,20 ); + clk[ZX296702_CLK_25 ] = +clk_register_fixed_factor (NULL ,"clk_25" ,"pll_mac_1000M" , +0 ,1 ,40 ); + clk[ZX296702_CLK_12 ] = +clk_register_fixed_factor (NULL ,"clk_12" ,"pll_mm1_72M" , +0 ,1 ,6 ); + clk[ZX296702_CLK_16M384 ] = +clk_register_fixed_factor (NULL ,"clk_16M384" , +"pll_audio_294M912" ,0 ,1 ,18 ); + clk[ZX296702_CLK_32K768 ] = +clk_register_fixed_factor (NULL ,"clk_32K768" ,"clk_16M384" , +0 ,1 ,500 ); + clk[ZX296702_SEC_WCLK_DIV ] = +zx_divtbl ("sec_wclk_div" ,"pll_lsp_104M" ,CLK_DIV ,6 ,3 , + sec_wclk_divider); + clk[ZX296702_DDR_WCLK_MUX ] = +zx_mux ("ddr_wclk_mux" , ddr_wclk_sel, +ARRAY_SIZE (ddr_wclk_sel),CLK_MUX ,24 ,2 ); + clk[ZX296702_NAND_WCLK_MUX ] = +zx_mux ("nand_wclk_mux" , nand_wclk_sel, +ARRAY_SIZE (nand_wclk_sel),CLK_MUX ,24 ,2 ); + clk[ZX296702_LSP_26_WCLK_MUX ] = +zx_mux ("lsp_26_wclk_mux" , lsp_26_wclk_sel, +ARRAY_SIZE (lsp_26_wclk_sel),CLK_MUX ,27 ,1 ); + +/* gates */ + clk[ZX296702_A9_AS0_ACLK ] = +zx_gate ("a9_as0_aclk" ,"matrix_aclk" ,CLK_EN0 ,0 ); + clk[ZX296702_A9_AS1_ACLK ] = +zx_gate ("a9_as1_aclk" ,"a9_as1_aclk_div" ,CLK_EN0 ,1 ); + clk[ZX296702_A9_TRACE_CLKIN ] = +zx_gate ("a9_trace_clkin" ,"a9_trace_clkin_mux" ,CLK_EN0 ,2 ); + clk[ZX296702_DECPPU_AXI_M_ACLK ] = +zx_gate ("decppu_axi_m_aclk" ,"decppu_aclk_mux" ,CLK_EN0 ,3 ); + clk[ZX296702_DECPPU_AHB_S_HCLK ] = +zx_gate ("decppu_ahb_s_hclk" ,"main_hclk" ,CLK_EN0 ,4 ); + clk[ZX296702_PPU_AXI_M_ACLK ] = +zx_gate ("ppu_axi_m_aclk" ,"ppu_aclk_mux" ,CLK_EN0 ,5 ); + clk[ZX296702_PPU_AHB_S_HCLK ] = +zx_gate ("ppu_ahb_s_hclk" ,"main_hclk" ,CLK_EN0 ,6 ); + clk[ZX296702_VOU_AXI_M_ACLK ] = +zx_gate ("vou_axi_m_aclk" ,"vou_aclk_mux" ,CLK_EN0 ,7 ); + clk[ZX296702_VOU_APB_PCLK ] = +zx_gate ("vou_apb_pclk" ,"main_pclk" ,CLK_EN0 ,8 ); + clk[ZX296702_VOU_MAIN_CHANNEL_WCLK ] = +zx_gate ("vou_main_channel_wclk" ,"vou_main_wclk_mux" , +CLK_EN0 ,9 ); + clk[ZX296702_VOU_AUX_CHANNEL_WCLK ] = +zx_gate ("vou_aux_channel_wclk" ,"vou_aux_wclk_mux" , +CLK_EN0 ,10 ); + clk[ZX296702_VOU_HDMI_OSCLK_CEC ] = +zx_gate ("vou_hdmi_osclk_cec" ,"clk_2" ,CLK_EN0 ,11 ); + clk[ZX296702_VOU_SCALER_WCLK ] = +zx_gate ("vou_scaler_wclk" ,"vou_scaler_wclk_mux" ,CLK_EN0 ,12 ); + clk[ZX296702_MALI400_AXI_M_ACLK ] = +zx_gate ("mali400_axi_m_aclk" ,"mali400_aclk_mux" ,CLK_EN0 ,13 ); + clk[ZX296702_MALI400_APB_PCLK ] = +zx_gate ("mali400_apb_pclk" ,"main_pclk" ,CLK_EN0 ,14 ); + clk[ZX296702_R2D_WCLK ] = +zx_gate ("r2d_wclk" ,"r2d_wclk_mux" ,CLK_EN0 ,15 ); + clk[ZX296702_R2D_AXI_M_ACLK ] = +zx_gate ("r2d_axi_m_aclk" ,"r2d_aclk_mux" ,CLK_EN0 ,16 ); + clk[ZX296702_R2D_AHB_HCLK ] = +zx_gate ("r2d_ahb_hclk" ,"main_hclk" ,CLK_EN0 ,17 ); + clk[ZX296702_DDR3_AXI_S0_ACLK ] = +zx_gate ("ddr3_axi_s0_aclk" ,"matrix_aclk" ,CLK_EN0 ,18 ); + clk[ZX296702_DDR3_APB_PCLK ] = +zx_gate ("ddr3_apb_pclk" ,"main_pclk" ,CLK_EN0 ,19 ); + clk[ZX296702_DDR3_WCLK ] = +zx_gate ("ddr3_wclk" ,"ddr_wclk_mux" ,CLK_EN0 ,20 ); + clk[ZX296702_USB20_0_AHB_HCLK ] = +zx_gate ("usb20_0_ahb_hclk" ,"main_hclk" ,CLK_EN0 ,21 ); + clk[ZX296702_USB20_0_EXTREFCLK ] = +zx_gate ("usb20_0_extrefclk" ,"clk_12" ,CLK_EN0 ,22 ); + clk[ZX296702_USB20_1_AHB_HCLK ] = +zx_gate ("usb20_1_ahb_hclk" ,"main_hclk" ,CLK_EN0 ,23 ); + clk[ZX296702_USB20_1_EXTREFCLK ] = +zx_gate ("usb20_1_extrefclk" ,"clk_12" ,CLK_EN0 ,24 ); + clk[ZX296702_USB20_2_AHB_HCLK ] = +zx_gate ("usb20_2_ahb_hclk" ,"main_hclk" ,CLK_EN0 ,25 ); + clk[ZX296702_USB20_2_EXTREFCLK ] = +zx_gate ("usb20_2_extrefclk" ,"clk_12" ,CLK_EN0 ,26 ); + clk[ZX296702_GMAC_AXI_M_ACLK ] = +zx_gate ("gmac_axi_m_aclk" ,"matrix_aclk" ,CLK_EN0 ,27 ); + clk[ZX296702_GMAC_APB_PCLK ] = +zx_gate ("gmac_apb_pclk" ,"main_pclk" ,CLK_EN0 ,28 ); + clk[ZX296702_GMAC_125_CLKIN ] = +zx_gate ("gmac_125_clkin" ,"clk_125" ,CLK_EN0 ,29 ); + clk[ZX296702_GMAC_RMII_CLKIN ] = +zx_gate ("gmac_rmii_clkin" ,"clk_50" ,CLK_EN0 ,30 ); + clk[ZX296702_GMAC_25M_CLK ] = +zx_gate ("gmac_25M_clk" ,"clk_25" ,CLK_EN0 ,31 ); + clk[ZX296702_NANDFLASH_AHB_HCLK ] = +zx_gate ("nandflash_ahb_hclk" ,"main_hclk" ,CLK_EN1 ,0 ); + clk[ZX296702_NANDFLASH_WCLK ] = +zx_gate ("nandflash_wclk" ,"nand_wclk_mux" ,CLK_EN1 ,1 ); + clk[ZX296702_LSP0_APB_PCLK ] = +zx_gate ("lsp0_apb_pclk" ,"main_pclk" ,CLK_EN1 ,2 ); + clk[ZX296702_LSP0_AHB_HCLK ] = +zx_gate ("lsp0_ahb_hclk" ,"main_hclk" ,CLK_EN1 ,3 ); + clk[ZX296702_LSP0_26M_WCLK ] = +zx_gate ("lsp0_26M_wclk" ,"lsp_26_wclk_mux" ,CLK_EN1 ,4 ); + clk[ZX296702_LSP0_104M_WCLK ] = +zx_gate ("lsp0_104M_wclk" ,"pll_lsp_104M" ,CLK_EN1 ,5 ); + clk[ZX296702_LSP0_16M384_WCLK ] = +zx_gate ("lsp0_16M384_wclk" ,"clk_16M384" ,CLK_EN1 ,6 ); + clk[ZX296702_LSP1_APB_PCLK ] = +zx_gate ("lsp1_apb_pclk" ,"main_pclk" ,CLK_EN1 ,7 ); +/* FIXME: wclk enable bit is bit8. We hack it as reserved 31 for +* UART does not work after parent clk is disabled/enabled */ + clk[ZX296702_LSP1_26M_WCLK ] = +zx_gate ("lsp1_26M_wclk" ,"lsp_26_wclk_mux" ,CLK_EN1 ,31 ); + clk[ZX296702_LSP1_104M_WCLK ] = +zx_gate ("lsp1_104M_wclk" ,"pll_lsp_104M" ,CLK_EN1 ,9 ); + clk[ZX296702_LSP1_32K_CLK ] = +zx_gate ("lsp1_32K_clk" ,"clk_32K768" ,CLK_EN1 ,10 ); + clk[ZX296702_AON_HCLK ] = +zx_gate ("aon_hclk" ,"main_hclk" ,CLK_EN1 ,11 ); + clk[ZX296702_SYS_CTRL_PCLK ] = +zx_gate ("sys_ctrl_pclk" ,"main_pclk" ,CLK_EN1 ,12 ); + clk[ZX296702_DMA_PCLK ] = +zx_gate ("dma_pclk" ,"main_pclk" ,CLK_EN1 ,13 ); + clk[ZX296702_DMA_ACLK ] = +zx_gate ("dma_aclk" ,"matrix_aclk" ,CLK_EN1 ,14 ); + clk[ZX296702_SEC_HCLK ] = +zx_gate ("sec_hclk" ,"main_hclk" ,CLK_EN1 ,15 ); + clk[ZX296702_AES_WCLK ] = +zx_gate ("aes_wclk" ,"sec_wclk_div" ,CLK_EN1 ,16 ); + clk[ZX296702_DES_WCLK ] = +zx_gate ("des_wclk" ,"sec_wclk_div" ,CLK_EN1 ,17 ); + clk[ZX296702_IRAM_ACLK ] = +zx_gate ("iram_aclk" ,"matrix_aclk" ,CLK_EN1 ,18 ); + clk[ZX296702_IROM_ACLK ] = +zx_gate ("irom_aclk" ,"matrix_aclk" ,CLK_EN1 ,19 ); + clk[ZX296702_BOOT_CTRL_HCLK ] = +zx_gate ("boot_ctrl_hclk" ,"main_hclk" ,CLK_EN1 ,20 ); + clk[ZX296702_EFUSE_CLK_30 ] = +zx_gate ("efuse_clk_30" ,"osc" ,CLK_EN1 ,21 ); + +/* TODO: add VOU Local clocks */ + clk[ZX296702_VOU_MAIN_CHANNEL_DIV ] = +zx_div ("vou_main_channel_div" ,"vou_main_channel_wclk" , +VOU_LOCAL_DIV2_SET ,1 ,1 ); + clk[ZX296702_VOU_AUX_CHANNEL_DIV ] = +zx_div ("vou_aux_channel_div" ,"vou_aux_channel_wclk" , +VOU_LOCAL_DIV2_SET ,0 ,1 ); + clk[ZX296702_VOU_TV_ENC_HD_DIV ] = +zx_div ("vou_tv_enc_hd_div" ,"vou_tv_enc_hd_mux" , +VOU_LOCAL_DIV2_SET ,3 ,1 ); + clk[ZX296702_VOU_TV_ENC_SD_DIV ] = +zx_div ("vou_tv_enc_sd_div" ,"vou_tv_enc_sd_mux" , +VOU_LOCAL_DIV2_SET ,2 ,1 ); + clk[ZX296702_VL0_MUX ] = +zx_mux ("vl0_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,8 ,1 ); + clk[ZX296702_VL1_MUX ] = +zx_mux ("vl1_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,9 ,1 ); + clk[ZX296702_VL2_MUX ] = +zx_mux ("vl2_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,10 ,1 ); + clk[ZX296702_GL0_MUX ] = +zx_mux ("gl0_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,5 ,1 ); + clk[ZX296702_GL1_MUX ] = +zx_mux ("gl1_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,6 ,1 ); + clk[ZX296702_GL2_MUX ] = +zx_mux ("gl2_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,7 ,1 ); + clk[ZX296702_WB_MUX ] = +zx_mux ("wb_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,11 ,1 ); + clk[ZX296702_HDMI_MUX ] = +zx_mux ("hdmi_mux" , hdmi_sel,ARRAY_SIZE (hdmi_sel), +VOU_LOCAL_CLKSEL ,4 ,1 ); + clk[ZX296702_VOU_TV_ENC_HD_MUX ] = +zx_mux ("vou_tv_enc_hd_mux" , hdmi_sel,ARRAY_SIZE (hdmi_sel), +VOU_LOCAL_CLKSEL ,3 ,1 ); + clk[ZX296702_VOU_TV_ENC_SD_MUX ] = +zx_mux ("vou_tv_enc_sd_mux" , hdmi_sel,ARRAY_SIZE (hdmi_sel), +VOU_LOCAL_CLKSEL ,2 ,1 ); + clk[ZX296702_VL0_CLK ] = +zx_gate ("vl0_clk" ,"vl0_mux" ,VOU_LOCAL_CLKEN ,8 ); + clk[ZX296702_VL1_CLK ] = +zx_gate ("vl1_clk" ,"vl1_mux" ,VOU_LOCAL_CLKEN ,9 ); + clk[ZX296702_VL2_CLK ] = +zx_gate ("vl2_clk" ,"vl2_mux" ,VOU_LOCAL_CLKEN ,10 ); + clk[ZX296702_GL0_CLK ] = +zx_gate ("gl0_clk" ,"gl0_mux" ,VOU_LOCAL_CLKEN ,5 ); + clk[ZX296702_GL1_CLK ] = +zx_gate ("gl1_clk" ,"gl1_mux" ,VOU_LOCAL_CLKEN ,6 ); + clk[ZX296702_GL2_CLK ] = +zx_gate ("gl2_clk" ,"gl2_mux" ,VOU_LOCAL_CLKEN ,7 ); + clk[ZX296702_WB_CLK ] = +zx_gate ("wb_clk" ,"wb_mux" ,VOU_LOCAL_CLKEN ,11 ); + clk[ZX296702_CL_CLK ] = +zx_gate ("cl_clk" ,"vou_main_channel_div" ,VOU_LOCAL_CLKEN ,12 ); + clk[ZX296702_MAIN_MIX_CLK ] = +zx_gate ("main_mix_clk" ,"vou_main_channel_div" , +VOU_LOCAL_CLKEN ,4 ); + clk[ZX296702_AUX_MIX_CLK ] = +zx_gate ("aux_mix_clk" ,"vou_aux_channel_div" , +VOU_LOCAL_CLKEN ,3 ); + clk[ZX296702_HDMI_CLK ] = +zx_gate ("hdmi_clk" ,"hdmi_mux" ,VOU_LOCAL_CLKEN ,2 ); + clk[ZX296702_VOU_TV_ENC_HD_DAC_CLK ] = +zx_gate ("vou_tv_enc_hd_dac_clk" ,"vou_tv_enc_hd_div" , +VOU_LOCAL_CLKEN ,1 ); + clk[ZX296702_VOU_TV_ENC_SD_DAC_CLK ] = +zx_gate ("vou_tv_enc_sd_dac_clk" ,"vou_tv_enc_sd_div" , +VOU_LOCAL_CLKEN ,0 ); + +/* CA9 PERIPHCLK = a9_wclk / 2 */ + clk[ZX296702_A9_PERIPHCLK ] = +clk_register_fixed_factor (NULL ,"a9_periphclk" ,"a9_wclk" , +0 ,1 ,2 ); + +for (i =0 ; i <ARRAY_SIZE (topclk); i++) { +if (IS_ERR (clk[i])) { +pr_err ("zx296702 clk %d: register failed with %ld\n" , + i,PTR_ERR (clk[i])); +return ; + } + } + + topclk_data.clks = topclk; + topclk_data.clk_num =ARRAY_SIZE (topclk); +of_clk_add_provider (np, of_clk_src_onecell_get, &topclk_data); +} +CLK_OF_DECLARE (zx296702_top_clk,"zte,zx296702-topcrm-clk" , + zx296702_top_clocks_init); + +static void __init zx296702_lsp0_clocks_init (struct device_node *np) +{ +struct clk **clk = lsp0clk; +int i; + + lsp0crpm_base =of_iomap (np,0 ); +WARN_ON (!lsp0crpm_base); + +/* SDMMC1 */ + clk[ZX296702_SDMMC1_WCLK_MUX ] = +zx_mux ("sdmmc1_wclk_mux" , sdmmc1_wclk_sel, +ARRAY_SIZE (sdmmc1_wclk_sel),CLK_SDMMC1 ,4 ,1 ); + clk[ZX296702_SDMMC1_WCLK_DIV ] = +zx_div ("sdmmc1_wclk_div" ,"sdmmc1_wclk_mux" ,CLK_SDMMC1 ,12 ,4 ); + clk[ZX296702_SDMMC1_WCLK ] = +zx_gate ("sdmmc1_wclk" ,"sdmmc1_wclk_div" ,CLK_SDMMC1 ,1 ); + clk[ZX296702_SDMMC1_PCLK ] = +zx_gate ("sdmmc1_pclk" ,"lsp1_apb_pclk" ,CLK_SDMMC1 ,0 ); + +for (i =0 ; i <ARRAY_SIZE (lsp0clk); i++) { +if (IS_ERR (clk[i])) { +pr_err ("zx296702 clk %d: register failed with %ld\n" , + i,PTR_ERR (clk[i])); +return ; + } + } + + lsp0clk_data.clks = lsp0clk; + lsp0clk_data.clk_num =ARRAY_SIZE (lsp0clk); +of_clk_add_provider (np, of_clk_src_onecell_get, &lsp0clk_data); +} +CLK_OF_DECLARE (zx296702_lsp0_clk,"zte,zx296702-lsp0crpm-clk" , + zx296702_lsp0_clocks_init); + +static void __init zx296702_lsp1_clocks_init (struct device_node *np) +{ +struct clk **clk = lsp1clk; +int i; + + lsp1crpm_base =of_iomap (np,0 ); +WARN_ON (!lsp1crpm_base); + +/* UART0 */ + clk[ZX296702_UART0_WCLK_MUX ] = +zx_mux ("uart0_wclk_mux" , uart_wclk_sel, +ARRAY_SIZE (uart_wclk_sel),CLK_UART0 ,4 ,1 ); +/* FIXME: uart wclk enable bit is bit1 in. We hack it as reserved 31 for +* UART does not work after parent clk is disabled/enabled */ + clk[ZX296702_UART0_WCLK ] = +zx_gate ("uart0_wclk" ,"uart0_wclk_mux" ,CLK_UART0 ,31 ); + clk[ZX296702_UART0_PCLK ] = +zx_gate ("uart0_pclk" ,"lsp1_apb_pclk" ,CLK_UART0 ,0 ); + +/* UART1 */ + clk[ZX296702_UART1_WCLK_MUX ] = +zx_mux ("uart1_wclk_mux" , uart_wclk_sel, +ARRAY_SIZE (uart_wclk_sel),CLK_UART1 ,4 ,1 ); + clk[ZX296702_UART1_WCLK ] = +zx_gate ("uart1_wclk" ,"uart1_wclk_mux" ,CLK_UART1 ,1 ); + clk[ZX296702_UART1_PCLK ] = +zx_gate ("uart1_pclk" ,"lsp1_apb_pclk" ,CLK_UART1 ,0 ); + +/* SDMMC0 */ + clk[ZX296702_SDMMC0_WCLK_MUX ] = +zx_mux ("sdmmc0_wclk_mux" , sdmmc0_wclk_sel, +ARRAY_SIZE (sdmmc0_wclk_sel),CLK_SDMMC0 ,4 ,1 ); + clk[ZX296702_SDMMC0_WCLK_DIV ] = +zx_div ("sdmmc0_wclk_div" ,"sdmmc0_wclk_mux" ,CLK_SDMMC0 ,12 ,4 ); + clk[ZX296702_SDMMC0_WCLK ] = +zx_gate ("sdmmc0_wclk" ,"sdmmc0_wclk_div" ,CLK_SDMMC0 ,1 ); + clk[ZX296702_SDMMC0_PCLK ] = +zx_gate ("sdmmc0_pclk" ,"lsp1_apb_pclk" ,CLK_SDMMC0 ,0 ); + +for (i =0 ; i <ARRAY_SIZE (lsp1clk); i++) { +if (IS_ERR (clk[i])) { +pr_err ("zx296702 clk %d: register failed with %ld\n" , + i,PTR_ERR (clk[i])); +return ; + } + } + + lsp1clk_data.clks = lsp1clk; + lsp1clk_data.clk_num =ARRAY_SIZE (lsp1clk); +of_clk_add_provider (np, of_clk_src_onecell_get, &lsp1clk_data); +} +CLK_OF_DECLARE (zx296702_lsp1_clk,"zte,zx296702-lsp1crpm-clk" , + zx296702_lsp1_clocks_init);drivers/clk/zte/clk.h new file +30
-0@@ -0,0 +1,30 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __ZTE_CLK_H +#define __ZTE_CLK_H + +struct zx_pll_config { +unsigned long rate; +u32 cfg0; +u32 cfg1; +}; + +struct clk_zx_pll { +struct clk_hw hw; +void __iomem *reg_base; +const struct zx_pll_config *lookup_table;/* order by rate asc */ +int count; +spinlock_t *lock; +}; + +struct clk *clk_register_zx_pll (const char *name,const char *parent_name, +unsigned long flags,void __iomem *reg_base, +const struct zx_pll_config *lookup_table,int count,spinlock_t *lock); +#endif include/dt-bindings/clock/zx296702-clock.h new file +162
-1@@ -0,0 +1,162 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __DT_BINDINGS_CLOCK_ZX296702_H +#define __DT_BINDINGS_CLOCK_ZX296702_H + +#define ZX296702_OSC 0 +#define ZX296702_PLL_A9 1 +#define ZX296702_PLL_A9_350M 2 +#define ZX296702_PLL_MAC_1000M 3 +#define ZX296702_PLL_MAC_333M 4 +#define ZX296702_PLL_MM0_1188M 5 +#define ZX296702_PLL_MM0_396M 6 +#define ZX296702_PLL_MM0_198M 7 +#define ZX296702_PLL_MM1_108M 8 +#define ZX296702_PLL_MM1_72M 9 +#define ZX296702_PLL_MM1_54M 10 +#define ZX296702_PLL_LSP_104M 11 +#define ZX296702_PLL_LSP_26M 12 +#define ZX296702_PLL_AUDIO_294M912 13 +#define ZX296702_PLL_DDR_266M 14 +#define ZX296702_CLK_148M5 15 +#define ZX296702_MATRIX_ACLK 16 +#define ZX296702_MAIN_HCLK 17 +#define ZX296702_MAIN_PCLK 18 +#define ZX296702_CLK_500 19 +#define ZX296702_CLK_250 20 +#define ZX296702_CLK_125 21 +#define ZX296702_CLK_74M25 22 +#define ZX296702_A9_WCLK 23 +#define ZX296702_A9_AS1_ACLK_MUX 24 +#define ZX296702_A9_TRACE_CLKIN_MUX 25 +#define ZX296702_A9_AS1_ACLK_DIV 26 +#define ZX296702_CLK_2 27 +#define ZX296702_CLK_27 28 +#define ZX296702_DECPPU_ACLK_MUX 29 +#define ZX296702_PPU_ACLK_MUX 30 +#define ZX296702_MALI400_ACLK_MUX 31 +#define ZX296702_VOU_ACLK_MUX 32 +#define ZX296702_VOU_MAIN_WCLK_MUX 33 +#define ZX296702_VOU_AUX_WCLK_MUX 34 +#define ZX296702_VOU_SCALER_WCLK_MUX 35 +#define ZX296702_R2D_ACLK_MUX 36 +#define ZX296702_R2D_WCLK_MUX 37 +#define ZX296702_CLK_50 38 +#define ZX296702_CLK_25 39 +#define ZX296702_CLK_12 40 +#define ZX296702_CLK_16M384 41 +#define ZX296702_CLK_32K768 42 +#define ZX296702_SEC_WCLK_DIV 43 +#define ZX296702_DDR_WCLK_MUX 44 +#define ZX296702_NAND_WCLK_MUX 45 +#define ZX296702_LSP_26_WCLK_MUX 46 +#define ZX296702_A9_AS0_ACLK 47 +#define ZX296702_A9_AS1_ACLK 48 +#define ZX296702_A9_TRACE_CLKIN 49 +#define ZX296702_DECPPU_AXI_M_ACLK 50 +#define ZX296702_DECPPU_AHB_S_HCLK 51 +#define ZX296702_PPU_AXI_M_ACLK 52 +#define ZX296702_PPU_AHB_S_HCLK 53 +#define ZX296702_VOU_AXI_M_ACLK 54 +#define ZX296702_VOU_APB_PCLK 55 +#define ZX296702_VOU_MAIN_CHANNEL_WCLK 56 +#define ZX296702_VOU_AUX_CHANNEL_WCLK 57 +#define ZX296702_VOU_HDMI_OSCLK_CEC 58 +#define ZX296702_VOU_SCALER_WCLK 59 +#define ZX296702_MALI400_AXI_M_ACLK 60 +#define ZX296702_MALI400_APB_PCLK 61 +#define ZX296702_R2D_WCLK 62 +#define ZX296702_R2D_AXI_M_ACLK 63 +#define ZX296702_R2D_AHB_HCLK 64 +#define ZX296702_DDR3_AXI_S0_ACLK 65 +#define ZX296702_DDR3_APB_PCLK 66 +#define ZX296702_DDR3_WCLK 67 +#define ZX296702_USB20_0_AHB_HCLK 68 +#define ZX296702_USB20_0_EXTREFCLK 69 +#define ZX296702_USB20_1_AHB_HCLK 70 +#define ZX296702_USB20_1_EXTREFCLK 71 +#define ZX296702_USB20_2_AHB_HCLK 72 +#define ZX296702_USB20_2_EXTREFCLK 73 +#define ZX296702_GMAC_AXI_M_ACLK 74 +#define ZX296702_GMAC_APB_PCLK 75 +#define ZX296702_GMAC_125_CLKIN 76 +#define ZX296702_GMAC_RMII_CLKIN 77 +#define ZX296702_GMAC_25M_CLK 78 +#define ZX296702_NANDFLASH_AHB_HCLK 79 +#define ZX296702_NANDFLASH_WCLK 80 +#define ZX296702_LSP0_APB_PCLK 81 +#define ZX296702_LSP0_AHB_HCLK 82 +#define ZX296702_LSP0_26M_WCLK 83 +#define ZX296702_LSP0_104M_WCLK 84 +#define ZX296702_LSP0_16M384_WCLK 85 +#define ZX296702_LSP1_APB_PCLK 86 +#define ZX296702_LSP1_26M_WCLK 87 +#define ZX296702_LSP1_104M_WCLK 88 +#define ZX296702_LSP1_32K_CLK 89 +#define ZX296702_AON_HCLK 90 +#define ZX296702_SYS_CTRL_PCLK 91 +#define ZX296702_DMA_PCLK 92 +#define ZX296702_DMA_ACLK 93 +#define ZX296702_SEC_HCLK 94 +#define ZX296702_AES_WCLK 95 +#define ZX296702_DES_WCLK 96 +#define ZX296702_IRAM_ACLK 97 +#define ZX296702_IROM_ACLK 98 +#define ZX296702_BOOT_CTRL_HCLK 99 +#define ZX296702_EFUSE_CLK_30 100 +#define ZX296702_VOU_MAIN_CHANNEL_DIV 101 +#define ZX296702_VOU_AUX_CHANNEL_DIV 102 +#define ZX296702_VOU_TV_ENC_HD_DIV 103 +#define ZX296702_VOU_TV_ENC_SD_DIV 104 +#define ZX296702_VL0_MUX 105 +#define ZX296702_VL1_MUX 106 +#define ZX296702_VL2_MUX 107 +#define ZX296702_GL0_MUX 108 +#define ZX296702_GL1_MUX 109 +#define ZX296702_GL2_MUX 110 +#define ZX296702_WB_MUX 111 +#define ZX296702_HDMI_MUX 112 +#define ZX296702_VOU_TV_ENC_HD_MUX 113 +#define ZX296702_VOU_TV_ENC_SD_MUX 114 +#define ZX296702_VL0_CLK 115 +#define ZX296702_VL1_CLK 116 +#define ZX296702_VL2_CLK 117 +#define ZX296702_GL0_CLK 118 +#define ZX296702_GL1_CLK 119 +#define ZX296702_GL2_CLK 120 +#define ZX296702_WB_CLK 121 +#define ZX296702_CL_CLK 122 +#define ZX296702_MAIN_MIX_CLK 123 +#define ZX296702_AUX_MIX_CLK 124 +#define ZX296702_HDMI_CLK 125 +#define ZX296702_VOU_TV_ENC_HD_DAC_CLK 126 +#define ZX296702_VOU_TV_ENC_SD_DAC_CLK 127 +#define ZX296702_A9_PERIPHCLK 128 +#define ZX296702_TOPCLK_END 129 + +#define ZX296702_SDMMC1_WCLK_MUX 0 +#define ZX296702_SDMMC1_WCLK_DIV 1 +#define ZX296702_SDMMC1_WCLK 2 +#define ZX296702_SDMMC1_PCLK 3 +#define ZX296702_LSP0CLK_END 4 + +#define ZX296702_UART0_WCLK_MUX 0 +#define ZX296702_UART0_WCLK 1 +#define ZX296702_UART0_PCLK 2 +#define ZX296702_UART1_WCLK_MUX 3 +#define ZX296702_UART1_WCLK 4 +#define ZX296702_UART1_PCLK 5 +#define ZX296702_SDMMC0_WCLK_MUX 6 +#define ZX296702_SDMMC0_WCLK_DIV 7 +#define ZX296702_SDMMC0_WCLK 8 +#define ZX296702_SDMMC0_PCLK 9 +#define ZX296702_LSP1CLK_END 10 + +#endif /* __DT_BINDINGS_CLOCK_ZX296702_H */ --1.9.1
PATCH v4 5/7 clk: zx: add clock support to zx296702
Quoted 11 lines
2015-04-28 17:18 GMT+08:00 Jun Nie <[email protected]>:
Quoted 5 lines
It adds a clock driver for zx296702 SoC to register the clock tree to Common Clock Framework. All the clocks of bus topology and some the peripheral clocks are ready with this commit. Some missing leaf clocks for peripherals will be added later when needed.
Mike & Stephen,
Could you help review and ack this patch? So that this patch set can be merged together in Arnd side.
Hi Mike,
Could you help on this? Thanks ^_^
Jun
Quoted 1,092 lines
Jun
Quoted 1,090 lines
Signed-off-by Jun Nie <[email protected]>--- drivers/clk/Makefile | 1 + drivers/clk/zte/Makefile | 2 + drivers/clk/zte/clk-pll.c | 180 ++++++++ drivers/clk/zte/clk-zx296702.c | 658 +++++++++++++++++++++++++++++ drivers/clk/zte/clk.h | 30 ++ include/dt-bindings/clock/zx296702-clock.h | 162 +++++++ 6 files changed, 1033 insertions(+) create mode 100644 drivers/clk/zte/Makefile create mode 100644 drivers/clk/zte/clk-pll.c create mode 100644 drivers/clk/zte/clk-zx296702.c create mode 100644 drivers/clk/zte/clk.h create mode 100644 include/dt-bindings/clock/zx296702-clock.hdrivers/clk/Makefile +1
-0@@ -72,4 +72,5 @@ obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ obj-$(CONFIG_X86) += x86/ +obj-$(CONFIG_ARCH_ZX) += zte/ obj-$(CONFIG_ARCH_ZYNQ) += zynq/drivers/clk/zte/Makefile new file +2
-0@@ -0,0 +1,2 @@ +obj-y := clk-pll.o +obj-$(CONFIG_SOC_ZX296702) += clk-zx296702.odrivers/clk/zte/clk-pll.c new file +180
-0@@ -0,0 +1,180 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/slab.h> +#include <linux/spinlock.h> + +#include "clk.h" + +#define to_clk_zx_pll (_hw) container_of(_hw, struct clk_zx_pll, hw) + +#define CFG0_CFG1_OFFSET 4 +#define LOCK_FLAG BIT(30) +#define POWER_DOWN BIT(31) + +static int rate_to_idx (struct clk_zx_pll *zx_pll,unsigned long rate) +{ +const struct zx_pll_config *config = zx_pll->lookup_table; +int i; + +for (i =0 ; i < zx_pll->count; i++) { +if (config[i].rate > rate) +return i >0 ? i -1 :0 ; + +if (config[i].rate == rate) +return i; + } + +return i -1 ; +} + +static int hw_to_idx (struct clk_zx_pll *zx_pll) +{ +const struct zx_pll_config *config = zx_pll->lookup_table; +u32 hw_cfg0, hw_cfg1; +int i; + + hw_cfg0 =readl_relaxed (zx_pll->reg_base); + hw_cfg1 =readl_relaxed (zx_pll->reg_base +CFG0_CFG1_OFFSET ); + +/* For matching the value in lookup table */ + hw_cfg0 &= ~LOCK_FLAG ; + hw_cfg0 |=POWER_DOWN ; + +for (i =0 ; i < zx_pll->count; i++) { +if (hw_cfg0 == config[i].cfg0 && hw_cfg1 == config[i].cfg1) +return i; + } + +return -1 ; +} + +static unsigned long zx_pll_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +struct clk_zx_pll *zx_pll =to_clk_zx_pll (hw); +int idx; + + idx =hw_to_idx (zx_pll); +if (unlikely (idx ==-1 )) +return 0 ; + +return zx_pll->lookup_table[idx].rate; +} + +static long zx_pll_round_rate (struct clk_hw *hw,unsigned long rate, +unsigned long *prate) +{ +struct clk_zx_pll *zx_pll =to_clk_zx_pll (hw); +int idx; + + idx =rate_to_idx (zx_pll, rate); + +return zx_pll->lookup_table[idx].rate; +} + +static int zx_pll_set_rate (struct clk_hw *hw,unsigned long rate, +unsigned long parent_rate) +{ +/* Assume current cpu is not running on current PLL */ +struct clk_zx_pll *zx_pll =to_clk_zx_pll (hw); +const struct zx_pll_config *config; +int idx; + + idx =rate_to_idx (zx_pll, rate); + config = &zx_pll->lookup_table[idx]; + +writel_relaxed (config->cfg0, zx_pll->reg_base); +writel_relaxed (config->cfg1, zx_pll->reg_base +CFG0_CFG1_OFFSET ); + +return 0 ; +} + +static int zx_pll_enable (struct clk_hw *hw) +{ +struct clk_zx_pll *zx_pll =to_clk_zx_pll (hw); +unsigned long timeout = jiffies +msecs_to_jiffies (500 ); +u32 reg; + + reg =readl_relaxed (zx_pll->reg_base); +writel_relaxed (reg & ~POWER_DOWN , zx_pll->reg_base); +while (!(readl_relaxed (zx_pll->reg_base) &LOCK_FLAG )) { +if (time_after (jiffies, timeout)) { +pr_err ("clk %s enable timeout\n" , +__clk_get_name (hw->clk)); +break ; + } + } + +return 0 ; +} + +static void zx_pll_disable (struct clk_hw *hw) +{ +struct clk_zx_pll *zx_pll =to_clk_zx_pll (hw); +u32 reg; + + reg =readl_relaxed (zx_pll->reg_base); +writel_relaxed (reg |POWER_DOWN , zx_pll->reg_base); +} + +static int zx_pll_is_enabled (struct clk_hw *hw) +{ +struct clk_zx_pll *zx_pll =to_clk_zx_pll (hw); +u32 reg; + + reg =readl_relaxed (zx_pll->reg_base); + +return !(reg &POWER_DOWN ); +} + +static const struct clk_ops zx_pll_ops = { + .recalc_rate = zx_pll_recalc_rate, + .round_rate = zx_pll_round_rate, + .set_rate = zx_pll_set_rate, + .enable = zx_pll_enable, + .disable = zx_pll_disable, + .is_enabled = zx_pll_is_enabled, +}; + +struct clk *clk_register_zx_pll (const char *name,const char *parent_name, +unsigned long flags,void __iomem *reg_base, +const struct zx_pll_config *lookup_table,int count,spinlock_t *lock) +{ +struct clk_zx_pll *zx_pll; +struct clk *clk; +struct clk_init_data init; + + zx_pll =kzalloc (sizeof (*zx_pll),GFP_KERNEL ); +if (!zx_pll) +return ERR_PTR (-ENOMEM ); + + init.name = name; + init.ops = &zx_pll_ops; + init.flags = flags; + init.parent_names = (parent_name ? &parent_name :NULL ); + init.num_parents = (parent_name ?1 :0 ); + + zx_pll->reg_base = reg_base; + zx_pll->lookup_table = lookup_table; + zx_pll->count = count; + zx_pll->lock = lock; + zx_pll->hw.init = &init; + + clk =clk_register (NULL , &zx_pll->hw); + +if (IS_ERR (clk)) +kfree (zx_pll); + +return clk; +}drivers/clk/zte/clk-zx296702.c new file +658
-0@@ -0,0 +1,658 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/of_address.h> +#include <dt-bindings/clock/zx296702-clock.h> +#include "clk.h" + +static DEFINE_SPINLOCK (reg_lock); + +static void __iomem *topcrm_base; +static void __iomem *lsp0crpm_base; +static void __iomem *lsp1crpm_base; + +static struct clk *topclk[ZX296702_TOPCLK_END ]; +static struct clk *lsp0clk[ZX296702_LSP0CLK_END ]; +static struct clk *lsp1clk[ZX296702_LSP1CLK_END ]; + +static struct clk_onecell_data topclk_data; +static struct clk_onecell_data lsp0clk_data; +static struct clk_onecell_data lsp1clk_data; + +#define CLK_MUX (topcrm_base + 0x04) +#define CLK_DIV (topcrm_base + 0x08) +#define CLK_EN0 (topcrm_base + 0x0c) +#define CLK_EN1 (topcrm_base + 0x10) +#define VOU_LOCAL_CLKEN (topcrm_base + 0x68) +#define VOU_LOCAL_CLKSEL (topcrm_base + 0x70) +#define VOU_LOCAL_DIV2_SET (topcrm_base + 0x74) +#define CLK_MUX1 (topcrm_base + 0x8c) + +#define CLK_SDMMC1 (lsp0crpm_base + 0x0c) + +#define CLK_UART0 (lsp1crpm_base + 0x20) +#define CLK_UART1 (lsp1crpm_base + 0x24) +#define CLK_SDMMC0 (lsp1crpm_base + 0x2c) + +static const struct zx_pll_config pll_a9_config[] = { + { .rate =700000000 , .cfg0 =0x800405d1 , .cfg1 =0x04555555 }, + { .rate =800000000 , .cfg0 =0x80040691 , .cfg1 =0x04aaaaaa }, + { .rate =900000000 , .cfg0 =0x80040791 , .cfg1 =0x04000000 }, + { .rate =1000000000 , .cfg0 =0x80040851 , .cfg1 =0x04555555 }, + { .rate =1100000000 , .cfg0 =0x80040911 , .cfg1 =0x04aaaaaa }, + { .rate =1200000000 , .cfg0 =0x80040a11 , .cfg1 =0x04000000 }, +}; + +static const struct clk_div_table main_hlk_div[] = { + { .val =1 , .div =2 , }, + { .val =3 , .div =4 , }, + {/* sentinel */ } +}; + +static const struct clk_div_table a9_as1_aclk_divider[] = { + { .val =0 , .div =1 , }, + { .val =1 , .div =2 , }, + { .val =3 , .div =4 , }, + {/* sentinel */ } +}; + +static const struct clk_div_table sec_wclk_divider[] = { + { .val =0 , .div =1 , }, + { .val =1 , .div =2 , }, + { .val =3 , .div =4 , }, + { .val =5 , .div =6 , }, + { .val =7 , .div =8 , }, + {/* sentinel */ } +}; + +static const char const *matrix_aclk_sel[] = { +"pll_mm0_198M" , +"osc" , +"clk_148M5" , +"pll_lsp_104M" , +}; + +static const char const *a9_wclk_sel[] = { +"pll_a9" , +"osc" , +"clk_500" , +"clk_250" , +}; + +static const char const *a9_as1_aclk_sel[] = { +"clk_250" , +"osc" , +"pll_mm0_396M" , +"pll_mac_333M" , +}; + +static const char const *a9_trace_clkin_sel[] = { +"clk_74M25" , +"pll_mm1_108M" , +"clk_125" , +"clk_148M5" , +}; + +static const char const *decppu_aclk_sel[] = { +"clk_250" , +"pll_mm0_198M" , +"pll_lsp_104M" , +"pll_audio_294M912" , +}; + +static const char const *vou_main_wclk_sel[] = { +"clk_148M5" , +"clk_74M25" , +"clk_27" , +"pll_mm1_54M" , +}; + +static const char const *vou_scaler_wclk_sel[] = { +"clk_250" , +"pll_mac_333M" , +"pll_audio_294M912" , +"pll_mm0_198M" , +}; + +static const char const *r2d_wclk_sel[] = { +"pll_audio_294M912" , +"pll_mac_333M" , +"pll_a9_350M" , +"pll_mm0_396M" , +}; + +static const char const *ddr_wclk_sel[] = { +"pll_mac_333M" , +"pll_ddr_266M" , +"pll_audio_294M912" , +"pll_mm0_198M" , +}; + +static const char const *nand_wclk_sel[] = { +"pll_lsp_104M" , +"osc" , +}; + +static const char const *lsp_26_wclk_sel[] = { +"pll_lsp_26M" , +"osc" , +}; + +static const char const *vl0_sel[] = { +"vou_main_channel_div" , +"vou_aux_channel_div" , +}; + +static const char const *hdmi_sel[] = { +"vou_main_channel_wclk" , +"vou_aux_channel_wclk" , +}; + +static const char const *sdmmc0_wclk_sel[] = { +"lsp1_104M_wclk" , +"lsp1_26M_wclk" , +}; + +static const char const *sdmmc1_wclk_sel[] = { +"lsp0_104M_wclk" , +"lsp0_26M_wclk" , +}; + +static const char const *uart_wclk_sel[] = { +"lsp1_104M_wclk" , +"lsp1_26M_wclk" , +}; + +static inline struct clk *zx_divtbl (const char *name,const char *parent, +void __iomem *reg,u8 shift,u8 width, +const struct clk_div_table *table) +{ +return clk_register_divider_table (NULL , name, parent,0 , reg, shift, + width,0 , table, ®_lock); +} + +static inline struct clk *zx_div (const char *name,const char *parent, +void __iomem *reg,u8 shift,u8 width) +{ +return clk_register_divider (NULL , name, parent,0 , + reg, shift, width,0 , ®_lock); +} + +static inline struct clk *zx_mux (const char *name,const char **parents, +int num_parents,void __iomem *reg,u8 shift,u8 width) +{ +return clk_register_mux (NULL , name, parents, num_parents, +0 , reg, shift, width,0 , ®_lock); +} + +static inline struct clk *zx_gate (const char *name,const char *parent, +void __iomem *reg,u8 shift) +{ +return clk_register_gate (NULL , name, parent,CLK_IGNORE_UNUSED , + reg, shift,0 , ®_lock); +} + +static void __init zx296702_top_clocks_init (struct device_node *np) +{ +struct clk **clk = topclk; +int i; + + topcrm_base =of_iomap (np,0 ); +WARN_ON (!topcrm_base); + + clk[ZX296702_OSC ] = +clk_register_fixed_rate (NULL ,"osc" ,NULL ,CLK_IS_ROOT , +30000000 ); + clk[ZX296702_PLL_A9 ] = +clk_register_zx_pll ("pll_a9" ,"osc" ,0 , topcrm_base + +0x01c , pll_a9_config, +ARRAY_SIZE (pll_a9_config), ®_lock); + +/* TODO: pll_a9_350M look like changeble follow a9 pll */ + clk[ZX296702_PLL_A9_350M ] = +clk_register_fixed_rate (NULL ,"pll_a9_350M" ,"osc" ,0 , +350000000 ); + clk[ZX296702_PLL_MAC_1000M ] = +clk_register_fixed_rate (NULL ,"pll_mac_1000M" ,"osc" ,0 , +1000000000 ); + clk[ZX296702_PLL_MAC_333M ] = +clk_register_fixed_rate (NULL ,"pll_mac_333M" ,"osc" ,0 , +333000000 ); + clk[ZX296702_PLL_MM0_1188M ] = +clk_register_fixed_rate (NULL ,"pll_mm0_1188M" ,"osc" ,0 , +1188000000 ); + clk[ZX296702_PLL_MM0_396M ] = +clk_register_fixed_rate (NULL ,"pll_mm0_396M" ,"osc" ,0 , +396000000 ); + clk[ZX296702_PLL_MM0_198M ] = +clk_register_fixed_rate (NULL ,"pll_mm0_198M" ,"osc" ,0 , +198000000 ); + clk[ZX296702_PLL_MM1_108M ] = +clk_register_fixed_rate (NULL ,"pll_mm1_108M" ,"osc" ,0 , +108000000 ); + clk[ZX296702_PLL_MM1_72M ] = +clk_register_fixed_rate (NULL ,"pll_mm1_72M" ,"osc" ,0 , +72000000 ); + clk[ZX296702_PLL_MM1_54M ] = +clk_register_fixed_rate (NULL ,"pll_mm1_54M" ,"osc" ,0 , +54000000 ); + clk[ZX296702_PLL_LSP_104M ] = +clk_register_fixed_rate (NULL ,"pll_lsp_104M" ,"osc" ,0 , +104000000 ); + clk[ZX296702_PLL_LSP_26M ] = +clk_register_fixed_rate (NULL ,"pll_lsp_26M" ,"osc" ,0 , +26000000 ); + clk[ZX296702_PLL_DDR_266M ] = +clk_register_fixed_rate (NULL ,"pll_ddr_266M" ,"osc" ,0 , +266000000 ); + clk[ZX296702_PLL_AUDIO_294M912 ] = +clk_register_fixed_rate (NULL ,"pll_audio_294M912" ,"osc" ,0 , +294912000 ); + +/* bus clock */ + clk[ZX296702_MATRIX_ACLK ] = +zx_mux ("matrix_aclk" , matrix_aclk_sel, +ARRAY_SIZE (matrix_aclk_sel),CLK_MUX ,2 ,2 ); + clk[ZX296702_MAIN_HCLK ] = +zx_divtbl ("main_hclk" ,"matrix_aclk" ,CLK_DIV ,0 ,2 , + main_hlk_div); + clk[ZX296702_MAIN_PCLK ] = +zx_divtbl ("main_pclk" ,"matrix_aclk" ,CLK_DIV ,2 ,2 , + main_hlk_div); + +/* cpu clock */ + clk[ZX296702_CLK_500 ] = +clk_register_fixed_factor (NULL ,"clk_500" ,"pll_mac_1000M" ,0 , +1 ,2 ); + clk[ZX296702_CLK_250 ] = +clk_register_fixed_factor (NULL ,"clk_250" ,"pll_mac_1000M" ,0 , +1 ,4 ); + clk[ZX296702_CLK_125 ] = +clk_register_fixed_factor (NULL ,"clk_125" ,"clk_250" ,0 ,1 ,2 ); + clk[ZX296702_CLK_148M5 ] = +clk_register_fixed_factor (NULL ,"clk_148M5" ,"pll_mm0_1188M" ,0 , +1 ,8 ); + clk[ZX296702_CLK_74M25 ] = +clk_register_fixed_factor (NULL ,"clk_74M25" ,"pll_mm0_1188M" ,0 , +1 ,16 ); + clk[ZX296702_A9_WCLK ] = +zx_mux ("a9_wclk" , a9_wclk_sel,ARRAY_SIZE (a9_wclk_sel),CLK_MUX , +0 ,2 ); + clk[ZX296702_A9_AS1_ACLK_MUX ] = +zx_mux ("a9_as1_aclk_mux" , a9_as1_aclk_sel, +ARRAY_SIZE (a9_as1_aclk_sel),CLK_MUX ,4 ,2 ); + clk[ZX296702_A9_TRACE_CLKIN_MUX ] = +zx_mux ("a9_trace_clkin_mux" , a9_trace_clkin_sel, +ARRAY_SIZE (a9_trace_clkin_sel),CLK_MUX1 ,0 ,2 ); + clk[ZX296702_A9_AS1_ACLK_DIV ] = +zx_divtbl ("a9_as1_aclk_div" ,"a9_as1_aclk_mux" ,CLK_DIV ,4 ,2 , + a9_as1_aclk_divider); + +/* multi-media clock */ + clk[ZX296702_CLK_2 ] = +clk_register_fixed_factor (NULL ,"clk_2" ,"pll_mm1_72M" ,0 , +1 ,36 ); + clk[ZX296702_CLK_27 ] = +clk_register_fixed_factor (NULL ,"clk_27" ,"pll_mm1_54M" ,0 , +1 ,2 ); + clk[ZX296702_DECPPU_ACLK_MUX ] = +zx_mux ("decppu_aclk_mux" , decppu_aclk_sel, +ARRAY_SIZE (decppu_aclk_sel),CLK_MUX ,6 ,2 ); + clk[ZX296702_PPU_ACLK_MUX ] = +zx_mux ("ppu_aclk_mux" , decppu_aclk_sel, +ARRAY_SIZE (decppu_aclk_sel),CLK_MUX ,8 ,2 ); + clk[ZX296702_MALI400_ACLK_MUX ] = +zx_mux ("mali400_aclk_mux" , decppu_aclk_sel, +ARRAY_SIZE (decppu_aclk_sel),CLK_MUX ,12 ,2 ); + clk[ZX296702_VOU_ACLK_MUX ] = +zx_mux ("vou_aclk_mux" , decppu_aclk_sel, +ARRAY_SIZE (decppu_aclk_sel),CLK_MUX ,10 ,2 ); + clk[ZX296702_VOU_MAIN_WCLK_MUX ] = +zx_mux ("vou_main_wclk_mux" , vou_main_wclk_sel, +ARRAY_SIZE (vou_main_wclk_sel),CLK_MUX ,14 ,2 ); + clk[ZX296702_VOU_AUX_WCLK_MUX ] = +zx_mux ("vou_aux_wclk_mux" , vou_main_wclk_sel, +ARRAY_SIZE (vou_main_wclk_sel),CLK_MUX ,16 ,2 ); + clk[ZX296702_VOU_SCALER_WCLK_MUX ] = +zx_mux ("vou_scaler_wclk_mux" , vou_scaler_wclk_sel, +ARRAY_SIZE (vou_scaler_wclk_sel),CLK_MUX , +18 ,2 ); + clk[ZX296702_R2D_ACLK_MUX ] = +zx_mux ("r2d_aclk_mux" , decppu_aclk_sel, +ARRAY_SIZE (decppu_aclk_sel),CLK_MUX ,20 ,2 ); + clk[ZX296702_R2D_WCLK_MUX ] = +zx_mux ("r2d_wclk_mux" , r2d_wclk_sel, +ARRAY_SIZE (r2d_wclk_sel),CLK_MUX ,22 ,2 ); + +/* other clock */ + clk[ZX296702_CLK_50 ] = +clk_register_fixed_factor (NULL ,"clk_50" ,"pll_mac_1000M" , +0 ,1 ,20 ); + clk[ZX296702_CLK_25 ] = +clk_register_fixed_factor (NULL ,"clk_25" ,"pll_mac_1000M" , +0 ,1 ,40 ); + clk[ZX296702_CLK_12 ] = +clk_register_fixed_factor (NULL ,"clk_12" ,"pll_mm1_72M" , +0 ,1 ,6 ); + clk[ZX296702_CLK_16M384 ] = +clk_register_fixed_factor (NULL ,"clk_16M384" , +"pll_audio_294M912" ,0 ,1 ,18 ); + clk[ZX296702_CLK_32K768 ] = +clk_register_fixed_factor (NULL ,"clk_32K768" ,"clk_16M384" , +0 ,1 ,500 ); + clk[ZX296702_SEC_WCLK_DIV ] = +zx_divtbl ("sec_wclk_div" ,"pll_lsp_104M" ,CLK_DIV ,6 ,3 , + sec_wclk_divider); + clk[ZX296702_DDR_WCLK_MUX ] = +zx_mux ("ddr_wclk_mux" , ddr_wclk_sel, +ARRAY_SIZE (ddr_wclk_sel),CLK_MUX ,24 ,2 ); + clk[ZX296702_NAND_WCLK_MUX ] = +zx_mux ("nand_wclk_mux" , nand_wclk_sel, +ARRAY_SIZE (nand_wclk_sel),CLK_MUX ,24 ,2 ); + clk[ZX296702_LSP_26_WCLK_MUX ] = +zx_mux ("lsp_26_wclk_mux" , lsp_26_wclk_sel, +ARRAY_SIZE (lsp_26_wclk_sel),CLK_MUX ,27 ,1 ); + +/* gates */ + clk[ZX296702_A9_AS0_ACLK ] = +zx_gate ("a9_as0_aclk" ,"matrix_aclk" ,CLK_EN0 ,0 ); + clk[ZX296702_A9_AS1_ACLK ] = +zx_gate ("a9_as1_aclk" ,"a9_as1_aclk_div" ,CLK_EN0 ,1 ); + clk[ZX296702_A9_TRACE_CLKIN ] = +zx_gate ("a9_trace_clkin" ,"a9_trace_clkin_mux" ,CLK_EN0 ,2 ); + clk[ZX296702_DECPPU_AXI_M_ACLK ] = +zx_gate ("decppu_axi_m_aclk" ,"decppu_aclk_mux" ,CLK_EN0 ,3 ); + clk[ZX296702_DECPPU_AHB_S_HCLK ] = +zx_gate ("decppu_ahb_s_hclk" ,"main_hclk" ,CLK_EN0 ,4 ); + clk[ZX296702_PPU_AXI_M_ACLK ] = +zx_gate ("ppu_axi_m_aclk" ,"ppu_aclk_mux" ,CLK_EN0 ,5 ); + clk[ZX296702_PPU_AHB_S_HCLK ] = +zx_gate ("ppu_ahb_s_hclk" ,"main_hclk" ,CLK_EN0 ,6 ); + clk[ZX296702_VOU_AXI_M_ACLK ] = +zx_gate ("vou_axi_m_aclk" ,"vou_aclk_mux" ,CLK_EN0 ,7 ); + clk[ZX296702_VOU_APB_PCLK ] = +zx_gate ("vou_apb_pclk" ,"main_pclk" ,CLK_EN0 ,8 ); + clk[ZX296702_VOU_MAIN_CHANNEL_WCLK ] = +zx_gate ("vou_main_channel_wclk" ,"vou_main_wclk_mux" , +CLK_EN0 ,9 ); + clk[ZX296702_VOU_AUX_CHANNEL_WCLK ] = +zx_gate ("vou_aux_channel_wclk" ,"vou_aux_wclk_mux" , +CLK_EN0 ,10 ); + clk[ZX296702_VOU_HDMI_OSCLK_CEC ] = +zx_gate ("vou_hdmi_osclk_cec" ,"clk_2" ,CLK_EN0 ,11 ); + clk[ZX296702_VOU_SCALER_WCLK ] = +zx_gate ("vou_scaler_wclk" ,"vou_scaler_wclk_mux" ,CLK_EN0 ,12 ); + clk[ZX296702_MALI400_AXI_M_ACLK ] = +zx_gate ("mali400_axi_m_aclk" ,"mali400_aclk_mux" ,CLK_EN0 ,13 ); + clk[ZX296702_MALI400_APB_PCLK ] = +zx_gate ("mali400_apb_pclk" ,"main_pclk" ,CLK_EN0 ,14 ); + clk[ZX296702_R2D_WCLK ] = +zx_gate ("r2d_wclk" ,"r2d_wclk_mux" ,CLK_EN0 ,15 ); + clk[ZX296702_R2D_AXI_M_ACLK ] = +zx_gate ("r2d_axi_m_aclk" ,"r2d_aclk_mux" ,CLK_EN0 ,16 ); + clk[ZX296702_R2D_AHB_HCLK ] = +zx_gate ("r2d_ahb_hclk" ,"main_hclk" ,CLK_EN0 ,17 ); + clk[ZX296702_DDR3_AXI_S0_ACLK ] = +zx_gate ("ddr3_axi_s0_aclk" ,"matrix_aclk" ,CLK_EN0 ,18 ); + clk[ZX296702_DDR3_APB_PCLK ] = +zx_gate ("ddr3_apb_pclk" ,"main_pclk" ,CLK_EN0 ,19 ); + clk[ZX296702_DDR3_WCLK ] = +zx_gate ("ddr3_wclk" ,"ddr_wclk_mux" ,CLK_EN0 ,20 ); + clk[ZX296702_USB20_0_AHB_HCLK ] = +zx_gate ("usb20_0_ahb_hclk" ,"main_hclk" ,CLK_EN0 ,21 ); + clk[ZX296702_USB20_0_EXTREFCLK ] = +zx_gate ("usb20_0_extrefclk" ,"clk_12" ,CLK_EN0 ,22 ); + clk[ZX296702_USB20_1_AHB_HCLK ] = +zx_gate ("usb20_1_ahb_hclk" ,"main_hclk" ,CLK_EN0 ,23 ); + clk[ZX296702_USB20_1_EXTREFCLK ] = +zx_gate ("usb20_1_extrefclk" ,"clk_12" ,CLK_EN0 ,24 ); + clk[ZX296702_USB20_2_AHB_HCLK ] = +zx_gate ("usb20_2_ahb_hclk" ,"main_hclk" ,CLK_EN0 ,25 ); + clk[ZX296702_USB20_2_EXTREFCLK ] = +zx_gate ("usb20_2_extrefclk" ,"clk_12" ,CLK_EN0 ,26 ); + clk[ZX296702_GMAC_AXI_M_ACLK ] = +zx_gate ("gmac_axi_m_aclk" ,"matrix_aclk" ,CLK_EN0 ,27 ); + clk[ZX296702_GMAC_APB_PCLK ] = +zx_gate ("gmac_apb_pclk" ,"main_pclk" ,CLK_EN0 ,28 ); + clk[ZX296702_GMAC_125_CLKIN ] = +zx_gate ("gmac_125_clkin" ,"clk_125" ,CLK_EN0 ,29 ); + clk[ZX296702_GMAC_RMII_CLKIN ] = +zx_gate ("gmac_rmii_clkin" ,"clk_50" ,CLK_EN0 ,30 ); + clk[ZX296702_GMAC_25M_CLK ] = +zx_gate ("gmac_25M_clk" ,"clk_25" ,CLK_EN0 ,31 ); + clk[ZX296702_NANDFLASH_AHB_HCLK ] = +zx_gate ("nandflash_ahb_hclk" ,"main_hclk" ,CLK_EN1 ,0 ); + clk[ZX296702_NANDFLASH_WCLK ] = +zx_gate ("nandflash_wclk" ,"nand_wclk_mux" ,CLK_EN1 ,1 ); + clk[ZX296702_LSP0_APB_PCLK ] = +zx_gate ("lsp0_apb_pclk" ,"main_pclk" ,CLK_EN1 ,2 ); + clk[ZX296702_LSP0_AHB_HCLK ] = +zx_gate ("lsp0_ahb_hclk" ,"main_hclk" ,CLK_EN1 ,3 ); + clk[ZX296702_LSP0_26M_WCLK ] = +zx_gate ("lsp0_26M_wclk" ,"lsp_26_wclk_mux" ,CLK_EN1 ,4 ); + clk[ZX296702_LSP0_104M_WCLK ] = +zx_gate ("lsp0_104M_wclk" ,"pll_lsp_104M" ,CLK_EN1 ,5 ); + clk[ZX296702_LSP0_16M384_WCLK ] = +zx_gate ("lsp0_16M384_wclk" ,"clk_16M384" ,CLK_EN1 ,6 ); + clk[ZX296702_LSP1_APB_PCLK ] = +zx_gate ("lsp1_apb_pclk" ,"main_pclk" ,CLK_EN1 ,7 ); +/* FIXME: wclk enable bit is bit8. We hack it as reserved 31 for +* UART does not work after parent clk is disabled/enabled */ + clk[ZX296702_LSP1_26M_WCLK ] = +zx_gate ("lsp1_26M_wclk" ,"lsp_26_wclk_mux" ,CLK_EN1 ,31 ); + clk[ZX296702_LSP1_104M_WCLK ] = +zx_gate ("lsp1_104M_wclk" ,"pll_lsp_104M" ,CLK_EN1 ,9 ); + clk[ZX296702_LSP1_32K_CLK ] = +zx_gate ("lsp1_32K_clk" ,"clk_32K768" ,CLK_EN1 ,10 ); + clk[ZX296702_AON_HCLK ] = +zx_gate ("aon_hclk" ,"main_hclk" ,CLK_EN1 ,11 ); + clk[ZX296702_SYS_CTRL_PCLK ] = +zx_gate ("sys_ctrl_pclk" ,"main_pclk" ,CLK_EN1 ,12 ); + clk[ZX296702_DMA_PCLK ] = +zx_gate ("dma_pclk" ,"main_pclk" ,CLK_EN1 ,13 ); + clk[ZX296702_DMA_ACLK ] = +zx_gate ("dma_aclk" ,"matrix_aclk" ,CLK_EN1 ,14 ); + clk[ZX296702_SEC_HCLK ] = +zx_gate ("sec_hclk" ,"main_hclk" ,CLK_EN1 ,15 ); + clk[ZX296702_AES_WCLK ] = +zx_gate ("aes_wclk" ,"sec_wclk_div" ,CLK_EN1 ,16 ); + clk[ZX296702_DES_WCLK ] = +zx_gate ("des_wclk" ,"sec_wclk_div" ,CLK_EN1 ,17 ); + clk[ZX296702_IRAM_ACLK ] = +zx_gate ("iram_aclk" ,"matrix_aclk" ,CLK_EN1 ,18 ); + clk[ZX296702_IROM_ACLK ] = +zx_gate ("irom_aclk" ,"matrix_aclk" ,CLK_EN1 ,19 ); + clk[ZX296702_BOOT_CTRL_HCLK ] = +zx_gate ("boot_ctrl_hclk" ,"main_hclk" ,CLK_EN1 ,20 ); + clk[ZX296702_EFUSE_CLK_30 ] = +zx_gate ("efuse_clk_30" ,"osc" ,CLK_EN1 ,21 ); + +/* TODO: add VOU Local clocks */ + clk[ZX296702_VOU_MAIN_CHANNEL_DIV ] = +zx_div ("vou_main_channel_div" ,"vou_main_channel_wclk" , +VOU_LOCAL_DIV2_SET ,1 ,1 ); + clk[ZX296702_VOU_AUX_CHANNEL_DIV ] = +zx_div ("vou_aux_channel_div" ,"vou_aux_channel_wclk" , +VOU_LOCAL_DIV2_SET ,0 ,1 ); + clk[ZX296702_VOU_TV_ENC_HD_DIV ] = +zx_div ("vou_tv_enc_hd_div" ,"vou_tv_enc_hd_mux" , +VOU_LOCAL_DIV2_SET ,3 ,1 ); + clk[ZX296702_VOU_TV_ENC_SD_DIV ] = +zx_div ("vou_tv_enc_sd_div" ,"vou_tv_enc_sd_mux" , +VOU_LOCAL_DIV2_SET ,2 ,1 ); + clk[ZX296702_VL0_MUX ] = +zx_mux ("vl0_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,8 ,1 ); + clk[ZX296702_VL1_MUX ] = +zx_mux ("vl1_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,9 ,1 ); + clk[ZX296702_VL2_MUX ] = +zx_mux ("vl2_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,10 ,1 ); + clk[ZX296702_GL0_MUX ] = +zx_mux ("gl0_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,5 ,1 ); + clk[ZX296702_GL1_MUX ] = +zx_mux ("gl1_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,6 ,1 ); + clk[ZX296702_GL2_MUX ] = +zx_mux ("gl2_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,7 ,1 ); + clk[ZX296702_WB_MUX ] = +zx_mux ("wb_mux" , vl0_sel,ARRAY_SIZE (vl0_sel), +VOU_LOCAL_CLKSEL ,11 ,1 ); + clk[ZX296702_HDMI_MUX ] = +zx_mux ("hdmi_mux" , hdmi_sel,ARRAY_SIZE (hdmi_sel), +VOU_LOCAL_CLKSEL ,4 ,1 ); + clk[ZX296702_VOU_TV_ENC_HD_MUX ] = +zx_mux ("vou_tv_enc_hd_mux" , hdmi_sel,ARRAY_SIZE (hdmi_sel), +VOU_LOCAL_CLKSEL ,3 ,1 ); + clk[ZX296702_VOU_TV_ENC_SD_MUX ] = +zx_mux ("vou_tv_enc_sd_mux" , hdmi_sel,ARRAY_SIZE (hdmi_sel), +VOU_LOCAL_CLKSEL ,2 ,1 ); + clk[ZX296702_VL0_CLK ] = +zx_gate ("vl0_clk" ,"vl0_mux" ,VOU_LOCAL_CLKEN ,8 ); + clk[ZX296702_VL1_CLK ] = +zx_gate ("vl1_clk" ,"vl1_mux" ,VOU_LOCAL_CLKEN ,9 ); + clk[ZX296702_VL2_CLK ] = +zx_gate ("vl2_clk" ,"vl2_mux" ,VOU_LOCAL_CLKEN ,10 ); + clk[ZX296702_GL0_CLK ] = +zx_gate ("gl0_clk" ,"gl0_mux" ,VOU_LOCAL_CLKEN ,5 ); + clk[ZX296702_GL1_CLK ] = +zx_gate ("gl1_clk" ,"gl1_mux" ,VOU_LOCAL_CLKEN ,6 ); + clk[ZX296702_GL2_CLK ] = +zx_gate ("gl2_clk" ,"gl2_mux" ,VOU_LOCAL_CLKEN ,7 ); + clk[ZX296702_WB_CLK ] = +zx_gate ("wb_clk" ,"wb_mux" ,VOU_LOCAL_CLKEN ,11 ); + clk[ZX296702_CL_CLK ] = +zx_gate ("cl_clk" ,"vou_main_channel_div" ,VOU_LOCAL_CLKEN ,12 ); + clk[ZX296702_MAIN_MIX_CLK ] = +zx_gate ("main_mix_clk" ,"vou_main_channel_div" , +VOU_LOCAL_CLKEN ,4 ); + clk[ZX296702_AUX_MIX_CLK ] = +zx_gate ("aux_mix_clk" ,"vou_aux_channel_div" , +VOU_LOCAL_CLKEN ,3 ); + clk[ZX296702_HDMI_CLK ] = +zx_gate ("hdmi_clk" ,"hdmi_mux" ,VOU_LOCAL_CLKEN ,2 ); + clk[ZX296702_VOU_TV_ENC_HD_DAC_CLK ] = +zx_gate ("vou_tv_enc_hd_dac_clk" ,"vou_tv_enc_hd_div" , +VOU_LOCAL_CLKEN ,1 ); + clk[ZX296702_VOU_TV_ENC_SD_DAC_CLK ] = +zx_gate ("vou_tv_enc_sd_dac_clk" ,"vou_tv_enc_sd_div" , +VOU_LOCAL_CLKEN ,0 ); + +/* CA9 PERIPHCLK = a9_wclk / 2 */ + clk[ZX296702_A9_PERIPHCLK ] = +clk_register_fixed_factor (NULL ,"a9_periphclk" ,"a9_wclk" , +0 ,1 ,2 ); + +for (i =0 ; i <ARRAY_SIZE (topclk); i++) { +if (IS_ERR (clk[i])) { +pr_err ("zx296702 clk %d: register failed with %ld\n" , + i,PTR_ERR (clk[i])); +return ; + } + } + + topclk_data.clks = topclk; + topclk_data.clk_num =ARRAY_SIZE (topclk); +of_clk_add_provider (np, of_clk_src_onecell_get, &topclk_data); +} +CLK_OF_DECLARE (zx296702_top_clk,"zte,zx296702-topcrm-clk" , + zx296702_top_clocks_init); + +static void __init zx296702_lsp0_clocks_init (struct device_node *np) +{ +struct clk **clk = lsp0clk; +int i; + + lsp0crpm_base =of_iomap (np,0 ); +WARN_ON (!lsp0crpm_base); + +/* SDMMC1 */ + clk[ZX296702_SDMMC1_WCLK_MUX ] = +zx_mux ("sdmmc1_wclk_mux" , sdmmc1_wclk_sel, +ARRAY_SIZE (sdmmc1_wclk_sel),CLK_SDMMC1 ,4 ,1 ); + clk[ZX296702_SDMMC1_WCLK_DIV ] = +zx_div ("sdmmc1_wclk_div" ,"sdmmc1_wclk_mux" ,CLK_SDMMC1 ,12 ,4 ); + clk[ZX296702_SDMMC1_WCLK ] = +zx_gate ("sdmmc1_wclk" ,"sdmmc1_wclk_div" ,CLK_SDMMC1 ,1 ); + clk[ZX296702_SDMMC1_PCLK ] = +zx_gate ("sdmmc1_pclk" ,"lsp1_apb_pclk" ,CLK_SDMMC1 ,0 ); + +for (i =0 ; i <ARRAY_SIZE (lsp0clk); i++) { +if (IS_ERR (clk[i])) { +pr_err ("zx296702 clk %d: register failed with %ld\n" , + i,PTR_ERR (clk[i])); +return ; + } + } + + lsp0clk_data.clks = lsp0clk; + lsp0clk_data.clk_num =ARRAY_SIZE (lsp0clk); +of_clk_add_provider (np, of_clk_src_onecell_get, &lsp0clk_data); +} +CLK_OF_DECLARE (zx296702_lsp0_clk,"zte,zx296702-lsp0crpm-clk" , + zx296702_lsp0_clocks_init); + +static void __init zx296702_lsp1_clocks_init (struct device_node *np) +{ +struct clk **clk = lsp1clk; +int i; + + lsp1crpm_base =of_iomap (np,0 ); +WARN_ON (!lsp1crpm_base); + +/* UART0 */ + clk[ZX296702_UART0_WCLK_MUX ] = +zx_mux ("uart0_wclk_mux" , uart_wclk_sel, +ARRAY_SIZE (uart_wclk_sel),CLK_UART0 ,4 ,1 ); +/* FIXME: uart wclk enable bit is bit1 in. We hack it as reserved 31 for +* UART does not work after parent clk is disabled/enabled */ + clk[ZX296702_UART0_WCLK ] = +zx_gate ("uart0_wclk" ,"uart0_wclk_mux" ,CLK_UART0 ,31 ); + clk[ZX296702_UART0_PCLK ] = +zx_gate ("uart0_pclk" ,"lsp1_apb_pclk" ,CLK_UART0 ,0 ); + +/* UART1 */ + clk[ZX296702_UART1_WCLK_MUX ] = +zx_mux ("uart1_wclk_mux" , uart_wclk_sel, +ARRAY_SIZE (uart_wclk_sel),CLK_UART1 ,4 ,1 ); + clk[ZX296702_UART1_WCLK ] = +zx_gate ("uart1_wclk" ,"uart1_wclk_mux" ,CLK_UART1 ,1 ); + clk[ZX296702_UART1_PCLK ] = +zx_gate ("uart1_pclk" ,"lsp1_apb_pclk" ,CLK_UART1 ,0 ); + +/* SDMMC0 */ + clk[ZX296702_SDMMC0_WCLK_MUX ] = +zx_mux ("sdmmc0_wclk_mux" , sdmmc0_wclk_sel, +ARRAY_SIZE (sdmmc0_wclk_sel),CLK_SDMMC0 ,4 ,1 ); + clk[ZX296702_SDMMC0_WCLK_DIV ] = +zx_div ("sdmmc0_wclk_div" ,"sdmmc0_wclk_mux" ,CLK_SDMMC0 ,12 ,4 ); + clk[ZX296702_SDMMC0_WCLK ] = +zx_gate ("sdmmc0_wclk" ,"sdmmc0_wclk_div" ,CLK_SDMMC0 ,1 ); + clk[ZX296702_SDMMC0_PCLK ] = +zx_gate ("sdmmc0_pclk" ,"lsp1_apb_pclk" ,CLK_SDMMC0 ,0 ); + +for (i =0 ; i <ARRAY_SIZE (lsp1clk); i++) { +if (IS_ERR (clk[i])) { +pr_err ("zx296702 clk %d: register failed with %ld\n" , + i,PTR_ERR (clk[i])); +return ; + } + } + + lsp1clk_data.clks = lsp1clk; + lsp1clk_data.clk_num =ARRAY_SIZE (lsp1clk); +of_clk_add_provider (np, of_clk_src_onecell_get, &lsp1clk_data); +} +CLK_OF_DECLARE (zx296702_lsp1_clk,"zte,zx296702-lsp1crpm-clk" , + zx296702_lsp1_clocks_init);drivers/clk/zte/clk.h new file +30
-0@@ -0,0 +1,30 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __ZTE_CLK_H +#define __ZTE_CLK_H + +struct zx_pll_config { +unsigned long rate; +u32 cfg0; +u32 cfg1; +}; + +struct clk_zx_pll { +struct clk_hw hw; +void __iomem *reg_base; +const struct zx_pll_config *lookup_table;/* order by rate asc */ +int count; +spinlock_t *lock; +}; + +struct clk *clk_register_zx_pll (const char *name,const char *parent_name, +unsigned long flags,void __iomem *reg_base, +const struct zx_pll_config *lookup_table,int count,spinlock_t *lock); +#endif include/dt-bindings/clock/zx296702-clock.h new file +162
-1@@ -0,0 +1,162 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __DT_BINDINGS_CLOCK_ZX296702_H +#define __DT_BINDINGS_CLOCK_ZX296702_H + +#define ZX296702_OSC 0 +#define ZX296702_PLL_A9 1 +#define ZX296702_PLL_A9_350M 2 +#define ZX296702_PLL_MAC_1000M 3 +#define ZX296702_PLL_MAC_333M 4 +#define ZX296702_PLL_MM0_1188M 5 +#define ZX296702_PLL_MM0_396M 6 +#define ZX296702_PLL_MM0_198M 7 +#define ZX296702_PLL_MM1_108M 8 +#define ZX296702_PLL_MM1_72M 9 +#define ZX296702_PLL_MM1_54M 10 +#define ZX296702_PLL_LSP_104M 11 +#define ZX296702_PLL_LSP_26M 12 +#define ZX296702_PLL_AUDIO_294M912 13 +#define ZX296702_PLL_DDR_266M 14 +#define ZX296702_CLK_148M5 15 +#define ZX296702_MATRIX_ACLK 16 +#define ZX296702_MAIN_HCLK 17 +#define ZX296702_MAIN_PCLK 18 +#define ZX296702_CLK_500 19 +#define ZX296702_CLK_250 20 +#define ZX296702_CLK_125 21 +#define ZX296702_CLK_74M25 22 +#define ZX296702_A9_WCLK 23 +#define ZX296702_A9_AS1_ACLK_MUX 24 +#define ZX296702_A9_TRACE_CLKIN_MUX 25 +#define ZX296702_A9_AS1_ACLK_DIV 26 +#define ZX296702_CLK_2 27 +#define ZX296702_CLK_27 28 +#define ZX296702_DECPPU_ACLK_MUX 29 +#define ZX296702_PPU_ACLK_MUX 30 +#define ZX296702_MALI400_ACLK_MUX 31 +#define ZX296702_VOU_ACLK_MUX 32 +#define ZX296702_VOU_MAIN_WCLK_MUX 33 +#define ZX296702_VOU_AUX_WCLK_MUX 34 +#define ZX296702_VOU_SCALER_WCLK_MUX 35 +#define ZX296702_R2D_ACLK_MUX 36 +#define ZX296702_R2D_WCLK_MUX 37 +#define ZX296702_CLK_50 38 +#define ZX296702_CLK_25 39 +#define ZX296702_CLK_12 40 +#define ZX296702_CLK_16M384 41 +#define ZX296702_CLK_32K768 42 +#define ZX296702_SEC_WCLK_DIV 43 +#define ZX296702_DDR_WCLK_MUX 44 +#define ZX296702_NAND_WCLK_MUX 45 +#define ZX296702_LSP_26_WCLK_MUX 46 +#define ZX296702_A9_AS0_ACLK 47 +#define ZX296702_A9_AS1_ACLK 48 +#define ZX296702_A9_TRACE_CLKIN 49 +#define ZX296702_DECPPU_AXI_M_ACLK 50 +#define ZX296702_DECPPU_AHB_S_HCLK 51 +#define ZX296702_PPU_AXI_M_ACLK 52 +#define ZX296702_PPU_AHB_S_HCLK 53 +#define ZX296702_VOU_AXI_M_ACLK 54 +#define ZX296702_VOU_APB_PCLK 55 +#define ZX296702_VOU_MAIN_CHANNEL_WCLK 56 +#define ZX296702_VOU_AUX_CHANNEL_WCLK 57 +#define ZX296702_VOU_HDMI_OSCLK_CEC 58 +#define ZX296702_VOU_SCALER_WCLK 59 +#define ZX296702_MALI400_AXI_M_ACLK 60 +#define ZX296702_MALI400_APB_PCLK 61 +#define ZX296702_R2D_WCLK 62 +#define ZX296702_R2D_AXI_M_ACLK 63 +#define ZX296702_R2D_AHB_HCLK 64 +#define ZX296702_DDR3_AXI_S0_ACLK 65 +#define ZX296702_DDR3_APB_PCLK 66 +#define ZX296702_DDR3_WCLK 67 +#define ZX296702_USB20_0_AHB_HCLK 68 +#define ZX296702_USB20_0_EXTREFCLK 69 +#define ZX296702_USB20_1_AHB_HCLK 70 +#define ZX296702_USB20_1_EXTREFCLK 71 +#define ZX296702_USB20_2_AHB_HCLK 72 +#define ZX296702_USB20_2_EXTREFCLK 73 +#define ZX296702_GMAC_AXI_M_ACLK 74 +#define ZX296702_GMAC_APB_PCLK 75 +#define ZX296702_GMAC_125_CLKIN 76 +#define ZX296702_GMAC_RMII_CLKIN 77 +#define ZX296702_GMAC_25M_CLK 78 +#define ZX296702_NANDFLASH_AHB_HCLK 79 +#define ZX296702_NANDFLASH_WCLK 80 +#define ZX296702_LSP0_APB_PCLK 81 +#define ZX296702_LSP0_AHB_HCLK 82 +#define ZX296702_LSP0_26M_WCLK 83 +#define ZX296702_LSP0_104M_WCLK 84 +#define ZX296702_LSP0_16M384_WCLK 85 +#define ZX296702_LSP1_APB_PCLK 86 +#define ZX296702_LSP1_26M_WCLK 87 +#define ZX296702_LSP1_104M_WCLK 88 +#define ZX296702_LSP1_32K_CLK 89 +#define ZX296702_AON_HCLK 90 +#define ZX296702_SYS_CTRL_PCLK 91 +#define ZX296702_DMA_PCLK 92 +#define ZX296702_DMA_ACLK 93 +#define ZX296702_SEC_HCLK 94 +#define ZX296702_AES_WCLK 95 +#define ZX296702_DES_WCLK 96 +#define ZX296702_IRAM_ACLK 97 +#define ZX296702_IROM_ACLK 98 +#define ZX296702_BOOT_CTRL_HCLK 99 +#define ZX296702_EFUSE_CLK_30 100 +#define ZX296702_VOU_MAIN_CHANNEL_DIV 101 +#define ZX296702_VOU_AUX_CHANNEL_DIV 102 +#define ZX296702_VOU_TV_ENC_HD_DIV 103 +#define ZX296702_VOU_TV_ENC_SD_DIV 104 +#define ZX296702_VL0_MUX 105 +#define ZX296702_VL1_MUX 106 +#define ZX296702_VL2_MUX 107 +#define ZX296702_GL0_MUX 108 +#define ZX296702_GL1_MUX 109 +#define ZX296702_GL2_MUX 110 +#define ZX296702_WB_MUX 111 +#define ZX296702_HDMI_MUX 112 +#define ZX296702_VOU_TV_ENC_HD_MUX 113 +#define ZX296702_VOU_TV_ENC_SD_MUX 114 +#define ZX296702_VL0_CLK 115 +#define ZX296702_VL1_CLK 116 +#define ZX296702_VL2_CLK 117 +#define ZX296702_GL0_CLK 118 +#define ZX296702_GL1_CLK 119 +#define ZX296702_GL2_CLK 120 +#define ZX296702_WB_CLK 121 +#define ZX296702_CL_CLK 122 +#define ZX296702_MAIN_MIX_CLK 123 +#define ZX296702_AUX_MIX_CLK 124 +#define ZX296702_HDMI_CLK 125 +#define ZX296702_VOU_TV_ENC_HD_DAC_CLK 126 +#define ZX296702_VOU_TV_ENC_SD_DAC_CLK 127 +#define ZX296702_A9_PERIPHCLK 128 +#define ZX296702_TOPCLK_END 129 + +#define ZX296702_SDMMC1_WCLK_MUX 0 +#define ZX296702_SDMMC1_WCLK_DIV 1 +#define ZX296702_SDMMC1_WCLK 2 +#define ZX296702_SDMMC1_PCLK 3 +#define ZX296702_LSP0CLK_END 4 + +#define ZX296702_UART0_WCLK_MUX 0 +#define ZX296702_UART0_WCLK 1 +#define ZX296702_UART0_PCLK 2 +#define ZX296702_UART1_WCLK_MUX 3 +#define ZX296702_UART1_WCLK 4 +#define ZX296702_UART1_PCLK 5 +#define ZX296702_SDMMC0_WCLK_MUX 6 +#define ZX296702_SDMMC0_WCLK_DIV 7 +#define ZX296702_SDMMC0_WCLK 8 +#define ZX296702_SDMMC0_PCLK 9 +#define ZX296702_LSP1CLK_END 10 + +#endif /* __DT_BINDINGS_CLOCK_ZX296702_H */ --1.9.1
PATCH v4 5/7 clk: zx: add clock support to zx296702
In reply to Jun NieQuoted 10 lines · Jun Nie
2015-04-28 17:18 GMT+08:00 Jun Nie <[email protected]>:
Quoted 5 lines
It adds a clock driver for zx296702 SoC to register the clock tree to Common Clock Framework. All the clocks of bus topology and some the peripheral clocks are ready with this commit. Some missing leaf clocks for peripherals will be added later when needed.
Mike & Stephen,
Could you help review and ack this patch? So that this patch set can be merged together in Arnd side.
A bit late, but here it goes!
Quoted 9 lines
Quoted 9 lines
drivers/clk/zte/clk-pll.c new file +3
-0@@ -0,0 +1,180 @@ + +static int zx_pll_enable (struct clk_hw *hw) +{
Quoted 8 lines
drivers/clk/zte/clk-pll.c line 112
Quoted 8 lines
drivers/clk/zte/clk-pll.c new file +8
-0+struct clk_zx_pll *zx_pll =to_clk_zx_pll (hw); +unsigned long timeout = jiffies +msecs_to_jiffies (500 ); +u32 reg; + + reg =readl_relaxed (zx_pll->reg_base); +writel_relaxed (reg & ~POWER_DOWN , zx_pll->reg_base); +while (!(readl_relaxed (zx_pll->reg_base) &LOCK_FLAG )) { +if (time_after (jiffies, timeout)) {
How does this work? zx_pll_enable() will be called with interrupts disabled so it's possible that jiffies will never increment while we're inside this loop. For polling bits we have iopoll.h now, so maybe you can use that?
Quoted 9 lines
Quoted 9 lines
drivers/clk/zte/clk-pll.c new file +9
-0+pr_err ("clk %s enable timeout\n" , +__clk_get_name (hw->clk)); +break ; + } + } + +return 0 ; +} +
[..]
Quoted 9 lines
Quoted 9 lines
drivers/clk/zte/clk-pll.c new file +9
-0+struct clk *clk_register_zx_pll (const char *name,const char *parent_name, +unsigned long flags,void __iomem *reg_base, +const struct zx_pll_config *lookup_table,int count,spinlock_t *lock) +{ +struct clk_zx_pll *zx_pll; +struct clk *clk; +struct clk_init_data init; + + zx_pll =kzalloc (sizeof (*zx_pll),GFP_KERNEL );
Quoted 8 lines
drivers/clk/zte/clk-pll.c line 166
Quoted 8 lines
drivers/clk/zte/clk-pll.c new file +8
-0+if (!zx_pll) +return ERR_PTR (-ENOMEM ); + + init.name = name; + init.ops = &zx_pll_ops; + init.flags = flags; + init.parent_names = (parent_name ? &parent_name :NULL ); + init.num_parents = (parent_name ?1 :0 );
Useless parentheses.
Quoted 10 lines
drivers/clk/zte/clk-pll.c line 176
Quoted 10 lines
drivers/clk/zte/clk-pll.c new file +10
-0+ + zx_pll->reg_base = reg_base; + zx_pll->lookup_table = lookup_table; + zx_pll->count = count; + zx_pll->lock = lock; + zx_pll->hw.init = &init; + + clk =clk_register (NULL , &zx_pll->hw); + +if (IS_ERR (clk))
Why the extra newline?
Quoted 12 lines
Quoted 12 lines
drivers/clk/zte/clk-pll.c new file +4
-0+kfree (zx_pll); + +return clk; +}drivers/clk/zte/clk-zx296702.c new file +2
-0@@ -0,0 +1,658 @@ +/* +* Copyright 2014 Linaro Ltd.
Quoted 8 lines
drivers/clk/zte/clk-zx296702.c line 10
Quoted 8 lines
drivers/clk/zte/clk-zx296702.c new file +8
-0+* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/clk.h>
Do you need this include? Applies to all files in this patch.
Quoted 86 lines
Quoted 86 lines
drivers/clk/zte/clk-zx296702.c new file +86
-0+#include <linux/clk-provider.h> +#include <linux/of_address.h> +#include <dt-bindings/clock/zx296702-clock.h> +#include "clk.h" + +static DEFINE_SPINLOCK (reg_lock); + +static void __iomem *topcrm_base; +static void __iomem *lsp0crpm_base; +static void __iomem *lsp1crpm_base; + +static struct clk *topclk[ZX296702_TOPCLK_END ]; +static struct clk *lsp0clk[ZX296702_LSP0CLK_END ]; +static struct clk *lsp1clk[ZX296702_LSP1CLK_END ]; + +static struct clk_onecell_data topclk_data; +static struct clk_onecell_data lsp0clk_data; +static struct clk_onecell_data lsp1clk_data; + +#define CLK_MUX (topcrm_base + 0x04) +#define CLK_DIV (topcrm_base + 0x08) +#define CLK_EN0 (topcrm_base + 0x0c) +#define CLK_EN1 (topcrm_base + 0x10) +#define VOU_LOCAL_CLKEN (topcrm_base + 0x68) +#define VOU_LOCAL_CLKSEL (topcrm_base + 0x70) +#define VOU_LOCAL_DIV2_SET (topcrm_base + 0x74) +#define CLK_MUX1 (topcrm_base + 0x8c) + +#define CLK_SDMMC1 (lsp0crpm_base + 0x0c) + +#define CLK_UART0 (lsp1crpm_base + 0x20) +#define CLK_UART1 (lsp1crpm_base + 0x24) +#define CLK_SDMMC0 (lsp1crpm_base + 0x2c) + +static const struct zx_pll_config pll_a9_config[] = { + { .rate =700000000 , .cfg0 =0x800405d1 , .cfg1 =0x04555555 }, + { .rate =800000000 , .cfg0 =0x80040691 , .cfg1 =0x04aaaaaa }, + { .rate =900000000 , .cfg0 =0x80040791 , .cfg1 =0x04000000 }, + { .rate =1000000000 , .cfg0 =0x80040851 , .cfg1 =0x04555555 }, + { .rate =1100000000 , .cfg0 =0x80040911 , .cfg1 =0x04aaaaaa }, + { .rate =1200000000 , .cfg0 =0x80040a11 , .cfg1 =0x04000000 }, +}; + +static const struct clk_div_table main_hlk_div[] = { + { .val =1 , .div =2 , }, + { .val =3 , .div =4 , }, + {/* sentinel */ } +}; + +static const struct clk_div_table a9_as1_aclk_divider[] = { + { .val =0 , .div =1 , }, + { .val =1 , .div =2 , }, + { .val =3 , .div =4 , }, + {/* sentinel */ } +}; + +static const struct clk_div_table sec_wclk_divider[] = { + { .val =0 , .div =1 , }, + { .val =1 , .div =2 , }, + { .val =3 , .div =4 , }, + { .val =5 , .div =6 , }, + { .val =7 , .div =8 , }, + {/* sentinel */ } +}; + +static const char const *matrix_aclk_sel[] = { +"pll_mm0_198M" , +"osc" , +"clk_148M5" , +"pll_lsp_104M" , +}; + +static const char const *a9_wclk_sel[] = { +"pll_a9" , +"osc" , +"clk_500" , +"clk_250" , +}; + +static const char const *a9_as1_aclk_sel[] = { +"clk_250" , +"osc" , +"pll_mm0_396M" , +"pll_mac_333M" , +}; +
Quoted 8 lines
drivers/clk/zte/clk-zx296702.c line 104
Quoted 8 lines
drivers/clk/zte/clk-zx296702.c new file +8
-0+static const char const *a9_trace_clkin_sel[] = { +"clk_74M25" , +"pll_mm1_108M" , +"clk_125" , +"clk_148M5" , +}; + +static const char const *decppu_aclk_sel[] = {
const char const doesn't make any sense. Did you mean const char
* const instead? If so, you'll need the patch in clk-next that
* allows that to work.
Quoted 9 lines
Quoted 9 lines
drivers/clk/zte/clk-zx296702.c new file +9
-0+"clk_250" , +"pll_mm0_198M" , +"pll_lsp_104M" , + "pll_audio_294M912", +}; + +static const char const *vou_main_wclk_sel[] = { +"clk_148M5" , + "clk_74M25",
[..]
Quoted 9 lines
Quoted 9 lines
drivers/clk/zte/clk.h new file +3
-0@@ -0,0 +1,30 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation.
Quoted 8 lines
drivers/clk/zte/clk.h line 11
Quoted 8 lines
drivers/clk/zte/clk.h new file +8
-0+* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __ZTE_CLK_H +#define __ZTE_CLK_H
#include <linux/clk-provider.h> for clk_hw usage?
#include <linux/spinlock.h> for spinlock_t usage?
Quoted 19 lines
Quoted 19 lines
drivers/clk/zte/clk.h new file +19
-0+ +struct zx_pll_config { +unsigned long rate; +u32 cfg0; +u32 cfg1; +}; + +struct clk_zx_pll { +struct clk_hw hw; +void __iomem *reg_base; +const struct zx_pll_config *lookup_table;/* order by rate asc */ +int count; +spinlock_t *lock; +}; + +struct clk *clk_register_zx_pll (const char *name,const char *parent_name, +unsigned long flags,void __iomem *reg_base, +const struct zx_pll_config *lookup_table,int count,spinlock_t *lock); +#endif
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH v4 6/7 ARM: zx: enable SMP and hotplug for zx296702
In reply to Jun NieBring up the secondary core. Enable hotplug with supporting powering off secondary core.
--- arch/arm/mach-zx/Makefile | 1 + arch/arm/mach-zx/core.h | 19 +++++ arch/arm/mach-zx/headsmp.S | 32 ++++++++ arch/arm/mach-zx/platsmp.c | 189 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 241 insertions(+) create mode 100644 arch/arm/mach-zx/core.h create mode 100644 arch/arm/mach-zx/headsmp.S create mode 100644 arch/arm/mach-zx/platsmp.c
arch/arm/mach-zx/Makefile +1 -0
@@ -1 +1,2 @@ obj-$(CONFIG_SOC_ZX296702) += zx296702.o +obj-$(CONFIG_SMP) += headsmp.o platsmp.o
arch/arm/mach-zx/core.h new file +19 -0
@@ -0,0 +1,19 @@ +/* +* Copyright 2014 Linaro Ltd. +* Copyright (C) 2014 ZTE Corporation. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __MACH_ZX_CORE_H +#define __MACH_ZX_CORE_H + +extern void zx_resume_jump (void ); +extern size_t zx_suspend_iram_sz; +extern unsigned long zx_secondary_startup_pa; + +void zx_secondary_startup (void ); + +#endif /* __MACH_ZX_CORE_H */
arch/arm/mach-zx/headsmp.S new file +32 -0
@@ -0,0 +1,32 @@ +/* + * Copyright 2014 Linaro Ltd. + * Copyright (C) 2014 ZTE Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> + + .align 3 + +/* It runs from physical address */ +ENTRY(zx_resume_jump) + adr r1, zx_secondary_startup_pa + ldr r0, [r1] + bx r0 +ENDPROC(zx_resume_jump) + +ENTRY(zx_secondary_startup_pa) + .word zx_secondary_startup_pa + +ENTRY(zx_suspend_iram_sz) + .word . - zx_resume_jump +ENDPROC(zx_secondary_startup_pa) + + +ENTRY(zx_secondary_startup) + bl v7_invalidate_l1 + b secondary_startup +ENDPROC(zx_secondary_startup)
arch/arm/mach-zx/platsmp.c new file +189 -0
189 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v4 7/7 ARM: zx: Add basic defconfig support for ZX296702
In reply to Jun NieAdd basic defconfig support to zx SOC, including uart, mmc
and other common config
--- arch/arm/configs/zx_defconfig | 130 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 arch/arm/configs/zx_defconfig
arch/arm/configs/zx_defconfig new file +130 -0
@@ -0,0 +1,130 @@ +CONFIG_EXPERIMENTAL=y +CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +CONFIG_CGROUP_DEBUG=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="initramfs.cpio.gz" +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +CONFIG_PERF_EVENTS=y +CONFIG_SLAB=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_ARCH_ZX=y +CONFIG_SOC_ZX296702=y +# CONFIG_SWP_EMULATE is not set +CONFIG_ARM_ERRATA_754322=y +CONFIG_ARM_ERRATA_775420=y +CONFIG_SMP=y +CONFIG_VMSPLIT_2G=y +CONFIG_PREEMPT=y +CONFIG_AEABI=y +CONFIG_KSM=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_KERNEL_MODE_NEON=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HIBERNATION=y +CONFIG_PM_RUNTIME=y +CONFIG_PM_DEBUG=y +CONFIG_SUSPEND_TIME=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyAMA0,115200 debug earlyprintk root=/dev/ram rw rootwait" +#CONFIG_NET is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=192 +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_UID_STAT=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_UEVENT=y +CONFIG_DM_VERITY=y +CONFIG_NETDEVICES=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_SERIO=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SPI=y +CONFIG_LOGO=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_CONSOLE_POLL=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_MMC=y +CONFIG_MMC_UNSAFE_RESUME=y +CONFIG_MMC_BLOCK_MINORS=16 +CONFIG_MMC_DW=y +CONFIG_MMC_DW_IDMAC=y +CONFIG_EXT2_FS=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_DEBUG=y +CONFIG_FUSE_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=936 +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +#CONFIG_NFS_FS is not set +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y +CONFIG_PRINTK_TIME=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_INFO=y +CONFIG_FRAME_WARN=4096 +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_PANIC_TIMEOUT=5 +# CONFIG_SCHED_DEBUG is not set +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +CONFIG_DEBUG_RT_MUTEXES=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_FTRACE is not set +CONFIG_KGDB=y +CONFIG_KGDB_KDB=y +# CONFIG_ARM_UNWIND is not set +CONFIG_DEBUG_PREEMPT=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_LL=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_STACKTRACE=y +CONFIG_DEBUG_ZTE_ZX=y +CONFIG_EARLY_PRINTK=y +CONFIG_CRYPTO_LZO=y +CONFIG_GPIOLIB=y
Signature · 1 line
1.9.1
Arnd Bergmann
maintainerPATCH v4 7/7 ARM: zx: Add basic defconfig support for ZX296702
Quoted 5 lines · On Tuesday 28 April 2015 17:18:11 Jun Nie wrote:
Add basic defconfig support to zx SOC, including uart, mmc
and other common configSigned-off-by Jun Nie <[email protected]>
Applied to next/defconfig. Please follow up with a patch to enable this platform in multi_v7_defconfig as well. You should enable all drivers for devices that are used on this platform, but preferrably use =m instead of =y in the multi_v7_defconfig (in zx_defconfig, it's up to your personal preference).
Thanks,
Arnd
v4 cover Basic support to ZTE ZX296702
In reply to Jun NieQuoted 1 line · Jun Nie
Rebase patches of v2 to 4.0-rc1. Ready for merge.
Hi Arnd,
Do you see any issue in this patch set? Or could you help drive merge? Thank you very much!
Jun
Quoted 54 lines
Change in v4 vs v3: Fix minor defconfig issue.
Jun Nie (7):
ARM: zx: add basic support for ZTE ZX296702
MAINTAINERS: add entry for ARM ZTE architecture
ARM: zx: add low level debug support for zx296702
ARM: dts: zx: add an initial zx296702 dts and doc
clk: zx: add clock support to zx296702
ARM: zx: enable SMP and hotplug for zx296702
ARM: zx: Add basic defconfig support for ZX296702Documentation/devicetree/bindings/arm/zte.txt | 15 + .../devicetree/bindings/clock/zx296702-clk.txt | 35 ++ Documentation/devicetree/bindings/serial/pl011.txt | 2 +- .../devicetree/bindings/vendor-prefixes.txt | 1 + MAINTAINERS | 9 + arch/arm/Kconfig | 2 + arch/arm/Kconfig.debug | 14 + arch/arm/Makefile | 1 + arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/zx296702-ad1.dts | 48 ++ arch/arm/boot/dts/zx296702.dtsi | 139 +++++ arch/arm/configs/zx_defconfig | 130 ++++ arch/arm/include/debug/pl01x.S | 7 + arch/arm/mach-zx/Kconfig | 18 + arch/arm/mach-zx/Makefile | 2 + arch/arm/mach-zx/core.h | 19 + arch/arm/mach-zx/headsmp.S | 32 + arch/arm/mach-zx/platsmp.c | 189 ++++++ arch/arm/mach-zx/zx296702.c | 31 + drivers/clk/Makefile | 1 + drivers/clk/zte/Makefile | 2 + drivers/clk/zte/clk-pll.c | 180 ++++++ drivers/clk/zte/clk-zx296702.c | 658 +++++++++++++++++++++ drivers/clk/zte/clk.h | 30 + include/dt-bindings/clock/zx296702-clock.h | 162 +++++ 25 files changed, 1727 insertions(+), 1 deletion(-)create mode 100644
Documentation/devicetree/bindings/arm/zte.txtcreate mode 100644Documentation/devicetree/bindings/clock/zx296702-clk.txtcreate mode 100644arch/arm/boot/dts/zx296702-ad1.dts
create mode 100644arch/arm/boot/dts/zx296702.dtsi
create mode 100644arch/arm/configs/zx_defconfig
create mode 100644arch/arm/mach-zx/Kconfig
create mode 100644arch/arm/mach-zx/Makefile
create mode 100644arch/arm/mach-zx/core.h
create mode 100644arch/arm/mach-zx/headsmp.S
create mode 100644arch/arm/mach-zx/platsmp.c
create mode 100644arch/arm/mach-zx/zx296702.c
create mode 100644drivers/clk/zte/Makefile
create mode 100644drivers/clk/zte/clk-pll.c
create mode 100644drivers/clk/zte/clk-zx296702.c
create mode 100644drivers/clk/zte/clk.h
create mode 100644include/dt-bindings/clock/zx296702-clock.h