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