📄 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 memsetupmemsetup: 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 loopEARLY_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 plenty1: 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 + -