Skip to content
Snippets Groups Projects
Commit 187f32fa authored by Sonic Zhang's avatar Sonic Zhang Committed by sonic
Browse files

blackfin: bf60x: add rsi/sdh support


Add rsi/sdh support for bf60x.

Signed-off-by: default avatarSonic Zhang <sonic.zhang@analog.com>
Signed-off-by: default avatarBob Liu <lliubbo@gmail.com>
Signed-off-by: default avatarSonic Zhang <sonic.adi@gmail.com>
parent 320ec9df
No related branches found
No related tags found
No related merge requests found
...@@ -12,18 +12,35 @@ ...@@ -12,18 +12,35 @@
#define CMD_INT_E 0x100 /* Command Interrupt */ #define CMD_INT_E 0x100 /* Command Interrupt */
#define CMD_PEND_E 0x200 /* Command Pending */ #define CMD_PEND_E 0x200 /* Command Pending */
#define CMD_E 0x400 /* Command Enable */ #define CMD_E 0x400 /* Command Enable */
#ifdef RSI_BLKSZ
#define CMD_CRC_CHECK_D 0x800 /* CRC Check is disabled */
#define CMD_DATA0_BUSY 0x1000 /* Check Busy State on DATA0 */
#endif
/* Bit masks for SDH_PWR_CTL */ /* Bit masks for SDH_PWR_CTL */
#ifndef RSI_BLKSZ
#define PWR_ON 0x3 /* Power On */ #define PWR_ON 0x3 /* Power On */
#define SD_CMD_OD 0x40 /* Open Drain Output */ #define SD_CMD_OD 0x40 /* Open Drain Output */
#define ROD_CTL 0x80 /* Rod Control */ #define ROD_CTL 0x80 /* Rod Control */
#endif
/* Bit masks for SDH_CLK_CTL */ /* Bit masks for SDH_CLK_CTL */
#define CLKDIV 0xff /* MC_CLK Divisor */ #define CLKDIV 0xff /* MC_CLK Divisor */
#define CLK_E 0x100 /* MC_CLK Bus Clock Enable */ #define CLK_E 0x100 /* MC_CLK Bus Clock Enable */
#define PWR_SV_E 0x200 /* Power Save Enable */ #define PWR_SV_E 0x200 /* Power Save Enable */
#define CLKDIV_BYPASS 0x400 /* Bypass Divisor */ #define CLKDIV_BYPASS 0x400 /* Bypass Divisor */
#define WIDE_BUS 0x800 /* Wide Bus Mode Enable */ #define BUS_MODE_MASK 0x1800 /* Bus Mode Mask */
#define STD_BUS_1 0x000 /* Standard Bus 1 bit mode */
#define WIDE_BUS_4 0x800 /* Wide Bus 4 bit mode */
#define BYTE_BUS_8 0x1000 /* Byte Bus 8 bit mode */
#ifdef RSI_BLKSZ
#define CARD_TYPE_MASK 0xe000 /* Card type mask */
#define CARD_TYPE_OFFSET 13 /* Card type offset */
#define CARD_TYPE_SDIO 0
#define CARD_TYPE_eMMC 1
#define CARD_TYPE_SD 2
#define CARD_TYPE_CEATA 3
#endif
/* Bit masks for SDH_RESP_CMD */ /* Bit masks for SDH_RESP_CMD */
#define RESP_CMD 0x3f /* Response Command */ #define RESP_CMD 0x3f /* Response Command */
...@@ -33,7 +50,13 @@ ...@@ -33,7 +50,13 @@
#define DTX_DIR 0x2 /* Data Transfer Direction */ #define DTX_DIR 0x2 /* Data Transfer Direction */
#define DTX_MODE 0x4 /* Data Transfer Mode */ #define DTX_MODE 0x4 /* Data Transfer Mode */
#define DTX_DMA_E 0x8 /* Data Transfer DMA Enable */ #define DTX_DMA_E 0x8 /* Data Transfer DMA Enable */
#ifndef RSI_BLKSZ
#define DTX_BLK_LGTH 0xf0 /* Data Transfer Block Length */ #define DTX_BLK_LGTH 0xf0 /* Data Transfer Block Length */
#else
/* Bit masks for SDH_BLK_SIZE */
#define DTX_BLK_LGTH 0x1fff /* Data Transfer Block Length */
#endif
/* Bit masks for SDH_STATUS */ /* Bit masks for SDH_STATUS */
#define CMD_CRC_FAIL 0x1 /* CMD CRC Fail */ #define CMD_CRC_FAIL 0x1 /* CMD CRC Fail */
...@@ -102,10 +125,13 @@ ...@@ -102,10 +125,13 @@
/* Bit masks for SDH_E_STATUS */ /* Bit masks for SDH_E_STATUS */
#define SDIO_INT_DET 0x2 /* SDIO Int Detected */ #define SDIO_INT_DET 0x2 /* SDIO Int Detected */
#define SD_CARD_DET 0x10 /* SD Card Detect */ #define SD_CARD_DET 0x10 /* SD Card Detect */
#define SD_CARD_BUSYMODE 0x80000000 /* Card is in Busy mode */
#define SD_CARD_SLPMODE 0x40000000 /* Card in Sleep Mode */
#define SD_CARD_READY 0x00020000 /* Card Ready */
/* Bit masks for SDH_E_MASK */ /* Bit masks for SDH_E_MASK */
#define SDIO_MSK 0x2 /* Mask SDIO Int Detected */ #define SDIO_MSK 0x2 /* Mask SDIO Int Detected */
#define SCD_MSK 0x40 /* Mask Card Detect */ #define SCD_MSK 0x10 /* Mask Card Detect */
/* Bit masks for SDH_CFG */ /* Bit masks for SDH_CFG */
#define CLKS_EN 0x1 /* Clocks Enable */ #define CLKS_EN 0x1 /* Clocks Enable */
...@@ -114,7 +140,15 @@ ...@@ -114,7 +140,15 @@
#define SD_RST 0x10 /* SDMMC Reset */ #define SD_RST 0x10 /* SDMMC Reset */
#define PUP_SDDAT 0x20 /* Pull-up SD_DAT */ #define PUP_SDDAT 0x20 /* Pull-up SD_DAT */
#define PUP_SDDAT3 0x40 /* Pull-up SD_DAT3 */ #define PUP_SDDAT3 0x40 /* Pull-up SD_DAT3 */
#ifndef RSI_BLKSZ
#define PD_SDDAT3 0x80 /* Pull-down SD_DAT3 */ #define PD_SDDAT3 0x80 /* Pull-down SD_DAT3 */
#else
#define PWR_ON 0x600 /* Power On */
#define SD_CMD_OD 0x800 /* Open Drain Output */
#define BOOT_EN 0x1000 /* Boot Enable */
#define BOOT_MODE 0x2000 /* Alternate Boot Mode */
#define BOOT_ACK_EN 0x4000 /* Boot ACK is expected */
#endif
/* Bit masks for SDH_RD_WAIT_EN */ /* Bit masks for SDH_RD_WAIT_EN */
#define RWR 0x1 /* Read Wait Request */ #define RWR 0x1 /* Read Wait Request */
......
...@@ -19,9 +19,7 @@ ...@@ -19,9 +19,7 @@
#include <asm/mach-common/bits/sdh.h> #include <asm/mach-common/bits/sdh.h>
#include <asm/mach-common/bits/dma.h> #include <asm/mach-common/bits/dma.h>
#if defined(__ADSPBF50x__) || defined(__ADSPBF51x__) #if defined(__ADSPBF50x__) || defined(__ADSPBF51x__) || defined(__ADSPBF60x__)
# define bfin_read_SDH_PWR_CTL bfin_read_RSI_PWR_CONTROL
# define bfin_write_SDH_PWR_CTL bfin_write_RSI_PWR_CONTROL
# define bfin_read_SDH_CLK_CTL bfin_read_RSI_CLK_CONTROL # define bfin_read_SDH_CLK_CTL bfin_read_RSI_CLK_CONTROL
# define bfin_write_SDH_CLK_CTL bfin_write_RSI_CLK_CONTROL # define bfin_write_SDH_CLK_CTL bfin_write_RSI_CLK_CONTROL
# define bfin_write_SDH_ARGUMENT bfin_write_RSI_ARGUMENT # define bfin_write_SDH_ARGUMENT bfin_write_RSI_ARGUMENT
...@@ -38,10 +36,21 @@ ...@@ -38,10 +36,21 @@
# define bfin_write_SDH_STATUS_CLR bfin_write_RSI_STATUSCL # define bfin_write_SDH_STATUS_CLR bfin_write_RSI_STATUSCL
# define bfin_read_SDH_CFG bfin_read_RSI_CONFIG # define bfin_read_SDH_CFG bfin_read_RSI_CONFIG
# define bfin_write_SDH_CFG bfin_write_RSI_CONFIG # define bfin_write_SDH_CFG bfin_write_RSI_CONFIG
# if defined(__ADSPBF60x__)
# define bfin_read_SDH_BLK_SIZE bfin_read_RSI_BLKSZ
# define bfin_write_SDH_BLK_SIZE bfin_write_RSI_BLKSZ
# define bfin_write_DMA_START_ADDR bfin_write_DMA10_START_ADDR
# define bfin_write_DMA_X_COUNT bfin_write_DMA10_X_COUNT
# define bfin_write_DMA_X_MODIFY bfin_write_DMA10_X_MODIFY
# define bfin_write_DMA_CONFIG bfin_write_DMA10_CONFIG
# else
# define bfin_read_SDH_PWR_CTL bfin_read_RSI_PWR_CONTROL
# define bfin_write_SDH_PWR_CTL bfin_write_RSI_PWR_CONTROL
# define bfin_write_DMA_START_ADDR bfin_write_DMA4_START_ADDR # define bfin_write_DMA_START_ADDR bfin_write_DMA4_START_ADDR
# define bfin_write_DMA_X_COUNT bfin_write_DMA4_X_COUNT # define bfin_write_DMA_X_COUNT bfin_write_DMA4_X_COUNT
# define bfin_write_DMA_X_MODIFY bfin_write_DMA4_X_MODIFY # define bfin_write_DMA_X_MODIFY bfin_write_DMA4_X_MODIFY
# define bfin_write_DMA_CONFIG bfin_write_DMA4_CONFIG # define bfin_write_DMA_CONFIG bfin_write_DMA4_CONFIG
# endif
# define PORTMUX_PINS \ # define PORTMUX_PINS \
{ P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, P_RSI_CMD, P_RSI_CLK, 0 } { P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, P_RSI_CMD, P_RSI_CLK, 0 }
#elif defined(__ADSPBF54x__) #elif defined(__ADSPBF54x__)
...@@ -70,6 +79,9 @@ sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd) ...@@ -70,6 +79,9 @@ sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
sdh_cmd |= CMD_RSP; sdh_cmd |= CMD_RSP;
if (flags & MMC_RSP_136) if (flags & MMC_RSP_136)
sdh_cmd |= CMD_L_RSP; sdh_cmd |= CMD_L_RSP;
#ifdef RSI_BLKSZ
sdh_cmd |= CMD_DATA0_BUSY;
#endif
bfin_write_SDH_ARGUMENT(arg); bfin_write_SDH_ARGUMENT(arg);
bfin_write_SDH_COMMAND(sdh_cmd); bfin_write_SDH_COMMAND(sdh_cmd);
...@@ -104,6 +116,12 @@ sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd) ...@@ -104,6 +116,12 @@ sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT | bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT |
CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT); CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT);
#ifdef RSI_BLKSZ
/* wait till card ready */
while (!(bfin_read_RSI_ESTAT() & SD_CARD_READY))
continue;
bfin_write_RSI_ESTAT(SD_CARD_READY);
#endif
return ret; return ret;
} }
...@@ -113,16 +131,19 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data) ...@@ -113,16 +131,19 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data)
{ {
u16 data_ctl = 0; u16 data_ctl = 0;
u16 dma_cfg = 0; u16 dma_cfg = 0;
int ret = 0;
unsigned long data_size = data->blocksize * data->blocks; unsigned long data_size = data->blocksize * data->blocks;
/* Don't support write yet. */ /* Don't support write yet. */
if (data->flags & MMC_DATA_WRITE) if (data->flags & MMC_DATA_WRITE)
return UNUSABLE_ERR; return UNUSABLE_ERR;
#ifndef RSI_BLKSZ
data_ctl |= ((ffs(data_size) - 1) << 4); data_ctl |= ((ffs(data_size) - 1) << 4);
#else
bfin_write_SDH_BLK_SIZE(data_size);
#endif
data_ctl |= DTX_DIR; data_ctl |= DTX_DIR;
bfin_write_SDH_DATA_CTL(data_ctl); bfin_write_SDH_DATA_CTL(data_ctl);
dma_cfg = WDSIZE_32 | RESTART | WNR | DMAEN; dma_cfg = WDSIZE_32 | PSIZE_32 | RESTART | WNR | DMAEN;
bfin_write_SDH_DATA_TIMER(-1); bfin_write_SDH_DATA_TIMER(-1);
...@@ -137,7 +158,7 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data) ...@@ -137,7 +158,7 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data)
/* kick off transfer */ /* kick off transfer */
bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E); bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E);
return ret; return 0;
} }
...@@ -147,13 +168,23 @@ static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd, ...@@ -147,13 +168,23 @@ static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd,
u32 status; u32 status;
int ret = 0; int ret = 0;
if (data) {
ret = sdh_setup_data(mmc, data);
if (ret)
return ret;
}
ret = sdh_send_cmd(mmc, cmd); ret = sdh_send_cmd(mmc, cmd);
if (ret) { if (ret) {
bfin_write_SDH_COMMAND(0);
bfin_write_DMA_CONFIG(0);
bfin_write_SDH_DATA_CTL(0);
SSYNC();
printf("sending CMD%d failed\n", cmd->cmdidx); printf("sending CMD%d failed\n", cmd->cmdidx);
return ret; return ret;
} }
if (data) { if (data) {
ret = sdh_setup_data(mmc, data);
do { do {
udelay(1); udelay(1);
status = bfin_read_SDH_STATUS(); status = bfin_read_SDH_STATUS();
...@@ -208,10 +239,12 @@ static void bfin_sdh_set_ios(struct mmc *mmc) ...@@ -208,10 +239,12 @@ static void bfin_sdh_set_ios(struct mmc *mmc)
if (mmc->bus_width == 4) { if (mmc->bus_width == 4) {
cfg = bfin_read_SDH_CFG(); cfg = bfin_read_SDH_CFG();
cfg &= ~0x80; #ifndef RSI_BLKSZ
cfg |= 0x40; cfg &= ~PD_SDDAT3;
#endif
cfg |= PUP_SDDAT3;
bfin_write_SDH_CFG(cfg); bfin_write_SDH_CFG(cfg);
clk_ctl |= WIDE_BUS; clk_ctl |= WIDE_BUS_4;
} }
bfin_write_SDH_CLK_CTL(clk_ctl); bfin_write_SDH_CLK_CTL(clk_ctl);
sdh_set_clk(mmc->clock); sdh_set_clk(mmc->clock);
...@@ -220,20 +253,23 @@ static void bfin_sdh_set_ios(struct mmc *mmc) ...@@ -220,20 +253,23 @@ static void bfin_sdh_set_ios(struct mmc *mmc)
static int bfin_sdh_init(struct mmc *mmc) static int bfin_sdh_init(struct mmc *mmc)
{ {
const unsigned short pins[] = PORTMUX_PINS; const unsigned short pins[] = PORTMUX_PINS;
u16 pwr_ctl = 0; int ret;
/* Initialize sdh controller */ /* Initialize sdh controller */
peripheral_request_list(pins, "bfin_sdh"); ret = peripheral_request_list(pins, "bfin_sdh");
if (ret < 0)
return ret;
#if defined(__ADSPBF54x__) #if defined(__ADSPBF54x__)
bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1); bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
#endif #endif
bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN); bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
/* Disable card detect pin */ /* Disable card detect pin */
bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | 0x60); bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | 0x60);
#ifndef RSI_BLKSZ
pwr_ctl |= ROD_CTL; bfin_write_SDH_PWR_CTL(PWR_ON | ROD_CTL);
pwr_ctl |= PWR_ON; #else
bfin_write_SDH_PWR_CTL(pwr_ctl); bfin_write_SDH_CFG(bfin_read_SDH_CFG() | PWR_ON);
#endif
return 0; return 0;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment