#include #include "bk_arm_arch.h" #if CONFIG_SDCARD #include "sdio_driver.h" #include "bk_drv_model.h" #include "bk_sys_ctrl.h" #include #include "bk_icu.h" #include "bk_gpio.h" #include #include "gpio_driver.h" #include #if CONFIG_SOC_BK7256XX #include "sys_types.h" #include "sys_driver.h" #include #endif /******************************************************************************/ /**************************** platform function *******************************/ /******************************************************************************/ /******************************************************************************/ /**************************** interface function ******************************/ /******************************************************************************/ #if (CONFIG_SOC_BK7256XX) /* clk_index: includes clock src and clock divider info */ void sdio_set_clock(UINT8 clk_index) { //temp code, will be switch to sdcard_driver.c *((volatile unsigned long *) (0x44010000+0x9*4)) = (((*((volatile unsigned long *) (0x44010000+0x9*4))) & (~0x3C000)) | ((clk_index) << 14)); } #else static void beken_sdcard_set_clk_div(UINT8 clkdiv) { UINT32 reg; reg = REG_READ(REG_SDCARD_FIFO_THRESHOLD); reg &= ~(SDCARD_FIFO_SD_RATE_SELECT_MASK << SDCARD_FIFO_SD_RATE_SELECT_POSI); reg |= ((clkdiv & SDCARD_FIFO_SD_RATE_SELECT_MASK) << SDCARD_FIFO_SD_RATE_SELECT_POSI); REG_WRITE(REG_SDCARD_FIFO_THRESHOLD, reg); } void sdio_set_clock(UINT8 clk_index) { beken_sdcard_set_clk_div(clk_index); } #endif #if (CONFIG_SOC_BK7256XX) #if (CONFIG_PIN_SDIO_GROUP_0) #define PIN_ID_SDIO_CLK (GPIO_14) #define PIN_ID_SDIO_CMD (GPIO_15) #define PIN_ID_SDIO_D0 (GPIO_16) #define PIN_ID_SDIO_D1 (GPIO_17) #define PIN_ID_SDIO_D2 (GPIO_18) #define PIN_ID_SDIO_D3 (GPIO_19) #else #define PIN_ID_SDIO_CLK (GPIO_2) #define PIN_ID_SDIO_CMD (GPIO_3) #define PIN_ID_SDIO_D0 (GPIO_4) #define PIN_ID_SDIO_D1 (GPIO_5) #define PIN_ID_SDIO_D2 (GPIO_10) #define PIN_ID_SDIO_D3 (GPIO_11) #endif void sdio_gpio_config(void) { gpio_dev_unmap(PIN_ID_SDIO_CLK); gpio_dev_unmap(PIN_ID_SDIO_CMD); gpio_dev_unmap(PIN_ID_SDIO_D0); #if CONFIG_SDCARD_BUSWIDTH_4LINE gpio_dev_unmap(PIN_ID_SDIO_D1); gpio_dev_unmap(PIN_ID_SDIO_D2); gpio_dev_unmap(PIN_ID_SDIO_D3); #endif gpio_dev_map(PIN_ID_SDIO_CLK, GPIO_DEV_SDIO_HOST_CLK); bk_gpio_pull_up(PIN_ID_SDIO_CLK); bk_gpio_set_capacity(PIN_ID_SDIO_CLK, 3); gpio_dev_map(PIN_ID_SDIO_CMD, GPIO_DEV_SDIO_HOST_CMD); bk_gpio_pull_up(PIN_ID_SDIO_CMD); bk_gpio_set_capacity(PIN_ID_SDIO_CMD, 3); gpio_dev_map(PIN_ID_SDIO_D0, GPIO_DEV_SDIO_HOST_DATA0); bk_gpio_pull_up(PIN_ID_SDIO_D0); bk_gpio_set_capacity(PIN_ID_SDIO_D0, 3); #if CONFIG_SDCARD_BUSWIDTH_4LINE gpio_dev_map(PIN_ID_SDIO_D1, GPIO_DEV_SDIO_HOST_DATA1); bk_gpio_pull_up(PIN_ID_SDIO_D1); bk_gpio_set_capacity(PIN_ID_SDIO_D1, 3); gpio_dev_map(PIN_ID_SDIO_D2, GPIO_DEV_SDIO_HOST_DATA2); bk_gpio_pull_up(PIN_ID_SDIO_D2); bk_gpio_set_capacity(PIN_ID_SDIO_D2, 3); gpio_dev_map(PIN_ID_SDIO_D3, GPIO_DEV_SDIO_HOST_DATA3); bk_gpio_pull_up(PIN_ID_SDIO_D3); bk_gpio_set_capacity(PIN_ID_SDIO_D3, 3); #endif } #if CONFIG_SOC_BK7256XX //1:clock always on, 0:auto gate void sdio_clk_gate_config(uint8_t enable) { uint32_t reg = REG_READ(REG_SDCARD_FIFO_THRESHOLD); //os_printf("%s:reg=0x%x, en=%d\r\n", __func__, reg, enable); if(enable) reg |= (1<= WAIT_MAX_CNT) && (i % 0x100000 == 0)) SDCARD_PRT("%s:i=%x,timeout\r\n", __func__, i); } REG_WRITE(REG_SDCARD_CMD_RSP_INT_SEL, SD_DATA_RSP);//clear the int flag if (reg & SDCARD_CMDRSP_DATA_TIME_OUT_INT) return SD_DATA_TIMEOUT; if (reg & SDCARD_CMDRSP_DATA_CRC_FAIL) { SDCARD_WARN("sdcard data crcfail,cmdresp_int_reg:0x%x\r\n", reg); return SD_DATA_CRC_FAIL; } for (i = 0; i < SD_DEFAULT_BLOCK_SIZE ;) { /* wait fifo data valid */ while (1) { //software needn't handle dead-loop,hardware can garantee if (REG_READ(REG_SDCARD_FIFO_THRESHOLD)&SDCARD_FIFO_RXFIFO_RD_READY) break; } reg = REG_READ(REG_SDCARD_RD_DATA_ADDR); *(receive_buf + i++) = reg & 0xff; *(receive_buf + i++) = (reg >> 8) & 0xff; *(receive_buf + i++) = (reg >> 16) & 0xff; *(receive_buf + i++) = (reg >> 24) & 0xff; } return SD_OK; } #if 0 SDIO_Error sdcard_write_data(UINT8 *writebuff, UINT32 block) { UINT32 i, j, reg, tmpval; i = 0; // 1. fill the first block to fifo and start write data enable while (REG_READ(REG_SDCARD_FIFO_THRESHOLD) & SDCARD_FIFO_TXFIFO_WR_READY) { tmpval = (writebuff[i] << 24) | (writebuff[i + 1] << 16) | (writebuff[i + 2] << 8) | writebuff[i + 3]; REG_WRITE(REG_SDCARD_WR_DATA_ADDR, tmpval); i += 4; if (SD_DEFAULT_BLOCK_SIZE <= i) break; } reg = REG_READ(REG_SDCARD_CMD_RSP_INT_MASK); reg |= SDCARD_CMDRSP_TX_FIFO_EMPTY_MASK; REG_WRITE(REG_SDCARD_CMD_RSP_INT_MASK, reg); REG_WRITE(REG_SDCARD_DATA_REC_TIMER, DEF_HIGH_SPEED_DATA_TIMEOUT * block); reg = (SD_DEFAULT_BLOCK_SIZE << SDCARD_DATA_REC_CTRL_BLK_SIZE_POSI) | SDCARD_DATA_REC_CTRL_DATA_MUL_BLK | SDCARD_DATA_REC_CTRL_DATA_BYTE_SEL | SDCARD_DATA_REC_CTRL_DATA_WR_DATA_EN #ifdef CONFIG_SDCARD_BUSWIDTH_4LINE | SDCARD_DATA_REC_CTRL_DATA_BUS #endif ; REG_WRITE(REG_SDCARD_DATA_REC_CTRL, reg); #if CONFIG_SOC_BK7256XX #else do { reg = REG_READ(REG_SDCARD_CMD_RSP_INT_SEL); } while (!(reg & SDCARD_CMDRSP_TX_FIFO_NEED_WRITE)); #endif // 2. write other blocks while (--block) { j = 0; while (j < SD_DEFAULT_BLOCK_SIZE) { if (REG_READ(REG_SDCARD_FIFO_THRESHOLD) & SDCARD_FIFO_TXFIFO_WR_READY) { tmpval = (writebuff[i] << 24) | (writebuff[i + 1] << 16) | (writebuff[i + 2] << 8) | writebuff[i + 3]; REG_WRITE(REG_SDCARD_WR_DATA_ADDR, tmpval); i += 4; j += 4; } } do { reg = REG_READ(REG_SDCARD_CMD_RSP_INT_SEL); } while (!(reg & SDCARD_CMDRSP_DATA_WR_END_INT)); REG_WRITE(REG_SDCARD_CMD_RSP_INT_SEL, SDCARD_CMDRSP_DATA_WR_END_INT); #if CONFIG_SOC_BK7256XX #else do { reg = REG_READ(REG_SDCARD_CMD_RSP_INT_SEL); } while (!(reg & SDCARD_CMDRSP_TX_FIFO_NEED_WRITE)); #endif if (2 != ((reg & SDCARD_CMDRSP_WR_STATU) >> 20)) return SD_ERROR; } // 3. after the last block,write zero while (1) { reg = REG_READ(REG_SDCARD_FIFO_THRESHOLD); if (reg & SDCARD_FIFO_TXFIFO_WR_READY) { REG_WRITE(REG_SDCARD_WR_DATA_ADDR, 0); break; } } // 4.wait and clear flag do { reg = REG_READ(REG_SDCARD_CMD_RSP_INT_SEL); } while (!(reg & SDCARD_CMDRSP_DATA_WR_END_INT)); REG_WRITE(REG_SDCARD_CMD_RSP_INT_SEL, SDCARD_CMDRSP_DATA_WR_END_INT); if (2 != ((reg & SDCARD_CMDRSP_WR_STATU) >> 20)) return SD_ERROR; return SD_OK; } SDIO_Error sdcard_wait_write_end(void) { UINT32 reg; while (1) { reg = REG_READ(REG_SDCARD_CMD_RSP_INT_SEL); if (reg & (SDCARD_CMDRSP_DATA_WR_END_INT | SDCARD_CMDRSP_DATA_CRC_FAIL | SDCARD_CMDRSP_DATA_TIME_OUT_INT)) break; } REG_WRITE(REG_SDCARD_CMD_RSP_INT_SEL, SD_DATA_RSP);//clear the int flag if (reg & SDCARD_CMDRSP_DATA_TIME_OUT_INT) return SD_DATA_TIMEOUT; if (reg & SDCARD_CMDRSP_DATA_CRC_FAIL) { SDCARD_WARN("sdcard write data crcfail,cmdresp_int_reg:0x%x\r\n", reg); return SD_DATA_CRC_FAIL; } return SD_OK; } #endif int wait_Receive_Data(void) { uint32 ret = SD_ERR_LONG_TIME_NO_RESPONS, status = 0; uint32 start_tm = rtos_get_time(); while (1) { if (rtos_get_time() > start_tm + 4000) { // 4s ret = SD_ERR_LONG_TIME_NO_RESPONS; break; } status = REG_READ(REG_SDCARD_CMD_RSP_INT_SEL); if (status & SDCARD_CMDRSP_DATA_REC_END_INT) { if (status & SDCARD_CMDRSP_DATA_CRC_FAIL) { os_printf("aaa\r\n"); //ret = SD_DATA_CRC_FAIL; ret = SD_OK; } else ret = SD_OK; break; } else if (status & SDCARD_CMDRSP_DATA_CRC_FAIL) { ret = SD_DATA_CRC_FAIL; break; } else if (status & SDCARD_CMDRSP_DATA_TIME_OUT_INT) { ret = SD_DATA_TIMEOUT; break; } } REG_WRITE(REG_SDCARD_CMD_RSP_INT_SEL, SD_DATA_RSP);/*< clear the int flag */ return ret; } #endif // CONFIG_SDCARD // EOF