;/*
; *  Copyright 2007 by Texas Instruments Japan Limited.
; *  All rights reserved. Property of Texas Instruments Japan Limited.
; *  You may modify the programs on the condition of using the programs
; *  solely and exclusively with semiconductor devices manufactured  by 
; *  or for TI.
; *  
; *  THE PROGRAMS ARE PROVIDED "AS IS". TIJ MAKES NO WARRANTIES OR
; *  REPRESENTATIONS, EITHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING ANY
; *  IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
; *  LACK OF VIRUSES, ACCURACY OR COMPLETENESS OF RESPONSES, RESULTS AND LACK OF
; *  NEGLIGENCE. TIJ DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET
; *  POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL PROPERTY
; *  RIGHTS WITH REGARD TO THE PROGRAMS OR YOUR USE OF THOSE PROGRAMS. 
; */


;**************************************************************
;* Define the Value of EMIF Conf Register
;*                NEED to customize these values.
;**************************************************************

;EMIFA Register Address and Values
EMIFA_ADDR          .equ  0x01800000  ;EMIFA Register Address
EMIFA_GCTL_V        .equ  0x00000068  ;EMIFA global control
EMIFA_CE0_V         .equ  0xffffff93  ;EMIFA CE1
EMIFA_CE1_V         .equ  0x02208812  ;EMIFA CE0
EMIFA_CE2_V         .equ  0x22a28a22  ;EMIFA CE2
EMIFA_CE3_V         .equ  0x22a28a22  ;EMIFA CE3
EMIFA_SDRAMCTL_V    .equ  0x57114000  ;EMIFA SDRAM control
EMIFA_SDRAMTIM_V    .equ  0x000004e2  ;SDRAM timing (refresh)
EMIFA_SDRAMEXT_V    .equ  0x000a8529  ;SDRAM extended control

;**************************************************************
;* Define COPY Table Address
;*                NEED to customize this value.
;**************************************************************

COPY_TABLE          .equ  0x90000400  ;depend on "-bootorg" option

;**************************************************************
;* Define the Value of PLL Conf Register
;*                NEED to customize these values.
;**************************************************************

;EMIFA Register Address and Values
PLL_BASE_ADDR       .equ  0x01b7c100  ;PLL Base Address
PLL_DIV0            .equ  0x00008000  ;Enable
PLL_DIV1            .equ  0x00008001  ;Enable + 1
PLL_DIV2            .equ  0x00008003  ;Enable + 3
PLL_DIV3            .equ  0x00008004  ;Enable + 4
PLL_MULT            .equ  0x00000008  ;
PLL_OSCDIV1         .equ  0x00008004  ;Enable + 4

PLL_DELAY1          .equ  0x00000100  ;
PLL_DELAY2          .equ  0x00010000  ;

;**************************************************************
;* BOOT PROGRAM
;**************************************************************
  .sect ".boot_load"      ;user section name
  .global _boot

_boot:
;**************************************************************
;* DEBUG LOOP -  COMMENT OUT B FOR NORMAL OPERATION
;**************************************************************
      zero  B1
_myloop:
  ;[!B1]  B  _myloop
      nop  5
_myloopend:  nop

;**************************************************************
;* CONFIGURE PLL
;**************************************************************

      mvkl .S2 PLL_DELAY2, B0
      mvkh .S2 PLL_DELAY2, B0
boot_wait_loop:
      nop 5
 [b0] b     boot_wait_loop
      sub   B0, 1, B0
      nop   5

;* Set PLL Reg. address to A4 *******************************
      mvkl .S2 PLL_BASE_ADDR, B4
      mvkh .S2 PLL_BASE_ADDR, B4
      nop 5

;* Configure params to PLL registers ************************
      ; PLL_CSR(+0x0) &= ~CSR_PLLEN(=1);
      ldw .D2T2 *B4, B5 
      nop 4
      and .L2 -2, B5, B5 
      stw .D2T2 B5, *B4 
      nop 5 

      mvkl .S2 PLL_DELAY1, B0
      mvkh .S2 PLL_DELAY1, B0
delay_loop0:
      nop 5
 [b0] b     delay_loop0
      sub   B0, 1, B0
      nop   5
      
      ; PLL_CSR  |= CSR_PLLRST(=8);
      ldw .D2T2 *B4, B5 
      nop 4
      or .L2 8, B5, B5 
      stw .D2T2 B5, *B4
      nop 5

      mvkl .S2 PLL_DIV0, B5
      mvkh .S2 PLL_DIV0, B5
      stw   B5, *+B4[5]      ; set PLL_DIV0 (+0x14)
      nop 5

      mvkl .S2 PLL_MULT, B5
      mvkh .S2 PLL_MULT, B5
      stw   B5, *+B4[4]      ; set PLL_MULT (+0x10)
      nop 5
      
      mvkl .S2 PLL_OSCDIV1, B5
      mvkh .S2 PLL_OSCDIV1, B5
      stw   B5, *+B4[9]      ; set PLL_OSCDIV1 (+0x24)
      nop 5
      
      mvkl .S2 PLL_DIV3, B5
      mvkh .S2 PLL_DIV3, B5
      stw   B5, *+B4[8]      ; set PLL_DIV3 (+0x20)
      nop 5
      mvkl .S2 PLL_DELAY1, B0
      mvkh .S2 PLL_DELAY1, B0
