diff options
author | Stephen Boyd <sboyd@codeaurora.org> | 2015-10-21 20:28:19 -0400 |
---|---|---|
committer | Stephen Boyd <sboyd@codeaurora.org> | 2015-10-21 20:28:19 -0400 |
commit | f63d19ef52aa66e97fca2425974845177ce02b0a (patch) | |
tree | 53ec668d90828b5a4144ef445df347e6fea19ae5 | |
parent | 938ce30e29dcb8ca0b1bf375305485ed17f40062 (diff) | |
parent | 0064c862340626400a56d72e5e86f01ef0d5a498 (diff) |
Merge branch 'clk-iproc' into clk-next
* clk-iproc:
clk: iproc: define Broadcom NS2 iProc clock binding
clk: iproc: define Broadcom NSP iProc clock binding
clk: ns2: add clock support for Broadcom Northstar 2 SoC
clk: iproc: Separate status and control variables
clk: iproc: Split off dig_filter
clk: iproc: Add PLL base write function
clk: nsp: add clock support for Broadcom Northstar Plus SoC
clk: iproc: Add PWRCTRL support
clk: cygnus: Convert all macros to all caps
ARM: cygnus: fix link failures when CONFIG_COMMON_CLK_IPROC is disabled
-rw-r--r-- | Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt | 78 | ||||
-rw-r--r-- | arch/arm/mach-bcm/Kconfig | 2 | ||||
-rw-r--r-- | drivers/clk/Makefile | 2 | ||||
-rw-r--r-- | drivers/clk/bcm/Kconfig | 4 | ||||
-rw-r--r-- | drivers/clk/bcm/Makefile | 3 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-cygnus.c | 155 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-iproc-pll.c | 183 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-iproc.h | 22 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-ns2.c | 288 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-nsp.c | 139 | ||||
-rw-r--r-- | include/dt-bindings/clock/bcm-ns2.h | 72 | ||||
-rw-r--r-- | include/dt-bindings/clock/bcm-nsp.h | 51 |
12 files changed, 840 insertions, 159 deletions
diff --git a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt index da8d9bb5751c..ede65a55e21b 100644 --- a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt +++ b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt | |||
@@ -130,3 +130,81 @@ These clock IDs are defined in: | |||
130 | ch3_unused mipipll 4 BCM_CYGNUS_MIPIPLL_CH3_UNUSED | 130 | ch3_unused mipipll 4 BCM_CYGNUS_MIPIPLL_CH3_UNUSED |
131 | ch4_unused mipipll 5 BCM_CYGNUS_MIPIPLL_CH4_UNUSED | 131 | ch4_unused mipipll 5 BCM_CYGNUS_MIPIPLL_CH4_UNUSED |
132 | ch5_unused mipipll 6 BCM_CYGNUS_MIPIPLL_CH5_UNUSED | 132 | ch5_unused mipipll 6 BCM_CYGNUS_MIPIPLL_CH5_UNUSED |
133 | |||
134 | Northstar and Northstar Plus | ||
135 | ------ | ||
136 | PLL and leaf clock compatible strings for Northstar and Northstar Plus are: | ||
137 | "brcm,nsp-armpll" | ||
138 | "brcm,nsp-genpll" | ||
139 | "brcm,nsp-lcpll0" | ||
140 | |||
141 | The following table defines the set of PLL/clock index and ID for Northstar and | ||
142 | Northstar Plus. These clock IDs are defined in: | ||
143 | "include/dt-bindings/clock/bcm-nsp.h" | ||
144 | |||
145 | Clock Source Index ID | ||
146 | --- ----- ----- --------- | ||
147 | crystal N/A N/A N/A | ||
148 | |||
149 | armpll crystal N/A N/A | ||
150 | |||
151 | genpll crystal 0 BCM_NSP_GENPLL | ||
152 | phy genpll 1 BCM_NSP_GENPLL_PHY_CLK | ||
153 | ethernetclk genpll 2 BCM_NSP_GENPLL_ENET_SW_CLK | ||
154 | usbclk genpll 3 BCM_NSP_GENPLL_USB_PHY_REF_CLK | ||
155 | iprocfast genpll 4 BCM_NSP_GENPLL_IPROCFAST_CLK | ||
156 | sata1 genpll 5 BCM_NSP_GENPLL_SATA1_CLK | ||
157 | sata2 genpll 6 BCM_NSP_GENPLL_SATA2_CLK | ||
158 | |||
159 | lcpll0 crystal 0 BCM_NSP_LCPLL0 | ||
160 | pcie_phy lcpll0 1 BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK | ||
161 | sdio lcpll0 2 BCM_NSP_LCPLL0_SDIO_CLK | ||
162 | ddr_phy lcpll0 3 BCM_NSP_LCPLL0_DDR_PHY_CLK | ||
163 | |||
164 | Northstar 2 | ||
165 | ----------- | ||
166 | PLL and leaf clock compatible strings for Northstar 2 are: | ||
167 | "brcm,ns2-genpll-scr" | ||
168 | "brcm,ns2-genpll-sw" | ||
169 | "brcm,ns2-lcpll-ddr" | ||
170 | "brcm,ns2-lcpll-ports" | ||
171 | |||
172 | The following table defines the set of PLL/clock index and ID for Northstar 2. | ||
173 | These clock IDs are defined in: | ||
174 | "include/dt-bindings/clock/bcm-ns2.h" | ||
175 | |||
176 | Clock Source Index ID | ||
177 | --- ----- ----- --------- | ||
178 | crystal N/A N/A N/A | ||
179 | |||
180 | genpll_scr crystal 0 BCM_NS2_GENPLL_SCR | ||
181 | scr genpll_scr 1 BCM_NS2_GENPLL_SCR_SCR_CLK | ||
182 | fs genpll_scr 2 BCM_NS2_GENPLL_SCR_FS_CLK | ||
183 | audio_ref genpll_scr 3 BCM_NS2_GENPLL_SCR_AUDIO_CLK | ||
184 | ch3_unused genpll_scr 4 BCM_NS2_GENPLL_SCR_CH3_UNUSED | ||
185 | ch4_unused genpll_scr 5 BCM_NS2_GENPLL_SCR_CH4_UNUSED | ||
186 | ch5_unused genpll_scr 6 BCM_NS2_GENPLL_SCR_CH5_UNUSED | ||
187 | |||
188 | genpll_sw crystal 0 BCM_NS2_GENPLL_SW | ||
189 | rpe genpll_sw 1 BCM_NS2_GENPLL_SW_RPE_CLK | ||
190 | 250 genpll_sw 2 BCM_NS2_GENPLL_SW_250_CLK | ||
191 | nic genpll_sw 3 BCM_NS2_GENPLL_SW_NIC_CLK | ||
192 | chimp genpll_sw 4 BCM_NS2_GENPLL_SW_CHIMP_CLK | ||
193 | port genpll_sw 5 BCM_NS2_GENPLL_SW_PORT_CLK | ||
194 | sdio genpll_sw 6 BCM_NS2_GENPLL_SW_SDIO_CLK | ||
195 | |||
196 | lcpll_ddr crystal 0 BCM_NS2_LCPLL_DDR | ||
197 | pcie_sata_usb lcpll_ddr 1 BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK | ||
198 | ddr lcpll_ddr 2 BCM_NS2_LCPLL_DDR_DDR_CLK | ||
199 | ch2_unused lcpll_ddr 3 BCM_NS2_LCPLL_DDR_CH2_UNUSED | ||
200 | ch3_unused lcpll_ddr 4 BCM_NS2_LCPLL_DDR_CH3_UNUSED | ||
201 | ch4_unused lcpll_ddr 5 BCM_NS2_LCPLL_DDR_CH4_UNUSED | ||
202 | ch5_unused lcpll_ddr 6 BCM_NS2_LCPLL_DDR_CH5_UNUSED | ||
203 | |||
204 | lcpll_ports crystal 0 BCM_NS2_LCPLL_PORTS | ||
205 | wan lcpll_ports 1 BCM_NS2_LCPLL_PORTS_WAN_CLK | ||
206 | rgmii lcpll_ports 2 BCM_NS2_LCPLL_PORTS_RGMII_CLK | ||
207 | ch2_unused lcpll_ports 3 BCM_NS2_LCPLL_PORTS_CH2_UNUSED | ||
208 | ch3_unused lcpll_ports 4 BCM_NS2_LCPLL_PORTS_CH3_UNUSED | ||
209 | ch4_unused lcpll_ports 5 BCM_NS2_LCPLL_PORTS_CH4_UNUSED | ||
210 | ch5_unused lcpll_ports 6 BCM_NS2_LCPLL_PORTS_CH5_UNUSED | ||
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 1319c3c14327..84bd26535ae9 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig | |||
@@ -14,7 +14,7 @@ config ARCH_BCM_IPROC | |||
14 | select HAVE_ARM_SCU if SMP | 14 | select HAVE_ARM_SCU if SMP |
15 | select HAVE_ARM_TWD if SMP | 15 | select HAVE_ARM_TWD if SMP |
16 | select ARM_GLOBAL_TIMER | 16 | select ARM_GLOBAL_TIMER |
17 | 17 | select COMMON_CLK_IPROC | |
18 | select CLKSRC_MMIO | 18 | select CLKSRC_MMIO |
19 | select ARCH_REQUIRE_GPIOLIB | 19 | select ARCH_REQUIRE_GPIOLIB |
20 | select ARM_AMBA | 20 | select ARM_AMBA |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 58fd167c462a..d3e1910eebab 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -48,7 +48,7 @@ obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o | |||
48 | obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o | 48 | obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o |
49 | obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o | 49 | obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o |
50 | obj-$(CONFIG_COMMON_CLK_AT91) += at91/ | 50 | obj-$(CONFIG_COMMON_CLK_AT91) += at91/ |
51 | obj-$(CONFIG_ARCH_BCM) += bcm/ | 51 | obj-y += bcm/ |
52 | obj-$(CONFIG_ARCH_BERLIN) += berlin/ | 52 | obj-$(CONFIG_ARCH_BERLIN) += berlin/ |
53 | obj-$(CONFIG_ARCH_HISI) += hisilicon/ | 53 | obj-$(CONFIG_ARCH_HISI) += hisilicon/ |
54 | obj-$(CONFIG_ARCH_MXC) += imx/ | 54 | obj-$(CONFIG_ARCH_MXC) += imx/ |
diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig index 561e9dc6d40d..85260fb96b36 100644 --- a/drivers/clk/bcm/Kconfig +++ b/drivers/clk/bcm/Kconfig | |||
@@ -9,10 +9,8 @@ config CLK_BCM_KONA | |||
9 | in the BCM281xx and BCM21664 families. | 9 | in the BCM281xx and BCM21664 families. |
10 | 10 | ||
11 | config COMMON_CLK_IPROC | 11 | config COMMON_CLK_IPROC |
12 | bool "Broadcom iProc clock support" | 12 | bool |
13 | depends on ARCH_BCM_IPROC || COMPILE_TEST | ||
14 | depends on COMMON_CLK | 13 | depends on COMMON_CLK |
15 | default ARCH_BCM_IPROC | ||
16 | help | 14 | help |
17 | Enable common clock framework support for Broadcom SoCs | 15 | Enable common clock framework support for Broadcom SoCs |
18 | based on the iProc architecture | 16 | based on the iProc architecture |
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile index ee2349bbe1f1..3fc95060d875 100644 --- a/drivers/clk/bcm/Makefile +++ b/drivers/clk/bcm/Makefile | |||
@@ -4,4 +4,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o | |||
4 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o | 4 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o |
5 | obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o | 5 | obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o |
6 | obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o | 6 | obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o |
7 | obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o | ||
7 | obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o | 8 | obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o |
9 | obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o | ||
10 | obj-$(CONFIG_ARCH_BCM_5301X) += clk-nsp.o | ||
diff --git a/drivers/clk/bcm/clk-cygnus.c b/drivers/clk/bcm/clk-cygnus.c index 316c60337661..3a228b6d4fee 100644 --- a/drivers/clk/bcm/clk-cygnus.c +++ b/drivers/clk/bcm/clk-cygnus.c | |||
@@ -23,28 +23,30 @@ | |||
23 | #include <dt-bindings/clock/bcm-cygnus.h> | 23 | #include <dt-bindings/clock/bcm-cygnus.h> |
24 | #include "clk-iproc.h" | 24 | #include "clk-iproc.h" |
25 | 25 | ||
26 | #define reg_val(o, s, w) { .offset = o, .shift = s, .width = w, } | 26 | #define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, } |
27 | 27 | ||
28 | #define aon_val(o, pw, ps, is) { .offset = o, .pwr_width = pw, \ | 28 | #define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \ |
29 | .pwr_shift = ps, .iso_shift = is } | 29 | .pwr_shift = ps, .iso_shift = is } |
30 | 30 | ||
31 | #define sw_ctrl_val(o, s) { .offset = o, .shift = s, } | 31 | #define SW_CTRL_VAL(o, s) { .offset = o, .shift = s, } |
32 | 32 | ||
33 | #define asiu_div_val(o, es, hs, hw, ls, lw) \ | 33 | #define ASIU_DIV_VAL(o, es, hs, hw, ls, lw) \ |
34 | { .offset = o, .en_shift = es, .high_shift = hs, \ | 34 | { .offset = o, .en_shift = es, .high_shift = hs, \ |
35 | .high_width = hw, .low_shift = ls, .low_width = lw } | 35 | .high_width = hw, .low_shift = ls, .low_width = lw } |
36 | 36 | ||
37 | #define reset_val(o, rs, prs, kis, kiw, kps, kpw, kas, kaw) { .offset = o, \ | 37 | #define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \ |
38 | .reset_shift = rs, .p_reset_shift = prs, .ki_shift = kis, \ | 38 | .p_reset_shift = prs } |
39 | .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas, \ | 39 | |
40 | #define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\ | ||
41 | .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas, \ | ||
40 | .ka_width = kaw } | 42 | .ka_width = kaw } |
41 | 43 | ||
42 | #define vco_ctrl_val(uo, lo) { .u_offset = uo, .l_offset = lo } | 44 | #define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo } |
43 | 45 | ||
44 | #define enable_val(o, es, hs, bs) { .offset = o, .enable_shift = es, \ | 46 | #define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \ |
45 | .hold_shift = hs, .bypass_shift = bs } | 47 | .hold_shift = hs, .bypass_shift = bs } |
46 | 48 | ||
47 | #define asiu_gate_val(o, es) { .offset = o, .en_shift = es } | 49 | #define ASIU_GATE_VAL(o, es) { .offset = o, .en_shift = es } |
48 | 50 | ||
49 | static void __init cygnus_armpll_init(struct device_node *node) | 51 | static void __init cygnus_armpll_init(struct device_node *node) |
50 | { | 52 | { |
@@ -55,52 +57,53 @@ CLK_OF_DECLARE(cygnus_armpll, "brcm,cygnus-armpll", cygnus_armpll_init); | |||
55 | static const struct iproc_pll_ctrl genpll = { | 57 | static const struct iproc_pll_ctrl genpll = { |
56 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC | | 58 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC | |
57 | IPROC_CLK_PLL_NEEDS_SW_CFG, | 59 | IPROC_CLK_PLL_NEEDS_SW_CFG, |
58 | .aon = aon_val(0x0, 2, 1, 0), | 60 | .aon = AON_VAL(0x0, 2, 1, 0), |
59 | .reset = reset_val(0x0, 11, 10, 4, 3, 0, 4, 7, 3), | 61 | .reset = RESET_VAL(0x0, 11, 10), |
60 | .sw_ctrl = sw_ctrl_val(0x10, 31), | 62 | .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3), |
61 | .ndiv_int = reg_val(0x10, 20, 10), | 63 | .sw_ctrl = SW_CTRL_VAL(0x10, 31), |
62 | .ndiv_frac = reg_val(0x10, 0, 20), | 64 | .ndiv_int = REG_VAL(0x10, 20, 10), |
63 | .pdiv = reg_val(0x14, 0, 4), | 65 | .ndiv_frac = REG_VAL(0x10, 0, 20), |
64 | .vco_ctrl = vco_ctrl_val(0x18, 0x1c), | 66 | .pdiv = REG_VAL(0x14, 0, 4), |
65 | .status = reg_val(0x28, 12, 1), | 67 | .vco_ctrl = VCO_CTRL_VAL(0x18, 0x1c), |
68 | .status = REG_VAL(0x28, 12, 1), | ||
66 | }; | 69 | }; |
67 | 70 | ||
68 | static const struct iproc_clk_ctrl genpll_clk[] = { | 71 | static const struct iproc_clk_ctrl genpll_clk[] = { |
69 | [BCM_CYGNUS_GENPLL_AXI21_CLK] = { | 72 | [BCM_CYGNUS_GENPLL_AXI21_CLK] = { |
70 | .channel = BCM_CYGNUS_GENPLL_AXI21_CLK, | 73 | .channel = BCM_CYGNUS_GENPLL_AXI21_CLK, |
71 | .flags = IPROC_CLK_AON, | 74 | .flags = IPROC_CLK_AON, |
72 | .enable = enable_val(0x4, 6, 0, 12), | 75 | .enable = ENABLE_VAL(0x4, 6, 0, 12), |
73 | .mdiv = reg_val(0x20, 0, 8), | 76 | .mdiv = REG_VAL(0x20, 0, 8), |
74 | }, | 77 | }, |
75 | [BCM_CYGNUS_GENPLL_250MHZ_CLK] = { | 78 | [BCM_CYGNUS_GENPLL_250MHZ_CLK] = { |
76 | .channel = BCM_CYGNUS_GENPLL_250MHZ_CLK, | 79 | .channel = BCM_CYGNUS_GENPLL_250MHZ_CLK, |
77 | .flags = IPROC_CLK_AON, | 80 | .flags = IPROC_CLK_AON, |
78 | .enable = enable_val(0x4, 7, 1, 13), | 81 | .enable = ENABLE_VAL(0x4, 7, 1, 13), |
79 | .mdiv = reg_val(0x20, 10, 8), | 82 | .mdiv = REG_VAL(0x20, 10, 8), |
80 | }, | 83 | }, |
81 | [BCM_CYGNUS_GENPLL_IHOST_SYS_CLK] = { | 84 | [BCM_CYGNUS_GENPLL_IHOST_SYS_CLK] = { |
82 | .channel = BCM_CYGNUS_GENPLL_IHOST_SYS_CLK, | 85 | .channel = BCM_CYGNUS_GENPLL_IHOST_SYS_CLK, |
83 | .flags = IPROC_CLK_AON, | 86 | .flags = IPROC_CLK_AON, |
84 | .enable = enable_val(0x4, 8, 2, 14), | 87 | .enable = ENABLE_VAL(0x4, 8, 2, 14), |
85 | .mdiv = reg_val(0x20, 20, 8), | 88 | .mdiv = REG_VAL(0x20, 20, 8), |
86 | }, | 89 | }, |
87 | [BCM_CYGNUS_GENPLL_ENET_SW_CLK] = { | 90 | [BCM_CYGNUS_GENPLL_ENET_SW_CLK] = { |
88 | .channel = BCM_CYGNUS_GENPLL_ENET_SW_CLK, | 91 | .channel = BCM_CYGNUS_GENPLL_ENET_SW_CLK, |
89 | .flags = IPROC_CLK_AON, | 92 | .flags = IPROC_CLK_AON, |
90 | .enable = enable_val(0x4, 9, 3, 15), | 93 | .enable = ENABLE_VAL(0x4, 9, 3, 15), |
91 | .mdiv = reg_val(0x24, 0, 8), | 94 | .mdiv = REG_VAL(0x24, 0, 8), |
92 | }, | 95 | }, |
93 | [BCM_CYGNUS_GENPLL_AUDIO_125_CLK] = { | 96 | [BCM_CYGNUS_GENPLL_AUDIO_125_CLK] = { |
94 | .channel = BCM_CYGNUS_GENPLL_AUDIO_125_CLK, | 97 | .channel = BCM_CYGNUS_GENPLL_AUDIO_125_CLK, |
95 | .flags = IPROC_CLK_AON, | 98 | .flags = IPROC_CLK_AON, |
96 | .enable = enable_val(0x4, 10, 4, 16), | 99 | .enable = ENABLE_VAL(0x4, 10, 4, 16), |
97 | .mdiv = reg_val(0x24, 10, 8), | 100 | .mdiv = REG_VAL(0x24, 10, 8), |
98 | }, | 101 | }, |
99 | [BCM_CYGNUS_GENPLL_CAN_CLK] = { | 102 | [BCM_CYGNUS_GENPLL_CAN_CLK] = { |
100 | .channel = BCM_CYGNUS_GENPLL_CAN_CLK, | 103 | .channel = BCM_CYGNUS_GENPLL_CAN_CLK, |
101 | .flags = IPROC_CLK_AON, | 104 | .flags = IPROC_CLK_AON, |
102 | .enable = enable_val(0x4, 11, 5, 17), | 105 | .enable = ENABLE_VAL(0x4, 11, 5, 17), |
103 | .mdiv = reg_val(0x24, 20, 8), | 106 | .mdiv = REG_VAL(0x24, 20, 8), |
104 | }, | 107 | }, |
105 | }; | 108 | }; |
106 | 109 | ||
@@ -113,51 +116,52 @@ CLK_OF_DECLARE(cygnus_genpll, "brcm,cygnus-genpll", cygnus_genpll_clk_init); | |||
113 | 116 | ||
114 | static const struct iproc_pll_ctrl lcpll0 = { | 117 | static const struct iproc_pll_ctrl lcpll0 = { |
115 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG, | 118 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG, |
116 | .aon = aon_val(0x0, 2, 5, 4), | 119 | .aon = AON_VAL(0x0, 2, 5, 4), |
117 | .reset = reset_val(0x0, 31, 30, 27, 3, 23, 4, 19, 4), | 120 | .reset = RESET_VAL(0x0, 31, 30), |
118 | .sw_ctrl = sw_ctrl_val(0x4, 31), | 121 | .dig_filter = DF_VAL(0x0, 27, 3, 23, 4, 19, 4), |
119 | .ndiv_int = reg_val(0x4, 16, 10), | 122 | .sw_ctrl = SW_CTRL_VAL(0x4, 31), |
120 | .pdiv = reg_val(0x4, 26, 4), | 123 | .ndiv_int = REG_VAL(0x4, 16, 10), |
121 | .vco_ctrl = vco_ctrl_val(0x10, 0x14), | 124 | .pdiv = REG_VAL(0x4, 26, 4), |
122 | .status = reg_val(0x18, 12, 1), | 125 | .vco_ctrl = VCO_CTRL_VAL(0x10, 0x14), |
126 | .status = REG_VAL(0x18, 12, 1), | ||
123 | }; | 127 | }; |
124 | 128 | ||
125 | static const struct iproc_clk_ctrl lcpll0_clk[] = { | 129 | static const struct iproc_clk_ctrl lcpll0_clk[] = { |
126 | [BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK] = { | 130 | [BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK] = { |
127 | .channel = BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK, | 131 | .channel = BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK, |
128 | .flags = IPROC_CLK_AON, | 132 | .flags = IPROC_CLK_AON, |
129 | .enable = enable_val(0x0, 7, 1, 13), | 133 | .enable = ENABLE_VAL(0x0, 7, 1, 13), |
130 | .mdiv = reg_val(0x8, 0, 8), | 134 | .mdiv = REG_VAL(0x8, 0, 8), |
131 | }, | 135 | }, |
132 | [BCM_CYGNUS_LCPLL0_DDR_PHY_CLK] = { | 136 | [BCM_CYGNUS_LCPLL0_DDR_PHY_CLK] = { |
133 | .channel = BCM_CYGNUS_LCPLL0_DDR_PHY_CLK, | 137 | .channel = BCM_CYGNUS_LCPLL0_DDR_PHY_CLK, |
134 | .flags = IPROC_CLK_AON, | 138 | .flags = IPROC_CLK_AON, |
135 | .enable = enable_val(0x0, 8, 2, 14), | 139 | .enable = ENABLE_VAL(0x0, 8, 2, 14), |
136 | .mdiv = reg_val(0x8, 10, 8), | 140 | .mdiv = REG_VAL(0x8, 10, 8), |
137 | }, | 141 | }, |
138 | [BCM_CYGNUS_LCPLL0_SDIO_CLK] = { | 142 | [BCM_CYGNUS_LCPLL0_SDIO_CLK] = { |
139 | .channel = BCM_CYGNUS_LCPLL0_SDIO_CLK, | 143 | .channel = BCM_CYGNUS_LCPLL0_SDIO_CLK, |
140 | .flags = IPROC_CLK_AON, | 144 | .flags = IPROC_CLK_AON, |
141 | .enable = enable_val(0x0, 9, 3, 15), | 145 | .enable = ENABLE_VAL(0x0, 9, 3, 15), |
142 | .mdiv = reg_val(0x8, 20, 8), | 146 | .mdiv = REG_VAL(0x8, 20, 8), |
143 | }, | 147 | }, |
144 | [BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK] = { | 148 | [BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK] = { |
145 | .channel = BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK, | 149 | .channel = BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK, |
146 | .flags = IPROC_CLK_AON, | 150 | .flags = IPROC_CLK_AON, |
147 | .enable = enable_val(0x0, 10, 4, 16), | 151 | .enable = ENABLE_VAL(0x0, 10, 4, 16), |
148 | .mdiv = reg_val(0xc, 0, 8), | 152 | .mdiv = REG_VAL(0xc, 0, 8), |
149 | }, | 153 | }, |
150 | [BCM_CYGNUS_LCPLL0_SMART_CARD_CLK] = { | 154 | [BCM_CYGNUS_LCPLL0_SMART_CARD_CLK] = { |
151 | .channel = BCM_CYGNUS_LCPLL0_SMART_CARD_CLK, | 155 | .channel = BCM_CYGNUS_LCPLL0_SMART_CARD_CLK, |
152 | .flags = IPROC_CLK_AON, | 156 | .flags = IPROC_CLK_AON, |
153 | .enable = enable_val(0x0, 11, 5, 17), | 157 | .enable = ENABLE_VAL(0x0, 11, 5, 17), |
154 | .mdiv = reg_val(0xc, 10, 8), | 158 | .mdiv = REG_VAL(0xc, 10, 8), |
155 | }, | 159 | }, |
156 | [BCM_CYGNUS_LCPLL0_CH5_UNUSED] = { | 160 | [BCM_CYGNUS_LCPLL0_CH5_UNUSED] = { |
157 | .channel = BCM_CYGNUS_LCPLL0_CH5_UNUSED, | 161 | .channel = BCM_CYGNUS_LCPLL0_CH5_UNUSED, |
158 | .flags = IPROC_CLK_AON, | 162 | .flags = IPROC_CLK_AON, |
159 | .enable = enable_val(0x0, 12, 6, 18), | 163 | .enable = ENABLE_VAL(0x0, 12, 6, 18), |
160 | .mdiv = reg_val(0xc, 20, 8), | 164 | .mdiv = REG_VAL(0xc, 20, 8), |
161 | }, | 165 | }, |
162 | }; | 166 | }; |
163 | 167 | ||
@@ -189,52 +193,53 @@ static const struct iproc_pll_vco_param mipipll_vco_params[] = { | |||
189 | static const struct iproc_pll_ctrl mipipll = { | 193 | static const struct iproc_pll_ctrl mipipll = { |
190 | .flags = IPROC_CLK_PLL_ASIU | IPROC_CLK_PLL_HAS_NDIV_FRAC | | 194 | .flags = IPROC_CLK_PLL_ASIU | IPROC_CLK_PLL_HAS_NDIV_FRAC | |
191 | IPROC_CLK_NEEDS_READ_BACK, | 195 | IPROC_CLK_NEEDS_READ_BACK, |
192 | .aon = aon_val(0x0, 4, 17, 16), | 196 | .aon = AON_VAL(0x0, 4, 17, 16), |
193 | .asiu = asiu_gate_val(0x0, 3), | 197 | .asiu = ASIU_GATE_VAL(0x0, 3), |
194 | .reset = reset_val(0x0, 11, 10, 4, 3, 0, 4, 7, 4), | 198 | .reset = RESET_VAL(0x0, 11, 10), |
195 | .ndiv_int = reg_val(0x10, 20, 10), | 199 | .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 4), |
196 | .ndiv_frac = reg_val(0x10, 0, 20), | 200 | .ndiv_int = REG_VAL(0x10, 20, 10), |
197 | .pdiv = reg_val(0x14, 0, 4), | 201 | .ndiv_frac = REG_VAL(0x10, 0, 20), |
198 | .vco_ctrl = vco_ctrl_val(0x18, 0x1c), | 202 | .pdiv = REG_VAL(0x14, 0, 4), |
199 | .status = reg_val(0x28, 12, 1), | 203 | .vco_ctrl = VCO_CTRL_VAL(0x18, 0x1c), |
204 | .status = REG_VAL(0x28, 12, 1), | ||
200 | }; | 205 | }; |
201 | 206 | ||
202 | static const struct iproc_clk_ctrl mipipll_clk[] = { | 207 | static const struct iproc_clk_ctrl mipipll_clk[] = { |
203 | [BCM_CYGNUS_MIPIPLL_CH0_UNUSED] = { | 208 | [BCM_CYGNUS_MIPIPLL_CH0_UNUSED] = { |
204 | .channel = BCM_CYGNUS_MIPIPLL_CH0_UNUSED, | 209 | .channel = BCM_CYGNUS_MIPIPLL_CH0_UNUSED, |
205 | .flags = IPROC_CLK_NEEDS_READ_BACK, | 210 | .flags = IPROC_CLK_NEEDS_READ_BACK, |
206 | .enable = enable_val(0x4, 12, 6, 18), | 211 | .enable = ENABLE_VAL(0x4, 12, 6, 18), |
207 | .mdiv = reg_val(0x20, 0, 8), | 212 | .mdiv = REG_VAL(0x20, 0, 8), |
208 | }, | 213 | }, |
209 | [BCM_CYGNUS_MIPIPLL_CH1_LCD] = { | 214 | [BCM_CYGNUS_MIPIPLL_CH1_LCD] = { |
210 | .channel = BCM_CYGNUS_MIPIPLL_CH1_LCD, | 215 | .channel = BCM_CYGNUS_MIPIPLL_CH1_LCD, |
211 | .flags = IPROC_CLK_NEEDS_READ_BACK, | 216 | .flags = IPROC_CLK_NEEDS_READ_BACK, |
212 | .enable = enable_val(0x4, 13, 7, 19), | 217 | .enable = ENABLE_VAL(0x4, 13, 7, 19), |
213 | .mdiv = reg_val(0x20, 10, 8), | 218 | .mdiv = REG_VAL(0x20, 10, 8), |
214 | }, | 219 | }, |
215 | [BCM_CYGNUS_MIPIPLL_CH2_V3D] = { | 220 | [BCM_CYGNUS_MIPIPLL_CH2_V3D] = { |
216 | .channel = BCM_CYGNUS_MIPIPLL_CH2_V3D, | 221 | .channel = BCM_CYGNUS_MIPIPLL_CH2_V3D, |
217 | .flags = IPROC_CLK_NEEDS_READ_BACK, | 222 | .flags = IPROC_CLK_NEEDS_READ_BACK, |
218 | .enable = enable_val(0x4, 14, 8, 20), | 223 | .enable = ENABLE_VAL(0x4, 14, 8, 20), |
219 | .mdiv = reg_val(0x20, 20, 8), | 224 | .mdiv = REG_VAL(0x20, 20, 8), |
220 | }, | 225 | }, |
221 | [BCM_CYGNUS_MIPIPLL_CH3_UNUSED] = { | 226 | [BCM_CYGNUS_MIPIPLL_CH3_UNUSED] = { |
222 | .channel = BCM_CYGNUS_MIPIPLL_CH3_UNUSED, | 227 | .channel = BCM_CYGNUS_MIPIPLL_CH3_UNUSED, |
223 | .flags = IPROC_CLK_NEEDS_READ_BACK, | 228 | .flags = IPROC_CLK_NEEDS_READ_BACK, |
224 | .enable = enable_val(0x4, 15, 9, 21), | 229 | .enable = ENABLE_VAL(0x4, 15, 9, 21), |
225 | .mdiv = reg_val(0x24, 0, 8), | 230 | .mdiv = REG_VAL(0x24, 0, 8), |
226 | }, | 231 | }, |
227 | [BCM_CYGNUS_MIPIPLL_CH4_UNUSED] = { | 232 | [BCM_CYGNUS_MIPIPLL_CH4_UNUSED] = { |
228 | .channel = BCM_CYGNUS_MIPIPLL_CH4_UNUSED, | 233 | .channel = BCM_CYGNUS_MIPIPLL_CH4_UNUSED, |
229 | .flags = IPROC_CLK_NEEDS_READ_BACK, | 234 | .flags = IPROC_CLK_NEEDS_READ_BACK, |
230 | .enable = enable_val(0x4, 16, 10, 22), | 235 | .enable = ENABLE_VAL(0x4, 16, 10, 22), |
231 | .mdiv = reg_val(0x24, 10, 8), | 236 | .mdiv = REG_VAL(0x24, 10, 8), |
232 | }, | 237 | }, |
233 | [BCM_CYGNUS_MIPIPLL_CH5_UNUSED] = { | 238 | [BCM_CYGNUS_MIPIPLL_CH5_UNUSED] = { |
234 | .channel = BCM_CYGNUS_MIPIPLL_CH5_UNUSED, | 239 | .channel = BCM_CYGNUS_MIPIPLL_CH5_UNUSED, |
235 | .flags = IPROC_CLK_NEEDS_READ_BACK, | 240 | .flags = IPROC_CLK_NEEDS_READ_BACK, |
236 | .enable = enable_val(0x4, 17, 11, 23), | 241 | .enable = ENABLE_VAL(0x4, 17, 11, 23), |
237 | .mdiv = reg_val(0x24, 20, 8), | 242 | .mdiv = REG_VAL(0x24, 20, 8), |
238 | }, | 243 | }, |
239 | }; | 244 | }; |
240 | 245 | ||
@@ -247,15 +252,15 @@ static void __init cygnus_mipipll_clk_init(struct device_node *node) | |||
247 | CLK_OF_DECLARE(cygnus_mipipll, "brcm,cygnus-mipipll", cygnus_mipipll_clk_init); | 252 | CLK_OF_DECLARE(cygnus_mipipll, "brcm,cygnus-mipipll", cygnus_mipipll_clk_init); |
248 | 253 | ||
249 | static const struct iproc_asiu_div asiu_div[] = { | 254 | static const struct iproc_asiu_div asiu_div[] = { |
250 | [BCM_CYGNUS_ASIU_KEYPAD_CLK] = asiu_div_val(0x0, 31, 16, 10, 0, 10), | 255 | [BCM_CYGNUS_ASIU_KEYPAD_CLK] = ASIU_DIV_VAL(0x0, 31, 16, 10, 0, 10), |
251 | [BCM_CYGNUS_ASIU_ADC_CLK] = asiu_div_val(0x4, 31, 16, 10, 0, 10), | 256 | [BCM_CYGNUS_ASIU_ADC_CLK] = ASIU_DIV_VAL(0x4, 31, 16, 10, 0, 10), |
252 | [BCM_CYGNUS_ASIU_PWM_CLK] = asiu_div_val(0x8, 31, 16, 10, 0, 10), | 257 | [BCM_CYGNUS_ASIU_PWM_CLK] = ASIU_DIV_VAL(0x8, 31, 16, 10, 0, 10), |
253 | }; | 258 | }; |
254 | 259 | ||
255 | static const struct iproc_asiu_gate asiu_gate[] = { | 260 | static const struct iproc_asiu_gate asiu_gate[] = { |
256 | [BCM_CYGNUS_ASIU_KEYPAD_CLK] = asiu_gate_val(0x0, 7), | 261 | [BCM_CYGNUS_ASIU_KEYPAD_CLK] = ASIU_GATE_VAL(0x0, 7), |
257 | [BCM_CYGNUS_ASIU_ADC_CLK] = asiu_gate_val(0x0, 9), | 262 | [BCM_CYGNUS_ASIU_ADC_CLK] = ASIU_GATE_VAL(0x0, 9), |
258 | [BCM_CYGNUS_ASIU_PWM_CLK] = asiu_gate_val(IPROC_CLK_INVALID_OFFSET, 0), | 263 | [BCM_CYGNUS_ASIU_PWM_CLK] = ASIU_GATE_VAL(IPROC_CLK_INVALID_OFFSET, 0), |
259 | }; | 264 | }; |
260 | 265 | ||
261 | static void __init cygnus_asiu_init(struct device_node *node) | 266 | static void __init cygnus_asiu_init(struct device_node *node) |
diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c index d679ab869653..afd5891ac9e6 100644 --- a/drivers/clk/bcm/clk-iproc-pll.c +++ b/drivers/clk/bcm/clk-iproc-pll.c | |||
@@ -74,7 +74,8 @@ struct iproc_clk { | |||
74 | }; | 74 | }; |
75 | 75 | ||
76 | struct iproc_pll { | 76 | struct iproc_pll { |
77 | void __iomem *pll_base; | 77 | void __iomem *status_base; |
78 | void __iomem *control_base; | ||
78 | void __iomem *pwr_base; | 79 | void __iomem *pwr_base; |
79 | void __iomem *asiu_base; | 80 | void __iomem *asiu_base; |
80 | 81 | ||
@@ -127,7 +128,7 @@ static int pll_wait_for_lock(struct iproc_pll *pll) | |||
127 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; | 128 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; |
128 | 129 | ||
129 | for (i = 0; i < LOCK_DELAY; i++) { | 130 | for (i = 0; i < LOCK_DELAY; i++) { |
130 | u32 val = readl(pll->pll_base + ctrl->status.offset); | 131 | u32 val = readl(pll->status_base + ctrl->status.offset); |
131 | 132 | ||
132 | if (val & (1 << ctrl->status.shift)) | 133 | if (val & (1 << ctrl->status.shift)) |
133 | return 0; | 134 | return 0; |
@@ -137,6 +138,18 @@ static int pll_wait_for_lock(struct iproc_pll *pll) | |||
137 | return -EIO; | 138 | return -EIO; |
138 | } | 139 | } |
139 | 140 | ||
141 | static void iproc_pll_write(const struct iproc_pll *pll, void __iomem *base, | ||
142 | const u32 offset, u32 val) | ||
143 | { | ||
144 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; | ||
145 | |||
146 | writel(val, base + offset); | ||
147 | |||
148 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK && | ||
149 | (base == pll->status_base || base == pll->control_base))) | ||
150 | val = readl(base + offset); | ||
151 | } | ||
152 | |||
140 | static void __pll_disable(struct iproc_pll *pll) | 153 | static void __pll_disable(struct iproc_pll *pll) |
141 | { | 154 | { |
142 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; | 155 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; |
@@ -145,17 +158,25 @@ static void __pll_disable(struct iproc_pll *pll) | |||
145 | if (ctrl->flags & IPROC_CLK_PLL_ASIU) { | 158 | if (ctrl->flags & IPROC_CLK_PLL_ASIU) { |
146 | val = readl(pll->asiu_base + ctrl->asiu.offset); | 159 | val = readl(pll->asiu_base + ctrl->asiu.offset); |
147 | val &= ~(1 << ctrl->asiu.en_shift); | 160 | val &= ~(1 << ctrl->asiu.en_shift); |
148 | writel(val, pll->asiu_base + ctrl->asiu.offset); | 161 | iproc_pll_write(pll, pll->asiu_base, ctrl->asiu.offset, val); |
162 | } | ||
163 | |||
164 | if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) { | ||
165 | val = readl(pll->control_base + ctrl->aon.offset); | ||
166 | val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift; | ||
167 | iproc_pll_write(pll, pll->control_base, ctrl->aon.offset, val); | ||
149 | } | 168 | } |
150 | 169 | ||
151 | /* latch input value so core power can be shut down */ | 170 | if (pll->pwr_base) { |
152 | val = readl(pll->pwr_base + ctrl->aon.offset); | 171 | /* latch input value so core power can be shut down */ |
153 | val |= (1 << ctrl->aon.iso_shift); | 172 | val = readl(pll->pwr_base + ctrl->aon.offset); |
154 | writel(val, pll->pwr_base + ctrl->aon.offset); | 173 | val |= 1 << ctrl->aon.iso_shift; |
174 | iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val); | ||
155 | 175 | ||
156 | /* power down the core */ | 176 | /* power down the core */ |
157 | val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift); | 177 | val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift); |
158 | writel(val, pll->pwr_base + ctrl->aon.offset); | 178 | iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val); |
179 | } | ||
159 | } | 180 | } |
160 | 181 | ||
161 | static int __pll_enable(struct iproc_pll *pll) | 182 | static int __pll_enable(struct iproc_pll *pll) |
@@ -163,17 +184,25 @@ static int __pll_enable(struct iproc_pll *pll) | |||
163 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; | 184 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; |
164 | u32 val; | 185 | u32 val; |
165 | 186 | ||
166 | /* power up the PLL and make sure it's not latched */ | 187 | if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) { |
167 | val = readl(pll->pwr_base + ctrl->aon.offset); | 188 | val = readl(pll->control_base + ctrl->aon.offset); |
168 | val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift; | 189 | val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift); |
169 | val &= ~(1 << ctrl->aon.iso_shift); | 190 | iproc_pll_write(pll, pll->control_base, ctrl->aon.offset, val); |
170 | writel(val, pll->pwr_base + ctrl->aon.offset); | 191 | } |
192 | |||
193 | if (pll->pwr_base) { | ||
194 | /* power up the PLL and make sure it's not latched */ | ||
195 | val = readl(pll->pwr_base + ctrl->aon.offset); | ||
196 | val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift; | ||
197 | val &= ~(1 << ctrl->aon.iso_shift); | ||
198 | iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val); | ||
199 | } | ||
171 | 200 | ||
172 | /* certain PLLs also need to be ungated from the ASIU top level */ | 201 | /* certain PLLs also need to be ungated from the ASIU top level */ |
173 | if (ctrl->flags & IPROC_CLK_PLL_ASIU) { | 202 | if (ctrl->flags & IPROC_CLK_PLL_ASIU) { |
174 | val = readl(pll->asiu_base + ctrl->asiu.offset); | 203 | val = readl(pll->asiu_base + ctrl->asiu.offset); |
175 | val |= (1 << ctrl->asiu.en_shift); | 204 | val |= (1 << ctrl->asiu.en_shift); |
176 | writel(val, pll->asiu_base + ctrl->asiu.offset); | 205 | iproc_pll_write(pll, pll->asiu_base, ctrl->asiu.offset, val); |
177 | } | 206 | } |
178 | 207 | ||
179 | return 0; | 208 | return 0; |
@@ -185,11 +214,9 @@ static void __pll_put_in_reset(struct iproc_pll *pll) | |||
185 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; | 214 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; |
186 | const struct iproc_pll_reset_ctrl *reset = &ctrl->reset; | 215 | const struct iproc_pll_reset_ctrl *reset = &ctrl->reset; |
187 | 216 | ||
188 | val = readl(pll->pll_base + reset->offset); | 217 | val = readl(pll->control_base + reset->offset); |
189 | val &= ~(1 << reset->reset_shift | 1 << reset->p_reset_shift); | 218 | val &= ~(1 << reset->reset_shift | 1 << reset->p_reset_shift); |
190 | writel(val, pll->pll_base + reset->offset); | 219 | iproc_pll_write(pll, pll->control_base, reset->offset, val); |
191 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
192 | readl(pll->pll_base + reset->offset); | ||
193 | } | 220 | } |
194 | 221 | ||
195 | static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp, | 222 | static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp, |
@@ -198,17 +225,19 @@ static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp, | |||
198 | u32 val; | 225 | u32 val; |
199 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; | 226 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; |
200 | const struct iproc_pll_reset_ctrl *reset = &ctrl->reset; | 227 | const struct iproc_pll_reset_ctrl *reset = &ctrl->reset; |
228 | const struct iproc_pll_dig_filter_ctrl *dig_filter = &ctrl->dig_filter; | ||
201 | 229 | ||
202 | val = readl(pll->pll_base + reset->offset); | 230 | val = readl(pll->control_base + dig_filter->offset); |
203 | val &= ~(bit_mask(reset->ki_width) << reset->ki_shift | | 231 | val &= ~(bit_mask(dig_filter->ki_width) << dig_filter->ki_shift | |
204 | bit_mask(reset->kp_width) << reset->kp_shift | | 232 | bit_mask(dig_filter->kp_width) << dig_filter->kp_shift | |
205 | bit_mask(reset->ka_width) << reset->ka_shift); | 233 | bit_mask(dig_filter->ka_width) << dig_filter->ka_shift); |
206 | val |= ki << reset->ki_shift | kp << reset->kp_shift | | 234 | val |= ki << dig_filter->ki_shift | kp << dig_filter->kp_shift | |
207 | ka << reset->ka_shift; | 235 | ka << dig_filter->ka_shift; |
236 | iproc_pll_write(pll, pll->control_base, dig_filter->offset, val); | ||
237 | |||
238 | val = readl(pll->control_base + reset->offset); | ||
208 | val |= 1 << reset->reset_shift | 1 << reset->p_reset_shift; | 239 | val |= 1 << reset->reset_shift | 1 << reset->p_reset_shift; |
209 | writel(val, pll->pll_base + reset->offset); | 240 | iproc_pll_write(pll, pll->control_base, reset->offset, val); |
210 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
211 | readl(pll->pll_base + reset->offset); | ||
212 | } | 241 | } |
213 | 242 | ||
214 | static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index, | 243 | static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index, |
@@ -263,10 +292,9 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index, | |||
263 | /* put PLL in reset */ | 292 | /* put PLL in reset */ |
264 | __pll_put_in_reset(pll); | 293 | __pll_put_in_reset(pll); |
265 | 294 | ||
266 | writel(0, pll->pll_base + ctrl->vco_ctrl.u_offset); | 295 | iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.u_offset, 0); |
267 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | 296 | |
268 | readl(pll->pll_base + ctrl->vco_ctrl.u_offset); | 297 | val = readl(pll->control_base + ctrl->vco_ctrl.l_offset); |
269 | val = readl(pll->pll_base + ctrl->vco_ctrl.l_offset); | ||
270 | 298 | ||
271 | if (rate >= VCO_LOW && rate < VCO_MID) | 299 | if (rate >= VCO_LOW && rate < VCO_MID) |
272 | val |= (1 << PLL_VCO_LOW_SHIFT); | 300 | val |= (1 << PLL_VCO_LOW_SHIFT); |
@@ -276,36 +304,29 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index, | |||
276 | else | 304 | else |
277 | val |= (1 << PLL_VCO_HIGH_SHIFT); | 305 | val |= (1 << PLL_VCO_HIGH_SHIFT); |
278 | 306 | ||
279 | writel(val, pll->pll_base + ctrl->vco_ctrl.l_offset); | 307 | iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.l_offset, val); |
280 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
281 | readl(pll->pll_base + ctrl->vco_ctrl.l_offset); | ||
282 | 308 | ||
283 | /* program integer part of NDIV */ | 309 | /* program integer part of NDIV */ |
284 | val = readl(pll->pll_base + ctrl->ndiv_int.offset); | 310 | val = readl(pll->control_base + ctrl->ndiv_int.offset); |
285 | val &= ~(bit_mask(ctrl->ndiv_int.width) << ctrl->ndiv_int.shift); | 311 | val &= ~(bit_mask(ctrl->ndiv_int.width) << ctrl->ndiv_int.shift); |
286 | val |= vco->ndiv_int << ctrl->ndiv_int.shift; | 312 | val |= vco->ndiv_int << ctrl->ndiv_int.shift; |
287 | writel(val, pll->pll_base + ctrl->ndiv_int.offset); | 313 | iproc_pll_write(pll, pll->control_base, ctrl->ndiv_int.offset, val); |
288 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
289 | readl(pll->pll_base + ctrl->ndiv_int.offset); | ||
290 | 314 | ||
291 | /* program fractional part of NDIV */ | 315 | /* program fractional part of NDIV */ |
292 | if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) { | 316 | if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) { |
293 | val = readl(pll->pll_base + ctrl->ndiv_frac.offset); | 317 | val = readl(pll->control_base + ctrl->ndiv_frac.offset); |
294 | val &= ~(bit_mask(ctrl->ndiv_frac.width) << | 318 | val &= ~(bit_mask(ctrl->ndiv_frac.width) << |
295 | ctrl->ndiv_frac.shift); | 319 | ctrl->ndiv_frac.shift); |
296 | val |= vco->ndiv_frac << ctrl->ndiv_frac.shift; | 320 | val |= vco->ndiv_frac << ctrl->ndiv_frac.shift; |
297 | writel(val, pll->pll_base + ctrl->ndiv_frac.offset); | 321 | iproc_pll_write(pll, pll->control_base, ctrl->ndiv_frac.offset, |
298 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | 322 | val); |
299 | readl(pll->pll_base + ctrl->ndiv_frac.offset); | ||
300 | } | 323 | } |
301 | 324 | ||
302 | /* program PDIV */ | 325 | /* program PDIV */ |
303 | val = readl(pll->pll_base + ctrl->pdiv.offset); | 326 | val = readl(pll->control_base + ctrl->pdiv.offset); |
304 | val &= ~(bit_mask(ctrl->pdiv.width) << ctrl->pdiv.shift); | 327 | val &= ~(bit_mask(ctrl->pdiv.width) << ctrl->pdiv.shift); |
305 | val |= vco->pdiv << ctrl->pdiv.shift; | 328 | val |= vco->pdiv << ctrl->pdiv.shift; |
306 | writel(val, pll->pll_base + ctrl->pdiv.offset); | 329 | iproc_pll_write(pll, pll->control_base, ctrl->pdiv.offset, val); |
307 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
308 | readl(pll->pll_base + ctrl->pdiv.offset); | ||
309 | 330 | ||
310 | __pll_bring_out_reset(pll, kp, ka, ki); | 331 | __pll_bring_out_reset(pll, kp, ka, ki); |
311 | 332 | ||
@@ -352,7 +373,7 @@ static unsigned long iproc_pll_recalc_rate(struct clk_hw *hw, | |||
352 | return 0; | 373 | return 0; |
353 | 374 | ||
354 | /* PLL needs to be locked */ | 375 | /* PLL needs to be locked */ |
355 | val = readl(pll->pll_base + ctrl->status.offset); | 376 | val = readl(pll->status_base + ctrl->status.offset); |
356 | if ((val & (1 << ctrl->status.shift)) == 0) { | 377 | if ((val & (1 << ctrl->status.shift)) == 0) { |
357 | clk->rate = 0; | 378 | clk->rate = 0; |
358 | return 0; | 379 | return 0; |
@@ -363,19 +384,19 @@ static unsigned long iproc_pll_recalc_rate(struct clk_hw *hw, | |||
363 | * | 384 | * |
364 | * ((ndiv_int + ndiv_frac / 2^20) * (parent clock rate / pdiv) | 385 | * ((ndiv_int + ndiv_frac / 2^20) * (parent clock rate / pdiv) |
365 | */ | 386 | */ |
366 | val = readl(pll->pll_base + ctrl->ndiv_int.offset); | 387 | val = readl(pll->control_base + ctrl->ndiv_int.offset); |
367 | ndiv_int = (val >> ctrl->ndiv_int.shift) & | 388 | ndiv_int = (val >> ctrl->ndiv_int.shift) & |
368 | bit_mask(ctrl->ndiv_int.width); | 389 | bit_mask(ctrl->ndiv_int.width); |
369 | ndiv = ndiv_int << 20; | 390 | ndiv = ndiv_int << 20; |
370 | 391 | ||
371 | if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) { | 392 | if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) { |
372 | val = readl(pll->pll_base + ctrl->ndiv_frac.offset); | 393 | val = readl(pll->control_base + ctrl->ndiv_frac.offset); |
373 | ndiv_frac = (val >> ctrl->ndiv_frac.shift) & | 394 | ndiv_frac = (val >> ctrl->ndiv_frac.shift) & |
374 | bit_mask(ctrl->ndiv_frac.width); | 395 | bit_mask(ctrl->ndiv_frac.width); |
375 | ndiv += ndiv_frac; | 396 | ndiv += ndiv_frac; |
376 | } | 397 | } |
377 | 398 | ||
378 | val = readl(pll->pll_base + ctrl->pdiv.offset); | 399 | val = readl(pll->control_base + ctrl->pdiv.offset); |
379 | pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width); | 400 | pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width); |
380 | 401 | ||
381 | clk->rate = (ndiv * parent_rate) >> 20; | 402 | clk->rate = (ndiv * parent_rate) >> 20; |
@@ -440,16 +461,14 @@ static int iproc_clk_enable(struct clk_hw *hw) | |||
440 | u32 val; | 461 | u32 val; |
441 | 462 | ||
442 | /* channel enable is active low */ | 463 | /* channel enable is active low */ |
443 | val = readl(pll->pll_base + ctrl->enable.offset); | 464 | val = readl(pll->control_base + ctrl->enable.offset); |
444 | val &= ~(1 << ctrl->enable.enable_shift); | 465 | val &= ~(1 << ctrl->enable.enable_shift); |
445 | writel(val, pll->pll_base + ctrl->enable.offset); | 466 | iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val); |
446 | 467 | ||
447 | /* also make sure channel is not held */ | 468 | /* also make sure channel is not held */ |
448 | val = readl(pll->pll_base + ctrl->enable.offset); | 469 | val = readl(pll->control_base + ctrl->enable.offset); |
449 | val &= ~(1 << ctrl->enable.hold_shift); | 470 | val &= ~(1 << ctrl->enable.hold_shift); |
450 | writel(val, pll->pll_base + ctrl->enable.offset); | 471 | iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val); |
451 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
452 | readl(pll->pll_base + ctrl->enable.offset); | ||
453 | 472 | ||
454 | return 0; | 473 | return 0; |
455 | } | 474 | } |
@@ -464,11 +483,9 @@ static void iproc_clk_disable(struct clk_hw *hw) | |||
464 | if (ctrl->flags & IPROC_CLK_AON) | 483 | if (ctrl->flags & IPROC_CLK_AON) |
465 | return; | 484 | return; |
466 | 485 | ||
467 | val = readl(pll->pll_base + ctrl->enable.offset); | 486 | val = readl(pll->control_base + ctrl->enable.offset); |
468 | val |= 1 << ctrl->enable.enable_shift; | 487 | val |= 1 << ctrl->enable.enable_shift; |
469 | writel(val, pll->pll_base + ctrl->enable.offset); | 488 | iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val); |
470 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
471 | readl(pll->pll_base + ctrl->enable.offset); | ||
472 | } | 489 | } |
473 | 490 | ||
474 | static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw, | 491 | static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw, |
@@ -483,7 +500,7 @@ static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw, | |||
483 | if (parent_rate == 0) | 500 | if (parent_rate == 0) |
484 | return 0; | 501 | return 0; |
485 | 502 | ||
486 | val = readl(pll->pll_base + ctrl->mdiv.offset); | 503 | val = readl(pll->control_base + ctrl->mdiv.offset); |
487 | mdiv = (val >> ctrl->mdiv.shift) & bit_mask(ctrl->mdiv.width); | 504 | mdiv = (val >> ctrl->mdiv.shift) & bit_mask(ctrl->mdiv.width); |
488 | if (mdiv == 0) | 505 | if (mdiv == 0) |
489 | mdiv = 256; | 506 | mdiv = 256; |
@@ -530,16 +547,14 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate, | |||
530 | if (div > 256) | 547 | if (div > 256) |
531 | return -EINVAL; | 548 | return -EINVAL; |
532 | 549 | ||
533 | val = readl(pll->pll_base + ctrl->mdiv.offset); | 550 | val = readl(pll->control_base + ctrl->mdiv.offset); |
534 | if (div == 256) { | 551 | if (div == 256) { |
535 | val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift); | 552 | val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift); |
536 | } else { | 553 | } else { |
537 | val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift); | 554 | val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift); |
538 | val |= div << ctrl->mdiv.shift; | 555 | val |= div << ctrl->mdiv.shift; |
539 | } | 556 | } |
540 | writel(val, pll->pll_base + ctrl->mdiv.offset); | 557 | iproc_pll_write(pll, pll->control_base, ctrl->mdiv.offset, val); |
541 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
542 | readl(pll->pll_base + ctrl->mdiv.offset); | ||
543 | clk->rate = parent_rate / div; | 558 | clk->rate = parent_rate / div; |
544 | 559 | ||
545 | return 0; | 560 | return 0; |
@@ -564,11 +579,10 @@ static void iproc_pll_sw_cfg(struct iproc_pll *pll) | |||
564 | if (ctrl->flags & IPROC_CLK_PLL_NEEDS_SW_CFG) { | 579 | if (ctrl->flags & IPROC_CLK_PLL_NEEDS_SW_CFG) { |
565 | u32 val; | 580 | u32 val; |
566 | 581 | ||
567 | val = readl(pll->pll_base + ctrl->sw_ctrl.offset); | 582 | val = readl(pll->control_base + ctrl->sw_ctrl.offset); |
568 | val |= BIT(ctrl->sw_ctrl.shift); | 583 | val |= BIT(ctrl->sw_ctrl.shift); |
569 | writel(val, pll->pll_base + ctrl->sw_ctrl.offset); | 584 | iproc_pll_write(pll, pll->control_base, ctrl->sw_ctrl.offset, |
570 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | 585 | val); |
571 | readl(pll->pll_base + ctrl->sw_ctrl.offset); | ||
572 | } | 586 | } |
573 | } | 587 | } |
574 | 588 | ||
@@ -603,13 +617,12 @@ void __init iproc_pll_clk_setup(struct device_node *node, | |||
603 | if (WARN_ON(!pll->clks)) | 617 | if (WARN_ON(!pll->clks)) |
604 | goto err_clks; | 618 | goto err_clks; |
605 | 619 | ||
606 | pll->pll_base = of_iomap(node, 0); | 620 | pll->control_base = of_iomap(node, 0); |
607 | if (WARN_ON(!pll->pll_base)) | 621 | if (WARN_ON(!pll->control_base)) |
608 | goto err_pll_iomap; | 622 | goto err_pll_iomap; |
609 | 623 | ||
624 | /* Some SoCs do not require the pwr_base, thus failing is not fatal */ | ||
610 | pll->pwr_base = of_iomap(node, 1); | 625 | pll->pwr_base = of_iomap(node, 1); |
611 | if (WARN_ON(!pll->pwr_base)) | ||
612 | goto err_pwr_iomap; | ||
613 | 626 | ||
614 | /* some PLLs require gating control at the top ASIU level */ | 627 | /* some PLLs require gating control at the top ASIU level */ |
615 | if (pll_ctrl->flags & IPROC_CLK_PLL_ASIU) { | 628 | if (pll_ctrl->flags & IPROC_CLK_PLL_ASIU) { |
@@ -618,6 +631,16 @@ void __init iproc_pll_clk_setup(struct device_node *node, | |||
618 | goto err_asiu_iomap; | 631 | goto err_asiu_iomap; |
619 | } | 632 | } |
620 | 633 | ||
634 | if (pll_ctrl->flags & IPROC_CLK_PLL_SPLIT_STAT_CTRL) { | ||
635 | /* Some SoCs have a split status/control. If this does not | ||
636 | * exist, assume they are unified. | ||
637 | */ | ||
638 | pll->status_base = of_iomap(node, 2); | ||
639 | if (!pll->status_base) | ||
640 | goto err_status_iomap; | ||
641 | } else | ||
642 | pll->status_base = pll->control_base; | ||
643 | |||
621 | /* initialize and register the PLL itself */ | 644 | /* initialize and register the PLL itself */ |
622 | pll->ctrl = pll_ctrl; | 645 | pll->ctrl = pll_ctrl; |
623 | 646 | ||
@@ -688,14 +711,18 @@ err_clk_register: | |||
688 | clk_unregister(pll->clk_data.clks[i]); | 711 | clk_unregister(pll->clk_data.clks[i]); |
689 | 712 | ||
690 | err_pll_register: | 713 | err_pll_register: |
714 | if (pll->status_base != pll->control_base) | ||
715 | iounmap(pll->status_base); | ||
716 | |||
717 | err_status_iomap: | ||
691 | if (pll->asiu_base) | 718 | if (pll->asiu_base) |
692 | iounmap(pll->asiu_base); | 719 | iounmap(pll->asiu_base); |
693 | 720 | ||
694 | err_asiu_iomap: | 721 | err_asiu_iomap: |
695 | iounmap(pll->pwr_base); | 722 | if (pll->pwr_base) |
723 | iounmap(pll->pwr_base); | ||
696 | 724 | ||
697 | err_pwr_iomap: | 725 | iounmap(pll->control_base); |
698 | iounmap(pll->pll_base); | ||
699 | 726 | ||
700 | err_pll_iomap: | 727 | err_pll_iomap: |
701 | kfree(pll->clks); | 728 | kfree(pll->clks); |
diff --git a/drivers/clk/bcm/clk-iproc.h b/drivers/clk/bcm/clk-iproc.h index d834b7abd5c6..8988de70a98c 100644 --- a/drivers/clk/bcm/clk-iproc.h +++ b/drivers/clk/bcm/clk-iproc.h | |||
@@ -49,6 +49,18 @@ | |||
49 | #define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4) | 49 | #define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4) |
50 | 50 | ||
51 | /* | 51 | /* |
52 | * Some PLLs use a different way to control clock power, via the PWRDWN bit in | ||
53 | * the PLL control register | ||
54 | */ | ||
55 | #define IPROC_CLK_EMBED_PWRCTRL BIT(5) | ||
56 | |||
57 | /* | ||
58 | * Some PLLs have separate registers for Status and Control. Identify this to | ||
59 | * let the driver know if additional registers need to be used | ||
60 | */ | ||
61 | #define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6) | ||
62 | |||
63 | /* | ||
52 | * Parameters for VCO frequency configuration | 64 | * Parameters for VCO frequency configuration |
53 | * | 65 | * |
54 | * VCO frequency = | 66 | * VCO frequency = |
@@ -88,12 +100,19 @@ struct iproc_pll_aon_pwr_ctrl { | |||
88 | }; | 100 | }; |
89 | 101 | ||
90 | /* | 102 | /* |
91 | * Control of the PLL reset, with Ki, Kp, and Ka parameters | 103 | * Control of the PLL reset |
92 | */ | 104 | */ |
93 | struct iproc_pll_reset_ctrl { | 105 | struct iproc_pll_reset_ctrl { |
94 | unsigned int offset; | 106 | unsigned int offset; |
95 | unsigned int reset_shift; | 107 | unsigned int reset_shift; |
96 | unsigned int p_reset_shift; | 108 | unsigned int p_reset_shift; |
109 | }; | ||
110 | |||
111 | /* | ||
112 | * Control of the Ki, Kp, and Ka parameters | ||
113 | */ | ||
114 | struct iproc_pll_dig_filter_ctrl { | ||
115 | unsigned int offset; | ||
97 | unsigned int ki_shift; | 116 | unsigned int ki_shift; |
98 | unsigned int ki_width; | 117 | unsigned int ki_width; |
99 | unsigned int kp_shift; | 118 | unsigned int kp_shift; |
@@ -123,6 +142,7 @@ struct iproc_pll_ctrl { | |||
123 | struct iproc_pll_aon_pwr_ctrl aon; | 142 | struct iproc_pll_aon_pwr_ctrl aon; |
124 | struct iproc_asiu_gate asiu; | 143 | struct iproc_asiu_gate asiu; |
125 | struct iproc_pll_reset_ctrl reset; | 144 | struct iproc_pll_reset_ctrl reset; |
145 | struct iproc_pll_dig_filter_ctrl dig_filter; | ||
126 | struct iproc_pll_sw_ctrl sw_ctrl; | 146 | struct iproc_pll_sw_ctrl sw_ctrl; |
127 | struct iproc_clk_reg_op ndiv_int; | 147 | struct iproc_clk_reg_op ndiv_int; |
128 | struct iproc_clk_reg_op ndiv_frac; | 148 | struct iproc_clk_reg_op ndiv_frac; |
diff --git a/drivers/clk/bcm/clk-ns2.c b/drivers/clk/bcm/clk-ns2.c new file mode 100644 index 000000000000..a564e9248814 --- /dev/null +++ b/drivers/clk/bcm/clk-ns2.c | |||
@@ -0,0 +1,288 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/clk-provider.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | |||
21 | #include <dt-bindings/clock/bcm-ns2.h> | ||
22 | #include "clk-iproc.h" | ||
23 | |||
24 | #define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, } | ||
25 | |||
26 | #define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \ | ||
27 | .pwr_shift = ps, .iso_shift = is } | ||
28 | |||
29 | #define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \ | ||
30 | .p_reset_shift = prs } | ||
31 | |||
32 | #define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\ | ||
33 | .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas, \ | ||
34 | .ka_width = kaw } | ||
35 | |||
36 | #define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo } | ||
37 | |||
38 | #define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \ | ||
39 | .hold_shift = hs, .bypass_shift = bs } | ||
40 | |||
41 | static const struct iproc_pll_ctrl genpll_scr = { | ||
42 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL, | ||
43 | .aon = AON_VAL(0x0, 1, 15, 12), | ||
44 | .reset = RESET_VAL(0x4, 2, 1), | ||
45 | .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 2, 3), | ||
46 | .ndiv_int = REG_VAL(0x8, 4, 10), | ||
47 | .pdiv = REG_VAL(0x8, 0, 4), | ||
48 | .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc), | ||
49 | .status = REG_VAL(0x0, 27, 1), | ||
50 | }; | ||
51 | |||
52 | |||
53 | static const struct iproc_clk_ctrl genpll_scr_clk[] = { | ||
54 | /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined | ||
55 | * in NS2. However, it doesn't appear to be used anywhere, so setting | ||
56 | * it to 0. | ||
57 | */ | ||
58 | [BCM_NS2_GENPLL_SCR_SCR_CLK] = { | ||
59 | .channel = BCM_NS2_GENPLL_SCR_SCR_CLK, | ||
60 | .flags = IPROC_CLK_AON, | ||
61 | .enable = ENABLE_VAL(0x0, 18, 12, 0), | ||
62 | .mdiv = REG_VAL(0x18, 0, 8), | ||
63 | }, | ||
64 | [BCM_NS2_GENPLL_SCR_FS_CLK] = { | ||
65 | .channel = BCM_NS2_GENPLL_SCR_FS_CLK, | ||
66 | .flags = IPROC_CLK_AON, | ||
67 | .enable = ENABLE_VAL(0x0, 19, 13, 0), | ||
68 | .mdiv = REG_VAL(0x18, 8, 8), | ||
69 | }, | ||
70 | [BCM_NS2_GENPLL_SCR_AUDIO_CLK] = { | ||
71 | .channel = BCM_NS2_GENPLL_SCR_AUDIO_CLK, | ||
72 | .flags = IPROC_CLK_AON, | ||
73 | .enable = ENABLE_VAL(0x0, 20, 14, 0), | ||
74 | .mdiv = REG_VAL(0x14, 0, 8), | ||
75 | }, | ||
76 | [BCM_NS2_GENPLL_SCR_CH3_UNUSED] = { | ||
77 | .channel = BCM_NS2_GENPLL_SCR_CH3_UNUSED, | ||
78 | .flags = IPROC_CLK_AON, | ||
79 | .enable = ENABLE_VAL(0x0, 21, 15, 0), | ||
80 | .mdiv = REG_VAL(0x14, 8, 8), | ||
81 | }, | ||
82 | [BCM_NS2_GENPLL_SCR_CH4_UNUSED] = { | ||
83 | .channel = BCM_NS2_GENPLL_SCR_CH4_UNUSED, | ||
84 | .flags = IPROC_CLK_AON, | ||
85 | .enable = ENABLE_VAL(0x0, 22, 16, 0), | ||
86 | .mdiv = REG_VAL(0x14, 16, 8), | ||
87 | }, | ||
88 | [BCM_NS2_GENPLL_SCR_CH5_UNUSED] = { | ||
89 | .channel = BCM_NS2_GENPLL_SCR_CH5_UNUSED, | ||
90 | .flags = IPROC_CLK_AON, | ||
91 | .enable = ENABLE_VAL(0x0, 23, 17, 0), | ||
92 | .mdiv = REG_VAL(0x14, 24, 8), | ||
93 | }, | ||
94 | }; | ||
95 | |||
96 | static void __init ns2_genpll_scr_clk_init(struct device_node *node) | ||
97 | { | ||
98 | iproc_pll_clk_setup(node, &genpll_scr, NULL, 0, genpll_scr_clk, | ||
99 | ARRAY_SIZE(genpll_scr_clk)); | ||
100 | } | ||
101 | CLK_OF_DECLARE(ns2_genpll_src_clk, "brcm,ns2-genpll-scr", | ||
102 | ns2_genpll_scr_clk_init); | ||
103 | |||
104 | static const struct iproc_pll_ctrl genpll_sw = { | ||
105 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL, | ||
106 | .aon = AON_VAL(0x0, 2, 9, 8), | ||
107 | .reset = RESET_VAL(0x4, 2, 1), | ||
108 | .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 2, 3), | ||
109 | .ndiv_int = REG_VAL(0x8, 4, 10), | ||
110 | .pdiv = REG_VAL(0x8, 0, 4), | ||
111 | .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc), | ||
112 | .status = REG_VAL(0x0, 13, 1), | ||
113 | }; | ||
114 | |||
115 | static const struct iproc_clk_ctrl genpll_sw_clk[] = { | ||
116 | /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined | ||
117 | * in NS2. However, it doesn't appear to be used anywhere, so setting | ||
118 | * it to 0. | ||
119 | */ | ||
120 | [BCM_NS2_GENPLL_SW_RPE_CLK] = { | ||
121 | .channel = BCM_NS2_GENPLL_SW_RPE_CLK, | ||
122 | .flags = IPROC_CLK_AON, | ||
123 | .enable = ENABLE_VAL(0x0, 18, 12, 0), | ||
124 | .mdiv = REG_VAL(0x18, 0, 8), | ||
125 | }, | ||
126 | [BCM_NS2_GENPLL_SW_250_CLK] = { | ||
127 | .channel = BCM_NS2_GENPLL_SW_250_CLK, | ||
128 | .flags = IPROC_CLK_AON, | ||
129 | .enable = ENABLE_VAL(0x0, 19, 13, 0), | ||
130 | .mdiv = REG_VAL(0x18, 8, 8), | ||
131 | }, | ||
132 | [BCM_NS2_GENPLL_SW_NIC_CLK] = { | ||
133 | .channel = BCM_NS2_GENPLL_SW_NIC_CLK, | ||
134 | .flags = IPROC_CLK_AON, | ||
135 | .enable = ENABLE_VAL(0x0, 20, 14, 0), | ||
136 | .mdiv = REG_VAL(0x14, 0, 8), | ||
137 | }, | ||
138 | [BCM_NS2_GENPLL_SW_CHIMP_CLK] = { | ||
139 | .channel = BCM_NS2_GENPLL_SW_CHIMP_CLK, | ||
140 | .flags = IPROC_CLK_AON, | ||
141 | .enable = ENABLE_VAL(0x0, 21, 15, 0), | ||
142 | .mdiv = REG_VAL(0x14, 8, 8), | ||
143 | }, | ||
144 | [BCM_NS2_GENPLL_SW_PORT_CLK] = { | ||
145 | .channel = BCM_NS2_GENPLL_SW_PORT_CLK, | ||
146 | .flags = IPROC_CLK_AON, | ||
147 | .enable = ENABLE_VAL(0x0, 22, 16, 0), | ||
148 | .mdiv = REG_VAL(0x14, 16, 8), | ||
149 | }, | ||
150 | [BCM_NS2_GENPLL_SW_SDIO_CLK] = { | ||
151 | .channel = BCM_NS2_GENPLL_SW_SDIO_CLK, | ||
152 | .flags = IPROC_CLK_AON, | ||
153 | .enable = ENABLE_VAL(0x0, 23, 17, 0), | ||
154 | .mdiv = REG_VAL(0x14, 24, 8), | ||
155 | }, | ||
156 | }; | ||
157 | |||
158 | static void __init ns2_genpll_sw_clk_init(struct device_node *node) | ||
159 | { | ||
160 | iproc_pll_clk_setup(node, &genpll_sw, NULL, 0, genpll_sw_clk, | ||
161 | ARRAY_SIZE(genpll_sw_clk)); | ||
162 | } | ||
163 | CLK_OF_DECLARE(ns2_genpll_sw_clk, "brcm,ns2-genpll-sw", | ||
164 | ns2_genpll_sw_clk_init); | ||
165 | |||
166 | static const struct iproc_pll_ctrl lcpll_ddr = { | ||
167 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL, | ||
168 | .aon = AON_VAL(0x0, 2, 1, 0), | ||
169 | .reset = RESET_VAL(0x4, 2, 1), | ||
170 | .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 1, 4), | ||
171 | .ndiv_int = REG_VAL(0x8, 4, 10), | ||
172 | .pdiv = REG_VAL(0x8, 0, 4), | ||
173 | .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc), | ||
174 | .status = REG_VAL(0x0, 0, 1), | ||
175 | }; | ||
176 | |||
177 | static const struct iproc_clk_ctrl lcpll_ddr_clk[] = { | ||
178 | /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined | ||
179 | * in NS2. However, it doesn't appear to be used anywhere, so setting | ||
180 | * it to 0. | ||
181 | */ | ||
182 | [BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK] = { | ||
183 | .channel = BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK, | ||
184 | .flags = IPROC_CLK_AON, | ||
185 | .enable = ENABLE_VAL(0x0, 18, 12, 0), | ||
186 | .mdiv = REG_VAL(0x14, 0, 8), | ||
187 | }, | ||
188 | [BCM_NS2_LCPLL_DDR_DDR_CLK] = { | ||
189 | .channel = BCM_NS2_LCPLL_DDR_DDR_CLK, | ||
190 | .flags = IPROC_CLK_AON, | ||
191 | .enable = ENABLE_VAL(0x0, 19, 13, 0), | ||
192 | .mdiv = REG_VAL(0x14, 8, 8), | ||
193 | }, | ||
194 | [BCM_NS2_LCPLL_DDR_CH2_UNUSED] = { | ||
195 | .channel = BCM_NS2_LCPLL_DDR_CH2_UNUSED, | ||
196 | .flags = IPROC_CLK_AON, | ||
197 | .enable = ENABLE_VAL(0x0, 20, 14, 0), | ||
198 | .mdiv = REG_VAL(0x10, 0, 8), | ||
199 | }, | ||
200 | [BCM_NS2_LCPLL_DDR_CH3_UNUSED] = { | ||
201 | .channel = BCM_NS2_LCPLL_DDR_CH3_UNUSED, | ||
202 | .flags = IPROC_CLK_AON, | ||
203 | .enable = ENABLE_VAL(0x0, 21, 15, 0), | ||
204 | .mdiv = REG_VAL(0x10, 8, 8), | ||
205 | }, | ||
206 | [BCM_NS2_LCPLL_DDR_CH4_UNUSED] = { | ||
207 | .channel = BCM_NS2_LCPLL_DDR_CH4_UNUSED, | ||
208 | .flags = IPROC_CLK_AON, | ||
209 | .enable = ENABLE_VAL(0x0, 22, 16, 0), | ||
210 | .mdiv = REG_VAL(0x10, 16, 8), | ||
211 | }, | ||
212 | [BCM_NS2_LCPLL_DDR_CH5_UNUSED] = { | ||
213 | .channel = BCM_NS2_LCPLL_DDR_CH5_UNUSED, | ||
214 | .flags = IPROC_CLK_AON, | ||
215 | .enable = ENABLE_VAL(0x0, 23, 17, 0), | ||
216 | .mdiv = REG_VAL(0x10, 24, 8), | ||
217 | }, | ||
218 | }; | ||
219 | |||
220 | static void __init ns2_lcpll_ddr_clk_init(struct device_node *node) | ||
221 | { | ||
222 | iproc_pll_clk_setup(node, &lcpll_ddr, NULL, 0, lcpll_ddr_clk, | ||
223 | ARRAY_SIZE(lcpll_ddr_clk)); | ||
224 | } | ||
225 | CLK_OF_DECLARE(ns2_lcpll_ddr_clk, "brcm,ns2-lcpll-ddr", | ||
226 | ns2_lcpll_ddr_clk_init); | ||
227 | |||
228 | static const struct iproc_pll_ctrl lcpll_ports = { | ||
229 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL, | ||
230 | .aon = AON_VAL(0x0, 2, 5, 4), | ||
231 | .reset = RESET_VAL(0x4, 2, 1), | ||
232 | .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 1, 4), | ||
233 | .ndiv_int = REG_VAL(0x8, 4, 10), | ||
234 | .pdiv = REG_VAL(0x8, 0, 4), | ||
235 | .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc), | ||
236 | .status = REG_VAL(0x0, 0, 1), | ||
237 | }; | ||
238 | |||
239 | static const struct iproc_clk_ctrl lcpll_ports_clk[] = { | ||
240 | /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined | ||
241 | * in NS2. However, it doesn't appear to be used anywhere, so setting | ||
242 | * it to 0. | ||
243 | */ | ||
244 | [BCM_NS2_LCPLL_PORTS_WAN_CLK] = { | ||
245 | .channel = BCM_NS2_LCPLL_PORTS_WAN_CLK, | ||
246 | .flags = IPROC_CLK_AON, | ||
247 | .enable = ENABLE_VAL(0x0, 18, 12, 0), | ||
248 | .mdiv = REG_VAL(0x14, 0, 8), | ||
249 | }, | ||
250 | [BCM_NS2_LCPLL_PORTS_RGMII_CLK] = { | ||
251 | .channel = BCM_NS2_LCPLL_PORTS_RGMII_CLK, | ||
252 | .flags = IPROC_CLK_AON, | ||
253 | .enable = ENABLE_VAL(0x0, 19, 13, 0), | ||
254 | .mdiv = REG_VAL(0x14, 8, 8), | ||
255 | }, | ||
256 | [BCM_NS2_LCPLL_PORTS_CH2_UNUSED] = { | ||
257 | .channel = BCM_NS2_LCPLL_PORTS_CH2_UNUSED, | ||
258 | .flags = IPROC_CLK_AON, | ||
259 | .enable = ENABLE_VAL(0x0, 20, 14, 0), | ||
260 | .mdiv = REG_VAL(0x10, 0, 8), | ||
261 | }, | ||
262 | [BCM_NS2_LCPLL_PORTS_CH3_UNUSED] = { | ||
263 | .channel = BCM_NS2_LCPLL_PORTS_CH3_UNUSED, | ||
264 | .flags = IPROC_CLK_AON, | ||
265 | .enable = ENABLE_VAL(0x0, 21, 15, 0), | ||
266 | .mdiv = REG_VAL(0x10, 8, 8), | ||
267 | }, | ||
268 | [BCM_NS2_LCPLL_PORTS_CH4_UNUSED] = { | ||
269 | .channel = BCM_NS2_LCPLL_PORTS_CH4_UNUSED, | ||
270 | .flags = IPROC_CLK_AON, | ||
271 | .enable = ENABLE_VAL(0x0, 22, 16, 0), | ||
272 | .mdiv = REG_VAL(0x10, 16, 8), | ||
273 | }, | ||
274 | [BCM_NS2_LCPLL_PORTS_CH5_UNUSED] = { | ||
275 | .channel = BCM_NS2_LCPLL_PORTS_CH5_UNUSED, | ||
276 | .flags = IPROC_CLK_AON, | ||
277 | .enable = ENABLE_VAL(0x0, 23, 17, 0), | ||
278 | .mdiv = REG_VAL(0x10, 24, 8), | ||
279 | }, | ||
280 | }; | ||
281 | |||
282 | static void __init ns2_lcpll_ports_clk_init(struct device_node *node) | ||
283 | { | ||
284 | iproc_pll_clk_setup(node, &lcpll_ports, NULL, 0, lcpll_ports_clk, | ||
285 | ARRAY_SIZE(lcpll_ports_clk)); | ||
286 | } | ||
287 | CLK_OF_DECLARE(ns2_lcpll_ports_clk, "brcm,ns2-lcpll-ports", | ||
288 | ns2_lcpll_ports_clk_init); | ||
diff --git a/drivers/clk/bcm/clk-nsp.c b/drivers/clk/bcm/clk-nsp.c new file mode 100644 index 000000000000..cf66f640a47d --- /dev/null +++ b/drivers/clk/bcm/clk-nsp.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/clk-provider.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | |||
21 | #include <dt-bindings/clock/bcm-nsp.h> | ||
22 | #include "clk-iproc.h" | ||
23 | |||
24 | #define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, } | ||
25 | |||
26 | #define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \ | ||
27 | .pwr_shift = ps, .iso_shift = is } | ||
28 | |||
29 | #define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \ | ||
30 | .p_reset_shift = prs } | ||
31 | |||
32 | #define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\ | ||
33 | .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas, \ | ||
34 | .ka_width = kaw } | ||
35 | |||
36 | #define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \ | ||
37 | .hold_shift = hs, .bypass_shift = bs } | ||
38 | |||
39 | static void __init nsp_armpll_init(struct device_node *node) | ||
40 | { | ||
41 | iproc_armpll_setup(node); | ||
42 | } | ||
43 | CLK_OF_DECLARE(nsp_armpll, "brcm,nsp-armpll", nsp_armpll_init); | ||
44 | |||
45 | static const struct iproc_pll_ctrl genpll = { | ||
46 | .flags = IPROC_CLK_PLL_HAS_NDIV_FRAC | IPROC_CLK_EMBED_PWRCTRL, | ||
47 | .aon = AON_VAL(0x0, 1, 12, 0), | ||
48 | .reset = RESET_VAL(0x0, 11, 10), | ||
49 | .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3), | ||
50 | .ndiv_int = REG_VAL(0x14, 20, 10), | ||
51 | .ndiv_frac = REG_VAL(0x14, 0, 20), | ||
52 | .pdiv = REG_VAL(0x18, 24, 3), | ||
53 | .status = REG_VAL(0x20, 12, 1), | ||
54 | }; | ||
55 | |||
56 | static const struct iproc_clk_ctrl genpll_clk[] = { | ||
57 | [BCM_NSP_GENPLL_PHY_CLK] = { | ||
58 | .channel = BCM_NSP_GENPLL_PHY_CLK, | ||
59 | .flags = IPROC_CLK_AON, | ||
60 | .enable = ENABLE_VAL(0x4, 12, 6, 18), | ||
61 | .mdiv = REG_VAL(0x18, 16, 8), | ||
62 | }, | ||
63 | [BCM_NSP_GENPLL_ENET_SW_CLK] = { | ||
64 | .channel = BCM_NSP_GENPLL_ENET_SW_CLK, | ||
65 | .flags = IPROC_CLK_AON, | ||
66 | .enable = ENABLE_VAL(0x4, 13, 7, 19), | ||
67 | .mdiv = REG_VAL(0x18, 8, 8), | ||
68 | }, | ||
69 | [BCM_NSP_GENPLL_USB_PHY_REF_CLK] = { | ||
70 | .channel = BCM_NSP_GENPLL_USB_PHY_REF_CLK, | ||
71 | .flags = IPROC_CLK_AON, | ||
72 | .enable = ENABLE_VAL(0x4, 14, 8, 20), | ||
73 | .mdiv = REG_VAL(0x18, 0, 8), | ||
74 | }, | ||
75 | [BCM_NSP_GENPLL_IPROCFAST_CLK] = { | ||
76 | .channel = BCM_NSP_GENPLL_IPROCFAST_CLK, | ||
77 | .flags = IPROC_CLK_AON, | ||
78 | .enable = ENABLE_VAL(0x4, 15, 9, 21), | ||
79 | .mdiv = REG_VAL(0x1c, 16, 8), | ||
80 | }, | ||
81 | [BCM_NSP_GENPLL_SATA1_CLK] = { | ||
82 | .channel = BCM_NSP_GENPLL_SATA1_CLK, | ||
83 | .flags = IPROC_CLK_AON, | ||
84 | .enable = ENABLE_VAL(0x4, 16, 10, 22), | ||
85 | .mdiv = REG_VAL(0x1c, 8, 8), | ||
86 | }, | ||
87 | [BCM_NSP_GENPLL_SATA2_CLK] = { | ||
88 | .channel = BCM_NSP_GENPLL_SATA2_CLK, | ||
89 | .flags = IPROC_CLK_AON, | ||
90 | .enable = ENABLE_VAL(0x4, 17, 11, 23), | ||
91 | .mdiv = REG_VAL(0x1c, 0, 8), | ||
92 | }, | ||
93 | }; | ||
94 | |||
95 | static void __init nsp_genpll_clk_init(struct device_node *node) | ||
96 | { | ||
97 | iproc_pll_clk_setup(node, &genpll, NULL, 0, genpll_clk, | ||
98 | ARRAY_SIZE(genpll_clk)); | ||
99 | } | ||
100 | CLK_OF_DECLARE(nsp_genpll_clk, "brcm,nsp-genpll", nsp_genpll_clk_init); | ||
101 | |||
102 | static const struct iproc_pll_ctrl lcpll0 = { | ||
103 | .flags = IPROC_CLK_PLL_HAS_NDIV_FRAC | IPROC_CLK_EMBED_PWRCTRL, | ||
104 | .aon = AON_VAL(0x0, 1, 24, 0), | ||
105 | .reset = RESET_VAL(0x0, 23, 22), | ||
106 | .dig_filter = DF_VAL(0x0, 16, 3, 12, 4, 19, 4), | ||
107 | .ndiv_int = REG_VAL(0x4, 20, 8), | ||
108 | .ndiv_frac = REG_VAL(0x4, 0, 20), | ||
109 | .pdiv = REG_VAL(0x4, 28, 3), | ||
110 | .status = REG_VAL(0x10, 12, 1), | ||
111 | }; | ||
112 | |||
113 | static const struct iproc_clk_ctrl lcpll0_clk[] = { | ||
114 | [BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK] = { | ||
115 | .channel = BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK, | ||
116 | .flags = IPROC_CLK_AON, | ||
117 | .enable = ENABLE_VAL(0x0, 6, 3, 9), | ||
118 | .mdiv = REG_VAL(0x8, 24, 8), | ||
119 | }, | ||
120 | [BCM_NSP_LCPLL0_SDIO_CLK] = { | ||
121 | .channel = BCM_NSP_LCPLL0_SDIO_CLK, | ||
122 | .flags = IPROC_CLK_AON, | ||
123 | .enable = ENABLE_VAL(0x0, 7, 4, 10), | ||
124 | .mdiv = REG_VAL(0x8, 16, 8), | ||
125 | }, | ||
126 | [BCM_NSP_LCPLL0_DDR_PHY_CLK] = { | ||
127 | .channel = BCM_NSP_LCPLL0_DDR_PHY_CLK, | ||
128 | .flags = IPROC_CLK_AON, | ||
129 | .enable = ENABLE_VAL(0x0, 8, 5, 11), | ||
130 | .mdiv = REG_VAL(0x8, 8, 8), | ||
131 | }, | ||
132 | }; | ||
133 | |||
134 | static void __init nsp_lcpll0_clk_init(struct device_node *node) | ||
135 | { | ||
136 | iproc_pll_clk_setup(node, &lcpll0, NULL, 0, lcpll0_clk, | ||
137 | ARRAY_SIZE(lcpll0_clk)); | ||
138 | } | ||
139 | CLK_OF_DECLARE(nsp_lcpll0_clk, "brcm,nsp-lcpll0", nsp_lcpll0_clk_init); | ||
diff --git a/include/dt-bindings/clock/bcm-ns2.h b/include/dt-bindings/clock/bcm-ns2.h new file mode 100644 index 000000000000..d99c7a2e70cb --- /dev/null +++ b/include/dt-bindings/clock/bcm-ns2.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * BSD LICENSE | ||
3 | * | ||
4 | * Copyright(c) 2015 Broadcom Corporation. All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * | ||
10 | * * Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * * Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * * Neither the name of Broadcom Corporation nor the names of its | ||
17 | * contributors may be used to endorse or promote products derived | ||
18 | * from this software without specific prior written permission. | ||
19 | * | ||
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | */ | ||
32 | |||
33 | #ifndef _CLOCK_BCM_NS2_H | ||
34 | #define _CLOCK_BCM_NS2_H | ||
35 | |||
36 | /* GENPLL SCR clock channel ID */ | ||
37 | #define BCM_NS2_GENPLL_SCR 0 | ||
38 | #define BCM_NS2_GENPLL_SCR_SCR_CLK 1 | ||
39 | #define BCM_NS2_GENPLL_SCR_FS_CLK 2 | ||
40 | #define BCM_NS2_GENPLL_SCR_AUDIO_CLK 3 | ||
41 | #define BCM_NS2_GENPLL_SCR_CH3_UNUSED 4 | ||
42 | #define BCM_NS2_GENPLL_SCR_CH4_UNUSED 5 | ||
43 | #define BCM_NS2_GENPLL_SCR_CH5_UNUSED 6 | ||
44 | |||
45 | /* GENPLL SW clock channel ID */ | ||
46 | #define BCM_NS2_GENPLL_SW 0 | ||
47 | #define BCM_NS2_GENPLL_SW_RPE_CLK 1 | ||
48 | #define BCM_NS2_GENPLL_SW_250_CLK 2 | ||
49 | #define BCM_NS2_GENPLL_SW_NIC_CLK 3 | ||
50 | #define BCM_NS2_GENPLL_SW_CHIMP_CLK 4 | ||
51 | #define BCM_NS2_GENPLL_SW_PORT_CLK 5 | ||
52 | #define BCM_NS2_GENPLL_SW_SDIO_CLK 6 | ||
53 | |||
54 | /* LCPLL DDR clock channel ID */ | ||
55 | #define BCM_NS2_LCPLL_DDR 0 | ||
56 | #define BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK 1 | ||
57 | #define BCM_NS2_LCPLL_DDR_DDR_CLK 2 | ||
58 | #define BCM_NS2_LCPLL_DDR_CH2_UNUSED 3 | ||
59 | #define BCM_NS2_LCPLL_DDR_CH3_UNUSED 4 | ||
60 | #define BCM_NS2_LCPLL_DDR_CH4_UNUSED 5 | ||
61 | #define BCM_NS2_LCPLL_DDR_CH5_UNUSED 6 | ||
62 | |||
63 | /* LCPLL PORTS clock channel ID */ | ||
64 | #define BCM_NS2_LCPLL_PORTS 0 | ||
65 | #define BCM_NS2_LCPLL_PORTS_WAN_CLK 1 | ||
66 | #define BCM_NS2_LCPLL_PORTS_RGMII_CLK 2 | ||
67 | #define BCM_NS2_LCPLL_PORTS_CH2_UNUSED 3 | ||
68 | #define BCM_NS2_LCPLL_PORTS_CH3_UNUSED 4 | ||
69 | #define BCM_NS2_LCPLL_PORTS_CH4_UNUSED 5 | ||
70 | #define BCM_NS2_LCPLL_PORTS_CH5_UNUSED 6 | ||
71 | |||
72 | #endif /* _CLOCK_BCM_NS2_H */ | ||
diff --git a/include/dt-bindings/clock/bcm-nsp.h b/include/dt-bindings/clock/bcm-nsp.h new file mode 100644 index 000000000000..ad5827cde782 --- /dev/null +++ b/include/dt-bindings/clock/bcm-nsp.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * BSD LICENSE | ||
3 | * | ||
4 | * Copyright(c) 2015 Broadcom Corporation. All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * | ||
10 | * * Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * * Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * * Neither the name of Broadcom Corporation nor the names of its | ||
17 | * contributors may be used to endorse or promote products derived | ||
18 | * from this software without specific prior written permission. | ||
19 | * | ||
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | */ | ||
32 | |||
33 | #ifndef _CLOCK_BCM_NSP_H | ||
34 | #define _CLOCK_BCM_NSP_H | ||
35 | |||
36 | /* GENPLL clock channel ID */ | ||
37 | #define BCM_NSP_GENPLL 0 | ||
38 | #define BCM_NSP_GENPLL_PHY_CLK 1 | ||
39 | #define BCM_NSP_GENPLL_ENET_SW_CLK 2 | ||
40 | #define BCM_NSP_GENPLL_USB_PHY_REF_CLK 3 | ||
41 | #define BCM_NSP_GENPLL_IPROCFAST_CLK 4 | ||
42 | #define BCM_NSP_GENPLL_SATA1_CLK 5 | ||
43 | #define BCM_NSP_GENPLL_SATA2_CLK 6 | ||
44 | |||
45 | /* LCPLL0 clock channel ID */ | ||
46 | #define BCM_NSP_LCPLL0 0 | ||
47 | #define BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK 1 | ||
48 | #define BCM_NSP_LCPLL0_SDIO_CLK 2 | ||
49 | #define BCM_NSP_LCPLL0_DDR_PHY_CLK 3 | ||
50 | |||
51 | #endif /* _CLOCK_BCM_NSP_H */ | ||