📄 memsetup-pxa.s
字号:
/*
* memsetup-pxa.S :memory setup for PXA architectures
*
* Copyright (c) 2003, Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#define __ASSEMBLY__
#ifdef HAVE_CONFIG_H
# include <blob/config.h>
#endif
#include <blob/arch.h>
.text
.globl memsetup
memsetup:
mov r10, lr
#if 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Workaround for sighting 27004: early termination
@ of SDRAM autorefresh on exit from processor sleep
@ state in B1 stepping of PXA250/210.
@ MDREFR
ldr r0, =MDREFR
@ Need to set MDREFR:DRI field to 0 for this to work. Side effect is
@ picking the MEMCLK:SDCLK ratio. The specified value (0x038FF000)
@ sets that ratio as 2:1. This corresponds to the defaults after reset,
@ including sleep reset.
mov r1, #0x03800000
orr r1, r1, #0x000FF000 @ VALUE
str r1, [r0] @ STORE
mov r0, #0xA0000000 @ SDRAM ADDRESS
ldr r1, [r0] @ CAUSES the first row refresh to all partitions
ldr r1, [r0] @ CAUSES the second row refresh to all partitions
mov r2, #0x2000 @ 8k loop
EARLY_REFRESH_LOOP:
ldr r1, [r0] @ CAUSES a row refresh to all partitions
subs r2, r2, #0x1
bpl EARLY_REFRESH_LOOP @ while >= 0
@ End workaround for sighting 27004
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#endif
//Must set the GPIOs up before any chip selects will work
//PSSR = 0x10 clear the PH bit in the PSSR
ldr r0, =PSSR
ldr r1, =0x10
str r1, [r0]
nop
nop
nop
nop
nop
// GPSR - put a 1 on any of the GPIOs (0=unchanged, 1=drive 1)
ldr r0, =GPSR0
ldr r1, =GPSR0_VAL
str r1, [r0]
ldr r0, =GPSR1
ldr r1, =GPSR1_VAL
str r1, [r0]
ldr r0, =GPSR2
ldr r1, =GPSR2_VAL
str r1, [r0]
//GPCR - put a 0 on any of the GPIOs (0=unchanged, 1=drive 0)
ldr r0, =GPCR0
ldr r1, =GPCR0_VAL
str r1, [r0]
ldr r0, =GPCR1
ldr r1, =GPCR1_VAL
str r1, [r0]
ldr r0, =GPCR2
ldr r1, =GPCR2_VAL
str r1, [r0]
//GPDR - put the GPIOs in the correct direction (0=in, 1=out)
ldr r0, =GPDR0
ldr r1, =GPDR0_VAL
str r1, [r0]
ldr r0, =GPDR1
ldr r1, =GPDR1_VAL
str r1, [r0]
ldr r0, =GPDR2
ldr r1, =GPDR2_VAL
str r1, [r0]
//GAFR - setup the alternate functions (00=normal, 01=alt fuct 1, etc)
ldr r0, =GAFR0_L
ldr r1, =GAFR0_L_VAL
str r1, [r0]
ldr r0, =GAFR0_U
ldr r1, =GAFR0_U_VAL
str r1, [r0]
ldr r0, =GAFR1_L
ldr r1, =GAFR1_L_VAL
str r1, [r0]
ldr r0, =GAFR1_U
ldr r1, =GAFR1_U_VAL
str r1, [r0]
ldr r0, =GAFR2_L
ldr r1, =GAFR2_L_VAL
str r1, [r0]
ldr r0, =GAFR2_U
ldr r1, =GAFR2_U_VAL
str r1, [r0]
//PSSR = 0x20 clear the RDH bit in the PSSR
ldr r0, =PSSR
ldr r1, =0x20
str r1, [r0]
#ifdef LUBBOCK
/* Light Lubbock LED */
ldr r0, =FPGA_REGS_BASE
mov r2, #0xFF
strh r2, [r0, #LED_BLANK_OFFSET]
ldr r2, =0xb10bb10b
#if (defined(CPU_pxa210) || defined(CPU_pxm261) )
strh r2, [r0, #HEX_LED_OFFSET]
#else
str r2, [r0, #HEX_LED_OFFSET]
#endif
#endif
@********************************************************************
@ Initlialize Memory Controller
@ The sequence below is based on the recommended init steps detailed
@ in the EAS, chapter 5.
@
@ pause for 200 uSecs- allow internal clocks to settle
@ *Note: only need this if hard reset... doing it anyway for now
@
@ ---- Wait 200 usec
ldr r3, =OSCR
mov r2, #0
str r2, [r3]
ldr r4, =0x300 @ really 0x2E1 is about 200usec, so 0x300 should be plenty
1:
ldr r2, [r3]
cmp r4, r2
bgt 1b
@ get memory controller base address
ldr r1, =MEMC_BASE
@****************************************************************************
@ Step 1
@
@ write msc0, read back to ensure data latches
@
ldr r2, =MSC0_VAL
str r2, [r1, #MSC0_OFFSET]
ldr r2, [r1, #MSC0_OFFSET]
@ write msc1
ldr r2, =MSC1_VAL
str r2, [r1, #MSC1_OFFSET]
ldr r2, [r1, #MSC1_OFFSET]
@ write msc2
ldr r2, =MSC2_VAL
str r2, [r1, #MSC2_OFFSET]
ldr r2, [r1, #MSC2_OFFSET]
@ write mecr
ldr r2, =MECR_VAL
str r2, [r1, #MECR_OFFSET]
@ write mcmem0
ldr r2, =MCMEM0_VAL
str r2, [r1, #MCMEM0_OFFSET]
@ write mcmem1
ldr r2, =MCMEM1_VAL
str r2, [r1, #MCMEM1_OFFSET]
@ write mcatt0
ldr r2, =MCATT0_VAL
str r2, [r1, #MCATT0_OFFSET]
@ write mcatt1
ldr r2, =MCATT1_VAL
str r2, [r1, #MCATT1_OFFSET]
@ write mcio0
ldr r2, =MCIO0_VAL
str r2, [r1, #MCIO0_OFFSET]
@ write mcio1
ldr r2, =MCIO1_VAL
str r2, [r1, #MCIO1_OFFSET]
@ fly-by-dma is defeatured on this part
@ write flycnfg
@ldr r2, =FLYCNFG_SETTINGS
@str r2, [r1, #FLYCNFG_OFFSET]
@-------------------------------------------------------
@ 3rd bullet, Step 1
@
@ get the mdrefr settings
ldr r3, =MDREFR_VAL
@ extract DRI field (we need a valid DRI field)
@
ldr r2, =0xFFF
@ valid DRI field in r3
@
and r3, r3, r2
@ get the reset state of MDREFR
@
ldr r4, [r1, #MDREFR_OFFSET]
@ clear the DRI field
@
bic r4, r4, r2
@ insert the valid DRI field loaded above
@
orr r4, r4, r3
@ write back mdrefr
@
str r4, [r1, #MDREFR_OFFSET]
@ *Note: preserve the mdrefr value in r4 *
@****************************************************************************
@ Step 2
@
@ fetch sxcnfg value
@
@ldr r2, =0
@ write back sxcnfg
@str r2, [r1, #SXCNFG_OFFSET]
@ if sxcnfg=0, don't program for synch-static memory
@cmp r2, #0
@beq 1f
@program sxmrs
@ldr r2, =SXMRS_SETTINGS
@str r2, [r1, #SXMRS_OFFSET]
@****************************************************************************
@ Step 3
@
@ Assumes previous mdrefr value in r4, if not then read current mdrefr
@ clear the free-running clock bits
@ (clear K0Free, K1Free, K2Free
@
bic r4, r4, #(0x00800000 | 0x01000000 | 0x02000000)
@ set K1RUN if bank 0 installed
@
orr r4, r4, #0x00010000
#ifdef LUBBOCK
@<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
@<!<!<!<!<!<!<!<!<!<!<! Begin INSERT 1 <!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Lubbock: Allow the user to select the {T/R/M} with predetermined
@ SDCLK. Based on Table 3-1 in PXA250 and PXA210 Dev Man.
@
@ * = Must set MDREFR.K1DB2 to halve the MemClk for desired SDCLK[1]
@
@ S25, S26 used to provide all 400 MHz BIN values for Cotulla (0,0 - 1,3)
@ S25, S26 used to provide all 200 MHz BIN values for Sabinal
@
@ S23: Force the halving of MemClk when deriving SDCLK[1]
@ DOT: no override !DOT: halve (if not already forced half)
@ *For certain MemClks, SDCLK's derivation is forced to be halved
@
@ S24: Run/Turbo.
@ DOT: Run mode !DOT: Turbo mode
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ Allow the user to control K1DB2 where applicable
@
@ Get the value of S23: @ 1 = DOT (unity), 0 = !DOT (halve it)
@
@ DOT: set K1DB2 (SDCLD = MemClk)
@ !DOT: clear K1DB2 (SDCLK = MemClk/2)
@
@ldr r2, =FPGA_REGS_BASE
bl GET_S23 @ r3, r2 @ get the value of S23 in R0, i put the base adx of fpga in r3
cmp r3, #0x0 @ is !DOT?
orreq r4, r4, #0x00020000 @ SDClk[1] = MemClk/2
bicne r4, r4, #0x00020000 @ SDClk[1] = MemClk
@
@ Next, we need to look for S25,S26 selections that necessitate the
@ halving of MemClk to derive SDCLK[1]: (S25,S26)={03-0C, 10-13}
@ Override above S23-based selection accordingly.
@
ldr r2, =FPGA_REGS_BASE
bl GET_S25 @ r0, r2
@ get the value of S25 in R0, i put the base adx of fpga in r2
ldr r2, =FPGA_REGS_BASE
BL GET_S26 @ r3, r2
@ get the value of S26 in R1, i put the base adx of fpga in r2
orr r0, r0, r3 @ concatenate S25 & S26 vals
and r0, r0, #0xFF
@ Set K1DB2 for the frequencies that require it
@
cmp r0, #0x03
cmpne r0, #0x04
cmpne r0, #0x05
cmpne r0, #0x06
cmpne r0, #0x07
cmpne r0, #0x08
cmpne r0, #0x09
cmpne r0, #0x0A
cmpne r0, #0x0B
cmpne r0, #0x0C
cmpne r0, #0x10
cmpne r0, #0x11
cmpne r0, #0x12
cmpne r0, #0x13
orreq r4, r4, #0x00020000 @ SDCLK[1] = (MemClk)/2 for 03 - 0C @ 10 - 13
@
@ *Must make MSC0&1 adjustments now for MEMClks > 100MHz.
@
@ Adjust MSC0 for MemClks > 100 MHz
@
ldreq r0, [r1, #MSC0_OFFSET]
ldreq r3, =0x7F007F00
biceq r0, r0, r3 @ clear MSC0[14:12, 11:8] (RRR, RDN)
ldreq r3, =0x46004600
orreq r0, r0, r3 @ set MSC0[14, 10:9] (doubling RRR, RDN)
streq r0, [r1, #MSC0_OFFSET]
ldreq r0, [r1, #MSC0_OFFSET] @ read it back to ensure that the data latches
@
@ Adjust MSC1.LH for MemClks > 100 MHz
@
ldreq r0, [r1, #MSC1_OFFSET]
ldreq r3, =0x7FF0
biceq r0, r0, r3 @ clear MSC1[14:12, 11:8, 7:4] (RRR, RDN, RDF)
ldreq r3, =0x4880
orreq r0, r0, r3 @ set MSC1[14, 11, 7] (doubling RRR, RDN, RDF)
streq r0, [r1, #MSC1_OFFSET]
ldreq r0, [r1, #MSC1_OFFSET] @ read it back to ensure that the data latches
@ @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@<!<!<!<!<!<!<!<!<!<!<! End INSERT 1 <!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
@<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
#endif
@ write back mdrefr
@
str r4, [r1, #MDREFR_OFFSET]
ldr r4, [r1, #MDREFR_OFFSET]
@ deassert SLFRSH
@
bic r4, r4, #0x00400000
@ write back mdrefr
@
str r4, [r1, #MDREFR_OFFSET]
@ assert E1PIN
@
orr r4, r4, #0x00008000
@ write back mdrefr
@
str r4, [r1, #MDREFR_OFFSET]
ldr r4, [r1, #MDREFR_OFFSET]
nop
nop
@****************************************************************************
@ Step 4
@
@ fetch platform value of mdcnfg
@
ldr r2, =MDCNFG_VAL
@ disable all sdram banks
@
bic r2, r2, #(MDCNFG_DE0 | MDCNFG_DE1)
bic r2, r2, #(MDCNFG_DE2 | MDCNFG_DE3)
@ program banks 0/1 for bus width
@
bic r2, r2, #MDCNFG_DWID0 @0=32-bit
@ write initial value of mdcnfg, w/o enabling sdram banks
@
str r2, [r1, #MDCNFG_OFFSET]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -