完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
最近在弄一个SD卡启动u-boot,但是不知道为什么只能用2G但是4G的SD卡无法启动u-boot。希望得到帮助,谢谢。下面把相关代码贴出来:
start.S文件: /* * ARMboot - Startup Code for S3C6400/ARM1176 CPU-core * * Copyright (c) 2007 Samsung Electronics * * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com) * 2007-09-21 - Added moviNAND and OneNAND boot codes by jsgood (jsgood.yang@samsung.com) * Base codes by scsuh (sc.suh) */ #include #include #ifdef CONFIG_ENABLE_MMU #include #endif #include #ifndef CONFIG_ENABLE_MMU #ifndef CFG_PHY_UBOOT_BASE #define CFG_PHY_UBOOT_BASE CFG_UBOOT_BASE #endif #endif /* ************************************************************************* * * Jump vector table as in table 3.1 in [1] * ************************************************************************* */ .globl _start _start: b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort ldr pc, _data_abort ldr pc, _not_used ldr pc, _irq ldr pc, _fiq _undefined_instruction: .word undefined_instruction _software_interrupt: .word software_interrupt _prefetch_abort: .word prefetch_abort _data_abort: .word data_abort _not_used: .word not_used _irq: .word irq _fiq: .word fiq _pad: .word 0x12345678 /* now 16*4=64 */ .global _end_vect _end_vect: .balignl 16,0xdeadbeef /* ************************************************************************* * * Startup Code (reset vector) * * do important init only if we don't start from memory! * setup Memory and board specific bits prior to relocation. * relocate armboot to ram * setup stack * ************************************************************************* */ _TEXT_BASE: .word TEXT_BASE /* * Below variable is very important because we use MMU in U-Boot. * Without it, we cannot run code correctly before MMU is ON. * by scsuh. */ _TEXT_PHY_BASE: .word CFG_PHY_UBOOT_BASE .globl _armboot_start _armboot_start: .word _start /* * These are defined in the board-specific linker script. */ .globl _bss_start _bss_start: .word __bss_start .globl _bss_end _bss_end: .word _end #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ .globl IRQ_STACK_START IRQ_STACK_START: .word 0x0badc0de /* IRQ stack memory (calculated at run-time) */ .globl FIQ_STACK_START FIQ_STACK_START: .word 0x0badc0de #endif /* * the actual reset code */ reset: /* * set the cpu to SVC32 mode */ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0 /* ************************************************************************* * * CPU_init_critical registers * * setup important registers * setup memory timing * ************************************************************************* */ /* * we do sys-critical inits only at reboot, * not when booting from ram! */ cpu_init_crit: /* * flush v4 I/D caches */ mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ /* * disable MMU stuff and caches */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) orr r0, r0, #0x00000002 @ set bit 2 (A) Align orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache mcr p15, 0, r0, c1, c0, 0 /* Peri port setup */ ldr r0, =0x70000000 orr r0, r0, #0x13 mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff) #ifdef CONFIG_BOOT_ONENAND ldr r0, =0x70000000 @ onenand controller setup orr r0, r0, #0x100000 ldr r1, =0x4000 orr r1, r1, #0xe0 str r1, [r0] #if defined(CONFIG_S3C6410) || defined(CONFIG_S3C6430) orr r0, r0, #300 @ disable watchdog mov r1, #1 str r1, [r0] mov r1, #0x23000000 @ start buffer register orr r1, r1, #0x30000 orr r1, r1, #0xc800 #else mov r1, =0x20000000 @ start buffer register orr r1, r1, #0xc30000 orr r1, r1, #0xc800 #endif sub r0, r1, #0x0400 @ start address1 register ldr r2, [r1, #0x84] @ ecc bypass orr r2, r2, #0x100 str r2, [r1, #0x84] mov r3, #0x0 @ DFS, FBA str r3, [r0, #0x00] str r3, [r0, #0x04] @ select dataram for DDP as 0 mov r4, #0x104 @ interrupt register mov r5, #0x0002 @ FPA, FSA mov r6, #0x0800 @ BSA onenand_bl1_load: str r5, [r0, #0x1c] @ save FPA, FSA orr r6, r6, #0x02 @ BSC str r6, [r1, #0x00] @ save BSA, BSC str r3, [r1, r4] @ clear interrupt str r3, [r1, #0x80] @ write load command mov r7, #0x100 @ need small delay onenand_wait_loop1: subs r7, r7, #0x1 bne onenand_wait_loop1 add r5, r5, #0x2 @ next FPA, FSA sub r6, r6, #0x2 add r6, r6, #0x200 @ next BSA cmp r5, #0x8 bne onenand_bl1_load #endif /* * Go setup Memory and board specific bits prior to relocation. */ bl lowlevel_init /* go setup pll,mux,memory */ /* when we already run in ram, we don't need to relocate U-Boot. * and actually, memory controller must be configured before U-Boot * is running in ram. */ ldr r0, =0xff000fff bic r1, pc, r0 /* r0 <- current base addr of code */ ldr r2, _TEXT_BASE /* r1 <- original base addr in ram */ bic r2, r2, r0 /* r0 <- current base addr of code */ cmp r1, r2 /* compare r0, r1 */ beq after_copy /* r0 == r1 then skip flash copy */ #ifdef CONFIG_BOOT_NOR /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ ldr r1, _TEXT_PHY_BASE /* r1 <- destination */ ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 /* r2 <- size of armboot */ add r2, r0, r2 /* r2 <- source end address */ nor_copy_loop: ldmia r0!, {r3-r10} /* copy from source address [r0] */ stmia r1!, {r3-r10} /* copy to target address [r1] */ cmp r0, r2 /* until source end addreee [r2] */ ble nor_copy_loop b after_copy #endif #ifdef CONFIG_BOOT_NAND mov r0, #0x1000 bl copy_from_nand #endif #ifdef CONFIG_BOOT_MOVINAND ldr sp, _TEXT_PHY_BASE bl movi_bl2_copy b after_copy #endif #ifdef CONFIG_BOOT_ONENAND ldr sp, =0x50000000 @ temporary stack #ifdef CONFIG_S3C6400 mov r1, =0x20000000 @ start buffer register orr r1, r1, #0xc30000 orr r1, r1, #0xc800 #else mov r1, #0x23000000 @ start buffer register orr r1, r1, #0x30000 orr r1, r1, #0xc800 #endif ldr r2, [r1, #0x84] @ ecc bypass orr r2, r2, #0x100 str r2, [r1, #0x84] sub r0, r1, #0x0400 @ start address1 register str r3, [r0, #0x00] str r3, [r0, #0x04] @ select dataram for DDP as 0 mov r4, #0x104 @ interrupt register mov r6, #0x0c00 @ fixed dataram1 sector number str r6, [r1, #0x00] mov r3, #0x0 @ DFS, FBA mov r5, #0x0000 @ FPA, FSA ldr r9, =CFG_PHY_UBOOT_BASE @ destination onenand_bl2_load: str r3, [r0, #0x00] @ save DFS, FBA str r5, [r0, #0x1c] @ save FPA, FSA mov r7, #0x0 @ clear interrupt str r7, [r1, r4] str r7, [r1, #0x80] @ write load command mov r8, #0x1000 onenand_wait_loop2: subs r8, r8, #0x1 bne onenand_wait_loop2 onenand_wait_int: @ wait INT and RI ldr r7, [r1, r4] mov r8, #0x8000 orr r8, r8, #0x80 tst r7, r8 beq onenand_wait_int mov r7, #0x0 @ clear interrupt str r7, [r1, r4] mov r8, #0xc00 @ source address (dataram1) mov r10, #0x40 @ copy loop count (64 = 2048 / 32) stmia sp, {r0-r7} @ backup onenand_copy_to_ram: ldmia r8!, {r0-r7} stmia r9!, {r0-r7} subs r10, r10, #0x1 bne onenand_copy_to_ram ldmia sp, {r0-r7} @ restore add r5, r5, #0x4 @ next FPA cmp r5, #0x100 @ last FPA? bne onenand_bl2_load /* next block */ mov r5, #0x0 @ reset FPA add r3, r3, #0x1 @ next FBA cmp r3, #0x2 @ last FBA? bne onenand_bl2_load b after_copy #endif #ifdef CONFIG_BOOT_ONENAND_IROM ldr sp, _TEXT_PHY_BASE bl onenand_bl2_copy b after_copy #endif after_copy: #ifdef CONFIG_ENABLE_MMU enable_mmu: /* enable domain access */ ldr r5, =0x0000ffff mcr p15, 0, r5, c3, c0, 0 @ load domain access register /* Set the TTB register */ ldr r0, _mmu_table_base ldr r1, =CFG_PHY_UBOOT_BASE ldr r2, =0xfff00000 bic r0, r0, r2 orr r1, r0, r1 mcr p15, 0, r1, c2, c0, 0 /* Enable the MMU */ mmu_on: mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #1 /* Set CR_M to enable MMU */ mcr p15, 0, r0, c1, c0, 0 nop nop nop nop #endif skip_hw_init: /* Set up the stack */ stack_setup: #ifdef CONFIG_MEMORY_UPPER_CODE ldr sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0xc) #else ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ #ifdef CONFIG_USE_IRQ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ #endif clear_bss: ldr r0, _bss_start /* find start of bss segment */ ldr r1, _bss_end /* stop here */ mov r2, #0x00000000 /* clear */ clbss_l: str r2, [r0] /* clear loop... */ add r0, r0, #4 cmp r0, r1 ble clbss_l ldr pc, _start_armboot _start_armboot: .word start_armboot #ifdef CONFIG_ENABLE_MMU _mmu_table_base: .word mmu_table #endif /* * copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND) * r0: size to be compared * Load 1'st 2blocks to RAM because U-boot's size is larger than 1block(128k) size */ .globl copy_from_nand copy_from_nand: mov r10, lr /* save return address */ mov r9, r0 /* get ready to call C functions */ ldr sp, _TEXT_PHY_BASE /* setup temp stack pointer */ sub sp, sp, #12 mov fp, #0 /* no previous frame, so fp=0 */ mov r9, #0x1000 bl copy_uboot_to_ram 3: tst r0, #0x0 bne copy_failed ldr r0, =0x0c000000 ldr r1, _TEXT_PHY_BASE 1: ldr r3, [r0], #4 ldr r4, [r1], #4 teq r3, r4 bne compare_failed /* not matched */ subs r9, r9, #4 bne 1b 4: mov lr, r10 /* all is OK */ mov pc, lr copy_failed: nop /* copy from nand failed */ b copy_failed compare_failed: nop /* compare failed */ b compare_failed /* * we assume that cache operation is done before. (eg. cleanup_before_linux()) * actually, we don't need to do anything about cache if not use d-cache in U-Boot * So, in this function we clean only MMU. by scsuh * * void theLastJump(void *kernel, int arch_num, uint boot_params); */ #ifdef CONFIG_ENABLE_MMU .globl theLastJump theLastJump: mov r9, r0 ldr r3, =0xfff00000 ldr r4, _TEXT_PHY_BASE adr r5, phy_last_jump bic r5, r5, r3 orr r5, r5, r4 mov pc, r5 phy_last_jump: /* * disable MMU stuff */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */ bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ mcr p15, 0, r0, c1, c0, 0 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ mov r0, #0 mov pc, r9 #endif /* ************************************************************************* * * Interrupt handling * ************************************************************************* */ @ @ IRQ stack frame. @ #define S_FRAME_SIZE 72 #define S_OLD_R0 68 #define S_PSR 64 #define S_PC 60 #define S_LR 56 #define S_SP 52 #define S_IP 48 #define S_FP 44 #define S_R10 40 #define S_R9 36 #define S_R8 32 #define S_R7 28 #define S_R6 24 #define S_R5 20 #define S_R4 16 #define S_R3 12 #define S_R2 8 #define S_R1 4 #define S_R0 0 #define MODE_SVC 0x13 #define I_BIT 0x80 /* * use bad_save_user_regs for abort/prefetch/undef/swi ... * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling */ .macro bad_save_user_regs sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 ldr r2, _armboot_start sub r2, r2, #(CFG_MALLOC_LEN) sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs) add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack add r5, sp, #S_SP mov r1, lr stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr mov r0, sp @ save current stack into r0 (param register) .endm .macro irq_save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0-r12 add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. stmdb r8, {sp, lr}^ @ Calling SP, LR str lr, [r8, #0] @ Save calling PC mrs r6, spsr str r6, [r8, #4] @ Save CPSR str r0, [r8, #8] @ Save OLD_R0 mov r0, sp .endm .macro irq_restore_user_regs ldmia sp, {r0 - lr}^ @ Calling r0 - lr mov r0, r0 ldr lr, [sp, #S_PC] @ Get PC add sp, sp, #S_FRAME_SIZE subs pc, lr, #4 @ return & move spsr_svc into cpsr .endm .macro get_bad_stack ldr r13, _armboot_start @ setup our mode stack (enter in banked mode) sub r13, r13, #(CFG_MALLOC_LEN) @ move past malloc pool sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack str lr, [r13] @ save caller lr in position 0 of saved stack mrs lr, spsr @ get the spsr str lr, [r13, #4] @ save spsr in position 1 of saved stack mov r13, #MODE_SVC @ prepare SVC-Mode @ msr spsr_c, r13 msr spsr, r13 @ switch modes, make sure moves will execute mov lr, pc @ capture return pc movs pc, lr @ jump to next instruction & switch modes. .endm .macro get_bad_stack_swi sub r13, r13, #4 @ space on current stack for scratch reg. str r0, [r13] @ save R0's value. ldr r0, _armboot_start @ get data regions start sub r0, r0, #(CFG_MALLOC_LEN) @ move past malloc pool sub r0, r0, #(CFG_GBL_DATA_SIZE+8) @ move past gbl and a couple spots for abort stack str lr, [r0] @ save caller lr in position 0 of saved stack mrs r0, spsr @ get the spsr str lr, [r0, #4] @ save spsr in position 1 of saved stack ldr r0, [r13] @ restore r0 add r13, r13, #4 @ pop stack entry .endm .macro get_irq_stack @ setup IRQ stack ldr sp, IRQ_STACK_START .endm .macro get_fiq_stack @ setup FIQ stack ldr sp, FIQ_STACK_START .endm /* * exception handlers */ .align 5 undefined_instruction: get_bad_stack bad_save_user_regs bl do_undefined_instruction .align 5 software_interrupt: get_bad_stack_swi bad_save_user_regs bl do_software_interrupt .align 5 prefetch_abort: get_bad_stack bad_save_user_regs bl do_prefetch_abort .align 5 data_abort: get_bad_stack bad_save_user_regs bl do_data_abort .align 5 not_used: get_bad_stack bad_save_user_regs bl do_not_used #ifdef CONFIG_USE_IRQ .align 5 irq: get_irq_stack irq_save_user_regs bl do_irq irq_restore_user_regs .align 5 fiq: get_fiq_stack /* someone ought to write a more effiction fiq_save_user_regs */ irq_save_user_regs bl do_fiq irq_restore_user_regs #else .align 5 irq: get_bad_stack bad_save_user_regs bl do_irq .align 5 fiq: get_bad_stack bad_save_user_regs bl do_fiq #endif .align 5 .global arm1136_cache_flush arm1136_cache_flush: mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache mov pc, lr @ back to caller #if defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_CINTEGRATOR) /* Use the IntegratorCP function from board/integratorcp/platform.S */ #elif defined(CONFIG_S3C64XX) /* For future usage of S3C64XX*/ #else .align 5 .globl reset_cpu reset_cpu: ldr r1, rstctl /* get addr for global reset reg */ mov r3, #0x2 /* full reset pll+mpu */ str r3, [r1] /* force reset */ mov r0, r0 _loop_forever: b _loop_forever rstctl: .word PM_RSTCTRL_WKUP #endif movi.c文件: #include #ifdef CONFIG_MOVINAND #if defined(CONFIG_TQ6410) #include #elif defined(CONFIG_SMDK6430) #include #endif #include #include uint movi_hc = 0; void movi_set_capacity(void) { #if defined(CONFIG_S3C6400) if (MOVI_HIGH_CAPACITY == 2) #else if (MOVI_HIGH_CAPACITY & 0x1) #endif movi_hc = 1; } int movi_set_ofs(uint last) { int changed = 0; if (ofsinfo.last != last) { ofsinfo.last = last - (eFUSE_SIZE / MOVI_BLKSIZE); ofsinfo.bl1 = ofsinfo.last - MOVI_BL1_BLKCNT; ofsinfo.env = ofsinfo.bl1 - MOVI_ENV_BLKCNT; ofsinfo.bl2 = ofsinfo.bl1 - (MOVI_BL2_BLKCNT + MOVI_ENV_BLKCNT); ofsinfo.kernel = ofsinfo.bl2 - MOVI_ZIMAGE_BLKCNT; ofsinfo.rootfs = ofsinfo.kernel - MOVI_ROOTFS_BLKCNT; changed = 1; } return changed; } int movi_init(void) { hsmmc_set_gpio(); hsmmc_reset(); if (hsmmc_init()) { printf("nCard Initialization failed.n"); return -1; } return 1; } void movi_write_env(ulong addr) { movi_write((uint)addr, ofsinfo.env, MOVI_ENV_BLKCNT); } void movi_read_env(ulong addr) { movi_read((uint)addr, ofsinfo.env, MOVI_ENV_BLKCNT); } void movi_bl2_copy(void) { #if defined(CONFIG_S3C6400) CopyMovitoMem(MOVI_BL2_POS, MOVI_BL2_BLKCNT, (uint *)BL2_BASE, CONFIG_SYS_CLK_FREQ, MOVI_INIT_REQUIRED); #else writel(readl(HM_CONTROL4) | (0x3 << 16), HM_CONTROL4); CopyMovitoMem(HSMMC_CHANNEL, MOVI_BL2_POS, MOVI_BL2_BLKCNT, (uint *)BL2_BASE, MOVI_INIT_REQUIRED); #endif } #endif hs_mmc.c文件: #include #if defined(CONFIG_SMDK6400) || defined(CONFIG_TQ6410) || defined(CONFIG_SMDK6430) #define CONFIG_SUPPORT_MMC_PLUS #define HCLK_OPERATION #undef DEBUG_HSMMC #ifdef DEBUG_HSMMC #define dbg(x...) printf(x) #else #define dbg(x...) do { } while (0) #endif #include #include #include #include #include #include "hs_mmc.h" #if defined(CONFIG_S3C6400) extern ulong virt_to_phy_smdk6400(ulong addr); #elif defined(CONFIG_S3C6410) extern ulong virt_to_phy_smdk6410(ulong addr); #elif defined(CONFIG_S3C6430) extern ulong virt_to_phy_smdk6430(ulong addr); #endif #define SDI_Tx_buffer_HSMMC (0x51000000) #define SDI_Rx_buffer_HSMMC (0x51000000+(0x300000)) #define SDI_Compare_buffer_HSMMC (0x51000000+(0x600000)) #define Card_OneBlockSize_ver1 512 /* Global variables */ static uint *Tx_buffer_HSMMC; static uint *Rx_buffer_HSMMC; static uint *Compare_buffer_HSMMC; static vu_long rd_cnt_HSMMC; static vu_long wt_cnt_HSMMC; static vu_long BlockNum_HSMMC = 0; static vu_long WriteBlockCnt_INT = 0; static vu_long ReadBlockCnt_INT = 0; static vu_long WRITEINT_DONE = 0; static vu_long READINT_DONE = 0; static vu_long COMPARE_INT_DONE = 0; static vu_long CompareCnt_INT = 0; static vu_long BufferBoundary_INT_Cnt = 0; static vu_long HS_DMA_END = 0; static vu_long HS_CARD_DETECT = 0; static uint ocr_check = 0; static uint mmc_card = 0; static uint rca = 0; static uint mmc_spec, sd_spec; static ulong HCLK; static uint card_mid = 0; /* extern variables */ extern uint movi_hc; /* extern functions */ extern ulong get_HCLK(void); #define s3c_hsmmc_readl(x) readl((ELFIN_HSMMC_BASE + (HSMMC_CHANNEL * 0x100000)) + (x)) #define s3c_hsmmc_readw(x) readw((ELFIN_HSMMC_BASE + (HSMMC_CHANNEL * 0x100000)) + (x)) #define s3c_hsmmc_readb(x) readb((ELFIN_HSMMC_BASE + (HSMMC_CHANNEL * 0x100000)) + (x)) #define s3c_hsmmc_writel(v,x) writel((v),(ELFIN_HSMMC_BASE + (HSMMC_CHANNEL * 0x100000)) + (x)) #define s3c_hsmmc_writew(v,x) writew((v),(ELFIN_HSMMC_BASE + (HSMMC_CHANNEL * 0x100000)) + (x)) #define s3c_hsmmc_writeb(v,x) writeb((v),(ELFIN_HSMMC_BASE + (HSMMC_CHANNEL * 0x100000)) + (x)) #if 0 static int wait_for_w_buf_ready (void) { uint uLoop = 0; while (!(rHM_NORINTSTS & 0x10)) { if (uLoop % 500000 == 0 && uLoop > 0) { return 0; } uLoop++; } return 1; } #endif static int wait_for_r_buf_ready (void) { uint uLoop = 0; while (!(s3c_hsmmc_readw(HM_NORINTSTS) & 0x20)) { if (uLoop % 500000 == 0 && uLoop > 0) { return 0; } uLoop++; } return 1; } static int wait_for_cmd_done (void) { uint i; ushort n_int, e_int; udelay(5000); dbg("wait_for_cmd_donen"); for (i = 0; i < 0x20000000; i++) { n_int = s3c_hsmmc_readw(HM_NORINTSTS); dbg(" HM_NORINTSTS: %04xn", n_int); if (n_int & 0x8000) break; if (n_int & 0x0001) return 0; } e_int = s3c_hsmmc_readw(HM_ERRINTSTS); s3c_hsmmc_writew(e_int, HM_ERRINTSTS); s3c_hsmmc_writew(n_int, HM_NORINTSTS); dbg("cmd error1: 0x%04x, HM_NORINTSTS: 0x%04xn", e_int, n_int); return 1; } /* XXX: must modify algorithm. it has bugs. by scsuh */ static int wait_for_data_done (void) { while (!(s3c_hsmmc_readw(HM_NORINTSTS) & 0x2)) return 1; return 0; } static void ClearCommandCompleteStatus(void) { s3c_hsmmc_writew(1 << 0, HM_NORINTSTS); while (s3c_hsmmc_readw(HM_NORINTSTS) & 0x1) { s3c_hsmmc_writew(1 << 0, HM_NORINTSTS); } } static void ClearTransferCompleteStatus(void) { s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTS) | (1 << 1), HM_NORINTSTS); while (s3c_hsmmc_readw(HM_NORINTSTS) & 0x2) { s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTS) | (1 << 1), HM_NORINTSTS); } } #if 0 static void ClearBufferWriteReadyStatus(void) { rHM_NORINTSTS |= (1 << 4); while (rHM_NORINTSTS & 0x10) rHM_NORINTSTS |= (1 << 4); } #endif static void ClearBufferReadReadyStatus(void) { s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTS) | (1 << 5), HM_NORINTSTS); while (s3c_hsmmc_readw(HM_NORINTSTS) & 0x20) s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTS) | (1 << 5), HM_NORINTSTS); } #if 0 static void HS_MMC_CardDetect(void) { rGPJCON = (rGPJCON & ~(0x3 << 28)) | (1 << 29); //rHM_CONTROL2 |= (1<<13)|(1<<12);/* Card Detect using a DAT[3] signal */ rHM_NORINTSTSEN |= (1 << 7) | (1 << 6); rHM_NORINTSIGEN |= (1 << 7) | (1 << 6); if (rHM_PRNSTS & (1 << 16)) { HS_CARD_DETECT = 1; printf("nCard is Insertedn"); } while (!HS_CARD_DETECT) { printf("nInsert a Cardn"); HS_CARD_DETECT = 0; do { printf("."); udelay(500000); } while (HS_CARD_DETECT == 0); } HS_CARD_DETECT = 0; rHM_CONTROL2 &= ~(1 << 13); } #endif static void card_irq_enable(ushort temp) { s3c_hsmmc_writew((s3c_hsmmc_readw(HM_NORINTSTSEN) & 0xFEFF) | (temp << 8), HM_NORINTSTSEN); } void hsmmc_reset (void) { s3c_hsmmc_writeb(0x3, HM_SWRST); } void hsmmc_set_gpio (void) { u32 reg; #if (HSMMC_CHANNEL == 0) reg = readl(GPGCON) & 0xf0000000; writel(reg | 0x02222222, GPGCON); reg = readl(GPGPUD) & 0xfffff000; writel(reg, GPGPUD); #elif (HSMMC_CHANNEL == 1) writel(0x00222222, GPHCON0); writel(0x00000000, GPHCON1); reg = readl(GPHPUD) & 0xfffff000; writel(reg, GPHPUD); #else printf("### HS-MMC channel is not defined!n"); #endif } static void set_transfer_mode_register (uint MultiBlk, uint DataDirection, uint AutoCmd12En, uint BlockCntEn, uint DmaEn) { s3c_hsmmc_writew((s3c_hsmmc_readw(HM_TRNMOD) & ~(0xffff)) | (MultiBlk << 5) | (DataDirection << 4) | (AutoCmd12En << 2) | (BlockCntEn << 1) | (DmaEn << 0), HM_TRNMOD); dbg("nHM_TRNMOD = 0x%04xn", HM_TRNMOD); } static void set_arg_register (uint arg) { s3c_hsmmc_writel(arg, HM_ARGUMENT); } static void set_blkcnt_register(ushort uBlkCnt) { s3c_hsmmc_writew(uBlkCnt, HM_BLKCNT); } static void SetSystemAddressReg(uint SysAddr) { s3c_hsmmc_writel(SysAddr, HM_SYSAD); } static void set_blksize_register(ushort uDmaBufBoundary, ushort uBlkSize) { s3c_hsmmc_writew((uDmaBufBoundary << 12) | (uBlkSize), HM_BLKSIZE); } static void ClearErrInterruptStatus(void) { while (s3c_hsmmc_readw(HM_NORINTSTS) & (0x1 << 15)) { s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTS), HM_NORINTSTS); s3c_hsmmc_writew(s3c_hsmmc_readw(HM_ERRINTSTS), HM_ERRINTSTS); } } static void InterruptEnable(ushort NormalIntEn, ushort ErrorIntEn) { ClearErrInterruptStatus(); s3c_hsmmc_writew(NormalIntEn, HM_NORINTSTSEN); s3c_hsmmc_writew(ErrorIntEn, HM_ERRINTSTSEN); } static void hsmmc_clock_onoff (int on) { u16 reg16; if (on == 0) { reg16 = s3c_hsmmc_readw(HM_CLKCON) & ~(0x1<<2); s3c_hsmmc_writew(reg16, HM_CLKCON); } else { reg16 = s3c_hsmmc_readw(HM_CLKCON); s3c_hsmmc_writew(reg16 | (0x1<<2), HM_CLKCON); while (1) { reg16 = s3c_hsmmc_readw(HM_CLKCON); if (reg16 & (0x1<<3)) /* SD_CLKSRC is Stable */ break; } } } static void set_clock (uint clksrc, uint div) { u16 reg16; uint i; #if defined(CONFIG_S3C6400) s3c_hsmmc_writel(0xC0000100 | (clksrc << 4), HM_CONTROL2); // feedback control off s3c_hsmmc_writel(0x00000000, HM_CONTROL3); #else s3c_hsmmc_writel(0xC0004100 | (clksrc << 4), HM_CONTROL2); // rx feedback control s3c_hsmmc_writel(0x00008080, HM_CONTROL3); // Low clock: 00008080 s3c_hsmmc_writel(0x3 << 16, HM_CONTROL4); #endif s3c_hsmmc_writew(s3c_hsmmc_readw(HM_CLKCON) & ~(0xff << 8), HM_CLKCON); /* SDCLK Value Setting + Internal Clock Enable */ s3c_hsmmc_writew(((div<<8) | 0x1), HM_CLKCON); /* CheckInternalClockStable */ for (i=0; i<0x10000; i++) { reg16 = s3c_hsmmc_readw(HM_CLKCON); if (reg16 & 0x2) break; } if (i == 0x10000) printf("internal clock stabilization failedn"); dbg("HM_CONTROL2(0x80) = 0x%08xn", s3c_hsmmc_readl(HM_CONTROL2)); dbg("HM_CONTROL3(0x84) = 0x%08xn", s3c_hsmmc_readl(HM_CONTROL3)); dbg("HM_CLKCON (0x2c) = 0x%04xn", s3c_hsmmc_readw(HM_CLKCON)); hsmmc_clock_onoff(1); } static void set_cmd_register (ushort cmd, uint data, uint flags) { ushort val = (cmd << 8); if (cmd == 12) val |= (3 << 6); if (flags & MMC_RSP_136) /* Long RSP */ val |= 0x01; else if (flags & MMC_RSP_BUSY) /* R1B */ val |= 0x03; else if (flags & MMC_RSP_PRESENT) /* Normal RSP */ val |= 0x02; if (flags & MMC_RSP_OPCODE) val |= (1<<4); if (flags & MMC_RSP_CRC) val |= (1<<3); if (data) val |= (1<<5); dbg("cmdreg = 0x%04xn", val); s3c_hsmmc_writew(val, HM_CMDREG); } static int issue_command (ushort cmd, uint arg, uint data, uint flags) { int i; dbg("### issue_command: %d, %08x, %d, %08xn", cmd, arg, data, flags); /* Check CommandInhibit_CMD */ for (i=0; i<0x1000000; i++) { if (!(s3c_hsmmc_readl(HM_PRNSTS) & 0x1)) break; } if (i == 0x1000000) { printf("@@@@@@1 rHM_PRNSTS: %08lxn", s3c_hsmmc_readl(HM_PRNSTS)); } /* Check CommandInhibit_DAT */ if (flags & MMC_RSP_BUSY) { for (i=0; i<0x1000000; i++) { if (!(s3c_hsmmc_readl(HM_PRNSTS) & 0x2)) break; } if (i == 0x1000000) { printf("@@@@@@2 rHM_PRNSTS: %08lxn", s3c_hsmmc_readl(HM_PRNSTS)); } } s3c_hsmmc_writel(arg, HM_ARGUMENT); set_cmd_register(cmd, data, flags); if (wait_for_cmd_done()) return 0; ClearCommandCompleteStatus(); if (!(s3c_hsmmc_readw(HM_NORINTSTS) & 0x8000)) { return 1; } else { if (ocr_check == 1) return 0; else { printf("Command = %d, Error Stat = 0x%04xn", (s3c_hsmmc_readw(HM_CMDREG) >> 8), s3c_hsmmc_readw(HM_ERRINTSTS)); return 0; } } } static void set_mmc_speed (uint eSDSpeedMode) { uint ucSpeedMode, arg; ucSpeedMode = (eSDSpeedMode == HIGH) ? 1 : 0; arg = (3 << 24) | (185 << 16) | (ucSpeedMode << 8); /* Change to the high-speed mode */ while (!issue_command(MMC_SWITCH, arg, 0, MMC_RSP_R1B)); } static void set_sd_speed (uint eSDSpeedMode) { uint temp; uint arg = 0; uchar ucSpeedMode; int i; ucSpeedMode = (eSDSpeedMode == HIGH) ? 1 : 0; if (!issue_command(MMC_SET_BLOCKLEN, 64, 0, MMC_RSP_R1)) { printf("CMD16 failn"); } else { set_blksize_register(7, 64); set_blkcnt_register(1); set_arg_register(0 * 64); set_transfer_mode_register(0, 1, 0, 0, 0); arg = (0x1 << 31) | (0xffff << 8) | (ucSpeedMode << 0); if (!issue_command(MMC_SWITCH, arg, 0, MMC_RSP_R1B)) printf("CMD6 failn"); else { wait_for_r_buf_ready(); ClearBufferReadReadyStatus(); for (i = 0; i < 16; i++) { temp = s3c_hsmmc_readl(HM_BDATA); } if (!wait_for_data_done()) printf(("Transfer NOT Completen")); ClearTransferCompleteStatus(); } } } static int get_sd_scr (void) { uint uSCR1, uSCR2; if (!issue_command(MMC_SET_BLOCKLEN, 8, 0, MMC_RSP_R1)) return 0; else { set_blksize_register(7, 8); set_blkcnt_register(1); set_arg_register(0 * 8); set_transfer_mode_register(0, 1, 0, 0, 0); if (!issue_command(MMC_APP_CMD, rca<<16, 0, MMC_RSP_R1)) return 0; else { if (!issue_command(SD_APP_SEND_SCR, 0, 1, MMC_RSP_R1)) return 0; else { wait_for_r_buf_ready(); ClearBufferReadReadyStatus(); uSCR1 = s3c_hsmmc_readl(HM_BDATA); uSCR2 = s3c_hsmmc_readl(HM_BDATA); if (!wait_for_data_done()) printf(("Transfer NOT Completen")); ClearTransferCompleteStatus(); if (uSCR1 & 0x1) sd_spec = 1; /* Version 1.10, support cmd6 */ else sd_spec = 0; /* Version 1.0 ~ 1.01 */ dbg("sd_spec = %d(0x%08x)n", sd_spec, uSCR1); return 1; } } } } static int check_card_status(void) { if (!issue_command(MMC_SEND_STATUS, rca<<16, 0, MMC_RSP_R1)) { return 0; } else { if (((s3c_hsmmc_readl(HM_RSPREG0) >> 9) & 0xf) == 4) { dbg("Card is transfer statusn"); return 1; } } return 1; } static void set_hostctl_speed (uchar mode) { u8 reg8; reg8 = s3c_hsmmc_readb(HM_HOSTCTL) & ~(0x1<<2); s3c_hsmmc_writeb(reg8 | (mode<<2), HM_HOSTCTL); } /* return 0: OK * return -1: error */ static int set_bus_width (uint width) { uint arg = 0; uchar reg = s3c_hsmmc_readb(HM_HOSTCTL); uchar bitmode = 0; dbg("bus width: %dn", width); switch (width) { case 8: width = mmc_card ? 8 : 4; break; case 4: case 1: break; default: return -1; } card_irq_enable(0); // Disable sd card interrupt if (mmc_card) { /* MMC Card */ /* MMC Spec 4.x or above */ if (mmc_spec == 4) { if (width == 1) bitmode = 0; else if (width == 4) bitmode = 1; else if (width == 8) bitmode = 2; else { printf("#### unknown moden"); return -1; } arg = ((3 << 24) | (183 << 16) | (bitmode << 8)); while (!issue_command(MMC_SWITCH, arg, 0, MMC_RSP_R1B)); } else bitmode = 0; } else { /* SD Card */ if (!issue_command(MMC_APP_CMD, rca<<16, 0, MMC_RSP_R1)) return -1; else { if (width == 1) { // 1-bits bitmode = 0; if (!issue_command(MMC_SWITCH, 0, 0, MMC_RSP_R1B)) return -1; } else { // 4-bits bitmode = 1; if (!issue_command(MMC_SWITCH, 2, 0, MMC_RSP_R1B)) return -1; } } } if (bitmode == 2) reg |= 1 << 5; else reg |= bitmode << 1; s3c_hsmmc_writeb(reg, HM_HOSTCTL); card_irq_enable(1); dbg(" transfer rHM_HOSTCTL(0x28) = 0x%02xn", s3c_hsmmc_readb(HM_HOSTCTL)); return 0; } static int set_sd_ocr (void) { uint i, ocr; issue_command(MMC_APP_CMD, 0x0, 0, MMC_RSP_R1); issue_command(SD_APP_OP_COND, 0x0, 0, MMC_RSP_R3); ocr = s3c_hsmmc_readl(HM_RSPREG0); dbg("ocr1: %08xn", ocr); for (i = 0; i < 250; i++) { issue_command(MMC_APP_CMD, 0x0, 0, MMC_RSP_R1); issue_command(SD_APP_OP_COND, ocr, 0, MMC_RSP_R3); ocr = s3c_hsmmc_readl(HM_RSPREG0); dbg("ocr2: %08xn", ocr); if (ocr & (0x1 << 31)) { dbg("Voltage range: "); if (ocr & (1 << 21)) dbg("2.7V ~ 3.4V"); else if (ocr & (1 << 20)) dbg("2.7V ~ 3.3V"); else if (ocr & (1 << 19)) dbg("2.7V ~ 3.2V"); else if (ocr & (1 << 18)) dbg("2.7V ~ 3.1V"); if (ocr & (1 << 7)) dbg(", 1.65V ~ 1.95Vn"); else dbg('n'); mmc_card = 0; return 1; } udelay(1000); } // The current card is MMC card, then there's time out error, need to be cleared. ClearErrInterruptStatus(); return 0; } static int set_mmc_ocr (void) { uint i, ocr; for (i = 0; i < 250; i++) { issue_command(MMC_SEND_OP_COND, 0x40FF8000, 0, MMC_RSP_R3); ocr = s3c_hsmmc_readl(HM_RSPREG0); dbg("ocr1: %08xn", ocr); if (ocr & (0x1 << 31)) { dbg("Voltage range: "); if (ocr & (1 << 21)) dbg("2.7V ~ 3.4V"); else if (ocr & (1 << 20)) dbg("2.7V ~ 3.3V"); else if (ocr & (1 << 19)) dbg("2.7V ~ 3.2V"); else if (ocr & (1 << 18)) dbg("2.7V ~ 3.1V"); mmc_card = 1; if (ocr & (1 << 7)) dbg(", 1.65V ~ 1.95Vn"); else dbg('n'); return 1; } } // The current card is SD card, then there's time out error, need to be cleared. ClearErrInterruptStatus(); return 0; } #ifdef CONFIG_SUPPORT_MMC_PLUS static void clock_config (uint clksrc, uint div) { uint base_freq = 0, freq; if (clksrc == SD_HCLK) base_freq = HCLK; else if (clksrc == SD_EPLL) /* Epll Out 48MHz */ base_freq = 100000000; else clksrc = HCLK; freq = base_freq / (div * 2); dbg("freq = %dMHzn", freq / (1000000)); if (mmc_card) { if (mmc_spec == 4) { /* It is necessary to enable the high speed mode * in the card before changing the clock freq * to a freq higher than 20MHz. */ if (freq > 20000000) { set_mmc_speed(HIGH); dbg("Set MMC High speed mode OK!!n"); } else { set_mmc_speed(NORMAL); dbg("Set MMC Normal speed mode OK!!n"); } } else // old version dbg("Old version MMC card can not support working frequency higher than 20MHzn"); } else { get_sd_scr(); if (sd_spec == 1) { if (freq > 25000000) { set_sd_speed(HIGH); //Higher than 25MHz, should use high speed mode. Max 50MHz and 25MB/sec dbg("Set SD High speed mode OK!!n"); } else { set_sd_speed(NORMAL); dbg("Set SD Normal speed mode OK!!n"); } } else dbg("Old version SD card can not support working frequency higher than 25MHzn"); } /* When Higher than 25MHz, it is necessary * to enable high speed mode of the host controller. */ if (freq > 25000000) { set_hostctl_speed(HIGH); } else { set_hostctl_speed(NORMAL); } /* when change the sd clock frequency, need to stop sd clock. */ hsmmc_clock_onoff(1); set_clock(clksrc, div); dbg("clock config rHM_HOSTCTL(0x28) = 0x%02xn", s3c_hsmmc_readb(HM_HOSTCTL)); } #else static void clock_config (uint clksrc, uint Divisior) { uint SrcFreq, WorkingFreq; if (clksrc == SD_HCLK) base_freq = HCLK; else if (clksrc == SD_EPLL) /* Epll Out 48MHz */ base_freq = 100000000; else clksrc = HCLK; WorkingFreq = SrcFreq / (Divisior * 2); printf("Card Working Frequency = %dMHzn", WorkingFreq / (1000000)); if (mmc_card) { if (mmc_spec == 4) { if (WorkingFreq > 20000000) { // It is necessary to enable the high speed mode in the card before changing the clock freq to a freq higher than 20MHz. set_mmc_speed(HIGH); printf("nSet MMC High speed mode OK!!n"); } else { set_mmc_speed(NORMAL); printf("nSet MMC Normal speed mode OK!!n"); } } else // old version printf("Old version MMC card can not support working frequency higher than 25MHz"); } if (WorkingFreq > 25000000) { // Higher than 25MHz, it is necessary to enable high speed mode of the host controller. set_hostctl_speed(HIGH); } else { set_hostctl_speed(NORMAL); } hsmmc_clock_onoff(0); // when change the sd clock frequency, need to stop sd clock. set_clock(clksrc, Divisior); printf("clock config rHM_HOSTCTL = 0x%02xn", s3c_hsmmc_readb(HM_HOSTCTL)); } #endif static void check_dma_int (void) { uint i; for (i = 0; i < 0x10000000; i++) { if (s3c_hsmmc_readw(HM_NORINTSTS) & 0x0002) { dbg("Transfer Completen"); HS_DMA_END = 1; s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTS) | 0x0002, HM_NORINTSTS); break; } if (s3c_hsmmc_readw(HM_NORINTSTS) & 0x8000) { printf("error found: %04xn", s3c_hsmmc_readw(HM_ERRINTSTS)); break; } } } static uint process_ext_csd (void) { u8 ext_csd[512]; memset(ext_csd, 0, sizeof(ext_csd)); if (ext_csd >= (u8 *)0xc0000000) SetSystemAddressReg(virt_to_phys((ulong)ext_csd)); else SetSystemAddressReg((ulong)ext_csd); set_blksize_register(7, 512); set_blkcnt_register(1); set_transfer_mode_register(0, 1, 0, 1, 1); while(!issue_command(MMC_SEND_EXT_CSD, 0, 1, MMC_RSP_R1 | MMC_CMD_ADTC)); check_dma_int(); while (!HS_DMA_END); return (((ext_csd[215] << 24) | (ext_csd[214] << 16) | (ext_csd[213] << 8) | ext_csd[212]) / (2 * 1024)); } static void display_card_info (void) { uint card_size; if (mmc_card && movi_hc) { card_size = process_ext_csd(); } else { uint i, resp[4]; uint c_size, c_size_multi, read_bl_len, read_bl_partial, blk_size; for (i=0; i<4; i++) { resp = s3c_hsmmc_readl(HM_RSPREG0+i*4); dbg("%08xn", resp); } read_bl_len = ((resp[2] >> 8) & 0xf); read_bl_partial = ((resp[2] >> 7) & 0x1); blk_size = (1 << read_bl_len); dbg(" read_bl_len: %dn", read_bl_len); dbg(" read_bl_partial: %dn", read_bl_partial); dbg(" One Block Size: %d Byten", blk_size); if (movi_hc) { card_size = ((resp[1] >> 8) & 0x3fffff) / 2; } else { c_size_multi = ((resp[1] >> 7) & 0x7); c_size = ((resp[2] & 0x3) << 10) | ((resp[1] >> 22) & 0x3ff); card_size = (1 << read_bl_len) * (c_size + 1) * (1 << (c_size_multi + 2)) / 1048576; dbg(" c_size: %dn", c_size); dbg(" c_size_multi: %dn", c_size_multi); } dbg(" Total Card Size: %d MBytenn", card_size + 1); } // printf("%d MB ", card_size + 1); if (!mmc_card && movi_hc) printf("(SDHC)"); if (card_mid == 0x15) printf("(moviNAND)"); // printf("n"); } static void DataRead_ForCompare (int StartAddr) { uint i = 0, j = 0; COMPARE_INT_DONE = 0; s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSIGEN) & ~(0xffff), HM_NORINTSIGEN); Compare_buffer_HSMMC = (uint *) SDI_Compare_buffer_HSMMC; for (i = 0; i < (512 * BlockNum_HSMMC) / 4; i++) *(Compare_buffer_HSMMC + i) = 0x0; dbg("Polling mode data read1n"); dbg("Read BlockNum = %dn", BlockNum_HSMMC); while (!check_card_status()); /* Maximum DMA Buffer Size, Block Size */ set_blksize_register(7, 512); /* Block Numbers to Write */ set_blkcnt_register(BlockNum_HSMMC); if (movi_hc) set_arg_register(StartAddr); else set_arg_register(StartAddr * 512); if (BlockNum_HSMMC == 1) { dbg("Single block readn"); set_transfer_mode_register(0, 1, 1, 1, 0); /* MMC_READ_SINGLE_BLOCK */ set_cmd_register(17, 1, MMC_RSP_R1); } else { dbg("Multi block readn"); set_transfer_mode_register(1, 1, 1, 1, 0); /* MMC_READ_MULTIPLE_BLOCK */ set_cmd_register(18, 1, MMC_RSP_R1); } if (wait_for_cmd_done()) { printf("Command is NOT completed1n"); } ClearCommandCompleteStatus(); for (j = 0; j < BlockNum_HSMMC; j++) { if (!wait_for_r_buf_ready()) printf("ReadBuffer NOT Readyn"); else ClearBufferReadReadyStatus(); for (i = 0; i < 512 / 4; i++) { *Compare_buffer_HSMMC++ = s3c_hsmmc_readl(HM_BDATA); CompareCnt_INT++; } } dbg("Read count=0x%08xn", CompareCnt_INT); if (!wait_for_data_done()) { printf(("Transfer NOT Completen")); } ClearTransferCompleteStatus(); dbg("nnHM_NORINTSTS = %x", s3c_hsmmc_readw(HM_NORINTSTS)); } static void DataCompare_HSMMC (uint a0, uint a1, uint bytes) { uint *pD0 = (uint *) a0; uint *pD1 = (uint *) a1; uint ErrCnt = 0; uint i; for (i = 0; i < bytes; i++) { if (*pD0 != *pD1) { dbg("n%08x=%02x <-> %08x=%02x", pD0, *pD0, pD1, *pD1); ErrCnt++; } pD0++; pD1++; } dbg("nTotal Error cnt = %d", ErrCnt); if (ErrCnt == 0) dbg("nData Compare Okn"); } int hsmmc_init (void) { u32 reg; uint width; width = 4; HCLK = get_HCLK(); dbg("HCLK = %08lun", HCLK); hsmmc_clock_onoff(0); reg = readl(SCLK_GATE); writel(reg | (1<<27), SCLK_GATE); set_clock(SD_EPLL, 0x80); s3c_hsmmc_writeb(0xe, HM_TIMEOUTCON); set_hostctl_speed(NORMAL); InterruptEnable(0xff, 0xff); dbg("HM_NORINTSTS = %xn", s3c_hsmmc_readw(HM_NORINTSTS)); /* MMC_GO_IDLE_STATE */ issue_command(MMC_GO_IDLE_STATE, 0x00, 0, 0); ocr_check = 1; if (set_mmc_ocr()) { mmc_card = 1; dbg("MMC card is detectedn"); } else if (set_sd_ocr()) { mmc_card = 0; dbg("SD card is detectedn"); } else { printf("0 MBn"); return 0; } ocr_check = 0; /* Check the attached card and place the card * in the IDENT state rHM_RSPREG0 */ issue_command(MMC_ALL_SEND_CID, 0, 0, MMC_RSP_R2); /* Manufacturer ID */ card_mid = (s3c_hsmmc_readl(HM_RSPREG3) >> 16) & 0xFF; dbg("Product Name : %c%c%c%c%c%cn", ((s3c_hsmmc_readl(HM_RSPREG2) >> 24) & 0xFF), ((s3c_hsmmc_readl(HM_RSPREG2) >> 16) & 0xFF), ((s3c_hsmmc_readl(HM_RSPREG2) >> 8) & 0xFF), (s3c_hsmmc_readl(HM_RSPREG2) & 0xFF), ((s3c_hsmmc_readl(HM_RSPREG1) >> 24) & 0xFF), ((s3c_hsmmc_readl(HM_RSPREG1) >> 16) & 0xFF)); // Send RCA(Relative Card Address). It places the card in the STBY state rca = (mmc_card) ? 0x0001 : 0x0000; issue_command(MMC_SET_RELATIVE_ADDR, rca<<16, 0, MMC_RSP_R1); if (!mmc_card) rca = (s3c_hsmmc_readl(HM_RSPREG0) >> 16) & 0xFFFF; dbg("Enter to the Stand-by Staten"); issue_command(MMC_SEND_CSD, rca<<16, 0, MMC_RSP_R2); if (mmc_card) { mmc_spec = (s3c_hsmmc_readl(HM_RSPREG3) >> 18) & 0xF; dbg("mmc_spec=%dn", mmc_spec); } issue_command(MMC_SELECT_CARD, rca<<16, 0, MMC_RSP_R1); dbg("Enter to the Transfer Staten"); display_card_info(); /* Operating Clock setting */ clock_config(SD_EPLL, 2); // Divisor 1 = Base clk /2 ,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ... while (set_bus_width(width)); while (!check_card_status()); /* MMC_SET_BLOCKLEN */ while (!issue_command(MMC_SET_BLOCKLEN, 512, 0, MMC_RSP_R1)); s3c_hsmmc_writew(0xffff, HM_NORINTSTS); return 0; } void movi_write (uint addr, uint start_blk, uint blknum) { uint blksize; wt_cnt_HSMMC = 0; BlockNum_HSMMC = 0; wt_cnt_HSMMC = 0; WriteBlockCnt_INT = 0; HS_DMA_END = 0; BlockNum_HSMMC = blknum; blksize = Card_OneBlockSize_ver1; s3c_hsmmc_writew((s3c_hsmmc_readw(HM_NORINTSTSEN) & ~(0xffff)) | BUFFER_READREADY_STS_INT_EN | BUFFER_WRITEREADY_STS_INT_EN | TRANSFERCOMPLETE_STS_INT_EN | COMMANDCOMPLETE_STS_INT_EN, HM_NORINTSTSEN); s3c_hsmmc_writew((s3c_hsmmc_readw(HM_NORINTSIGEN) & ~(0xffff)) | TRANSFERCOMPLETE_SIG_INT_EN, HM_NORINTSIGEN); SetSystemAddressReg(addr); // AHB System Address For Write set_blksize_register(7, 512); // Maximum DMA Buffer Size, Block Size set_blkcnt_register(BlockNum_HSMMC); // Block Numbers to Write if (movi_hc) set_arg_register(start_blk); else set_arg_register(start_blk * 512); if (BlockNum_HSMMC == 1) { set_transfer_mode_register(0, 0, 1, 1, 1); set_cmd_register(24, 1, MMC_RSP_R1); } else { set_transfer_mode_register(1, 0, 1, 1, 1); set_cmd_register(25, 1, MMC_RSP_R1); } if (wait_for_cmd_done()) { printf("nCommand is NOT completed3n"); } ClearCommandCompleteStatus(); /* wait for DMA transfer */ check_dma_int(); while (!HS_DMA_END); if (!wait_for_data_done()) { printf(("Transfer is NOT Completen")); } ClearTransferCompleteStatus(); s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTS) | (1 << 3), HM_NORINTSTS); BlockNum_HSMMC = 0; wt_cnt_HSMMC = 0; WriteBlockCnt_INT = 0; HS_DMA_END = 0; BufferBoundary_INT_Cnt = 0; CompareCnt_INT = 0; Compare_buffer_HSMMC = 0; } void movi_read (uint addr, uint start_blk, uint blknum) { uint blksize; //j, , Addr_temp = start_blk; uint dma = 0, cmd, multi; //, TotalReadByte, read_blk_cnt = 0; rd_cnt_HSMMC = 0; HS_DMA_END = 0; BlockNum_HSMMC = 0; rd_cnt_HSMMC = 0; ReadBlockCnt_INT = 0; BlockNum_HSMMC = blknum; blksize = Card_OneBlockSize_ver1; while (!check_card_status()); s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTSEN) & ~(DMA_STS_INT_EN | BLOCKGAP_EVENT_STS_INT_EN), HM_NORINTSTSEN); s3c_hsmmc_writew((HM_NORINTSIGEN & ~(0xffff)) | TRANSFERCOMPLETE_SIG_INT_EN, HM_NORINTSIGEN); SetSystemAddressReg(addr); // AHB System Address For Write dma = 1; set_blksize_register(7, 512); // Maximum DMA Buffer Size, Block Size set_blkcnt_register(BlockNum_HSMMC); // Block Numbers to Write if (movi_hc) set_arg_register(start_blk); // Card Start Block Address to Write else set_arg_register(start_blk * 512); // Card Start Block Address to Write cmd = (blknum > 1) ? 18 : 17; multi = (blknum > 1); set_transfer_mode_register(multi, 1, multi, 1, dma); set_cmd_register(cmd, 1, MMC_RSP_R1); if (wait_for_cmd_done()) { printf(("Command NOT Completen")); } else ClearCommandCompleteStatus(); check_dma_int(); while (!HS_DMA_END); dbg(("nDMA Read Endn")); HS_DMA_END = 0; BlockNum_HSMMC = 0; rd_cnt_HSMMC = 0; ReadBlockCnt_INT = 0; } static void write_test (uint test, uint start_blk, uint blknum) { uint i, blksize; //j, uint uTxBufAddr = SDI_Tx_buffer_HSMMC; uint uCompareBufAddr = SDI_Compare_buffer_HSMMC; wt_cnt_HSMMC = 0; BlockNum_HSMMC = 0; wt_cnt_HSMMC = 0; WriteBlockCnt_INT = 0; HS_DMA_END = 0; printf("nHS-MMC block Write test: %d, 0x%x 0x%xn", test, start_blk, blknum); BlockNum_HSMMC = blknum; blksize = Card_OneBlockSize_ver1; Tx_buffer_HSMMC = (uint *) SDI_Tx_buffer_HSMMC; for (i = 0; i < (blksize * BlockNum_HSMMC) / 4; i++) { *(Tx_buffer_HSMMC + i) = ((start_blk<<16) + i); } printf("## using DMAn"); s3c_hsmmc_writew((s3c_hsmmc_readw(HM_NORINTSTSEN) & ~(0xffff)) | BUFFER_READREADY_STS_INT_EN | BUFFER_WRITEREADY_STS_INT_EN | TRANSFERCOMPLETE_STS_INT_EN | COMMANDCOMPLETE_STS_INT_EN, HM_NORINTSTSEN); s3c_hsmmc_writew((s3c_hsmmc_readw(HM_NORINTSIGEN) & ~(0xffff)) | TRANSFERCOMPLETE_SIG_INT_EN, HM_NORINTSIGEN); SetSystemAddressReg(SDI_Tx_buffer_HSMMC); // AHB System Address For Write set_blksize_register(7, 512); // Maximum DMA Buffer Size, Block Size set_blkcnt_register(BlockNum_HSMMC); // Block Numbers to Write if (movi_hc) set_arg_register(start_blk); // Card Start Block Address to Write else set_arg_register(start_blk * 512); // Card Start Block Address to Write if (BlockNum_HSMMC == 1) { set_transfer_mode_register(0, 0, 1, 1, 1); set_cmd_register(24, 1, MMC_RSP_R1); } else { set_transfer_mode_register(1, 0, 1, 1, 1); set_cmd_register(25, 1, MMC_RSP_R1); } if (wait_for_cmd_done()) { printf("nCommand is NOT completed3n"); } ClearCommandCompleteStatus(); /* wait for DMA transfer */ check_dma_int(); while (!HS_DMA_END); if (!wait_for_data_done()) { printf(("Transfer is NOT Completen")); } ClearTransferCompleteStatus(); s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTS) | (1 << 3), HM_NORINTSTS); printf(("nDMA Write Endn")); DataRead_ForCompare(start_blk); DataCompare_HSMMC(uTxBufAddr, uCompareBufAddr, BlockNum_HSMMC * 128); BlockNum_HSMMC = 0; wt_cnt_HSMMC = 0; WriteBlockCnt_INT = 0; HS_DMA_END = 0; BufferBoundary_INT_Cnt = 0; CompareCnt_INT = 0; Compare_buffer_HSMMC = 0; } static void read_test (uint test, uint start_blk, uint blknum) { uint i, blksize; //j, , Addr_temp = start_blk; uint dma = 0, cmd, multi; //, TotalReadByte, read_blk_cnt = 0; rd_cnt_HSMMC = 0; HS_DMA_END = 0; BlockNum_HSMMC = 0; rd_cnt_HSMMC = 0; ReadBlockCnt_INT = 0; printf("nHS-MMC block Read test: %d, 0x%x 0x%xn", test, start_blk, blknum); BlockNum_HSMMC = blknum; blksize = Card_OneBlockSize_ver1; Rx_buffer_HSMMC = (uint *) SDI_Rx_buffer_HSMMC; for (i = 0; i < (blksize * BlockNum_HSMMC) / 4; i++) *(Rx_buffer_HSMMC + i) = 0x0; while (!check_card_status()); s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTSEN) & ~(DMA_STS_INT_EN | BLOCKGAP_EVENT_STS_INT_EN), HM_NORINTSTSEN); s3c_hsmmc_writew((HM_NORINTSIGEN & ~(0xffff)) | TRANSFERCOMPLETE_SIG_INT_EN, HM_NORINTSIGEN); SetSystemAddressReg(SDI_Rx_buffer_HSMMC); // AHB System Address For Write dma = 1; set_blksize_register(7, 512); // Maximum DMA Buffer Size, Block Size set_blkcnt_register(BlockNum_HSMMC); // Block Numbers to Write if (movi_hc) set_arg_register(start_blk); // Card Start Block Address to Write else set_arg_register(start_blk * 512); // Card Start Block Address to Write cmd = (blknum > 1) ? 18 : 17; multi = (blknum > 1); set_transfer_mode_register(multi, 1, multi, 1, dma); set_cmd_register(cmd, 1, MMC_RSP_R1); if (wait_for_cmd_done()) { printf(("Command NOT Completen")); } else ClearCommandCompleteStatus(); check_dma_int(); while (!HS_DMA_END); printf(("nDMA Read Endn")); HS_DMA_END = 0; BlockNum_HSMMC = 0; rd_cnt_HSMMC = 0; ReadBlockCnt_INT = 0; } void test_hsmmc (uint width, uint test, uint start_blk, uint blknum) { hsmmc_set_gpio(); #if 0 HS_MMC_CardDetect(); #endif hsmmc_reset(); if (hsmmc_init()) { printf("nCard Initialization FAILEDn"); } memset((ulong *)0x51300000, 0, 0x100000); memset((ulong *)0x51000000, 0, 0x100000); memset((ulong *)0x51600000, 0, 0x100000); write_test(test, start_blk, blknum); read_test(test, start_blk, blknum); } #endif smdk6410.h文件: /* * (C) Copyright 2002 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Marius Groeger <mgroeger@sysgo.de> * Gary Jennejohn <gj@denx.de> * David Mueller <d.mueller@elsoft.ch> * * Configuation settings for the SAMSUNG SMDK6400(mDirac-III) board. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #ifndef __CONFIG_H #define __CONFIG_H /* * High Level Configuration Options * (easy to change) */ #define CONFIG_S3C6410 1 /* in a SAMSUNG S3C6410 SoC */ #define CONFIG_S3C64XX 1 /* in a SAMSUNG S3C64XX Family */ #define CONFIG_SMDK6410 1 /* on a SAMSUNG SMDK6410 Board */ //#define CONFIG_SMDK6410_X5A 1 /* on a SAMSUNG SMDK6410 OneNAND POP Board */ #define MEMORY_BASE_ADDRESS 0x50000000 /* input clock of PLL */ #define CONFIG_SYS_CLK_FREQ 12000000 /* the SMDK6400 has 12MHz input clock */ #define CONFIG_ENABLE_MMU #ifdef CONFIG_ENABLE_MMU #define virt_to_phys(x) virt_to_phy_smdk6410(x) #else #define virt_to_phys(x) (x) #endif #define CONFIG_MEMORY_UPPER_CODE #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ #define CONFIG_INCLUDE_TEST #define CONFIG_ZIMAGE_BOOT #define CONFIG_IMAGE_BOOT #define BOARD_LATE_INIT #define CONFIG_SETUP_MEMORY_TAGS #define CONFIG_CMDLINE_TAG #define CONFIG_INITRD_TAG /* * Architecture magic and machine type */ #define MACH_TYPE 1626 #define UBOOT_MAGIC (0x43090000 | MACH_TYPE) /* Power Management is enabled */ #define CONFIG_PM #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO #undef CONFIG_SKIP_RELOCATE_UBOOT #undef CONFIG_USE_NOR_BOOT /* * Size of malloc() pool */ //jkeqiang change it to avoid stack flow #define CFG_MALLOC_LEN (CFG_ENV_SIZE + 512*1024) //#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 1024*1024) #define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ #define CFG_STACK_SIZE 512*1024 /* * Hardware drivers */ //#define CONFIG_DRIVER_SMC911X 1 /* we have a SMC9115 on-board */ //#define CONFIG_CH7033 #ifdef CONFIG_DRIVER_SMC911X #undef CONFIG_DRIVER_CS8900 #define CONFIG_DRIVER_SMC911X_BASE 0x18800300 #else #define CONFIG_DRIVER_CS8900 0 /* we have a CS8900 on-board */ #define CS8900_BASE 0x18800300 #define CS8900_BUS16 1 /* the Linux driver does accesses as shorts */ #endif /* * select serial console configuration */ #define CONFIG_SERIAL1 1 /* we use SERIAL 1 on SMDK6400 */ #define CFG_HUSH_PARSER /* use "hush" command parser */ #ifdef CFG_HUSH_PARSER #define CFG_PROMPT_HUSH_PS2 "> " #endif #define CONFIG_CMDLINE_EDITING //#undef CONFIG_S3C64XX_I2C /* this board has H/W I2C */ #define CONFIG_S3C64XX_I2C /*add by phantom*/ #ifdef CONFIG_S3C64XX_I2C #define CONFIG_HARD_I2C 1 #define CFG_I2C_SPEED 10000 #define CFG_I2C_SLAVE 0xFE #endif #define CONFIG_DOS_PARTITION #define CONFIG_SUPPORT_VFAT #define CONFIG_USB_OHCI #undef CONFIG_USB_STORAGE #define CONFIG_S3C_USBD #define USBD_DOWN_ADDR 0xc0000000 /************************************************************ * RTC ************************************************************/ #define CONFIG_RTC_S3C64XX 1 /* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE #define CONFIG_BAUDRATE 115200 /*********************************************************** * Command definition ***********************************************************/ #define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_CACHE | CFG_CMD_USB | CFG_CMD_REGINFO | CFG_CMD_LOADS | CFG_CMD_LOADB | CFG_CMD_ENV | CFG_CMD_NAND | CFG_CMD_MOVINAND| CFG_CMD_ONENAND | CFG_CMD_DATE | CFG_CMD_PING | CFG_CMD_ELF) & ~(CFG_CMD_AUTOSCRIPT | CFG_CMD_BOOTD | CFG_CMD_IMI | CFG_CMD_RUN | CFG_CMD_CONSOLE | CFG_CMD_DOCG3P3 | CFG_CMD_EEPROM | CFG_CMD_I2C | 0) /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include #define CONFIG_BOOTDELAY 1 //#define CONFIG_BOOTARGS "root=/dev/mtdblock2 rootfstype=yaffs2 console=tty0 console=ttySAC0,115200" #define CONFIG_BOOTARGS "root=/dev/mtdblock2 rootfstype=cramfs console=ttySAC0,115200" #define CONFIG_ETHADDR 00:40:5c:26:0a:5b #define CONFIG_NETMASK 255.255.255.0 #define CONFIG_IPADDR 192.168.1.20 #define CONFIG_SERVERIP 192.168.1.10 #define CONFIG_GATEWAYIP 192.168.1.1 #define CONFIG_ZERO_BOOTDELAY_CHECK /*#define CONFIG_NET_MULTI 1 */ #if (CONFIG_COMMANDS & CFG_CMD_KGDB) #define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */ /* what's this ? it's not used anywhere */ #define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */ #endif /* * Miscellaneous configurable options */ #define CFG_LONGHELP /* undef to save memory */ #define CFG_PROMPT "SMDK6410 # " /* Monitor Command Prompt */ #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ #define CFG_PBSIZE 384 /* Print Buffer Size */ #define CFG_MAXARGS 16 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ #define CFG_MEMTEST_START MEMORY_BASE_ADDRESS /* memtest works on */ #define CFG_MEMTEST_END MEMORY_BASE_ADDRESS + 0x7e00000 /* 128 MB in DRAM */ #undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ #define CFG_LOAD_ADDR MEMORY_BASE_ADDRESS /* default load address */ /* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */ /* it to wrap 100 times (total 1562500) to get 1 sec. */ #define CFG_HZ 1562500 // at PCLK 50MHz /* valid baudrates */ #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } /*----------------------------------------------------------------------- * Stack sizes * * The stack sizes are set up in start.S using the settings below */ #define CONFIG_STACKSIZE 0x40000 /* regular stack 256KB */ #ifdef CONFIG_USE_IRQ #define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ #define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ #endif //#define CONFIG_CLK_800_133_66 //#define CONFIG_CLK_666_133_66 #define CONFIG_CLK_532_133_66 //#define CONFIG_CLK_400_133_66 //#define CONFIG_CLK_400_100_50 //#define CONFIG_CLK_OTHERS #define CONFIG_CLKSRC_CLKUART #define set_pll(mdiv, pdiv, sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv) #if defined(CONFIG_CLK_666_133_66) /* FIN 12MHz, Fout 666MHz */ #define APLL_MDIV 333 #define APLL_PDIV 3 #define APLL_SDIV 1 #undef CONFIG_SYNC_MODE /* ASYNC MODE */ #elif defined(CONFIG_CLK_532_133_66) /* FIN 12MHz, Fout 532MHz */ #define APLL_MDIV 266 #define APLL_PDIV 3 #define APLL_SDIV 1 #define CONFIG_SYNC_MODE #elif defined(CONFIG_CLK_400_133_66) || defined(CONFIG_CLK_800_133_66) /* FIN 12MHz, Fout 800MHz */ #define APLL_MDIV 400 #define APLL_PDIV 3 #define APLL_SDIV 1 #define CONFIG_SYNC_MODE #elif defined(CONFIG_CLK_400_100_50) /* FIN 12MHz, Fout 400MHz */ #define APLL_MDIV 400 #define APLL_PDIV 3 #define APLL_SDIV 2 #define CONFIG_SYNC_MODE #elif defined(CONFIG_CLK_OTHERS) /*If you have to use another value, please define pll value here*/ /* FIN 12MHz, Fout 532MHz */ #define APLL_MDIV 266 #define APLL_PDIV 3 #define APLL_SDIV 1 #define CONFIG_SYNC_MODE #else #error "Not Support Fequency or Mode!! you have to setup right configuration." #endif #define CONFIG_UART_66 /* default clock value of CLK_UART */ #define APLL_VAL set_pll(APLL_MDIV, APLL_PDIV, APLL_SDIV) /* prevent overflow */ #define Startup_APLL (CONFIG_SYS_CLK_FREQ/(APLL_PDIV< /* fixed MPLL 533MHz */ #define MPLL_MDIV 266 #define MPLL_PDIV 3 #define MPLL_SDIV 1 #define MPLL_VAL set_pll(MPLL_MDIV, MPLL_PDIV, MPLL_SDIV) /* prevent overflow */ #define Startup_MPLL ((CONFIG_SYS_CLK_FREQ)/(MPLL_PDIV< #if defined(CONFIG_CLK_800_133_66) #define Startup_APLLdiv 0 #define Startup_HCLKx2div 2 #elif defined(CONFIG_CLK_400_133_66) #define Startup_APLLdiv 1 #define Startup_HCLKx2div 2 #else #define Startup_APLLdiv 0 #define Startup_HCLKx2div 1 #endif #define Startup_PCLKdiv 3 #define Startup_HCLKdiv 1 #define Startup_MPLLdiv 1 #define CLK_DIV_VAL ((Startup_PCLKdiv<<12)|(Startup_HCLKx2div<<9)|(Startup_HCLKdiv<<8)|(Startup_MPLLdiv<<4)|Startup_APLLdiv) #if defined(CONFIG_SYNC_MODE) #define Startup_HCLK (Startup_APLL/(Startup_HCLKx2div+1)/(Startup_HCLKdiv+1)) #else #define Startup_HCLK (Startup_MPLL/(Startup_HCLKx2div+1)/(Startup_HCLKdiv+1)) #endif /*----------------------------------------------------------------------- * Physical Memory Map */ #ifndef CONFIG_SMDK6410_X5A //#define DMC1_MEM_CFG 0x00010012 /* Supports one CKE control, Chip1, Burst4, Row/Column bit */ #define DMC1_MEM_CFG 0x0001001a /* Supports one CKE control, Chip1, Burst4, Row/Column bit */ #define DMC1_MEM_CFG2 0xB45 //#define DMC1_CHIP0_CFG 0x150F8 #define DMC1_CHIP0_CFG 0x150F0 #define DMC_DDR_32_CFG 0x0 /* 32bit, DDR */ /* Memory Parameters */ /* DDR Parameters */ #define DDR_tREFRESH 7800 /* ns */ #define DDR_tRAS 45 /* ns (min: 45ns)*/ #define DDR_tRC 68 /* ns (min: 67.5ns)*/ #define DDR_tRCD 23 /* ns (min: 22.5ns)*/ #define DDR_tRFC 80 /* ns (min: 80ns)*/ #define DDR_tRP 23 /* ns (min: 22.5ns)*/ #define DDR_tRRD 15 /* ns (min: 15ns)*/ #define DDR_tWR 15 /* ns (min: 15ns)*/ #define DDR_tXSR 120 /* ns (min: 120ns)*/ #define DDR_CASL 3 /* CAS Latency 3 */ #else #define DMC1_MEM_CFG 0x00210011 /* Supports one CKE control, Chip1, Burst4, Row/Column bit */ #define DMC1_MEM_CFG2 0xB41 #define DMC1_CHIP0_CFG 0x150FC #define DMC1_CHIP1_CFG 0x154FC #define DMC_DDR_32_CFG 0x0 /* 32bit, DDR */ /* Memory Parameters */ /* DDR Parameters */ #define DDR_tREFRESH 5865 /* ns */ #define DDR_tRAS 50 /* ns (min: 45ns)*/ #define DDR_tRC 68 /* ns (min: 67.5ns)*/ #define DDR_tRCD 23 /* ns (min: 22.5ns)*/ #define DDR_tRFC 133 /* ns (min: 80ns)*/ #define DDR_tRP 23 /* ns (min: 22.5ns)*/ #define DDR_tRRD 20 /* ns (min: 15ns)*/ #define DDR_tWR 20 /* ns (min: 15ns)*/ #define DDR_tXSR 125 /* ns (min: 120ns)*/ #define DDR_CASL 3 /* CAS Latency 3 */ #endif /* * mDDR memory configuration */ #define DMC_DDR_BA_EMRS 2 #define DMC_DDR_MEM_CASLAT 3 #define DMC_DDR_CAS_LATENCY (DDR_CASL<<1) //6 Set Cas Latency to 3 #define DMC_DDR_t_DQSS 1 // Min 0.75 ~ 1.25 #define DMC_DDR_t_MRD 2 //Min 2 tck #define DMC_DDR_t_RAS (((Startup_HCLK / 1000 * DDR_tRAS) - 1) / 1000000 + 1) //7, Min 45ns #define DMC_DDR_t_RC (((Startup_HCLK / 1000 * DDR_tRC) - 1) / 1000000 + 1) //10, Min 67.5ns #define DMC_DDR_t_RCD (((Startup_HCLK / 1000 * DDR_tRCD) - 1) / 1000000 + 1) //4,5(TRM), Min 22.5ns #define DMC_DDR_schedule_RCD ((DMC_DDR_t_RCD - 3) << 3) #define DMC_DDR_t_RFC (((Startup_HCLK / 1000 * DDR_tRFC) - 1) / 1000000 + 1) //11,18(TRM) Min 80ns #define DMC_DDR_schedule_RFC ((DMC_DDR_t_RFC - 3) << 5) #define DMC_DDR_t_RP (((Startup_HCLK / 1000 * DDR_tRP) - 1) / 1000000 + 1) //4, 5(TRM) Min 22.5ns #define DMC_DDR_schedule_RP ((DMC_DDR_t_RP - 3) << 3) #define DMC_DDR_t_RRD (((Startup_HCLK / 1000 * DDR_tRRD) - 1) / 1000000 + 1) //3, Min 15ns #define DMC_DDR_t_WR (((Startup_HCLK / 1000 * DDR_tWR) - 1) / 1000000 + 1) //Min 15ns #define DMC_DDR_t_WTR 2 #define DMC_DDR_t_XP 2 //1tck + tIS(1.5ns) #define DMC_DDR_t_XSR (((Startup_HCLK / 1000 * DDR_tXSR) - 1) / 1000000 + 1) //17, Min 120ns #define DMC_DDR_t_ESR DMC_DDR_t_XSR #define DMC_DDR_REFRESH_PRD (((Startup_HCLK / 1000 * DDR_tREFRESH) - 1) / 1000000) // TRM 2656 #define DMC_DDR_USER_CONFIG 1 // 2b01 : mDDR #define CONFIG_NR_DRAM_BANKS 1 /* we have 2 bank of DRAM */ #define PHYS_SDRAM_1 MEMORY_BASE_ADDRESS /* SDRAM Bank #1 */ //#define PHYS_SDRAM_1_SIZE 0x08000000 /* 64 MB */ #define PHYS_SDRAM_1_SIZE 0x10000000 #define CFG_FLASH_BASE 0x00000000 /*----------------------------------------------------------------------- * FLASH and environment organization */ #define CFG_MAX_FLASH_BANKS 0 /* max number of memory banks */ #define CFG_MAX_FLASH_SECT 1024 #define CONFIG_AMD_LV800 #define PHYS_FLASH_SIZE 0x100000 /* timeout values are in ticks */ #define CFG_FLASH_ERASE_TOUT (5*CFG_HZ) /* Timeout for Flash Erase */ #define CFG_FLASH_WRITE_TOUT (5*CFG_HZ) /* Timeout for Flash Write */ #define CFG_ENV_ADDR 0 #define CFG_ENV_SIZE 0x80000 /* Total Size of Environment Sector */ /* * SMDK6400 board specific data */ #define CONFIG_IDENT_STRING " for SMDK6410" /* total memory required by uboot */ #define CFG_UBOOT_SIZE (2*1024*1024) /* base address for uboot */ #ifdef CONFIG_ENABLE_MMU #define CFG_UBOOT_BASE 0xc7e00000 #else #define CFG_UBOOT_BASE 0x57e00000 #endif #define CFG_PHY_UBOOT_BASE MEMORY_BASE_ADDRESS + 0x7e00000 #define CFG_ENV_OFFSET 0x00080000 /* NAND configuration */ #define CFG_MAX_NAND_DEVICE 1 #define CFG_NAND_BASE (0x70200010) #define NAND_MAX_CHIPS 1 #define NAND_DISABLE_CE() (NFCONT_REG |= (1 << 1)) #define NAND_ENABLE_CE() (NFCONT_REG &= ~(1 << 1)) #define NF_TRANSRnB() do { while(!(NFSTAT_REG & (1 << 0))); } while(0) #define CFG_NAND_SKIP_BAD_DOT_I 1 /* ".i" read skips bad blocks */ #define CFG_NAND_WP 1 #define CFG_NAND_YAFFS_WRITE 1 /* support yaffs write */ /* Boot configuration (define only one of next) */ #define CONFIG_BOOT_NAND #define CONFIG_NAND /* * BL1 should be written in the block0 with 8 bit ecc parity codes * Enable this definition if you use iROM-NAND boot */ #define CONFIG_NAND_BL1_8BIT_ECC /* Settings as above boot configuration */ #if defined(CONFIG_BOOT_NAND) #define CFG_ENV_IS_IN_NAND //jkeqiang close it //#define CFG_NAND_LARGEPAGE_SAVEENV #define CFG_NAND_HWECC //#define CFG_NAND_FLASH_BBT #define CONFIG_BOOTCOMMAND "nand read 0xc0008000 0x100000 0x500000;bootm 0xc0008000" #elif defined(CONFIG_BOOT_MOVINAND) #define CFG_ENV_IS_IN_MOVINAND #define CONFIG_BOOTCOMMAND "movi read kernel c0008000;movi read rootfs c0800000;bootm c0008000" #elif defined(CONFIG_BOOT_ONENAND) || defined(CONFIG_BOOT_ONENAND_IROM) #define CFG_ONENAND_BASE (0x70100000) #define CFG_MAX_ONENAND_DEVICE 1 #define CFG_ENV_IS_IN_ONENAND #define CONFIG_BOOTCOMMAND "onenand read c0008000 40000 3c0000;bootm c0008000" #else # error Define one of CONFIG_BOOT_{NAND|MOVINAND|ONENAND|ONENAND_IROM} #endif #endif /* __CONFIG_H */ 请帮助解决,不能用4G的SD卡启动,不知道是什么原因,但是用2G的又可以。 |
|
相关推荐
1个回答
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
197个成员聚集在这个小组
加入小组为什么点亮LED的例子放在NORFlash上跑会出现奇怪的现象?
2161 浏览 6 评论
1968 浏览 5 评论
韦东山老师推出的《玩转ARM裸机实战》课程将帮你以上问题一扫而光!
4524 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-28 20:22 , Processed in 0.826760 second(s), Total 79, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号