137 lines
3.2 KiB
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;
|
||
|
|
}
|