2 * BCM47XX Sonics SiliconBackplane MIPS core routines
4 * Copyright 2004, 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.
28 * Memory segments (32bit kernel mode addresses)
35 #define KUSEG 0x00000000
36 #define KSEG0 0x80000000
37 #define KSEG1 0xa0000000
38 #define KSEG2 0xc0000000
39 #define KSEG3 0xe0000000
42 * Map an address to a certain kernel segment
48 #define KSEG0ADDR(a) (((a) & 0x1fffffff) | KSEG0)
49 #define KSEG1ADDR(a) (((a) & 0x1fffffff) | KSEG1)
50 #define KSEG2ADDR(a) (((a) & 0x1fffffff) | KSEG2)
51 #define KSEG3ADDR(a) (((a) & 0x1fffffff) | KSEG3)
54 * The following macros are especially useful for __asm__
61 #define STR(x) __STR(x)
64 /* *********************************************************************
66 ********************************************************************* */
68 #define C0_INX 0 /* CP0: TLB Index */
69 #define C0_RAND 1 /* CP0: TLB Random */
70 #define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */
71 #define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */
72 #define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */
73 #define C0_CTEXT 4 /* CP0: Context */
74 #define C0_PGMASK 5 /* CP0: TLB PageMask */
75 #define C0_WIRED 6 /* CP0: TLB Wired */
76 #define C0_BADVADDR 8 /* CP0: Bad Virtual Address */
77 #define C0_COUNT 9 /* CP0: Count */
78 #define C0_TLBHI 10 /* CP0: TLB EntryHi */
79 #define C0_COMPARE 11 /* CP0: Compare */
80 #define C0_SR 12 /* CP0: Processor Status */
81 #define C0_STATUS C0_SR /* CP0: Processor Status */
82 #define C0_CAUSE 13 /* CP0: Exception Cause */
83 #define C0_EPC 14 /* CP0: Exception PC */
84 #define C0_PRID 15 /* CP0: Processor Revision Indentifier */
85 #define C0_CONFIG 16 /* CP0: Config */
86 #define C0_LLADDR 17 /* CP0: LLAddr */
87 #define C0_WATCHLO 18 /* CP0: WatchpointLo */
88 #define C0_WATCHHI 19 /* CP0: WatchpointHi */
89 #define C0_XCTEXT 20 /* CP0: XContext */
90 #define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */
91 #define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */
92 #define C0_ECC 26 /* CP0: ECC */
93 #define C0_CACHEERR 27 /* CP0: CacheErr */
94 #define C0_TAGLO 28 /* CP0: TagLo */
95 #define C0_TAGHI 29 /* CP0: TagHi */
96 #define C0_ERREPC 30 /* CP0: ErrorEPC */
99 * Macros to access the system control coprocessor
102 #define MFC0(source, sel) \
105 __asm__ __volatile__( \
106 ".set\tnoreorder\n\t" \
108 ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \
118 #define MTC0(source, sel, value) \
120 __asm__ __volatile__( \
121 ".set\tnoreorder\n\t" \
124 ".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \
133 * R4x00 interrupt enable / cause bits
143 #define IE_SW0 (1<< 8)
144 #define IE_SW1 (1<< 9)
145 #define IE_IRQ0 (1<<10)
146 #define IE_IRQ1 (1<<11)
147 #define IE_IRQ2 (1<<12)
148 #define IE_IRQ3 (1<<13)
149 #define IE_IRQ4 (1<<14)
150 #define IE_IRQ5 (1<<15)
153 * Bitfields in the R4xx0 cp0 status register
155 #define ST0_IE 0x00000001
156 #define ST0_EXL 0x00000002
157 #define ST0_ERL 0x00000004
158 #define ST0_KSU 0x00000018
159 # define KSU_USER 0x00000010
160 # define KSU_SUPERVISOR 0x00000008
161 # define KSU_KERNEL 0x00000000
162 #define ST0_UX 0x00000020
163 #define ST0_SX 0x00000040
164 #define ST0_KX 0x00000080
165 #define ST0_DE 0x00010000
166 #define ST0_CE 0x00020000
169 * Status register bits available in all MIPS CPUs.
171 #define ST0_IM 0x0000ff00
172 #define ST0_CH 0x00040000
173 #define ST0_SR 0x00100000
174 #define ST0_TS 0x00200000
175 #define ST0_BEV 0x00400000
176 #define ST0_RE 0x02000000
177 #define ST0_FR 0x04000000
178 #define ST0_CU 0xf0000000
179 #define ST0_CU0 0x10000000
180 #define ST0_CU1 0x20000000
181 #define ST0_CU2 0x40000000
182 #define ST0_CU3 0x80000000
183 #define ST0_XX 0x80000000 /* MIPS IV naming */
193 #define cache_unroll(base,op) \
194 __asm__ __volatile__(" \
205 * These are the UART port assignments, expressed as offsets from the base
206 * register. These assignments should hold for any serial port based on
207 * a 8250, 16450, or 16550(A).
210 #define UART_MCR 4 /* Out: Modem Control Register */
211 #define UART_MSR 6 /* In: Modem Status Register */
212 #define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
215 * Returns TRUE if an external UART exists at the given base
219 serial_exists(uint8
*regs
)
221 uint8 save_mcr
, status1
;
223 save_mcr
= R_REG(®s
[UART_MCR
]);
224 W_REG(®s
[UART_MCR
], UART_MCR_LOOP
| 0x0a);
225 status1
= R_REG(®s
[UART_MSR
]) & 0xf0;
226 W_REG(®s
[UART_MCR
], save_mcr
);
228 return (status1
== 0x90);
232 * Initializes UART access. The callback function will be called once
236 sb_serial_init(void *sbh
, void (*add
)(void *regs
, uint irq
, uint baud_base
, uint reg_shift
))
243 if ((regs
= sb_setcore(sbh
, SB_EXTIF
, 0))) {
244 extifregs_t
*eir
= (extifregs_t
*) regs
;
247 /* Determine external UART register base */
248 sb
= (sbconfig_t
*)((ulong
) eir
+ SBCONFIGOFF
);
249 base
= EXTIF_CFGIF_BASE(sb_base(R_REG(&sb
->sbadmatch1
)));
254 /* Disable GPIO interrupt initially */
255 W_REG(&eir
->gpiointpolarity
, 0);
256 W_REG(&eir
->gpiointmask
, 0);
258 /* Search for external UARTs */
260 for (i
= 0; i
< 2; i
++) {
261 regs
= (void *) REG_MAP(base
+ (i
* 8), 8);
262 if (serial_exists(regs
)) {
263 /* Set GPIO 1 to be the external UART IRQ */
264 W_REG(&eir
->gpiointmask
, 2);
266 add(regs
, irq
, 13500000, 0);
270 /* Add internal UART if enabled */
271 if (R_REG(&eir
->corecontrol
) & CC_UE
)
273 add((void *) &eir
->uartdata
, irq
, sb_clock(sbh
), 2);
274 } else if ((regs
= sb_setcore(sbh
, SB_CC
, 0))) {
275 chipcregs_t
*cc
= (chipcregs_t
*) regs
;
276 uint32 rev
, cap
, pll
, baud_base
, div
;
278 /* Determine core revision and capabilities */
279 rev
= sb_corerev(sbh
);
280 cap
= R_REG(&cc
->capabilities
);
281 pll
= cap
& CAP_PLL_MASK
;
286 if (pll
== PLL_TYPE1
) {
288 baud_base
= sb_clock_rate(pll
,
289 R_REG(&cc
->clockcontrol_n
),
290 R_REG(&cc
->clockcontrol_m2
));
292 } else if (rev
>= 3) {
293 /* Internal backplane clock */
294 baud_base
= sb_clock_rate(pll
,
295 R_REG(&cc
->clockcontrol_n
),
296 R_REG(&cc
->clockcontrol_sb
));
297 div
= 2; /* Minimum divisor */
298 W_REG(&cc
->clkdiv
, ((R_REG(&cc
->clkdiv
) & ~CLKD_UART
) | div
));
300 /* Fixed internal backplane clock */
301 baud_base
= 88000000;
305 /* Clock source depends on strapping if UartClkOverride is unset */
306 if ((rev
> 0) && ((R_REG(&cc
->corecontrol
) & CC_UARTCLKO
) == 0)) {
307 if ((cap
& CAP_UCLKSEL
) == CAP_UINTCLK
) {
308 /* Internal divided backplane clock */
311 /* Assume external clock of 1.8432 MHz */
316 /* Add internal UARTs */
317 n
= cap
& CAP_UARTS_MASK
;
318 for (i
= 0; i
< n
; i
++) {
319 /* Register offset changed after revision 0 */
321 regs
= (void *)((ulong
) &cc
->uart0data
+ (i
* 256));
323 regs
= (void *)((ulong
) &cc
->uart0data
+ (i
* 8));
326 add(regs
, irq
, baud_base
, 0);
331 /* Returns the SB interrupt flag of the current core. */
338 regs
= sb_coreregs(sbh
);
339 sb
= (sbconfig_t
*)((ulong
) regs
+ SBCONFIGOFF
);
341 return (R_REG(&sb
->sbtpsflag
) & SBTPS_NUM0_MASK
);
344 static const uint32 sbips_int_mask
[] = {
352 static const uint32 sbips_int_shift
[] = {
361 * Returns the MIPS IRQ assignment of the current core. If unassigned,
370 uint32 flag
, sbipsflag
;
375 idx
= sb_coreidx(sbh
);
377 if ((regs
= sb_setcore(sbh
, SB_MIPS
, 0)) ||
378 (regs
= sb_setcore(sbh
, SB_MIPS33
, 0))) {
379 sb
= (sbconfig_t
*)((ulong
) regs
+ SBCONFIGOFF
);
381 /* sbipsflag specifies which core is routed to interrupts 1 to 4 */
382 sbipsflag
= R_REG(&sb
->sbipsflag
);
383 for (irq
= 1; irq
<= 4; irq
++) {
384 if (((sbipsflag
& sbips_int_mask
[irq
]) >> sbips_int_shift
[irq
]) == flag
)
391 sb_setcoreidx(sbh
, idx
);
396 /* Clears the specified MIPS IRQ. */
398 sb_clearirq(void *sbh
, uint irq
)
403 if (!(regs
= sb_setcore(sbh
, SB_MIPS
, 0)) &&
404 !(regs
= sb_setcore(sbh
, SB_MIPS33
, 0)))
406 sb
= (sbconfig_t
*)((ulong
) regs
+ SBCONFIGOFF
);
409 W_REG(&sb
->sbintvec
, 0);
411 OR_REG(&sb
->sbipsflag
, sbips_int_mask
[irq
]);
415 * Assigns the specified MIPS IRQ to the specified core. Shared MIPS
416 * IRQ 0 may be assigned more than once.
419 sb_setirq(void *sbh
, uint irq
, uint coreid
, uint coreunit
)
425 regs
= sb_setcore(sbh
, coreid
, coreunit
);
429 if (!(regs
= sb_setcore(sbh
, SB_MIPS
, 0)) &&
430 !(regs
= sb_setcore(sbh
, SB_MIPS33
, 0)))
432 sb
= (sbconfig_t
*)((ulong
) regs
+ SBCONFIGOFF
);
435 OR_REG(&sb
->sbintvec
, 1 << flag
);
437 flag
<<= sbips_int_shift
[irq
];
438 ASSERT(!(flag
& ~sbips_int_mask
[irq
]));
439 flag
|= R_REG(&sb
->sbipsflag
) & ~sbips_int_mask
[irq
];
440 W_REG(&sb
->sbipsflag
, flag
);
445 * Initializes clocks and interrupts. SB and NVRAM access must be
446 * initialized prior to calling.
449 sb_mips_init(void *sbh
)
457 /* Figure out current SB clock speed */
458 if ((hz
= sb_clock(sbh
)) == 0)
460 ns
= 1000000000 / hz
;
462 /* Setup external interface timing */
463 if ((eir
= sb_setcore(sbh
, SB_EXTIF
, 0))) {
464 /* Initialize extif so we can get to the LEDs and external UART */
465 W_REG(&eir
->prog_config
, CF_EN
);
467 /* Set timing for the flash */
468 tmp
= CEIL(10, ns
) << FW_W3_SHIFT
; /* W3 = 10nS */
469 tmp
= tmp
| (CEIL(40, ns
) << FW_W1_SHIFT
); /* W1 = 40nS */
470 tmp
= tmp
| CEIL(120, ns
); /* W0 = 120nS */
471 W_REG(&eir
->prog_waitcount
, tmp
); /* 0x01020a0c for a 100Mhz clock */
473 /* Set programmable interface timing for external uart */
474 tmp
= CEIL(10, ns
) << FW_W3_SHIFT
; /* W3 = 10nS */
475 tmp
= tmp
| (CEIL(20, ns
) << FW_W2_SHIFT
); /* W2 = 20nS */
476 tmp
= tmp
| (CEIL(100, ns
) << FW_W1_SHIFT
); /* W1 = 100nS */
477 tmp
= tmp
| CEIL(120, ns
); /* W0 = 120nS */
478 W_REG(&eir
->prog_waitcount
, tmp
); /* 0x01020a0c for a 100Mhz clock */
479 } else if ((cc
= sb_setcore(sbh
, SB_CC
, 0))) {
480 /* Set timing for the flash */
481 tmp
= CEIL(10, ns
) << FW_W3_SHIFT
; /* W3 = 10nS */
482 tmp
|= CEIL(10, ns
) << FW_W1_SHIFT
; /* W1 = 10nS */
483 tmp
|= CEIL(120, ns
); /* W0 = 120nS */
484 W_REG(&cc
->flash_waitcount
, tmp
);
486 W_REG(&cc
->pcmcia_memwait
, tmp
);
489 /* Chip specific initialization */
490 switch (sb_chip(sbh
)) {
491 case BCM4710_DEVICE_ID
:
492 /* Clear interrupt map */
493 for (irq
= 0; irq
<= 4; irq
++)
494 sb_clearirq(sbh
, irq
);
495 sb_setirq(sbh
, 0, SB_CODEC
, 0);
496 sb_setirq(sbh
, 0, SB_EXTIF
, 0);
497 sb_setirq(sbh
, 2, SB_ENET
, 1);
498 sb_setirq(sbh
, 3, SB_ILINE20
, 0);
499 sb_setirq(sbh
, 4, SB_PCI
, 0);
501 value
= nvram_get("et0phyaddr");
502 if (value
&& !strcmp(value
, "31")) {
503 /* Enable internal UART */
504 W_REG(&eir
->corecontrol
, CC_UE
);
505 /* Give USB its own interrupt */
506 sb_setirq(sbh
, 1, SB_USB
, 0);
508 /* Disable internal UART */
509 W_REG(&eir
->corecontrol
, 0);
510 /* Give Ethernet its own interrupt */
511 sb_setirq(sbh
, 1, SB_ENET
, 0);
512 sb_setirq(sbh
, 0, SB_USB
, 0);
515 case BCM4310_DEVICE_ID
:
516 MTC0(C0_BROADCOM
, 0, MFC0(C0_BROADCOM
, 0) & ~(1 << 22));
522 sb_mips_clock(void *sbh
)
528 uint32 pll_type
, rate
= 0;
530 /* get index of the current core */
531 idx
= sb_coreidx(sbh
);
532 pll_type
= PLL_TYPE1
;
534 /* switch to extif or chipc core */
535 if ((eir
= (extifregs_t
*) sb_setcore(sbh
, SB_EXTIF
, 0))) {
536 n
= R_REG(&eir
->clockcontrol_n
);
537 m
= R_REG(&eir
->clockcontrol_sb
);
538 } else if ((cc
= (chipcregs_t
*) sb_setcore(sbh
, SB_CC
, 0))) {
539 pll_type
= R_REG(&cc
->capabilities
) & CAP_PLL_MASK
;
540 n
= R_REG(&cc
->clockcontrol_n
);
541 if ((pll_type
== PLL_TYPE2
) || (pll_type
== PLL_TYPE4
))
542 m
= R_REG(&cc
->clockcontrol_mips
);
543 else if (pll_type
== PLL_TYPE3
) {
547 m
= R_REG(&cc
->clockcontrol_sb
);
552 rate
= sb_clock_rate(pll_type
, n
, m
);
555 /* switch back to previous core */
556 sb_setcoreidx(sbh
, idx
);
562 icache_probe(int *size
, int *lsize
)
567 config1
= MFC0(C0_CONFIG
, 1);
569 /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */
570 if ((*lsize
= ((config1
>> 19) & 7)))
571 *lsize
= 2 << *lsize
;
572 sets
= 64 << ((config1
>> 22) & 7);
573 ways
= 1 + ((config1
>> 16) & 7);
574 *size
= *lsize
* sets
* ways
;
577 #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
587 /* Disable interrupts */
588 /* MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */
590 "and $15, $15, -31746\n\t"
599 /* The following MUST come right after handler() */
606 * Set the MIPS, backplane and PCI clocks as closely as possible.
609 sb_mips_setclock(void *sbh
, uint32 mipsclock
, uint32 sbclock
, uint32 pciclock
)
611 extifregs_t
*eir
= NULL
;
612 chipcregs_t
*cc
= NULL
;
613 mipsregs_t
*mipsr
= NULL
;
614 volatile uint32
*clockcontrol_n
, *clockcontrol_sb
, *clockcontrol_pci
;
615 uint32 orig_n
, orig_sb
, orig_pci
, orig_m2
, orig_mips
, orig_ratio_parm
, new_ratio
;
616 uint32 pll_type
, sync_mode
;
625 static n3m_table_t type1_table
[] = {
626 { 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, /* 96.000 32.000 24.000 */
627 { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, /* 100.000 33.333 25.000 */
628 { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, /* 104.000 31.200 24.960 */
629 { 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 }, /* 108.000 32.400 24.923 */
630 { 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 }, /* 112.000 32.000 24.889 */
631 { 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 }, /* 115.200 32.000 24.000 */
632 { 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 }, /* 120.000 30.000 24.000 */
633 { 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 }, /* 124.800 31.200 24.960 */
634 { 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 }, /* 128.000 32.000 24.000 */
635 { 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 }, /* 132.000 33.000 24.750 */
636 { 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 }, /* 136.000 32.640 24.727 */
637 { 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 }, /* 140.000 30.000 24.706 */
638 { 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 }, /* 144.000 30.857 24.686 */
639 { 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 }, /* 150.857 33.000 24.000 */
640 { 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 }, /* 152.000 32.571 24.000 */
641 { 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 }, /* 156.000 31.200 24.960 */
642 { 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 }, /* 160.000 32.000 24.000 */
643 { 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 }, /* 163.200 32.640 24.727 */
644 { 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 }, /* 168.000 32.000 24.889 */
645 { 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 }, /* 176.000 33.000 24.000 */
659 static n4m_table_t type2_table
[] = {
660 { 180000000, 80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
661 { 180000000, 90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 },
662 { 200000000, 100000000, 0x0303, 0x01000000, 0x01000600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 },
663 { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
664 { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
665 { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
666 { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
667 { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
668 { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 },
669 { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
670 { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
671 { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
672 { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 },
673 { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
674 { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 },
675 { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
676 { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 }
679 static n4m_table_t type4_table
[] = {
680 { 192000000, 96000000, 0x0702, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 0x21, 0x0aaa0555 },
681 { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 0x21, 0x0aaa0555 },
682 { 216000000, 108000000, 0x0111, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 0x21, 0x0aaa0555 },
683 { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x11030305, 0x04000005, 0x94, 0x012a00a9 },
684 { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 0x21, 0x0aaa0555 },
685 { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 0x21, 0x0aaa0555 },
686 { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 0x21, 0x0aaa0555 },
687 { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 0x21, 0x0aaa0555 },
688 { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 0x73, 0x254a14a9 },
689 { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 0x73, 0x254a14a9 },
690 { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 0x73, 0x254a14a9 },
691 { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002, 0x52, 0x02520129 }
693 uint icache_size
, ic_lsize
;
694 ulong start
, end
, dst
;
697 /* get index of the current core */
698 idx
= sb_coreidx(sbh
);
700 /* switch to extif or chipc core */
701 if ((eir
= (extifregs_t
*) sb_setcore(sbh
, SB_EXTIF
, 0))) {
702 pll_type
= PLL_TYPE1
;
703 clockcontrol_n
= &eir
->clockcontrol_n
;
704 clockcontrol_sb
= &eir
->clockcontrol_sb
;
705 clockcontrol_pci
= &eir
->clockcontrol_pci
;
706 } else if ((cc
= (chipcregs_t
*) sb_setcore(sbh
, SB_CC
, 0))) {
707 pll_type
= R_REG(&cc
->capabilities
) & CAP_PLL_MASK
;
708 clockcontrol_n
= &cc
->clockcontrol_n
;
709 clockcontrol_sb
= &cc
->clockcontrol_sb
;
710 clockcontrol_pci
= &cc
->clockcontrol_pci
;
714 /* Store the current clock register values */
715 orig_n
= R_REG(clockcontrol_n
);
716 orig_sb
= R_REG(clockcontrol_sb
);
717 orig_pci
= R_REG(clockcontrol_pci
);
719 if (pll_type
== PLL_TYPE1
) {
720 /* Keep the current PCI clock if not specified */
722 pciclock
= sb_clock_rate(pll_type
, R_REG(clockcontrol_n
), R_REG(clockcontrol_pci
));
723 pciclock
= (pciclock
<= 25000000) ? 25000000 : 33000000;
726 /* Search for the closest MIPS clock less than or equal to a preferred value */
727 for (i
= 0; i
< ARRAYSIZE(type1_table
); i
++) {
728 ASSERT(type1_table
[i
].mipsclock
==
729 sb_clock_rate(pll_type
, type1_table
[i
].n
, type1_table
[i
].sb
));
730 if (type1_table
[i
].mipsclock
> mipsclock
)
740 ASSERT(type1_table
[i
].mipsclock
<= mipsclock
);
743 if ((orig_n
== type1_table
[i
].n
) &&
744 (orig_sb
== type1_table
[i
].sb
) &&
745 (orig_pci
== type1_table
[i
].pci33
))
748 /* Set the PLL controls */
749 W_REG(clockcontrol_n
, type1_table
[i
].n
);
750 W_REG(clockcontrol_sb
, type1_table
[i
].sb
);
751 if (pciclock
== 25000000)
752 W_REG(clockcontrol_pci
, type1_table
[i
].pci25
);
754 W_REG(clockcontrol_pci
, type1_table
[i
].pci33
);
759 } else if ((pll_type
== PLL_TYPE2
) || (pll_type
== PLL_TYPE4
)) {
760 n4m_table_t
*table
= (pll_type
== PLL_TYPE2
) ? type2_table
: type4_table
;
761 uint tabsz
= (pll_type
== PLL_TYPE2
) ? ARRAYSIZE(type2_table
) : ARRAYSIZE(type4_table
);
765 /* Store the current clock register values */
766 orig_m2
= R_REG(&cc
->clockcontrol_m2
);
767 orig_mips
= R_REG(&cc
->clockcontrol_mips
);
770 /* Look up current ratio */
771 for (i
= 0; i
< tabsz
; i
++) {
772 if ((orig_n
== table
[i
].n
) &&
773 (orig_sb
== table
[i
].sb
) &&
774 (orig_pci
== table
[i
].pci33
) &&
775 (orig_m2
== table
[i
].m2
) &&
776 (orig_mips
== table
[i
].m3
)) {
777 orig_ratio_parm
= table
[i
].ratio_parm
;
782 /* Search for the closest MIPS clock greater or equal to a preferred value */
783 for (i
= 0; i
< tabsz
; i
++) {
784 ASSERT(table
[i
].mipsclock
==
785 sb_clock_rate(pll_type
, table
[i
].n
, table
[i
].m3
));
786 if ((mipsclock
<= table
[i
].mipsclock
) &&
787 ((sbclock
== 0) || (sbclock
<= table
[i
].sbclock
)))
798 if ((orig_n
== table
[i
].n
) &&
799 (orig_sb
== table
[i
].sb
) &&
800 (orig_pci
== table
[i
].pci33
) &&
801 (orig_m2
== table
[i
].m2
) &&
802 (orig_mips
== table
[i
].m3
))
805 /* Set the PLL controls */
806 W_REG(clockcontrol_n
, table
[i
].n
);
807 W_REG(clockcontrol_sb
, table
[i
].sb
);
808 W_REG(clockcontrol_pci
, table
[i
].pci33
);
809 W_REG(&cc
->clockcontrol_m2
, table
[i
].m2
);
810 W_REG(&cc
->clockcontrol_mips
, table
[i
].m3
);
812 /* No ratio change */
813 if (orig_ratio_parm
== table
[i
].ratio_parm
)
816 new_ratio
= table
[i
].ratio_parm
;
818 icache_probe(&icache_size
, &ic_lsize
);
820 /* Preload the code into the cache */
821 start
= ((ulong
) &&start_fill
) & ~(ic_lsize
- 1);
822 end
= ((ulong
) &&end_fill
+ (ic_lsize
- 1)) & ~(ic_lsize
- 1);
823 while (start
< end
) {
824 cache_unroll(start
, Fill_I
);
828 /* Copy the handler */
829 start
= (ulong
) &handler
;
830 end
= (ulong
) &afterhandler
;
831 dst
= KSEG1ADDR(0x180);
832 for (i
= 0; i
< (end
- start
); i
+= 4)
833 *((ulong
*)(dst
+ i
)) = *((ulong
*)(start
+ i
));
835 /* Preload handler into the cache one line at a time */
836 for (i
= 0; i
< (end
- start
); i
+= 4)
837 cache_unroll(dst
+ i
, Fill_I
);
840 MTC0(C0_STATUS
, 0, MFC0(C0_STATUS
, 0) & ~ST0_BEV
);
842 /* Enable interrupts */
843 MTC0(C0_STATUS
, 0, MFC0(C0_STATUS
, 0) | (ALLINTS
| ST0_IE
));
845 /* Enable MIPS timer interrupt */
846 if (!(mipsr
= sb_setcore(sbh
, SB_MIPS
, 0)) &&
847 !(mipsr
= sb_setcore(sbh
, SB_MIPS33
, 0)))
849 W_REG(&mipsr
->intmask
, 1);
852 /* step 1, set clock ratios */
853 MTC0(C0_BROADCOM
, 3, new_ratio
);
854 MTC0(C0_BROADCOM
, 1, 8);
856 /* step 2: program timer intr */
857 W_REG(&mipsr
->timer
, 100);
858 (void) R_REG(&mipsr
->timer
);
860 /* step 3, switch to async */
861 sync_mode
= MFC0(C0_BROADCOM
, 4);
862 MTC0(C0_BROADCOM
, 4, 1 << 22);
864 /* step 4, set cfg active */
865 MTC0(C0_BROADCOM
, 2, 0x9);
869 __asm__
__volatile__ (
875 /* step 7, clear cfg_active */
876 MTC0(C0_BROADCOM
, 2, 0);
878 /* Additional Step: set back to orig sync mode */
879 MTC0(C0_BROADCOM
, 4, sync_mode
);
881 /* step 8, fake soft reset */
882 MTC0(C0_BROADCOM
, 5, MFC0(C0_BROADCOM
, 5) | 4);
885 /* step 9 set watchdog timer */
886 sb_watchdog(sbh
, 20);
887 (void) R_REG(&cc
->chipid
);
890 __asm__
__volatile__ (
900 /* switch back to previous core */
901 sb_setcoreidx(sbh
, idx
);
907 /* returns the ncdl value to be programmed into sdram_ncdl for calibration */
909 sb_memc_get_ncdl(void *sbh
)
913 uint32 config
, rd
, wr
, misc
, dqsg
, cd
, sm
, sd
;
916 idx
= sb_coreidx(sbh
);
918 memc
= (sbmemcregs_t
*)sb_setcore(sbh
, SB_MEMC
, 0);
922 rev
= sb_corerev(sbh
);
924 config
= R_REG(&memc
->config
);
925 wr
= R_REG(&memc
->wrncdlcor
);
926 rd
= R_REG(&memc
->rdncdlcor
);
927 misc
= R_REG(&memc
->miscdlyctl
);
928 dqsg
= R_REG(&memc
->dqsgatencdl
);
930 rd
&= MEMC_RDNCDLCOR_RD_MASK
;
931 wr
&= MEMC_WRNCDLCOR_WR_MASK
;
932 dqsg
&= MEMC_DQSGATENCDL_G_MASK
;
934 if (config
& MEMC_CONFIG_DDR
) {
935 ret
= (wr
<< 16) | (rd
<< 8) | dqsg
;
940 cd
= (rd
== MEMC_CD_THRESHOLD
) ? rd
: (wr
+ MEMC_CD_THRESHOLD
);
941 sm
= (misc
& MEMC_MISC_SM_MASK
) >> MEMC_MISC_SM_SHIFT
;
942 sd
= (misc
& MEMC_MISC_SD_MASK
) >> MEMC_MISC_SD_SHIFT
;
943 ret
= (sm
<< 16) | (sd
<< 8) | cd
;
947 /* switch back to previous core */
948 sb_setcoreidx(sbh
, idx
);
This page took 0.095131 seconds and 5 git commands to generate.