1/*  *********************************************************************
2    *  SB1250 Board Support Package
3    *
4    *  Board-specific initialization		File: LAUSANNE_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    *  Lausanne edits:	Jeffrey Cheng
12    *
13    *********************************************************************
14    *
15    *  Copyright 2000,2001,2002,2003
16    *  Broadcom Corporation. All rights reserved.
17    *
18    *  This software is furnished under license and may be used and
19    *  copied only in accordance with the following terms and
20    *  conditions.  Subject to these conditions, you may download,
21    *  copy, install, use, modify and distribute modified or unmodified
22    *  copies of this software in source and/or binary form.  No title
23    *  or ownership is transferred hereby.
24    *
25    *  1) Any source code used, modified or distributed must reproduce
26    *     and retain this copyright notice and list of conditions
27    *     as they appear in the source file.
28    *
29    *  2) No right is granted to use any trade name, trademark, or
30    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
31    *     name may not be used to endorse or promote products derived
32    *     from this software without the prior written permission of
33    *     Broadcom Corporation.
34    *
35    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
36    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
37    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
39    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
40    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
41    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
43    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
46    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
47    *     THE POSSIBILITY OF SUCH DAMAGE.
48    ********************************************************************* */
49
50
51#include "sbmips.h"
52#include "sb1250_genbus.h"
53#include "sb1250_regs.h"
54#include "sb1250_scd.h"
55#include "bsp_config.h"
56#include "cpu_config.h"
57#include "lausanne.h"
58#include "mipsmacros.h"
59#include "sb1250_draminit.h"
60
61		.text
62
63
64/*  *********************************************************************
65    *  Macros
66    ********************************************************************* */
67
68
69/*
70 * Define this to send the LED messages to the serial port instead
71 * of to the LEDs.
72 */
73
74/* #define _SERIAL_PORT_LEDS_ */
75
76#ifdef _SERIAL_PORT_LEDS_
77#include "sb1250_uart.h"		/* need this for serial defs */
78#endif
79
80
81/*  *********************************************************************
82    *  BOARD_EARLYINIT()
83    *
84    *  Initialize board registers.  This is the earliest
85    *  time the BSP gets control.  This routine cannot assume that
86    *  memory is operational, and therefore all code in this routine
87    *  must run from registers only.  The $ra register must not
88    *  be modified, as it contains the return address.
89    *
90    *  This routine will be called from uncached space, before
91    *  the caches are initialized.  If you want to make
92    *  subroutine calls from here, you must use the CALLKSEG1 macro.
93    *
94    *  Among other things, this is where the GPIO registers get
95    *  programmed to make on-board LEDs function, or other startup
96    *  that has to be done before anything will work.
97    *
98    *  Input parameters:
99    *  	   nothing
100    *
101    *  Return value:
102    *  	   nothing
103    ********************************************************************* */
104
105LEAF(board_earlyinit)
106
107	#
108	# Reprogram the SCD to make sure UART0 is enabled.
109	# Some CSWARM boards have the SER0 enable bit when
110	# they're not supposed to, which switches the UART
111	# into synchronous mode.  Kill off the SCD bit.
112	# XXX this should be investigated in hardware, as
113	# XXX it is a strap option on the CPU.
114	#
115
116		li      t0,PHYS_TO_K1(A_SCD_SYSTEM_CFG)
117		ld	t1,0(t0)
118		dli	t2,~M_SYS_SER0_ENABLE
119		and	t1,t1,t2
120		sd	t1,0(t0)
121
122       #
123       # First turn off flash burst mode
124       #
125		li	t0,PHYS_TO_K1(A_GPIO_PIN_CLR)
126		li	t1,_SB_MAKEMASK1(GPIO_FLASH_BYTE_EN)
127		sd	t1,0(t0)
128
129       #
130       # Configure the GPIOs
131       #
132
133		li	t0,PHYS_TO_K1(A_GPIO_DIRECTION)
134		li	t1,GPIO_OUTPUT_MASK
135		sd	t1,0(t0)
136
137		li	t0,PHYS_TO_K1(A_GPIO_INT_TYPE)
138		li	t1,GPIO_INTERRUPT_MASK
139		sd	t1,0(t0)
140
141       #
142       # Configure the LEDs
143       #
144
145		li	t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(LEDS_CS))
146		li	t1,LEDS_PHYS >> S_IO_ADDRBASE
147		sd	t1,R_IO_EXT_START_ADDR(t0)
148
149		li	t1,LEDS_SIZE-1	/* Needs to be 1 smaller, se UM for details */
150		sd	t1,R_IO_EXT_MULT_SIZE(t0)
151
152		li	t1,LEDS_TIMING0
153		sd	t1,R_IO_EXT_TIME_CFG0(t0)
154
155		li	t1,LEDS_TIMING1
156		sd	t1,R_IO_EXT_TIME_CFG1(t0)
157
158		li	t1,LEDS_CONFIG
159		sd	t1,R_IO_EXT_CFG(t0)
160
161
162
163       #
164       # Configure the alternate boot ROM
165       #
166
167		li	t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(ALT_BOOTROM_CS))
168
169		li	t1,ALT_BOOTROM_PHYS >> S_IO_ADDRBASE
170		sd	t1,R_IO_EXT_START_ADDR(t0)
171
172		li	t1,ALT_BOOTROM_SIZE-1
173		sd	t1,R_IO_EXT_MULT_SIZE(t0)
174
175		li	t1,ALT_BOOTROM_TIMING0
176		sd	t1,R_IO_EXT_TIME_CFG0(t0)
177
178		li	t1,ALT_BOOTROM_TIMING1
179		sd	t1,R_IO_EXT_TIME_CFG1(t0)
180
181		li	t1,ALT_BOOTROM_CONFIG
182		sd	t1,R_IO_EXT_CFG(t0)
183
184
185
186       #
187       # Configure the CPLD interface
188       #
189
190		li	t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(CPLD_CS))
191
192		li	t1,CPLD_PHYS >> S_IO_ADDRBASE
193		sd	t1,R_IO_EXT_START_ADDR(t0)
194
195		li	t1,CPLD_SIZE-1
196		sd	t1,R_IO_EXT_MULT_SIZE(t0)
197
198		li	t1,CPLD_TIMING0
199		sd	t1,R_IO_EXT_TIME_CFG0(t0)
200
201		li	t1,CPLD_TIMING1
202		sd	t1,R_IO_EXT_TIME_CFG1(t0)
203
204		li	t1,CPLD_CONFIG
205		sd	t1,R_IO_EXT_CFG(t0)
206
207
208
209#ifdef _SERIAL_PORT_LEDS_
210
211       /*
212        * If sending the LED messages to the serial port, we will need
213	* to initialize the port now.
214	*/
215
216	# Program the mode register for 8 bits/char, no parity
217
218		li	t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A)
219		li	t1,V_DUART_BITS_PER_CHAR_8 | V_DUART_PARITY_MODE_NONE
220		sd	t1,(t0)
221
222	# Program the mode register for 1 stop bit, ignore CTS
223
224		li	t0,PHYS_TO_K1(A_DUART_MODE_REG_2_A)
225		li	t1,M_DUART_STOP_BIT_LEN_1
226		sd	t1,(t0)
227
228	# Program the baud rate to 115200
229
230		li	t0,PHYS_TO_K1(A_DUART_CLK_SEL_A)
231		li	t1,V_DUART_BAUD_RATE(CFG_SERIAL_BAUD_RATE)
232		sd	t1,(t0)
233
234	# Dont use any interrupts
235
236		li	t0,PHYS_TO_K1(A_DUART_IMR)
237		ld	t1,(t0)
238		and	t1,~M_DUART_IMR_ALL_A
239		sd	t1,(t0)
240
241	# Enable sending and receiving
242
243		li	t0,PHYS_TO_K1(A_DUART_CMD_A)
244		li	t1,M_DUART_RX_EN | M_DUART_TX_EN
245		sd	t1,(t0)
246
247#endif
248
249
250		j	ra
251
252END(board_earlyinit)
253
254
255/*  *********************************************************************
256    *  BOARD_DRAMINFO
257    *
258    *  Return the address of the DRAM information table
259    *
260    *  Input parameters:
261    *  	   nothing
262    *
263    *  Return value:
264    *  	   v0 - DRAM info table, return 0 to use default table
265    ********************************************************************* */
266
267
268LEAF(board_draminfo)
269
270		la	v0,myinfo
271		j	ra
272
273myinfo:
274
275
276    /*
277     * Global data: Interleave mode from bsp_config.h
278     */
279
280    DRAM_GLOBALS(CFG_DRAM_INTERLEAVE)	   		/* do port interleaving if possible */
281
282    /*
283     * Memory channel 0: Configure via SMBUS, Automatic Timing, Big Memory mode, Force Register
284     *
285     * There's an external register on the board, so dimms appear to be "registered" even though
286     * the SPD says they're not.
287     *
288     * SPD SMBus Channel 0 Device 0x50	-> MC0 slot 0  \___ goes to real MC0 CS0 via external decode
289     * SPD SMBus Channel 0 Device 0x51	-> MC0 slot 1  /
290     * SPD SMBus Channel 0 Device 0x52	-> MC0 slot 2  \___ goes to real MC0 CS1 via external decode
291     * SPD SMBus Channel 0 Device 0x53	-> MC0 slot 3  /
292     *
293     * DRAM must always be added in pairs!
294     */
295
296    DRAM_CHAN_CFG(MC_CHAN0, CFG_DRAM_MIN_tMEMCLK, JEDEC, CASCHECK, CFG_DRAM_BLOCK_SIZE, NOCSINTLV, CFG_DRAM_ECC, (MCFLG_BIGMEM | MCFLG_FORCEREG))
297    DRAM_CHAN_CLKCFG(0x0F,0x08,0x08,0x00,0x0F,0x00)
298
299    DRAM_CS_SPD(MC_CS0, 0, 0, 0x50)
300    DRAM_CS_SPD(MC_CS1, 0, 0, 0x52)
301
302    /*
303     * Memory channel 1: Configure via SMBUS, Automatic Timing, Big Memory mode, Force Register
304     *
305     * There's an external register on the board, so dimms appear to be "registered" even though
306     * the SPD says they're not.
307     *
308     * SPD SMBus Channel 0 Device 0x54	-> MC1 slot 0  \___ goes to real MC1 CS0 via external decode
309     * SPD SMBus Channel 0 Device 0x55	-> MC1 slot 1  /
310     * SPD SMBus Channel 0 Device 0x56	-> MC1 slot 2  \___ goes to real MC1 CS1 via external decode
311     * SPD SMBus Channel 0 Device 0x57	-> MC1 slot 3  /
312     *
313     * DRAM must always be added in pairs!
314     */
315
316    DRAM_CHAN_CFG(MC_CHAN1, CFG_DRAM_MIN_tMEMCLK, JEDEC, CASCHECK, CFG_DRAM_BLOCK_SIZE, NOCSINTLV, CFG_DRAM_ECC, (MCFLG_BIGMEM | MCFLG_FORCEREG))
317    DRAM_CHAN_CLKCFG(0x0F,0x08,0x08,0x00,0x0F,0x00)
318
319    DRAM_CS_SPD(MC_CS0, 0, 0, 0x54)
320    DRAM_CS_SPD(MC_CS1, 0, 0, 0x56)
321
322   /*
323    * End of Table
324    */
325
326    DRAM_EOT
327
328
329
330END(board_draminfo)
331
332
333/*  *********************************************************************
334    *  BOARD_UARTA_TXCHAR
335    *
336    *  Transmit a single character via UART A
337    *
338    *  Input parameters:
339    *  	   a0 - character to transmit (low-order 8 bits)
340    *
341    *  Return value:
342    *  	   nothing
343    *
344    *  Registers used:
345    *  	   t0,t1
346    ********************************************************************* */
347#ifdef _SERIAL_PORT_LEDS_
348LEAF(board_uarta_txchar)
349
350	# Wait until there is space in the transmit buffer
351
3521:		li	t0,PHYS_TO_K1(A_DUART_STATUS_A)
353		ld	t1,(t0)			# Get status bits
354		and	t1,M_DUART_TX_RDY	# test for ready
355		beq	t1,0,1b			# keep going till ready
356
357	# Okay, now send the character.
358
359		li	t0,PHYS_TO_K1(A_DUART_TX_HOLD_A)
360		sd	a0,(t0)
361
362	# done!
363
364		j	ra
365
366END(board_uarta_txchar)
367#endif
368
369/*  *********************************************************************
370    *  BOARD_SETLEDS(x)
371    *
372    *  Set LEDs for boot-time progress indication.  Not used if
373    *  the board does not have progress LEDs.  This routine
374    *  must not call any other routines, since it may be invoked
375    *  either from KSEG0 or KSEG1 and it may be invoked
376    *  whether or not the icache is operational.
377    *
378    *  Input parameters:
379    *  	   a0 - LED value (8 bits per character, 4 characters)
380    *
381    *  Return value:
382    *  	   nothing
383    *
384    *  Registers used:
385    *  	   t0,t1,t2,t3
386    ********************************************************************* */
387
388
389#define LED_CHAR0	(32+8*3)
390#define LED_CHAR1	(32+8*2)
391#define LED_CHAR2	(32+8*1)
392#define LED_CHAR3	(32+8*0)
393
394LEAF(board_setleds)
395
396#ifdef _SERIAL_PORT_LEDS_
397
398       /*
399        * Sending to serial port
400	*/
401		move	t3,ra
402		move	t2,a0
403
404		li	a0,'['
405		bal	board_uarta_txchar
406
407		move	a0,t2
408		rol	a0,8
409		bal	board_uarta_txchar
410		rol	a0,8
411		bal	board_uarta_txchar
412		rol	a0,8
413		bal	board_uarta_txchar
414		rol	a0,8
415		bal	board_uarta_txchar
416
417		li	a0,']'
418		bal	board_uarta_txchar
419
420		move	ra,t3
421		j	ra
422
423#else
424
425	/*
426	 * Sending to LEDs
427	 */
428		li	t0,PHYS_TO_K1(LEDS_PHYS)
429
430		rol	a0,a0,8
431		and	t1,a0,0xFF
432		sb	t1,LED_CHAR0(t0)
433
434		rol	a0,a0,8
435		and	t1,a0,0xFF
436		sb	t1,LED_CHAR1(t0)
437
438		rol	a0,a0,8
439		and	t1,a0,0xFF
440		sb	t1,LED_CHAR2(t0)
441
442		rol	a0,a0,8
443		and	t1,a0,0xFF
444		sb	t1,LED_CHAR3(t0)
445
446		j	ra
447#endif
448
449END(board_setleds)
450
451