1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * 4 * Copyright (C) 2010 John Crispin <john@phrozen.org> 5 * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG 6 */ 7 8 #include <linux/io.h> 9 #include <linux/export.h> 10 #include <linux/clk.h> 11 12 #include <asm/time.h> 13 #include <asm/irq.h> 14 #include <asm/div64.h> 15 16 #include <lantiq_soc.h> 17 18 #include "../clk.h" 19 20 static unsigned int ram_clocks[] = { 21 CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M }; 22 #define DDR_HZ ram_clocks[ltq_cgu_r32(CGU_SYS) & 0x3] 23 24 /* legacy xway clock */ 25 #define CGU_SYS 0x10 26 27 /* vr9, ar10/grx390 clock */ 28 #define CGU_SYS_XRX 0x0c 29 #define CGU_IF_CLK_AR10 0x24 30 31 unsigned long ltq_danube_fpi_hz(void) 32 { 33 unsigned long ddr_clock = DDR_HZ; 34 35 if (ltq_cgu_r32(CGU_SYS) & 0x40) 36 return ddr_clock >> 1; 37 return ddr_clock; 38 } 39 40 unsigned long ltq_danube_cpu_hz(void) 41 { 42 switch (ltq_cgu_r32(CGU_SYS) & 0xc) { 43 case 0: 44 return CLOCK_333M; 45 case 4: 46 return DDR_HZ; 47 case 8: 48 return DDR_HZ << 1; 49 default: 50 return DDR_HZ >> 1; 51 } 52 } 53 54 unsigned long ltq_danube_pp32_hz(void) 55 { 56 unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 7) & 3; 57 unsigned long clk; 58 59 switch (clksys) { 60 case 1: 61 clk = CLOCK_240M; 62 break; 63 case 2: 64 clk = CLOCK_222M; 65 break; 66 case 3: 67 clk = CLOCK_133M; 68 break; 69 default: 70 clk = CLOCK_266M; 71 break; 72 } 73 74 return clk; 75 } 76 77 unsigned long ltq_ar9_sys_hz(void) 78 { 79 if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2) 80 return CLOCK_393M; 81 return CLOCK_333M; 82 } 83 84 unsigned long ltq_ar9_fpi_hz(void) 85 { 86 unsigned long sys = ltq_ar9_sys_hz(); 87 88 if (ltq_cgu_r32(CGU_SYS) & BIT(0)) 89 return sys / 3; 90 else 91 return sys / 2; 92 } 93 94 unsigned long ltq_ar9_cpu_hz(void) 95 { 96 if (ltq_cgu_r32(CGU_SYS) & BIT(2)) 97 return ltq_ar9_fpi_hz(); 98 else 99 return ltq_ar9_sys_hz(); 100 } 101 102 unsigned long ltq_vr9_cpu_hz(void) 103 { 104 unsigned int cpu_sel; 105 unsigned long clk; 106 107 cpu_sel = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0xf; 108 109 switch (cpu_sel) { 110 case 0: 111 clk = CLOCK_600M; 112 break; 113 case 1: 114 clk = CLOCK_500M; 115 break; 116 case 2: 117 clk = CLOCK_393M; 118 break; 119 case 3: 120 clk = CLOCK_333M; 121 break; 122 case 5: 123 case 6: 124 clk = CLOCK_196_608M; 125 break; 126 case 7: 127 clk = CLOCK_167M; 128 break; 129 case 4: 130 case 8: 131 case 9: 132 clk = CLOCK_125M; 133 break; 134 default: 135 clk = 0; 136 break; 137 } 138 139 return clk; 140 } 141 142 unsigned long ltq_vr9_fpi_hz(void) 143 { 144 unsigned int ocp_sel, cpu_clk; 145 unsigned long clk; 146 147 cpu_clk = ltq_vr9_cpu_hz(); 148 ocp_sel = ltq_cgu_r32(CGU_SYS_XRX) & 0x3; 149 150 switch (ocp_sel) { 151 case 0: 152 /* OCP ratio 1 */ 153 clk = cpu_clk; 154 break; 155 case 2: 156 /* OCP ratio 2 */ 157 clk = cpu_clk / 2; 158 break; 159 case 3: 160 /* OCP ratio 2.5 */ 161 clk = (cpu_clk * 2) / 5; 162 break; 163 case 4: 164 /* OCP ratio 3 */ 165 clk = cpu_clk / 3; 166 break; 167 default: 168 clk = 0; 169 break; 170 } 171 172 return clk; 173 } 174 175 unsigned long ltq_vr9_pp32_hz(void) 176 { 177 unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; 178 unsigned long clk; 179 180 switch (clksys) { 181 case 0: 182 clk = CLOCK_500M; 183 break; 184 case 1: 185 clk = CLOCK_432M; 186 break; 187 case 2: 188 clk = CLOCK_288M; 189 break; 190 default: 191 clk = CLOCK_500M; 192 break; 193 } 194 195 return clk; 196 } 197 198 unsigned long ltq_ar10_cpu_hz(void) 199 { 200 unsigned int clksys; 201 int cpu_fs = (ltq_cgu_r32(CGU_SYS_XRX) >> 8) & 0x1; 202 int freq_div = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7; 203 204 switch (cpu_fs) { 205 case 0: 206 clksys = CLOCK_500M; 207 break; 208 case 1: 209 clksys = CLOCK_600M; 210 break; 211 default: 212 clksys = CLOCK_500M; 213 break; 214 } 215 216 switch (freq_div) { 217 case 0: 218 return clksys; 219 case 1: 220 return clksys >> 1; 221 case 2: 222 return clksys >> 2; 223 default: 224 return clksys; 225 } 226 } 227 228 unsigned long ltq_ar10_fpi_hz(void) 229 { 230 int freq_fpi = (ltq_cgu_r32(CGU_IF_CLK_AR10) >> 25) & 0xf; 231 232 switch (freq_fpi) { 233 case 1: 234 return CLOCK_300M; 235 case 5: 236 return CLOCK_250M; 237 case 2: 238 return CLOCK_150M; 239 case 6: 240 return CLOCK_125M; 241 242 default: 243 return CLOCK_125M; 244 } 245 } 246 247 unsigned long ltq_ar10_pp32_hz(void) 248 { 249 unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; 250 unsigned long clk; 251 252 switch (clksys) { 253 case 1: 254 clk = CLOCK_250M; 255 break; 256 case 4: 257 clk = CLOCK_400M; 258 break; 259 default: 260 clk = CLOCK_250M; 261 break; 262 } 263 264 return clk; 265 } 266 267 unsigned long ltq_grx390_cpu_hz(void) 268 { 269 unsigned int clksys; 270 int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3); 271 int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7); 272 273 switch (cpu_fs) { 274 case 0: 275 clksys = CLOCK_600M; 276 break; 277 case 1: 278 clksys = CLOCK_666M; 279 break; 280 case 2: 281 clksys = CLOCK_720M; 282 break; 283 default: 284 clksys = CLOCK_600M; 285 break; 286 } 287 288 switch (freq_div) { 289 case 0: 290 return clksys; 291 case 1: 292 return clksys >> 1; 293 case 2: 294 return clksys >> 2; 295 default: 296 return clksys; 297 } 298 } 299 300 unsigned long ltq_grx390_fpi_hz(void) 301 { 302 /* fpi clock is derived from ddr_clk */ 303 unsigned int clksys; 304 int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3); 305 int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX)) & 0x7); 306 switch (cpu_fs) { 307 case 0: 308 clksys = CLOCK_600M; 309 break; 310 case 1: 311 clksys = CLOCK_666M; 312 break; 313 case 2: 314 clksys = CLOCK_720M; 315 break; 316 default: 317 clksys = CLOCK_600M; 318 break; 319 } 320 321 switch (freq_div) { 322 case 1: 323 return clksys >> 1; 324 case 2: 325 return clksys >> 2; 326 default: 327 return clksys >> 1; 328 } 329 } 330 331 unsigned long ltq_grx390_pp32_hz(void) 332 { 333 unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; 334 unsigned long clk; 335 336 switch (clksys) { 337 case 1: 338 clk = CLOCK_250M; 339 break; 340 case 2: 341 clk = CLOCK_432M; 342 break; 343 case 4: 344 clk = CLOCK_400M; 345 break; 346 default: 347 clk = CLOCK_250M; 348 break; 349 } 350 return clk; 351 } 352