int emmc_boot(void) { int ret; current_boot = EMMC_BOOT; ctl_num = 0; sd_init(); REG_MSC_CLKRT(ctl_num) = 1; REG_MSC_LPM(ctl_num) = 1; /* cmd12 reset when we reading or writing from the card, send this cmd */ mmc_cmd(12, 0, 0x1, MSC_CMDAT_RESPONSE_R1); mmc_cmd(0, 0xf0f0f0f0, 0x80, MSC_CMDAT_RESPONSE_NONE); REG_MSC_BLKLEN(ctl_num) = 0x200; REG_MSC_NOB(ctl_num) = (SPL_SIZE + redundancy_size) / 512; mmc_cmd(0, 0xfffffffa, ((MSC_CMDAT_INIT) | (MSC_CMDAT_EXP_BOOT_ACK) | (MSC_CMDAT_BOOT_MODE_A) | (MSC_CMDAT_DATA_EN)), MSC_CMDAT_RESPONSE_NONE); ret = mmc_block_readp(SPL_SIZE + redundancy_size, (u32 *)start_addr); if(!ret){ mmc_cmd(0, 0, 0x0, MSC_CMDAT_RESPONSE_NONE); if (!(REG32(start_addr) == 0x4d53504c)){ return sd_boot(1); } return xfer_d2i(start_addr + jump_offset, SPL_SIZE); }else{ return error_handler(current_boot); } }
int mmc_found(void) { u8 *resp; u32 timeout = 100; DBG("mmc_found\n"); if (ctl_num == 1) return 1; resp = mmc_cmd(1, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3); while (timeout-- && !(resp[4] & 0x80)) { xmdelay(10); resp = mmc_cmd(1, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3); } if (!(resp[4] & 0x80)) return 1; resp = mmc_cmd(2, 0, 0x2, MSC_CMDAT_RESPONSE_R2); resp = mmc_cmd(3, 0x10, 0x1, MSC_CMDAT_RESPONSE_R1); REG_MSC_CLKRT(ctl_num) = 1; resp = mmc_cmd(7, 0x10, 0x1, MSC_CMDAT_RESPONSE_R1); resp = mmc_cmd(6, 0x3b70001, 0x41, MSC_CMDAT_RESPONSE_R1); wait_prog_done(); return 0; }
int sd_found(void) { u8 *resp; u32 cardaddr, timeout = 1000; DBG("sd_found\n"); resp = mmc_cmd(55, 0, 0x1, MSC_CMDAT_RESPONSE_R1); resp = mmc_cmd(41, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3); while (timeout-- && !(resp[4] & 0x80)) { xmdelay(10); resp = mmc_cmd(55, 0, 0x1, MSC_CMDAT_RESPONSE_R1); resp = mmc_cmd(41, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3); } if (!(resp[4] & 0x80)) return 1; resp = mmc_cmd(2, 0, 0x2, MSC_CMDAT_RESPONSE_R2); resp = mmc_cmd(3, 0, 0x6, MSC_CMDAT_RESPONSE_R6); cardaddr = (resp[4] << 8) | resp[3]; rca = cardaddr << 16; REG_MSC_CLKRT(ctl_num) = 1; resp = mmc_cmd(7, rca, 0x1, MSC_CMDAT_RESPONSE_R1); resp = mmc_cmd(55, rca, 0x1, MSC_CMDAT_RESPONSE_R1); resp = mmc_cmd(6, 0, 0x1, MSC_CMDAT_RESPONSE_R1); return 0; }
/* Select the MMC clock frequency */ static int jz_mmc_set_clock(u32 rate) { int clkrt; /* __cpm_select_msc_clk_high will select 48M clock for MMC/SD card * perhaps this will made some card with bad quality init fail,or * bad stabilization. */ if (rate > SD_CLOCK_FAST) { __cpm_select_msc_clk_high(MSC_ID,1); /* select clock source from CPM */ clkrt = jz_mmc_calc_clkrt(0, rate); } else { __cpm_select_msc_clk(MSC_ID,1); /* select clock source from CPM */ clkrt = jz_mmc_calc_clkrt(1, rate); } #ifndef CONFIG_FPGA REG_MSC_CLKRT(MSC_ID) = clkrt; #else REG_MSC_CLKRT(MSC_ID) = 7; #endif return MMC_NO_ERROR; }
int sd_boot(num) { u8 *resp; u32 ret = 0; u32 clk_set = 0, clkrt = 0; DBG("sd_boot\n"); current_boot = SD_BOOT; ctl_num = num; if (ctl_num == 1) REG_CPM_CLKGR &= ~(1 << 11); sd_init(); clk_set = jz_extal / 2; while (200000 < clk_set) { clkrt++; clk_set >>= 1; } if (clkrt > 7) { clkrt = 7; } REG_MSC_CLKRT(ctl_num) = clkrt; REG_MSC_LPM(ctl_num) = 1; /* cmd12 reset when we reading or writing from the card, send this cmd */ resp = mmc_cmd(12, 0, 0x41, MSC_CMDAT_RESPONSE_R1); resp = mmc_cmd(0, 0, 0x80, MSC_CMDAT_RESPONSE_NONE); resp = mmc_cmd(8, 0x1aa, 0x1, MSC_CMDAT_RESPONSE_R1); resp = mmc_cmd(55, 0, 0x1, MSC_CMDAT_RESPONSE_R1); if (resp[0] & 0x20){ if (resp[5] == 0x37){ resp = mmc_cmd(41, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3); if (resp[5] == 0x3f) ret = sd_found(); else ret = mmc_found(); } else { ret = mmc_found(); } } else { ret = mmc_found(); } if (ret) return error_handler(current_boot); ret = mmc_block_read(SPL_SIZE + redundancy_size, (u32 *)start_addr); //SDRAM ADDR if(!ret) { if (!(REG32(start_addr) == 0x4d53504c)) { if (ctl_num == 0) return sd_boot(1); if (ctl_num == 1) return usb_boot(); } else { return xfer_d2i(start_addr + jump_offset, SPL_SIZE); } } else { return error_handler(current_boot); } }