2 * BCM47XX Sonics SiliconBackplane MIPS core routines
4 * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved.
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * $Id: hndmips.c 419467 2013-08-21 09:19:48Z $
33 #include <mips33_core.h>
34 #include <mips74k_core.h>
38 #include <dmemc_core.h>
42 #define HNDMIPS_ERROR(args) printf args
44 #define HNDMIPS_ERROR(args)
45 #endif /* BCMDBG_ERR */
48 #define HNDMIPS_MSG(args) printf args
50 #define HNDMIPS_MSG(args)
52 #define HNDMIPS_NONE(args)
54 /* sbipsflag register format, indexed by irq. */
55 static const uint32 sbips_int_mask
[] = {
63 static const uint32 sbips_int_shift
[] = {
72 * Map SB cores sharing the MIPS hardware IRQ0 to virtual dedicated OS IRQs.
73 * Per-port BSP code is required to provide necessary translations between
74 * the shared MIPS IRQ and the virtual OS IRQs based on SB core flag.
76 * See si_irq() for the mapping.
78 static uint shirq_map_base
= 0;
81 * Returns the MIPS IRQ assignment of the current core. If unassigned,
91 uint32 flag
, sbipsflag
;
97 idx
= si_coreidx(sih
);
99 if ((regs
= si_setcore(sih
, MIPS74K_CORE_ID
, 0)) != NULL
) {
100 /* IntMask1,2,3,4 regs are configured to enable propagation of
101 * backplane interrupts 0,1,2,3 to mips hw interrupts 1,2,3,4.
103 for (irq
= 1; irq
<= 4; irq
++) {
104 if (R_REG(osh
, &((mips74kregs_t
*)regs
)->intmask
[irq
]) &
108 } else if ((regs
= si_setcore(sih
, MIPS33_CORE_ID
, 0)) != NULL
) {
109 sb
= (sbconfig_t
*)((ulong
) regs
+ SBCONFIGOFF
);
111 /* sbipsflag specifies which core is routed to interrupts 1 to 4 */
112 sbipsflag
= R_REG(osh
, &sb
->sbipsflag
);
113 for (irq
= 1; irq
<= 4; irq
++) {
114 if (((sbipsflag
& sbips_int_mask
[irq
]) >>
115 sbips_int_shift
[irq
]) == flag
)
119 ASSERT("Unknown processor core" == NULL
);
120 return 1000; /* An invalid value */
123 /* If we didn't find it it must be in the shared int (0) */
127 si_setcoreidx(sih
, idx
);
133 * Return the MIPS IRQ assignment of the current core. If necessary
134 * map cores sharing the MIPS hw IRQ0 to virtual dedicated OS IRQs.
139 uint irq
= si_getirq(sih
);
140 if (irq
== 0 && shirq_map_base
)
141 irq
= si_flag(sih
) + shirq_map_base
;
145 /* Clears the specified MIPS IRQ. */
147 BCMINITFN(si_clearirq
)(si_t
*sih
, uint irq
)
155 if ((regs
= si_setcore(sih
, MIPS74K_CORE_ID
, 0)) != NULL
) {
156 W_REG(osh
, &((mips74kregs_t
*)regs
)->intmask
[irq
], 0);
157 } else if ((regs
= si_setcore(sih
, MIPS33_CORE_ID
, 0)) != NULL
) {
158 sb
= (sbconfig_t
*)((ulong
) regs
+ SBCONFIGOFF
);
160 W_REG(osh
, &sb
->sbintvec
, 0);
162 OR_REG(osh
, &sb
->sbipsflag
, sbips_int_mask
[irq
]);
164 ASSERT("Unknown processor core" == NULL
);
168 * Assigns the specified MIPS IRQ to the specified core. Shared MIPS
169 * IRQ 0 may be assigned more than once.
171 * The old assignment to the specified core is removed first.
174 BCMATTACHFN(si_setirq
)(si_t
*sih
, uint irq
, uint coreid
, uint coreunit
)
184 regs
= si_setcore(sih
, coreid
, coreunit
);
187 oldirq
= si_getirq(sih
);
189 si_clearirq(sih
, oldirq
);
191 if ((regs
= si_setcore(sih
, MIPS74K_CORE_ID
, 0)) != NULL
) {
193 AND_REG(osh
, &((mips74kregs_t
*)regs
)->intmask
[0], ~(1 << flag
));
196 OR_REG(osh
, &((mips74kregs_t
*)regs
)->intmask
[0], 1 << flag
);
198 W_REG(osh
, &((mips74kregs_t
*)regs
)->intmask
[irq
], 1 << flag
);
200 } else if ((regs
= si_setcore(sih
, MIPS33_CORE_ID
, 0)) != NULL
) {
201 sb
= (sbconfig_t
*)((ulong
) regs
+ SBCONFIGOFF
);
204 AND_REG(osh
, &sb
->sbintvec
, ~(1 << flag
));
207 OR_REG(osh
, &sb
->sbintvec
, 1 << flag
);
209 flag
<<= sbips_int_shift
[irq
];
210 ASSERT(!(flag
& ~sbips_int_mask
[irq
]));
211 flag
|= R_REG(osh
, &sb
->sbipsflag
) & ~sbips_int_mask
[irq
];
212 W_REG(osh
, &sb
->sbipsflag
, flag
);
215 ASSERT("Unknown processor core" == NULL
);
219 * Initializes clocks and interrupts. SB and NVRAM access must be
220 * initialized prior to calling.
222 * 'shirqmap' enables virtual dedicated OS IRQ mapping if non-zero.
225 BCMATTACHFN(si_mips_init
)(si_t
*sih
, uint shirqmap
)
235 /* Disable interrupts */
236 c0reg
= MFC0(C0_STATUS
, 0);
238 MTC0(C0_STATUS
, 0, c0reg
);
240 /* Figure out current SB clock speed */
241 if ((hz
= si_clock(sih
)) == 0)
243 ns
= 1000000000 / hz
;
245 /* Setup external interface timing */
246 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
249 /* Set timing for the flash */
250 tmp
= CEIL(10, ns
) << FW_W3_SHIFT
; /* W3 = 10nS */
251 tmp
|= CEIL(10, ns
) << FW_W1_SHIFT
; /* W1 = 10nS */
252 tmp
|= CEIL(120, ns
); /* W0 = 120nS */
254 W_REG(osh
, &cc
->flash_waitcount
, tmp
);
256 if ((sih
->ccrev
< 9) ||
257 ((CHIPID(sih
->chip
) == BCM5350_CHIP_ID
) && CHIPREV(sih
->chiprev
) == 0)) {
258 W_REG(osh
, &cc
->pcmcia_memwait
, tmp
);
261 /* Save shared IRQ mapping base */
262 shirq_map_base
= shirqmap
;
264 /* Chip specific initialization */
265 switch (CHIPID(sih
->chip
)) {
266 case BCM5350_CHIP_ID
:
267 /* Clear interrupt map */
268 for (irq
= 0; irq
<= 4; irq
++)
269 si_clearirq(sih
, irq
);
270 si_setirq(sih
, 0, CC_CORE_ID
, 0);
271 si_setirq(sih
, 0, MIPS33_CORE_ID
, 0);
272 si_setirq(sih
, 1, D11_CORE_ID
, 0);
273 si_setirq(sih
, 2, ENET_CORE_ID
, 0);
274 si_setirq(sih
, 3, PCI_CORE_ID
, 0);
275 si_setirq(sih
, 4, USB_CORE_ID
, 0);
277 case BCM4785_CHIP_ID
:
278 /* Reassign PCI to irq 4 */
279 si_setirq(sih
, 4, PCI_CORE_ID
, 0);
281 case BCM4716_CHIP_ID
:
282 case BCM4748_CHIP_ID
:
283 /* Clear interrupt map */
284 for (irq
= 0; irq
<= 4; irq
++)
285 si_clearirq(sih
, irq
);
286 si_setirq(sih
, 1, D11_CORE_ID
, 0);
287 si_setirq(sih
, 2, GMAC_CORE_ID
, 0);
288 si_setirq(sih
, 3, USB20H_CORE_ID
, 0);
289 si_setirq(sih
, 4, PCIE_CORE_ID
, 0);
290 si_setirq(sih
, 0, CC_CORE_ID
, 0);
291 si_setirq(sih
, 0, I2S_CORE_ID
, 0);
293 case BCM5356_CHIP_ID
:
294 case BCM47162_CHIP_ID
:
295 case BCM53572_CHIP_ID
:
296 /* Clear interrupt map */
297 for (irq
= 0; irq
<= 4; irq
++)
298 si_clearirq(sih
, irq
);
299 si_setirq(sih
, 1, D11_CORE_ID
, 0);
300 si_setirq(sih
, 2, GMAC_CORE_ID
, 0);
301 si_setirq(sih
, 0, CC_CORE_ID
, 0);
303 case BCM5357_CHIP_ID
:
304 case BCM4749_CHIP_ID
:
305 /* Clear interrupt map */
306 for (irq
= 0; irq
<= 4; irq
++)
307 si_clearirq(sih
, irq
);
308 si_setirq(sih
, 1, D11_CORE_ID
, 0);
309 si_setirq(sih
, 2, GMAC_CORE_ID
, 0);
310 si_setirq(sih
, 3, USB20H_CORE_ID
, 0);
311 si_setirq(sih
, 0, CC_CORE_ID
, 0);
312 si_setirq(sih
, 0, I2S_CORE_ID
, 0);
314 case BCM4706_CHIP_ID
:
315 /* Clear interrupt map */
316 for (irq
= 0; irq
<= 4; irq
++)
317 si_clearirq(sih
, irq
);
318 si_setirq(sih
, 1, PCIE_CORE_ID
, 0);
319 si_setirq(sih
, 2, GMAC_CORE_ID
, 0);
320 si_setirq(sih
, 3, PCIE_CORE_ID
, 1);
321 si_setirq(sih
, 4, USB20H_CORE_ID
, 0);
322 si_setirq(sih
, 0, CC_CORE_ID
, 0);
328 /* Do any setup necessary to run a new image and jump to it. */
330 hnd_cpu_jumpto(void *addr
)
332 void (*jumpto
)(void) = addr
;
338 BCMINITFN(si_cpu_clock
)(si_t
*sih
)
344 uint32 pll_type
, rate
= 0;
349 if (sih
->cccaps
& CC_CAP_PMU
)
350 return si_pmu_cpu_clock(sih
, osh
);
352 /* get index of the current core */
353 idx
= si_coreidx(sih
);
355 /* switch to chipc core */
356 cc
= (chipcregs_t
*)si_setcoreidx(sih
, SI_CC_IDX
);
359 pll_type
= sih
->cccaps
& CC_CAP_PLL_MASK
;
360 n
= R_REG(osh
, &cc
->clockcontrol_n
);
361 if ((pll_type
== PLL_TYPE2
) ||
362 (pll_type
== PLL_TYPE4
) ||
363 (pll_type
== PLL_TYPE6
) ||
364 (pll_type
== PLL_TYPE7
))
365 m
= R_REG(osh
, &cc
->clockcontrol_m3
);
366 else if (pll_type
== PLL_TYPE5
) {
369 } else if (pll_type
== PLL_TYPE3
) {
370 if (CHIPID(sih
->chip
) == BCM5365_CHIP_ID
) {
374 /* 5350 uses m2 to control mips */
376 m
= R_REG(osh
, &cc
->clockcontrol_m2
);
378 m
= R_REG(osh
, &cc
->clockcontrol_sb
);
381 rate
= si_clock_rate(pll_type
, n
, m
);
383 if (pll_type
== PLL_TYPE6
)
384 rate
= SB2MIPS_T6(rate
);
387 /* switch back to previous core */
388 si_setcoreidx(sih
, idx
);
394 BCMINITFN(si_mem_clock
)(si_t
*sih
)
400 if (sih
->cccaps
& CC_CAP_PMU
)
401 return si_pmu_mem_clock(sih
, osh
);
403 return si_clock(sih
);
406 #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
408 static void __attribute__ ((__noinline__
))
409 ephy_poll_phyaccess(void)
411 asm("phypoll: \tlui $8, 0xb800\n\t"
412 "lw $9, 0x2180($8)\n\t"
415 "bnez $9, phypoll\n\t"
419 static void __attribute__ ((__noinline__
))
422 /* for (i = 0; i < 3000000; i++); */
423 asm("lui $8, 0x2d\n\t"
424 "ori $8,$8,0xc6c0\n\t"
425 "coma_delay_loop: \taddiu $8,$8,-1\n\t"
426 "bnez $8,coma_delay_loop\n\t"
430 static void __attribute__ ((__noinline__
))
431 do_router_coma(si_t
*sih
, void *dmem
, int delay
)
435 /* set jtag user reg 0 = 0x80 to set DDR pad power saving mode */
436 asm("lui $8, 0xb800");
437 asm("li $9, 0xff03ff3a"); /* (16 + addr) << 20 | 0xfe03ff3a */
438 asm("sw $9, 0x0034($8)");
439 asm("li $9, 0x80"); /* data */
440 asm("sw $9, 0x0038($8)");
441 asm("li $9, 0x80071f1f");
442 asm("sw $9, 0x0030($8)");
447 /* ephy ports powerdown */
449 /* robo_wreg 0x0 0xf 0x1f 0x2 */
450 asm("lui $8, 0xb800");
451 asm("li $9, 0x0090001e");
452 asm("sw $9, 0x2188($8)");
455 asm("lui $8, 0xb800");
456 asm("li $9, 0x701e0001");
457 asm("sw $9, 0x2180($8)");
461 ephy_poll_phyaccess();
463 asm("lui $8, 0xb800");
464 asm("li $9, 0x0090001e");
465 asm("sw $9, 0x2188($8)");
468 asm("lui $8, 0xb800");
469 asm("li $9, 0x781e001f");
470 asm("sw $9, 0x2180($8)");
474 ephy_poll_phyaccess();
476 asm("lui $8, 0xb800");
477 asm("li $9, 0x0090001e");
478 asm("sw $9, 0x2188($8)");
481 asm("lui $8, 0xb800");
482 asm("li $9, 0x711e0f01");
483 asm("sw $9, 0x2180($8)");
487 ephy_poll_phyaccess();
489 asm("lui $8, 0xb800");
490 asm("li $9, 0x0090001e");
491 asm("sw $9, 0x2188($8)");
494 asm("lui $8, 0xb800");
495 asm("li $9, 0x511e0000");
496 asm("sw $9, 0x2180($8)");
500 ephy_poll_phyaccess();
502 /* ports 0-5 writes start */
506 for (phy
= 0; phy
< 5; phy
++) {
508 asm("sll $11, $10, 16");
510 asm("li $9, 0x00900000");
511 asm("or $9, $9, $10");
512 asm("lui $8, 0xb800");
513 asm("sw $9, 0x2188($8)");
516 asm("li $9, 0x7f00008b");
517 asm("or $9, $9, $11");
518 asm("lui $8, 0xb800");
519 asm("sw $9, 0x2180($8)");
523 ephy_poll_phyaccess();
525 asm("li $9, 0x00900000");
526 asm("or $9, $9, $10");
527 asm("lui $8, 0xb800");
528 asm("sw $9, 0x2188($8)");
531 asm("li $9, 0x74006000");
532 asm("or $9, $9, $11");
533 asm("lui $8, 0xb800");
534 asm("sw $9, 0x2180($8)");
538 ephy_poll_phyaccess();
540 asm("li $9, 0x00900000");
541 asm("or $9, $9, $10");
542 asm("lui $8, 0xb800");
543 asm("sw $9, 0x2188($8)");
546 asm("li $9, 0x70000700");
547 asm("or $9, $9, $11");
548 asm("lui $8, 0xb800");
549 asm("sw $9, 0x2180($8)");
553 ephy_poll_phyaccess();
555 asm("li $9, 0x00900000");
556 asm("or $9, $9, $10");
557 asm("lui $8, 0xb800");
558 asm("sw $9, 0x2188($8)");
561 asm("li $9, 0x71001000");
562 asm("or $9, $9, $11");
563 asm("lui $8, 0xb800");
564 asm("sw $9, 0x2180($8)");
568 ephy_poll_phyaccess();
570 asm("li $9, 0x00900000");
571 asm("or $9, $9, $10");
572 asm("lui $8, 0xb800");
573 asm("sw $9, 0x2188($8)");
576 asm("li $9, 0x7f00000b");
577 asm("or $9, $9, $11");
578 asm("lui $8, 0xb800");
579 asm("sw $9, 0x2180($8)");
583 ephy_poll_phyaccess();
585 asm("addi $10, $10, 1");
589 /* ports 0-5 writes end */
591 if (((CHIPID(sih
->chip
)) == BCM53572_CHIP_ID
)) {
592 /* set ephy pll and bias power save through chipc registers */
593 asm("lui $8, 0xb800");
595 asm("sw $9, 0x0650($8)");
596 asm("li $9, 0x8a60e001");
597 asm("sw $9, 0x0654($8)");
603 asm("lui $8, 0xb800");
605 asm("sw $9, 0x0650($8)");
606 asm("li $9, 0xcad0000f");
607 asm("sw $9, 0x0654($8)");
613 /* Clear the dmems ddrctrl reg */
614 asm("lui $8, 0xb800");
616 asm("sw $9, 0x41e4($8)");
624 if (sih
->chiprev
== 0) {
626 /* set jtag user reg 3 = 0x60000 to turn off ephy pll and bias power */
627 asm("lui $8, 0xb800");
628 asm("li $9, 0xff33ff3a"); /* (16 + addr) << 20 | 0xfe03ff3a */
629 asm("sw $9, 0x0034($8)");
630 asm("li $9, 0x60000"); /* data */
631 asm("sw $9, 0x0038($8)");
632 asm("li $9, 0x80071f1f");
633 asm("sw $9, 0x0030($8)");
639 /* set ephy pll and bias power power save through chipc registers */
640 asm("lui $8, 0xb800");
642 asm("sw $9, 0x0650($8)");
643 asm("li $9, 0x8a60e001");
644 asm("sw $9, 0x0654($8)");
650 asm("lui $8, 0xb800");
652 asm("sw $9, 0x0650($8)");
653 asm("li $9, 0xcad0000f");
654 asm("sw $9, 0x0654($8)");
662 /* set jtag user reg 7 = 0xc0 to turn off the pll and bias power of ephy */
663 asm("lui $8, 0xb800");
664 asm("li $9, 0xff73ff3a");
665 asm("sw $9, 0x0034($8)");
666 asm("li $9, 0xc0"); /* data */
667 asm("sw $9, 0x0038($8)");
668 asm("li $9, 0x80071f1f");
669 asm("sw $9, 0x0030($8)");
674 /* set gmac dmp io control = 0 */
675 asm("lui $8, 0xb810");
677 asm("sw $9, 0x2408($8)");
683 if (((CHIPID(sih
->chip
)) == BCM53572_CHIP_ID
)) {
684 /* set ddr dmp io control = 0 */
685 asm("lui $8, 0xb810");
687 asm("sw $9, 0x4408($8)");
690 /* put dmems in reset */
692 asm("sw $9, 0x4800($8)");
696 /* set ddr dmp io control = 0 */
697 asm("lui $8, 0xb810");
699 asm("sw $9, 0x5408($8)");
702 /* put dmemc in reset */
704 asm("sw $9, 0x5800($8)");
711 /* set PMU control = 1 */
712 asm("lui $8, 0xb800");
714 asm("sw $9, 0x0600($8)");
720 if (((CHIPID(sih
->chip
)) != BCM53572_CHIP_ID
)) {
721 /* Set switching freq of internal 12V regulator to 600kHz */
722 asm("lui $8, 0xb800");
724 asm("sw $9, 0x0658($8)");
727 asm("lui $8, 0xb800");
728 asm("li $9, 0x00018000");
729 asm("sw $9, 0x065c($8)");
736 /* set mips dmp io control = 0 */
737 asm("lui $8, 0xb810");
739 asm("sw $9, 0x3408($8)");
743 /* wait for watch dog timer done */
754 static void __attribute__ ((__noinline__
))
755 BCMINITFN(aftercoma
)(void)
761 si_router_coma(si_t
*sih
, int reset
, int delay
)
765 uint ic_size
, ic_lsize
;
774 /* Disable interrupts */
776 c0reg
= MFC0(C0_STATUS
, 0);
777 tmp
= (c0reg
& ~(ALLINTS
| ST0_IE
));
778 MTC0(C0_STATUS
, 0, tmp
);
780 icache_probe(MFC0(C0_CONFIG
, 1), &ic_size
, &ic_lsize
);
782 /* Put coma routine into the icache */
783 start
= (ulong
)&ephy_poll_phyaccess
;
784 end
= (ulong
)&aftercoma
;
785 for (i
= 0; i
< (end
- start
); i
+= ic_lsize
)
786 cache_op(start
+ i
, Fill_I
);
788 /* Prepare JTAG registers */
789 si_setcore(sih
, CC_CORE_ID
, 0);
790 cc
= (chipcregs_t
*)si_setcoreidx(sih
, SI_CC_IDX
);
792 W_REG(osh
, &cc
->jtagctrl
, 0x01);
793 W_REG(osh
, &cc
->jtagcmd
, 0x80030000);
794 W_REG(osh
, &cc
->gpioouten
, 0x0);
797 W_REG(osh
, &cc
->gpioouten
, 0x0);
798 W_REG(osh
, &cc
->chipcontrol_addr
, 0x2);
799 W_REG(osh
, &cc
->chipcontrol_data
, 0x04000600);
801 /* Set the watchdog */
802 if (((CHIPID(sih
->chip
)) == BCM5357_CHIP_ID
) && (sih
->chiprev
== 0)) {
803 W_REG(osh
, &cc
->watchdog
, reset
*ILP_CLOCK
);
805 si_watchdog_ms(sih
, reset
*1000);
808 if (((CHIPID(sih
->chip
)) == BCM53572_CHIP_ID
))
809 dmem
= (void *)si_setcore(sih
, DMEMS_CORE_ID
, 0);
811 dmem
= (void *)si_setcore(sih
, DMEMC_CORE_ID
, 0);
813 do_router_coma(sih
, dmem
, delay
);
816 #define PLL_ENTRIES_4706 1
818 BCMINITFN(mips_pmu_setclock_4706
)(si_t
*sih
, uint32 mipsclock
,
819 uint32 ddrclock
, uint32 axiclock
)
821 chipcregs_t
*cc
= NULL
;
824 bool ret
= TRUE
, boolChanged
= FALSE
;
825 /* 25MHz table for 4706 */
826 static uint32
BCMINITDATA(pll25mhz_table
)[][3 + PLL_ENTRIES_4706
] = {
827 /* cpu, ddr, axi, proc_PLL, */
828 { 200, 100, 50, 0xc0011080, },
829 { 300, 150, 75, 0xc00110c0, },
830 { 400, 200, 100, 0xc0011100, },
831 { 500, 250, 125, 0xc0011140, },
832 { 600, 300, 150, 0xc0011180, },
833 { 632, 316, 158, 0xc00157e8, },
834 { 650, 325, 162, 0xc00111a0, },
835 { 662, 331, 165, 0xc00111a8, },
838 static uint32
BCMINITDATA(pll25mhz_table_4706L
)[][3 + PLL_ENTRIES_4706
] = {
839 /* cpu, ddr, axi, proc_PLL, */
840 { 200, 100, 50, 0xc0011100, },
841 { 300, 150, 75, 0xc0011180, },
842 { 400, 200, 100, 0xc0011200, },
845 uint32 (*pll_table
)[4] = pll25mhz_table
;
847 /* Since we already in 4706 specific routine, we no longer check the chip id
848 * The 4706L PLL m value is default to 4, thus the n value needs to be doubled
849 * And since it supports the max frequency is 400MHz, we replace the pll table
852 if (sih
->chippkg
== BCM4706L_PKG_ID
) {
853 pll_table
= pll25mhz_table_4706L
;
858 /* get index of the current core */
859 idx
= si_coreidx(sih
);
861 /* switch to chipc core */
862 cc
= (chipcregs_t
*)si_setcoreidx(sih
, SI_CC_IDX
);
865 mipsclock
/= 1000000;
869 for (idx
= 0; pll_table
[idx
][0] != 0; idx
++) {
870 if ((mipsclock
<= pll_table
[idx
][0]) &&
871 ((ddrclock
== 0) || (ddrclock
<= pll_table
[idx
][1])) &&
872 ((axiclock
== 0) || (axiclock
<= pll_table
[idx
][2])))
876 if (pll_table
[idx
][0] == 0) {
881 for (i
= 0; i
< PLL_ENTRIES_4706
; i
++) {
882 W_REG(osh
, &cc
->pllcontrol_addr
, PMU6_4706_PROCPLL_OFF
+ i
);
883 (void)R_REG(osh
, &cc
->pllcontrol_addr
);
884 if (R_REG(osh
, &cc
->pllcontrol_data
) != pll_table
[idx
][i
+ 3]) {
885 W_REG(osh
, &cc
->pllcontrol_data
, pll_table
[idx
][i
+ 3]);
890 if (boolChanged
== FALSE
)
893 /* Wait for the last write */
894 (void)R_REG(osh
, &cc
->pllcontrol_data
);
896 /* And now do the pll update */
897 W_REG(osh
, &cc
->pmucontrol
,
898 R_REG(osh
, &cc
->pmucontrol
) | PCTL_PLL_PLLCTL_UPD
);
900 __asm__
__volatile__(
907 si_setcoreidx(sih
, idx
);
912 * Set the MIPS, backplane and DDR clocks as closely as possible in chips
913 * with a PMU. So far that means 4716, 47162, 5357, and 5356 all of which share
914 * the same PLL controls.
917 BCMINITFN(mips_pmu_setclock
)(si_t
*sih
, uint32 mipsclock
, uint32 ddrclock
, uint32 axiclock
)
920 chipcregs_t
*cc
= NULL
;
922 uint mainpll_pll0
= PMU4716_MAINPLL_PLL0
;
924 uint32 (*pll_table
)[8];
926 /* 20MHz table for 4716, 4717, 4718, 47162, 5357 */
927 static uint32
BCMINITDATA(pll20mhz_table
)[][8] = {
928 /* cpu, ddr, axi, pllctl12, pllctl13, pllctl14, pllctl15, pllctl16 */
929 { 66, 66, 66, 0x11100070, 0x00121212, 0x03c00000, 0x20000000, 0x200005c0 },
930 { 75, 75, 75, 0x11100070, 0x00101010, 0x03c00000, 0x20000000, 0x200005c0 },
931 { 80, 80, 80, 0x11100070, 0x000a0a0a, 0x02800000, 0x20000000, 0x200005c0 },
932 { 83, 83, 83, 0x11100070, 0x000c0c0c, 0x03200000, 0x20000000, 0x200005c0 },
933 { 100, 66, 66, 0x11100070, 0x0012120c, 0x03c00000, 0x30000000, 0x200005c0 },
934 { 100, 100, 100, 0x11100070, 0x000c0c0c, 0x03c00000, 0x20000000, 0x200005c0 },
935 { 120, 60, 60, 0x11100070, 0x00101008, 0x03000000, 0x40000000, 0x200005c0 },
936 { 120, 120, 120, 0x11100070, 0x00080808, 0x03000000, 0x20000000, 0x200005c0 },
937 { 125, 83, 83, 0x11100070, 0x000c0c08, 0x03200000, 0x30000000, 0x200005c0 },
938 { 133, 66, 66, 0x11100070, 0x0018180c, 0x05000000, 0x40000000, 0x200005c0 },
939 { 133, 133, 133, 0x11100070, 0x000c0c0c, 0x05000000, 0x20000000, 0x200005c0 },
940 { 148, 148, 74, 0x11100070, 0x00120909, 0x04300000, 0x28000000, 0x200005c0 },
941 { 150, 75, 75, 0x11100070, 0x00101008, 0x03c00000, 0x40000000, 0x200005c0 },
942 { 150, 100, 100, 0x11100070, 0x000c0c08, 0x03c00000, 0x30000000, 0x200005c0 },
943 { 150, 150, 75, 0x11100070, 0x00100808, 0x03c00000, 0x28000000, 0x200005c0 },
944 { 150, 150, 150, 0x11100070, 0x00080808, 0x03c00000, 0x20000000, 0x200005c0 },
945 { 155, 155, 77, 0x11100070, 0x00120909, 0x04600000, 0x28000000, 0x200005c0 },
946 { 155, 155, 155, 0x11100070, 0x00090909, 0x04600000, 0x20000000, 0x200005c0 },
947 { 166, 83, 83, 0x11100070, 0x000c0c06, 0x03200000, 0x40000000, 0x200005c0 },
948 { 166, 166, 83, 0x11100070, 0x000c0606, 0x03200000, 0x28000000, 0x200005c0 },
949 { 166, 166, 166, 0x11100070, 0x00060606, 0x03200000, 0x20000000, 0x200005c0 },
950 { 200, 200, 100, 0x11100070, 0x000c0606, 0x03c00000, 0x28000000, 0x200005c0 },
951 { 223, 148, 74, 0x11100070, 0x00120906, 0x04300000, 0x38000000, 0x200005c0 },
952 { 240, 120, 120, 0x11100070, 0x00080804, 0x03000000, 0x40000000, 0x200005c0 },
953 { 240, 240, 120, 0x11100070, 0x00080404, 0x03000000, 0x28000000, 0x200005c0 },
954 { 250, 166, 83, 0x11100070, 0x000c0604, 0x03200000, 0x38000000, 0x200005c0 },
955 { 250, 166, 166, 0x11100070, 0x00060604, 0x03200000, 0x30000000, 0x200005c0 },
956 { 266, 133, 133, 0x11100070, 0x000c0c06, 0x05000000, 0x40000000, 0x200005c0 },
957 { 266, 266, 133, 0x11100070, 0x000c0606, 0x05000000, 0x28000000, 0x200005c0 },
958 { 300, 100, 100, 0x11100070, 0x000c0c04, 0x03c00000, 0x60000000, 0x200005c0 },
959 { 300, 150, 75, 0x11100070, 0x00100804, 0x03c00000, 0x48000000, 0x200005c0 },
960 { 300, 150, 150, 0x11100070, 0x00080804, 0x03c00000, 0x40000000, 0x200005c0 },
961 { 300, 200, 100, 0x11100070, 0x000c0604, 0x03c00000, 0x38000000, 0x200005c0 },
962 { 320, 160, 80, 0x11100070, 0x00100804, 0x04000000, 0x48000000, 0x200005c0 },
963 { 320, 213, 106, 0x11100070, 0x000c0604, 0x04000000, 0x38000000, 0x200005c0 },
964 { 320, 240, 120, 0x11100070, 0x00080403, 0x03000000, 0x38000000, 0x200005c0 },
965 { 320, 256, 128, 0x11100070, 0x000a0504, 0x04000000, 0x38000000, 0x200005c0 },
966 { 330, 165, 82, 0x11100070, 0x00100804, 0x04200000, 0x48000000, 0x200005c0 },
967 { 330, 165, 165, 0x11100070, 0x00080804, 0x04200000, 0x40000000, 0x200005c0 },
968 { 333, 166, 83, 0x11100070, 0x000c0603, 0x03200000, 0x48000000, 0x200005c0 },
969 { 333, 166, 166, 0x11100070, 0x00060603, 0x03200000, 0x40000000, 0x200005c0 },
970 { 340, 226, 113, 0x11100070, 0x000c0604, 0x04400000, 0x38000000, 0x200005c0 },
971 { 350, 175, 87, 0x11100070, 0x00100804, 0x04600000, 0x48000000, 0x200005c0 },
972 { 353, 176, 88, 0x11100070, 0x000c0603, 0x03500000, 0x48000000, 0x200005c0 },
973 { 360, 240, 120, 0x11100070, 0x000c0604, 0x04800000, 0x38000000, 0x200005c0 },
974 { 370, 185, 92, 0x11100070, 0x00100804, 0x04a00000, 0x48000000, 0x200005c0 },
975 { 370, 246, 123, 0x11100070, 0x000c0604, 0x04a00000, 0x38000000, 0x200005c0 },
976 { 373, 186, 93, 0x11100070, 0x000c0603, 0x03800000, 0x48000000, 0x200005c0 },
977 { 400, 133, 133, 0x11100070, 0x000c0c04, 0x05000000, 0x60000000, 0x200005c0 },
978 { 400, 160, 80, 0x11100070, 0x00140a04, 0x05000000, 0x58000000, 0x200005c0 },
979 { 400, 160, 160, 0x11100070, 0x000a0a04, 0x05000000, 0x50000000, 0x200005c0 },
980 { 400, 200, 100, 0x11100070, 0x00100804, 0x05000000, 0x48000000, 0x200005c0 },
981 { 400, 266, 133, 0x11100070, 0x000c0604, 0x05000000, 0x38000000, 0x200005c0 },
982 { 426, 213, 106, 0x11100070, 0x000c0603, 0x04000000, 0x48000000, 0x200005c0 },
983 { 440, 220, 110, 0x11100070, 0x000c0603, 0x04200000, 0x48000000, 0x200005c0 },
984 { 446, 148, 74, 0x11100070, 0x00120903, 0x04300000, 0x68000000, 0x200005c0 },
985 { 453, 226, 113, 0x11100070, 0x000c0603, 0x04400000, 0x48000000, 0x200005c0 },
986 { 466, 233, 116, 0x11100070, 0x000c0603, 0x04600000, 0x48000000, 0x200005c0 },
987 { 480, 137, 68, 0x11100070, 0x000e0702, 0x03000000, 0x78000000, 0x200005c0 },
988 { 480, 137, 137, 0x11100070, 0x00070702, 0x03000000, 0x70000000, 0x200005c0 },
989 { 480, 160, 80, 0x11100070, 0x000c0602, 0x03000000, 0x68000000, 0x200005c0 },
990 { 480, 240, 120, 0x11100070, 0x00080402, 0x03000000, 0x48000000, 0x200005c0 },
991 { 500, 100, 100, 0x11100070, 0x000a0a02, 0x03200000, 0xa0000000, 0x200005c0 },
992 { 500, 166, 83, 0x11100070, 0x000c0602, 0x03200000, 0x68000000, 0x200005c0 },
993 { 500, 166, 166, 0x11100070, 0x00060602, 0x03200000, 0x60000000, 0x200005c0 },
994 { 500, 200, 100, 0x11100070, 0x000a0502, 0x03200000, 0x58000000, 0x200005c0 },
995 { 500, 250, 125, 0x11100070, 0x00080402, 0x03200000, 0x48000000, 0x200005c0 },
996 { 530, 176, 88, 0x11100070, 0x000c0602, 0x03500000, 0x68000000, 0x200005c0 },
997 { 530, 176, 176, 0x11100070, 0x00060602, 0x03500000, 0x60000000, 0x200005c0 },
998 { 530, 212, 106, 0x11100070, 0x000a0502, 0x03500000, 0x58000000, 0x200005c0 },
999 { 530, 265, 132, 0x11100070, 0x00080402, 0x03500000, 0x48000000, 0x200005c0 },
1000 { 533, 133, 133, 0x11100070, 0x000c0c03, 0x05000000, 0x80000000, 0x200005c0 },
1001 { 533, 266, 133, 0x11100070, 0x000c0603, 0x05000000, 0x48000000, 0x200005c0 },
1005 /* 25MHz table for 5356 */
1006 static uint32
BCMINITDATA(pll25mhz_table
)[][8] = {
1007 /* cpu, ddr, axi, pllctl12, pllctl13, pllctl14, pllctl15, pllctl16 */
1008 { 66, 66, 66, 0x11100070, 0x00121212, 0x03000000, 0x20000000, 0x200005c0 },
1009 { 75, 75, 75, 0x11100070, 0x00101010, 0x03000000, 0x20000000, 0x200005c0 },
1010 { 80, 80, 80, 0x11100070, 0x000a0a0a, 0x02000000, 0x20000000, 0x200005c0 },
1011 { 83, 83, 83, 0x11100070, 0x000c0c0c, 0x02800000, 0x20000000, 0x200005c0 },
1012 { 100, 66, 66, 0x11100070, 0x0012120c, 0x03000000, 0x30000000, 0x200005c0 },
1013 { 100, 100, 100, 0x11100070, 0x000c0c0c, 0x03000000, 0x20000000, 0x200005c0 },
1014 { 125, 83, 83, 0x11100070, 0x000c0c08, 0x02800000, 0x30000000, 0x200005c0 },
1015 { 133, 133, 133, 0x11100070, 0x000c0c0c, 0x04000000, 0x20000000, 0x200005c0 },
1016 { 150, 75, 75, 0x11100070, 0x00101008, 0x03000000, 0x40000000, 0x200005c0 },
1017 { 150, 100, 100, 0x11100070, 0x000c0c08, 0x03000000, 0x30000000, 0x200005c0 },
1018 { 150, 150, 75, 0x11100070, 0x00100808, 0x03000000, 0x28000000, 0x200005c0 },
1019 { 150, 150, 150, 0x11100070, 0x00080808, 0x03000000, 0x20000000, 0x200005c0 },
1020 { 166, 83, 83, 0x11100070, 0x000c0c06, 0x02800000, 0x40000000, 0x200005c0 },
1021 { 166, 166, 83, 0x11100070, 0x000c0606, 0x02800000, 0x28000000, 0x200005c0 },
1022 { 166, 166, 166, 0x11100070, 0x00060606, 0x02800000, 0x20000000, 0x200005c0 },
1023 { 200, 133, 133, 0x11100070, 0x000c0c08, 0x04000000, 0x30000000, 0x200005c0 },
1024 { 200, 200, 100, 0x11100070, 0x000c0606, 0x03000000, 0x28000000, 0x200005c0 },
1025 { 250, 166, 83, 0x11100070, 0x000c0604, 0x02800000, 0x38000000, 0x200005c0 },
1026 { 250, 166, 166, 0x11100070, 0x00060604, 0x02800000, 0x30000000, 0x200005c0 },
1027 { 293, 195, 97, 0x11100070, 0x000c0604, 0x02f00000, 0x38000000, 0x200005c0 },
1028 { 300, 100, 100, 0x11100070, 0x000c0c04, 0x03000000, 0x60000000, 0x200005c0 },
1029 { 300, 120, 120, 0x11100070, 0x000a0a04, 0x03000000, 0x50000000, 0x200005c0 },
1030 { 300, 150, 75, 0x11100070, 0x00100804, 0x03000000, 0x48000000, 0x200005c0 },
1031 { 300, 150, 150, 0x11100070, 0x00080804, 0x03000000, 0x40000000, 0x200005c0 },
1032 { 300, 200, 100, 0x11100070, 0x000c0604, 0x03000000, 0x38000000, 0x200005c0 },
1033 { 332, 110, 110, 0x11100070, 0x000c0c04, 0x03540000, 0x6047ae14, 0x202c2820 },
1034 { 332, 133, 133, 0x11100070, 0x000a0a04, 0x03540000, 0x5047ae14, 0x202c2820 },
1035 { 332, 166, 83, 0x11100070, 0x00100804, 0x03540000, 0x4847ae14, 0x202c2820 },
1036 { 333, 111, 111, 0x11100070, 0x00090903, 0x02800000, 0x60000000, 0x200005c0 },
1037 { 333, 133, 133, 0x11100070, 0x000f0f06, 0x05000000, 0x50000000, 0x38000700 },
1038 { 333, 166, 83, 0x11100070, 0x000c0603, 0x02800000, 0x48000000, 0x200005c0 },
1039 { 333, 166, 166, 0x11100070, 0x00060603, 0x02800000, 0x40000000, 0x200005c0 },
1040 { 400, 133, 133, 0x11100070, 0x000c0c04, 0x04000000, 0x60000000, 0x200005c0 },
1041 { 400, 200, 100, 0x11100070, 0x000c0603, 0x03000000, 0x48000000, 0x200005c0 },
1042 { 400, 266, 133, 0x11100070, 0x000c0604, 0x04000000, 0x38000000, 0x200005c0 },
1043 { 500, 166, 83, 0x11100070, 0x000c0602, 0x02800000, 0x68000000, 0x200005c0 },
1044 { 500, 166, 166, 0x11100070, 0x00060602, 0x02800000, 0x60000000, 0x200005c0 },
1045 { 500, 200, 100, 0x11100070, 0x000a0502, 0x02800000, 0x58000000, 0x200005c0 },
1046 { 500, 250, 125, 0x11100070, 0x00080402, 0x02800000, 0x48000000, 0x200005c0 },
1050 if (CHIPID(sih
->chip
) == BCM4706_CHIP_ID
)
1051 return mips_pmu_setclock_4706(sih
, mipsclock
, ddrclock
, axiclock
);
1053 /* By default use the 20MHz pll table */
1054 pll_table
= pll20mhz_table
;
1058 /* Adjust the mainpll_pll0 address and pll table for 5356 */
1059 if (CHIPID(sih
->chip
) == BCM5356_CHIP_ID
) {
1060 mainpll_pll0
= PMU5356_MAINPLL_PLL0
;
1061 pll_table
= pll25mhz_table
;
1063 /* Adjust the mainpll_pll0 address and pll table for 5357 */
1064 if ((CHIPID(sih
->chip
) == BCM5357_CHIP_ID
) ||
1065 (CHIPID(sih
->chip
) == BCM4749_CHIP_ID
)) {
1066 mainpll_pll0
= PMU5357_MAINPLL_PLL0
;
1067 pll_table
= pll20mhz_table
;
1070 /* get index of the current core */
1071 idx
= si_coreidx(sih
);
1073 /* switch to chipc core */
1074 cc
= (chipcregs_t
*)si_setcoreidx(sih
, SI_CC_IDX
);
1077 mipsclock
/= 1000000;
1078 ddrclock
/= 1000000;
1079 axiclock
/= 1000000;
1081 HNDMIPS_NONE(("Looking for %d/%d/%d\n", mipsclock
, ddrclock
, axiclock
));
1083 for (idx
= 0; pll_table
[idx
][0] != 0; idx
++) {
1085 /* Bypass pll entries that are not allowed */
1086 if ((((pll_table
[idx
][4] & 0xff) < 4) ||
1087 (((pll_table
[idx
][5] >> 20) & 0x1ff) > 0x50)) &&
1088 ((CHIPID(sih
->chip
) == BCM5357_CHIP_ID
) ||
1089 (CHIPID(sih
->chip
) == BCM4749_CHIP_ID
)) &&
1090 (((chippkg
= R_REG(osh
, &cc
->sromotp
[23])) & 0x80) == 0x80)) {
1093 if ((mipsclock
<= pll_table
[idx
][0]) &&
1094 ((ddrclock
== 0) || (ddrclock
<= pll_table
[idx
][1])) &&
1095 ((axiclock
== 0) || (axiclock
<= pll_table
[idx
][2])))
1099 if (pll_table
[idx
][0] == 0) {
1104 HNDMIPS_NONE(("Using entry %d: %d/%d/%d, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %d\n", idx
,
1105 pll_table
[idx
][0], pll_table
[idx
][1], pll_table
[idx
][2],
1106 pll_table
[idx
][3], pll_table
[idx
][4], pll_table
[idx
][5],
1107 pll_table
[idx
][6], pll_table
[idx
][7]));
1109 for (i
= PMU5_PLL_P1P2_OFF
; i
<= PMU5_PLL_FMAB_OFF
; i
++) {
1110 W_REG(osh
, &cc
->pllcontrol_addr
, mainpll_pll0
+ i
);
1111 (void)R_REG(osh
, &cc
->pllcontrol_addr
);
1112 if (R_REG(osh
, &cc
->pllcontrol_data
) != pll_table
[idx
][i
+ 3])
1116 /* All matched, no change needed */
1117 if (i
== (PMU5_PLL_FMAB_OFF
+ 1))
1120 /* Write new PLL settings */
1121 for (i
= PMU5_PLL_P1P2_OFF
; i
<= PMU5_PLL_PLLCTL_OFF
; i
++) {
1124 W_REG(osh
, &cc
->pllcontrol_addr
, mainpll_pll0
+ i
);
1125 (void)R_REG(osh
, &cc
->pllcontrol_addr
);
1126 tmp
= pll_table
[idx
][i
+ 3];
1127 W_REG(osh
, &cc
->pllcontrol_data
, tmp
);
1129 /* Wait for the last write */
1130 (void)R_REG(osh
, &cc
->pllcontrol_data
);
1132 if (CHIPID(sih
->chip
) == BCM47162_CHIP_ID
) {
1133 /* In 47162, clear min_res_mask */
1134 W_REG(osh
, &cc
->min_res_mask
,
1135 R_REG(osh
, &cc
->min_res_mask
) & ~RES4716_PROC_HT_AVAIL
);
1137 /* Reset, use chipcommon's watchdog, not the PMU */
1138 W_REG(osh
, &cc
->watchdog
, 1000);
1140 /* And now do the pll update */
1141 W_REG(osh
, &cc
->pmucontrol
,
1142 R_REG(osh
, &cc
->pmucontrol
) | PCTL_PLL_PLLCTL_UPD
);
1144 si_watchdog(sih
, 100);
1146 /* wait for timer interrupt */
1148 __asm__
__volatile__(
1155 /* switch back to previous core */
1156 si_setcoreidx(sih
, idx
);
1162 BCMINITFN(handler
)(void)
1168 /* Disable interrupts */
1169 /* MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */
1171 /* Just a Hack to not to use reg 'at' which was causing problems on 4704 A2 */
1172 "li $14, -31746\n\t"
1173 "and $15, $15, $14\n\t"
1181 /* The following MUST come right after handler() */
1183 BCMINITFN(afterhandler
)(void)
1188 * Set the MIPS, backplane and PCI clocks as closely as possible.
1190 * MIPS clocks synchronization function has been moved from PLL in chipcommon
1191 * core rev. 15 to a DLL inside the MIPS core in 4785.
1194 BCMINITFN(si_mips_setclock
)(si_t
*sih
, uint32 mipsclock
, uint32 siclock
, uint32 pciclock
)
1197 chipcregs_t
*cc
= NULL
;
1198 mips33regs_t
*mipsr
= NULL
;
1199 volatile uint32
*clockcontrol_n
, *clockcontrol_sb
, *clockcontrol_pci
, *clockcontrol_m2
;
1200 uint32 orig_n
, orig_sb
, orig_pci
, orig_m2
, orig_mips
, orig_ratio_parm
, orig_ratio_cfg
;
1201 uint32 pll_type
, sync_mode
;
1202 uint ic_size
, ic_lsize
;
1205 /* PLL configuration: type 3 */
1209 uint32 m2
; /* that is the clockcontrol_m2 */
1211 static type3_table_t type3_table
[] = {
1212 /* for 5350, mips clock is always double sb clock */
1213 { 150000000, 0x311, 0x4020005 },
1214 { 200000000, 0x311, 0x4020003 },
1217 /* PLL configuration: type 2, 4, 7 */
1232 static n4m_table_t
BCMINITDATA(type2_table
)[] = {
1233 { 120000000, 60000000, 32000000, 0x0303, 0x01000200, 0x01000600, 0x01000200,
1234 0x05000200, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1235 { 150000000, 75000000, 33333333, 0x0303, 0x01000100, 0x01000600, 0x01000100,
1236 0x05000100, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1237 { 180000000, 80000000, 30000000, 0x0403, 0x01010000, 0x01020300, 0x01020600,
1238 0x05000100, 8, 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
1239 { 180000000, 90000000, 30000000, 0x0403, 0x01000100, 0x01020300, 0x01000100,
1240 0x05000100, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1241 { 200000000, 100000000, 33333333, 0x0303, 0x02010000, 0x02040001, 0x02010000,
1242 0x06000001, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1243 { 211200000, 105600000, 30171428, 0x0902, 0x01000200, 0x01030400, 0x01000200,
1244 0x05000200, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1245 { 220800000, 110400000, 31542857, 0x1500, 0x01000200, 0x01030400, 0x01000200,
1246 0x05000200, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1247 { 230400000, 115200000, 32000000, 0x0604, 0x01000200, 0x01020600, 0x01000200,
1248 0x05000200, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1249 { 234000000, 104000000, 31200000, 0x0b01, 0x01010000, 0x01010700, 0x01020600,
1250 0x05000100, 8, 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
1251 { 240000000, 120000000, 33333333, 0x0803, 0x01000200, 0x01020600, 0x01000200,
1252 0x05000200, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1253 { 252000000, 126000000, 33333333, 0x0504, 0x01000100, 0x01020500, 0x01000100,
1254 0x05000100, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1255 { 264000000, 132000000, 33000000, 0x0903, 0x01000200, 0x01020700, 0x01000200,
1256 0x05000200, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1257 { 270000000, 120000000, 30000000, 0x0703, 0x01010000, 0x01030400, 0x01020600,
1258 0x05000100, 8, 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
1259 { 276000000, 122666666, 31542857, 0x1500, 0x01010000, 0x01030400, 0x01020600,
1260 0x05000100, 8, 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
1261 { 280000000, 140000000, 31111111, 0x0503, 0x01000000, 0x01010600, 0x01000000,
1262 0x05000000, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1263 { 288000000, 128000000, 32914285, 0x0604, 0x01010000, 0x01030400, 0x01020600,
1264 0x05000100, 8, 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
1265 { 288000000, 144000000, 32000000, 0x0404, 0x01000000, 0x01010600, 0x01000000,
1266 0x05000000, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1267 { 300000000, 133333333, 33333333, 0x0803, 0x01010000, 0x01020600, 0x01010100,
1268 0x05000100, 8, 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
1269 { 300000000, 133333333, 37500000, 0x0803, 0x01010000, 0x01020500, 0x01010100,
1270 0x05000100, 8, 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
1271 { 300000000, 133333333, 42857142, 0x0803, 0x01010000, 0x01020400, 0x01010100,
1272 0x05000100, 8, 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
1273 { 300000000, 133333333, 50000000, 0x0803, 0x01010000, 0x01020300, 0x01010100,
1274 0x05000100, 8, 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
1275 { 300000000, 133333333, 60000000, 0x0803, 0x01010000, 0x01020200, 0x01010100,
1276 0x05000100, 8, 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
1277 { 300000000, 150000000, 33333333, 0x0803, 0x01000100, 0x01020600, 0x01010100,
1278 0x05000100, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1279 { 300000000, 150000000, 37500000, 0x0803, 0x01000100, 0x01020500, 0x01010100,
1280 0x05000100, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1281 { 300000000, 150000000, 42857142, 0x0803, 0x01000100, 0x01020400, 0x01010100,
1282 0x05000100, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1283 { 300000000, 150000000, 50000000, 0x0803, 0x01000100, 0x01020300, 0x01010100,
1284 0x05000100, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1285 { 300000000, 150000000, 60000000, 0x0803, 0x01000100, 0x01020200, 0x01010100,
1286 0x05000100, 11, 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
1287 { 330000000, 132000000, 33000000, 0x0903, 0x01000200, 0x00020200, 0x01010100,
1288 0x05000100, 0, 0, 10 /* ratio 4/10 */, 0x02520129 },
1289 { 330000000, 146666666, 33000000, 0x0903, 0x01010000, 0x00020200, 0x01010100,
1290 0x05000100, 0, 0, 9 /* ratio 4/9 */, 0x012a00a9 },
1291 { 330000000, 165000000, 33000000, 0x0903, 0x01000100, 0x00020200, 0x01010100,
1292 0x05000100, 0, 0, 8 /* ratio 4/8 */, 0x00aa0055 },
1293 { 330000000, 165000000, 41250000, 0x0903, 0x01000100, 0x00020100, 0x01010100,
1294 0x05000100, 0, 0, 8 /* ratio 4/8 */, 0x00aa0055 },
1295 { 330000000, 165000000, 55000000, 0x0903, 0x01000100, 0x00020000, 0x01010100,
1296 0x05000100, 0, 0, 8 /* ratio 4/8 */, 0x00aa0055 },
1297 { 360000000, 120000000, 32000000, 0x0a03, 0x01000300, 0x00010201, 0x01010200,
1298 0x05000100, 0, 0, 12 /* ratio 4/12 */, 0x04920492 },
1299 { 360000000, 144000000, 32000000, 0x0a03, 0x01000200, 0x00010201, 0x01010200,
1300 0x05000100, 0, 0, 10 /* ratio 4/10 */, 0x02520129 },
1301 { 360000000, 160000000, 32000000, 0x0a03, 0x01010000, 0x00010201, 0x01010200,
1302 0x05000100, 0, 0, 9 /* ratio 4/9 */, 0x012a00a9 },
1303 { 360000000, 180000000, 32000000, 0x0a03, 0x01000100, 0x00010201, 0x01010200,
1304 0x05000100, 0, 0, 8 /* ratio 4/8 */, 0x00aa0055 },
1305 { 360000000, 180000000, 40000000, 0x0a03, 0x01000100, 0x00010101, 0x01010200,
1306 0x05000100, 0, 0, 8 /* ratio 4/8 */, 0x00aa0055 },
1307 { 360000000, 180000000, 53333333, 0x0a03, 0x01000100, 0x00010001, 0x01010200,
1308 0x05000100, 0, 0, 8 /* ratio 4/8 */, 0x00aa0055 },
1309 { 390000000, 130000000, 32500000, 0x0b03, 0x01010100, 0x00020101, 0x01020100,
1310 0x05000100, 0, 0, 12 /* ratio 4/12 */, 0x04920492 },
1311 { 390000000, 156000000, 32500000, 0x0b03, 0x01000200, 0x00020101, 0x01020100,
1312 0x05000100, 0, 0, 10 /* ratio 4/10 */, 0x02520129 },
1313 { 390000000, 173000000, 32500000, 0x0b03, 0x01010000, 0x00020101, 0x01020100,
1314 0x05000100, 0, 0, 9 /* ratio 4/9 */, 0x012a00a9 },
1315 { 390000000, 195000000, 32500000, 0x0b03, 0x01000100, 0x00020101, 0x01020100,
1316 0x05000100, 0, 0, 8 /* ratio 4/8 */, 0x00aa0055 },
1318 static n4m_table_t
BCMINITDATA(type4_table
)[] = {
1319 { 120000000, 60000000, 0, 0x0009, 0x11020009, 0x01030203, 0x11020009, 0x04000009,
1321 { 150000000, 75000000, 0, 0x0009, 0x11050002, 0x01030203, 0x11050002, 0x04000005,
1323 { 192000000, 96000000, 0, 0x0702, 0x04000011, 0x11030011, 0x04000011, 0x04000003,
1325 { 198000000, 99000000, 0, 0x0603, 0x11020005, 0x11030011, 0x11020005, 0x04000005,
1327 { 200000000, 100000000, 0, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003,
1329 { 204000000, 102000000, 0, 0x0c02, 0x11020005, 0x01030303, 0x11020005, 0x04000005,
1331 { 208000000, 104000000, 0, 0x0802, 0x11030002, 0x11090005, 0x11030002, 0x04000003,
1333 { 210000000, 105000000, 0, 0x0209, 0x11020005, 0x01030303, 0x11020005, 0x04000005,
1335 { 216000000, 108000000, 0, 0x0111, 0x11020005, 0x01030303, 0x11020005, 0x04000005,
1337 { 224000000, 112000000, 0, 0x0205, 0x11030002, 0x02002103, 0x11030002, 0x04000003,
1339 { 228000000, 101333333, 0, 0x0e02, 0x11030003, 0x11210005, 0x01030305, 0x04000005,
1341 { 228000000, 114000000, 0, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005,
1343 { 240000000, 102857143, 0, 0x0109, 0x04000021, 0x01050203, 0x11030021, 0x04000003,
1345 { 240000000, 120000000, 0, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003,
1347 { 252000000, 100800000, 0, 0x0203, 0x04000009, 0x11050005, 0x02000209, 0x04000002,
1349 { 252000000, 126000000, 0, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002,
1351 { 264000000, 132000000, 0, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002,
1353 { 272000000, 116571428, 0, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003,
1355 { 280000000, 120000000, 0, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003,
1357 { 288000000, 123428571, 0, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003,
1359 { 300000000, 120000000, 0, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002,
1361 { 300000000, 150000000, 0, 0x0009, 0x04000005, 0x01030203, 0x04000005, 0x04000002,
1364 static n4m_table_t
BCMINITDATA(type7_table
)[] = {
1365 { 183333333, 91666666, 0, 0x0605, 0x04000011, 0x11030011, 0x04000011, 0x04000003,
1367 { 187500000, 93750000, 0, 0x0a03, 0x04000011, 0x11030011, 0x04000011, 0x04000003,
1369 { 196875000, 98437500, 0, 0x1003, 0x11020005, 0x11050011, 0x11020005, 0x04000005,
1371 { 200000000, 100000000, 0, 0x0311, 0x04000011, 0x11030011, 0x04000009, 0x04000003,
1373 { 200000000, 100000000, 0, 0x0311, 0x04020011, 0x11030011, 0x04020011, 0x04020003,
1375 { 206250000, 103125000, 0, 0x1103, 0x11020005, 0x11050011, 0x11020005, 0x04000005,
1377 { 212500000, 106250000, 0, 0x0c05, 0x11020005, 0x01030303, 0x11020005, 0x04000005,
1379 { 215625000, 107812500, 0, 0x1203, 0x11090009, 0x11050005, 0x11020005, 0x04000005,
1381 { 216666666, 108333333, 0, 0x0805, 0x11020003, 0x11030011, 0x11020003, 0x04000003,
1383 { 225000000, 112500000, 0, 0x0d03, 0x11020003, 0x11030011, 0x11020003, 0x04000003,
1385 { 233333333, 116666666, 0, 0x0905, 0x11020003, 0x11030011, 0x11020003, 0x04000003,
1387 { 237500000, 118750000, 0, 0x0e05, 0x11020005, 0x11210005, 0x11020005, 0x04000005,
1389 { 240000000, 120000000, 0, 0x0b11, 0x11020009, 0x11210009, 0x11020009, 0x04000009,
1391 { 250000000, 125000000, 0, 0x0f03, 0x11020003, 0x11210003, 0x11020003, 0x04000003,
1395 ulong start
, end
, dst
;
1398 volatile uint32
*dll_ctrl
= (volatile uint32
*)0xff400008;
1399 volatile uint32
*dll_r1
= (volatile uint32
*)0xff400010;
1400 volatile uint32
*dll_r2
= (volatile uint32
*)0xff400018;
1402 /* 5354 chipcommon pll setting can't be changed.
1403 * The PMU on power up comes up with the default clk frequency
1406 if ((CHIPID(sih
->chip
) == BCM5354_CHIP_ID
) || (CHIPID(sih
->chip
) == BCM53572_CHIP_ID
))
1409 if (sih
->cccaps
& CC_CAP_PMU
)
1410 return mips_pmu_setclock(sih
, mipsclock
, siclock
, pciclock
);
1414 /* get index of the current core */
1415 idx
= si_coreidx(sih
);
1416 clockcontrol_m2
= NULL
;
1418 /* switch to chipc core */
1419 cc
= (chipcregs_t
*)si_setcoreidx(sih
, SI_CC_IDX
);
1422 pll_type
= sih
->cccaps
& CC_CAP_PLL_MASK
;
1423 if (pll_type
== PLL_TYPE6
) {
1424 clockcontrol_n
= NULL
;
1425 clockcontrol_sb
= NULL
;
1426 clockcontrol_pci
= NULL
;
1428 clockcontrol_n
= &cc
->clockcontrol_n
;
1429 clockcontrol_sb
= &cc
->clockcontrol_sb
;
1430 clockcontrol_pci
= &cc
->clockcontrol_pci
;
1431 clockcontrol_m2
= &cc
->clockcontrol_m2
;
1434 if (pll_type
== PLL_TYPE6
) {
1435 /* Silence compilers */
1436 orig_n
= orig_sb
= orig_pci
= 0;
1438 /* Store the current clock register values */
1439 orig_n
= R_REG(osh
, clockcontrol_n
);
1440 orig_sb
= R_REG(osh
, clockcontrol_sb
);
1441 orig_pci
= R_REG(osh
, clockcontrol_pci
);
1444 if (pll_type
== PLL_TYPE3
) {
1446 if (CHIPID(sih
->chip
) != BCM5365_CHIP_ID
) {
1448 * Search for the closest MIPS clock less than or equal to
1449 * a preferred value.
1451 for (i
= 0; i
< ARRAYSIZE(type3_table
); i
++) {
1452 if (type3_table
[i
].mipsclock
> mipsclock
)
1462 ASSERT(type3_table
[i
].mipsclock
<= mipsclock
);
1465 orig_m2
= R_REG(osh
, &cc
->clockcontrol_m2
);
1466 if ((orig_n
== type3_table
[i
].n
) &&
1467 (orig_m2
== type3_table
[i
].m2
)) {
1471 /* Set the PLL controls */
1472 W_REG(osh
, clockcontrol_n
, type3_table
[i
].n
);
1473 W_REG(osh
, clockcontrol_m2
, type3_table
[i
].m2
);
1476 si_watchdog(sih
, 1);
1479 } else if ((pll_type
== PLL_TYPE2
) ||
1480 (pll_type
== PLL_TYPE4
) ||
1481 (pll_type
== PLL_TYPE6
) ||
1482 (pll_type
== PLL_TYPE7
)) {
1483 n4m_table_t
*table
= NULL
, *te
;
1488 orig_mips
= R_REG(osh
, &cc
->clockcontrol_m3
);
1492 uint32 new_mips
= 0;
1495 if (mipsclock
<= SB2MIPS_T6(CC_T6_M1
))
1496 new_mips
= CC_T6_MMASK
;
1498 if (orig_mips
== new_mips
)
1501 W_REG(osh
, &cc
->clockcontrol_m3
, new_mips
);
1505 table
= type2_table
;
1506 tabsz
= ARRAYSIZE(type2_table
);
1509 table
= type4_table
;
1510 tabsz
= ARRAYSIZE(type4_table
);
1513 table
= type7_table
;
1514 tabsz
= ARRAYSIZE(type7_table
);
1517 ASSERT("No table for plltype" == NULL
);
1521 /* Store the current clock register values */
1522 orig_m2
= R_REG(osh
, &cc
->clockcontrol_m2
);
1523 orig_ratio_parm
= 0;
1526 /* Look up current ratio */
1527 for (i
= 0; i
< tabsz
; i
++) {
1528 if ((orig_n
== table
[i
].n
) &&
1529 (orig_sb
== table
[i
].sb
) &&
1530 (orig_pci
== table
[i
].pci33
) &&
1531 (orig_m2
== table
[i
].m2
) &&
1532 (orig_mips
== table
[i
].m3
)) {
1533 orig_ratio_parm
= table
[i
].ratio_parm
;
1534 orig_ratio_cfg
= table
[i
].ratio_cfg
;
1539 /* Search for the closest MIPS clock greater or equal to a preferred value */
1540 for (i
= 0; i
< tabsz
; i
++) {
1541 ASSERT(table
[i
].mipsclock
==
1542 si_clock_rate(pll_type
, table
[i
].n
, table
[i
].m3
));
1543 if ((mipsclock
<= table
[i
].mipsclock
) &&
1544 ((siclock
== 0) || (siclock
<= table
[i
].sbclock
)) &&
1545 ((pciclock
== 0) || (pciclock
<= table
[i
].pciclock
)))
1557 if ((orig_n
== te
->n
) &&
1558 (orig_sb
== te
->sb
) &&
1559 (orig_pci
== te
->pci33
) &&
1560 (orig_m2
== te
->m2
) &&
1561 (orig_mips
== te
->m3
))
1564 /* Set the PLL controls */
1565 W_REG(osh
, clockcontrol_n
, te
->n
);
1566 W_REG(osh
, clockcontrol_sb
, te
->sb
);
1567 W_REG(osh
, clockcontrol_pci
, te
->pci33
);
1568 W_REG(osh
, &cc
->clockcontrol_m2
, te
->m2
);
1569 W_REG(osh
, &cc
->clockcontrol_m3
, te
->m3
);
1571 /* Set the chipcontrol bit to change mipsref to the backplane divider if needed */
1572 if ((pll_type
== PLL_TYPE7
) && (te
->sb
!= te
->m2
) &&
1573 (si_clock_rate(pll_type
, te
->n
, te
->m2
) == 120000000))
1574 W_REG(osh
, &cc
->chipcontrol
,
1575 R_REG(osh
, &cc
->chipcontrol
) | 0x100);
1577 /* No ratio change */
1578 if (CHIPID(sih
->chip
) != BCM4785_CHIP_ID
) {
1579 if (orig_ratio_parm
== te
->ratio_parm
)
1583 /* Preload the code into the cache */
1584 icache_probe(MFC0(C0_CONFIG
, 1), &ic_size
, &ic_lsize
);
1585 if (CHIPID(sih
->chip
) == BCM4785_CHIP_ID
) {
1586 start
= ((ulong
) &&start_fill_4785
) & ~(ic_lsize
- 1);
1587 end
= ((ulong
) &&end_fill_4785
+ (ic_lsize
- 1)) & ~(ic_lsize
- 1);
1590 start
= ((ulong
) &&start_fill
) & ~(ic_lsize
- 1);
1591 end
= ((ulong
) &&end_fill
+ (ic_lsize
- 1)) & ~(ic_lsize
- 1);
1593 while (start
< end
) {
1594 cache_op(start
, Fill_I
);
1598 /* 4785 clock freq change procedures */
1599 if (CHIPID(sih
->chip
) == BCM4785_CHIP_ID
) {
1601 /* Switch to async */
1602 MTC0(C0_BROADCOM
, 4, (1 << 22));
1604 /* Set clock ratio in MIPS */
1605 *dll_r1
= (*dll_r1
& 0xfffffff0) | (te
->dll_r1
- 1);
1606 *dll_r2
= te
->dll_r2
;
1608 /* Enable new settings in MIPS */
1609 *dll_r1
= *dll_r1
| 0xc0000000;
1611 /* Set active cfg */
1612 MTC0(C0_BROADCOM
, 2, MFC0(C0_BROADCOM
, 2) | (1 << 3) | 1);
1614 /* Fake soft reset (clock cfg registers not reset) */
1615 MTC0(C0_BROADCOM
, 5, MFC0(C0_BROADCOM
, 5) | (1 << 2));
1617 /* Clear active cfg */
1618 MTC0(C0_BROADCOM
, 2, MFC0(C0_BROADCOM
, 2) & ~(1 << 3));
1620 /* set watchdog timer */
1621 W_REG(osh
, &cc
->watchdog
, 20);
1622 (void) R_REG(osh
, &cc
->chipid
);
1624 /* wait for timer interrupt */
1625 __asm__
__volatile__(
1633 /* Generic clock freq change procedures */
1635 /* Copy the handler */
1636 start
= (ulong
) &handler
;
1637 end
= (ulong
) &afterhandler
;
1638 dst
= KSEG1ADDR(0x180);
1639 for (i
= 0; i
< (end
- start
); i
+= 4)
1640 *((ulong
*)(dst
+ i
)) = *((ulong
*)(start
+ i
));
1642 /* Preload the handler into the cache one line at a time */
1643 for (i
= 0; i
< (end
- start
); i
+= ic_lsize
)
1644 cache_op(dst
+ i
, Fill_I
);
1647 MTC0(C0_STATUS
, 0, MFC0(C0_STATUS
, 0) & ~ST0_BEV
);
1649 /* Enable interrupts */
1650 MTC0(C0_STATUS
, 0, MFC0(C0_STATUS
, 0) | (ALLINTS
| ST0_IE
));
1652 /* Enable MIPS timer interrupt */
1653 mipsr
= si_setcore(sih
, MIPS33_CORE_ID
, 0);
1655 W_REG(osh
, &mipsr
->intmask
, 1);
1658 /* step 1, set clock ratios */
1659 MTC0(C0_BROADCOM
, 3, te
->ratio_parm
);
1660 MTC0(C0_BROADCOM
, 1, te
->ratio_cfg
);
1662 /* step 2: program timer intr */
1663 W_REG(osh
, &mipsr
->timer
, 100);
1664 (void) R_REG(osh
, &mipsr
->timer
);
1666 /* step 3, switch to async */
1667 sync_mode
= MFC0(C0_BROADCOM
, 4);
1668 MTC0(C0_BROADCOM
, 4, 1 << 22);
1670 /* step 4, set cfg active */
1671 MTC0(C0_BROADCOM
, 2, (1 << 3) | 1);
1674 __asm__
__volatile__(
1679 /* step 7, clear cfg active */
1680 MTC0(C0_BROADCOM
, 2, 0);
1682 /* Additional Step: set back to orig sync mode */
1683 MTC0(C0_BROADCOM
, 4, sync_mode
);
1685 /* step 8, fake soft reset */
1686 MTC0(C0_BROADCOM
, 5, MFC0(C0_BROADCOM
, 5) | (1 << 2));
1689 /* set watchdog timer */
1690 W_REG(osh
, &cc
->watchdog
, 20);
1691 (void) R_REG(osh
, &cc
->chipid
);
1693 /* wait for timer interrupt */
1694 __asm__
__volatile__(
1704 /* Enable 4785 DLL */
1705 if (CHIPID(sih
->chip
) == BCM4785_CHIP_ID
) {
1708 /* set mask to 1e, enable DLL (bit 0) */
1709 *dll_ctrl
|= 0x0041e021;
1711 /* enable aggressive hardware mode */
1712 *dll_ctrl
|= 0x00000080;
1714 /* wait for lock flag to clear */
1715 while ((*dll_ctrl
& 0x2) == 0);
1717 /* clear sticky flags (clear on write 1) */
1721 /* set mask to 5b'10001 */
1722 *dll_ctrl
= (*dll_ctrl
& 0xfffc1fff) | 0x00022000;
1724 /* enable sync mode */
1725 MTC0(C0_BROADCOM
, 4, MFC0(C0_BROADCOM
, 4) & 0xfe3fffff);
1726 (void)MFC0(C0_BROADCOM
, 4);
1729 /* switch back to previous core */
1730 si_setcoreidx(sih
, idx
);
1736 BCMINITFN(enable_pfc
)(uint32 mode
)
1740 uint ic_size
, ic_lsize
;
1742 prid
= MFC0(C0_PRID
, 0);
1746 /* enable prefetch cache if available */
1747 if (MFC0(C0_BROADCOM
, 0) & BRCM_PFC_AVAIL
) {
1748 /* If auto then choose the correct mode for this
1749 * platform, currently we only ever select one mode
1751 if (mode
== PFC_AUTO
)
1754 icache_probe(MFC0(C0_CONFIG
, 1), &ic_size
, &ic_lsize
);
1756 start
= ((ulong
) &&setpfc_start
) & ~(ic_lsize
- 1);
1757 end
= ((ulong
) &&setpfc_end
+ (ic_lsize
- 1)) & ~(ic_lsize
- 1);
1759 /* Preload setpfc code into the cache one line at a time */
1760 while (start
< end
) {
1761 cache_op(start
, Fill_I
);
1765 /* Now set the pfc */
1768 *(volatile uint32
*)PFC_CR1
= 0xffff0000;
1771 *(volatile uint32
*)PFC_CR0
= mode
;
1773 /* Compiler foder */
1778 /* returns the ncdl value to be programmed into sdram_ncdl for calibration */
1780 BCMINITFN(si_memc_get_ncdl
)(si_t
*sih
)
1785 uint32 config
, rd
, wr
, misc
, dqsg
, cd
, sm
, sd
;
1790 idx
= si_coreidx(sih
);
1792 memc
= (sbmemcregs_t
*)si_setcore(sih
, MEMC_CORE_ID
, 0);
1796 rev
= si_corerev(sih
);
1798 config
= R_REG(osh
, &memc
->config
);
1799 wr
= R_REG(osh
, &memc
->wrncdlcor
);
1800 rd
= R_REG(osh
, &memc
->rdncdlcor
);
1801 misc
= R_REG(osh
, &memc
->miscdlyctl
);
1802 dqsg
= R_REG(osh
, &memc
->dqsgatencdl
);
1804 rd
&= MEMC_RDNCDLCOR_RD_MASK
;
1805 wr
&= MEMC_WRNCDLCOR_WR_MASK
;
1806 dqsg
&= MEMC_DQSGATENCDL_G_MASK
;
1808 if (config
& MEMC_CONFIG_DDR
) {
1809 ret
= (wr
<< 16) | (rd
<< 8) | dqsg
;
1814 cd
= (rd
== MEMC_CD_THRESHOLD
) ? rd
: (wr
+ MEMC_CD_THRESHOLD
);
1815 sm
= (misc
& MEMC_MISC_SM_MASK
) >> MEMC_MISC_SM_SHIFT
;
1816 sd
= (misc
& MEMC_MISC_SD_MASK
) >> MEMC_MISC_SD_SHIFT
;
1817 ret
= (sm
<< 16) | (sd
<< 8) | cd
;
1821 /* switch back to previous core */
1822 si_setcoreidx(sih
, idx
);
1828 hnd_cpu_reset(si_t
*sih
)
1830 if (CHIPID(sih
->chip
) == BCM4785_CHIP_ID
)
1831 MTC0(C0_BROADCOM
, 4, (1 << 22));
1832 si_watchdog(sih
, 1);
1833 if (CHIPID(sih
->chip
) == BCM4785_CHIP_ID
) {
1834 __asm__
__volatile__(
1843 #if defined(BCMPERFSTATS)
1845 * CP0 Register 25 supports 4 semi-independent 32bit performance counters.
1846 * $25 select 0, 1, 2, and 3 are the counters. The counters *decrement* (who thought this one up?)
1847 * $25 select 4 and 5 each contain 2-16bit control fields, one for each of the 4 counters
1848 * $25 select 6 is the global perf control register.
1850 /* enable and start instruction counting */
1853 hndmips_perf_cyclecount_enable(void)
1855 MTC0(C0_PERFORMANCE
, 6, 0x80000200); /* global enable perf counters */
1856 MTC0(C0_PERFORMANCE
, 4,
1857 0x8048 | MFC0(C0_PERFORMANCE
, 4)); /* enable cycles counting for counter 0 */
1858 MTC0(C0_PERFORMANCE
, 0, 0); /* zero counter zero */
1862 hndmips_perf_instrcount_enable(void)
1864 MTC0(C0_PERFORMANCE
, 6, 0x80000200); /* global enable perf counters */
1865 MTC0(C0_PERFORMANCE
, 4,
1866 0x8044 | MFC0(C0_PERFORMANCE
, 4)); /* enable instructions counting for counter 0 */
1867 MTC0(C0_PERFORMANCE
, 0, 0); /* zero counter zero */
1870 /* enable and start I$ hit and I$ miss counting */
1872 hndmips_perf_icachecount_enable(void)
1874 MTC0(C0_PERFORMANCE
, 6, 0x80000218); /* enable I$ counting */
1875 MTC0(C0_PERFORMANCE
, 4, 0x80148018); /* count I$ hits in cntr 0 and misses in cntr 1 */
1876 MTC0(C0_PERFORMANCE
, 0, 0); /* zero counter 0 - # I$ hits */
1877 MTC0(C0_PERFORMANCE
, 1, 0); /* zero counter 1 - # I$ misses */
1880 /* enable and start D$ hit and I$ miss counting */
1882 hndmips_perf_dcachecount_enable(void)
1884 MTC0(C0_PERFORMANCE
, 6, 0x80000211); /* enable D$ counting */
1885 MTC0(C0_PERFORMANCE
, 4, 0x80248028); /* count D$ hits in cntr 0 and misses in cntr 1 */
1886 MTC0(C0_PERFORMANCE
, 0, 0); /* zero counter 0 - # D$ hits */
1887 MTC0(C0_PERFORMANCE
, 1, 0); /* zero counter 1 - # D$ misses */
1891 hndmips_perf_icache_miss_enable()
1893 MTC0(C0_PERFORMANCE
, 4,
1894 0x80140000 | MFC0(C0_PERFORMANCE
, 4)); /* enable cache misses counting for counter 1 */
1895 MTC0(C0_PERFORMANCE
, 1, 0); /* zero counter one */
1900 hndmips_perf_icache_hit_enable()
1902 MTC0(C0_PERFORMANCE
, 5, 0x8018 | MFC0(C0_PERFORMANCE
, 5));
1903 /* enable cache hits counting for counter 2 */
1904 MTC0(C0_PERFORMANCE
, 2, 0); /* zero counter 2 */
1908 hndmips_perf_read_instrcount()
1910 return -(long)(MFC0(C0_PERFORMANCE
, 0));
1914 hndmips_perf_read_cache_miss()
1916 return -(long)(MFC0(C0_PERFORMANCE
, 1));
1920 hndmips_perf_read_cache_hit()
1922 return -(long)(MFC0(C0_PERFORMANCE
, 2));