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; }
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; }
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; }
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; }
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; }
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; }
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; }