delay_loop1:
      nop 5
 [b0] b     delay_loop1
      sub   B0, 1, B0
      nop   5
      
      mvkl .S2 PLL_DIV2, B5
      mvkh .S2 PLL_DIV2, B5
      stw   B5, *+B4[7]      ; set PLL_DIV2 (+0x1C)
      mvkl  PLL_DELAY1, B0
      mvkh  PLL_DELAY1, B0
delay_loop2:
      nop 5
 [b0] b     delay_loop2
      sub   B0, 1, B0
      nop   5
      
      mvkl .S2 PLL_DIV1, B5
      mvkh .S2 PLL_DIV1, B5
      stw   B5, *+B4[6]      ; set PLL_DIV1 (+0x18)
      mvkl .S2 PLL_DELAY1, B0
      mvkh .S2 PLL_DELAY1, B0
delay_loop3:
      nop 5
 [b0] b     delay_loop3
      sub   B0, 1, B0
      nop   5
      
      ; PLL_CSR(+0x0) &= ~CSR_PLLRST(=8); 
      ldw .D2T2 *B4, B5 
      nop 4
      and .L2 -9, B5, B5 
      stw .D2T2 B5, *B4 
      nop 5
       
      mvkl .S2 PLL_DELAY2, B0
      mvkh .S2 PLL_DELAY2, B0
delay_loop4:
      nop   5
 [b0] b     delay_loop4
      sub   B0, 1, B0
      nop   5

      ; PLL_CSR(+0x0) |= CSR_PLLEN(=1);
      ldw .D2T2 *B4, B5 
      nop 4
      or .L2 1, B5, B5 
      stw .D2T2 B5, *B4
      nop 2 
      
      mvkl .S2 PLL_DELAY1, B0
      mvkh .S2 PLL_DELAY1, B0
delay_loop5:
      nop 5
 [b0] b     delay_loop5
      sub   B0, 1, B0
      nop   5 

;**************************************************************
;* CONFIGURE EMIF
;**************************************************************
;* Set EMIFA Reg. address to A4 *******************************
      mvkl  EMIFA_ADDR, A4
      mvkh  EMIFA_ADDR, A4
      
;* Configure params to EMIFA registers ************************
      mvkl  EMIFA_GCTL_V, B4
      mvkh  EMIFA_GCTL_V, B4
      stw   B4, *+A4[0]      ; set global control reg.

      mvkl  EMIFA_CE0_V, B4
      mvkh  EMIFA_CE0_V, B4
      stw   B4, *+A4[2]      ; set EMIFA CE0 reg.
      
      mvkl  EMIFA_CE1_V, B4
      mvkh  EMIFA_CE1_V, B4
      stw   B4, *+A4[1]      ; set EMIFA CE1 reg.
      
      mvkl  EMIFA_CE2_V, B4
      mvkh  EMIFA_CE2_V, B4
      stw   B4, *+A4[4]      ; set EMIFA CE2 reg.
      
      mvkl  EMIFA_CE3_V, B4
      mvkh  EMIFA_CE3_V, B4
      stw   B4, *+A4[5]      ; set EMIFA CE3 reg.
      
      mvkl  EMIFA_SDRAMCTL_V, B4
      mvkh  EMIFA_SDRAMCTL_V, B4
      stw   B4, *+A4[6]      ; set SDRAM timing reg.
      
      mvkl  EMIFA_SDRAMTIM_V, B4
      mvkh  EMIFA_SDRAMTIM_V, B4
      stw   B4, *+A4[7]      ; set SDRAM ext ctrl reg.
      
      mvkl  EMIFA_SDRAMEXT_V, B4
      mvkh  EMIFA_SDRAMEXT_V, B4
      stw   B4, *+A4[8]      ; set SDRAM control reg.
      
;**************************************************************
; Copy sections
;**************************************************************
_copy_section:
      mvkl  COPY_TABLE, A3    ; load table pointer
      mvkh  COPY_TABLE, A3
      
      ldw    *A3++, B1      ; read entry point
      
copy_section_top:
      ldw    *A3++, B0      ; read byte count of the section
      ldw    *A3++, A4      ; read destination start address
      nop    3

  [!b0]  b    copy_done      ; If section size=0, end copy
      nop    5          ; and jump to entry point
      
copy_loop:
      ldb    *A3++,B5      ; read data from ROM
      sub    B0, 1, B0      ; decrement counter
  [ b0]  b    copy_loop      ; coutinue copy till counter=0
  [!b0]  b    copy_section_top  ; jump to copy_section_top when copy is completed
      zero  A1
  [!b0]  and    3, A3, A1
      stb    B5, *A4++      ; write data to RAM
  [!b0]  and    -4, A3, A5      ; round address up to next multiple of 4
  [ a1]  add    4, A5, A3      ; round address up to next multiple of 4

;**************************************************************
; Jump to entry point
;**************************************************************
copy_done:
      b  .S2  B1          ; jump to _c_int00
      nop    5


