Files
TAIXIN/sdk/lib/sdhost/emmc.c

137 lines
3.2 KiB
C

#include "sys_config.h"
#include "typesdef.h"
#include "devid.h"
#include "list.h"
#include "dev.h"
#include "osal/task.h"
#include "osal/semaphore.h"
#include "osal/mutex.h"
#include "lib/sdhost/sdhost.h"
#include "lib/sdhost/mmc.h"
#include "lib/sdhost/mmc_ops.h"
#include "hal/gpio.h"
#include "osal/irq.h"
#include "osal/string.h"
#include "osal/mutex.h"
#include "osal/irq.h"
#include "osal/task.h"
#include "osal/sleep.h"
#include "osal/timer.h"
#include "osal/work.h"
extern void sdhost_io_func_init(uint32 req);
extern uint32 sd_power_up(struct sdh_device *host,uint8 bus_w);
extern void sd_set_clk(struct sdh_device * host,uint32 clk);
#if 1
#define EMMC_PRINTF(fmt, arg...) printf(fmt, ##arg)
#else
#define EMMC_PRINTF(fmt, arg...)
#endif
uint32_t send_op_cond(struct sdh_device *host,
uint32_t ocr,
uint32_t *rocr)
{
struct rt_mmcsd_cmd cmd;
int ret;
memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
cmd.cmd_code = SEND_OP_COND;
cmd.arg = ocr;
cmd.flags = RESP_SPI_R1 | RESP_R3 | CMD_BCR;
ret = ((const struct sdhc_hal_ops *)host->dev.ops)->cmd(host, &cmd);
if(ret){
EMMC_PRINTF("cmd%d err\r\n", cmd.cmd_code);
}
EMMC_PRINTF("cmd resp:%x\r\n",cmd.resp[0]);
if(rocr)
*rocr = cmd.resp[0];
return ret;
}
int emmc_init(struct sdh_device * host, uint32 clk)
{
uint32_t ocr;
uint8_t bw = 1;
uint8_t *ext_csd = NULL;
if(((const struct sdhc_hal_ops *)host->dev.ops)->open)
((const struct sdhc_hal_ops *)host->dev.ops)->open(host, 1, SD_MODE_TYPE);
host->flags |= MMCSD_BUSWIDTH_4;
os_printf("host->flags:%x\r\n",host->flags);
sdhost_io_func_init(host->flags);
if(bw == 4)
sd_power_up(host, MMCSD_BUSWIDTH_4);
else
sd_power_up(host,0);
sd_set_clk(host, 400*1000);
send_idle(host);
send_op_cond(host, 0x40FF8080, &ocr);
while(!(ocr & 0x80000000))
{
os_sleep_ms(5);
send_op_cond(host, 0x40FF8080, &ocr);
}
send_all_get_cid(host, host->resp_cid);
EMMC_PRINTF("cid0: 0x%x cid1: 0x%x\r\n", host->resp_cid[0], host->resp_cid[1]);
host->rca = 1;
mmc_set_card_addr(host, host->rca);
EMMC_PRINTF("rca: 0x%x\r\n", host->rca);
//解析csd (to do)
send_get_csd(host, host->resp_csd);
host->card_blksize = 1 << GET_BITS(host->resp_csd, 80, 4);
EMMC_PRINTF("emmc spec verision: 0x%x\r\n", GET_BITS(host->resp_csd, 122, 4));
EMMC_PRINTF("max clock frequency %d\r\n", GET_BITS(host->resp_csd, 96, 3) * GET_BITS(host->resp_csd, 99, 4));
EMMC_PRINTF("block len: %d\r\n", host->card_blksize);
//select card
send_select_card(host);
//解析ext_csd (to do)
ext_csd = os_malloc(512);
if(!ext_csd) {
EMMC_PRINTF("ext_csd malloc fail\r\n");
}
mmc_get_ext_csd(host, ext_csd);
mmc_parse_ext_csd(host, ext_csd);
//切换bus width
// mmc_select_bus_width(host, ext_csd);
//配置驱动能力
//设置频率 & 采样调谐
#ifndef FPGA_SUPPORT
#endif
sd_set_clk(host, clk);
host->cardflags |= CARD_FLAG_SDHC;
os_free(ext_csd);
EMMC_PRINTF("emmc init done\r\n");
return 0;
}