1/*  *********************************************************************
2    *  SB1250 Board Support Package
3    *
4    *  Board-specific initialization		File: BCM91125CPCI_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 "sb1250_genbus.h"
52#include "sb1250_regs.h"
53#include "sb1250_scd.h"
54#include "bsp_config.h"
55#include "cpu_config.h"
56#include "mipsmacros.h"
57#include "sb1250_draminit.h"
58#include "sb1250_smbus.h"
59
60		.text
61
62/*  *********************************************************************
63    *  Macros
64    ********************************************************************* */
65
66/*
67 * Define this to send the LED messages to the serial port instead
68 * of to the LEDs.
69 */
70
71/*#define _SERIAL_PORT_LEDS_*/
72
73#ifdef _SERIAL_PORT_LEDS_
74#include "sb1250_uart.h"		/* need this for serial defs */
75#endif
76
77
78/*  *********************************************************************
79    *  BOARD_EARLYINIT()
80    *
81    *  Initialize board registers.  This is the earliest
82    *  time the BSP gets control.  This routine cannot assume that
83    *  memory is operational, and therefore all code in this routine
84    *  must run from registers only.  The $ra register must not
85    *  be modified, as it contains the return address.
86    *
87    *  This routine will be called from uncached space, before
88    *  the caches are initialized.  If you want to make
89    *  subroutine calls from here, you must use the CALLKSEG1 macro.
90    *
91    *  Among other things, this is where the GPIO registers get
92    *  programmed to make on-board LEDs function, or other startup
93    *  that has to be done before anything will work.
94    *
95    *  Input parameters:
96    *  	   nothing
97    *
98    *  Return value:
99    *  	   nothing
100    ********************************************************************* */
101
102LEAF(board_earlyinit)
103
104	#
105	# Reprogram the SCD to make sure UART0 is enabled.
106	# Some BCM91125CPCI boards have the SER0 enable bit when
107	# they're not supposed to, which switches the UART
108	# into synchronous mode.  Kill off the SCD bit.
109	# XXX this should be investigated in hardware, as
110	# XXX it is a strap option on the CPU.
111	#
112
113		li      t0,PHYS_TO_K1(A_SCD_SYSTEM_CFG)
114		ld	t1,0(t0)
115		dli	t2,~(M_SYS_SER0_ENABLE|M_SYS_SER1_ENABLE|M_SYS_LDT_TEST_EN|M_SYS_GEN_PARITY_EN)
116		and	t1,t1,t2
117		dli	t2,M_SYS_PCMCIA_ENABLE
118		or	t1,t1,t2
119		sd	t1,0(t0)
120
121
122       #
123       # Configure the GPIOs
124       #
125
126		li	t0,PHYS_TO_K1(A_GPIO_DIRECTION)
127		li	t1,GPIO_OUTPUT_MASK
128		sd	t1,0(t0)
129
130		li	t0,PHYS_TO_K1(A_GPIO_INT_TYPE)
131		li	t1,GPIO_INTERRUPT_MASK
132		sd	t1,0(t0)
133
134       #
135       # Turn off the diagnostic LED.
136       #
137		li	t0,PHYS_TO_K1(A_GPIO_PIN_CLR)
138		li	t1,M_GPIO_DEBUG_LED
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	# Configure CS 0 size from 4MB to 16MB.  Do the same for CS1
163	#
164		li	t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(BOOTROM_CS))
165
166		li	t1,BOOTROM_SIZE-1
167		sd	t1,R_IO_EXT_MULT_SIZE(t0)
168
169
170       #
171       # Configure the alternate boot ROM
172       #
173
174		li	t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(ALT_BOOTROM_CS))
175
176		li	t1,ALT_BOOTROM_PHYS >> S_IO_ADDRBASE
177		sd	t1,R_IO_EXT_START_ADDR(t0)
178
179		li	t1,BOOTROM_SIZE-1	/* use bigger size in case switch is set */
180		sd	t1,R_IO_EXT_MULT_SIZE(t0)
181
182		li	t1,ALT_BOOTROM_TIMING0
183		sd	t1,R_IO_EXT_TIME_CFG0(t0)
184
185		li	t1,ALT_BOOTROM_TIMING1
186		sd	t1,R_IO_EXT_TIME_CFG1(t0)
187
188		li	t1,ALT_BOOTROM_CONFIG
189		sd	t1,R_IO_EXT_CFG(t0)
190
191       #
192       # Configure the PCMCIA
193       #
194
195		li	t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(PCMCIA_CS))
196
197		li	t1,PCMCIA_PHYS >> S_IO_ADDRBASE
198		sd	t1,R_IO_EXT_START_ADDR(t0)
199
200		li	t1,PCMCIA_SIZE-1
201		sd	t1,R_IO_EXT_MULT_SIZE(t0)
202
203		li	t1,PCMCIA_TIMING0
204		sd	t1,R_IO_EXT_TIME_CFG0(t0)
205
206		li	t1,PCMCIA_TIMING1
207		sd	t1,R_IO_EXT_TIME_CFG1(t0)
208
209		li	t1,PCMCIA_CONFIG
210		sd	t1,R_IO_EXT_CFG(t0)
211
212#ifdef _SERIAL_PORT_LEDS_
213
214	# Program the mode register for 8 bits/char, no parity
215
216		li	t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A)
217		li	t1,V_DUART_BITS_PER_CHAR_8 | V_DUART_PARITY_MODE_NONE
218		sd	t1,(t0)
219
220	# Program the mode register for 1 stop bit, ignore CTS
221
222		li	t0,PHYS_TO_K1(A_DUART_MODE_REG_2_A)
223		li	t1,M_DUART_STOP_BIT_LEN_1
224		sd	t1,(t0)
225
226	# Program the baud rate to 115200
227
228		li	t0,PHYS_TO_K1(A_DUART_CLK_SEL_A)
229		li	t1,V_DUART_BAUD_RATE(CFG_SERIAL_BAUD_RATE)
230		sd	t1,(t0)
231
232	# Dont use any interrupts
233
234		li	t0,PHYS_TO_K1(A_DUART_IMR)
235		ld	t1,(t0)
236		and	t1,~M_DUART_IMR_ALL_A
237		sd	t1,(t0)
238
239	# Enable sending and receiving
240
241		li	t0,PHYS_TO_K1(A_DUART_CMD_A)
242		li	t1,M_DUART_RX_EN | M_DUART_TX_EN
243		sd	t1,(t0)
244
245#endif
246
247	j	ra
248
249END(board_earlyinit)
250
251
252/*  *********************************************************************
253    *  BOARD_DRAMINFO
254    *
255    *  Return the address of the DRAM information table
256    *
257    *  Input parameters:
258    *  	   nothing
259    *
260    *  Return value:
261    *  	   v0 - DRAM info table, return 0 to use default table
262    ********************************************************************* */
263
264
265LEAF(board_draminfo)
266
267	la	v0,spd
268	j	ra
269
270spd:
271
272	/*
273	 * Globals: Only one memory controller, no port interleaving
274	 */
275	DRAM_GLOBALS(0)
276        DRAM_CHAN_CFG(MC_CHAN1, DRT10(8,0), JEDEC, CASCHECK, BLKSIZE32, CFG_DRAM_CSINTERLEAVE, CFG_DRAM_ECC, 0)
277
278	/* XXX Reduce drive strength a little.  Might not be necessary. */
279	DRAM_CHAN_CLKCFG(0x00,0x08,0x08,0x00,0x0F,0x0F)
280
281	DRAM_CS_SPD(MC_CS0, 0, SODIMM1_SMBUS_CHAN, SODIMM1_SMBUS_DEV)
282	DRAM_EOT
283
284
285END(board_draminfo)
286
287/*  *********************************************************************
288    *  BOARD_UARTA_TXCHAR
289    *
290    *  Transmit a single character via UART A
291    *
292    *  Input parameters:
293    *  	   a0 - character to transmit (low-order 8 bits)
294    *
295    *  Return value:
296    *  	   nothing
297    *
298    *  Registers used:
299    *  	   t0,t1
300    ********************************************************************* */
301#ifdef _SERIAL_PORT_LEDS_
302LEAF(board_uarta_txchar)
303
304	# Wait until there is space in the transmit buffer
305
3061:		li	t0,PHYS_TO_K1(A_DUART_STATUS_A)
307		ld	t1,(t0)			# Get status bits
308		and	t1,M_DUART_TX_RDY	# test for ready
309		beq	t1,0,1b			# keep going till ready
310
311	# Okay, now send the character.
312
313		li	t0,PHYS_TO_K1(A_DUART_TX_HOLD_A)
314		sd	a0,(t0)
315
316	# done!
317
318		j	ra
319
320END(board_uarta_txchar)
321#endif
322
323/*  *********************************************************************
324    *  BOARD_SETLEDS(x)
325    *
326    *  Set LEDs for boot-time progress indication.  Not used if
327    *  the board does not have progress LEDs.  This routine
328    *  must not call any other routines, since it may be invoked
329    *  either from KSEG0 or KSEG1 and it may be invoked
330    *  whether or not the icache is operational.
331    *
332    *  Input parameters:
333    *  	   a0 - LED value (8 bits per character, 4 characters)
334    *
335    *  Return value:
336    *  	   nothing
337    *
338    *  Registers used:
339    *  	   t0,t1,t2,t3
340    ********************************************************************* */
341
342#define LED_CHAR0	(8*3)
343#define LED_CHAR1	(8*2)
344#define LED_CHAR2	(8*1)
345#define LED_CHAR3	(8*0)
346
347LEAF(board_setleds)
348
349
350	/*
351	 * Sending to LEDs
352	 */
353		li	t0,PHYS_TO_K1(LEDS_PHYS)
354
355		rol	a0,a0,8
356		and	t1,a0,0xFF
357		sb	t1,LED_CHAR0(t0)
358
359		rol	a0,a0,8
360		and	t1,a0,0xFF
361		sb	t1,LED_CHAR1(t0)
362
363		rol	a0,a0,8
364		and	t1,a0,0xFF
365		sb	t1,LED_CHAR2(t0)
366
367		rol	a0,a0,8
368		and	t1,a0,0xFF
369		sb	t1,LED_CHAR3(t0)
370
371	/*
372	 * A0 is now the same value it was at the beginning.
373	 */
374
375
376#ifdef _SERIAL_PORT_LEDS_
377		move	t3,ra
378		move	t2,a0
379
380		li	a0,'['
381		bal	board_uarta_txchar
382
383		move	a0,t2
384		rol	a0,8
385		bal	board_uarta_txchar
386
387		rol	a0,8
388		bal	board_uarta_txchar
389
390		rol	a0,8
391		bal	board_uarta_txchar
392
393		rol	a0,8
394		bal	board_uarta_txchar
395
396		li	a0,']'
397		bal	board_uarta_txchar
398		li	a0,13
399		bal	board_uarta_txchar
400		li	a0,10
401		bal	board_uarta_txchar
402
403		move	ra,t3
404#endif
405		j	ra
406
407END(board_setleds)
408
409
410
411