summaryrefslogtreecommitdiff
path: root/cpu/arm920t/wmt/mmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/arm920t/wmt/mmc.c')
-rwxr-xr-xcpu/arm920t/wmt/mmc.c2854
1 files changed, 2854 insertions, 0 deletions
diff --git a/cpu/arm920t/wmt/mmc.c b/cpu/arm920t/wmt/mmc.c
new file mode 100755
index 0000000..9782a57
--- /dev/null
+++ b/cpu/arm920t/wmt/mmc.c
@@ -0,0 +1,2854 @@
+/*++
+Copyright (c) 2013 WonderMedia Technologies, Inc.
+
+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, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+4F, 531-1, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+/*
+ * (C) Copyright 2003
+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
+ *
+ * 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
+ */
+
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <asm/errno.h>
+#include <asm/arch/hardware.h>
+#include <part.h>
+#include "ttype.h"
+#include "./sdc.h"
+#include <asm-arm/arch-wmt/common_def.h>
+#include "../../../board/wmt/include/wmt_clk.h"
+/*#define CONFIG_MMC*/
+
+#ifdef CONFIG_MMC
+/***********************************************************************************/
+#define BA_SDC_1 0xD800A400 /* SD Controller Base Address */
+#define BA_SDCDMA_1 0xD800A500 /* SD Controller DMA Base Address */
+#define BA_SDC 0xD800A000 /* SD Controller Base Address */
+#define BA_SDCDMA 0xD800A100 /* SD Controller DMA Base Address */
+#define BA_SDC_2 0xD800A800 /* SD Controller Base Address */
+#define BA_SDCDMA_2 0xD800A900 /* SD Controller DMA Base Address */
+
+
+#define SDMMC_SET_BLKSIZE(pHC, b) {pHC->blklen &= 0xF800; pHC->blklen |= ((b) & 0x7FF); }
+
+/* PMC module reg */
+#define PMC_BASE_ADDR 0XD8130000
+#define PMC_SD1_CLK REG32_PTR(PMC_BASE_ADDR + 0x324)
+#define PMC_SD_CLK REG32_PTR(PMC_BASE_ADDR + 0x328)
+#define PMC_Enable_SD_CLK REG32_PTR(PMC_BASE_ADDR + 0x254)
+#define PMC_PLLB_MULTIPLIER REG32_PTR(PMC_BASE_ADDR + 0x204)
+#define PMC_SD_CLOCK_EN 0x40000
+
+/* GPIO module reg */
+#define GPIO_BASE_ADDR 0xD8110000
+#define GPIO_SD_ENABLE REG32_PTR(GPIO_BASE_ADDR + 0x40)
+
+
+PWMT_SDMMC_REG pSd_Reg = (PWMT_SDMMC_REG) BA_SDC;
+struct _SD_PDMA_REG_ *pSd_PDma_Reg = (struct _SD_PDMA_REG_ *) BA_SDCDMA;
+PGPIO_REG GpioReg = (PGPIO_REG) GPIO_BASE_ADDR;
+/*static unsigned long RCA;*/
+sd_info_t *SDDevInfo;
+sd_info_t SD0DevInfo;
+sd_info_t SD1DevInfo;
+sd_info_t SD2DevInfo;
+
+static unsigned int Bitmode ;
+static unsigned short chip_id;
+static block_dev_desc_t *mmc_dev;
+static block_dev_desc_t mmc0_dev;
+static block_dev_desc_t mmc1_dev;
+static block_dev_desc_t mmc2_dev;
+
+static int mmc_ready;
+static int mmc0_ready;
+static int mmc1_ready;
+static int mmc2_ready;
+
+#define SDPRINTK(x...) do { } while (0)/*printf(x)*/
+extern int auto_pll_divisor(enum dev_id dev, enum clk_cmd cmd, int unit, int freq);
+
+/**********************************************************************************/
+int sd_command(unsigned char command, unsigned char cmdtype, unsigned int arg, unsigned char rsptype);
+int sd_config_pdma(unsigned long *DescAddr, char dir);
+unsigned int get_chip_version(void);
+
+void Change_SD_host(int host_num)
+{
+ switch (host_num) {
+ case 0:
+ pSd_Reg = (PWMT_SDMMC_REG) BA_SDC;
+ pSd_PDma_Reg = (struct _SD_PDMA_REG_ *) BA_SDCDMA;
+ SDDevInfo = &SD0DevInfo;
+ mmc_dev = &mmc0_dev;
+ mmc_ready = mmc0_ready;
+ break;
+ case 1:
+ if (chip_id == 0x3437 ||
+ chip_id == 0x3429 ||
+ chip_id == 0x3451 ||
+ chip_id == 0x3445 ||
+ chip_id == 0x3481 ||
+ chip_id == 0x3498) {
+
+ pSd_Reg = (PWMT_SDMMC_REG) BA_SDC_1;
+ pSd_PDma_Reg = (struct _SD_PDMA_REG_ *) BA_SDCDMA_1;
+ SDDevInfo = &SD1DevInfo;
+ mmc_dev = &mmc1_dev;
+ mmc_ready = mmc1_ready;
+ }
+ break;
+ case 2:
+ if (chip_id == 0x3445 ||
+ chip_id == 0x3481 ||
+ chip_id == 0x3498) {
+
+ pSd_Reg = (PWMT_SDMMC_REG) BA_SDC_2;
+ pSd_PDma_Reg = (struct _SD_PDMA_REG_ *) BA_SDCDMA_2;
+ SDDevInfo = &SD2DevInfo;
+ mmc_dev = &mmc2_dev;
+ mmc_ready = mmc2_ready;
+ }
+ break;
+ default:
+ break;
+ }
+}
+int SD_Init_PDMA(void)
+{
+ pSd_PDma_Reg->DMA_GCR = SD_PDMA_GCR_SOFTRESET;
+ pSd_PDma_Reg->DMA_GCR = SD_PDMA_GCR_DMA_EN;
+ if (pSd_PDma_Reg->DMA_GCR & SD_PDMA_GCR_DMA_EN)
+ return 0;
+ else
+ return 1;
+}
+
+int PrintPDMAReg(void)
+{
+ printf("0x00 =%x\n", pSd_PDma_Reg->DMA_GCR);
+ printf("0x04 =%x\n", pSd_PDma_Reg->DMA_IER);
+ printf("0x08 =%x\n", pSd_PDma_Reg->DMA_ISR);
+ printf("0x0C =%x\n", pSd_PDma_Reg->DMA_DESPR);
+ printf("0x10 =%x\n", pSd_PDma_Reg->DMA_RBR);
+ printf("0x14 =%x\n", pSd_PDma_Reg->DMA_DAR);
+ printf("0x18 =%x\n", pSd_PDma_Reg->DMA_BAR);
+ printf("0x1C =%x\n", pSd_PDma_Reg->DMA_CPR);
+ printf("0x20 =%x\n", pSd_PDma_Reg->DMA_CCR);
+}
+
+/* Check Align problem. if brffer size have no align, break up a descript
+ into two descripts for Align problem using AXI bus.*/
+int sd_check_long_desc(unsigned long *DescAddr, int Desc_num, unsigned int ReqCount,
+ unsigned long *BufferAddr, unsigned long *BranchAddr, int End)
+{
+ unsigned long first_size, second_size;
+ SDPRINTK("\nDescAddr=0x%x, Desc_num=%d, ReqCount=%d,\
+ BufferAddr=0x%x, BranchAddr=0x%x, End=%d\n",
+ DescAddr, Desc_num, ReqCount, BufferAddr, BranchAddr, End);
+
+ first_size = (unsigned long)BufferAddr % 0x1000;
+ first_size = 0x1000 - first_size;
+
+ SDPRINTK("firstsize=%d, buf+first 0x%x, sizeof=0x%x\n",
+ first_size,
+ (unsigned int)BufferAddr + first_size,
+ sizeof(struct _SD_PDMA_DESC_L));
+
+ if ((ReqCount > first_size) && (Desc_num > 1)) {
+ sd_init_long_desc(DescAddr, first_size, BufferAddr, BranchAddr, 0);
+ second_size = ReqCount - first_size;
+ sd_init_long_desc(BranchAddr, second_size, ((unsigned int)BufferAddr + first_size),
+ (unsigned int)BranchAddr + sizeof(struct _SD_PDMA_DESC_L), 1);
+ } else {
+ sd_init_long_desc(DescAddr, ReqCount, BufferAddr, BranchAddr, 1);
+ }
+
+ return 0;
+}
+
+int sd_init_long_desc(unsigned long *DescAddr, unsigned int ReqCount,
+ unsigned long *BufferAddr, unsigned long *BranchAddr, int End)
+{
+ struct _SD_PDMA_DESC_L *CurDes_L;
+ CurDes_L = (struct _SD_PDMA_DESC_L *) DescAddr;
+ /*Bug, Fix by leoli @2009.4 */
+ CurDes_L->ReqCount = (u16) ReqCount;
+ CurDes_L->i = 0;
+ CurDes_L->format = 1;
+ CurDes_L->end = 0;
+ CurDes_L->DataBufferAddr = BufferAddr;
+ CurDes_L->BranchAddr = BranchAddr;
+ SDPRINTK("DescAddr=0x%x, ReqCount=%d\
+ BufferAddr=0x%x, BranchAddr=0x%x,End=%d\n",
+ DescAddr, ReqCount, BufferAddr, BranchAddr, End);
+ if (End) {
+ CurDes_L->end = 1;
+ CurDes_L->i = 1;
+ }
+ SDPRINTK("ReqCount=0x%x, i=0x%x, end=0x%x, format=0x%d,\
+ DataBufferAddr=0x%x,BranchAddr=0x%x\n",
+ CurDes_L->ReqCount, CurDes_L->i, CurDes_L->end, CurDes_L->format,
+ CurDes_L->DataBufferAddr, CurDes_L->BranchAddr);
+ return 0;
+}
+
+int sd_pdma_handler(void)
+{
+ unsigned long status = SD_PDMA_CCR_Evt_no_status;
+ long count = 0;
+/* SDPRINTK("Before polling DMA status:\nSTS[0-3]: 0x%x 0x%x 0x%x 0x%x \n",pSd_Reg->str0,
+ pSd_Reg->str1, pSd_Reg->str2, pSd_Reg->str3);*/
+ count = 0x10000000;
+ /* polling CSR TC status */
+
+ do {
+ count--;
+ if (pSd_PDma_Reg->DMA_ISR & SD_PDMA_IER_INT_STS) {
+ SDPRINTK("pSd_PDma_Reg->DMA_CCR = 0x%lx!\n", pSd_PDma_Reg->DMA_CCR);
+ status = pSd_PDma_Reg->DMA_CCR & SD_PDMA_CCR_EvtCode;
+ pSd_PDma_Reg->DMA_ISR |= SD_PDMA_IER_INT_STS;
+ break ;
+ }
+ if (count == 0) {
+ SDPRINTK("SDPDMA Time Out!\n");
+ break;
+ }
+ } while (1);
+
+ /* SDPRINTK("\nPolling CSR TC status: 0x%lx!\n",status); */
+ if (status == SD_PDMA_CCR_Evt_ff_underrun)
+ SDPRINTK("PDMA Buffer under run!\n");
+
+ if (status == SD_PDMA_CCR_Evt_ff_overrun)
+ SDPRINTK("PDMA Buffer over run!\n");
+
+ if (status == SD_PDMA_CCR_Evt_desp_read)
+ SDPRINTK("PDMA read Descriptor error!\n");
+
+ if (status == SD_PDMA_CCR_Evt_data_rw)
+ SDPRINTK("PDMA read/write memory error!\n");
+
+ if (status == SD_PDMA_CCR_Evt_early_end)
+ SDPRINTK("PDMA read early end!\n");
+
+ if (count == 0) {
+ SDPRINTK("SDPDMA TimeOut!\n");
+ return -1;
+ }
+
+ count = 0x10000000;
+ /* check write direction */
+ /* Leo fix bug here, never go into the branch. */
+ if ((pSd_PDma_Reg->DMA_CCR & SD_PDMA_CCR_peripheral_to_IF) == SD_PDMA_CCR_IF_to_peripheral) {
+ if (pSd_Reg->cmdi == WRITE_MULTIPLE_BLOCK) {
+ while (!(pSd_Reg->str0 & 0x10)) {
+ count--;
+ if (count == 0) {
+ printf("SD Control Data TimeOut!\n");
+ return -1;
+ }
+ }
+ }
+ while (!(pSd_Reg->str0 & 0x30)) {
+ count--;
+ if (count == 0) {
+ printf("SD Control Data TimeOut!\n");
+ return -1;
+ }
+ }
+ }
+ /* printf("SD handler count = %x\n",count); */
+ return 0 ;
+}
+
+void sdmmcSendExCSD(unsigned long *ahb_mem_data_in)
+{
+ unsigned char Resp1[4], tmp;
+ struct _SD_PDMA_DESC_L ReadDesc;
+ /* bzero(ahb_mem_data_in, 512); */
+ memset(ahb_mem_data_in, 0x0, 512);
+ pSd_Reg->blkcnt = 0x01;
+
+ /* set normal speed bus mode */
+ pSd_Reg->extctl &= 0x7F;
+
+ /* set time-out value */
+ pSd_Reg->rtor = 0x1F;
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset */
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+
+ SD_Init_PDMA();
+ sd_init_long_desc(
+ (unsigned long*)(&ReadDesc),
+ 512,
+ ahb_mem_data_in,
+ (unsigned long *)(&ReadDesc + sizeof(struct _SD_PDMA_DESC_L)),
+ 1
+ );
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+
+ if (sd_command(SEND_EXT_CSD, 2, 0x0, R1) != 0) {
+ SDPRINTK("\nErr : send extend csd! \n");
+ return;
+ }
+
+ tmp = pSd_Reg->resr[0];
+ Resp1[0] = pSd_Reg->resr[1];
+ Resp1[1] = pSd_Reg->resr[2];
+ Resp1[2] = pSd_Reg->resr[3];
+ Resp1[3] = pSd_Reg->resr[4];
+ /*
+ SDPRINTK("SWT response[31:24] =%x \n\r",Resp1[0]);
+ SDPRINTK("SWT response[23:16] =%x \n\r",Resp1[1]);
+ SDPRINTK("SWT response[15:8] =%x \n\r", Resp1[2]);
+ SDPRINTK("SWT response[7:0] =%x \n\r", Resp1[3]);
+ */
+ /* while (ost_delay_ms(200) != OST_NO_ERROR); */
+
+ sd_pdma_handler();
+
+ /* *IMR0_REG = 0x08; / Clark - RX buffer half full intr enable */
+
+ return;
+
+}
+
+int sd_free_pdma(void)
+{
+ pSd_PDma_Reg->DMA_DESPR = 0;
+ pSd_PDma_Reg->DMA_GCR = 0;
+ /*SDPRINTK("sd_free_pdma okay!\n");*/
+ return 0;
+}
+
+int sdmmcSwitch(void)
+{
+ unsigned char *SCR ;
+ unsigned char tmp ;
+ unsigned long *ahb_mem_data_in = (unsigned long *)malloc(64);
+ struct _SD_PDMA_DESC_L ReadDesc;
+ memset(ahb_mem_data_in, 0x0, 64);
+ /*bzero(ahb_mem_data_in, 64);*/
+
+ SDDevInfo->HighSpeedSupport = SD_FALSE;
+ SDDevInfo->MMCMaxClockRate = SD_Clk_25MHz;
+
+ pSd_Reg->blklen = 0x003F;
+ pSd_Reg->blkcnt = 0x00;
+ pSd_Reg->ctlr |= 0x08 ;
+
+
+ /* set normal speed bus mode */
+ pSd_Reg->extctl &= 0x7F ;
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_init_long_desc(
+ (unsigned long *)(&ReadDesc),
+ 64,
+ ahb_mem_data_in,
+ (unsigned long *)(&ReadDesc + sizeof(struct _SD_PDMA_DESC_L)),
+ 1
+ );
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+
+ /* (1)SD_SWITCH:Check function
+ * check Card support High speed mode
+ */
+ if (sd_command(0x6, 2, 0x00FFFF01, R1) != 0) {
+ SDPRINTK("\nErr : send switch cmd! \n");
+ return -1;
+ }
+
+ sd_pdma_handler();
+
+ SCR = (unsigned char *)(ahb_mem_data_in);
+ tmp = *(SCR+16) ;
+ if ((tmp & 0x0F) == 0x01) {
+ SDDevInfo->HighSpeedSupport = SD_TRUE;
+ SDDevInfo->MMCMaxClockRate = SD_Clk_44MHz;
+ }
+
+ /* while (ost_delay_ms(100) != OST_NO_ERROR); */
+
+ if (SDDevInfo->HighSpeedSupport == SD_TRUE) {
+ pSd_Reg->ctlr |= 0x08 ;
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+
+ sd_init_long_desc(
+ (unsigned long *)(&ReadDesc),
+ 64,
+ ahb_mem_data_in,
+ (unsigned long *)(&ReadDesc + sizeof(struct _SD_PDMA_DESC_L)),
+ 1
+ );
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+
+ /* (1)SD_SWITCH:SET function
+ * switch card to High speend mode
+ */
+ if (sd_command(0x6, 2, 0x80FFFF01, R1) != 0) {
+ SDPRINTK("\nErr : send switch cmd! \n");
+ return -1;
+ }
+
+ sd_pdma_handler();
+
+ /* free dma */
+ sd_free_pdma();
+
+ SCR = (unsigned char *)(ahb_mem_data_in) ;
+ tmp = *(SCR+16) ;
+
+ if ((tmp & 0x0F) == 0x0F) {
+ SDDevInfo->HighSpeedSupport = SD_FALSE;
+ SDDevInfo->MMCMaxClockRate = SD_Clk_25MHz;
+ SDPRINTK("SD Card NormSpeed!\n") ;
+ return 0 ;
+ } else{
+ SDPRINTK("SD Card High Speed!\n") ;
+ }
+
+ }
+
+ return 0 ;
+}
+
+int sd_send_scr(void)
+{
+
+ unsigned long sd_status;
+ unsigned char rb_data ;
+
+ sd_status = sd_command(SD_SEND_SCR , 2, 0, R1);
+ if (sd_status != 0)
+ return -1;
+
+ while ((pSd_Reg->str0 & BLK_DONE) != BLK_DONE) {
+ if (pSd_Reg->str1 & DATA_TIMEOUT) {
+ rb_data = pSd_Reg->str1 ;
+ rb_data = pSd_Reg->str1 ;
+ rb_data = pSd_Reg->str1 ;
+ return -1 ;
+ }
+ }
+
+ rb_data = pSd_Reg->str0 ;
+ rb_data = pSd_Reg->str0 ;
+ rb_data = pSd_Reg->str0 ;
+
+ return 0 ;
+}
+
+void card_nop(void)
+{
+ int i = 2000 ;
+ do {
+ i--;
+ } while (i != 0);
+}
+
+/*------------------------------------------------------
+*send SD command (non-data related command) to SD card
+*
+*arg depends on command type
+*
+*-----------------------------------------------------
+*/
+int sd_command(
+ unsigned char command,
+ unsigned char cmdtype,
+ unsigned int arg,
+ unsigned char rsptype
+ )
+{
+
+ unsigned char rb_data ;
+
+
+ /* set command*/
+ pSd_Reg->cmdi = command ;
+ /* set command argument*/
+ pSd_Reg->cmdarg0 = (BYTE)arg;
+ pSd_Reg->cmdarg1 = (BYTE)(arg >> 8);/*move 8 bits*/
+ pSd_Reg->cmdarg2 = (BYTE)(arg >> 16);/*move 16 bits*/
+ pSd_Reg->cmdarg3 = (BYTE)(arg >> 24);/*move 24 bits*/
+ pSd_Reg->respt = rsptype;
+
+ /*clear all status registers*/
+ pSd_Reg->str0 &= 0xff;
+ pSd_Reg->str1 &= 0xff;
+ pSd_Reg->str2 &= 0xff;
+ pSd_Reg->str3 &= 0xff;
+
+ /*Choose SD mode*/
+ if (chip_id == 0x3426)
+ pSd_Reg->busm &= 0xEF;
+ else
+ pSd_Reg->busm |= 0x10;
+
+ pSd_Reg->ctlr &= 0x0F;
+ pSd_Reg->ctlr |= (cmdtype << 4);
+
+
+ /*send out the command*/
+ pSd_Reg->ctlr |= CMD_START;
+ rb_data = pSd_Reg->ctlr ;
+
+ /*wait for Ctrl[busy] clear*/
+ while ((pSd_Reg->ctlr & 0x1) != 0)
+ ;
+ /*wait for command completion, STS1[cmd-rsp-done]*/
+ while ((pSd_Reg->str1 & 0x4) != 0x4) {
+ if ((pSd_Reg->str1 & 0x2) == 0x2) {
+ rb_data = pSd_Reg->str1;
+ rb_data = pSd_Reg->str1;
+ rb_data = pSd_Reg->ctlr;
+ break;
+ }
+ }
+
+ /*SD status : command-response time-out*/
+ if ((pSd_Reg->str1 & 0x4) == 0x4) {
+ rb_data = pSd_Reg->str1;
+ rb_data = pSd_Reg->str1;
+ rb_data = pSd_Reg->ctlr;
+ return -1;
+ }
+
+ return 0;
+}
+
+int sd_app_command(
+ unsigned char command,
+ unsigned char cmdtype,
+ unsigned int arg,
+ unsigned char rsptype
+ )
+{
+ unsigned long sd_status;
+
+ if (command == SD_SEND_SCR) {
+ /*change blk length to 8 (SCR register is 8byte)*/
+ pSd_Reg->blklen = 0x7;
+ pSd_Reg->blkcnt = 0x00;
+ }
+
+ sd_status = sd_command(APP_CMD, 0, SDDevInfo->RCA, R1) ;
+
+ /*while( ost_delay_ms(200) != OST_NO_ERROR );*/
+ if (sd_status != 0) /*not successfully on CMD55*/
+ return -1;
+ /*while( ost_delay_ms(1000) != OST_NO_ERROR );*/
+
+ if (command == SD_SEND_SCR) {
+ sd_status = sd_send_scr();
+
+ if (sd_status != 0)
+ return -1;
+ } else {
+ sd_status = sd_command(command, cmdtype, arg, rsptype) ;
+
+ if(sd_status != 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+int sd_alloc_desc_pool(unsigned long *DescAddr)
+{
+ /*bzero(DescAddr, 0x1000);*/
+ return 0;
+}
+
+int sd_init_short_desc(unsigned long *DescAddr, unsigned int ReqCount, unsigned long *BufferAddr)
+{
+ struct _SD_PDMA_DESC_S *CurDes_S;
+ CurDes_S = (struct _SD_PDMA_DESC_S *) DescAddr;
+ CurDes_S->ReqCount = ReqCount;
+ CurDes_S->i = 0;
+ CurDes_S->format = 0;
+ CurDes_S->DataBufferAddr = BufferAddr;
+ return 0;
+}
+
+int sd_init_short_desc_with_end(unsigned long *DescAddr, unsigned int ReqCount,
+ unsigned long *BufferAddr, int end)
+{
+ struct _SD_PDMA_DESC_S *CurDes_S = (struct _SD_PDMA_DESC_S *) DescAddr;
+ sd_init_short_desc(DescAddr,ReqCount,BufferAddr);
+ CurDes_S->end = end;
+ return 0;
+
+}
+
+#define MAX_LONG_DES_LEN ((1<<16) - 32) /*2^15*/
+
+
+void sd_config_desc(unsigned long *DescAddr, unsigned long *BufferAddr, int Blk_Cnt)
+{
+ struct _SD_PDMA_DESC_S *CurDes_S = (struct _SD_PDMA_DESC_S *)DescAddr;
+
+ CurDes_S->ReqCount = 512*Blk_Cnt;
+ CurDes_S->i = 1;
+ CurDes_S->format = 0;
+ CurDes_S->end = 1;
+ CurDes_S->DataBufferAddr = BufferAddr;
+
+}
+
+
+void sd_dump_memory(int where, int how_many)
+{
+ unsigned long *ahb_mem_data_in = (unsigned long *)(0x4600000) ;
+ unsigned long * CurValue = NULL;
+ int Blk_Cnt = how_many;
+ int loop = 0;
+ for (CurValue=ahb_mem_data_in + (where*512/4);
+ loop <Blk_Cnt*512/4;
+ loop++, CurValue++)
+ {
+ if (loop % 8 == 0)
+ SDPRINTK("\n0x%8x: 0x%8lx", (where*512+loop*4), *CurValue);
+ else
+ SDPRINTK(" 0x%8lx", *CurValue);
+ }
+}
+int sd_config_pdma(unsigned long *DescAddr, char dir)
+{
+ pSd_PDma_Reg->DMA_IER = SD_PDMA_IER_INT_EN;
+ pSd_PDma_Reg->DMA_DESPR = DescAddr;
+ if (dir == SD_PDMA_WRITE)
+ pSd_PDma_Reg->DMA_CCR &= SD_PDMA_CCR_IF_to_peripheral;
+ else
+ pSd_PDma_Reg->DMA_CCR |= SD_PDMA_CCR_peripheral_to_IF;
+ pSd_PDma_Reg->DMA_CCR |= SD_PDMA_CCR_RUN;
+ return 0;
+}
+
+int SD_Init(void)
+{
+ struct _SD_PDMA_DESC_L ReadDesc;
+ unsigned long *ahb_mem_data_in = (unsigned long *)malloc(8);
+ unsigned char *mmc_ext_csd = (unsigned char *)malloc(512);
+ memset(ahb_mem_data_in, 0x0, 8);
+ memset(mmc_ext_csd, 0x0, 512);
+ unsigned char csd[16];
+ unsigned int i;
+ unsigned char tmp, powerupOK, FourBitSupport = SD_FALSE;
+ unsigned int pwr_range0, pwr_range1, pwr_range2, pwr_range3, temp;
+ unsigned char Read_Blk_Len, C_Size_Multi;
+ unsigned short C_Size, blkLength;
+
+ unsigned long Card_Capacity, retryCount, sdstatus;
+
+ unsigned char scr[8], card_status[5], card_status_ready[5];
+ unsigned int RCA_t1, RCA_t2;
+
+ SDDevInfo->RCAHi = 0x0;
+ SDDevInfo->RCALo = 0x0;
+ SDDevInfo->RCA = 0;
+ udelay(1000);
+
+ /* get Strapping option status register */
+ SDDevInfo->strapping &= 0xE;
+ /* if strapping is emmc+sf, SD1 need boot software reset. */
+ if (SDDevInfo->CtrlID == 1 && SDDevInfo->strapping == 0x2) {
+ pSd_Reg->Reserved2[0] &= ~0x1;
+ pSd_Reg->busm &= ~0x10;
+ pSd_Reg->busm |= 0x10;
+ }
+
+ /* (1)send CMD0 to set all sd cards into Idle state */
+ sdstatus = sd_command(GO_IDLE_STATE, 0, 0, R0);
+ if (sdstatus != 0)
+ goto err;
+
+
+ /* (2)check card type and its voltage range */
+ powerupOK = SD_FALSE;
+ retryCount = 0;
+ SDDevInfo->SDVersion = SD1_1;
+
+ sdstatus = sd_command(SEND_IF_COND, 0, 0x000001AA, R1);
+ retryCount = 0;
+ while ((sdstatus != 0) && (retryCount < 5)) { /* retry 5 times */
+ sdstatus = sd_command(SEND_IF_COND, 0, 0x000001AA, R1);
+ retryCount++;
+ }
+
+ if (sdstatus == 0) {
+ SDDevInfo->MMC_Card = SD_FALSE;
+ SDDevInfo->SD_Card = SD_TRUE;
+
+ tmp = pSd_Reg->resr[0]; /* 1st byte is cmd index, no use */
+ pwr_range0 = pSd_Reg->resr[1]; /* 2st byte is resvert argument, no use */
+ pwr_range1 = pSd_Reg->resr[2]; /* 3st byte is resvert argument, no use */
+ pwr_range2 = pSd_Reg->resr[3]; /* 4st byte is VHS */
+ pwr_range3 = pSd_Reg->resr[4]; /* 5st byte is Echo check pattern */
+
+ if ((pwr_range2 == 0x01) && (pwr_range3 == 0xAA)) { /* operation condition accepted by card */
+ SDDevInfo->SDVersion = SD2_0;
+ SDPRINTK("\nSD2_0 : SDHC card!\n") ;
+ } else{
+ printf("0x%x, 0x%x, 0x%x, 0x%x\n", pwr_range0, pwr_range1, pwr_range2, pwr_range3);
+ SDPRINTK("\nSD2_0 Err : power fail !\n") ;
+ goto err;
+ }
+ } else {
+ /* 2006/10/13 janshiue SEND_IF_COND(CMD8) retry 5 times no response
+ * it means SD card below ver 1.1 or MMC card
+ * F/W resend RESET(CMD0) to restart initial procedure.
+ */
+ SDDevInfo->SDVersion = SD1_1;
+ sdstatus = sd_command(GO_IDLE_STATE, 0, 0, R0);
+
+ if (sdstatus != 0) {
+ SDPRINTK("\nSD1_1 Err : idle fail !\n");
+ goto err;
+ }
+ }
+
+ /* for 1.0 and 1.1 */
+ if (SDDevInfo->SDVersion != SD2_0) {
+ /* ACMD41 to get card's require voltage range */
+ sdstatus = sd_app_command(SD_APP_OP_COND, 0, 0, R3);
+ retryCount = 0;
+ /* retry ACMD41 */
+ while ((sdstatus != 0) && (retryCount < 20)) {
+ sdstatus = sd_app_command(SD_APP_OP_COND, 0, 0, R3);
+ retryCount++;
+ card_nop();
+ card_nop();
+ card_nop();
+ }
+
+ if (sdstatus == 0) {
+ SDDevInfo->MMC_Card = SD_FALSE;
+ SDDevInfo->SD_Card = SD_TRUE;
+ SDPRINTK("\nInit : SD Card !\n");
+ } else {
+ SDDevInfo->MMCMaxClockRate = SD_Clk_15MHz;
+ SDDevInfo->MMC_Card = SD_TRUE;
+ SDDevInfo->SD_Card = SD_FALSE;
+ SDPRINTK("\nInit : MMC Card !\n");
+ }
+
+ }
+
+
+ /* (i)check MMC card or not */
+ if (SDDevInfo->SD_Card == SD_FALSE) {
+ sdstatus = sd_command(GO_IDLE_STATE, 0, 0, R0);
+ if (sdstatus != 0) {
+ SDPRINTK("\nMMC Err : idle fail 1!\n");
+ goto err;
+ }
+ /* CMD1 to get card's require voltage range */
+ sdstatus = sd_command(SEND_OP_COND, 0x0, 0x40fc0000, R3);
+ retryCount = 0;
+ /* retry CMD1 */
+ while ((sdstatus != 0) && (retryCount < 10)) {
+ sdstatus = sd_command(SEND_OP_COND, 0x0, 0x40fc0000, R3);
+ retryCount++;
+ }
+ if (sdstatus == 0) {
+ SDDevInfo->MMC_Card = SD_TRUE;
+ SDDevInfo->SD_Card = SD_FALSE;
+ } else {
+ SDDevInfo->MMC_Card = SD_FALSE;
+ SDDevInfo->SD_Card = SD_FALSE;
+ }
+ }
+
+ /* no response to SD_APP_OP_COND and SEND_OP_COND */
+ /* card type can't be judged */
+ if ((SDDevInfo->MMC_Card == SD_FALSE) && (SDDevInfo->SD_Card == SD_FALSE)) {
+ SDPRINTK("\nErr : unknown type !\n");
+ goto err;
+ }
+
+ if (SDDevInfo->SDVersion == SD2_0)
+ sdstatus = sd_app_command(SD_APP_OP_COND, 0, 0x40ff8000, R3); /* 2.7~3.6 v */
+
+
+
+ /* get the retun OCR content */
+ tmp = pSd_Reg->resr[0]; /* 1st byte is cmd index, no use */
+ pwr_range0 = pSd_Reg->resr[1]; /* OCR[31:24] */
+ pwr_range1 = pSd_Reg->resr[2]; /* OCR[23:16] */
+ pwr_range2 = pSd_Reg->resr[3]; /* OCR[15:8] */
+ pwr_range3 = pSd_Reg->resr[4]; /* OCR[7:0] */
+
+ if (SDDevInfo->SDVersion == SD2_0) {
+ /* to support SD2.0 High capacity card */
+ pwr_range0 |= HostCapacitySupport;
+ }
+
+ /* (3)power the card and wait for card power phase complete */
+
+ /* retry CMD1 or ACMD41 till powerup ok */
+ retryCount = 0;
+ powerupOK = SD_FALSE;
+ /* add timeout to SD power up retry check (ACMD41 & CMD1). It is for plugin-plugout issue. */
+ if (chip_id == 0x3481 && SDDevInfo->CtrlID == 1) {
+ udelay(1000); //for ASUS MID case.
+ } else {
+ udelay(64000);
+ }
+ /*add timeout to SD power up retry check (ACMD41 & CMD1). It is for plugin-plugout issue.*/
+
+ /* If this card is MMCcard, resend CMD0 to reset MMC card register,
+ * MMC card enter Idel mode. If SD card don't enter Idle mode. added by Eason 2012/6/22 */
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ sdstatus = sd_command(GO_IDLE_STATE, 0, 0, R0);
+ if (sdstatus != 0) {
+ SDPRINTK("\nMMC Err : idle fail 2!\n");
+ goto err;
+ }
+ }
+
+ while (powerupOK == SD_FALSE) {
+ if (SDDevInfo->MMC_Card == SD_TRUE)
+ sdstatus = sd_command(SEND_OP_COND, 0, 0x40fc0000, R3);
+ else{
+ temp = (pwr_range0 << 24)|(pwr_range1 << 16)|(pwr_range2 << 8)|(pwr_range3) ;
+ sdstatus = sd_app_command(SD_APP_OP_COND, 0, temp, R3);
+ }
+ /* chek OCR[31] bit set or not */
+ tmp = pSd_Reg->resr[0]; /* 1st byte is cmd index */
+ tmp = pSd_Reg->resr[1]; /* OCR[31:24] */
+ /* Save OCR Register */
+ SDDevInfo->ocr[0] = pSd_Reg->resr[1];
+ SDDevInfo->ocr[1] = pSd_Reg->resr[2];
+ SDDevInfo->ocr[2] = pSd_Reg->resr[3];
+ SDDevInfo->ocr[3] = pSd_Reg->resr[4];
+
+ if (tmp & 0x80) {
+ /* check CardCapacityStatus MMCA 4.2 must check this*/
+ if (tmp & 0x40)
+ SDDevInfo->CardCapacityStatus = HighCapacity;
+ else
+ SDDevInfo->CardCapacityStatus = StandardCapacity;
+
+
+ powerupOK = SD_TRUE;
+ } else{
+ for (i = 0; i < 20; i++) {
+ tmp = pSd_Reg->resr[i];
+ card_nop();
+ card_nop();
+ card_nop();
+ }
+ }
+
+
+ retryCount++;
+ udelay(64000);
+
+ if (retryCount > 36) {
+ SDPRINTK("\nSD Err : power fail 1 !\n");
+ goto err;
+ }
+
+ }
+
+ if (sdstatus != 0) {
+ SDPRINTK("\nSD Err : power fail 2 !\n");
+ goto err;
+ }
+ SDPRINTK("\nInit : Read OCR OK !\n");
+ /* (4)read card CID, RCA */
+ sdstatus = sd_command(ALL_SEND_CID, 0, 0x0, R2);
+ if (sdstatus != 0) {
+ SDPRINTK("\n Err :send CID fail !\n");
+ goto err;
+ }
+ /* Save CID Register*/
+ SDDevInfo->cid[0] = pSd_Reg->resr[1];
+ SDDevInfo->cid[1] = pSd_Reg->resr[2];
+ SDDevInfo->cid[2] = pSd_Reg->resr[3];
+ SDDevInfo->cid[3] = pSd_Reg->resr[4];
+ SDDevInfo->cid[4] = pSd_Reg->resr[5];
+ SDDevInfo->cid[5] = pSd_Reg->resr[6];
+ SDDevInfo->cid[6] = pSd_Reg->resr[7];
+ SDDevInfo->cid[7] = pSd_Reg->resr[8];
+ SDDevInfo->cid[8] = pSd_Reg->resr[9];
+ SDDevInfo->cid[9] = pSd_Reg->resr[10];
+ SDDevInfo->cid[10] = pSd_Reg->resr[11];
+ SDDevInfo->cid[11] = pSd_Reg->resr[12];
+ SDDevInfo->cid[12] = pSd_Reg->resr[13];
+ SDDevInfo->cid[13] = pSd_Reg->resr[14];
+ SDDevInfo->cid[14] = pSd_Reg->resr[15];
+
+
+ /**************************************************
+ *if SD Card, get RCA from card
+ *if MMC_Card, controller need to assign RCA (0xffc1) for card
+ **************************************************/
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ sdstatus = sd_command(SEND_RELATIVE_ADDR, 0, 0x0, R6);
+ if (sdstatus != 0) {
+ SDPRINTK("\nSD Err :send RCA fail !\n");
+ goto err;
+ }
+
+ tmp = pSd_Reg->resr[1];
+ SDDevInfo->RCAHi = tmp;
+ tmp = pSd_Reg->resr[2];
+ SDDevInfo->RCALo = tmp;
+ } else {
+ /* PKtest 9/5 adjust the timeOut register value */
+ sdstatus = sd_command(SET_RELATIVE_ADDR, 0, 0xffc10000, R1);
+ if (sdstatus != 0) {
+ SDPRINTK("\nMMC Err :send RCA fail !\n");
+ goto err;
+ }
+
+ SDDevInfo->RCAHi = 0xff;
+ SDDevInfo->RCALo = 0xc1;
+ }
+
+ /* (5)read card CSD to know card size, capability */
+
+ RCA_t1 = 0x0;
+ RCA_t2 = 0x0;
+ RCA_t1 |= SDDevInfo->RCAHi;
+ RCA_t2 |= SDDevInfo->RCALo;
+ SDDevInfo->RCA = (RCA_t1 << 24) | (RCA_t2 << 16);
+
+ sdstatus = sd_command(SEND_CSD, 0, SDDevInfo->RCA, R2);
+ if (sdstatus != 0) {
+ SDPRINTK("\nErr :send CSD fail !\n");
+ goto err;
+ }
+
+ /* Save CSD Register*/
+ for (i = 0; i < 15; i++) {
+ csd[i]= pSd_Reg->resr[i+1];
+ SDDevInfo->csd[i] = pSd_Reg->resr[i+1];
+ }
+
+ Read_Blk_Len = csd[5] & 0x0f;
+
+ if ((SDDevInfo->SD_Card == SD_TRUE) && (csd[0] == 0x40)) {
+ /* CSD 2.0 */
+ Card_Capacity = ((((csd[7] & 0x3F) << 8)|csd[8]) << 8) | csd[9];
+ Card_Capacity++;
+
+ /* SD2.0 SPEC : memory capacity = (C_SIZE + 1) * 512 K Byte
+ * Card_Capacity is base on 512 bytes,
+ * thus return Card_Capacity *((512 * 1024)/512)
+ */
+ Card_Capacity = Card_Capacity * 1024;
+ SDDevInfo->SDCard_Size = Card_Capacity;
+ }
+
+ if ((SDDevInfo->MMC_Card == SD_TRUE) || (csd[0] == 0x00)) {
+ /* MMC card or SD 1.1 below */
+ C_Size = (((csd[6] & 0x03) << 8) | csd[7]) << 2 | (csd[8] & 0xC0) >> 6;
+ C_Size_Multi = (csd[9] & 0x3) << 1 | (csd[10] & 0x80) >> 7;
+ blkLength = ((unsigned short)1) << Read_Blk_Len;
+ Card_Capacity = ((((unsigned long)(C_Size + 1)) << (C_Size_Multi + 2)) * blkLength) / 512;
+ SDDevInfo->SDCard_Size = Card_Capacity;
+ }
+
+ /* (6)select card */
+ sdstatus = sd_command(SELECT_DESELECT_CARD, 0, SDDevInfo->RCA, R1);
+ if (sdstatus != 0) {
+ SDPRINTK("\nErr :deselect card fail !\n");
+ goto err;
+ }
+
+ sdstatus = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sdstatus != 0)
+ goto err;
+
+ for (i = 0; i <= 4; i++) {
+ card_status[i] = 0 ;
+ card_status_ready[i] = 0;
+ }
+ card_status_ready[0] = 0x0;
+ card_status_ready[1] = 0x0;
+ card_status_ready[2] = 0x0;
+ card_status_ready[3] = 0x09;
+ card_status_ready[4] = 0x0;
+
+ for (i = 1; i <= 4; i++)
+ card_status[i] = pSd_Reg->resr[i];
+
+ for (i = 1; i <= 4; i++) {
+ if (card_status[i] != card_status_ready[i]) {
+ if (card_status[4] == 0x40) {
+ /* back operation support */
+ printf("\n !! Warning !! pSd_Reg->Rsp[4]=%X ! \n", pSd_Reg->resr[4]);
+ } else {
+ SDPRINTK("\n pSd_Reg->Rsp[1]=%X ! \n", pSd_Reg->resr[1]);
+ SDPRINTK("\n pSd_Reg->Rsp[2]=%X ! \n", pSd_Reg->resr[2]);
+ SDPRINTK("\n pSd_Reg->Rsp[3]=%X ! \n", pSd_Reg->resr[3]);
+ SDPRINTK("\n pSd_Reg->Rsp[4]=%X ! \n", pSd_Reg->resr[4]);
+
+ SDPRINTK("\n Card Status Error ! \n");
+ goto err;
+ }
+ }
+ }
+ SDPRINTK("\nInit : card selected !\n");
+ /* (7)read card SCR to know card support 4bit mode or not */
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ SDPRINTK("\nInit : SD card set mode !\n");
+ FourBitSupport = SD_FALSE;
+
+ SD_Init_PDMA();
+ sd_init_long_desc(
+ (unsigned long *)&ReadDesc,
+ 8,
+ ahb_mem_data_in,
+ (unsigned long *)(&ReadDesc + sizeof(struct _SD_PDMA_DESC_L)),
+ 1
+ );
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+
+ sdstatus = sd_app_command(SD_SEND_SCR, 2, 0x0, R1);
+ if (sdstatus != 0)
+ goto err;
+
+ sdstatus = sd_pdma_handler();
+
+ if (sdstatus != 0)
+ goto err;
+
+ /* Save SCR Register*/
+ for (i = 0; i < 8; i++) {
+ scr[i] = *((uchar *)ahb_mem_data_in + i);
+ SDDevInfo->scr[i] = *((uchar *)ahb_mem_data_in + i);
+ }
+ /* free dma */
+ sd_free_pdma();
+
+
+ tmp = scr[0];
+ if ((tmp & 0x0f) != 0x00)
+ SDDevInfo->HighSpeedSupport = SD_TRUE;
+
+ tmp = scr[1];
+ if ((tmp & 0x0f) == 0x05)
+ FourBitSupport = SD_TRUE;
+ }
+
+ /* (8)set blklength and bus width */
+
+ /* set block length to be 512bytes */
+ blkLength = 0;
+ blkLength = ((unsigned short)1) << Read_Blk_Len;
+ if (blkLength != 512) {
+ SDPRINTK("\nset blocklen fun. !\n");
+ sdstatus = sd_command(SET_BLOCKLEN, 0, 0x200, R1);
+ if (sdstatus != 0) {
+ SDPRINTK("\nErr :set blocklen fail !\n");
+ goto err;
+ }
+ }
+
+ pSd_Reg->blklen |= 0x1FF;
+
+ //if SD card support 4bit bus set to 4bit mode transfer
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ SDDevInfo->MMCMaxClockRate = SD_Clk_25MHz;
+ if (FourBitSupport == SD_TRUE) {
+ if (Bitmode == 0) {
+ sdstatus = sd_app_command(SET_BUS_WIDTH, 0, 0x2, R1);
+ if (sdstatus != 0)
+ goto err;
+
+ /* set BusMode register to 4bit mode */
+ pSd_Reg->busm |= FOURBIT_MODE;
+ SDPRINTK("\nSD:Four Bits Mode!\n");
+ } else {
+ pSd_Reg->busm &= ONEBIT_MODE;
+ SDPRINTK("\nSD:One Bit Mode!\n");
+ }
+ }
+ /* Check SD Card High Speend Support */
+ if (SDDevInfo->HighSpeedSupport == SD_TRUE) {
+ /* SDPRINTK("\nsdmmcSwitch func.\n"); */
+
+ SDDevInfo->MMCMaxClockRate = SD_Clk_44MHz;
+ if ( sdmmcSwitch() != 0 ) {
+ SDPRINTK("\nErr: sdmmcSwitch func.\n");
+ pSd_Reg->blklen = 0x01FF;
+ goto err;
+ }
+
+ pSd_Reg->blklen = 0x01FF;
+ }
+ }
+
+
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ SDPRINTK("\nInit :MMC card set mode !\n");
+ /* save the MMCVersion */
+ SDDevInfo->MMCVersion = (csd[0] >> 2) & 0x0f;
+
+ /* check spec version */
+ if (SDDevInfo->MMCVersion < MMC4_01) {
+ pSd_Reg->busm &= ONEBIT_MODE ;
+ SDPRINTK("\nMMC1_0 :One Bit Mode!\n");
+
+ }
+ if (SDDevInfo->MMCVersion >= MMC4_01) {
+
+ sdmmcSendExCSD((unsigned long *)mmc_ext_csd);
+ /* Save MMC Extended CSD Register */
+ for (i = 0; i < 512; i += 4) {
+ SDDevInfo->ext_csd[i] = *(mmc_ext_csd + i);
+ SDDevInfo->ext_csd[i + 1] = *(mmc_ext_csd + i + 1);
+ SDDevInfo->ext_csd[i + 2] = *(mmc_ext_csd + i + 2);
+ SDDevInfo->ext_csd[i + 3] = *(mmc_ext_csd + i + 3);
+ /*SDPRINTK("CMD %x SCR[%x] =%x \n", pSd_Reg->Cmd, i, *(mmc_ext_csd + i));*/
+ }
+ Card_Capacity = SDDevInfo->ext_csd[212] << 0 |
+ SDDevInfo->ext_csd[213] << 8 |
+ SDDevInfo->ext_csd[214] << 16 |
+ SDDevInfo->ext_csd[215] << 24;
+ if (Card_Capacity)
+ SDDevInfo->SDCard_Size = Card_Capacity;
+
+ tmp = *(mmc_ext_csd + 196);
+ if (tmp & BIT1) { /* high speed and max clock rate at 52Mhz*/
+ /*high speed mode 52Mhz*/
+ SDDevInfo->MMCMaxClockRate = SD_Clk_44MHz;
+ SDDevInfo->HighSpeedSupport = SD_TRUE;
+ SDPRINTK("\nMMC : CLK 48!\n");
+ } else if (tmp == 0x01) {/* high speed and max clock rate at 26Mhz*/
+ SDDevInfo->MMCMaxClockRate = SD_Clk_25MHz;
+ SDDevInfo->HighSpeedSupport = SD_FALSE;
+ SDPRINTK("\nMMC : CLK 24!\n");
+ } else {
+ SDDevInfo->MMCMaxClockRate = SD_Clk_15MHz;/*Clk_15;*/
+ SDDevInfo->HighSpeedSupport = SD_FALSE;
+ SDPRINTK("\nMMC : CLK 15!\n");
+ }
+
+ if (SDDevInfo->HighSpeedSupport == SD_TRUE) {
+ SDPRINTK("\nInit :MMC card High Speed Support !\n");
+ /* Card support High Speed interface */
+ sdstatus = sd_command(SWITCH_MMC, 0, 0x03B90100, R1);
+
+ /*add delay to patch eMMC for MMCA 4.3*/
+ udelay(10000);
+
+ sdstatus = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ for (i = 1; i <= 4; i++)
+ card_status[i]=pSd_Reg->resr[i];
+
+ if ((card_status[3] & 0x80) == 0x00) {
+ /* switch command ok */
+ /* check SWITCH to High speed timming SUCCESS */
+
+ sdmmcSendExCSD((unsigned long *)mmc_ext_csd);
+ tmp = *(mmc_ext_csd + 185);
+
+ if (tmp == 0x01) {/* switch to high speed timming*/
+ SDDevInfo->HighSpeedSupport = SD_TRUE;
+ SDPRINTK("\nMMC : High speed is true !\n");
+ } else { /* switch failer*/
+ SDDevInfo->HighSpeedSupport = SD_FALSE;
+ SDPRINTK("\nMMC : High speed is false !\n");
+ }
+ }
+ }
+
+ /* Use SWITCH command to set MMC 4.0 card to 4bit mode
+ * access = 0x3 write byte
+ * index = 183 point to BUS_WIDTH field
+ * value = 1 indicate 4 bit bus, 2 indicate 8 bit bus
+ */
+ if (Bitmode == 0)
+ Bitmode = 4;
+ if (Bitmode == 0) {
+ sdstatus = sd_command(SWITCH_MMC, 0, 0x03B70200, R1);
+
+ sdstatus = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ for (i = 1; i <= 4; i++)
+ card_status[i]=pSd_Reg->resr[i];
+
+ if ((card_status[3] & 0x80) == 0x00) { /* switch command ok */
+ /* set BusMode register to 8bit mode */
+ /*
+ //SDReg.BusMode |= FOURBIT_MODE;
+ //SDDevInfo->MMC40 = TRUE;
+ */
+ pSd_Reg->extctl |= EIGHTBIT_MODE;
+ SDDevInfo->MMCVersion = MMC4_01;
+ SDPRINTK("\nMMC4_0 : Eight Bits Mode !\n");
+ } else {
+ /* can't switch to 8bit mode, try 4bit mode */
+
+ /*2006/03/08 marked by janshiue, Since if card don't support
+ * 8 bit mode the card still MMC 4.0 card, it should
+ * perform at 1 or 4 bit mode. if set SDDevInfo->MMCVersion to
+ * MMC3_123. it will also disable the high speed support.
+ */
+ /*//SDDevInfo->MMCVersion = MMC4_01;*/
+
+ sdstatus = sd_command(SWITCH_MMC, 0, 0x03B70100, R1);
+
+ sdstatus = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ for (i = 1; i <= 4; i++)
+ card_status[i]=pSd_Reg->resr[i];
+
+ if ((card_status[3] & 0x80) == 0x00) {
+ /* switch command ok */
+ /* set BusMode register to 4bit mode */
+ pSd_Reg->busm |= FOURBIT_MODE;
+ SDPRINTK("\nMMC4_0:Four Bits Mode!\n");
+ SDDevInfo->MMCVersion = MMC4_01;
+ }
+
+ }
+ }
+ if (Bitmode == 4) {
+ /*switch to 4 bit mode*/
+
+ sdstatus = sd_command(SWITCH_MMC, 0, 0x03B70100, R1);
+
+ sdstatus = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ for (i = 1; i <= 4; i++)
+ card_status[i] = pSd_Reg->resr[i] ;
+
+ if ((card_status[3] & 0x80) == 0x00) {
+ /* switch command ok */
+ /* set BusMode register to 4bit mode */
+ pSd_Reg->busm |= FOURBIT_MODE;
+ SDPRINTK("\nMMC4_0:Four Bits Mode!\n") ;
+ SDDevInfo->MMCVersion = MMC4_01;
+ }
+ }
+ if (Bitmode == 1) {
+ sdstatus = sd_command(SWITCH_MMC, 0, 0x03B70000, R1);
+ sdstatus = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ for (i = 1; i <= 4; i++)
+ card_status[i] = pSd_Reg->resr[i];
+
+ if ((card_status[3] & 0x80) == 0x00) {
+ /* switch command ok */
+ /* set BusMode register to 1bit mode */
+ pSd_Reg->busm &= ONEBIT_MODE ;
+ SDPRINTK("\nMMC4_0 :One Bit Mode!\n");
+ SDDevInfo->MMCVersion = MMC4_01;
+ }
+ }
+
+ }
+ }
+ free(mmc_ext_csd);
+ free(ahb_mem_data_in);
+ return 0;
+err:
+ free(mmc_ext_csd);
+ free(ahb_mem_data_in);
+ return -1;
+}
+
+
+int SD_Initialization(void)
+{
+ unsigned char sdstatus = 0;
+
+ Bitmode = 0; /* eight/four bits mode */
+ /* card type is unknown here */
+ SDDevInfo->MMC_Card = SD_FALSE;
+ SDDevInfo->SD_Card = SD_FALSE;
+ SDDevInfo->SD_IO_Card = SD_FALSE;
+
+ /* get SD/MMC card info */
+ SDDevInfo->InitOK = SD_FALSE;
+ /* SDDevInfo->MMCMaxClockRate = Clk_375; */
+ sdstatus = SD_Init();
+ /* error handle during initialization */
+ if (sdstatus != 0) {
+ printf("\nInitial SD/MMC Card Fail!\n");
+ return -1;
+ } else {
+ SDDevInfo->InitOK = SD_TRUE;
+ printf("\nInitial SD/MMC Card OK!\n");
+ }
+
+ return 0;
+}
+
+
+
+/**********************************************************************************/
+extern int
+fat_register_device(block_dev_desc_t *dev_desc, int part_no);
+
+block_dev_desc_t * mmc_get_dev(int dev)
+{
+ if (dev == 0)
+ return ((block_dev_desc_t *)&mmc0_dev);
+ else if (dev == 1)
+ return ((block_dev_desc_t *)&mmc1_dev);
+ else if (dev == 2)
+ return ((block_dev_desc_t *)&mmc2_dev);
+ return NULL;
+}
+
+/*
+ * FIXME needs to read cid and csd info to determine block size
+ * and other parameters
+ */
+//static uchar mmc_buf[MMC_BLOCK_SIZE];
+//static mmc_csd_t mmc_csd;
+
+
+int
+/****************************************************/
+mmc_block_read_singleblock(uchar *dst, ulong src)
+/****************************************************/
+{
+ unsigned long sd_status;
+ struct _SD_PDMA_DESC_S ReadDesc;
+ /*SDPRINTK("\n Read Single block begin \n");*/
+ long count =1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1 ;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_read_singleblock Time Out!\n");
+ break;
+ }
+
+ }
+
+ pSd_Reg->blkcnt = 0x01;
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_config_desc((unsigned long *)(&ReadDesc), (unsigned long*)dst, 1);
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+
+ sd_status = sd_command(READ_SINGLE_BLOCK, 2, src, R1);
+ if (sd_status != 0) {
+ SDPRINTK("\nRead single Block CMD Err !\n");
+ return -1 ;
+ }
+
+ sd_status = sd_pdma_handler();
+ if (sd_status != 0) {
+ pSd_Reg->timeval = 0xefff;
+ /* SDPRINTK("pSd_Reg->Cmd = 0x%x\n", pSd_Reg->Cmd);
+ SDPRINTK("pSd_Reg->STS0 = 0x%x\n", pSd_Reg->ctrl);
+ SDPRINTK("pSd_Reg->DmaTout0 = 0x%x\n", pSd_Reg->DmaTout[0]);
+ SDPRINTK("pSd_Reg->DmaTout1 = 0x%x\n", pSd_Reg->DmaTout[1]);
+ SDPRINTK("pSd_Reg->STS1 = 0x%x\n", pSd_Reg->str1);
+ SDPRINTK("pSd_Reg->BlkCnt[0] = 0x%x\n", pSd_Reg->blkcnt);
+ SDPRINTK("pSd_Reg->Cbcr[0] = 0x%x\n", pSd_Reg->Cbcr[0]);
+ SDPRINTK("pSd_Reg->Cbcr[1] = 0x%x\n", pSd_Reg->Cbcr[1]);
+ SDPRINTK("pSd_Reg->Res3[0] = 0x%x\n", pSd_Reg->Res3[0]);
+ SDPRINTK("pSd_Reg->Res3[1] = 0x%x\n", pSd_Reg->Res3[1]);*/
+ return -1 ;
+
+ }
+
+ /* free dma */
+ sd_free_pdma();
+ /*SDPRINTK("\n Read Single block end \n");*/
+ return 0;
+
+}
+
+int
+/****************************************************/
+mmc_block_read_multiblock(uchar *dst, ulong src, ulong ulBlockCount)
+/****************************************************/
+{
+ unsigned long sd_status;
+ struct _SD_PDMA_DESC_S ReadDesc;
+ long count =1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1 ;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_read_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+
+ /*SDPRINTK("\n Read Multi block begin \n");*/
+ while (ulBlockCount > 127) {
+ pSd_Reg->blkcnt = (unsigned short)(127 & 0xFFFF);
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset, */
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_config_desc((unsigned long *)(&ReadDesc), (unsigned long*)dst, 127);
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+ /* pSd_Reg->extctl |= 0x01; */
+
+ sd_status = sd_command(READ_MULTIPLE_BLOCK, 4, src, R1);
+ if (sd_status != 0) {
+ SDPRINTK("\nRead Multi Block CMD Err !\n");
+ return -1;
+ }
+
+ sd_status = sd_pdma_handler();
+
+ if (sd_status != 0) {
+ pSd_Reg->timeval = 0xefff;
+ /* SDPRINTK("pSd_Reg->Cmd = 0x%x\n", pSd_Reg->Cmd);
+ SDPRINTK("pSd_Reg->STS0 = 0x%x\n", pSd_Reg->ctrl);
+ SDPRINTK("pSd_Reg->DmaTout0 = 0x%x\n", pSd_Reg->DmaTout[0]);
+ SDPRINTK("pSd_Reg->DmaTout1 = 0x%x\n", pSd_Reg->DmaTout[1]);
+ SDPRINTK("pSd_Reg->STS1 = 0x%x\n", pSd_Reg->str1);
+ SDPRINTK("pSd_Reg->BlkCnt[0] = 0x%x\n", pSd_Reg->blkcnt);
+ SDPRINTK("pSd_Reg->Cbcr[0] = 0x%x\n", pSd_Reg->Cbcr[0]);
+ SDPRINTK("pSd_Reg->Cbcr[1] = 0x%x\n", pSd_Reg->Cbcr[1]);
+ SDPRINTK("pSd_Reg->Res3[0] = 0x%x\n", pSd_Reg->Res3[0]);
+ SDPRINTK("pSd_Reg->Res3[1] = 0x%x\n", pSd_Reg->Res3[1]);*/
+ return -1;
+ }
+
+ /* free dma */
+ sd_free_pdma();
+
+ /* send CMD12 : stop command */
+ pSd_Reg->ctlr |= 0x08 ; /* response FIFO reset, */
+ sd_status = sd_command(STOP_TRANSMISSION, 7, src, R1b);
+ if (sd_status != 0)
+ return -1 ;
+ ulBlockCount -= 127;
+
+ if (SDDevInfo->CardCapacityStatus == 0)
+ src += 127*512;
+ else
+ src += 127;
+ dst += 127*512;
+
+ count = 1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1 ;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_write_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+
+ }
+ if (ulBlockCount) {
+ pSd_Reg->blkcnt = (unsigned short)(ulBlockCount & 0xFFFF);
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset, */
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_config_desc((unsigned long *)(&ReadDesc), (unsigned long*)dst, ulBlockCount);
+ sd_config_pdma((unsigned long *)(&ReadDesc), SD_PDMA_READ);
+ //pSd_Reg->extctl |= 0x01;
+
+ sd_status = sd_command(READ_MULTIPLE_BLOCK, 4, src, R1);
+ if (sd_status != 0) {
+ SDPRINTK("\nRead Multi Block CMD Err !\n");
+ return -1 ;
+ }
+
+ sd_status = sd_pdma_handler();
+ if (sd_status != 0) {
+ pSd_Reg->timeval = 0xefff;
+ /* SDPRINTK("pSd_Reg->Cmd = 0x%x\n", pSd_Reg->Cmd);
+ SDPRINTK("pSd_Reg->STS0 = 0x%x\n", pSd_Reg->ctrl);
+ SDPRINTK("pSd_Reg->DmaTout0 = 0x%x\n", pSd_Reg->DmaTout[0]);
+ SDPRINTK("pSd_Reg->DmaTout1 = 0x%x\n", pSd_Reg->DmaTout[1]);
+ SDPRINTK("pSd_Reg->STS1 = 0x%x\n", pSd_Reg->str1);
+ SDPRINTK("pSd_Reg->BlkCnt[0] = 0x%x\n", pSd_Reg->blkcnt);
+ SDPRINTK("pSd_Reg->Cbcr[0] = 0x%x\n", pSd_Reg->Cbcr[0]);
+ SDPRINTK("pSd_Reg->Cbcr[1] = 0x%x\n", pSd_Reg->Cbcr[1]);
+ SDPRINTK("pSd_Reg->Res3[0] = 0x%x\n", pSd_Reg->Res3[0]);
+ SDPRINTK("pSd_Reg->Res3[1] = 0x%x\n", pSd_Reg->Res3[1]);*/
+ return -1;
+ }
+
+ /* free dma */
+ sd_free_pdma();
+
+ /* send CMD12 : stop command */
+ pSd_Reg->ctlr |= 0x08 ; /* response FIFO reset, */
+ sd_status = sd_command(STOP_TRANSMISSION, 7, src, R1b);
+ if (sd_status != 0)
+ return -1;
+
+ count =1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_write_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+
+ }
+ /*SDPRINTK("\nRead multi Block CMD OK !\n");*/
+ return 0 ;
+}
+
+int
+/****************************************************/
+mmc_block_write_singleblock(uchar *src, ulong ulBlockStart)
+/****************************************************/
+{
+ unsigned long sd_status;
+ struct _SD_PDMA_DESC_S WriteDesc;
+ //SDPRINTK("\n Write Single block begin \n");
+ long count =0x1000000;
+
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset, */
+ pSd_Reg->str0 |= 0x30;
+
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1 ;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_write_singleblock Time Out!\n");
+ break;
+ }
+
+ }
+
+ pSd_Reg->blkcnt = 0x01;
+
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_config_desc((unsigned long *)(&WriteDesc), (unsigned long*)src, 1);
+ sd_config_pdma((unsigned long *)(&WriteDesc), SD_PDMA_WRITE);
+
+ sd_status = sd_command(WRITE_SINGLE_BLOCK, 1, ulBlockStart, R1);
+ if (sd_status != 0) {
+ SDPRINTK("\nRead single Block CMD Err !\n");
+ return -1;
+ }
+
+ sd_status = sd_pdma_handler();
+ if (sd_status != 0) {
+ pSd_Reg->timeval = 0xefff;
+ return -1;
+ }
+
+ /* free dma */
+ sd_free_pdma();
+ //SDPRINTK("\n Write Single block end \n");
+
+ count = 0x1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_write_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+ return 0;
+
+}
+
+int
+/****************************************************/
+mmc_block_write_multiblock(uchar *src, ulong ulBlockStart, ulong ulBlockCount)
+/****************************************************/
+{
+ unsigned long sd_status;
+ long count =0x1000000;
+ struct _SD_PDMA_DESC_S WriteDesc;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ SDPRINTK("mmc_block_write_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+ while(ulBlockCount > 127) {
+ pSd_Reg->blkcnt = (unsigned short)(127 & 0xFFFF);
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset, */
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_config_desc((unsigned long *)(&WriteDesc), (unsigned long*)src, 127);
+ sd_config_pdma((unsigned long *)(&WriteDesc), SD_PDMA_WRITE);
+ /* pSd_Reg->extctl |= 0x01; */
+
+ sd_status = sd_command(WRITE_MULTIPLE_BLOCK, 3, ulBlockStart, R1);
+ if (sd_status != 0) {
+ SDPRINTK("\nWrite Multi Block CMD Err !\n");
+ return -1 ;
+ }
+
+ /*sd_status = vt3400_sd_dma_handler() ;*/
+ sd_status = sd_pdma_handler();
+ if (sd_status != 0) {
+ pSd_Reg->timeval = 0xefff;
+ return -1;
+ }
+
+ /* free dma */
+ sd_free_pdma();
+
+ /* send CMD12 : stop command */
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset, */
+ sd_status = sd_command(STOP_TRANSMISSION, 7, (unsigned int)src, R1b);
+ if (sd_status != 0)
+ return -1;
+ if (SDDevInfo->CardCapacityStatus == 0)
+ ulBlockStart += 127*512;
+ else
+ ulBlockStart += 127;
+ ulBlockCount -= 127;
+ src += 127*512;
+
+
+ count = 0x1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0) {
+ printf("mmc_block_write_multiblock fail!\n");
+ return -1;
+ }
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ printf("mmc_block_write_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+ }
+
+ if (ulBlockCount) {
+ pSd_Reg->blkcnt = (unsigned short)(ulBlockCount & 0xFFFF);
+ pSd_Reg->ctlr |= 0x08; /* response FIFO reset, */
+ pSd_Reg->str0 |= 0xFF;
+ pSd_Reg->str1 |= 0xFF;
+ /* Config Read DMA */
+ SD_Init_PDMA();
+ sd_config_desc((unsigned long *)(&WriteDesc), (unsigned long*)src, ulBlockCount);
+ sd_config_pdma((unsigned long *)(&WriteDesc), SD_PDMA_WRITE);
+ //pSd_Reg->extctl |= 0x01;
+
+ sd_status = sd_command(WRITE_MULTIPLE_BLOCK, 3, ulBlockStart, R1);
+ if (sd_status != 0) {
+ SDPRINTK("\nWrite Multi Block CMD last Err ! ulBlockStart %d ulBlockCount %d\n", ulBlockStart, ulBlockCount);
+ return -1 ;
+ }
+
+
+ sd_status = sd_pdma_handler();
+ if (sd_status != 0) {
+ pSd_Reg->timeval = 0xefff;
+ return -1 ;
+ }
+
+ /* free dma */
+ sd_free_pdma();
+
+ /* send CMD12 : stop command */
+ pSd_Reg->ctlr |= 0x08 ; /* response FIFO reset, */
+ sd_status = sd_command(STOP_TRANSMISSION, 7, (unsigned int)src, R1b);
+ if (sd_status != 0)
+ return -1 ;
+
+ count = 0x1000000;
+ while(1) {
+ sd_status = sd_command(SEND_STATUS, 0, SDDevInfo->RCA, R1);
+ if (sd_status != 0)
+ return -1;
+ if (pSd_Reg->resr[3] == 0x09)
+ break;
+ count--;
+ if (count == 0) {
+ printf("mmc_block_write_multiblock Time Out!\n");
+ break;
+ }
+
+ }
+ }
+ SDPRINTK("\n Write multi Block CMD OK !\n");
+ return 0 ;
+}
+
+int
+/****************************************************/
+mmc_read(ulong src, uchar *dst, int size)
+/****************************************************/
+{
+ ulong end, part_start, part_end, aligned_start, aligned_end;
+ ulong mmc_block_size, mmc_block_address, ulBlockCount;
+
+ if (size == 0) {
+ return 0;
+ }
+
+ if (!mmc_ready) {
+ printf("Please initial the MMC first\n");
+ return -1;
+ }
+
+ mmc_block_size = MMC_BLOCK_SIZE;
+ mmc_block_address = ~(mmc_block_size - 1);
+
+ src -= CFG_MMC_BASE;
+ end = src + size;
+ part_start = ~mmc_block_address & src;
+ part_end = ~mmc_block_address & end;
+ aligned_start = mmc_block_address & src;
+ aligned_end = mmc_block_address & end;
+ ulBlockCount = (aligned_end-src)/MMC_BLOCK_SIZE;
+
+ if (ulBlockCount ==1) {
+ /*This is for single block read*/
+ /*for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size) {*/
+ if ((mmc_block_read_singleblock((uchar *)dst, (src>>9*SDDevInfo->CardCapacityStatus))) < 0) {
+ return -1;
+ }
+ /*}*/
+ } else {
+ /*This is for multi block read*/
+ if (mmc_block_read_multiblock((uchar*)dst, (src>>9*SDDevInfo->CardCapacityStatus), ulBlockCount) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int
+/****************************************************/
+mmc_write(uchar *src, ulong dst, int size)
+/****************************************************/
+{
+
+ return 0;
+}
+
+
+ulong
+/****************************************************/
+mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst)
+/****************************************************/
+{
+ ulong src = 0;
+ //ulong src_size = 0; //20120105 by eason
+ //ulong SDCard_Size = SDDevInfo->SDCard_Size;
+ //printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+ //printf(" dst 0x%x dev_num 0x%x, blknr 0x%x, blkcnt 0x%x \n", dst, dev_num, blknr, blkcnt);
+ //printf(" SDDevInfo->CardCapacityStatus %d \n", SDDevInfo->CardCapacityStatus);
+ if(!blkcnt)
+ return blkcnt;
+
+ /*select host*/
+ Change_SD_host(dev_num);
+
+ if (!mmc_ready) {
+ printf("Please initial the MMC first\n");
+ return -1;
+ }
+
+ src = SDDevInfo->CardCapacityStatus ? blknr : (blknr*MMC_BLOCK_SIZE);
+ /*ount SD size by block based, a block = 512 bytes */
+ //src_size = SDDevInfo->CardCapacityStatus ? src : (src/MMC_BLOCK_SIZE);
+ //if(src_size > SDCard_Size) { /*if reas address > SDCard size , the part_address is error */
+ // printf("mmc_bwrite part_offset error\n");
+ // return -1;
+ //}
+
+ if (blkcnt == 1) {
+ /*This is for single block read*/
+ if ((mmc_block_read_singleblock((uchar *)dst, src)) < 0) {
+ return -1;
+ }
+ } else {
+ /*This is for multi block read*/
+ if (mmc_block_read_multiblock((uchar*)dst, src, blkcnt) < 0) {
+ return -1;
+ }
+ }
+ return blkcnt;
+}
+
+
+ulong
+/****************************************************/
+mmc_bwrite(int dev_num, ulong blknr, ulong blkcnt, ulong *src)
+/****************************************************/
+{
+ ulong dst = 0;
+ //ulong dst_size = 0;
+ //ulong SDCard_Size = SDDevInfo->SDCard_Size;
+ dst = SDDevInfo->CardCapacityStatus ? blknr : (blknr*MMC_BLOCK_SIZE);
+
+ /* count SD size by block based, a block = 512 bytes */
+ //dst_size = SDDevInfo->CardCapacityStatus ? dst : (dst/MMC_BLOCK_SIZE);
+ //printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+ //printf("[mmc_bwrite] dst 0x%x src 0x%x dev_num 0x%x, blknr 0x%x, blkcnt 0x%x \n", dst, src, dev_num, blknr, blkcnt);
+ if(!blkcnt)
+ return blkcnt;
+
+ /*select host*/
+ Change_SD_host(dev_num);
+
+ if (!mmc_ready) {
+ printf("Please initial the MMC first\n");
+ return -1;
+ }
+ //if(dst_size > SDCard_Size) { /*if write address > SDCard size , the part_offset is error */
+ // printf("mmc_bwrite part_offset error\n");
+ // return -1;
+ //}
+ if (blkcnt ==1) {
+ /*This is for single block read*/
+ if ((mmc_block_write_singleblock((uchar *)src, dst)) < 0) {
+ return -1;
+ }
+ } else {
+ /*This is for multi block read*/
+ if (mmc_block_write_multiblock((uchar*)src, dst, blkcnt) < 0) {
+ return -1;
+ }
+ }
+ return blkcnt;
+}
+int
+/****************************************************/
+mmc_fb_write(unsigned dev_num, ulong blknr, ulong blkcnt, uchar *src)
+/****************************************************/
+{
+ ulong dst = 0;
+ //ulong dst_size = 0;
+ //ulong SDCard_Size = SDDevInfo->SDCard_Size;
+ dst = SDDevInfo->CardCapacityStatus ? blknr : (blknr*MMC_BLOCK_SIZE);
+
+ /* count SD size by block based, a block = 512 bytes */
+ //dst_size = SDDevInfo->CardCapacityStatus ? dst : (dst/MMC_BLOCK_SIZE);
+ //printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+ //printf("[mmc_bwrite] dst 0x%x src 0x%x dev_num 0x%x, blknr 0x%x, blkcnt 0x%x \n", dst, src, dev_num, blknr, blkcnt);
+ if(!blkcnt)
+ return blkcnt;
+
+ /*select host*/
+ Change_SD_host(dev_num);
+
+ if (!mmc_ready) {
+ printf("Please initial the MMC first\n");
+ return -1;
+ }
+ //if(dst_size > SDCard_Size) { /*if write address > SDCard size , the part_offset is error */
+ // printf("mmc_bwrite part_offset error\n");
+ // return -1;
+ //}
+ if (blkcnt ==1) {
+ /*This is for single block read*/
+ if ((mmc_block_write_singleblock((uchar *)src, dst)) < 0) {
+ return -1;
+ }
+ } else {
+ /*This is for multi block read*/
+ if (mmc_block_write_multiblock((uchar*)src, dst, blkcnt) < 0) {
+ return -1;
+ }
+ }
+ return blkcnt;
+}
+int sd_set_clock(int Frequence)
+{
+
+ if (Frequence == SD_Clk_Auto) {
+ /* Check SD Card */
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ if (SDDevInfo->HighSpeedSupport == SD_TRUE)
+ Frequence = 6; /* 50Mhz */
+ else
+ Frequence = 3; /* 25Mhz */
+ }
+
+ /* Check MMC Card */
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ if (SDDevInfo->MMCMaxClockRate == Clk_48)
+ Frequence = 6; /* 50Mhz */
+ else if (SDDevInfo->MMCMaxClockRate == Clk_24)
+ Frequence = 3; /* 25Mhz */
+ else if (SDDevInfo->MMCMaxClockRate == Clk_15)
+ Frequence = 1; /* 15Mhz */
+ }
+ }
+
+ switch (Frequence) {
+ case SD_Clk_Auto:
+ break;
+ case SD_Clk_15MHz:
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 15);
+ SDPRINTK("ATSMB Host0 15MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 15);
+ SDPRINTK("ATSMB Host1 15MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 15);
+ SDPRINTK("ATSMB Host2 15MHz \n");
+ }
+ break;
+ case SD_Clk_20MHz:
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 20);
+ SDPRINTK("ATSMB Host0 20MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 20);
+ SDPRINTK("ATSMB Host1 20MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 20);
+ SDPRINTK("ATSMB Host2 20MHz \n");
+ }
+ break;
+ case SD_Clk_25MHz:
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 24);
+ SDPRINTK("ATSMB Host0 25MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 24);
+ SDPRINTK("ATSMB Host1 25MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 24);
+ SDPRINTK("ATSMB Host2 25MHz \n");
+ }
+ break;
+ case SD_Clk_33MHz:
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ pSd_Reg->extctl |= 0x80; /* Enable High Speed timing */
+ }
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ }
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 33);
+ SDPRINTK("ATSMB Host0 33MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing for WM3498 */
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 33);
+ SDPRINTK("ATSMB Host1 33MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 33);
+ SDPRINTK("ATSMB Host2 33MHz \n");
+ }
+ break;
+ case SD_Clk_40MHz:
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ pSd_Reg->extctl |= 0x80; /* Enable High Speed timing */
+ }
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ }
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 40);
+ SDPRINTK("ATSMB Host0 40MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing for WM3498 */
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 40);
+ SDPRINTK("ATSMB Host1 40MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 40);
+ SDPRINTK("ATSMB Host2 40MHz \n");
+ }
+ break;
+ case SD_Clk_44MHz:
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ pSd_Reg->extctl |= 0x80; /* Enable High Speed timing */
+ }
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ }
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 44);
+ SDPRINTK("ATSMB Host0 44MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing for WM3498 */
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 44);
+ SDPRINTK("ATSMB Host1 44MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 44);
+ SDPRINTK("ATSMB Host2 44MHz \n");
+ }
+ break;
+/* case SD_Clk_50MHz:
+ if (SDDevInfo->SD_Card == SD_TRUE) {
+ pSd_Reg->extctl |= 0x80;
+ }
+ if (SDDevInfo->MMC_Card == SD_TRUE) {
+ pSd_Reg->extctl &= ~0x80;
+ }
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 2, 50);
+ SDPRINTK("ATSMB Host0 50MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 2, 50);
+ SDPRINTK("ATSMB Host1 50MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 2, 50);
+ SDPRINTK("ATSMB Host2 50MHz \n");
+ }
+ if (SDDevInfo->CtrlID == 3) {
+ auto_pll_divisor(DEV_SDMMC3, SET_DIV, 2, 50);
+ SDPRINTK("ATSMB Host3 50MHz \n");
+ }
+ break;*/
+ case SD_Clk_400KHz:
+ pSd_Reg->extctl &= ~0x80; /* Disable High Speed timing */
+ if (SDDevInfo->CtrlID == 0) {
+ auto_pll_divisor(DEV_SDMMC0, SET_DIV, 1, 400);
+ SDPRINTK("ATSMB Host0 400KHz \n");
+ }
+ if (SDDevInfo->CtrlID == 1) {
+ auto_pll_divisor(DEV_SDMMC1, SET_DIV, 1, 400);
+ SDPRINTK("ATSMB Host1 400KHz \n");
+ }
+ if (SDDevInfo->CtrlID == 2) {
+ auto_pll_divisor(DEV_SDMMC2, SET_DIV, 1, 400);
+ SDPRINTK("ATSMB Host2 400KHz \n");
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int
+mmc_init(int verbose, int device_num)
+/****************************************************/
+{
+ unsigned long sd_status;
+
+
+ int Fre = 3;/*3*/
+
+ get_chip_version();
+ if (chip_id == 0x3437 ||
+ chip_id == 0x3429 ||
+ chip_id == 0x3451) {
+ if (device_num > 1)
+ device_num = 1;
+ if (device_num < 0)
+ device_num = 0;
+ } else if (chip_id == 0x3445 || chip_id == 0x3498) {
+ if (device_num > 2)
+ device_num = 2;
+ if (device_num < 0)
+ device_num = 0;
+ } else if (chip_id == 0x3481) {
+ if (device_num > 3)
+ device_num = 3;
+ if (device_num < 0)
+ device_num = 0;
+ } else {
+ device_num = 0;
+ }
+
+ if (device_num == 0)
+ auto_pll_divisor(DEV_SDMMC0, CLK_ENABLE, 0, 0);
+ if (device_num == 1)
+ auto_pll_divisor(DEV_SDMMC1, CLK_ENABLE, 0, 0);
+ if (device_num == 2)
+ auto_pll_divisor(DEV_SDMMC2, CLK_ENABLE, 0, 0);
+
+ Change_SD_host(device_num);
+ memset(SDDevInfo, 0x0, sizeof(sd_info_t));
+ SDDevInfo->CtrlID = (char)device_num;
+
+ SD_Controller_Powerup();
+
+ sd_status = SD_Initialization(); /* for Emul. */
+ if (sd_status != 0 )
+ return -1 ;
+ Fre = SDDevInfo->MMCMaxClockRate;
+ switch (Fre) {
+ case SD_Clk_400KHz:
+ sd_set_clock(SD_Clk_400KHz); /* 400Khz */
+ printf("SD/MMC clock is 400Khz\n");
+ break;
+ case SD_Clk_15MHz:
+ sd_set_clock(SD_Clk_15MHz); /* 15Mhz */
+ printf("SD/MMC clock is 15Mhz\n");
+ break;
+ case SD_Clk_25MHz:
+ sd_set_clock(SD_Clk_25MHz); /* 25Mhz */
+ printf("SD/MMC clock is 22.36Mhz\n");
+ break;
+ case SD_Clk_44MHz:
+ sd_set_clock(SD_Clk_44MHz); /* 44Mhz */
+ printf("SD/MMC clock is 41Mhz\n");
+ break;
+ /*case SD_Clk_50MHz:
+ sd_set_clock(SD_Clk_50MHz); /* 48Mhz
+ printf( "SD/MMC clock is 50Mhz\n");
+ break;*/
+ default:
+ break;
+
+ }
+
+ /* set normal speed bus mode */
+ /* pSd_Reg->extctl &= 0x7F; */
+
+ pSd_Reg->blkcnt = 0x01 ;
+ pSd_Reg->ctlr |= 0x08 ; // response FIFO reset,
+
+
+ mmc_dev->if_type = IF_TYPE_MMC;
+ mmc_dev->part_type = PART_TYPE_DOS;
+ mmc_dev->dev = device_num;
+ mmc_dev->lun = 0;
+ mmc_dev->type = 0;
+ /* FIXME fill in the correct size (is set to 32MByte) */
+ mmc_dev->blksz = 512;
+ mmc_dev->lba = SDDevInfo->SDCard_Size;
+ mmc_dev->removable = 0;
+ mmc_dev->block_read = mmc_bread;
+ mmc_dev->block_write = mmc_bwrite;
+
+ if (device_num == 0)
+ mmc0_ready = 1;
+ if (device_num == 1)
+ mmc1_ready = 1;
+ if (device_num == 2)
+ mmc2_ready = 1;
+ mmc_ready = 1;
+
+
+ printf("register mmc device\n");
+ SDPRINTK("SDCard_Size = %ld MB\n",SDDevInfo->SDCard_Size / (2*1024));
+ fat_register_device(mmc_dev, 1); /* partitions start counting with 1 */
+
+ return 0;
+}
+
+int
+mmc_ident(block_dev_desc_t *dev)
+{
+ return 0;
+}
+
+int
+mmc2info(ulong addr)
+{
+ /* FIXME hard codes to 32 MB device */
+ if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000) {
+ return 1;
+ }
+ return 0;
+}
+
+unsigned int get_chip_version(void)
+{
+ static unsigned int chip_version = 0;
+ unsigned int val;
+
+ if (chip_version)
+ return chip_version;
+
+ chip_id = *(unsigned short *) 0xD8120002;
+ switch (chip_id) {
+ case 0x3357:
+ val = *(unsigned int *)(0xd8120700);
+ *(unsigned int *)(0xd8120700) = val;
+
+ val = *(unsigned int *)(0xd8120700);
+ chip_version = ((0xA + ((val & 0x0F) - 0x02)) << 4) + ((val & 0xF0) >> 4);
+ break;
+ case 0x3400:
+ val = *(unsigned int *) 0xD8120000;
+ chip_version = ((val & 0xF00) >> 4) + 0x90 + ((val & 0xFF) - 1);
+ break;
+ case 0x3426:
+ pSd_Reg = (PWMT_SDMMC_REG) BA_SDC;
+ pSd_PDma_Reg = (struct _SD_PDMA_REG_ *) BA_SDCDMA;
+ val = *(unsigned int *) 0xD8120000;
+ chip_version = ((val & 0xF00) >> 4) + 0x90 + ((val & 0xFF) - 1);
+ break;
+ default:
+ val = *(unsigned int *) 0xD8120000;
+ chip_version = ((val & 0xF00) >> 4) + 0x90 + ((val & 0xFF) - 1);
+ break;
+ }
+ chip_version = (chip_id << 16) | chip_version;
+ SDPRINTK( "debug chip_id = %x, chip_version = %x\n", chip_id, chip_version);
+ return chip_version;
+}
+
+
+
+void SD_Controller_Powerup(void)
+{
+
+#define GPIO_PIN_Sharing REG32_PTR(GPIO_BASE_ADDR + 0x200)
+#define GPIO_Strapping REG32_PTR(GPIO_BASE_ADDR + 0x100)
+
+/*SD0*/
+#define GPIO_INPUT_DATA_SD018SEL REG8_PTR(GPIO_BASE_ADDR + 0x00C)
+#define GPIO_INPUT_DATA_SD REG8_PTR(GPIO_BASE_ADDR + 0x00D)
+#define GPIO_INPUT_DATA_SDCardDetect REG8_PTR(GPIO_BASE_ADDR + 0x03F)
+
+#define GPIO_Enable_SD018SEL REG8_PTR(GPIO_BASE_ADDR + 0x04C)
+#define GPIO_Enable_SD REG8_PTR(GPIO_BASE_ADDR + 0x04D)
+#define GPIO_Enable_SDCardDetect REG8_PTR(GPIO_BASE_ADDR + 0x07F)
+
+#define GPIO_OUTPUT_Enable_SD018SEL REG8_PTR(GPIO_BASE_ADDR + 0x08C)
+#define GPIO_OUTPUT_Enable_SD REG8_PTR(GPIO_BASE_ADDR + 0x08D)
+#define GPIO_OUTPUT_Enable_SDCardDetect REG8_PTR(GPIO_BASE_ADDR + 0x0BF)
+
+#define GPIO_OUTPUT_DATA_SD018SEL REG8_PTR(GPIO_BASE_ADDR + 0x0CC)
+#define GPIO_OUTPUT_DATA_SD REG8_PTR(GPIO_BASE_ADDR + 0x0CD)
+#define GPIO_OUTPUT_DATA_SDCardDetect REG8_PTR(GPIO_BASE_ADDR + 0x0FF)
+
+#define GPIO_PULL_Enable_SD018SEL REG8_PTR(GPIO_BASE_ADDR + 0x48C)
+#define GPIO_PULL_Enable_SD REG8_PTR(GPIO_BASE_ADDR + 0x48D)
+#define GPIO_PULL_Enable_SDCardDetect REG8_PTR(GPIO_BASE_ADDR + 0x4BF)
+
+#define GPIO_PULL_Control_SD018SEL REG8_PTR(GPIO_BASE_ADDR + 0x4CC)
+#define GPIO_PULL_Control_SD REG8_PTR(GPIO_BASE_ADDR + 0x4CD)
+#define GPIO_PULL_Control2_SD REG8_PTR(GPIO_BASE_ADDR + 0x4DB)
+#define GPIO_PULL_Control_SDCardDetect REG8_PTR(GPIO_BASE_ADDR + 0x4FF)
+
+/*SD1*/
+#define GPIO_INPUT_DATA_SD1 REG8_PTR(GPIO_BASE_ADDR + 0x00E)
+#define GPIO_INPUT_DATA_SD1Data REG8_PTR(GPIO_BASE_ADDR + 0x010)
+
+#define GPIO_Enable_SD1 REG8_PTR(GPIO_BASE_ADDR + 0x04E)
+#define GPIO_Enable_SD1Data REG8_PTR(GPIO_BASE_ADDR + 0x050)
+
+#define GPIO_OUTPUT_Enable_SD1 REG8_PTR(GPIO_BASE_ADDR + 0x08E)
+#define GPIO_OUTPUT_Enable_SD1Data REG8_PTR(GPIO_BASE_ADDR + 0x090)
+
+#define GPIO_OUTPUT_DATA_SD1 REG8_PTR(GPIO_BASE_ADDR + 0x0CE)
+#define GPIO_OUTPUT_DATA_SD1Data REG8_PTR(GPIO_BASE_ADDR + 0x0D0)
+
+#define GPIO_PULL_Enable_SD1 REG8_PTR(GPIO_BASE_ADDR + 0x48E)
+#define GPIO_PULL_Enable_SD1Data REG8_PTR(GPIO_BASE_ADDR + 0x490)
+
+#define GPIO_PULL_Control_SD1 REG8_PTR(GPIO_BASE_ADDR + 0x4CE)
+#define GPIO_PULL_Control_SD1Data REG8_PTR(GPIO_BASE_ADDR + 0x4D0)
+
+/*SD2*/
+#define GPIO_INPUT_DATA_SD2 REG8_PTR(GPIO_BASE_ADDR + 0x013)
+#define GPIO_INPUT_DATA_SD2CardDetect REG8_PTR(GPIO_BASE_ADDR + 0x03F)
+
+#define GPIO_Enable_SD2 REG8_PTR(GPIO_BASE_ADDR + 0x053)
+#define GPIO_Enable_SD2CardDetect REG8_PTR(GPIO_BASE_ADDR + 0x07F)
+
+#define GPIO_OUTPUT_Enable_SD2 REG8_PTR(GPIO_BASE_ADDR + 0x093)
+#define GPIO_OUTPUT_Enable_SD2CardDetect REG8_PTR(GPIO_BASE_ADDR + 0x0BF)
+
+#define GPIO_OUTPUT_DATA_SD2 REG8_PTR(GPIO_BASE_ADDR + 0x0D3)
+#define GPIO_OUTPUT_DATA_SD2CardDetect REG8_PTR(GPIO_BASE_ADDR + 0x0FF)
+
+#define GPIO_PULL_Enable_SD2 REG8_PTR(GPIO_BASE_ADDR + 0x493)
+#define GPIO_PULL_Enable_SD2CardDetect REG8_PTR(GPIO_BASE_ADDR + 0x4BF)
+
+#define GPIO_PULL_Control_SD2 REG8_PTR(GPIO_BASE_ADDR + 0x4D3)
+#define GPIO_PULL_Control_SD2CardDetect REG8_PTR(GPIO_BASE_ADDR + 0x4FF)
+
+/* SD pin */
+#define GPIO_SD0_CD BIT4
+#define GPIO_SD0_Data (BIT6 | BIT5 | BIT4 | BIT3)
+#define GPIO_SD0_WriteProtect BIT2
+#define GPIO_SD0_Command BIT1
+#define GPIO_SD0_Clock BIT0
+#define GPIO_SD0_POWER BIT7
+#define GPIO_SD0_18SEL BIT4
+
+#define GPIO_SD1_Data (BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+#define GPIO_SD1_Command BIT1
+#define GPIO_SD1_Clock BIT0
+#define GPIO_SD1_CD BIT6
+#define GPIO_SD1_WriteProtect BIT5
+#define GPIO_SD1_POWER BIT4
+#define GPIO_SD1_RSTN BIT3
+
+#define GPIO_SD2_Data (BIT3 | BIT2 | BIT1 | BIT0)
+#define GPIO_SD2_Command BIT4
+#define GPIO_SD2_Clock BIT5
+#define GPIO_SD2_CD BIT2
+#define GPIO_SD2_WriteProtect BIT7
+#define GPIO_SD2_POWER BIT6
+
+/* PIN share switch */
+#define GPIO_SD1_PinShare BIT11
+#define GPIO_SD2_PinShare BIT28
+
+#define SD0_CARD_PWR BIT1
+#define SD1_CARD_PWR BIT2
+#define SD2_CARD_PWR BIT3
+
+ /* unsigned long SD0_PIN,SD1_PIN,SD2_PIN; */
+ /* SD0_PIN = ( GPIO_SD0_Clock | GPIO_SD0_Command | GPIO_SD0_WriteProtect | GPIO_SD0_Data); */
+ /* SD1_PIN = ( GPIO_SD1_Clock | GPIO_SD1_Command | GPIO_SD1_WriteProtect | GPIO_SD1_RSTN | GPIO_SD1_CD); */
+ /* SD2_PIN = ( GPIO_SD2_Clock | GPIO_SD2_Command | GPIO_SD2_WriteProtect | GPIO_SD2_Data); */
+ /* Get Strapping option status register */
+ SDDevInfo->strapping = *GPIO_Strapping;
+
+ /* set normal speed bus mode */
+ pSd_Reg->extctl = 0x0;
+ pSd_Reg->busm = 0x0; /* response FIFO reset, */
+
+ /* disable SD Card power */
+ if (SDDevInfo->CtrlID == 0) {
+ /*set SD0 power pin as GPO pin*/
+ *GPIO_Enable_SD |= GPIO_SD0_POWER; /*Set power pin as GPIO pin*/
+ *GPIO_OUTPUT_Enable_SD |= GPIO_SD0_POWER; /*Set output pin*/
+
+ /*set internal pull up*/
+ *GPIO_PULL_Control_SD |= GPIO_SD0_POWER;
+
+ /*set internal pull enable*/
+ *GPIO_PULL_Enable_SD |= GPIO_SD0_POWER;
+
+ /*disable SD0 power*/
+ *GPIO_OUTPUT_DATA_SD |= GPIO_SD0_POWER;
+ } else if (SDDevInfo->CtrlID == 1) {
+ /*set SD1 power pin as GPO pin*/
+ *GPIO_Enable_SD1 |= GPIO_SD1_POWER; /*Set power pin as GPIO pin*/
+ *GPIO_OUTPUT_Enable_SD1 |= GPIO_SD1_POWER; /*Set output pin*/
+
+ /*set internal pull up*/
+ *GPIO_PULL_Control_SD1 |= GPIO_SD1_POWER;
+
+ /*set internal pull enable*/
+ *GPIO_PULL_Enable_SD1 |= GPIO_SD1_POWER;
+
+ /*disable SD1 power*/
+ *GPIO_OUTPUT_DATA_SD1 |= GPIO_SD1_POWER;
+ } else if (SDDevInfo->CtrlID == 2) {
+ /*set SD2 power pin as GPO pin*/
+ *GPIO_Enable_SD2 |= GPIO_SD2_POWER; /*Set power pin as GPIO pin*/
+ *GPIO_OUTPUT_Enable_SD2 |= GPIO_SD2_POWER; /*Set output pin*/
+
+ /*set internal pull up*/
+ *GPIO_PULL_Control_SD2 |= GPIO_SD2_POWER;
+
+ /*set internal pull enable*/
+ *GPIO_PULL_Enable_SD2 |= GPIO_SD2_POWER;
+
+ /*disable SD2 power*/
+ *GPIO_OUTPUT_DATA_SD2 |= GPIO_SD2_POWER;
+ }
+
+ /* Config SD PIN share */
+ if (SDDevInfo->CtrlID == 1)
+ *GPIO_PIN_Sharing |= GPIO_SD1_PinShare;
+ else if (SDDevInfo->CtrlID == 2)
+ *GPIO_PIN_Sharing |= GPIO_SD2_PinShare;
+
+ /* do not config GPIO_SD1_CD because ISR has already rum,
+ * config card detect will issue ISR storm.
+ */
+
+ /* Config SD to GPIO */
+ if (SDDevInfo->CtrlID == 0) {
+ *GPIO_Enable_SD |= (GPIO_SD0_Clock | GPIO_SD0_Command | GPIO_SD0_WriteProtect | GPIO_SD0_Data);
+ *GPIO_Enable_SDCardDetect |= GPIO_SD0_CD;
+ *GPIO_Enable_SD018SEL |= GPIO_SD0_18SEL;
+ } else if (SDDevInfo->CtrlID == 1) {
+ *GPIO_Enable_SD1 |= (GPIO_SD1_Clock | GPIO_SD1_Command | GPIO_SD1_WriteProtect | GPIO_SD1_RSTN | GPIO_SD1_CD);
+ *GPIO_Enable_SD1Data |= GPIO_SD1_Data;
+ } else if (SDDevInfo->CtrlID == 2) {
+ *GPIO_Enable_SD2 |= (GPIO_SD2_Clock | GPIO_SD2_Command | GPIO_SD1_WriteProtect | GPIO_SD2_Data);
+ *GPIO_Enable_SD2CardDetect |= GPIO_SD2_CD;
+ }
+
+ /* SD all pins output low */
+ if (SDDevInfo->CtrlID == 0) {
+ *GPIO_OUTPUT_DATA_SD &= ~(GPIO_SD0_Clock | GPIO_SD0_Command | GPIO_SD0_WriteProtect | GPIO_SD0_Data);
+ *GPIO_OUTPUT_DATA_SDCardDetect &= ~GPIO_SD0_CD;
+ *GPIO_OUTPUT_DATA_SD018SEL |= GPIO_SD0_18SEL;
+ } else if (SDDevInfo->CtrlID == 1) {
+ *GPIO_OUTPUT_DATA_SD1 &= ~(GPIO_SD1_Clock | GPIO_SD1_Command | GPIO_SD1_WriteProtect | GPIO_SD1_RSTN | GPIO_SD1_CD);
+ *GPIO_OUTPUT_DATA_SD1Data &= ~GPIO_SD1_Data;
+ } else if (SDDevInfo->CtrlID == 2) {
+ *GPIO_OUTPUT_DATA_SD2 &= ~(GPIO_SD2_Clock | GPIO_SD2_Command | GPIO_SD1_WriteProtect | GPIO_SD2_Data);
+ *GPIO_OUTPUT_DATA_SD2CardDetect &= ~GPIO_SD2_CD;
+ }
+
+ /* Config SD to GPO */
+ if (SDDevInfo->CtrlID == 0) {
+ *GPIO_OUTPUT_Enable_SD |= (GPIO_SD0_Clock | GPIO_SD0_Command | GPIO_SD0_WriteProtect | GPIO_SD0_Data);
+ *GPIO_OUTPUT_Enable_SDCardDetect |= GPIO_SD0_CD;
+ *GPIO_OUTPUT_Enable_SD018SEL = GPIO_SD0_18SEL;
+ } else if (SDDevInfo->CtrlID == 1) {
+ *GPIO_OUTPUT_Enable_SD1 |= (GPIO_SD1_Clock | GPIO_SD1_Command | GPIO_SD1_WriteProtect | GPIO_SD1_RSTN | GPIO_SD1_CD);
+ *GPIO_OUTPUT_Enable_SD1Data |= GPIO_SD1_Data;
+ } else if (SDDevInfo->CtrlID == 2) {
+ *GPIO_OUTPUT_Enable_SD2 |= (GPIO_SD2_Clock | GPIO_SD2_Command | GPIO_SD1_WriteProtect | GPIO_SD2_Data);
+ *GPIO_OUTPUT_Enable_SD2CardDetect |= GPIO_SD2_CD;
+ }
+
+ /* stop SD output clock */
+ pSd_Reg->busm &= ~BIT4;
+ udelay(100000); /* for SD card, need to delay 100 ms. */
+
+ /* Pull up/down resister of SD Bus */
+ if (SDDevInfo->CtrlID == 0) {
+ /*Disable Clock & CMD Pull enable*/
+ *GPIO_PULL_Enable_SD &= ~(GPIO_SD0_Clock | GPIO_SD0_Command);
+
+ /*Set CD ,WP ,DATA pin pull up*/
+ *GPIO_PULL_Control_SDCardDetect |= GPIO_SD0_CD;
+ *GPIO_PULL_Control_SD |= (GPIO_SD0_Data | GPIO_SD0_WriteProtect);
+ *GPIO_PULL_Control_SD018SEL |= GPIO_SD0_18SEL;
+
+ /*Enable CD ,WP ,DATA internal pull*/
+ *GPIO_PULL_Enable_SDCardDetect |= GPIO_SD0_CD;
+ *GPIO_PULL_Enable_SD |= (GPIO_SD0_Data | GPIO_SD0_WriteProtect);
+ *GPIO_PULL_Enable_SD018SEL |= GPIO_SD0_18SEL;
+
+ } else if (SDDevInfo->CtrlID == 1) {
+ /*Disable Clock & CMD Pull enable*/
+ *GPIO_PULL_Enable_SD1 &= ~(GPIO_SD1_Clock | GPIO_SD1_Command);
+
+ /*Set CD ,WP ,DATA pin pull up*/
+ /* SD1 no card detect feature Bow */
+ /**GPIO_PULL_Control_SD1 |= GPIO_SD1_CD;*/
+ *GPIO_PULL_Control_SD1 |= GPIO_SD1_WriteProtect;
+ *GPIO_PULL_Control_SD1Data |= GPIO_SD1_Data;
+
+ /*Enable CD ,WP ,DATA internal pull*/
+ /* SD1 no card detect feature Bow */
+ /**GPIO_PULL_Enable_SD1 |= GPIO_SD1_CD;*/
+ *GPIO_PULL_Enable_SD1 |= GPIO_SD1_WriteProtect;
+ *GPIO_PULL_Enable_SD1Data |= GPIO_SD1_Data;
+
+ } else if (SDDevInfo->CtrlID == 2) {
+ /*Disable Clock & CMD Pull enable*/
+ *GPIO_PULL_Enable_SD2 &= ~(GPIO_SD2_Clock | GPIO_SD2_Command);
+
+ /*Set CD ,WP ,DATA pin pull up*/
+ *GPIO_PULL_Control_SD2CardDetect |= GPIO_SD2_CD;
+ *GPIO_PULL_Control_SD2 |= (GPIO_SD2_Data | GPIO_SD2_WriteProtect);
+
+ /*Enable CD ,WP ,DATA internal pull*/
+ *GPIO_PULL_Enable_SD2CardDetect |= GPIO_SD2_CD;
+ *GPIO_PULL_Enable_SD2 |= (GPIO_SD2_Data | GPIO_SD2_WriteProtect);
+
+ }
+
+ udelay(10000);
+ /*enable SD power*/
+ if (SDDevInfo->CtrlID == 0) {
+ /*Enable SD0 power*/
+ *GPIO_OUTPUT_DATA_SD &= ~GPIO_SD0_POWER;
+ } else if (SDDevInfo->CtrlID == 1) {
+ /*Ensable SD1 power*/
+ *GPIO_OUTPUT_DATA_SD1 &= ~GPIO_SD1_POWER;
+ } else if (SDDevInfo->CtrlID == 2) {
+ /*Ensable SD2 power*/
+ *GPIO_OUTPUT_DATA_SD2 &= ~GPIO_SD2_POWER;
+ }
+
+ /* issue softReset to SD controller */
+ pSd_Reg->busm = SOFT_RESET;
+
+ /* automatic clock freezing enable */
+ pSd_Reg->str2 = DIS_FORCECLK;
+
+ pSd_Reg->timeval = 0xefff;
+ SD_Init_PDMA();
+
+ /* clear card_insert in STS0[7] */
+ pSd_Reg->str0 = DEVICE_INS;
+
+ /* SD clock = 400Khz */
+ sd_set_clock(SD_Clk_400KHz);
+
+ /* enable SD output clock */
+ pSd_Reg->busm |= 0x10;
+ udelay(10000);
+
+
+ /* Config SD back to function */
+ if (SDDevInfo->CtrlID == 0) {
+ *GPIO_Enable_SD &= ~(GPIO_SD0_Clock | GPIO_SD0_Command | GPIO_SD0_WriteProtect | GPIO_SD0_Data);
+ *GPIO_Enable_SDCardDetect &= ~GPIO_SD0_CD;
+ *GPIO_Enable_SD018SEL &= ~GPIO_SD0_18SEL;
+ } else if (SDDevInfo->CtrlID == 1) {
+ *GPIO_Enable_SD1 &= ~(GPIO_SD1_Clock | GPIO_SD1_Command | GPIO_SD1_WriteProtect | GPIO_SD1_RSTN);
+ /* SD1 no card detect feature Bow */
+ /**GPIO_Enable_SD1CardDetect &= ~GPIO_SD1_CD;*/
+ *GPIO_Enable_SD1Data &= ~GPIO_SD1_Data;
+ } else if (SDDevInfo->CtrlID == 2) {
+ *GPIO_Enable_SD2 &= ~(GPIO_SD2_Clock | GPIO_SD2_Command | GPIO_SD2_WriteProtect | GPIO_SD2_Data);
+ *GPIO_Enable_SD2CardDetect &= ~GPIO_SD2_CD;
+ }
+
+ /* issue softReset to SD controller */
+ //pSd_Reg->busm= SOFT_RESET;
+ card_nop();
+}
+
+
+int SD_card_inserted(void)
+{
+ int ret;
+ SD_Controller_Powerup();
+
+ sd_command(GO_IDLE_STATE, 0, 0x0, R0); /*reset SD Card*/
+ ret = sd_command(APP_CMD, 0, 0x0, R1);
+ if (!ret)
+ ret = sd_command(SD_APP_OP_COND, 0, 0x0, R3); /*send ACMD41 to get card's require voltage range*/
+ if (!ret)
+ return 1; /*inserted*/
+ else
+ return 0; /*not inserted*/
+}
+
+
+int mmc_wfs_read(unsigned long dev, unsigned long addr, char *filename, unsigned long bytes) {
+
+
+ disk_partition_t pt;
+ char buffer[512];
+ root_dir *RootDir = buffer;
+ unsigned long blkcnt = 0;
+ unsigned long blk_addr = 0;
+ unsigned long status = 0;
+
+ Change_SD_host(dev);
+
+ if (!mmc_ready) {
+ printf("Please initial the SD/MMC first\n");
+ return -1;
+ }
+#if 0
+ printf("mmc_wfs_read\n");
+ printf("<dev> : 0x%x\n",dev);
+ printf("<addr> : 0x%x\n",addr);
+ printf("<filename> : %s\n",filename);
+ printf("<bytes> : 0x%x\n",bytes);
+#endif
+ get_partition_info(mmc_dev, 1, &pt);
+#if 0
+ printf("\nPartition info\n");
+ printf("offset = 0x%x\n", pt.offset);
+ printf("start = 0x%x\n", pt.start);
+ printf("size = 0x%x 0x%xMB\n", pt.size, pt.size/2048);
+ printf("blksz = 0x%x\n", pt.blksz);
+ printf("name = %s\n", &pt.name);
+ printf("type = %s\n", &pt.type);
+#endif
+ /*Read Root Dir*/
+ mmc_bread(dev, pt.start, 1, RootDir);
+
+ if (strcmp(RootDir->MagicHeader, "WMTBLS!") != 0) {
+ printf("The MagicHeader is not correct '%s'\n",RootDir->MagicHeader);
+ return -1;
+ }
+#if 0
+ printf("RootDir->MagicHeader = %s\n",RootDir->MagicHeader);
+ printf("RootDir->filename1 = %s\n",RootDir->filename1);
+ printf("RootDir->filesize1 = 0x%x\n",RootDir->filesize1);
+ printf("RootDir->filename2 = %s\n",RootDir->filename2);
+ printf("RootDir->filesize2 = 0x%x\n",RootDir->filesize2);
+ printf("RootDir->filename3 = %s\n",RootDir->filename3);
+ printf("RootDir->filesize3 = 0x%x\n",RootDir->filesize3);
+#endif
+ if (strcmp(filename, "wx-load.bin") == 0) {
+ if (bytes > 0) {
+ blkcnt = bytes/MMC_BLOCK_SIZE;
+
+ if (bytes % MMC_BLOCK_SIZE)
+ blkcnt++;
+ } else {
+ blkcnt = RootDir->filesize1/MMC_BLOCK_SIZE;
+
+ if (RootDir->filesize1 % MMC_BLOCK_SIZE)
+ blkcnt++;
+ }
+
+ blk_addr = pt.start + (0x10000 / MMC_BLOCK_SIZE);
+
+ status = mmc_bread(dev, blk_addr, blkcnt, addr);
+
+ if (status == -1)
+ return -1;
+ } else if (strcmp(filename, "wmt-env.bin") == 0){
+ if (bytes > 0) {
+ blkcnt = bytes/MMC_BLOCK_SIZE;
+
+ if (bytes % MMC_BLOCK_SIZE)
+ blkcnt++;
+ } else {
+ blkcnt = RootDir->filesize2/MMC_BLOCK_SIZE;
+
+ if (RootDir->filesize2 % MMC_BLOCK_SIZE)
+ blkcnt++;
+ }
+
+ blk_addr = pt.start + (0x20000 / MMC_BLOCK_SIZE);
+
+ status = mmc_bread(dev, blk_addr, blkcnt, addr);
+
+ if (status == -1)
+ return -1;
+ } else if (strcmp(filename, "u-boot.bin") == 0) {
+ if (bytes > 0) {
+ blkcnt = bytes/MMC_BLOCK_SIZE;
+
+ if (bytes % MMC_BLOCK_SIZE)
+ blkcnt++;
+ } else {
+ blkcnt = RootDir->filesize3/MMC_BLOCK_SIZE;
+
+ if (RootDir->filesize3 % MMC_BLOCK_SIZE)
+ blkcnt++;
+ }
+
+ blk_addr = pt.start + (0x30000 / MMC_BLOCK_SIZE);
+
+ status = mmc_bread(dev, blk_addr, blkcnt, addr);
+
+ if (status == -1)
+ return -1;
+ } else
+ return -1;
+
+
+ return 0;
+
+}
+
+int mmc_wfs_write(unsigned long dev, unsigned long addr, char *filename, unsigned long bytes) {
+
+ disk_partition_t pt;
+ char buffer[512];
+ root_dir *RootDir = buffer;
+ unsigned long blkcnt = 0;
+ unsigned long blk_addr = 0;
+ unsigned long status = 0;
+ int i = 0;
+
+
+ Change_SD_host(dev);
+
+ if (!mmc_ready) {
+ printf("Please initial the SD/MMC first\n");
+ return -1;
+ }
+
+#if 0
+ printf("mmc_wfs_read\n");
+ printf("<dev> : 0x%x\n",dev);
+ printf("<addr> : 0x%x\n",addr);
+ printf("<filename> : %s\n",filename);
+ printf("<bytes> : 0x%x\n",bytes);
+#endif
+ get_partition_info(mmc_dev, 1, &pt);
+#if 0
+ printf("\nPartition info\n");
+ printf("offset = 0x%x\n", pt.offset);
+ printf("start = 0x%x\n", pt.start);
+ printf("size = 0x%x 0x%xMB\n", pt.size, pt.size/2048);
+ printf("blksz = 0x%x\n", pt.blksz);
+ printf("name = %s\n", &pt.name);
+ printf("type = %s\n", &pt.type);
+#endif
+
+ /*Read Root Dir*/
+ mmc_bread(dev, pt.start, 1, (unsigned long *)RootDir);
+
+ strcpy(RootDir->MagicHeader, "WMTBLS!");
+
+
+ if (strcmp(filename, "wx-load.bin") == 0) {
+ blkcnt = bytes/MMC_BLOCK_SIZE;
+
+ if (bytes % MMC_BLOCK_SIZE)
+ blkcnt++;
+
+ RootDir->filesize1 = bytes;
+
+ strcpy(RootDir->filename1, "wx-load.bin");
+
+ blk_addr = pt.start + (0x10000 / MMC_BLOCK_SIZE);
+
+ status = mmc_bwrite(dev, blk_addr, blkcnt, addr);
+
+ if (status == -1)
+ return -1;
+
+ /*Write RootDir*/
+ status = mmc_bwrite(dev, pt.start, 1, RootDir);
+ if (status == -1)
+ return -1;
+
+
+ } else if (strcmp(filename, "wmt-env.bin") == 0){
+ blkcnt = bytes/MMC_BLOCK_SIZE;
+
+ if (bytes % MMC_BLOCK_SIZE)
+ blkcnt++;
+
+ RootDir->filesize2 = bytes;
+
+ strcpy(RootDir->filename2, "wmt-env.bin");
+
+ blk_addr = pt.start + (0x20000 / MMC_BLOCK_SIZE);
+
+ status = mmc_bwrite(dev, blk_addr, blkcnt, addr);
+
+ if (status == -1)
+ return -1;
+
+ /*Write RootDir*/
+ status = mmc_bwrite(dev, pt.start, 1, RootDir);
+ if (status == -1)
+ return -1;
+ } else if (strcmp(filename, "u-boot.bin") == 0) {
+ blkcnt = bytes/MMC_BLOCK_SIZE;
+
+ if (bytes % MMC_BLOCK_SIZE)
+ blkcnt++;
+
+ RootDir->filesize3 = bytes;
+
+ strcpy(RootDir->filename3, "u-boot.bin");
+
+ blk_addr = pt.start + (0x30000 / MMC_BLOCK_SIZE);
+
+ status = mmc_bwrite(dev, blk_addr, blkcnt, addr);
+
+ if (status == -1)
+ return -1;
+
+ /*Write RootDir*/
+ status = mmc_bwrite(dev, pt.start, 1, RootDir);
+ if (status == -1)
+ return -1;
+ } else
+ return -1;
+
+
+
+#if 0
+ printf("RootDir = 0x%x\n",RootDir);
+ printf("RootDir->MagicHeader = %s\n",RootDir->MagicHeader);
+ printf("RootDir->filename1 = %s\n",RootDir->filename1);
+ printf("RootDir->filesize1 = 0x%x\n",RootDir->filesize1);
+ printf("RootDir->filename2 = %s\n",RootDir->filename2);
+ printf("RootDir->filesize2 = 0x%x\n",RootDir->filesize2);
+ printf("RootDir->filename3 = %s\n",RootDir->filename3);
+ printf("RootDir->filesize3 = 0x%x\n",RootDir->filesize3);
+#endif
+
+ return 0;
+}
+
+#endif /* CONFIG_MMC */