unsigned char mmc_send_cmd(unsigned int base, unsigned int cmd,
			unsigned int arg, unsigned int *response)
{
	unsigned int mmc_stat;
	unsigned int cmd_index = cmd >> 24;

	while ((OMAP_HSMMC_PSTATE(base) & DATI_MASK) == DATI_CMDDIS);

#ifdef CONFIG_USBBOOT_ERASER
/* support multi write for emmc erase */
	OMAP_HSMMC_STAT(base) = 0xFFFFFFFF;
	OMAP_HSMMC_ARG(base) = arg;
	if (cmd_index == 0x19) { /* CMD25: Multi block write */
		OMAP_HSMMC_CMD(base) = cmd | CMD_TYPE_NORMAL | CICE_NOCHECK |
			CCCE_NOCHECK | MSBS | BCE | ACEN_DISABLE | DE_DISABLE;
	} else if (cmd_index == 0xC) {
		OMAP_HSMMC_CMD(base) = cmd | 0x3 << 22 | CICE_NOCHECK |
		CCCE_NOCHECK | ACEN_DISABLE | BCE_DISABLE |
			DE_DISABLE;
	} else {
		OMAP_HSMMC_BLK(base) = BLEN_512BYTESLEN | NBLK_STPCNT;
		OMAP_HSMMC_CMD(base) = cmd | CMD_TYPE_NORMAL | CICE_NOCHECK |
		CCCE_NOCHECK | MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE |
			DE_DISABLE;
	}
#else
	OMAP_HSMMC_BLK(base) = BLEN_512BYTESLEN | NBLK_STPCNT;
	OMAP_HSMMC_STAT(base) = 0xFFFFFFFF;
	OMAP_HSMMC_ARG(base) = arg;
	OMAP_HSMMC_CMD(base) = cmd | CMD_TYPE_NORMAL | CICE_NOCHECK |
	    CCCE_NOCHECK | MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE |
	    DE_DISABLE;
#endif

	while (1) {
		do {
			mmc_stat = OMAP_HSMMC_STAT(base);
		} while (mmc_stat == 0);

		if ((mmc_stat & ERRI_MASK) != 0)
			return (unsigned char)mmc_stat;


		if (mmc_stat & CC_MASK) {
			OMAP_HSMMC_STAT(base) = CC_MASK;
			response[0] = OMAP_HSMMC_RSP10(base);
			if ((cmd & RSP_TYPE_MASK) == RSP_TYPE_LGHT136) {
				response[1] = OMAP_HSMMC_RSP32(base);
				response[2] = OMAP_HSMMC_RSP54(base);
				response[3] = OMAP_HSMMC_RSP76(base);
			}
			break;
		}
	}
	return 1;
}
Beispiel #2
0
Datei: mmc.c Projekt: UAVXP/A10
unsigned char mmc_send_cmd(unsigned int base, unsigned int cmd,
			unsigned int arg, unsigned int *response)
{
	unsigned int mmc_stat;
	unsigned int cmd_index = cmd >> 24;

	while ((OMAP_HSMMC_PSTATE(base) & DATI_MASK) == DATI_CMDDIS)
		;

	OMAP_HSMMC_STAT(base) = 0xFFFFFFFF;
	OMAP_HSMMC_ARG(base) = arg;
//++ Peter_20100914, Add Mulit Block Read.
#if 0
	if (cmd_index == 0x19) { /* CMD25: Multi block write */
#else
	if ((cmd_index == 0x19)||(cmd_index == 0x12)) { /* CMD25: Multi block write */ /* CMD18: Multi block read */
#endif
//-- Peter_20100914, Add Mulit Block Read.
		OMAP_HSMMC_CMD(base) = cmd | CMD_TYPE_NORMAL | CICE_NOCHECK |
			CCCE_NOCHECK | MSBS | BCE | ACEN_DISABLE | DE_DISABLE;
	} else {
		OMAP_HSMMC_BLK(base) = BLEN_512BYTESLEN | NBLK_STPCNT;
		OMAP_HSMMC_CMD(base) = cmd | CMD_TYPE_NORMAL | CICE_NOCHECK |
			CCCE_NOCHECK | MSBS_SGLEBLK | ACEN_DISABLE |
			BCE_DISABLE | DE_DISABLE;
	}

	while (1) {
		do {
			mmc_stat = OMAP_HSMMC_STAT(base);
		} while (mmc_stat == 0);

		if ((mmc_stat & ERRI_MASK) != 0)
			return (unsigned char)mmc_stat;


		if (mmc_stat & CC_MASK) {
			OMAP_HSMMC_STAT(base) = CC_MASK;
			response[0] = OMAP_HSMMC_RSP10(base);
			if ((cmd & RSP_TYPE_MASK) == RSP_TYPE_LGHT136) {
				response[1] = OMAP_HSMMC_RSP32(base);
				response[2] = OMAP_HSMMC_RSP54(base);
				response[3] = OMAP_HSMMC_RSP76(base);
			}
			break;
		}
	}
	return 1;
}

unsigned char mmc_read_data(unsigned int base, unsigned int *output_buf)
{
	unsigned int mmc_stat;
	unsigned int read_count = 0;

	/*
	 * Start Polled Read
	 */
	while (1) {
		do {
			mmc_stat = OMAP_HSMMC_STAT(base);
		} while (mmc_stat == 0);

		if ((mmc_stat & ERRI_MASK) != 0)
			return (unsigned char)mmc_stat;

		if (mmc_stat & BRR_MASK) {
			unsigned int k;

			OMAP_HSMMC_STAT(base) |= BRR_MASK;
			for (k = 0; k < MMCSD_SECTOR_SIZE / 4; k++) {
				*output_buf = OMAP_HSMMC_DATA(base);
				output_buf++;
				read_count += 4;
			}
		}

		if (mmc_stat & BWR_MASK)
			OMAP_HSMMC_STAT(base) |= BWR_MASK;

		if (mmc_stat & TC_MASK) {
			OMAP_HSMMC_STAT(base) |= TC_MASK;
			break;
		}
	}
	return 1;
}