Esempio n. 1
0
int
/****************************************************/
mmc_block_write(ulong dst, uchar *src, int len)
/****************************************************/
{
	uchar *resp;
	ushort argh, argl;
	ulong status;

	if (len == 0) {
		return 0;
	}

	debug("mmc_block_wr dst %lx src %lx len %d\n", dst, (ulong)src, len);

	argh = len >> 16;
	argl = len & 0xffff;

	/* set block len */
	resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, argh, argl, MMC_CMDAT_R1);

	/* send write command */
	argh = dst >> 16;
	argl = dst & 0xffff;
	MMC_STRPCL = MMC_STRPCL_STOP_CLK;
	MMC_NOB = 1;
	MMC_BLKLEN = len;
	resp = mmc_cmd(MMC_CMD_WRITE_BLOCK, argh, argl,
			MMC_CMDAT_R1|MMC_CMDAT_WRITE|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN);

	MMC_I_MASK = ~MMC_I_MASK_TXFIFO_WR_REQ;
	while (len) {
		if (MMC_I_REG & MMC_I_REG_TXFIFO_WR_REQ) {
			int i, bytes = min(32,len);

			for (i=0; i<bytes; i++) {
				MMC_TXFIFO = *src++;
			}
			if (bytes < 32) {
				MMC_PRTBUF = MMC_PRTBUF_BUF_PART_FULL;
			}
			len -= bytes;
		}
		status = MMC_STAT;
		if (status & MMC_STAT_ERRORS) {
			printf("MMC_STAT error %lx\n", status);
			return -1;
		}
	}
	MMC_I_MASK = ~MMC_I_MASK_DATA_TRAN_DONE;
	while (!(MMC_I_REG & MMC_I_REG_DATA_TRAN_DONE));
	MMC_I_MASK = ~MMC_I_MASK_PRG_DONE;
	while (!(MMC_I_REG & MMC_I_REG_PRG_DONE));
	status = MMC_STAT;
	if (status & MMC_STAT_ERRORS) {
		printf("MMC_STAT error %lx\n", status);
		return -1;
	}
	return 0;
}
Esempio n. 2
0
File: sd_boot.c Progetto: ykli/misc
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);
	}
}
Esempio n. 3
0
/* init mmc/sd card we assume that the card is in the slot */
static int  mmc_init(unsigned int msc_clkrt_val)
{
    int retries, ret;
    u8 *resp;
    //unsigned int msc_clk_div = (__cpm_get_pllout())/24000000;
    __msc_reset();
    mmc_init_gpio();
    REG_MSC_IMASK = 0xffff;
    REG_MSC_IREG = 0xffff;
    REG_MSC_CLKRT = 6;    //200k

    /* just for reading and writing, suddenly it was reset, and the power of sd card was not broken off */
    resp = mmc_cmd(12, 0, 0x41, MSC_CMDAT_RESPONSE_R1);

    /* reset */
    resp = mmc_cmd(0, 0, 0x80, 0);
    resp = mmc_cmd(8, 0x1aa, 0x1, MSC_CMDAT_RESPONSE_R1);
    resp = mmc_cmd(55, 0, 0x1, MSC_CMDAT_RESPONSE_R1);
    if(resp[5] == 0x37) {
        resp = mmc_cmd(41, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3);
        if(resp[5] == 0x3f)
            ret = sd_init(msc_clkrt_val);
        return ret;
    }
    ret = mmc_found(msc_clkrt_val);
    return ret;
}
Esempio n. 4
0
int
/****************************************************/
mmc_block_read(uchar *dst, ulong src, ulong len)
/****************************************************/
{
	uchar *resp;
	ushort argh, argl;
	ulong status;

	if (len == 0)
	{
		return 0;
	}

	debug("mmc_block_rd dst %lx src %lx len %d\n", (ulong)dst, src, len);

	argh = len >> 16;
	argl = len & 0xffff;

	/* set block len */
	resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, argh, argl, MMC_CMDAT_R1);

	/* send read command */
	argh = src >> 16;
	argl = src & 0xffff;
	MMC_STRPCL = MMC_STRPCL_STOP_CLK;
	MMC_RDTO = 0xffff;
	MMC_NOB = 1;
	MMC_BLKLEN = len;
	resp = mmc_cmd(MMC_CMD_READ_BLOCK, argh, argl,
			MMC_CMDAT_R1|MMC_CMDAT_READ|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN);


	MMC_I_MASK = ~MMC_I_MASK_RXFIFO_RD_REQ;
	while (len)
	{
		if (MMC_I_REG & MMC_I_REG_RXFIFO_RD_REQ)
		{
			*dst++ = MMC_RXFIFO;
			len--;
		}
		status = MMC_STAT;
		if (status & MMC_STAT_ERRORS)
		{
			printf("MMC_STAT error %lx\n", status);
			return -1;
		}
	}
	MMC_I_MASK = ~MMC_I_MASK_DATA_TRAN_DONE;
	while (!(MMC_I_REG & MMC_I_REG_DATA_TRAN_DONE));
	status = MMC_STAT;
	if (status & MMC_STAT_ERRORS)
	{
		printf("MMC_STAT error %lx\n", status);
		return -1;
	}
	return 0;
}
Esempio n. 5
0
File: sd_boot.c Progetto: ykli/misc
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;
}
Esempio n. 6
0
static void sd_init(void)
{
	int retries;
	u8 *resp;
	unsigned int cardaddr;

	resp = mmc_cmd(41, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3);
	retries = 500;
	while (retries-- && resp && !(resp[4] & 0x80)) {
		resp = mmc_cmd(55, 0, 0x1, MSC_CMDAT_RESPONSE_R1);
		resp = mmc_cmd(41, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3);
		udelay(1000);
		udelay(1000);
	}

	if (resp[4] & 0x80) 
		serial_puts("SD init ok\n");
	else 
		serial_puts("SD init fail\n");

	/* try to get card id */
	resp = mmc_cmd(2, 0, 0x2, MSC_CMDAT_RESPONSE_R2);
	resp = mmc_cmd(3, 0, 0x6, MSC_CMDAT_RESPONSE_R1);
	cardaddr = (resp[4] << 8) | resp[3]; 
	rca = cardaddr << 16;
	resp = mmc_cmd(9, rca, 0x2, MSC_CMDAT_RESPONSE_R2);
	sd2_0 = (resp[14] & 0xc0) >> 6;
	REG_MSC_CLKRT = 2;    //2 is ok ,dont't grater
	resp = mmc_cmd(7, rca, 0x41, MSC_CMDAT_RESPONSE_R1);
	resp = mmc_cmd(55, rca, 0x1, MSC_CMDAT_RESPONSE_R1);
	resp = mmc_cmd(6, 0x2, 0x401, MSC_CMDAT_RESPONSE_R1);
}
Esempio n. 7
0
static void sd_init(void)
{
	int retries, wait;
	u8 *resp;
	unsigned int cardaddr;
	serial_puts("SD card found!\n");

	resp = mmc_cmd(41, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3);
	retries = 100;
	while (retries-- && resp && !(resp[4] & 0x80)) {
		resp = mmc_cmd(55, 0, 0x1, MSC_CMDAT_RESPONSE_R1);
		resp = mmc_cmd(41, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3);
		sd_mdelay(10);
	}

	if (resp[4] & 0x80) 
		serial_puts("MMC/SD init ok\n");
	else 
		serial_puts("SD init fail\n");

	/* try to get card id */
	resp = mmc_cmd(2, 0, 0x2, MSC_CMDAT_RESPONSE_R2);
	resp = mmc_cmd(3, 0, 0x6, MSC_CMDAT_RESPONSE_R1);
	cardaddr = (resp[4] << 8) | resp[3]; 
	rca = cardaddr << 16;

	resp = mmc_cmd(9, rca, 0x2, MSC_CMDAT_RESPONSE_R2);
	highcap = (resp[14] & 0xc0) >> 6;
	REG_MSC_CLKRT = 0;
	resp = mmc_cmd(7, rca, 0x41, MSC_CMDAT_RESPONSE_R1);
	resp = mmc_cmd(55, rca, 0x1, MSC_CMDAT_RESPONSE_R1);
	resp = mmc_cmd(6, 0x2, 0x401, MSC_CMDAT_RESPONSE_R1);
}
Esempio n. 8
0
/* init mmc/sd card we assume that the card is in the slot */
static int  mmc_init(void)
{
	int retries;
	u8 *resp;

	__gpio_as_msc();
	__msc_reset();
	MMC_IRQ_MASK();	

	REG_CPM_MSCCDR = __cpm_get_pllout2()%24000000 ? __cpm_get_pllout2()/24000000 : __cpm_get_pllout2()/24000000 - 1;
	REG_CPM_CPCCR |= CPM_CPCCR_CE;

	REG_MSC_CLKRT = 7;    //250k
	REG_MSC_RDTO = 0xffffffff;

	resp = mmc_cmd(12, 0, 0x41, MSC_CMDAT_RESPONSE_R1);
	/* reset */
	resp = mmc_cmd(0, 0, 0x80, 0);
	resp = mmc_cmd(8, 0x1aa, 0x1, MSC_CMDAT_RESPONSE_R1);
	resp = mmc_cmd(55, 0, 0x1, MSC_CMDAT_RESPONSE_R1);
	if(!(resp[0] & 0x20) && (resp[5] != 0x37)) { 
		resp = mmc_cmd(1, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3);
		retries = 500;
		while (retries-- && resp && !(resp[4] & 0x80)) {
			resp = mmc_cmd(1, 0x40300000, 0x3, MSC_CMDAT_RESPONSE_R3);
			udelay(1000);
			udelay(1000);
		}

		if ((resp[4] & 0x80 ) == 0x80) 
			serial_puts("MMC init ok\n");
		else 
			serial_puts("MMC init fail\n");

		if((resp[4] & 0x60) == 0x40)
			highcap = 1;
		else
			highcap = 0;
	
		/* try to get card id */
		resp = mmc_cmd(2, 0, 0x2, MSC_CMDAT_RESPONSE_R2);
		resp = mmc_cmd(3, 0x10, 0x1, MSC_CMDAT_RESPONSE_R1);

		REG_MSC_CLKRT = 2;	/* 16/1 MHz */
		resp = mmc_cmd(7, 0x10, 0x1, MSC_CMDAT_RESPONSE_R1);
		resp = mmc_cmd(6, 0x3b70101, 0x441, MSC_CMDAT_RESPONSE_R1);
		while(!(REG_MSC_STAT & MSC_STAT_PRG_DONE))
			;
		REG_MSC_IREG |= MSC_IREG_PRG_DONE;
	}
	else
		sd_init();
	return 0;
}
Esempio n. 9
0
int init_MMC(int max_tries)
{
	int i,tries,c;
	tries=0;
		
	output_low(ChipSel);   /// reset chip hardware !!! required
	delay_ms(100);

	for(tries=0; tries < max_tries; tries++)
	{
		output_high(ChipSel);   /// reset chip hardware !!! required
		delay_ms(20);
		for(i=0;i<20;i++) 
			SPI_READ(0xFF); // min 80 clocks to get MMC ready

		output_low(ChipSel);   ///                      !!! required
	
		delay_ms(20);

		c=mmc_cmd(0x40,0x00000000,128,0x01,0x99);

		if (c==0x01) 
			break;
	}
	
	if(tries >= max_tries)
	{
		output_high(ChipSel);
		return MMC_INIT_RESET_ERR;
	}

	/// now try  to switch to idle mode
	/// Note: cmd1(idle) is the only command allowed after a cmd0(reset)

	for(tries=0; tries < max_tries; tries++)
	{
		c=mmc_cmd(0x41,0x00000000,128,0x00,0x99);
		if (c==0x00) 
			break;
	}

	output_high(ChipSel);
	
	if(tries >= max_tries)
		return MMC_INIT_IDLE_ERR;
		
	return MMC_NO_ERR;

}
Esempio n. 10
0
static int
mmc_acmd(unsigned long cmd, unsigned long arg, void *resp, unsigned long flags)
{
	unsigned long aresp[4];
	int ret = 0;

	ret = mmc_cmd(MMC_CMD_APP_CMD, 0, aresp,
		      MMC_RSP_PRESENT);
	if (ret)
		return ret;

	if ((aresp[0] & (ILLEGAL_COMMAND | APP_CMD)) != APP_CMD)
		return -ENODEV;
	ret = mmc_cmd(cmd, arg, resp, flags);
	return ret;
}
Esempio n. 11
0
/* init mmc/sd card we assume that the card is in the slot */
static int  mmc_init(void)
{
	int retries;
	u8 *resp;

	__gpio_as_msc();
	__msc_reset();
	MMC_IRQ_MASK();	
	__cpm_select_msc_clk(0,1);
	REG_MSC_CLKRT = 7;    //250k

	resp = mmc_cmd(12, 0, 0x41, MSC_CMDAT_RESPONSE_R1);
	/* reset */
	resp = mmc_cmd(0, 0, 0x80, 0);
	resp = mmc_cmd(8, 0x1aa, 0x1, MSC_CMDAT_RESPONSE_R1);
	resp = mmc_cmd(55, 0, 0x1, MSC_CMDAT_RESPONSE_R1);
	if(!(resp[0] & 0x20) && (resp[5] != 0x37)) { 
		resp = mmc_cmd(1, 0xff8000, 0x3, MSC_CMDAT_RESPONSE_R3);
		retries = 500;
		while (retries-- && resp && !(resp[4] & 0x80)) {
			resp = mmc_cmd(1, 0x40300000, 0x3, MSC_CMDAT_RESPONSE_R3);
			udelay(1000);
			udelay(1000);
		}

		if (resp[4]== 0x80) 
			serial_puts("MMC init ok\n");
		else 
			serial_puts("MMC init fail\n");

		/* try to get card id */
		resp = mmc_cmd(2, 0, 0x2, MSC_CMDAT_RESPONSE_R2);
		resp = mmc_cmd(3, 0x10, 0x1, MSC_CMDAT_RESPONSE_R1);

		REG_MSC_CLKRT = 2;	/* 16/1 MHz */
		resp = mmc_cmd(7, 0x10, 0x1, MSC_CMDAT_RESPONSE_R1);
		resp = mmc_cmd(6, 0x3b70101, 0x401, MSC_CMDAT_RESPONSE_R1);
	}
	else
		sd_init();
	return 0;
}
Esempio n. 12
0
/* init mmc/sd card we assume that the card is in the slot */
int  mmc_init(void)
{
	int retries, wait;
	u8 *resp;

	__gpio_as_msc();
	__msc_reset();
	MMC_IRQ_MASK();	
	REG_MSC_CLKRT = 7;    //250k
	REG_MSC_RDTO = 0xffffffff;

	serial_puts("\n\nMMC/SD INIT\n");

	/* reset */
	resp = mmc_cmd(0, 0, 0x80, 0);
	resp = mmc_cmd(8, 0x1aa, 0x1, MSC_CMDAT_RESPONSE_R1);
	resp = mmc_cmd(55, 0, 0x1, MSC_CMDAT_RESPONSE_R1);
	if(!(resp[0] & 0x20) && (resp[5] != 0x37)) { 
		serial_puts("MMC card found!\n");
		resp = mmc_cmd(1, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3);
		retries = 100;
		while (retries-- && resp && !(resp[4] & 0x80)) {
			resp = mmc_cmd(1, 0x40300000, 0x3, MSC_CMDAT_RESPONSE_R3);
			sd_mdelay(10);
		}

		if ((resp[4] & 0x80) == 0x80) 
			serial_puts("MMC init ok\n");
		else 
			serial_puts("MMC init fail\n");
		
		if((resp[4] & 0x60) == 0x40)
			highcap = 1;
		else
			highcap = 0;
		/* try to get card id */
		resp = mmc_cmd(2, 0, 0x2, MSC_CMDAT_RESPONSE_R2);
		resp = mmc_cmd(3, 0x10, 0x1, MSC_CMDAT_RESPONSE_R1);

		REG_MSC_CLKRT = 0;	/* 16/1 MHz */
		resp = mmc_cmd(7, 0x10, 0x1, MSC_CMDAT_RESPONSE_R1);
		resp = mmc_cmd(6, 0x3b70101, 0x441, MSC_CMDAT_RESPONSE_R1);
	}
	else
		sd_init();
	return 0;
}
Esempio n. 13
0
File: sd_boot.c Progetto: ykli/misc
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;
}
Esempio n. 14
0
static int sd_init(unsigned int msc_clkrt_val)
{
    int retries, wait;
//	int rca;
    u8 *resp;
    unsigned int cardaddr;
    serial_puts("SD card found!\n");
    resp = mmc_cmd(55, 0, 0x1, MSC_CMDAT_RESPONSE_R1);
    resp = mmc_cmd(41, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3);
    retries = 500;
    while (retries-- && resp && !(resp[4] & 0x80)) {
        resp = mmc_cmd(55, 0, 0x1, MSC_CMDAT_RESPONSE_R1);
        resp = mmc_cmd(41, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3);

        sd_mdelay(10);
    }

    if ((resp[4] & 0x80) == 0x80)
        serial_puts("SD init ok\n");
    else {
        serial_puts("SD init fail\n");
        return -1;
    }
    /* try to get card id */
    resp = mmc_cmd(2, 0, 0x2, MSC_CMDAT_RESPONSE_R2);
    serial_puts("CID=");
    serial_dump_data(resp, 15);
    resp = mmc_cmd(3, 0, 0x6, MSC_CMDAT_RESPONSE_R1);
    cardaddr = (resp[4] << 8) | resp[3];
    rca = cardaddr << 16;

    resp = mmc_cmd(9, rca, 0x2, MSC_CMDAT_RESPONSE_R2);
    highcap = (resp[14] & 0xc0) >> 6;
    REG_MSC_CLKRT = msc_clkrt_val;
    resp = mmc_cmd(7, rca, 0x41, MSC_CMDAT_RESPONSE_R1);
    resp = mmc_cmd(55, rca, 0x1, MSC_CMDAT_RESPONSE_R1);
    resp = mmc_cmd(6, BUS_WIDTH, 0x1 | (BUS_WIDTH << 9), MSC_CMDAT_RESPONSE_R1);
    return 0;
}
static int mmc_acmd(unsigned long cmd, unsigned long arg,
		    void *resp, unsigned long flags)
{
	unsigned long aresp[4];
	int ret;

	/*
	 * Seems like the APP_CMD part of an ACMD has 64 cycles max
	 * latency even though the ACMD part doesn't. This isn't
	 * entirely clear in the SD Card spec, but some cards refuse
	 * to work if we attempt to use 5 cycles max latency here...
	 */
	ret = mmc_cmd(MMC_CMD_APP_CMD, 0, aresp,
		      R1 | NCR | (flags & OPEN_DRAIN));
	if (ret)
		return ret;
	if ((aresp[0] & (R1_ILLEGAL_COMMAND | R1_APP_CMD)) != R1_APP_CMD)
		return -ENODEV;

	ret = mmc_cmd(cmd, arg, resp, flags);
	return ret;
}
Esempio n. 16
0
File: sd_boot.c Progetto: ykli/misc
int mmc_block_read(u32 size, u32 *dst)
{
	u8 *resp;
	u32 nob, cnt, stat;

	resp = mmc_cmd(16, 0x200, 0x1, MSC_CMDAT_RESPONSE_R1);

	REG_MSC_BLKLEN(ctl_num) = 0x200;
	REG_MSC_NOB(ctl_num) = size / 512;

	resp = mmc_cmd(18, 0x0, 0x9, MSC_CMDAT_RESPONSE_R1);	//more than 16
	nob = size / 64;

	for (; nob > 0; nob--) {
		while(1){
			stat = REG_MSC_STAT(ctl_num);
			if (stat & (MSC_STAT_TIME_OUT_READ | MSC_STAT_CRC_READ_ERROR)) {
				goto err;
			}

			if(!(stat & MSC_STAT_DATA_FIFO_EMPTY))
				break;
		}

		cnt = 16;		//16 words
		while (cnt--) {
			while (!(REG_MSC_IREG(ctl_num) & MSC_IREG_RXFIFO_RD_REQ))
				;
			*dst = REG_MSC_RXFIFO(ctl_num);
			if (size - (nob * 64) >= redundancy_size)
				dst++;
		}
	}
	resp = mmc_cmd(12, 0, 0x1, MSC_CMDAT_RESPONSE_R1);
	return 0;
err:
	return 1;
}
Esempio n. 17
0
static int mmc_found(unsigned int msc_clkrt_val)
{
    int retries;
    u8 *resp;
    int ocr;

    serial_puts("MMC card found!\n");
    resp = mmc_cmd(1, 0x40ff8000, 0x3, MSC_CMDAT_RESPONSE_R3);
    retries = 1000;
    while (retries-- && resp && !(resp[4] & 0x80)) {
        resp = mmc_cmd(1, 0x40300000, 0x3, MSC_CMDAT_RESPONSE_R3);
        ocr = (resp[4] << 24) | (resp[3] << 16) | (resp[2] << 8) | resp[1];
        serial_puts("  ocr = ");
        serial_put_hex(ocr);
        sd_mdelay(10);
    }

    sd_mdelay(10);

    if ((resp[4] & 0x80 )== 0x80)
        serial_puts("MMC init ok\n");
    else {
        serial_puts("MMC init fail\n");
        return -1;
    }
    if((resp[4] & 0x60 ) == 0x40)
        highcap = 1;
    else
        highcap =0;
    /* try to get card id */
    resp = mmc_cmd(2, 0, 0x2, MSC_CMDAT_RESPONSE_R2);
    serial_puts("CID=");
    serial_dump_data(resp, 15);

    resp = mmc_cmd(3, 0x10, 0x1, MSC_CMDAT_RESPONSE_R1);

    REG_MSC_CLKRT = msc_clkrt_val;	/* 16/1 MHz */
    resp = mmc_cmd(7, 0x10, 0x1, MSC_CMDAT_RESPONSE_R1);

    if(BUS_WIDTH == 2) {
        resp = mmc_cmd(6, 0x3b70101, 0x441, MSC_CMDAT_RESPONSE_R1);
    }
    else if(BUS_WIDTH == 0) {
        resp = mmc_cmd(6, 0x3b30001, 0x41, MSC_CMDAT_RESPONSE_R1);
    }
    return 0;
}
Esempio n. 18
0
int ReadSector( int32 sector, char *buff)
{
	int r1;
	long i,iw; /// allows large gt 255 buff size addressing

	output_low(ChipSel);   
	delay_ms(1);
	
	TRACE1("\r\nRead sector# %lu.", sector);
	
	r1=mmc_cmd(0x51,sector<<9,16,0x00,0x40);

	if(r1 == 0x40)
	{
		output_high(ChipSel);
		return MMC_READ_INVALID_ERR;
	}
	else if(r1 != 0x00)
	{
		output_high(ChipSel);
		return MMC_READ_GEN_ERR;
	}
	
	//Get token
	for(iw=0;iw<1024;iw++)
	{
		r1=SPI_READ(0xFF);
		if (r1==0xFE) 
			break;
	}
	
	//Get token error. It may be caused by improper MMC reset
	if(r1 != 0xFE)
	{
		output_high(ChipSel);
		return MMC_READ_TOKEN_ERR;
	}
#ifdef SPEED_BOOST
	FSR0 = buff;            // Set start address in index register
   	for (i=0;i<512;i++)
   	{
     // POSTINC0 = SPI_READ(0xFF); // Write data to Buffer and increase address
     	WRITE_SSP(0xFF);
     	WAIT_FOR_SSP();
     	POSTINC0 = READ_SSP();
    }  
#else
	//Read the whole sector (512 bytes)
	for (i=0;i<512;i++) 
		buff[i]=SPI_READ(0xFF);
#endif

	SPI_READ(0xFF); // read crc
	SPI_READ(0xFF);

#ifdef TRACE_READ_SECTOR
	fprintf(debug, "\r\nRead sector #%lu:", sector);

	for(i = 0; i<512; i++)
	{
		if(i%16 == 0)
			fprintf(debug, "\r\n%04LX - ", i);
		r1 = *buff;
		if(r1 < ' ' || r1 > 'z')
			r1 = '.';
		fprintf(debug, "%02X%c ", *buff++, r1);

	}
#endif

	output_high(ChipSel);
	return MMC_NO_ERR;
}
Esempio n. 19
0
static int mmc_block_writem(u32 src, u32 num, u8 *dst)
{
    u8 *resp;
    u32 stat, timeout, data, cnt, wait, nob, i, j;
    u32 *wbuf = (u32 *)dst;

    resp = mmc_cmd(16, 0x200, 0x1, MSC_CMDAT_RESPONSE_R1);
    REG_MSC_BLKLEN = 0x200;
    REG_MSC_NOB = num / 512;

    if (highcap)
        resp = mmc_cmd(25, src, 0x19 | (BUS_WIDTH << 9), MSC_CMDAT_RESPONSE_R1); // for sdhc card
    else
        resp = mmc_cmd(25, src * 512, 0x19 | (BUS_WIDTH << 9), MSC_CMDAT_RESPONSE_R1);
    nob  = num / 512;
    timeout = 0x3ffffff;
    //serial_puts("nob ==w===");serial_put_hex(nob);
    //serial_dump_data(dst, 16);
    for (i = 0; i < nob; i++) {
        timeout = 0x3FFFFFF;
        while (timeout) {
            timeout--;
            stat = REG_MSC_STAT;

            if (stat & (MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_WRITE_ERROR_NOSTS))
                return -1;
            else if (!(stat & MSC_STAT_DATA_FIFO_FULL)) {
                /* Ready to write data */
                break;
            }

            wait = 336;
            while (wait--)
                ;
        }
        if (!timeout)
            return -1;

        /* Write data to TXFIFO */
        cnt = 128;
        while (cnt) {
            //stat = REG_MSC_STAT;
            //serial_puts("stat ==write===");serial_put_hex(stat);
            while(!(REG_MSC_IREG & MSC_IREG_TXFIFO_WR_REQ))
                ;
            for (j=0; j<16; j++)
            {
                //serial_put_hex(*wbuf);
                REG_MSC_TXFIFO = *wbuf++;
                cnt--;
            }
        }
    }
#if 0
    while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE)) ;
    REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE;	/* clear status */

    resp = mmc_cmd(12, 0, 0x441, MSC_CMDAT_RESPONSE_R1);
    while (!(REG_MSC_IREG & MSC_IREG_PRG_DONE)) ;
    REG_MSC_IREG = MSC_IREG_PRG_DONE;	/* clear status */

