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, 1, 11, 10), 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); 289