2 * BCM47XX Sonics SiliconBackplane MIPS core routines
4 * Copyright 2005, Broadcom Corporation
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
12 * $Id: sbmips.c,v 1.3 2005/03/07 08:35:32 kanki Exp $
29 * Returns TRUE if an external UART exists at the given base
33 BCMINITFN(serial_exists
)(uint8
*regs
)
35 uint8 save_mcr
, status1
;
37 save_mcr
= R_REG(®s
[UART_MCR
]);
38 W_REG(®s
[UART_MCR
], UART_MCR_LOOP
| 0x0a);
39 status1
= R_REG(®s
[UART_MSR
]) & 0xf0;
40 W_REG(®s
[UART_MCR
], save_mcr
);
42 return (status1
== 0x90);
46 * Initializes UART access. The callback function will be called once
50 BCMINITFN(sb_serial_init
)(void *sbh
, void (*add
)(void *regs
, uint irq
, uint baud_base
, uint reg_shift
))
57 if ((regs
= sb_setcore(sbh
, SB_EXTIF
, 0))) {
58 extifregs_t
*eir
= (extifregs_t
*) regs
;
61 /* Determine external UART register base */
62 sb
= (sbconfig_t
*)((ulong
) eir
+ SBCONFIGOFF
);
63 base
= EXTIF_CFGIF_BASE(sb_base(R_REG(&sb
->sbadmatch1
)));
68 /* Disable GPIO interrupt initially */
69 W_REG(&eir
->gpiointpolarity
, 0);
70 W_REG(&eir
->gpiointmask
, 0);
72 /* Search for external UARTs */
74 for (i
= 0; i
< 2; i
++) {
75 regs
= (void *) REG_MAP(base
+ (i
* 8), 8);
76 if (BCMINIT(serial_exists
)(regs
)) {
77 /* Set GPIO 1 to be the external UART IRQ */
78 W_REG(&eir
->gpiointmask
, 2);
80 add(regs
, irq
, 13500000, 0);
84 /* Add internal UART if enabled */
85 if (R_REG(&eir
->corecontrol
) & CC_UE
)
87 add((void *) &eir
->uartdata
, irq
, sb_clock(sbh
), 2);
88 } else if ((regs
= sb_setcore(sbh
, SB_CC
, 0))) {
89 chipcregs_t
*cc
= (chipcregs_t
*) regs
;
90 uint32 rev
, cap
, pll
, baud_base
, div
;
92 /* Determine core revision and capabilities */
93 rev
= sb_corerev(sbh
);
94 cap
= R_REG(&cc
->capabilities
);
95 pll
= cap
& CAP_PLL_MASK
;
100 if (pll
== PLL_TYPE1
) {
102 baud_base
= sb_clock_rate(pll
,
103 R_REG(&cc
->clockcontrol_n
),
104 R_REG(&cc
->clockcontrol_m2
));
108 /* Fixed ALP clock */
109 baud_base
= 20000000;
111 /* Set the override bit so we don't divide it */
112 W_REG(&cc
->corecontrol
, CC_UARTCLKO
);
113 } else if (rev
>= 3) {
114 /* Internal backplane clock */
115 baud_base
= sb_clock(sbh
);
116 div
= 2; /* Minimum divisor */
118 ((R_REG(&cc
->clkdiv
) & ~CLKD_UART
) | div
));
120 /* Fixed internal backplane clock */
121 baud_base
= 88000000;
125 /* Clock source depends on strapping if UartClkOverride is unset */
127 ((R_REG(&cc
->corecontrol
) & CC_UARTCLKO
) == 0)) {
128 if ((cap
& CAP_UCLKSEL
) == CAP_UINTCLK
) {
129 /* Internal divided backplane clock */
132 /* Assume external clock of 1.8432 MHz */
138 /* Add internal UARTs */
139 n
= cap
& CAP_UARTS_MASK
;
140 for (i
= 0; i
< n
; i
++) {
141 /* Register offset changed after revision 0 */
143 regs
= (void *)((ulong
) &cc
->uart0data
+ (i
* 256));
145 regs
= (void *)((ulong
) &cc
->uart0data
+ (i
* 8));
148 add(regs
, irq
, baud_base
, 0);
154 * Initialize jtag master and return handle for
155 * jtag_rwreg. Returns NULL on failure.
158 sb_jtagm_init(void *sbh
, uint clkd
, bool exttap
)
162 if ((regs
= sb_setcore(sbh
, SB_CC
, 0)) != NULL
) {
163 chipcregs_t
*cc
= (chipcregs_t
*) regs
;
167 * Determine jtagm availability from
168 * core revision and capabilities.
170 tmp
= sb_corerev(sbh
);
172 * Corerev 10 has jtagm, but the only chip
173 * with it does not have a mips, and
174 * the layout of the jtagcmd register is
175 * different. We'll only accept >= 11.
180 tmp
= R_REG(&cc
->capabilities
);
181 if ((tmp
& CAP_JTAGP
) == 0)
184 /* Set clock divider if requested */
186 tmp
= R_REG(&cc
->clkdiv
);
187 tmp
= (tmp
& ~CLKD_JTAG
) |
188 ((clkd
<< CLKD_JTAG_SHIFT
) & CLKD_JTAG
);
189 W_REG(&cc
->clkdiv
, tmp
);
193 tmp
= JCTRL_EN
| (exttap
? JCTRL_EXT_EN
: 0);
194 W_REG(&cc
->jtagctrl
, tmp
);
201 sb_jtagm_disable(void *h
)
203 chipcregs_t
*cc
= (chipcregs_t
*)h
;
205 W_REG(&cc
->jtagctrl
, R_REG(&cc
->jtagctrl
) & ~JCTRL_EN
);
209 * Read/write a jtag register. Assumes a target with
210 * 8 bit IR and 32 bit DR.
215 jtag_rwreg(void *h
, uint32 ir
, uint32 dr
)
217 chipcregs_t
*cc
= (chipcregs_t
*) h
;
220 W_REG(&cc
->jtagir
, ir
);
221 W_REG(&cc
->jtagdr
, dr
);
222 tmp
= JCMD_START
| JCMD_ACC_IRDR
|
223 ((IRWIDTH
- 1) << JCMD_IRW_SHIFT
) |
225 W_REG(&cc
->jtagcmd
, tmp
);
226 while (((tmp
= R_REG(&cc
->jtagcmd
)) & JCMD_BUSY
) == JCMD_BUSY
) {
230 tmp
= R_REG(&cc
->jtagdr
);
234 /* Returns the SB interrupt flag of the current core. */
241 regs
= sb_coreregs(sbh
);
242 sb
= (sbconfig_t
*)((ulong
) regs
+ SBCONFIGOFF
);
244 return (R_REG(&sb
->sbtpsflag
) & SBTPS_NUM0_MASK
);
247 static const uint32 sbips_int_mask
[] = {
255 static const uint32 sbips_int_shift
[] = {
264 * Returns the MIPS IRQ assignment of the current core. If unassigned,
273 uint32 flag
, sbipsflag
;
278 idx
= sb_coreidx(sbh
);
280 if ((regs
= sb_setcore(sbh
, SB_MIPS
, 0)) ||
281 (regs
= sb_setcore(sbh
, SB_MIPS33
, 0))) {
282 sb
= (sbconfig_t
*)((ulong
) regs
+ SBCONFIGOFF
);
284 /* sbipsflag specifies which core is routed to interrupts 1 to 4 */
285 sbipsflag
= R_REG(&sb
->sbipsflag
);
286 for (irq
= 1; irq
<= 4; irq
++) {
287 if (((sbipsflag
& sbips_int_mask
[irq
]) >> sbips_int_shift
[irq
]) == flag
)
294 sb_setcoreidx(sbh
, idx
);
299 /* Clears the specified MIPS IRQ. */
301 BCMINITFN(sb_clearirq
)(void *sbh
, uint irq
)
306 if (!(regs
= sb_setcore(sbh
, SB_MIPS
, 0)) &&
307 !(regs
= sb_setcore(sbh
, SB_MIPS33
, 0)))
309 sb
= (sbconfig_t
*)((ulong
) regs
+ SBCONFIGOFF
);
312 W_REG(&sb
->sbintvec
, 0);
314 OR_REG(&sb
->sbipsflag
, sbips_int_mask
[irq
]);
318 * Assigns the specified MIPS IRQ to the specified core. Shared MIPS
319 * IRQ 0 may be assigned more than once.
322 BCMINITFN(sb_setirq
)(void *sbh
, uint irq
, uint coreid
, uint coreunit
)
328 regs
= sb_setcore(sbh
, coreid
, coreunit
);
332 if (!(regs
= sb_setcore(sbh
, SB_MIPS
, 0)) &&
333 !(regs
= sb_setcore(sbh
, SB_MIPS33
, 0)))
335 sb
= (sbconfig_t
*)((ulong
) regs
+ SBCONFIGOFF
);
338 OR_REG(&sb
->sbintvec
, 1 << flag
);
340 flag
<<= sbips_int_shift
[irq
];
341 ASSERT(!(flag
& ~sbips_int_mask
[irq
]));
342 flag
|= R_REG(&sb
->sbipsflag
) & ~sbips_int_mask
[irq
];
343 W_REG(&sb
->sbipsflag
, flag
);
348 * Initializes clocks and interrupts. SB and NVRAM access must be
349 * initialized prior to calling.
352 BCMINITFN(sb_mips_init
)(void *sbh
)
360 /* Figure out current SB clock speed */
361 if ((hz
= sb_clock(sbh
)) == 0)
363 ns
= 1000000000 / hz
;
365 /* Setup external interface timing */
366 if ((eir
= sb_setcore(sbh
, SB_EXTIF
, 0))) {
367 /* Initialize extif so we can get to the LEDs and external UART */
368 W_REG(&eir
->prog_config
, CF_EN
);
370 /* Set timing for the flash */
371 tmp
= CEIL(10, ns
) << FW_W3_SHIFT
; /* W3 = 10nS */
372 tmp
= tmp
| (CEIL(40, ns
) << FW_W1_SHIFT
); /* W1 = 40nS */
373 tmp
= tmp
| CEIL(120, ns
); /* W0 = 120nS */
374 W_REG(&eir
->prog_waitcount
, tmp
); /* 0x01020a0c for a 100Mhz clock */
376 /* Set programmable interface timing for external uart */
377 tmp
= CEIL(10, ns
) << FW_W3_SHIFT
; /* W3 = 10nS */
378 tmp
= tmp
| (CEIL(20, ns
) << FW_W2_SHIFT
); /* W2 = 20nS */
379 tmp
= tmp
| (CEIL(100, ns
) << FW_W1_SHIFT
); /* W1 = 100nS */
380 tmp
= tmp
| CEIL(120, ns
); /* W0 = 120nS */
381 W_REG(&eir
->prog_waitcount
, tmp
); /* 0x01020a0c for a 100Mhz clock */
382 } else if ((cc
= sb_setcore(sbh
, SB_CC
, 0))) {
383 //==================================tallest===============================================
384 /* set register for external IO to control LED. */
385 W_REG(&cc
->prog_config
, 0x11);
386 tmp
= CEIL(10, ns
) << FW_W3_SHIFT
; /* W3 = 10nS */
387 tmp
= tmp
| (CEIL(40, ns
) << FW_W1_SHIFT
); /* W1 = 40nS */
388 tmp
= tmp
| CEIL(240, ns
); /* W0 = 120nS */
389 W_REG(&cc
->prog_waitcount
, tmp
); /* 0x01020a0c for a 100Mhz clock */
390 //========================================================================================
391 /* Set timing for the flash */
392 tmp
= CEIL(10, ns
) << FW_W3_SHIFT
; /* W3 = 10nS */
393 tmp
|= CEIL(10, ns
) << FW_W1_SHIFT
; /* W1 = 10nS */
394 tmp
|= CEIL(120, ns
); /* W0 = 120nS */
395 if (sb_corerev(sbh
) < 9)
396 W_REG(&cc
->flash_waitcount
, tmp
);
398 if ( (sb_corerev(sbh
) < 9) ||
399 ((BCMINIT(sb_chip
)(sbh
) == BCM5350_DEVICE_ID
) && BCMINIT(sb_chiprev
)(sbh
) == 0) ) {
400 W_REG(&cc
->pcmcia_memwait
, tmp
);
404 /* Chip specific initialization */
405 switch (BCMINIT(sb_chip
)(sbh
)) {
406 case BCM4710_DEVICE_ID
:
407 /* Clear interrupt map */
408 for (irq
= 0; irq
<= 4; irq
++)
409 BCMINIT(sb_clearirq
)(sbh
, irq
);
410 BCMINIT(sb_setirq
)(sbh
, 0, SB_CODEC
, 0);
411 BCMINIT(sb_setirq
)(sbh
, 0, SB_EXTIF
, 0);
412 BCMINIT(sb_setirq
)(sbh
, 2, SB_ENET
, 1);
413 BCMINIT(sb_setirq
)(sbh
, 3, SB_ILINE20
, 0);
414 BCMINIT(sb_setirq
)(sbh
, 4, SB_PCI
, 0);
416 value
= BCMINIT(nvram_get
)("et0phyaddr");
417 if (value
&& !strcmp(value
, "31")) {
418 /* Enable internal UART */
419 W_REG(&eir
->corecontrol
, CC_UE
);
420 /* Give USB its own interrupt */
421 BCMINIT(sb_setirq
)(sbh
, 1, SB_USB
, 0);
423 /* Disable internal UART */
424 W_REG(&eir
->corecontrol
, 0);
425 /* Give Ethernet its own interrupt */
426 BCMINIT(sb_setirq
)(sbh
, 1, SB_ENET
, 0);
427 BCMINIT(sb_setirq
)(sbh
, 0, SB_USB
, 0);
430 case BCM4310_DEVICE_ID
:
431 MTC0(C0_BROADCOM
, 0, MFC0(C0_BROADCOM
, 0) & ~(1 << 22));
433 case BCM5350_DEVICE_ID
:
434 /* Clear interrupt map */
435 for (irq
= 0; irq
<= 4; irq
++)
436 BCMINIT(sb_clearirq
)(sbh
, irq
);
437 BCMINIT(sb_setirq
)(sbh
, 0, SB_CC
, 0);
438 BCMINIT(sb_setirq
)(sbh
, 1, SB_D11
, 0);
439 BCMINIT(sb_setirq
)(sbh
, 2, SB_ENET
, 0);
440 BCMINIT(sb_setirq
)(sbh
, 3, SB_IPSEC
, 0);
441 BCMINIT(sb_setirq
)(sbh
, 4, SB_USB
, 0);
447 BCMINITFN(sb_mips_clock
)(void *sbh
)
453 uint32 pll_type
, rate
= 0;
455 /* get index of the current core */
456 idx
= sb_coreidx(sbh
);
457 pll_type
= PLL_TYPE1
;
459 /* switch to extif or chipc core */
460 if ((eir
= (extifregs_t
*) sb_setcore(sbh
, SB_EXTIF
, 0))) {
461 n
= R_REG(&eir
->clockcontrol_n
);
462 m
= R_REG(&eir
->clockcontrol_sb
);
463 } else if ((cc
= (chipcregs_t
*) sb_setcore(sbh
, SB_CC
, 0))) {
464 pll_type
= R_REG(&cc
->capabilities
) & CAP_PLL_MASK
;
465 n
= R_REG(&cc
->clockcontrol_n
);
466 if ((pll_type
== PLL_TYPE2
) ||
467 (pll_type
== PLL_TYPE4
) ||
468 (pll_type
== PLL_TYPE6
) ||
469 (pll_type
== PLL_TYPE7
))
470 m
= R_REG(&cc
->clockcontrol_mips
);
471 else if (pll_type
== PLL_TYPE5
) {
475 else if (pll_type
== PLL_TYPE3
) {
476 if (BCMINIT(sb_chip
)(sbh
) == BCM5365_DEVICE_ID
) { /* 5365 is also type3 */
480 m
= R_REG(&cc
->clockcontrol_m2
); /* 5350 uses m2 to control mips */
482 m
= R_REG(&cc
->clockcontrol_sb
);
487 rate
= sb_clock_rate(pll_type
, n
, m
);
489 if (pll_type
== PLL_TYPE6
)
490 rate
= SB2MIPS_T6(rate
);
493 /* switch back to previous core */
494 sb_setcoreidx(sbh
, idx
);
499 #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
502 BCMINITFN(handler
)(void)
509 /* Disable interrupts */
510 /* MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */
512 /* Just a Hack to not to use reg 'at' which was causing problems on 4704 A2 */
514 "and $15, $15, $14\n\t"
523 /* The following MUST come right after handler() */
525 BCMINITFN(afterhandler
)(void)
530 * Set the MIPS, backplane and PCI clocks as closely as possible.
533 BCMINITFN(sb_mips_setclock
)(void *sbh
, uint32 mipsclock
, uint32 sbclock
, uint32 pciclock
)
535 extifregs_t
*eir
= NULL
;
536 chipcregs_t
*cc
= NULL
;
537 mipsregs_t
*mipsr
= NULL
;
538 volatile uint32
*clockcontrol_n
, *clockcontrol_sb
, *clockcontrol_pci
, *clockcontrol_m2
;
539 uint32 orig_n
, orig_sb
, orig_pci
, orig_m2
, orig_mips
, orig_ratio_parm
, orig_ratio_cfg
;
540 uint32 pll_type
, sync_mode
;
541 uint ic_size
, ic_lsize
;
550 static n3m_table_t
BCMINITDATA(type1_table
)[] = {
551 { 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, /* 96.000 32.000 24.000 */
552 { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, /* 100.000 33.333 25.000 */
553 { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, /* 104.000 31.200 24.960 */
554 { 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 }, /* 108.000 32.400 24.923 */
555 { 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 }, /* 112.000 32.000 24.889 */
556 { 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 }, /* 115.200 32.000 24.000 */
557 { 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 }, /* 120.000 30.000 24.000 */
558 { 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 }, /* 124.800 31.200 24.960 */
559 { 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 }, /* 128.000 32.000 24.000 */
560 { 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 }, /* 132.000 33.000 24.750 */
561 { 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 }, /* 136.000 32.640 24.727 */
562 { 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 }, /* 140.000 30.000 24.706 */
563 { 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 }, /* 144.000 30.857 24.686 */
564 { 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 }, /* 150.857 33.000 24.000 */
565 { 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 }, /* 152.000 32.571 24.000 */
566 { 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 }, /* 156.000 31.200 24.960 */
567 { 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 }, /* 160.000 32.000 24.000 */
568 { 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 }, /* 163.200 32.640 24.727 */
569 { 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 }, /* 168.000 32.000 24.889 */
570 { 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 }, /* 176.000 33.000 24.000 */
575 uint32 m2
; /* that is the clockcontrol_m2 */
577 static type3_table_t type3_table
[] = { /* for 5350, mips clock is always double sb clock */
578 { 150000000, 0x311, 0x4020005 },
579 { 200000000, 0x311, 0x4020003 },
593 static n4m_table_t
BCMINITDATA(type2_table
)[] = {
594 { 180000000, 80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100, 8, 0x012a00a9 },
595 { 180000000, 90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 11, 0x0aaa0555 },
596 { 200000000, 100000000, 0x0303, 0x02010000, 0x02040001, 0x02010000, 0x06000001, 11, 0x0aaa0555 },
597 { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
598 { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
599 { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
600 { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100, 8, 0x012a00a9 },
601 { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
602 { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 11, 0x0aaa0555 },
603 { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
604 { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 },
605 { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 },
606 { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 },
607 { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 },
608 { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 },
609 { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01020600, 0x05000100, 8, 0x012a00a9 },
610 { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01000100, 0x05000100, 11, 0x0aaa0555 }
613 static n4m_table_t
BCMINITDATA(type4_table
)[] = {
614 { 192000000, 96000000, 0x0702, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 },
615 { 198000000, 99000000, 0x0603, 0x11020005, 0x11030011, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
616 { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 },
617 { 204000000, 102000000, 0x0c02, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
618 { 208000000, 104000000, 0x0802, 0x11030002, 0x11090005, 0x11030002, 0x04000003, 11, 0x0aaa0555 },
619 { 210000000, 105000000, 0x0209, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
620 { 216000000, 108000000, 0x0111, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
621 { 224000000, 112000000, 0x0205, 0x11030002, 0x02002103, 0x11030002, 0x04000003, 11, 0x0aaa0555 },
622 { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x01030305, 0x04000005, 8, 0x012a00a9 },
623 { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
624 { 240000000, 102857143, 0x0109, 0x04000021, 0x01050203, 0x11030021, 0x04000003, 13, 0x254a14a9 },
625 { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 11, 0x0aaa0555 },
626 { 252000000, 100800000, 0x0203, 0x04000009, 0x11050005, 0x02000209, 0x04000002, 9, 0x02520129 },
627 { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 },
628 { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 },
629 { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 13, 0x254a14a9 },
630 { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 },
631 { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 },
632 { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002, 9, 0x02520129 },
633 { 300000000, 150000000, 0x0009, 0x04000005, 0x01030203, 0x04000005, 0x04000002, 11, 0x0aaa0555 }
636 static n4m_table_t
BCMINITDATA(type7_table
)[] = {
637 { 183333333, 91666666, 0x0605, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 },
638 { 187500000, 93750000, 0x0a03, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 },
639 { 196875000, 98437500, 0x1003, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
640 { 200000000, 100000000, 0x0311, 0x04000011, 0x11030011, 0x04000009, 0x04000003, 11, 0x0aaa0555 },
641 { 200000000, 100000000, 0x0311, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 },
642 { 206250000, 103125000, 0x1103, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
643 { 212500000, 106250000, 0x0c05, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
644 { 215625000, 107812500, 0x1203, 0x11090009, 0x11050005, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
645 { 216666666, 108333333, 0x0805, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 },
646 { 225000000, 112500000, 0x0d03, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 },
647 { 233333333, 116666666, 0x0905, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 },
648 { 237500000, 118750000, 0x0e05, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
649 { 240000000, 120000000, 0x0b11, 0x11020009, 0x11210009, 0x11020009, 0x04000009, 11, 0x0aaa0555 },
650 { 250000000, 125000000, 0x0f03, 0x11020003, 0x11210003, 0x11020003, 0x04000003, 11, 0x0aaa0555 }
653 ulong start
, end
, dst
;
656 /* get index of the current core */
657 idx
= sb_coreidx(sbh
);
658 clockcontrol_m2
= NULL
;
660 /* switch to extif or chipc core */
661 if ((eir
= (extifregs_t
*) sb_setcore(sbh
, SB_EXTIF
, 0))) {
662 pll_type
= PLL_TYPE1
;
663 clockcontrol_n
= &eir
->clockcontrol_n
;
664 clockcontrol_sb
= &eir
->clockcontrol_sb
;
665 clockcontrol_pci
= &eir
->clockcontrol_pci
;
666 clockcontrol_m2
= &cc
->clockcontrol_m2
;
667 } else if ((cc
= (chipcregs_t
*) sb_setcore(sbh
, SB_CC
, 0))) {
668 pll_type
= R_REG(&cc
->capabilities
) & CAP_PLL_MASK
;
669 if (pll_type
== PLL_TYPE6
) {
670 clockcontrol_n
= NULL
;
671 clockcontrol_sb
= NULL
;
672 clockcontrol_pci
= NULL
;
674 clockcontrol_n
= &cc
->clockcontrol_n
;
675 clockcontrol_sb
= &cc
->clockcontrol_sb
;
676 clockcontrol_pci
= &cc
->clockcontrol_pci
;
677 clockcontrol_m2
= &cc
->clockcontrol_m2
;
682 if (pll_type
== PLL_TYPE6
) {
683 /* Silence compilers */
684 orig_n
= orig_sb
= orig_pci
= 0;
686 /* Store the current clock register values */
687 orig_n
= R_REG(clockcontrol_n
);
688 orig_sb
= R_REG(clockcontrol_sb
);
689 orig_pci
= R_REG(clockcontrol_pci
);
692 if (pll_type
== PLL_TYPE1
) {
693 /* Keep the current PCI clock if not specified */
695 pciclock
= sb_clock_rate(pll_type
, R_REG(clockcontrol_n
), R_REG(clockcontrol_pci
));
696 pciclock
= (pciclock
<= 25000000) ? 25000000 : 33000000;
699 /* Search for the closest MIPS clock less than or equal to a preferred value */
700 for (i
= 0; i
< ARRAYSIZE(BCMINIT(type1_table
)); i
++) {
701 ASSERT(BCMINIT(type1_table
)[i
].mipsclock
==
702 sb_clock_rate(pll_type
, BCMINIT(type1_table
)[i
].n
, BCMINIT(type1_table
)[i
].sb
));
703 if (BCMINIT(type1_table
)[i
].mipsclock
> mipsclock
)
713 ASSERT(BCMINIT(type1_table
)[i
].mipsclock
<= mipsclock
);
716 if ((orig_n
== BCMINIT(type1_table
)[i
].n
) &&
717 (orig_sb
== BCMINIT(type1_table
)[i
].sb
) &&
718 (orig_pci
== BCMINIT(type1_table
)[i
].pci33
))
721 /* Set the PLL controls */
722 W_REG(clockcontrol_n
, BCMINIT(type1_table
)[i
].n
);
723 W_REG(clockcontrol_sb
, BCMINIT(type1_table
)[i
].sb
);
724 if (pciclock
== 25000000)
725 W_REG(clockcontrol_pci
, BCMINIT(type1_table
)[i
].pci25
);
727 W_REG(clockcontrol_pci
, BCMINIT(type1_table
)[i
].pci33
);
733 } else if ((pll_type
== PLL_TYPE3
) &&
734 (BCMINIT(sb_chip
)(sbh
) != BCM5365_DEVICE_ID
)) {
736 /* Search for the closest MIPS clock less than or equal to a preferred value */
738 for (i
= 0; i
< ARRAYSIZE(type3_table
); i
++) {
739 if (type3_table
[i
].mipsclock
> mipsclock
)
749 ASSERT(type3_table
[i
].mipsclock
<= mipsclock
);
752 orig_m2
= R_REG(&cc
->clockcontrol_m2
);
753 if ((orig_n
== type3_table
[i
].n
) &&
754 (orig_m2
== type3_table
[i
].m2
)) {
758 /* Set the PLL controls */
759 W_REG(clockcontrol_n
, type3_table
[i
].n
);
760 W_REG(clockcontrol_m2
, type3_table
[i
].m2
);
765 } else if ((pll_type
== PLL_TYPE2
) ||
766 (pll_type
== PLL_TYPE4
) ||
767 (pll_type
== PLL_TYPE6
) ||
768 (pll_type
== PLL_TYPE7
)) {
769 n4m_table_t
*table
= NULL
, *te
;
774 orig_mips
= R_REG(&cc
->clockcontrol_mips
);
776 if (pll_type
== PLL_TYPE6
) {
780 if (mipsclock
<= SB2MIPS_T6(CC_T6_M1
))
781 new_mips
= CC_T6_MMASK
;
783 if (orig_mips
== new_mips
)
786 W_REG(&cc
->clockcontrol_mips
, new_mips
);
790 if (pll_type
== PLL_TYPE2
) {
791 table
= BCMINIT(type2_table
);
792 tabsz
= ARRAYSIZE(BCMINIT(type2_table
));
793 } else if (pll_type
== PLL_TYPE4
) {
794 table
= BCMINIT(type4_table
);
795 tabsz
= ARRAYSIZE(BCMINIT(type4_table
));
796 } else if (pll_type
== PLL_TYPE7
) {
797 table
= BCMINIT(type7_table
);
798 tabsz
= ARRAYSIZE(BCMINIT(type7_table
));
800 ASSERT((char *)"No table for plltype" == NULL
);
802 /* Store the current clock register values */
803 orig_m2
= R_REG(&cc
->clockcontrol_m2
);
807 /* Look up current ratio */
808 for (i
= 0; i
< tabsz
; i
++) {
809 if ((orig_n
== table
[i
].n
) &&
810 (orig_sb
== table
[i
].sb
) &&
811 (orig_pci
== table
[i
].pci33
) &&
812 (orig_m2
== table
[i
].m2
) &&
813 (orig_mips
== table
[i
].m3
)) {
814 orig_ratio_parm
= table
[i
].ratio_parm
;
815 orig_ratio_cfg
= table
[i
].ratio_cfg
;
820 /* Search for the closest MIPS clock greater or equal to a preferred value */
821 for (i
= 0; i
< tabsz
; i
++) {
822 ASSERT(table
[i
].mipsclock
==
823 sb_clock_rate(pll_type
, table
[i
].n
, table
[i
].m3
));
824 if ((mipsclock
<= table
[i
].mipsclock
) &&
825 ((sbclock
== 0) || (sbclock
<= table
[i
].sbclock
)))
837 if ((orig_n
== te
->n
) &&
838 (orig_sb
== te
->sb
) &&
839 (orig_pci
== te
->pci33
) &&
840 (orig_m2
== te
->m2
) &&
841 (orig_mips
== te
->m3
))
844 /* Set the PLL controls */
845 W_REG(clockcontrol_n
, te
->n
);
846 W_REG(clockcontrol_sb
, te
->sb
);
847 W_REG(clockcontrol_pci
, te
->pci33
);
848 W_REG(&cc
->clockcontrol_m2
, te
->m2
);
849 W_REG(&cc
->clockcontrol_mips
, te
->m3
);
851 /* Set the chipcontrol bit to change mipsref to the backplane divider if needed */
852 if ((pll_type
== PLL_TYPE7
) &&
853 (te
->sb
!= te
->m2
) &&
854 (sb_clock_rate(pll_type
, te
->n
, te
->m2
) == 120000000))
855 W_REG(&cc
->chipcontrol
, R_REG(&cc
->chipcontrol
) | 0x100);
857 /* No ratio change */
858 if (orig_ratio_parm
== te
->ratio_parm
)
861 icache_probe(MFC0(C0_CONFIG
, 1), &ic_size
, &ic_lsize
);
863 /* Preload the code into the cache */
864 start
= ((ulong
) &&start_fill
) & ~(ic_lsize
- 1);
865 end
= ((ulong
) &&end_fill
+ (ic_lsize
- 1)) & ~(ic_lsize
- 1);
866 while (start
< end
) {
867 cache_unroll(start
, Fill_I
);
871 /* Copy the handler */
872 start
= (ulong
) &BCMINIT(handler
);
873 end
= (ulong
) &BCMINIT(afterhandler
);
874 dst
= KSEG1ADDR(0x180);
875 for (i
= 0; i
< (end
- start
); i
+= 4)
876 *((ulong
*)(dst
+ i
)) = *((ulong
*)(start
+ i
));
878 /* Preload handler into the cache one line at a time */
879 for (i
= 0; i
< (end
- start
); i
+= 4)
880 cache_unroll(dst
+ i
, Fill_I
);
883 MTC0(C0_STATUS
, 0, MFC0(C0_STATUS
, 0) & ~ST0_BEV
);
885 /* Enable interrupts */
886 MTC0(C0_STATUS
, 0, MFC0(C0_STATUS
, 0) | (ALLINTS
| ST0_IE
));
888 /* Enable MIPS timer interrupt */
889 if (!(mipsr
= sb_setcore(sbh
, SB_MIPS
, 0)) &&
890 !(mipsr
= sb_setcore(sbh
, SB_MIPS33
, 0)))
892 W_REG(&mipsr
->intmask
, 1);
895 /* step 1, set clock ratios */
896 MTC0(C0_BROADCOM
, 3, te
->ratio_parm
);
897 MTC0(C0_BROADCOM
, 1, te
->ratio_cfg
);
899 /* step 2: program timer intr */
900 W_REG(&mipsr
->timer
, 100);
901 (void) R_REG(&mipsr
->timer
);
903 /* step 3, switch to async */
904 sync_mode
= MFC0(C0_BROADCOM
, 4);
905 MTC0(C0_BROADCOM
, 4, 1 << 22);
907 /* step 4, set cfg active */
908 MTC0(C0_BROADCOM
, 2, 0x9);
912 __asm__
__volatile__ (
918 /* step 7, clear cfg_active */
919 MTC0(C0_BROADCOM
, 2, 0);
921 /* Additional Step: set back to orig sync mode */
922 MTC0(C0_BROADCOM
, 4, sync_mode
);
924 /* step 8, fake soft reset */
925 MTC0(C0_BROADCOM
, 5, MFC0(C0_BROADCOM
, 5) | 4);
928 /* step 9 set watchdog timer */
929 sb_watchdog(sbh
, 20);
930 (void) R_REG(&cc
->chipid
);
933 __asm__
__volatile__ (
943 /* switch back to previous core */
944 sb_setcoreidx(sbh
, idx
);
950 /* returns the ncdl value to be programmed into sdram_ncdl for calibration */
952 BCMINITFN(sb_memc_get_ncdl
)(void *sbh
)
956 uint32 config
, rd
, wr
, misc
, dqsg
, cd
, sm
, sd
;
959 idx
= sb_coreidx(sbh
);
961 memc
= (sbmemcregs_t
*)sb_setcore(sbh
, SB_MEMC
, 0);
965 rev
= sb_corerev(sbh
);
967 config
= R_REG(&memc
->config
);
968 wr
= R_REG(&memc
->wrncdlcor
);
969 rd
= R_REG(&memc
->rdncdlcor
);
970 misc
= R_REG(&memc
->miscdlyctl
);
971 dqsg
= R_REG(&memc
->dqsgatencdl
);
973 rd
&= MEMC_RDNCDLCOR_RD_MASK
;
974 wr
&= MEMC_WRNCDLCOR_WR_MASK
;
975 dqsg
&= MEMC_DQSGATENCDL_G_MASK
;
977 if (config
& MEMC_CONFIG_DDR
) {
978 ret
= (wr
<< 16) | (rd
<< 8) | dqsg
;
983 cd
= (rd
== MEMC_CD_THRESHOLD
) ? rd
: (wr
+ MEMC_CD_THRESHOLD
);
984 sm
= (misc
& MEMC_MISC_SM_MASK
) >> MEMC_MISC_SM_SHIFT
;
985 sd
= (misc
& MEMC_MISC_SD_MASK
) >> MEMC_MISC_SD_SHIFT
;
986 ret
= (sm
<< 16) | (sd
<< 8) | cd
;
990 /* switch back to previous core */
991 sb_setcoreidx(sbh
, idx
);
996 /* returns the PFC values to be used based on the chip ID*/
999 BCMINITFN(sb_mips_get_pfc
)(void *sbh
)
1001 if (BCMINIT(sb_chip
)(sbh
) == BCM5350_DEVICE_ID
)