RT-AC66 3.0.0.4.374.130 core
[tomato.git] / release / src-rt-6.x / cfe / cfe / arch / mips / board / littlesur / src / littlesur_init.S
blob3824808a00354f10226090fbb85dd179ddf817ea
1 /*  *********************************************************************
2     *  SB1250 Board Support Package
3     *  
4     *  Board-specific initialization            File: LITTLESUR_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 (mpl@broadcom.com)
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     ********************************************************************* */
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 "littlesur.h"
56 #include "mipsmacros.h"
57 #include "sb1250_draminit.h"
59                 .text
62 /*  *********************************************************************
63     *  Macros
64     ********************************************************************* */
68  * Define this to send the LED messages to the serial port instead
69  * of to the LEDs.
70  */
72 /*#define _SERIAL_PORT_LEDS_*/
73 #if (defined(_CSWARM_DIAG3E_CFG_) || defined(_CSWARM_DIAG_CFG_))
74 #define _PROMICE_PORT_LEDS_
75 #endif
77 #ifdef _SERIAL_PORT_LEDS_
78 #include "sb1250_uart.h"                /* need this for serial defs */
79 #endif
81 #ifdef _PROMICE_PORT_LEDS_
82 #define BOARD_PROMICE_BASE      (0x1FDFFC00)
83 #define BOARD_PROMICE_ZERO      (0)
84 #define BOARD_PROMICE_ONE       (1)
85 #define BOARD_PROMICE_DATA      (2)
86 #define BOARD_PROMICE_STATUS    (3)
88 #define TDA 0x01        /* Target data available */
89 #define HDA 0x02        /* Host data available */
90 #define OVR 0x04        /* Host data overflow */
91 #endif
95 #if (CFG_UNIPROCESSOR_CPU0 && !CFG_MULTI_CPUS)
96 /*  *********************************************************************
97     *  sb1250_switch_unicpu0
98     *  
99     *  Switch the processor into uniprocessor CPU0 mode - this 
100     *  effectively disables CPU1 and changes the CPU to look
101     *  like an 1125 with a big L2 cache (an 1150, if you will).
102     *  
103     *  This routine will do one of two things:  If we are already in
104     *  uniprocessor mode, it just returns.  If we are not in uni
105     *  mode, we muck with the SCD to enable uni mode and do a
106     *  soft reset.  The processor will reset and eventuall wind
107     *  back here, where it will notice that the uni mode is turned
108     *  on and execution will continue.
109     *  
110     *  Input parameters: 
111     *      nothing
112     *      
113     *  Return value:
114     *      nothing
115     *      
116     *  Registers used:
117     *      t0,t1,t2,t3,t4
118     *      register s0 must be preserved, it contains the return address
119     ********************************************************************* */
121 LEAF(sb1250_switch_unicpu0)
123         /*
124          * If the CPU is a 1250 or hybrid, certain initialization has
125          * to be done so that the chip can be used like an 112x.
126          */
128                 /* First, figure out what type of SOC we're on. */
129                 ld      t0, PHYS_TO_K1(A_SCD_SYSTEM_REVISION)
130                 and     t1, t0, M_SYS_PART
131                 dsrl    t1, t1, S_SYS_PART      # part number now in t1
132                 and     t2, t0, M_SYS_REVISION
133                 dsrl    t2, t2, S_SYS_REVISION  # revision now in t2
135         /*
136          * Calculating SOC type:
137          *      soc_type = part & 0xf;
138          *      if (system_revision <= PASS2
139          *          && (soc_type == 2 || soc_type == 5))
140          *        soc_type = 0;                 # really a 1250.
141          */
143                 andi    t3, t1, 0xf             # soc_type (t3) = part & 0xf;
144                 bgt     t2, K_SYS_REVISION_PASS2, soc_type_ok
145                 beq     t3, 2, soc_type_bogus
146                 beq     t3, 5, soc_type_bogus
147                 b       soc_type_ok
149 soc_type_bogus:
150                 move    t3, zero
152 soc_type_ok:
154         /*
155          * We have a 1250 or hybrid.  Initialize registers as appropriate.
156          */
159         /*
160          * If we're not already running as a uniprocessor, get us there.
161          */
162                 and     t3, t1, 0xf00
163                 dsrl    t3, t3, 8               # t3 = numcpus
165                 ld      t4, PHYS_TO_K1(A_SCD_SYSTEM_CFG)
166                 or      t4, t4, M_SYS_SB_SOFTRES
167                 xor     t4, t4, M_SYS_SB_SOFTRES
168                 sd      t4, PHYS_TO_K1(A_SCD_SYSTEM_CFG)        /* clear soft reset */
169                 
170                 beq     t3, 1, 2f
172                 or      t4, t4, M_SYS_SB_SOFTRES | M_SYS_UNICPU0
173                 sd      t4, PHYS_TO_K1(A_SCD_SYSTEM_CFG)        /* go unicpu */
174                 sync
176 1:              b       1b                      # loop till reset sinks in
178 2:              j       ra
180 END(sb1250_switch_unicpu0)
181 #endif
183 /*  *********************************************************************
184     *  BOARD_EARLYINIT()
185     *  
186     *  Initialize board registers.  This is the earliest 
187     *  time the BSP gets control.  This routine cannot assume that
188     *  memory is operational, and therefore all code in this routine
189     *  must run from registers only.  The $ra register must not
190     *  be modified, as it contains the return address.
191     *
192     *  This routine will be called from uncached space, before
193     *  the caches are initialized.  If you want to make
194     *  subroutine calls from here, you must use the CALLKSEG1 macro.
195     *
196     *  Among other things, this is where the GPIO registers get 
197     *  programmed to make on-board LEDs function, or other startup
198     *  that has to be done before anything will work.
199     *  
200     *  Input parameters: 
201     *      nothing
202     *      
203     *  Return value:
204     *      nothing
205     ********************************************************************* */
207 LEAF(board_earlyinit)
210         #
211         # If configured, switch the chip into uniprocessor mode
212         #
213 #if (CFG_UNIPROCESSOR_CPU0 && !CFG_MULTI_CPUS)
214                 move    s0,ra                   # need this to get out of here
215                 bal     sb1250_switch_unicpu0   # might not return
216                 move    ra,s0                   # restore saved return address
217 #endif
219         #
220         # Reprogram the SCD to make sure UART0 is enabled.
221         # Some CSWARM boards have the SER0 enable bit when
222         # they're not supposed to, which switches the UART
223         # into synchronous mode.  Kill off the SCD bit.
224         # XXX this should be investigated in hardware, as 
225         # XXX it is a strap option on the CPU.
226         #
228                 li      t0,PHYS_TO_K1(A_SCD_SYSTEM_CFG)
229                 ld      t1,0(t0)
230                 dli     t2,~M_SYS_SER0_ENABLE
231                 and     t1,t1,t2
232                 sd      t1,0(t0)
234        #
235        # Configure the GPIOs
236        #
238                 li      t0,PHYS_TO_K1(A_GPIO_DIRECTION)
239                 li      t1,GPIO_OUTPUT_MASK
240                 sd      t1,0(t0)
242                 li      t0,PHYS_TO_K1(A_GPIO_INT_TYPE)
243                 li      t1,GPIO_INTERRUPT_MASK
244                 sd      t1,0(t0)
248        #
249        # Configure the LEDs
250        #     
252                 li      t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(LEDS_CS))
253                 li      t1,LEDS_PHYS >> S_IO_ADDRBASE
254                 sd      t1,R_IO_EXT_START_ADDR(t0)
256                 li      t1,LEDS_SIZE-1  /* Needs to be 1 smaller, se UM for details */
257                 sd      t1,R_IO_EXT_MULT_SIZE(t0)
259                 li      t1,LEDS_TIMING0
260                 sd      t1,R_IO_EXT_TIME_CFG0(t0)
262                 li      t1,LEDS_TIMING1
263                 sd      t1,R_IO_EXT_TIME_CFG1(t0)
265                 li      t1,LEDS_CONFIG
266                 sd      t1,R_IO_EXT_CFG(t0)
268        #
269        # Configure the RTC
270        #     
272                 li      t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(RTC_CS))
273                 li      t1,RTC_PHYS >> S_IO_ADDRBASE
274                 sd      t1,R_IO_EXT_START_ADDR(t0)
276                 li      t1,RTC_SIZE-1   /* Needs to be 1 smaller, se UM for details */
277                 sd      t1,R_IO_EXT_MULT_SIZE(t0)
279                 li      t1,RTC_TIMING0
280                 sd      t1,R_IO_EXT_TIME_CFG0(t0)
282                 li      t1,RTC_TIMING1
283                 sd      t1,R_IO_EXT_TIME_CFG1(t0)
285                 li      t1,RTC_CONFIG
286                 sd      t1,R_IO_EXT_CFG(t0)
289        #
290        # Configure the IDE interface
291        #     
293                 li      t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(IDE_CS))
295                 li      t1,IDE_PHYS >> S_IO_ADDRBASE
296                 sd      t1,R_IO_EXT_START_ADDR(t0)
298                 li      t1,IDE_SIZE-1
299                 sd      t1,R_IO_EXT_MULT_SIZE(t0)
301                 li      t1,IDE_TIMING0
302                 sd      t1,R_IO_EXT_TIME_CFG0(t0)
304                 li      t1,IDE_TIMING1
305                 sd      t1,R_IO_EXT_TIME_CFG1(t0)
307                 li      t1,IDE_CONFIG
308                 sd      t1,R_IO_EXT_CFG(t0)
311 #ifdef _SERIAL_PORT_LEDS_
313        /*
314         * If sending the LED messages to the serial port, we will need
315         * to initialize the port now.
316         */
318         # Program the mode register for 8 bits/char, no parity
320                 li      t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A)     
321                 li      t1,V_DUART_BITS_PER_CHAR_8 | V_DUART_PARITY_MODE_NONE
322                 sd      t1,(t0)
324         # Program the mode register for 1 stop bit, ignore CTS
327                 li      t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A)
328                 ld      t1,(t0)                 # Errata 1956 workaround
329                 li      t0,PHYS_TO_K1(A_DUART_MODE_REG_2_A)     
330                 li      t1,M_DUART_STOP_BIT_LEN_1
331                 sd      t1,(t0)
333         # Program the baud rate to 115200
335                 li      t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A)
336                 ld      t1,(t0)                 # Errata 1956 workaround
337                 li      t0,PHYS_TO_K1(A_DUART_CLK_SEL_A)
338                 li      t1,V_DUART_BAUD_RATE(CFG_SERIAL_BAUD_RATE)
339                 sd      t1,(t0)
341         # Dont use any interrupts
343                 li      t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A)
344                 ld      t1,(t0)                 # Errata 1956 workaround
345                 li      t0,PHYS_TO_K1(A_DUART_IMR)
346                 ld      t1,(t0)
347                 and     t1,~M_DUART_IMR_ALL_A
348                 sd      t1,(t0)
350         # Enable sending and receiving
352                 li      t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A)
353                 ld      t1,(t0)                 # Errata 1956 workaround
354                 li      t0,PHYS_TO_K1(A_DUART_CMD_A)
355                 li      t1,M_DUART_RX_EN | M_DUART_TX_EN
356                 sd      t1,(t0)
358 #endif
360 #ifdef _PROMICE_PORT_LEDS_
362        /*
363         * Initialize the promice port.  read status until
364         * it does not read 0xCC, then do a dummy read from the
365         * data register.
366         */
368                 li      t1,PHYS_TO_K1(BOARD_PROMICE_BASE)
370                 li      t2,10000
371 1:              sub     t2,1
372                 beq     t2,zero,2f
373                 lbu     t0,BOARD_PROMICE_STATUS(t1)
374                 beq     t0,0xCC,1b
376 2:              lbu     t0,BOARD_PROMICE_DATA(t1)
378 #endif
382                 j       ra
384 END(board_earlyinit)
387 /*  *********************************************************************
388     *  BOARD_DRAMINFO
389     *  
390     *  Return the address of the DRAM information table
391     *  
392     *  Input parameters: 
393     *      nothing
394     *      
395     *  Return value:
396     *      v0 - DRAM info table, return 0 to use default table
397     ********************************************************************* */
400 LEAF(board_draminfo)
402                 move    t0,ra
404 #ifdef _HARDWIRED_MEMORY_TABLE
405                 LOADREL(v0,myinfo)
406 #else
407                 move    v0,zero         # auto configure
408 #endif
410                 move    ra,t0
411                 j       ra
415 myinfo:
416         DRAM_GLOBALS(CFG_DRAM_INTERLEAVE)
417         
419         /* 128MB on MC0 (SDRAM) */ 
420         DRAM_CHAN_CFG(MC_CHAN0, DRT10(8,0), JEDEC,CASCHECK, BLKSIZE32, CFG_DRAM_CSINTERLEAVE, CFG_DRAM_ECC, 0)
421         DRAM_CS_GEOM(MC_CS0, 12, 8, 2)
422         DRAM_CS_TIMING(DRT10(7,5), JEDEC_RFSH_64khz, JEDEC_CASLAT_25, 0,  45, DRT4(20,0), DRT4(15,0),  DRT4(20,0),  0, 0)
423         DRAM_EOT
426 END(board_draminfo)
429 /*  *********************************************************************
430     *  BOARD_UARTA_TXCHAR
431     *  
432     *  Transmit a single character via UART A
433     *  
434     *  Input parameters: 
435     *      a0 - character to transmit (low-order 8 bits)
436     *      
437     *  Return value:
438     *      nothing
439     *      
440     *  Registers used:
441     *      t0,t1
442     ********************************************************************* */
443 #ifdef _SERIAL_PORT_LEDS_
444 LEAF(board_uarta_txchar)
446         # Wait until there is space in the transmit buffer
448 1:              li      t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A)
449                 ld      t1,(t0)                 # Errata 1956 workaround
450                 li      t0,PHYS_TO_K1(A_DUART_STATUS_A)
451                 ld      t1,(t0)                 # Get status bits
452                 and     t1,M_DUART_TX_RDY       # test for ready
453                 beq     t1,0,1b                 # keep going till ready
455         # Okay, now send the character.
457                 li      t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A)
458                 ld      t1,(t0)                 # Errata 1956 workaround
459                 li      t0,PHYS_TO_K1(A_DUART_TX_HOLD_A)
460                 sd      a0,(t0)
462         # done!
464                 j       ra
466 END(board_uarta_txchar)
467 #endif
469 /*  *********************************************************************
470     *  BOARD_PIAI2_TXCHAR
471     *  
472     *  Transmit a single character via UART A
473     *  
474     *  Input parameters: 
475     *      a0 - character to transmit (low-order 8 bits)
476     *      
477     *  Return value:
478     *      nothing
479     *      
480     *  Registers used:
481     *      t0,t1
482     ********************************************************************* */
484 #ifdef _PROMICE_PORT_LEDS_
486 LEAF(board_piai2_txchar)
488         # Wait until there is space in the transmit buffer
490                 li      t0,PHYS_TO_K1(BOARD_PROMICE_BASE)
492 1:              lb      t1,BOARD_PROMICE_STATUS(t0)
493                 andi    t1,TDA
494                 bne     t1,zero,1b
496         # Okay, now send the character.
498                 sb      a0,BOARD_PROMICE_ZERO(t0)
500         # done!
502                 j       ra
504 END(board_piai2_txchar)
505 #endif
508 /*  *********************************************************************
509     *  BOARD_SETLEDS(x)
510     *  
511     *  Set LEDs for boot-time progress indication.  Not used if
512     *  the board does not have progress LEDs.  This routine
513     *  must not call any other routines, since it may be invoked
514     *  either from KSEG0 or KSEG1 and it may be invoked 
515     *  whether or not the icache is operational.
516     *  
517     *  Input parameters: 
518     *      a0 - LED value (8 bits per character, 4 characters)
519     *      
520     *  Return value:
521     *      nothing
522     *  
523     *  Registers used:
524     *      t0,t1,t2,t3
525     ********************************************************************* */
528 #define LED_CHAR0       (0x38)
529 #define LED_CHAR1       (0x39)
530 #define LED_CHAR2       (0x3A)
531 #define LED_CHAR3       (0x3B)
533 LEAF(board_setleds)
535 #if defined(_SERIAL_PORT_LEDS_)
537        /*
538         * Sending to serial port
539         */
540                 move    t3,ra
541                 move    t2,a0
543                 li      a0,'['
544                 bal     board_uarta_txchar
546                 move    a0,t2
547                 rol     a0,8
548                 bal     board_uarta_txchar
549                 rol     a0,8
550                 bal     board_uarta_txchar
551                 rol     a0,8
552                 bal     board_uarta_txchar
553                 rol     a0,8
554                 bal     board_uarta_txchar
556                 li      a0,']'
557                 bal     board_uarta_txchar
559                 move    ra,t3
561 #elif defined(_PROMICE_PORT_LEDS_)
562                 move    t3,ra
563                 move    t2,a0
565                 li      a0,'['
566                 bal     board_piai2_txchar
568                 move    a0,t2
569                 rol     a0,8
570                 li      t0,PHYS_TO_K1(LEDS_PHYS)
571                 sb      a0,LED_CHAR0(t0)
572                 bal     board_piai2_txchar
574                 rol     a0,8
575                 li      t0,PHYS_TO_K1(LEDS_PHYS)
576                 sb      a0,LED_CHAR1(t0)
577                 bal     board_piai2_txchar
579                 rol     a0,8
580                 li      t0,PHYS_TO_K1(LEDS_PHYS)
581                 sb      a0,LED_CHAR2(t0)
582                 bal     board_piai2_txchar
584                 rol     a0,8
585                 li      t0,PHYS_TO_K1(LEDS_PHYS)
586                 sb      a0,LED_CHAR3(t0)
587                 bal     board_piai2_txchar
589                 li      a0,']'
590                 bal     board_piai2_txchar
591                 li      a0,13
592                 bal     board_piai2_txchar
593                 li      a0,10
594                 bal     board_piai2_txchar
596                 move    ra,t3
597 #else
599         /*
600          * Sending to LEDs
601          */
602                 li      t0,PHYS_TO_K1(LEDS_PHYS)
604                 rol     a0,a0,8
605                 and     t1,a0,0xFF
606                 sb      t1,LED_CHAR0(t0)
608                 rol     a0,a0,8
609                 and     t1,a0,0xFF
610                 sb      t1,LED_CHAR1(t0)
612                 rol     a0,a0,8
613                 and     t1,a0,0xFF
614                 sb      t1,LED_CHAR2(t0)
616                 rol     a0,a0,8
617                 and     t1,a0,0xFF
618                 sb      t1,LED_CHAR3(t0)
620 #endif
621                 j       ra
623 END(board_setleds)