1/*  *********************************************************************
2    *  BCM1280/BCM1480 Board Support Package
3    *
4    *  Board-specific initialization		File: BCM91280E_INIT.S
5    *
6    *  This module contains the assembly-language part of the init
7    *  code for this board support package.  The routine
8    *  "board_earlyinit" lives here.
9    *
10    *  Author:  Mitch Lichtenberg
11    *
12    *********************************************************************
13    *
14    *  Copyright 2000,2001,2002,2003
15    *  Broadcom Corporation. All rights reserved.
16    *
17    *  This software is furnished under license and may be used and
18    *  copied only in accordance with the following terms and
19    *  conditions.  Subject to these conditions, you may download,
20    *  copy, install, use, modify and distribute modified or unmodified
21    *  copies of this software in source and/or binary form.  No title
22    *  or ownership is transferred hereby.
23    *
24    *  1) Any source code used, modified or distributed must reproduce
25    *     and retain this copyright notice and list of conditions
26    *     as they appear in the source file.
27    *
28    *  2) No right is granted to use any trade name, trademark, or
29    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
30    *     name may not be used to endorse or promote products derived
31    *     from this software without the prior written permission of
32    *     Broadcom Corporation.
33    *
34    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
35    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
36    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
37    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
38    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
39    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
40    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
44    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
45    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
46    *     THE POSSIBILITY OF SUCH DAMAGE.
47    ********************************************************************* */
48
49
50#include "sbmips.h"
51#include "bcm1480_regs.h"
52#include "bcm1480_scd.h"
53#include "bcm1480_l2c.h"
54#include "sb1250_genbus.h"
55#include "bcm1480_draminit.h"
56#include "jedec.h"
57#include "bsp_config.h"
58#include "cpu_config.h"
59#include "mipsmacros.h"
60#include "bcm91280e.h"
61
62		.text
63
64
65
66/*  *********************************************************************
67    *  Macros
68    ********************************************************************* */
69
70/*
71#define _SERIAL_PORT_LEDS_
72*/
73
74#ifdef _SERIAL_PORT_LEDS_
75#include "sb1250_uart.h"
76#endif
77
78/*  *********************************************************************
79    *  LED macros
80    ********************************************************************* */
81
82#define SETLEDS1(a,b,c,d)                     \
83	li     a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ;    \
84	JAL_KSEG1(board_setleds)
85#define SETLEDS(a,b,c,d)                     \
86	li     a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ;    \
87	JAL_KSEG1(board_setleds)
88
89
90/*  *********************************************************************
91    *  BOARD_EARLYINIT()
92    *
93    *  Initialize board registers.  This is the earliest
94    *  time the BSP gets control.  This routine cannot assume that
95    *  memory is operational, and therefore all code in this routine
96    *  must run from registers only.  The $ra register must not
97    *  be modified, as it contains the return address.
98    *
99    *  This routine will be called from uncached space, before
100    *  the caches are initialized.  If you want to make
101    *  subroutine calls from here, you must use the JAL_KSEG1 macro.
102    *
103    *  Among other things, this is where the GPIO registers get
104    *  programmed to make on-board LEDs function, or other startup
105    *  that has to be done before anything will work.
106    *
107    *  Input parameters:
108    *  	   nothing
109    *
110    *  Return value:
111    *  	   nothing
112    ********************************************************************* */
113
114LEAF(board_earlyinit)
115
116		move	s0, ra
117
118       #
119       # Configure the GPIOs
120       #
121
122		li	t0,PHYS_TO_K1(A_GPIO_DIRECTION)
123		li	t1,GPIO_OUTPUT_MASK
124		sd	t1,0(t0)
125
126		li	t0,PHYS_TO_K1(A_GPIO_INT_TYPE)
127		li	t1,GPIO_INTERRUPT_MASK
128		sd	t1,0(t0)
129
130#if CFG_L2_RAM  /* Variant for using L2 as memory via TLB for 32 bits */
131       #
132       # Set up the L2 cache to be used as SRAM by setting the
133       # way_disable address (the actual flush will be done by
134       # sb1250_l2cache_init).
135       #
136		li	t0,PHYS_TO_K1(A_BCM1480_L2_MAKE_WAY_ENABLE_LO(0x00))
137		sd	zero,(t0)
138		li	t0,PHYS_TO_K1(A_BCM1480_L2_MAKE_WAY_ENABLE_HI(0x08))
139		sd	zero,(t0)
140
141       # Use the result of a load to stall the pipe here.
142       # Ref sec 5.4.2 (aka page 92, 1250_1125UM100-R).
143       # XXX Probably not necessary for these early, global accesses.
144		ld	t0,(t0)
145		addu	t0,t0,t0
146#endif
147
148       #
149       # Configure the alternate boot ROM
150       #
151
152		li	t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(ALT_BOOTROM_CS))
153
154		li	t1,ALT_BOOTROM_PHYS >> S_IO_ADDRBASE
155		sd	t1,R_IO_EXT_START_ADDR(t0)
156
157		li	t1,ALT_BOOTROM_SIZE-1
158		sd	t1,R_IO_EXT_MULT_SIZE(t0)
159
160		li	t1,ALT_BOOTROM_TIMING0
161		sd	t1,R_IO_EXT_TIME_CFG0(t0)
162
163		li	t1,ALT_BOOTROM_TIMING1
164		sd	t1,R_IO_EXT_TIME_CFG1(t0)
165
166		li	t1,ALT_BOOTROM_CONFIG
167		sd	t1,R_IO_EXT_CFG(t0)
168
169
170       #
171       # Configure the LEDs
172       #
173		li	t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(LEDS_CS))
174		li	t1,LEDS_PHYS >> S_IO_ADDRBASE
175		sd	t1,R_IO_EXT_START_ADDR(t0)
176
177		li	t1,LEDS_SIZE-1	/* Needs to be 1 smaller, se UM for details */
178		sd	t1,R_IO_EXT_MULT_SIZE(t0)
179
180		li	t1,LEDS_TIMING0
181		sd	t1,R_IO_EXT_TIME_CFG0(t0)
182
183		li	t1,LEDS_TIMING1
184		sd	t1,R_IO_EXT_TIME_CFG1(t0)
185
186		li	t1,LEDS_CONFIG
187		sd	t1,R_IO_EXT_CFG(t0)
188
189	#
190	# Make sure that the mailbox registers are cleared
191	#
192
193		li	t0,PHYS_TO_K1(A_BCM1480_IMR_REGISTER(0,R_BCM1480_IMR_MAILBOX_0_CLR_CPU))
194		nor	t1, zero, zero
195		sd	t1,(t0)
196		li	t0,PHYS_TO_K1(A_BCM1480_IMR_REGISTER(0,R_BCM1480_IMR_MAILBOX_1_CLR_CPU))
197		sd	t1,(t0)
198
199#ifdef _SERIAL_PORT_LEDS_
200
201	# Program the mode register for 8 bits/char, no parity
202
203		li	t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A)
204		li	t1,V_DUART_BITS_PER_CHAR_8 | V_DUART_PARITY_MODE_NONE
205		sd	t1,(t0)
206
207	# Program the mode register for 1 stop bit, ignore CTS
208
209		li	t0,PHYS_TO_K1(A_DUART_MODE_REG_2_A)
210		li	t1,M_DUART_STOP_BIT_LEN_1
211		sd	t1,(t0)
212
213	# Program the baud rate to 115200
214
215		li	t0,PHYS_TO_K1(A_DUART_CLK_SEL_A)
216		li	t1,V_DUART_BAUD_RATE(CFG_SERIAL_BAUD_RATE)
217		sd	t1,(t0)
218
219	# Dont use any interrupts
220
221		li	t0,PHYS_TO_K1(A_DUART_IMR)
222		ld	t1,(t0)
223		and	t1,~M_DUART_IMR_ALL_A
224		sd	t1,(t0)
225
226	# Enable sending and receiving
227
228		li	t0,PHYS_TO_K1(A_DUART_CMD_A)
229		li	t1,M_DUART_RX_EN | M_DUART_TX_EN
230		sd	t1,(t0)
231
232#endif
233
234
235       #
236       # If the config switches request that half the cache be
237       # disabled (to model 512kB-cache parts on boards w/ 1MB
238       # caches), disable half of the cache now.
239       #
240
241		SETLEDS1('D','L','2','?')
242
243		JAL_KSEG1(board_get_config)
244
245		and	v0, v0, BOARD_CFG_HALF_L2
246		beqz	v0, 1f			# Disable not requested.  Done.
247
248		SETLEDS1('D','L','2','!')
249
250		la      t0, PHYS_TO_K1(A_BCM1480_L2_MISC0_VALUE)
251		ld      t0, 0(t0)
252
253		and	t0, t0, (M_BCM1480_L2C_MISC0_CACHE_DISABLE \
254				 | M_BCM1480_L2C_MISC0_CACHE_QUAD)
255		bnez	t0, 1f			# Some bits set -> half already
256						# disabled -> Done.
257
258		SETLEDS1('D','L','2','H')
259
260		la	t0, PHYS_TO_K1(A_BCM1480_L2_MAKECACHEDISABLE(1))
261		sd	zero, 0(t0)		# disable half.
262		sync
263
264		# read back a mgmt register just to make sure the write has
265		# completed.
266		la      t0, PHYS_TO_K1(A_BCM1480_L2_MISC0_VALUE)
267		ld      zero, 0(t0)
268		sync
2691:
270		SETLEDS1('D','L','2','D')
271
272
273       #
274       # If the config switches request that only two CPUs remain
275       # enabled (to model 2-CPU parts on boards w/ more than two CPUs),
276       # disable CPUs until only two remain.
277       #
278
279		SETLEDS1('D','C',' ','?')
280
281		JAL_KSEG1(board_get_config)
282
283		and	v0, v0, BOARD_CFG_2CPU
284		beqz	v0, 1f			# Disable not requested.  Done.
285
286		SETLEDS1('D','C',' ','!')
287
288		li	s1, 2
289		la      s2, PHYS_TO_K1(A_SCD_SYSTEM_CFG)
290
291		JAL_KSEG1(bcm1480_num_cpus)
292		ble	v0, s1, 1f		# #cpus <= 2?  Done.
293
294		# disable CPU 3.
295		SETLEDS1('D','C','3','!')
296		ld      t0, 0(s2)
297		or 	t0, M_BCM1480_SYS_DISABLECPU3
298		BCM1480_WRITE_SYSTEM_CFG(s2, t0)
299
300		JAL_KSEG1(bcm1480_num_cpus)
301		ble	v0, s1, 1f		# #cpus <= 2?  Done.
302
303		# disable CPU 2.
304		SETLEDS1('D','C','2','!')
305		ld      t0, 0(s2)
306		or 	t0, M_BCM1480_SYS_DISABLECPU2
307		BCM1480_WRITE_SYSTEM_CFG(s2, t0)
308
309		# If we reach this point, CPUs 2 and 3 have just been
310		# disabled.  Therefore we have two CPUs disabled, and
311		# we're done.
3121:
313		SETLEDS1('D','C',' ','D')
314
315
316		move	ra, s0
317		j	ra
318
319END(board_earlyinit)
320
321
322/*  *********************************************************************
323    *  BOARD_DRAMINFO
324    *
325    *  Return the address of the DRAM information table
326    *
327    *  Input parameters:
328    *  	   nothing
329    *
330    *  Return value:
331    *  	   v0 - DRAM info table, return 0 to use default table
332    ********************************************************************* */
333
334
335#define VPN2_256K(va)  (((va)>>(13+6))<<6)
336#define PFN(pa)        ((pa)>>12)
337#define PGMASK_256K    (0x3F<<13)
338
339LEAF(board_draminfo)
340
341
342#if CFG_L2_RAM  /* Variant for using L2 as memory via TLB for 32 bits */
343	/*
344	 * Map 512K of L2 space to VA 0x300000 using a pair of 256K
345	 * page frames.
346	 * This is an abuse of the function, but it is called at the
347	 * correct point in the initialization sequence, where adding
348	 * new function calls is delicate.
349	 */
350
351		.set	push
352		.set	mips64
353
354		dli	v0,(VPN2_256K(0x00300000)<<13)
355		dmtc0	v0,C0_TLBHI
356		li	v0,(PFN(0xd0300000)<<6 | (5<<3) | 7)
357		mtc0	v0,C0_TLBLO0
358		li	v0,(PFN(0xd0340000)<<6 | (5<<3) | 7)
359		mtc0	v0,C0_TLBLO1
360		li	v0,PGMASK_256K
361		mtc0	v0,C0_PGMASK
362		li	v0,1
363		mtc0	v0,C0_WIRED
364		li	v0,0
365		mtc0	v0,C0_INDEX
366		tlbwi
367
368		HAZARD
369
370		.set	pop
371#endif /* CFG_L2_RAM */
372
373       /*
374        * Return pointer to DRAM table.
375	*/
376
377		la	v0,dramtab
378		j	ra
379
380
381dramtab:
382
383        DRAM_GLOBALS(CFG_DRAM_INTERLEAVE)
384
385        DRAM_CHAN_CFG(MC_CHAN0, DRT10(3,0), DRT10(3,0), MC_32BIT_CHAN, JEDEC_DDR2, CASCHECK, CFG_DRAM_CSINTERLEAVE, CFG_DRAM_ECC, 0)
386        DRAM_CS_GEOM(MC_CS0, 14, 10, 2, 0)
387        DRAM_CS_TIMING(DRT10(3,0), JEDEC_RFSH_128khz, JEDEC_CASLAT_DDR2_5, 0,  45, DRT4(15,0), DRT4(7,5),  DRT4(15,0),  105, 55)
388	DRAM_CS_TIMING2(0,DRT4(7,5),0)
389	DRAM_CHAN_ODTCFG(0x00,0x00,0x00,0x00,CS_ODD_ODT_EN,ODT_75,0)
390	DRAM_CHAN_DLLCFG2(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)
391
392
393        DRAM_CHAN_CFG(MC_CHAN1, DRT10(3,0), DRT10(3,0), MC_32BIT_CHAN, JEDEC_DDR2, CASCHECK, CFG_DRAM_CSINTERLEAVE, CFG_DRAM_ECC, 0)
394        DRAM_CS_GEOM(MC_CS0, 14, 10, 2, 0)
395        DRAM_CS_TIMING(DRT10(3,0), JEDEC_RFSH_128khz, JEDEC_CASLAT_DDR2_5, 0,  45, DRT4(15,0), DRT4(7,5),  DRT4(15,0),  105, 55)
396	DRAM_CS_TIMING2(0,DRT4(7,5),0)
397	DRAM_CHAN_ODTCFG(0x00,0x00,0x00,0x00,CS_ODD_ODT_EN,ODT_75,0)
398	DRAM_CHAN_DLLCFG2(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)
399
400
401        DRAM_CHAN_CFG(MC_CHAN2, DRT10(3,0), DRT10(3,0), MC_32BIT_CHAN, JEDEC_DDR2, CASCHECK, CFG_DRAM_CSINTERLEAVE, CFG_DRAM_ECC, 0)
402        DRAM_CS_GEOM(MC_CS0, 14, 10, 2, 0)
403        DRAM_CS_TIMING(DRT10(3,0), JEDEC_RFSH_128khz, JEDEC_CASLAT_DDR2_5, 0,  45, DRT4(15,0), DRT4(7,5),  DRT4(15,0),  105, 55)
404	DRAM_CS_TIMING2(0,DRT4(7,5),0)
405	DRAM_CHAN_ODTCFG(0x00,0x00,0x00,0x00,CS_ODD_ODT_EN,ODT_75,0)
406	DRAM_CHAN_DLLCFG2(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)
407
408
409	DRAM_CHAN_CFG(MC_CHAN3, DRT10(3,0), DRT10(3,0), MC_32BIT_CHAN, JEDEC_DDR2, CASCHECK, CFG_DRAM_CSINTERLEAVE, CFG_DRAM_ECC, 0)
410        DRAM_CS_GEOM(MC_CS0, 14, 10, 2, 0)
411	DRAM_CS_TIMING(DRT10(3,0), JEDEC_RFSH_128khz, JEDEC_CASLAT_DDR2_5, 0,  45, DRT4(15,0), DRT4(7,5),  DRT4(15,0),  105, 55)
412	DRAM_CS_TIMING2(0,DRT4(7,5),0)
413	DRAM_CHAN_ODTCFG(0x00,0x00,0x00,0x00,CS_ODD_ODT_EN,ODT_75,0)
414	DRAM_CHAN_DLLCFG2(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)
415
416        DRAM_EOT
417
418END(board_draminfo)
419
420
421/*  *********************************************************************
422    *  BOARD_PIAI2_TXCHAR
423    *
424    *  Transmit a single character via UART A
425    *
426    *  Input parameters:
427    *  	   a0 - character to transmit (low-order 8 bits)
428    *
429    *  Return value:
430    *  	   nothing
431    *
432    *  Registers used:
433    *  	   t0,t1
434    ********************************************************************* */
435
436#ifdef _PROMICE_PORT_LEDS_
437
438LEAF(board_piai2_txchar)
439
440	# Wait until there is space in the transmit buffer
441
442	        li      t0,PHYS_TO_K1(BOARD_PROMICE_BASE)
443
4441:		lb	t1,BOARD_PROMICE_STATUS(t0)
445		andi	t1,TDA
446		bne	t1,zero,1b
447
448	# Okay, now send the character.
449
450		sb	a0,BOARD_PROMICE_ZERO(t0)
451
452	# done!
453
454		j	ra
455
456END(board_piai2_txchar)
457#endif
458
459/*  *********************************************************************
460    *  BOARD_UARTA_TXCHAR
461    *
462    *  Transmit a single character via UART A
463    *
464    *  Input parameters:
465    *  	   a0 - character to transmit (low-order 8 bits)
466    *
467    *  Return value:
468    *  	   nothing
469    *
470    *  Registers used:
471    *  	   t0,t1
472    ********************************************************************* */
473
474#ifdef _SERIAL_PORT_LEDS_
475board_uarta_txchar:
476
477	# Wait until there is space in the transmit buffer
478
4791:		li	t0,PHYS_TO_K1(A_DUART_STATUS_A)
480		ld	t1,(t0)			# Get status bits
481		and	t1,M_DUART_TX_RDY	# test for ready
482		beq	t1,0,1b			# keep going till ready
483
484	# Okay, now send the character.
485
486		li	t0,PHYS_TO_K1(A_DUART_TX_HOLD_A)
487		sd	a0,(t0)
488
489	# done!
490
491		j	ra
492
493
494#endif
495
496/*  *********************************************************************
497    *  BOARD_SETLEDS(x)
498    *
499    *  Set LEDs for boot-time progress indication.  Not used if
500    *  the board does not have progress LEDs.  This routine
501    *  must not call any other routines, since it may be invoked
502    *  either from KSEG0 or KSEG1 and it may be invoked
503    *  whether or not the icache is operational.
504    *
505    *  Input parameters:
506    *  	   a0 - LED value (8 bits per character, 4 characters)
507    *
508    *  Return value:
509    *  	   nothing
510    *
511    *  Registers used:
512    *  	   t0,t1,t2,t3
513    ********************************************************************* */
514
515
516#define LED_CHAR0	(32+8*3)
517#define LED_CHAR1	(32+8*2)
518#define LED_CHAR2	(32+8*1)
519#define LED_CHAR3	(32+8*0)
520
521
522LEAF(board_setleds)
523
524	/*
525	 * Sending to LEDs
526	 */
527
528		li	t0,PHYS_TO_K1(LEDS_PHYS)
529
530		rol	a0,a0,8
531		and	t1,a0,0xFF
532		sb	t1,LED_CHAR0(t0)
533
534		rol	a0,a0,8
535		and	t1,a0,0xFF
536		sb	t1,LED_CHAR1(t0)
537
538		rol	a0,a0,8
539		and	t1,a0,0xFF
540		sb	t1,LED_CHAR2(t0)
541
542		rol	a0,a0,8
543		and	t1,a0,0xFF
544		sb	t1,LED_CHAR3(t0)
545
546
547
548#ifdef _SERIAL_PORT_LEDS_
549		move	t3,ra
550		move	t2,a0
551
552		li	a0,'['
553		bal	board_uarta_txchar
554
555		move	a0,t2
556		rol	a0,8
557		bal	board_uarta_txchar
558		rol	a0,8
559		bal	board_uarta_txchar
560		rol	a0,8
561		bal	board_uarta_txchar
562		rol	a0,8
563		bal	board_uarta_txchar
564
565		li	a0,']'
566		bal	board_uarta_txchar
567		li	a0,13
568		bal	board_uarta_txchar
569		li	a0,10
570		bal	board_uarta_txchar
571
572		move	a0,t2
573		move	ra,t3
574
575#endif
576
577		j	ra
578
579END(board_setleds)
580
581LEAF(board_get_config)
582		.set push
583		.set noreorder
584		.set nomacro
585		lui	t0, %hi(PHYS_TO_K1(A_SCD_SYSTEM_CFG))
586		ld	t0, %lo(PHYS_TO_K1(A_SCD_SYSTEM_CFG))(t0)
587		dsrl	t0, t0, S_BCM1480_SYS_CONFIG
588		li	v0, (M_BCM1480_SYS_CONFIG >> S_BCM1480_SYS_CONFIG)
589		and	v0, v0, t0
590		jr	ra
591		 nop
592		.set pop
593END(board_get_config)
594
595
596
597