#else
    while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE)) ;
    REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE;	/* clear status */

    while (!(REG_MSC_STAT & MSC_STAT_PRG_DONE)) ;
    REG_MSC_IREG = MSC_IREG_PRG_DONE;	/* clear status */

    resp = mmc_cmd(12, 0, 0x441, MSC_CMDAT_RESPONSE_R1);
    do {
        resp = mmc_cmd(13, rca, 0x1, MSC_CMDAT_RESPONSE_R1); // for sdhc card
    } while(!(resp[2] & 0x1));   //wait the card is ready for data

#endif
    jz_mmc_stop_clock();
    //return src+nob;
    return 0;
}
Esempio n. 20
0
static int mmc_block_readm(u32 src, u32 num, u8 *dst)
{
    u8 *resp;
    u32 stat, timeout, data, cnt, wait, nob;

    resp = mmc_cmd(16, 0x200, 0x401, MSC_CMDAT_RESPONSE_R1);
    REG_MSC_BLKLEN = 0x200;
    REG_MSC_NOB = num / 512;

    if (highcap)
        resp = mmc_cmd(18, src,  0x10409, MSC_CMDAT_RESPONSE_R1); // for sdhc card
    else
        resp = mmc_cmd(18, src * 512, 0x10409, MSC_CMDAT_RESPONSE_R1);
    nob  = num / 512;
    //serial_puts("nob ==r===");serial_put_hex(nob);
    //serial_puts("src ==r===");serial_put_hex(src);
    for (nob; nob >= 1; nob--) {
        timeout = 0x7ffffff;
        while (timeout) {
            timeout--;
            stat = REG_MSC_STAT;

            if (stat & MSC_STAT_TIME_OUT_READ) {
                serial_puts("\n MSC_STAT_TIME_OUT_READ\n\n");
                return -1;
            }
            else if (stat & MSC_STAT_CRC_READ_ERROR) {
                serial_puts("\n MSC_STAT_CRC_READ_ERROR\n\n");
                return -1;
            }
            else if (!(stat & MSC_STAT_DATA_FIFO_EMPTY)) {
                /* Ready to read data */
                break;
            }
            wait = 336;
            while (wait--)
                ;
        }
        if (!timeout) {
            serial_puts("\n mmc/sd read timeout\n");
            return -1;
        }

        /* Read data from RXFIFO. It could be FULL or PARTIAL FULL */
        cnt = 128;
        while (cnt) {
            while (cnt && (REG_MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY))
                ;
            cnt --;
            data = REG_MSC_RXFIFO;
            {
                *dst++ = (u8)(data >> 0);
                *dst++ = (u8)(data >> 8);
                *dst++ = (u8)(data >> 16);
                *dst++ = (u8)(data >> 24);
            }
        }
    }
#if defined(MSC_STAT_AUTO_CMD_DONE)
    while(!(REG_MSC_STAT & MSC_STAT_AUTO_CMD_DONE));
#else
    resp = mmc_cmd(12, 0, 0x41, MSC_CMDAT_RESPONSE_R1);
    while (!(REG_MSC_STAT & MSC_STAT_DATA_TRAN_DONE));
#endif
    jz_mmc_stop_clock();
    return 0;
}
static unsigned long
mmc_bread(int dev, unsigned long start, lbaint_t blkcnt,
	  unsigned long *buffer)
{
	int ret, i = 0;
	unsigned long resp[4];
	unsigned long card_status, data;
	unsigned long wordcount;
	u32 status;

	if (blkcnt == 0)
		return 0;

	pr_debug("mmc_bread: dev %d, start %lx, blkcnt %lx\n",
		 dev, start, blkcnt);

	/* Put the device into Transfer state */
	ret = mmc_cmd(MMC_CMD_SELECT_CARD, mmc_rca << 16, resp, R1 | NCR);
	if (ret) goto fail;

	/* Set block length */
	ret = mmc_cmd(MMC_CMD_SET_BLOCKLEN, mmc_blkdev.blksz, resp, R1 | NCR);
	if (ret) goto fail;

	pr_debug("MCI_DTOR = %08lx\n", mmci_readl(DTOR));

	for (i = 0; i < blkcnt; i++, start++) {
		ret = mmc_cmd(MMC_CMD_READ_SINGLE_BLOCK,
			      start * mmc_blkdev.blksz, resp,
			      (R1 | NCR | TRCMD_START | TRDIR_READ
			       | TRTYP_BLOCK));
		if (ret) goto fail;

		ret = -EIO;
		wordcount = 0;
		do {
			do {
				status = mmci_readl(SR);
				if (status & (ERROR_FLAGS | MMCI_BIT(OVRE)))
					goto fail;
			} while (!(status & MMCI_BIT(RXRDY)));

			if (status & MMCI_BIT(RXRDY)) {
				data = mmci_readl(RDR);
				/* pr_debug("%x\n", data); */
				*buffer++ = data;
				wordcount++;
			}
		} while(wordcount < (mmc_blkdev.blksz / 4));

		pr_debug("mmc: read %u words, waiting for BLKE\n", wordcount);

		do {
			status = mmci_readl(SR);
		} while (!(status & MMCI_BIT(BLKE)));

		putc('.');
	}

out:
	/* Put the device back into Standby state */
	mmc_cmd(MMC_CMD_SELECT_CARD, 0, resp, NCR);
	return i;

fail:
	mmc_cmd(MMC_CMD_SEND_STATUS, mmc_rca << 16, &card_status, R1 | NCR);
	printf("mmc: bread failed, card status = %08x\n", card_status);
	goto out;
}
Esempio n. 22
0
static int mmc_block_writem(u32 src, u32 num, u8 *dst)
{
	u8 *resp;
	u32 stat, timeout, cnt, nob, sorm;
	u32 *wbuf = (u32 *)dst;

	resp = mmc_cmd(16, 0x200, 0x401, MSC_CMDAT_RESPONSE_R1);
	REG_MSC_BLKLEN = 0x200;
	REG_MSC_NOB = num / 512;
	nob  = num / 512;

	if (nob == 1) {
		if (highcap)
			resp = mmc_cmd(24, src, 0x419, MSC_CMDAT_RESPONSE_R1);
		else
			resp = mmc_cmd(24, src * 512, 0x419, MSC_CMDAT_RESPONSE_R1);

		sorm = 0;
	} else {
		if (highcap)
			resp = mmc_cmd(25, src, 0x419, MSC_CMDAT_RESPONSE_R1); // for sdhc card
		else
			resp = mmc_cmd(25, src * 512, 0x419, MSC_CMDAT_RESPONSE_R1);

		sorm = 1;
	}

	for (nob; nob >= 1; nob--) {
		timeout = 0x3FFFFFF;

		while (timeout) {
			timeout--;
			stat = REG_MSC_STAT;
			if (stat & (MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_WRITE_ERROR_NOSTS)) {
				serial_puts("\n MSC_STAT_CRC_WRITE_ERROR\n\n");
				return -1;
			}
			else if (!(stat & MSC_STAT_DATA_FIFO_FULL)) {
				/* Ready to write data */
				break;
			}

			udelay(1);
		}

		if (!timeout)
			return -1;

		/* Write data to TXFIFO */
		cnt = 128;
		while (cnt) {
			while (REG_MSC_STAT & MSC_STAT_DATA_FIFO_FULL)
				;
			REG_MSC_TXFIFO = *wbuf++;
			cnt--;
		}
	}

	if (sorm)
		resp = mmc_cmd(12, 0, 0x41, MSC_CMDAT_RESPONSE_R1);

	while (!(REG_MSC_STAT & MSC_STAT_DATA_TRAN_DONE))
		;
	
	REG_MSC_IREG |= MSC_IREG_DATA_TRAN_DONE;	

	while (!(REG_MSC_STAT & MSC_STAT_PRG_DONE))
		;
	REG_MSC_IREG |= MSC_IREG_PRG_DONE;	

	jz_mmc_stop_clock();
	return 0;
}
Esempio n. 23
0
static int mmc_block_readm(u32 src, u32 num, u8 *dst)
{
	u8 *resp;
	u32 stat, timeout, data, cnt, nob, sorm;

	resp = mmc_cmd(16, 0x200, 0x401, MSC_CMDAT_RESPONSE_R1);
	REG_MSC_BLKLEN = 0x200;
	REG_MSC_NOB = num / 512;
	nob  = num / 512;

	if (nob == 1) {
		if (highcap)
			resp = mmc_cmd(17, src, 0x409, MSC_CMDAT_RESPONSE_R1);
		else
			resp = mmc_cmd(17, src * 512, 0x409, MSC_CMDAT_RESPONSE_R1);
			
		sorm = 0;
	} else {
		if (highcap)
			resp = mmc_cmd(18, src, 0x409, MSC_CMDAT_RESPONSE_R1);
		else
			resp = mmc_cmd(18, src * 512, 0x409, MSC_CMDAT_RESPONSE_R1);

		sorm = 1;
	}

	for (nob; nob >= 1; nob--) {
		timeout = 0x3ffffff;

		while (timeout) {
			timeout--;
			stat = REG_MSC_STAT;
			if (stat & MSC_STAT_TIME_OUT_READ) {
				serial_puts("\n MSC_STAT_TIME_OUT_READ\n\n");
				return -1;
			}
			else if (stat & MSC_STAT_CRC_READ_ERROR) {
				serial_puts("\n MSC_STAT_CRC_READ_ERROR\n\n");
				return -1;
			}
			else if (!(stat & MSC_STAT_DATA_FIFO_EMPTY)) {
				/* Ready to read data */
				break;
			}
			udelay(1);
		}
		if (!timeout) {
			serial_puts("\n mmc/sd read timeout\n");
			return -1;
		}

		/* Read data from RXFIFO. It could be FULL or PARTIAL FULL */
		cnt = 128;
		while (cnt) {
			while (cnt && (REG_MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY))
				;
			cnt --;

			data = REG_MSC_RXFIFO;
			{
				*dst++ = (u8)(data >> 0);
				*dst++ = (u8)(data >> 8);
				*dst++ = (u8)(data >> 16);
				*dst++ = (u8)(data >> 24);
			}
		}
	}

	if (sorm)
		resp = mmc_cmd(12, 0, 0x41, MSC_CMDAT_RESPONSE_R1);

	while (!(REG_MSC_STAT & MSC_STAT_DATA_TRAN_DONE))
		;
	
	REG_MSC_IREG |= MSC_IREG_DATA_TRAN_DONE;	

	jz_mmc_stop_clock();
	return 0;
}
Esempio n. 24
0
static unsigned long
mmc_bwrite(int dev, unsigned long start, lbaint_t blkcnt, const void *buffer)
{
	int ret, i = 0;
	unsigned long resp[4];
	unsigned long card_status;
	const __u8 *buf = buffer;
	__u32 status;
	__u16 data_ctl = 0;
	__u16 dma_cfg = 0;

	if (blkcnt == 0)
		return 0;
		
	debug("mmc_bwrite: dev %d, start %lx, blkcnt %lx\n",
		 dev, start, blkcnt);
	/* Force to use 512-byte block,because a lot of code depends on this */
	data_ctl |= 9 << 4;
	data_ctl &= ~DTX_DIR;
	bfin_write_SDH_DATA_CTL(data_ctl);
	dma_cfg |= WDSIZE_32 | RESTART | DMAEN;
	/* FIXME later */
	bfin_write_SDH_DATA_TIMER(0xFFFFFFFF);
	for (i = 0; i < blkcnt; ++i, ++start) {
		bfin_write_DMA_START_ADDR(buf + i * mmc_blkdev.blksz);
		bfin_write_DMA_X_COUNT(mmc_blkdev.blksz / 4);
		bfin_write_DMA_X_MODIFY(4);
		bfin_write_DMA_CONFIG(dma_cfg);
		bfin_write_SDH_DATA_LGTH(mmc_blkdev.blksz);

		/* Put the device into Transfer state */
		ret = mmc_cmd(MMC_CMD_SELECT_CARD, mmc_rca << 16, resp, MMC_RSP_R1);
		if (ret) {
			printf("MMC_CMD_SELECT_CARD failed\n");
			goto out;
		}
		/* Set block length */
		ret = mmc_cmd(MMC_CMD_SET_BLOCKLEN, mmc_blkdev.blksz, resp, MMC_RSP_R1);
		if (ret) {
			printf("MMC_CMD_SET_BLOCKLEN failed\n");
			goto out;
		}
		ret = mmc_cmd(MMC_CMD_WRITE_SINGLE_BLOCK,
			      start * mmc_blkdev.blksz, resp,
			      MMC_RSP_R1);
		if (ret) {
			printf("MMC_CMD_WRITE_SINGLE_BLOCK failed\n");
			goto out;
		}
		bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E);

		do {
			udelay(1);
			status = bfin_read_SDH_STATUS();
		} while (!(status & (DAT_BLK_END | DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | TX_UNDERRUN)));

		if (status & (DAT_TIME_OUT | DAT_CRC_FAIL | TX_UNDERRUN)) {
			bfin_write_SDH_STATUS_CLR(DAT_TIMEOUT_STAT |
				DAT_CRC_FAIL_STAT | TX_UNDERRUN_STAT);
			goto write_error;
		} else {
			bfin_write_SDH_STATUS_CLR(DAT_BLK_END_STAT | DAT_END_STAT);
			mmc_cmd(MMC_CMD_SELECT_CARD, 0, resp, 0);
		}
	}
 out:
	return i;

 write_error:
	mmc_cmd(MMC_CMD_SEND_STATUS, mmc_rca << 16, &card_status, MMC_RSP_R1);
	printf("mmc: bwrite failed, status = %08x, card status = %08lx\n",
	       status, card_status);
	goto out;
}
Esempio n. 25
0
int
/****************************************************/
mmc_init(int verbose)
/****************************************************/
{
 	int retries, rc = -ENODEV;
	uchar *resp;

#ifdef CONFIG_LUBBOCK
	set_GPIO_mode( GPIO6_MMCCLK_MD );
	set_GPIO_mode( GPIO8_MMCCS0_MD );
#endif
	CKEN |= CKEN12_MMC; /* enable MMC unit clock */

	mmc_csd.c_size = 0;

	MMC_CLKRT  = MMC_CLKRT_0_3125MHZ;
	MMC_RESTO  = MMC_RES_TO_MAX;
	MMC_SPI    = MMC_SPI_DISABLE;

	/* reset */
	retries = 10;
	resp = mmc_cmd(0, 0, 0, 0);
	resp = mmc_cmd(1, 0x00ff, 0xc000, MMC_CMDAT_INIT|MMC_CMDAT_BUSY|MMC_CMDAT_R3);
	while (retries-- && resp && !(resp[4] & 0x80))
	{
		debug("resp %x %x\n", resp[0], resp[1]);
		udelay(50);
		resp = mmc_cmd(1, 0x00ff, 0xff00, MMC_CMDAT_BUSY|MMC_CMDAT_R3);
	}

	/* try to get card id */
	resp = mmc_cmd(2, 0, 0, MMC_CMDAT_R2);
	if (resp)
	{
		/* TODO configure mmc driver depending on card attributes */
		mmc_cid_t *cid = (mmc_cid_t *)resp;
		if (verbose)
		{
			printf("MMC found. Card desciption is:\n");
			printf("Manufacturer ID = %02x%02x%02x\n",
							cid->id[0], cid->id[1], cid->id[2]);
			printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev);
			cid->hwrev = cid->fwrev = 0;	/* null terminate string */
			printf("Product Name = %s\n",cid->name);
			printf("Serial Number = %02x%02x%02x\n",
							cid->sn[0], cid->sn[1], cid->sn[2]);
			printf("Month = %d\n",cid->month);
			printf("Year = %d\n",1997 + cid->year);
		}
		/* fill in device description */
		mmc_dev.if_type = IF_TYPE_MMC;
		mmc_dev.dev = 0;
		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 = 0x10000;
		sprintf(mmc_dev.vendor,"Man %02x%02x%02x Snr %02x%02x%02x",
				cid->id[0], cid->id[1], cid->id[2],
				cid->sn[0], cid->sn[1], cid->sn[2]);
		sprintf(mmc_dev.product,"%s",cid->name);
		sprintf(mmc_dev.revision,"%x %x",cid->hwrev, cid->fwrev);
		mmc_dev.removable = 0;
		mmc_dev.block_read = mmc_bread;

		/* MMC exists, get CSD too */
		resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
		resp = mmc_cmd(MMC_CMD_SEND_CSD, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R2);
		if (resp)
		{
			mmc_csd_t *csd = (mmc_csd_t *)resp;
			memcpy(&mmc_csd, csd, sizeof(csd));
			rc = 0;
			mmc_ready = 1;
			/* FIXME add verbose printout for csd */
		}
	}

	MMC_CLKRT = 0;	/* 20 MHz */
	resp = mmc_cmd(7, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);

	fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */

	return rc;
}
Esempio n. 26
0
int WriteSector(int32 sector, char *buff)

