Exemplo n.º 1
0
Arquivo: mmc.c Projeto: UAVXP/A10
unsigned char mmc_write_data(unsigned int base, unsigned int *input_buf)
{
	unsigned int mmc_stat;

	/*
	 * Start Polled Write
	 */
	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 & BWR_MASK) {
			unsigned int k;

			OMAP_HSMMC_STAT(base) |= BWR_MASK;
			for (k = 0; k < MMCSD_SECTOR_SIZE / 4; k++) {
				OMAP_HSMMC_DATA(base) = *input_buf;
				input_buf++;
			}
		}

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

		if (mmc_stat & TC_MASK) {
			OMAP_HSMMC_STAT(base) |= TC_MASK;
			break;
		}
	}
	return 1;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
void mmc_init_stream(mmc_controller_data *mmc_cont_cur)
{
	OMAP_HSMMC_CON(mmc_cont_cur->base) |= INIT_INITSTREAM;

	OMAP_HSMMC_CMD(mmc_cont_cur->base) = MMC_CMD0;
	while (!(OMAP_HSMMC_STAT(mmc_cont_cur->base) & CC_MASK));

	OMAP_HSMMC_STAT(mmc_cont_cur->base) = CC_MASK;

	OMAP_HSMMC_CMD(mmc_cont_cur->base) = MMC_CMD0;
	while (!(OMAP_HSMMC_STAT(mmc_cont_cur->base) & CC_MASK));


	OMAP_HSMMC_STAT(mmc_cont_cur->base) =
				OMAP_HSMMC_STAT(mmc_cont_cur->base);
	OMAP_HSMMC_CON(mmc_cont_cur->base) &= ~INIT_INITSTREAM;
}
Exemplo n.º 4
0
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);
		mmc_stat_last=mmc_stat;

		if ((mmc_stat & ERRI_MASK) != 0) {
			printf("mmc read data error  0x%x\n", mmc_stat);
			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;
}
Exemplo n.º 5
0
int mmc_write_data(unsigned int base, unsigned int *input_buf)
{
	unsigned int mmc_stat;
	int count = 0;

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

		if ((mmc_stat & ERRI_MASK) != 0) {
			printf("mmc write error %08x\n", mmc_stat);
			return -1;
		}

		if (mmc_stat & BWR_MASK) {
			unsigned int k;

			OMAP_HSMMC_STAT(base) |= BWR_MASK;
			for (k = 0; k < MMCSD_SECTOR_SIZE / 4; k++) {
				OMAP_HSMMC_DATA(base) = *input_buf;
				input_buf++;
			}
			count++;
		}

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

		if (mmc_stat & TC_MASK) {
			OMAP_HSMMC_STAT(base) |= TC_MASK;
			break;
		}
	}
	return count;
}
Exemplo n.º 6
0
unsigned char omap_mmc_erase_sect(unsigned int start,
	mmc_controller_data *mmc_cont_cur, mmc_card_data *mmc_c, int size)
{
	unsigned char err;
	unsigned int argument;
	unsigned int num_sec_val;
	unsigned int sec_inc_val;
	unsigned int resp[4];
	unsigned int mmc_stat;
	unsigned int blk_cnt_current_tns;

	if ((start / MMCSD_SECTOR_SIZE) > mmc_c->size ||
			((start + size) / MMCSD_SECTOR_SIZE) > mmc_c->size) {
		printf("mmc erase: erase to Sector is\n"
			"out of card range\n");
		return 1;
	}
	num_sec_val = (size + (MMCSD_SECTOR_SIZE - 1)) / MMCSD_SECTOR_SIZE;
	if (mmc_c->mode == SECTOR_MODE) {
		argument = start;
		sec_inc_val = 1;
	} else {
		argument = start * MMCSD_SECTOR_SIZE;
		sec_inc_val = MMCSD_SECTOR_SIZE;
	}
	while (num_sec_val) {
		if (num_sec_val > 0xFFFF)
			blk_cnt_current_tns = 0xFFFF;
		else
			blk_cnt_current_tns = num_sec_val;

		/* check for Multi Block */
		if (blk_cnt_current_tns > 1) {

			OMAP_HSMMC_BLK(mmc_cont_cur->base) = BLEN_512BYTESLEN |
						(blk_cnt_current_tns << 16);

			err = mmc_send_cmd(mmc_cont_cur->base,
					MMC_CMD25, argument, resp);
			if (err != 1)
				return err;

		} else {
			err = mmc_send_cmd(mmc_cont_cur->base, MMC_CMD24,
								argument, resp);
			if (err != 1)
				return err;
		}
		while (1) {
			do {
				mmc_stat = OMAP_HSMMC_STAT(mmc_cont_cur->base);
			} while (mmc_stat == 0);

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

			if (mmc_stat & BWR_MASK) {
				unsigned int k;

				OMAP_HSMMC_STAT(mmc_cont_cur->base) |= BWR_MASK;
				for (k = 0; k < MMCSD_SECTOR_SIZE / 4; k++) {
					OMAP_HSMMC_DATA(mmc_cont_cur->base) =
								0XFFFFFFFF;
				}
			}

			if (mmc_stat & BRR_MASK)
				OMAP_HSMMC_STAT(mmc_cont_cur->base) |= BRR_MASK;

			if (mmc_stat & TC_MASK) {
				OMAP_HSMMC_STAT(mmc_cont_cur->base) |= TC_MASK;
				break;
			}
		}

		if (blk_cnt_current_tns > 1) {
			err = mmc_send_cmd(mmc_cont_cur->base,
						MMC_CMD12, 0, resp);

			if (err != 1) {
				printf("MMC_CMD12 failed 0x%x\n", err);
				return err;
			}
		}

		argument += sec_inc_val * blk_cnt_current_tns;
		num_sec_val -= blk_cnt_current_tns;
	}
	return 1;
}
Exemplo n.º 7
0
Arquivo: mmc.c Projeto: 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;
}