1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * Silicon Backplane utilities File: sb_utils.c 5 * 6 ********************************************************************* 7 * 8 * Copyright 2003,2004 9 * Broadcom Corporation. All rights reserved. 10 * 11 * This software is furnished under license and may be used and 12 * copied only in accordance with the following terms and 13 * conditions. Subject to these conditions, you may download, 14 * copy, install, use, modify and distribute modified or unmodified 15 * copies of this software in source and/or binary form. No title 16 * or ownership is transferred hereby. 17 * 18 * 1) Any source code used, modified or distributed must reproduce 19 * and retain this copyright notice and list of conditions 20 * as they appear in the source file. 21 * 22 * 2) No right is granted to use any trade name, trademark, or 23 * logo of Broadcom Corporation. The "Broadcom Corporation" 24 * name may not be used to endorse or promote products derived 25 * from this software without the prior written permission of 26 * Broadcom Corporation. 27 * 28 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 29 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 30 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 31 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 32 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 33 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 35 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 36 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 37 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 38 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 39 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 40 * THE POSSIBILITY OF SUCH DAMAGE. 41 ********************************************************************* */ 42 43/* 44 * Misc utility routines for accessing chip-specific features 45 * of SiliconBackplane-based chips. 46 */ 47 48#include "cfe.h" 49 50#include "sbmips32.h" 51#include "sb_bp.h" 52#include "sb_utils.h" 53 54/* 55 * Depending on the chip, either the Chip Common or the External 56 * Interface core provides global state and control. These are 57 * mutually exclusive. The corresponding registers in the two cores 58 * have compatible formats, but the core base address and the register 59 * offsets depend on the core. 60 */ 61 62#if defined(SB_EXTIF_BASE) 63#include "sb_extif.h" 64#elif defined(SB_CHIPC_BASE) 65#include "sb_chipc.h" 66#else 67#error "Neither EXT_IF nor CHIPC defined" 68#endif 69 70 71#define ASSERT(x) \ 72 do { if (!(x)) printf("sb_utils: assertion failed\n"); } while (0) 73 74/* Sharable clock related definitions and calculations. */ 75 76/* PLL types */ 77 78#define PLL_NONE 0x00000000 79#define PLL_N3M 0x00010000 80#define PLL_N4M 0x00020000 81#define PLL_TYPE3 0x00030000 82#define PLL_TYPE4 0x00008000 83 84#define CC_CLOCK_BASE 24000000 /* Half the clock freq. */ 85 86/* bcm4710 (N3M) Clock Control magic field values */ 87 88#define CC_F6_2 0x02 /* A factor of 2 in */ 89#define CC_F6_3 0x03 /* 6-bit fields like */ 90#define CC_F6_4 0x05 /* N1, M1 or M3 */ 91#define CC_F6_5 0x09 92#define CC_F6_6 0x11 93#define CC_F6_7 0x21 94 95#define CC_F5_BIAS 5 /* 5-bit fields get this added */ 96 97#define CC_MC_BYPASS 0x08 98#define CC_MC_M1 0x04 99#define CC_MC_M1M2 0x02 100#define CC_MC_M1M2M3 0x01 101#define CC_MC_M1M3 0x11 102 103/* bcm5836 (N4M) Clock Control magic field values (ditto) */ 104 105#define CC_T2_BIAS 2 /* N1, N2, M1 & M3 bias */ 106#define CC_T2M2_BIAS 3 /* M2 bias */ 107 108#define CC_T2MC_M1BYP 1 109#define CC_T2MC_M2BYP 2 110#define CC_T2MC_M3BYP 4 111 112 113static inline uint32_t 114factor6(uint32_t x) 115{ 116 switch (x) { 117 case CC_F6_2: return 2; 118 case CC_F6_3: return 3; 119 case CC_F6_4: return 4; 120 case CC_F6_5: return 5; 121 case CC_F6_6: return 6; 122 case CC_F6_7: return 7; 123 default: return 0; 124 } 125} 126 127/* 128 * Calculate the PLL output frequency given a set of clockcontrol 129 * values (CC_CLOCK_BASE assumed fixed). 130 */ 131 132static uint32_t 133sb_clock_rate(uint32_t pll_type, uint32_t n, uint32_t m) 134{ 135 uint32_t n1, n2, clock, m1, m2, m3, mc; 136 137 n1 = G_CCN_N1(n); 138 n2 = G_CCN_N2(n); 139 140 if (pll_type == PLL_N3M) { 141 n1 = factor6(n1); 142 n2 += CC_F5_BIAS; 143 } 144 else if (pll_type == PLL_N4M) { 145 n1 += CC_T2_BIAS; 146 n2 += CC_T2_BIAS; 147 } 148 else if (pll_type == PLL_TYPE3) { 149 return 100000000; /* NB: for SB only */ 150 } 151 else { 152 ASSERT(0); 153 return 0; 154 } 155 156 clock = CC_CLOCK_BASE * n1 * n2; 157 158 if (clock == 0) 159 return 0; 160 161 m1 = G_CCM_M1(m); 162 m2 = G_CCM_M2(m); 163 m3 = G_CCM_M3(m); 164 mc = G_CCM_MC(m); 165 166 if (pll_type == PLL_N3M) { 167 m1 = factor6(m1); 168 m2 += CC_F5_BIAS; 169 m3 = factor6(m3); 170 171 switch (mc) { 172 case CC_MC_BYPASS: return clock; 173 case CC_MC_M1: return clock / m1; 174 case CC_MC_M1M2: return clock / (m1 * m2); 175 case CC_MC_M1M2M3: return clock / (m1 * m2 * m3); 176 case CC_MC_M1M3: return clock / (m1 * m3); 177 default: return 0; 178 } 179 } 180 else if (pll_type == PLL_N4M) { 181 m1 += CC_T2_BIAS; 182 m2 += CC_T2M2_BIAS; 183 m3 += CC_T2_BIAS; 184 if ((mc & CC_T2MC_M1BYP) == 0) 185 clock /= m1; 186 if ((mc & CC_T2MC_M2BYP) == 0) 187 clock /= m2; 188 if ((mc & CC_T2MC_M3BYP) == 0) 189 clock /= m3; 190 return clock; 191 } 192 else { 193 ASSERT(0); 194 return 0; 195 } 196} 197 198 199#if defined(SB_EXTIF_BASE) 200 201/* Note: For EXTIF cores, the PLL must be N3M (aka TYPE1). */ 202 203/* Access EXTIF "enumeration" space */ 204 205#define READCSR(x) \ 206 (*(volatile uint32_t *)PHYS_TO_K1(SB_EXTIF_BASE+(x))) 207#define WRITECSR(x,v) \ 208 (*(volatile uint32_t *)PHYS_TO_K1(SB_EXTIF_BASE+(x)) = (v)) 209 210/* 211 * Reset the entire chip and copy master clock registers to the slaves. 212 */ 213 214void 215sb_chip_reset(void) 216{ 217 /* instant NMI from watchdog timeout after 1 tick */ 218 WRITECSR(R_WATCHDOGCNTR, 1); 219 while (1) 220 ; 221} 222 223 224/* Return the current speed the SB is running at */ 225uint32_t 226sb_clock(void) 227{ 228 uint32_t clockcontrol_n, clockcontrol_sb; 229 230 clockcontrol_n = READCSR(R_CLOCKCONTROLN); 231 clockcontrol_sb = READCSR(R_CLOCKCONTROLSB); 232 233 return sb_clock_rate(PLL_N3M, clockcontrol_n, clockcontrol_sb); 234} 235 236/* Return the current speed the CPU is running at. */ 237uint32_t 238sb_cpu_clock(void) 239{ 240 /* For EXTIF parts, cpu and backplane clocks are identical. */ 241 return sb_clock(); 242} 243 244 245/* Set the current speed of the SB to the desired rate (as closely as 246 possible) */ 247int 248sb_setclock(uint32_t sb, uint32_t pci) 249{ 250 uint32_t old_n, old_sb, old_pci; 251 uint32_t new_n, new_sb, new_pci; 252 uint i; 253 static const struct { 254 uint32_t clock; 255 uint16_t n; 256 uint32_t sb; 257 uint32_t m33; 258 uint32_t m25; 259 } sb_clock_table[] = { 260 { 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, 261 /* 96.000 32.000 24.000 */ 262 { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, 263 /* 100.000 33.333 25.000 */ 264 { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, 265 /* 104.000 31.200 24.960 */ 266 { 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 }, 267 /* 108.000 32.400 24.923 */ 268 { 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 }, 269 /* 112.000 32.000 24.889 */ 270 { 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 }, 271 /* 115.200 32.000 24.000 */ 272 { 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 }, 273 /* 120.000 30.000 24.000 */ 274 { 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 }, 275 /* 124.800 31.200 24.960 */ 276 { 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 }, 277 /* 128.000 32.000 24.000 */ 278 { 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 }, 279 /* 132.000 33.000 24.750 */ 280 { 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 }, 281 /* 136.000 32.640 24.727 */ 282 { 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 }, 283 /* 140.000 30.000 24.706 */ 284 { 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 }, 285 /* 144.000 30.857 24.686 */ 286 { 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 }, 287 /* 150.857 33.000 24.000 */ 288 { 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 }, 289 /* 152.000 32.571 24.000 */ 290 { 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 }, 291 /* 156.000 31.200 24.960 */ 292 { 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 }, 293 /* 160.000 32.000 24.000 */ 294 { 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 }, 295 /* 163.200 32.640 24.727 */ 296 { 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 }, 297 /* 168.000 32.000 24.889 */ 298 { 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 }, 299 /* 176.000 33.000 24.000 */ 300 }; 301 uint sb_clock_entries = sizeof(sb_clock_table)/sizeof(sb_clock_table[0]); 302 303 /* Store the current clock reg values */ 304 old_n = READCSR(R_CLOCKCONTROLN); 305 old_sb = READCSR(R_CLOCKCONTROLSB); 306 old_pci = READCSR(R_CLOCKCONTROLPCI); 307 308 /* keep current pci clock if not specified */ 309 if (pci == 0) { 310 pci = sb_clock_rate(PLL_N3M, old_n, old_pci); 311 } 312 pci = (pci <= 25000000) ? 25000000 : 33000000; 313 314 /* Find a supported clock setting no faster than the request. */ 315 if (sb < sb_clock_table[0].clock) 316 return 0; 317 for (i = sb_clock_entries-1; i > 0; i--) { 318 if (sb >= sb_clock_table[i].clock) 319 break; 320 } 321 322 new_n = sb_clock_table[i].n; 323 new_sb = sb_clock_table[i].sb; 324 new_pci = pci == 25000000 ? sb_clock_table[i].m25 : sb_clock_table[i].m33; 325 326 if (old_n != new_n || old_sb != new_sb || old_pci != new_pci) { 327 /* Reset to install the new clocks if any changed. */ 328 WRITECSR(R_CLOCKCONTROLN, new_n); 329 WRITECSR(R_CLOCKCONTROLSB, new_sb); 330 WRITECSR(R_CLOCKCONTROLPCI, new_pci); 331 /* Clock MII at 25 MHz. */ 332 WRITECSR(R_CLOCKCONTROLMII, sb_clock_table[i].m25); 333 334 /* No return from chip reset. */ 335 sb_chip_reset(); 336 } 337 338 return 1; 339} 340 341#elif defined(SB_CHIPC_BASE) 342 343/* Access CHIPC "enumeration" space */ 344 345#define READCSR(x) \ 346 (*(volatile uint32_t *)PHYS_TO_K1(SB_CHIPC_BASE+(x))) 347#define WRITECSR(x,v) \ 348 (*(volatile uint32_t *)PHYS_TO_K1(SB_CHIPC_BASE+(x)) = (v)) 349 350void 351sb_chip_reset(void) 352{ 353 /* instant NMI from watchdog timeout after 1 tick */ 354 WRITECSR(R_WATCHDOGCNTR, 1); 355 while (1) /* Use 'wait' instead? */ 356 ; 357} 358 359/* Return the current speed the SB is running at. */ 360uint32_t 361sb_clock(void) 362{ 363 uint32_t corecap; 364 uint32_t clockcontrol_n, clockcontrol_sb; 365 uint32_t pll_type; 366 367 corecap = READCSR(R_CORECAPABILITIES); 368 switch (G_CORECAP_PL(corecap)) { 369 case K_PL_4710: pll_type = PLL_N3M; break; 370 case K_PL_4704: pll_type = PLL_N4M; break; 371 case K_PL_5365: pll_type = PLL_TYPE3; break; 372 default: pll_type = PLL_NONE; break; 373 } 374 clockcontrol_n = READCSR(R_CLOCKCONTROLN); 375 clockcontrol_sb = READCSR(R_CLOCKCONTROLSB); 376 377 return sb_clock_rate(pll_type, clockcontrol_n, clockcontrol_sb); 378} 379 380/* Return the current speed the CPU is running at. */ 381uint32_t 382sb_cpu_clock(void) 383{ 384 uint32_t corecap; 385 uint32_t clockcontrol_n, clockcontrol_m; 386 uint32_t pll_type; 387 388 corecap = READCSR(R_CORECAPABILITIES); 389 clockcontrol_n = READCSR(R_CLOCKCONTROLN); 390 switch (G_CORECAP_PL(corecap)) { 391 case K_PL_4710: 392 pll_type = PLL_N3M; 393 clockcontrol_m = READCSR(R_CLOCKCONTROLM0); 394 break; 395 case K_PL_4704: 396 pll_type = PLL_N4M; 397 clockcontrol_m = READCSR(R_CLOCKCONTROLM3); 398 break; 399 case K_PL_5365: 400 pll_type = PLL_TYPE3; 401 return 200000000; /* until PLL_TYPE3 is documented */ 402 break; 403 default: 404 pll_type = PLL_NONE; 405 clockcontrol_m = 0; 406 break; 407 } 408 409 return sb_clock_rate(pll_type, clockcontrol_n, clockcontrol_m); 410} 411 412 413/* Set the current speed of the CPU to the desired rate (as closely as 414 possible). XXX Currently, cannot change CPU:SB ratio. */ 415int 416sb_setclock(uint32_t cpu, uint32_t pci) 417{ 418 typedef struct { 419 uint32_t mipsclock; 420 uint32_t sbclock; 421 uint16_t n; 422 uint32_t sb; /* aka m0 */ 423 uint32_t pci33; /* aka m1 */ 424 uint32_t m2; /* aka mii/uart/mipsref */ 425 uint32_t m3; /* aka mips */ 426 uint32_t ratio; /* cpu:sb */ 427 uint32_t ratio_parm; /* for CP0 register 22, sel 3 (ClkSync) */ 428 } n4m_table_t; 429 430 /* XXX 9:4 ratio parm was 0x012a0115. Current value from BMIPS docs. */ 431 static const n4m_table_t type2_table[] = { 432 { 180000000, 80000000, 0x0403, 0x01010000, 0x01020300, 433 0x01020600, 0x05000100, 0x94, 0x012a00a9 }, 434 { 180000000, 90000000, 0x0403, 0x01000100, 0x01020300, 435 0x01000100, 0x05000100, 0x21, 0x0aaa0555 }, 436 { 200000000, 100000000, 0x0303, 0x01000000, 0x01000600, 437 0x01000000, 0x05000000, 0x21, 0x0aaa0555 }, 438 { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 439 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, 440 { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 441 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, 442 { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 443 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, 444 { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 445 0x01020600, 0x05000100, 0x94, 0x012a00a9 }, 446 { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 447 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, 448 { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 449 0x01000100, 0x05000100, 0x21, 0x0aaa0555 }, 450 { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 451 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, 452 { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 453 0x01020600, 0x05000100, 0x94, 0x012a00a9 }, 454 { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 455 0x01020600, 0x05000100, 0x94, 0x012a00a9 }, 456 { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 457 0x01000000, 0x05000000, 0x21, 0x0aaa0555 }, 458 { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 459 0x01020600, 0x05000100, 0x94, 0x012a00a9 }, 460 { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 461 0x01000000, 0x05000000, 0x21, 0x0aaa0555 }, 462 { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 463 0x01020600, 0x05000100, 0x94, 0x012a00a9 }, 464 { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 465 0x01000100, 0x05000100, 0x21, 0x0aaa0555 } 466 }; 467 468 static const n4m_table_t type4_table[] = { 469 { 192000000, 96000000, 0x0702, 0x04020011, 0x11030011, 470 0x04020011, 0x04020003, 0x21, 0x0aaa0555 }, 471 { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 472 0x04020011, 0x04020003, 0x21, 0x0aaa0555 }, 473 { 216000000, 108000000, 0x0211, 0x11020005, 0x11030303, 474 0x11020005, 0x04000005, 0x21, 0x0aaa0555 }, 475 { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 476 0x11030305, 0x04000005, 0x94, 0x012a00a9 }, 477 { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 478 0x11020005, 0x04000005, 0x21, 0x0aaa0555 }, 479 { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 480 0x11030002, 0x04000003, 0x21, 0x0aaa0555 }, 481 { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 482 0x04000005, 0x04000002, 0x21, 0x0aaa0555 }, 483 { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 484 0x04000005, 0x04000002, 0x21, 0x0aaa0555 }, 485 { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 486 0x02000221, 0x04000003, 0x73, 0x254a14a9 }, 487 { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 488 0x02000221, 0x04000003, 0x73, 0x254a14a9 }, 489 { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 490 0x02000221, 0x04000003, 0x73, 0x254a14a9 }, 491 { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 492 0x02000902, 0x04000002, 0x52, 0x02520129 } 493 }; 494 495 const n4m_table_t *clock_table; 496 uint clock_entries; 497 uint i; 498 uint32_t old_n; 499 uint32_t old_m0, old_m1, old_m2, old_m3; 500 uint32_t new_n; 501 uint32_t new_m0, new_m1, new_m2, new_m3; 502 uint32_t old_ratio, new_ratio; 503 uint32_t corecap; 504 uint32_t pll_type; 505 506 clock_table = NULL; clock_entries = 0; /* defaults */ 507 508 corecap = READCSR(R_CORECAPABILITIES); 509 switch (G_CORECAP_PL(corecap)) { 510 case K_PL_4710: /* XXX Does this ever occur for CHIPC parts? */ 511 pll_type = PLL_N3M; 512 break; 513 case K_PL_4704: 514 pll_type = PLL_N4M; 515 clock_table = type2_table; 516 clock_entries = sizeof(type2_table)/sizeof(n4m_table_t); 517 break; 518 case K_PL_5365: 519 pll_type = PLL_TYPE3; 520 clock_table = NULL; 521 return 200000000; /* until PLL_TYPE3 is documented */ 522 break; 523 case 0: /* XXX Fix for expanded field. */ 524 pll_type = PLL_TYPE4; 525 clock_entries = sizeof(type4_table)/sizeof(n4m_table_t); 526 break; 527 default: 528 pll_type = PLL_NONE; 529 break; 530 } 531 532 if (clock_table == NULL) 533 return 0; 534 535 /* Remember the current settings */ 536 old_n = READCSR(R_CLOCKCONTROLN); 537 old_m0 = READCSR(R_CLOCKCONTROLM0); 538 old_m1 = READCSR(R_CLOCKCONTROLM1); 539 old_m2 = READCSR(R_CLOCKCONTROLM2); 540 old_m3 = READCSR(R_CLOCKCONTROLM3); 541 542 /* Match to deduce current cpu:sb ratio. */ 543 old_ratio = 0; 544 for (i = 0; i < clock_entries; i++) { 545 if (old_n == clock_table[i].n 546 && old_m0 == clock_table[i].sb && old_m1 == clock_table[i].pci33 547 && old_m2 == clock_table[i].m2 && old_m3 == clock_table[i].m3) { 548 old_ratio = clock_table[i].ratio; 549 break; 550 } 551 } 552 if (i == clock_entries) { 553 /* No match; look for the supported ratios. */ 554 uint32_t mips_clk = sb_clock_rate(pll_type, old_n, old_m3); 555 uint32_t sb_clk = sb_clock_rate(pll_type, old_n, old_m0); 556 557 if (mips_clk == 2*sb_clk) 558 old_ratio = 0x21; 559 else if (mips_clk == (sb_clk/4)*9) 560 old_ratio = 0x94; 561 } 562 if (old_ratio == 0) 563 return 0; 564 565 /* Find a supported CPU clock setting no faster than the request. */ 566 new_ratio = 0; 567 if (cpu < clock_table[0].mipsclock) 568 return 0; 569 for (i = clock_entries-1; i > 0; i--) { 570 if (cpu >= clock_table[i].mipsclock) 571 break; 572 } 573 574 new_ratio = clock_table[i].ratio; 575 if (new_ratio != old_ratio) /* For now, can't change ratios. */ 576 return 0; 577 578 new_n = clock_table[i].n; 579 new_m0 = clock_table[i].sb; 580 new_m1 = clock_table[i].pci33; 581 new_m2 = clock_table[i].m2; 582 new_m3 = clock_table[i].m3; 583 584 if (old_n != new_n || old_m0 != new_m0 || old_m1 != new_m1 585 || old_m2 != new_m2 || old_m3 != new_m3) { 586 /* Reset to install the new clocks if any changed. */ 587 WRITECSR(R_CLOCKCONTROLN, new_n); 588 WRITECSR(R_CLOCKCONTROLM0, new_m0); 589 WRITECSR(R_CLOCKCONTROLM1, new_m1); 590 WRITECSR(R_CLOCKCONTROLM2, new_m2); 591 WRITECSR(R_CLOCKCONTROLM3, new_m3); 592 593 /* No return from chip reset. */ 594 sb_chip_reset(); 595 } 596 597 return 1; 598} 599 600 601/* Return the reference clock being supplied to the internal UART(s). */ 602uint32_t 603sb_uart_clock(void) 604{ 605 uint32_t coreid, corecap, corectl; 606 uint32_t pll_type; 607 uint32_t cc_n, cc_m; 608 uint32_t clock, div; 609 610 coreid = READCSR(R_SBIDHIGH); 611 corecap = READCSR(R_CORECAPABILITIES); 612 switch (G_CORECAP_PL(corecap)) { 613 case K_PL_4710: pll_type = PLL_N3M; break; 614 case K_PL_4704: pll_type = PLL_N4M; break; 615 case K_PL_5365: pll_type = PLL_TYPE3; break; 616 default: pll_type = PLL_NONE; break; 617 } 618 619 cc_n = READCSR(R_CLOCKCONTROLN); 620 if (pll_type == PLL_N3M) { 621 cc_m = READCSR(R_CLOCKCONTROLM2); 622 clock = sb_clock_rate(PLL_N3M, cc_n, cc_m); 623 div = 1; 624 } 625 else if (pll_type == PLL_TYPE3) { 626 /* 5365 type clock, not documented */ 627 clock = 100000000; 628 div = 54; /* clock/1843200 */ 629 WRITECSR(R_UARTCLOCKDIV, div); 630 } 631 else { 632 if (G_SBID_RV(coreid) >= 3) { 633 /* Internal backplane clock. */ 634 cc_m = READCSR(R_CLOCKCONTROLSB); 635 clock = sb_clock_rate(PLL_N4M, cc_n, cc_m); 636 div = clock/1843200; 637 WRITECSR(R_UARTCLOCKDIV, div); 638 } 639 else { 640 /* Fixed internal backplane clock (4310, certain 4306). */ 641 clock = 88000000; 642 div = 48; 643 } 644 } 645 646 /* Clock source depends on strapping if UartClkOverride is unset. */ 647 corectl = READCSR(R_CORECONTROL); 648 if ((G_SBID_RV(coreid) > 0) && ((corectl & M_CORECTL_CO) == 0)) { 649 if (G_CORECAP_CS(corecap) == K_CS_INTERNAL) { 650 /* Internal divided backplane clock */ 651 clock /= div; 652 } 653 else { 654 /* Assume external clock of 1.8432 MHz */ 655 clock = 1843200; 656 } 657 } 658 659 return clock; 660} 661#endif /* SB_CHIPC_BASE */ 662 663 664/* Backplane interrupt mapping. */ 665 666#if defined(SB_MIPS_BASE) 667#define SB_CPU_BASE SB_MIPS_BASE 668#elif defined(SB_MIPS33_BASE) 669#define SB_CPU_BASE SB_MIPS33_BASE 670#else 671#error "Neither MIPS nor MIPS33 core defined" 672#endif 673 674#define READREG(b,x) (*(uint32_t *)PHYS_TO_K1((b)+(x))) 675#define WRITEREG(b,x,v) (*(uint32_t *)PHYS_TO_K1((b)+(x)) = (v)) 676 677/* 678 * Map the interrupt index for a core (SBTPSFlagNum0 in SBTPSFlag 679 * register) into the (external) interrupt priorities (IPn) defined by 680 * the MIPS architecture. 681 * 682 * The mapping of backplane interrupts to MIPS interrupts is 683 * controlled by the CPU core's SBIPSFLAG register. Note that any 684 * interrupt source not mapped by the four SBIPSFLAG fields will be 685 * directed to IP0 (level 2) and must additionally be enabled in the 686 * SBINTVEC register. */ 687 688unsigned int 689sb_map_irq(unsigned int flagnum) 690{ 691 unsigned int ip; 692 uint32_t ipsflags, intvec; 693 694 ipsflags = READREG(SB_CPU_BASE, R_SBIPSFLAG); 695 696 if (flagnum == G_SBISF_F1(ipsflags)) 697 ip = 1; 698 else if (flagnum == G_SBISF_F2(ipsflags)) 699 ip = 2; 700 else if (flagnum == G_SBISF_F3(ipsflags)) 701 ip = 3; 702 else if (flagnum == G_SBISF_F4(ipsflags)) 703 ip = 4; 704 else { 705 intvec = READREG(SB_CPU_BASE, R_SBINTVEC); 706 intvec |= (1 << flagnum); 707 WRITEREG(SB_CPU_BASE, R_SBINTVEC, intvec); 708 ip = 0; 709 } 710 711 return ip; 712} 713