{
	int r1;
	int16 i;


	TRACE1("\r\nWriteSector(%lu).", sector);

	if(sector == 0)	//never write sector 0
		return MMC_WRITE_SEC0_ERR;

	output_low(ChipSel);
	delay_ms(1);
	
	r1=mmc_cmd(0x58,sector<<9,16,0x00,0x40);


	if(r1 == 0x40)
	{
		output_high(ChipSel);	
		return MMC_WRITE_INVALID_ERR;
	}
	else if(r1 != 0x00)
	{
		output_high(ChipSel);
		return MMC_WRITE_GEN_ERR;
	}

	SPI_READ(0xFE);

#ifdef SPEED_BOOST
	FSR0 = buff;            // Set start address in index register
   	for (i=0;i<512;i++)
   	{
		//	SPI_READ(POSTINC0);  /// send payload
		WRITE_SSP(POSTINC0);
		WAIT_FOR_SSP();
	}
#else
	for (i=0;i < 512;i++) 
	{
		SPI_READ(buff[i]);  /// send payload
	}
#endif

	SPI_READ(0xFF); // send dummy chcksum
	SPI_READ(0xFF);
	r1=SPI_READ(0xFF);
	for( i=0;i<0x0fff;i++) 
	{
		r1=SPI_READ(0xFF);// digest prior operation
		if (r1!=0x00) 
			break;
	}

#ifdef TRACE_WRITE_SECTOR
	fprintf(debug, "\r\nWrite sector #%lu:", sector);

	for(i = 0; i<512; i++)
	{
		if(i%16 == 0)
			fprintf(debug, "\r\n%04LX - ", i);
		r1 = *buff;
		if(r1 < ' ' || r1 > 'z')
			r1 = '.';
		fprintf(debug, "%02X%c ", *buff++, r1);

	}

#endif

	output_high(ChipSel);
	return MMC_NO_ERR;
}
Esempio n. 27
0
File: sd_boot.c Progetto: ykli/misc
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);
	}
}