From 2b0034ec2ea1fe2c836741b2010b80982016ab53 Mon Sep 17 00:00:00 2001 From: xbw Date: Fri, 2 Aug 2013 15:58:43 +0800 Subject: [PATCH] =?utf8?q?SDMMC:=201=E3=80=81add=20the=20support=20for=20S?= =?utf8?q?D=20Spec=20V3.0.=202=E3=80=81add=20the=20support=20for=20UHS-I?= =?utf8?q?=203.=20add=20the=20support=20for=20IDMA(Internal=20DMA)=204.=20?= =?utf8?q?eliminate=20the=20small=20flaw=20about=20some=20machines=20may?= =?utf8?q?=20crash=20because=20of=20sdio-interrupt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- drivers/mmc/core/sd.c | 6 +- drivers/mmc/host/rk29_sdmmc.c | 310 ++++++++++++++++++++++++++++++---- drivers/mmc/host/rk29_sdmmc.h | 229 +++++++++++++++++-------- 3 files changed, 439 insertions(+), 106 deletions(-) diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 2e636377b156..8d99c7fd1adc 100755 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -243,7 +243,8 @@ static int mmc_read_ssr(struct mmc_card *card) * bitfield positions accordingly. */ au = UNSTUFF_BITS(ssr, 428 - 384, 4); - if (au > 0 || au <= 9) { + //if (au > 0 || au <= 9) { //Modifyed by xbw at 2013-02-28 + if (au > 0 && au <= 9) { card->ssr.au = 1 << (au + 4); es = UNSTUFF_BITS(ssr, 408 - 384, 16); et = UNSTUFF_BITS(ssr, 402 - 384, 6); @@ -290,7 +291,8 @@ static int mmc_read_switch(struct mmc_card *card) } /* Find out the supported Bus Speed Modes. */ - err = mmc_sd_switch(card, 0, 0, 1, status); + //err = mmc_sd_switch(card, 0, 0, 1, status); + err = mmc_sd_switch(card, 0, 0, 0, status); //Modifyed by xbw at 2013-02-28 if (err) { /* * If the host or the card can't do the switch, diff --git a/drivers/mmc/host/rk29_sdmmc.c b/drivers/mmc/host/rk29_sdmmc.c index 3f4e7cc08b69..0059e0220b92 100755 --- a/drivers/mmc/host/rk29_sdmmc.c +++ b/drivers/mmc/host/rk29_sdmmc.c @@ -106,7 +106,7 @@ int debug_level = 5; #define RK29_SDMMC_WAIT_DTO_INTERNVAL 4500 //The time interval from the CMD_DONE_INT to DTO_INT #define RK29_SDMMC_REMOVAL_DELAY 2000 //The time interval from the CD_INT to detect_timer react. -#define RK29_SDMMC_VERSION "Ver.5.05 The last modify date is 2013-05-08" +#define RK29_SDMMC_VERSION "Ver.6.00 The last modify date is 2013-08-02" #if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD) #define RK29_CTRL_SDMMC_ID 0 //mainly used by SDMMC @@ -137,6 +137,16 @@ int debug_level = 5; #define DRIVER_SDMMC_USE_NEW_IOMUX_API 0 #endif +//support Internal DMA +#if 0 //Sometime in the future to enable +#define DRIVER_SDMMC_USE_IDMA 1 +#else +#define DRIVER_SDMMC_USE_IDMA 0 +#endif + +#define SWITCH_VOLTAGE_18_33 0 //RK30_PIN2_PD7 //Temporary experiment +#define SWITCH_VOLTAGE_ENABLE_VALUE_33 GPIO_LOW + enum { EVENT_CMD_COMPLETE = 0, EVENT_DATA_COMPLETE, @@ -728,6 +738,28 @@ err: } #endif + + +/** +** This function checks whether the core supports the IDMAC. +** return Returns 1 if HW supports IDMAC, else returns 0. +*/ +u32 rk_sdmmc_check_idma_support(struct rk29_sdmmc *host) +{ + u32 retval = 0; + u32 ctrl_reg; + ctrl_reg = rk29_sdmmc_read(host->regs, SDMMC_CTRL); + if(ctrl_reg & SDMMC_CTRL_USE_IDMAC) + retval = 1;//Return "true", indicating the hardware supports IDMAC + else + retval = 0;// Hardware doesnot support IDMAC + + return retval; +} + + + + static u32 rk29_sdmmc_prepare_command(struct mmc_command *cmd) { u32 cmdr = cmd->opcode; @@ -855,6 +887,7 @@ static int rk29_sdmmc_start_command(struct rk29_sdmmc *host, struct mmc_command } rk29_sdmmc_write(host->regs, SDMMC_CMDARG, cmd->arg); // write to SDMMC_CMDARG register + #if defined(CONFIG_ARCH_RK29) rk29_sdmmc_write(host->regs, SDMMC_CMD, cmd_flags | SDMMC_CMD_START); // write to SDMMC_CMD register #else @@ -890,7 +923,7 @@ static int rk29_sdmmc_start_command(struct rk29_sdmmc *host, struct mmc_command return SDM_WAIT_FOR_CMDSTART_TIMEOUT; } host->errorstep = 0xfe; - + return SDM_SUCCESS; } @@ -1644,6 +1677,90 @@ static int rk29_sdmmc_get_cd(struct mmc_host *mmc) } +/** + * Delay loop. + * Very rough microsecond delay loop for the system. + * \param[in] u32 Value in Number of Microseconds. + * \return Returns Void + **/ +void rk_sdmmc_udelay(u32 value) +{ + u32 counter; + for (counter = 0; counter < value ; counter++) + udelay(1); +} + +int rk_sdmmc_reset_host(struct rk29_sdmmc *host) +{ + int ret = SDM_SUCCESS; + int timeout; + //reset the host cotroller + rk29_sdmmc_write(host->regs, SDMMC_CTRL, SDMMC_CTRL_RESET); + udelay(10); + + timeout = 1000; + while((rk29_sdmmc_read(host->regs, SDMMC_CTRL) & SDMMC_CTRL_RESET)&& timeout--) + udelay(1); + if(0 == timeout) + { + ret = SDM_FALSE; + printk(KERN_ERR "%d.. reset ctrl_reset fail! [%s]=\n", __LINE__, host->dma_name); + goto EXIT_RESET; + } + +#if !defined(CONFIG_ARCH_RK29) + //reset DMA + rk29_sdmmc_write(host->regs, SDMMC_CTRL, SDMMC_CTRL_DMA_RESET); + udelay(10); + + timeout = 1000; + while((rk29_sdmmc_read(host->regs, SDMMC_CTRL) & SDMMC_CTRL_DMA_RESET)&& timeout--) + udelay(1); + if(0 == timeout) + { + ret = SDM_FALSE; + printk(KERN_ERR "%d.. reset dma_reset fail! [%s]=\n", __LINE__, host->dma_name); + goto EXIT_RESET; + } +#endif + + //reset FIFO + rk29_sdmmc_write(host->regs, SDMMC_CTRL, SDMMC_CTRL_FIFO_RESET); + udelay(10); + + timeout = 1000; + while((rk29_sdmmc_read(host->regs, SDMMC_CTRL) & SDMMC_CTRL_FIFO_RESET)&& timeout--) + udelay(1); + if(0 == timeout) + { + ret = SDM_FALSE; + printk(KERN_ERR "%d.. reset fofo_reset fail! [%s]=\n", __LINE__, host->dma_name); + goto EXIT_RESET; + } + +#if DRIVER_SDMMC_USE_IDMA + //reset the internal DMA Controller. + rk29_sdmmc_write(host->regs, SDMMC_BMOD, BMOD_SWR); + udelay(10); + + timeout = 1000; + while((rk29_sdmmc_read(host->regs, SDMMC_BMOD) & BMOD_SWR)&& timeout--) + udelay(1); + if(0 == timeout) + { + ret = SDM_FALSE; + printk(KERN_ERR "%d.. reset IDMAC fail! [%s]=\n", __LINE__, host->dma_name); + goto EXIT_RESET; + } + + // Program the BMOD register for DMA + rk29_sdmmc_write(host->regs, SDMMC_BMOD, BMOD_DSL_TWO); +#endif + +EXIT_RESET: + return ret; +} + /****************************************************************/ //reset the SDMMC controller of the current host /****************************************************************/ @@ -1662,38 +1779,22 @@ int rk29_sdmmc_reset_controller(struct rk29_sdmmc *host) value = rk29_sdmmc_read(host->regs, SDMMC_DATA); } - - /* reset */ -#if defined(CONFIG_ARCH_RK29) - rk29_sdmmc_write(host->regs, SDMMC_CTRL,(SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET )); -#else - rk29_sdmmc_write(host->regs, SDMMC_CTRL,(SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_DMA_RESET)); -#endif - timeOut = 1000; - value = rk29_sdmmc_read(host->regs, SDMMC_CTRL); - while (( value & (SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_RESET)) && (timeOut > 0)) - { - udelay(1); - timeOut--; - value = rk29_sdmmc_read(host->regs, SDMMC_CTRL); - } - if (timeOut == 0) - { - printk(KERN_WARNING "%s..%s..%d.. reset controller fail! [%s]=\n",\ - __FILE__, __FUNCTION__,__LINE__, host->dma_name); - - host->errorstep = 0x0A; - return SDM_WAIT_FOR_FIFORESET_TIMEOUT; - } + /* reset */ + value = rk_sdmmc_reset_host(host); + if(value) + return SDM_FALSE; /* FIFO threshold settings */ - rk29_sdmmc_write(host->regs, SDMMC_FIFOTH, (SD_MSIZE_16 | (RX_WMARK << RX_WMARK_SHIFT) | (TX_WMARK << TX_WMARK_SHIFT))); + rk29_sdmmc_write(host->regs, SDMMC_FIFOTH, FIFO_THRESHOLD_WATERMASK); rk29_sdmmc_write(host->regs, SDMMC_CTYPE, SDMMC_CTYPE_1BIT); rk29_sdmmc_write(host->regs, SDMMC_CLKSRC, CLK_DIV_SRC_0); + /* config debounce */ host->bus_hz = clk_get_rate(host->clk); + +#if 0//Perhaps in some cases, it is necessary to restrict. if((host->bus_hz > 52000000) || (host->bus_hz <= 0)) { printk(KERN_WARNING "%s..%s..%d..****Error!!!!!! Bus clock %d hz is beyond the prescribed limits. [%s]\n",\ @@ -1702,14 +1803,16 @@ int rk29_sdmmc_reset_controller(struct rk29_sdmmc *host) host->errorstep = 0x0B; return SDM_PARAM_ERROR; } +#endif - rk29_sdmmc_write(host->regs, SDMMC_DEBNCE, (DEBOUNCE_TIME*host->bus_hz)&0xFFFFFF); + rk29_sdmmc_write(host->regs, SDMMC_DEBNCE, (DEBOUNCE_TIME*host->bus_hz)& SDMMC_DEFAULT_DEBNCE_VAL); /* config interrupt */ rk29_sdmmc_write(host->regs, SDMMC_RINTSTS, 0xFFFFFFFF); if(host->use_dma) { + if(RK29_CTRL_SDMMC_ID == host->pdev->id) { rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA); @@ -1793,10 +1896,21 @@ int rk29_sdmmc_reset_controller(struct rk29_sdmmc *host) } } + /* + ** Some machines may crash because of sdio-interrupt to open too early. + ** then, in the initialization phase, close the interruption. + ** noted by xbw,at 2013-07-25 + */ + rk29_sdmmc_write(host->regs, SDMMC_INTMASK,rk29_sdmmc_read(host->regs, SDMMC_INTMASK) & ~SDMMC_INT_SDIO); + rk29_sdmmc_write(host->regs, SDMMC_PWREN, POWER_ENABLE); +#if DRIVER_SDMMC_USE_IDMA + rk29_sdmmc_write(host->regs, SDMMC_CTRL, SDMMC_CTRL_INT_ENABLE | SDMMC_CTRL_USE_IDMAC); //Set the bit use_internal_dmac. +#else rk29_sdmmc_write(host->regs, SDMMC_CTRL,SDMMC_CTRL_INT_ENABLE); // enable mci interrupt - +#endif + return SDM_SUCCESS; } @@ -2251,7 +2365,23 @@ static int rk29_sdmmc_start_request(struct mmc_host *mmc ) goto start_request_Err; } host->errorstep = 0xfd; - + +#if DRIVER_SDMMC_USE_IDMA + /* Check if it is a data command. If yes, we need to handle only IDMAC interrupts + ** So we disable the Slave mode interrupts and enable DMA mode interrupts. + ** CTRL and BMOD registers are set up for DMA mode of operation + */ + if(mrq->data) + { + rk29_sdmmc_write(host->regs, SDMMC_INTMASK, 0x00000000);//Mask all slave interrupts + rk29_sdmmc_write(host->regs, SDMMC_IDINTEN, IDMAC_EN_INT_ALL); + rk29_sdmmc_write(host->regs, SDMMC_CTRL, SDMMC_CTRL_USE_IDMAC); + rk29_sdmmc_write(host->regs, SDMMC_BMOD, BMOD_DE); + rk29_sdmmc_write(host->regs, SDMMC_BMOD, BMOD_DSL_TWO);// Program the BMOD register for DMA + rk29_sdmmc_write(host->regs, SDMMC_FIFOTH, FIFO_THRESHOLD_WATERMASK); + } +#endif + xbwprintk(7, "%s..%d... CMD=%d, wait for INT_CMD_DONE, ret=%d , \n \ host->state=0x%x, cmdINT=0x%x \n host->pendingEvent=0x%lu, host->completeEvents=0x%lu [%s]\n\n",\ __FUNCTION__, __LINE__, host->cmd->opcode,ret, \ @@ -2679,6 +2809,112 @@ static int rk29_sdmmc_clear_fifo(struct rk29_sdmmc *host) return ret; } +static int rk_sdmmc_signal_voltage_switch(struct mmc_host *mmc, + struct mmc_ios *ios) +{ + struct rk29_sdmmc *host; + unsigned int value,uhs_reg; + + host = mmc_priv(mmc); + + /* + * We first check whether the request is to set signalling voltage + * to 3.3V. If so, we change the voltage to 3.3V and return quickly. + */ + uhs_reg = rk29_sdmmc_read(host->regs, SDMMC_UHS_REG); + if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) + { + //set 3.3v + #if SWITCH_VOLTAGE_18_33 + if(NULL != SWITCH_VOLTAGE_18_33) + gpio_direction_output(SWITCH_VOLTAGE_18_33, SWITCH_VOLTAGE_ENABLE_VALUE_33); + #endif + //set High-power mode + value = rk29_sdmmc_read(host->regs, SDMMC_CLKENA); + rk29_sdmmc_write(host->regs,SDMMC_CLKENA , value& ~SDMMC_CLKEN_LOW_PWR); + + //SDMMC_UHS_REG + rk29_sdmmc_write(host->regs,SDMMC_UHS_REG , uhs_reg & ~SDMMC_UHS_VOLT_REG_18); + + /* Wait for 5ms */ + usleep_range(5000, 5500); + + /* 3.3V regulator output should be stable within 5 ms */ + uhs_reg = rk29_sdmmc_read(host->regs, SDMMC_UHS_REG); + if( !(uhs_reg & SDMMC_UHS_VOLT_REG_18)) + return 0; + else + { + printk(KERN_INFO ": Switching to 3.3V " + "signalling voltage failed. [%s]\n", host->dma_name); + return -EIO; + } + + } + else if (!(uhs_reg & SDMMC_UHS_VOLT_REG_18) && (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)) + { + /* Stop SDCLK */ + rk29_sdmmc_control_clock(host, FALSE); + + /* Check whether DAT[3:0] is 0000 */ + value = rk29_sdmmc_read(host->regs, SDMMC_STATUS); + if ((value & SDMMC_STAUTS_DATA_BUSY) == 0) + { + /* + * Enable 1.8V Signal Enable in the Host register + */ + rk29_sdmmc_write(host->regs,SDMMC_UHS_REG , uhs_reg |SDMMC_UHS_VOLT_REG_18); + + /* Wait for 5ms */ + usleep_range(5000, 5500); + + uhs_reg = rk29_sdmmc_read(host->regs, SDMMC_UHS_REG); + if( uhs_reg & SDMMC_UHS_VOLT_REG_18) + { + + /* Provide SDCLK again and wait for 1ms*/ + rk29_sdmmc_control_clock(host, TRUE); + usleep_range(1000, 1500); + + /* + * If DAT[3:0] level is 1111b, then the card + * was successfully switched to 1.8V signaling. + */ + value = rk29_sdmmc_read(host->regs, SDMMC_STATUS); + if ((value & SDMMC_STAUTS_DATA_BUSY) == 0) + return 0; + } + } + + /* + * If we are here, that means the switch to 1.8V signaling + * failed. We power cycle the card, and retry initialization + * sequence by setting S18R to 0. + */ + #if SWITCH_VOLTAGE_18_33 + if(NULL != SWITCH_VOLTAGE_18_33) + gpio_direction_output(SWITCH_VOLTAGE_18_33, !(SWITCH_VOLTAGE_ENABLE_VALUE_33)); + #endif + + /* Wait for 1ms as per the spec */ + usleep_range(1000, 1500); + + #if SWITCH_VOLTAGE_18_33 + if(NULL != SWITCH_VOLTAGE_18_33) + gpio_direction_output(SWITCH_VOLTAGE_18_33, SWITCH_VOLTAGE_ENABLE_VALUE_33); + #endif + + printk(KERN_INFO ": Switching to 1.8V signalling " + "voltage failed, retrying with S18R set to 0. [%s]\n", host->dma_name); + return -EAGAIN; + + } + else + { + /* No signal voltage switch required */ + return 0; + } +} static const struct mmc_host_ops rk29_sdmmc_ops[] = { @@ -2687,6 +2923,7 @@ static const struct mmc_host_ops rk29_sdmmc_ops[] = { .set_ios = rk29_sdmmc_set_ios, .get_ro = rk29_sdmmc_get_ro, .get_cd = rk29_sdmmc_get_cd, + .start_signal_voltage_switch = rk_sdmmc_signal_voltage_switch, }, { .request = rk29_sdmmc_request, @@ -3700,7 +3937,18 @@ static int rk29_sdmmc_probe(struct platform_device *pdev) //mmc->ocr_avail = pdata->host_ocr_avail; mmc->ocr_avail = MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31 | MMC_VDD_31_32|MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_34_35| MMC_VDD_35_36; ///set valid volage 2.7---3.6v +#if 1 + + mmc->ocr_avail = mmc->ocr_avail |MMC_VDD_26_27 |MMC_VDD_25_26 |MMC_VDD_24_25 |MMC_VDD_23_24 + |MMC_VDD_22_23 |MMC_VDD_21_22 |MMC_VDD_20_21 |MMC_VDD_165_195; +#endif mmc->caps = pdata->host_caps; +#if 1 + mmc->caps = mmc->caps | MMC_CAP_1_8V_DDR |MMC_CAP_1_2V_DDR /*|MMC_CAP_DRIVER_TYPE_A |MMC_CAP_DRIVER_TYPE_C |MMC_CAP_DRIVER_TYPE_D*/ + |MMC_CAP_UHS_SDR12 |MMC_CAP_UHS_SDR25 |MMC_CAP_UHS_SDR50 |MMC_CAP_UHS_SDR104 |MMC_CAP_UHS_DDR50 + /* |MMC_CAP_MAX_CURRENT_200 |MMC_CAP_MAX_CURRENT_400 |MMC_CAP_MAX_CURRENT_600 |MMC_CAP_MAX_CURRENT_800 + |MMC_CAP_SET_XPC_330*/; +#endif mmc->re_initialized_flags = 1; mmc->doneflag = 1; mmc->sdmmc_host_hw_init = rk29_sdmmc_hw_init; @@ -3831,6 +4079,10 @@ static int rk29_sdmmc_probe(struct platform_device *pdev) goto err_dmaunmap; } + //gpio request for switch_voltage + if(RK29_CTRL_SDMMC_ID == host->pdev->id) + gpio_request(SWITCH_VOLTAGE_18_33, "sd_volt_switch"); + #if defined(CONFIG_SDMMC0_RK29_SDCARD_DET_FROM_GPIO) if((RK29_CTRL_SDMMC_ID == host->pdev->id) && (INVALID_GPIO != host->det_pin.io)) { diff --git a/drivers/mmc/host/rk29_sdmmc.h b/drivers/mmc/host/rk29_sdmmc.h index 33b5999b7269..8bcd32491df5 100755 --- a/drivers/mmc/host/rk29_sdmmc.h +++ b/drivers/mmc/host/rk29_sdmmc.h @@ -16,6 +16,8 @@ #ifndef __RK2918_SDMMC_H #define __RK2918_SDMMC_H +#include + #define MAX_SG_CHN 2 @@ -47,32 +49,46 @@ #define SDMMC_USRID (0x068) //User ID register #if defined(CONFIG_ARCH_RK29) -#define SDMMC_DATA (0x100) +#define SDMMC_DATA (0x100) //FIFO data read write #else #define SDMMC_VERID (0x06c) //Version ID register #define SDMMC_UHS_REG (0x074) //UHS-I register #define SDMMC_RST_n (0x078) //Hardware reset register +#define SDMMC_BMOD (0x080) //Bus mode register, control IMAC +#define SDMMC_PLDMND (0x084) //Poll Demand Register +#define SDMMC_DBADDR (0x088) //Descriptor List Base Address Register for 32-bit. +#define SDMMC_IDSTS (0x08c) //Internal DMAC Status register +#define SDMMC_IDINTEN (0x090) //Internal DMAC Interrupt Enable Register +#define SDMMC_DSCADDR (0x094) //Current Host Descriptor Address Register for 32-bit +#define SDMMC_BUFADDR (0x098) //Current Buffer Descriptor Address Register for 32-bit #define SDMMC_CARDTHRCTL (0x100) //Card Read Threshold Enable #define SDMMC_BACK_END_POWER (0x104) //Back-end Power -#define SDMMC_FIFO_BASE (0x200) // +#define SDMMC_FIFO_BASE (0x200) //FIFO data read write #define SDMMC_DATA SDMMC_FIFO_BASE #endif -#define RK2818_BIT(n) (1<<(n)) +#define BIT(n) (1<<(n)) #define RK_CLEAR_BIT(n) (0<<(n)) /* Control register defines (base+ 0x00)*/ -#define SDMMC_CTRL_OD_PULLUP RK2818_BIT(24) -#define SDMMC_CTRL_DMA_ENABLE RK2818_BIT(5) -#define SDMMC_CTRL_INT_ENABLE RK2818_BIT(4) -#define SDMMC_CTRL_DMA_RESET RK2818_BIT(2) -#define SDMMC_CTRL_FIFO_RESET RK2818_BIT(1) -#define SDMMC_CTRL_RESET RK2818_BIT(0) +#define SDMMC_CTRL_USE_IDMAC BIT(25) +#define SDMMC_CTRL_OD_PULLUP BIT(24) +#define SDMMC_CTRL_CEATA_INT_EN BIT(11) +#define SDMMC_CTRL_SEND_AS_CCSD BIT(10) +#define SDMMC_CTRL_SEND_CCSD BIT(9) +#define SDMMC_CTRL_ABRT_READ_DATA BIT(8) +#define SDMMC_CTRL_SEND_IRQ_RESP BIT(7) +#define SDMMC_CTRL_READ_WAIT BIT(6) +#define SDMMC_CTRL_DMA_ENABLE BIT(5) +#define SDMMC_CTRL_INT_ENABLE BIT(4) +#define SDMMC_CTRL_DMA_RESET BIT(2) +#define SDMMC_CTRL_FIFO_RESET BIT(1) +#define SDMMC_CTRL_RESET BIT(0) /* Power Enable Register(base+ 0x04) */ -#define POWER_ENABLE RK2818_BIT(0) //Power enable +#define POWER_ENABLE BIT(0) //Power enable #define POWER_DISABLE RK_CLEAR_BIT(0) //Power off /* SDMMC Clock source Register(base+ 0x0C) */ @@ -83,9 +99,9 @@ /* Clock Enable register defines(base+0x10) */ -#define SDMMC_CLKEN_LOW_PWR RK2818_BIT(16) +#define SDMMC_CLKEN_LOW_PWR BIT(16) #define SDMMC_CLKEN_NO_LOW_PWR RK_CLEAR_BIT(16) //low-power mode disabled -#define SDMMC_CLKEN_ENABLE RK2818_BIT(0) +#define SDMMC_CLKEN_ENABLE BIT(0) #define SDMMC_CLKEN_DISABLE RK_CLEAR_BIT(16) //clock disabled /* time-out register defines(base+0x14) */ @@ -95,79 +111,83 @@ #define SDMMC_TMOUT_RESP_MSK 0xFF /* card-type register defines(base+0x18) */ -#define SDMMC_CTYPE_8BIT RK2818_BIT(16) -#define SDMMC_CTYPE_4BIT RK2818_BIT(0) +#define SDMMC_CTYPE_8BIT BIT(16) +#define SDMMC_CTYPE_4BIT BIT(0) #define SDMMC_CTYPE_1BIT RK_CLEAR_BIT(0) /* Interrupt status & mask register defines(base+0x24) */ #if defined(CONFIG_ARCH_RK29) -#define SDMMC_INT_SDIO RK2818_BIT(16) //SDIO interrupt +#define SDMMC_INT_SDIO BIT(16) //SDIO interrupt #else -#define SDMMC_INT_SDIO RK2818_BIT(24) //SDIO interrupt -#define SDMMC_INT_UNBUSY RK2818_BIT(16) //data no busy interrupt +#define SDMMC_INT_SDIO BIT(24) //SDIO interrupt +#define SDMMC_INT_UNBUSY BIT(16) //data no busy interrupt #endif -#define SDMMC_INT_EBE RK2818_BIT(15) //End Bit Error(read)/Write no CRC -#define SDMMC_INT_ACD RK2818_BIT(14) //Auto Command Done -#define SDMMC_INT_SBE RK2818_BIT(13) //Start Bit Error -#define SDMMC_INT_HLE RK2818_BIT(12) //Hardware Locked Write Error -#define SDMMC_INT_FRUN RK2818_BIT(11) //FIFO Underrun/Overrun Error -#define SDMMC_INT_HTO RK2818_BIT(10) //Data Starvation by Host Timeout -#define SDMMC_INT_DRTO RK2818_BIT(9) //Data Read TimeOut -#define SDMMC_INT_RTO RK2818_BIT(8) //Response TimeOut -#define SDMMC_INT_DCRC RK2818_BIT(7) //Data CRC Error -#define SDMMC_INT_RCRC RK2818_BIT(6) //Response CRC Error -#define SDMMC_INT_RXDR RK2818_BIT(5) //Receive FIFO Data Request -#define SDMMC_INT_TXDR RK2818_BIT(4) //Transmit FIFO Data Request -#define SDMMC_INT_DTO RK2818_BIT(3) //Data Transfer Over -#define SDMMC_INT_CMD_DONE RK2818_BIT(2) //Command Done -#define SDMMC_INT_RE RK2818_BIT(1) //Response Error -#define SDMMC_INT_CD RK2818_BIT(0) //Card Detect +#define SDMMC_INT_EBE BIT(15) //End Bit Error(read)/Write no CRC +#define SDMMC_INT_ACD BIT(14) //Auto Command Done +#define SDMMC_INT_SBE BIT(13) //Start Bit Error +#define SDMMC_INT_HLE BIT(12) //Hardware Locked Write Error +#define SDMMC_INT_FRUN BIT(11) //FIFO Underrun/Overrun Error +#define SDMMC_INT_HTO BIT(10) //Data Starvation by Host Timeout +#define SDMMC_INT_VSI SDMMC_INT_HTO // VSI => Voltage Switch Interrupt,Volt_Switch_int +#define SDMMC_INT_DRTO BIT(9) //Data Read TimeOut +#define SDMMC_INT_RTO BIT(8) //Response TimeOut +#define SDMMC_INT_DCRC BIT(7) //Data CRC Error +#define SDMMC_INT_RCRC BIT(6) //Response CRC Error +#define SDMMC_INT_RXDR BIT(5) //Receive FIFO Data Request +#define SDMMC_INT_TXDR BIT(4) //Transmit FIFO Data Request +#define SDMMC_INT_DTO BIT(3) //Data Transfer Over +#define SDMMC_INT_CMD_DONE BIT(2) //Command Done +#define SDMMC_INT_RE BIT(1) //Response Error +#define SDMMC_INT_CD BIT(0) //Card Detect /* Command register defines(base+0x2C) */ -#define SDMMC_CMD_START RK2818_BIT(31) //start command +#define SDMMC_CMD_START BIT(31) //start command #if !defined(CONFIG_ARCH_RK29) -#define SDMMC_CMD_USE_HOLD_REG RK2818_BIT(29) //Use hold register. -#define SDMMC_CMD_VOLT_SWITCH RK2818_BIT(28) //Voltage switch bit -#define SDMMC_CMD_BOOT_MODE RK2818_BIT(27) //set boot mode. -#define SDMMC_CMD_DISABLE_BOOT RK2818_BIT(26) //disable boot. -#define SDMMC_CMD_EXPECT_BOOT_ACK RK2818_BIT(25) //Expect Boot Acknowledge. -#define SDMMC_CMD_ENABLE_BOOT RK2818_BIT(24) //be set only for mandatory boot mode. +#define SDMMC_CMD_USE_HOLD_REG BIT(29) //Use hold register. +#define SDMMC_CMD_VOLT_SWITCH BIT(28) //Voltage switch bit +#define SDMMC_CMD_BOOT_MODE BIT(27) //set boot mode. +#define SDMMC_CMD_DISABLE_BOOT BIT(26) //disable boot. +#define SDMMC_CMD_EXPECT_BOOT_ACK BIT(25) //Expect Boot Acknowledge. +#define SDMMC_CMD_ENABLE_BOOT BIT(24) //be set only for mandatory boot mode. +#define SDMMC_CMD_CCS_EXP BIT(23) //expect Command Completion Signal(CCS) from the CE-ATA device. +#define SDMMC_CMD_CEATA_RD BIT(22) //software should set this bit to indicate that CE-ATA device #endif -#define SDMMC_CMD_UPD_CLK RK2818_BIT(21) //update clock register only -#define SDMMC_CMD_INIT RK2818_BIT(15) //send initialization sequence -#define SDMMC_CMD_STOP RK2818_BIT(14) //stop abort command -#define SDMMC_CMD_PRV_DAT_NO_WAIT RK_CLEAR_BIT(13) //not wait previous data transfer complete, send command at once -#define SDMMC_CMD_PRV_DAT_WAIT RK2818_BIT(13) //wait previous data transfer complete -#define SDMMC_CMD_SEND_STOP RK2818_BIT(12) //send auto stop command at end of data transfer -#define SDMMC_CMD_BLOCK_MODE RK_CLEAR_BIT(11) //block data transfer command -#define SDMMC_CMD_STRM_MODE RK2818_BIT(11) //stream data transfer command -#define SDMMC_CMD_DAT_READ RK_CLEAR_BIT(10) //read from card -#define SDMMC_CMD_DAT_WRITE RK2818_BIT(10) //write to card; -#define SDMMC_CMD_DAT_WR RK2818_BIT(10) //write to card; -#define SDMMC_CMD_DAT_NO_EXP RK_CLEAR_BIT(9) //no data transfer expected -#define SDMMC_CMD_DAT_EXP RK2818_BIT(9) //data transfer expected -#define SDMMC_CMD_RESP_NO_CRC RK_CLEAR_BIT(8) //do not check response crc -#define SDMMC_CMD_RESP_CRC RK2818_BIT(8) //check response crc +#define SDMMC_CMD_UPD_CLK BIT(21) //update clock register only +#define SDMMC_CMD_INIT BIT(15) //send initialization sequence +#define SDMMC_CMD_STOP BIT(14) //stop abort command +#define SDMMC_CMD_PRV_DAT_NO_WAIT RK_CLEAR_BIT(13) //not wait previous data transfer complete, send command at once +#define SDMMC_CMD_PRV_DAT_WAIT BIT(13) //wait previous data transfer complete +#define SDMMC_CMD_SEND_STOP BIT(12) //send auto stop command at end of data transfer +#define SDMMC_CMD_BLOCK_MODE RK_CLEAR_BIT(11) //block data transfer command +#define SDMMC_CMD_STRM_MODE BIT(11) //stream data transfer command +#define SDMMC_CMD_DAT_READ RK_CLEAR_BIT(10) //read from card +#define SDMMC_CMD_DAT_WRITE BIT(10) //write to card; +#define SDMMC_CMD_DAT_WR BIT(10) //write to card; +#define SDMMC_CMD_DAT_NO_EXP RK_CLEAR_BIT(9) //no data transfer expected +#define SDMMC_CMD_DAT_EXP BIT(9) //data transfer expected +#define SDMMC_CMD_RESP_NO_CRC RK_CLEAR_BIT(8) //do not check response crc +#define SDMMC_CMD_RESP_CRC BIT(8) //check response crc #define SDMMC_CMD_RESP_CRC_NOCARE SDMMC_CMD_RESP_CRC //not care response crc -#define SDMMC_CMD_RESP_SHORT RK_CLEAR_BIT(7) //short response expected from card -#define SDMMC_CMD_RESP_LONG RK2818_BIT(7) //long response expected from card; -#define SDMMC_CMD_RESP_NOCARE SDMMC_CMD_RESP_SHORT //not care response length -#define SDMMC_CMD_RESP_NO_EXP RK_CLEAR_BIT(6) //no response expected from card -#define SDMMC_CMD_RESP_EXP RK2818_BIT(6) //response expected from card -#define SDMMC_CMD_INDX(n) ((n) & 0x1F) +#define SDMMC_CMD_RESP_SHORT RK_CLEAR_BIT(7) //short response expected from card +#define SDMMC_CMD_RESP_LONG BIT(7) //long response expected from card; +#define SDMMC_CMD_RESP_NOCARE SDMMC_CMD_RESP_SHORT //not care response length +#define SDMMC_CMD_RESP_NO_EXP RK_CLEAR_BIT(6) //no response expected from card +#define SDMMC_CMD_RESP_EXP BIT(6) //response expected from card +#define SDMMC_CMD_INDX(n) ((n) & 0x1F) /* Status register defines (base+0x48)*/ -#define SDMMC_STAUTS_MC_BUSY RK2818_BIT(10) -#define SDMMC_STAUTS_DATA_BUSY RK2818_BIT(9) //Card busy -#define SDMMC_CMD_FSM_MASK (0x0F << 4) //Command FSM status mask -#define SDMMC_CMD_FSM_IDLE (0x00) //CMD FSM is IDLE -#define SDMMC_STAUTS_FIFO_FULL RK2818_BIT(3) //FIFO is full status -#define SDMMC_STAUTS_FIFO_EMPTY RK2818_BIT(2) //FIFO is empty status +#define SDMMC_STAUTS_MC_BUSY BIT(10) +#define SDMMC_STAUTS_DATA_BUSY BIT(9) //Card busy +#define SDMMC_CMD_FSM_MASK (0x0F << 4) //Command FSM status mask +#define SDMMC_CMD_FSM_IDLE (0x00) //CMD FSM is IDLE +#define SDMMC_STAUTS_FIFO_FULL BIT(3) //FIFO is full status +#define SDMMC_STAUTS_FIFO_EMPTY BIT(2) //FIFO is empty status -#define SDMMC_GET_FCNT(x) (((x)>>17) & 0x1FF)//fifo_count, numbers of filled locations in FIFO -#define SDMMC_FIFO_SZ 32 +/* Status register defines */ +#define SDMMC_GET_FCNT(x) (((x)>>17) & 0x1FF)//fifo_count, numbers of filled locations in FIFO +#define SDMMC_FIFO_SZ 32 /* FIFO Register (base + 0x4c)*/ @@ -180,6 +200,7 @@ #define SD_MSIZE_128 (0x6 << 28) #define SD_MSIZE_256 (0x7 << 28) + #if defined(CONFIG_ARCH_RK29) #define FIFO_DEPTH (0x20) //FIFO depth = 32 word #define RX_WMARK_SHIFT (16) @@ -199,20 +220,78 @@ #define TX_WMARK (FIFO_DEPTH/2) //TX watermark level set to 128 #endif +#define FIFO_THRESHOLD_WATERMASK (SD_MSIZE_16 |(RX_WMARK << RX_WMARK_SHIFT)|(TX_WMARK << TX_WMARK_SHIFT)) + /* CDETECT register defines (base+0x50)*/ -#define SDMMC_CARD_DETECT_N RK2818_BIT(0) //0--represents presence of card. +#define SDMMC_CARD_DETECT_N BIT(0) //0--represents presence of card. /* WRIPRT register defines (base+0x54)*/ -#define SDMMC_WRITE_PROTECT RK2818_BIT(0) // 1--represents write protect - - +#define SDMMC_WRITE_PROTECT BIT(0) // 1--represents write protect + +/* Control SDMMC_UHS_REG defines (base+ 0x74)*/ +#define SDMMC_UHS_DDR_MODE BIT(16) // 0--Non DDR Mode; 1--DDR mode +#define SDMMC_UHS_VOLT_REG_18 BIT(0) // 0--3.3v; 1--1.8V + + +// #ifdef IDMAC_SUPPORT + +/* Bus Mode Register (base + 0x80) */ +#define BMOD_SWR BIT(0) // Software Reset: Auto cleared after one clock cycle 0 +#define BMOD_FB BIT(1) // Fixed Burst Length: when set SINGLE/INCR/INCR4/INCR8/INCR16 used at the start 1 +#define BMOD_DE BIT(7) // Idmac Enable: When set IDMAC is enabled 7 +#define BMOD_DSL_MSK 0x0000007C // Descriptor Skip length: In Number of Words 6:2 +#define BMOD_DSL_Shift 2 // Descriptor Skip length Shift value +#define BMOD_DSL_ZERO 0x00000000 // No Gap between Descriptors +#define BMOD_DSL_TWO 0x00000008 // 2 Words Gap between Descriptors +#define BMOD_PBL 0x00000400 // MSIZE in FIFOTH Register + +/* Internal DMAC Status Register(base + 0x8c)*/ +/* Internal DMAC Interrupt Enable Register Bit Definitions */ +#define IDMAC_AI 0x00000200 // Abnormal Interrupt Summary Enable/ Status 9 +#define IDMAC_NI 0x00000100 // Normal Interrupt Summary Enable/ Status 8 +#define IDMAC_CES 0x00000020 // Card Error Summary Interrupt Enable/ status 5 +#define IDMAC_DU 0x00000010 // Descriptor Unavailabe Interrupt Enable /Status 4 +#define IDMAC_FBE 0x00000004 // Fata Bus Error Enable/ Status 2 +#define IDMAC_RI 0x00000002 // Rx Interrupt Enable/ Status 1 +#define IDMAC_TI 0x00000001 // Tx Interrupt Enable/ Status 0 + +#define IDMAC_EN_INT_ALL 0x00000337 // Enables all interrupts + +#define IDMAC_HOST_ABORT_TX 0x00000400 // Host Abort received during Transmission 12:10 +#define IDMAC_HOST_ABORT_RX 0x00000800 // Host Abort received during Reception 12:10 + +/* IDMAC FSM States */ +#define IDMAC_DMA_IDLE 0x00000000 // DMA is in IDLE state +#define IDMAC_DMA_SUSPEND 0x00002000 // DMA is in SUSPEND state +#define IDMAC_DESC_RD 0x00004000 // DMA is in DESC READ or FETCH State +#define IDMAC_DESC_CHK 0x00006000 // DMA is checking the Descriptor for Correctness +#define IDMAC_DMA_RD_REQ_WAIT 0x00008000 // DMA is in this state till dma_req is asserted (Read operation) +#define IDMAC_DMA_WR_REQ_WAIT 0x0000A000 // DMA is in this state till dma_req is asserted (Write operation) +#define IDMAC_DMA_RD 0x0000C000 // DMA is in Read mode +#define IDMAC_DMA_WR 0x0000E000 // DMA is in Write mode +#define IDMAC_DESC_CLOSE 0x00010000 // DMA is closing the Descriptor + +#define FIFOTH_MSIZE_1 0x00000000 // Multiple Trans. Size is 1 +#define FIFOTH_MSIZE_4 0x10000000 // Multiple Trans. Size is 4 +#define FIFOTH_MSIZE_8 0x20000000 // Multiple Trans. Size is 8 +#define FIFOTH_MSIZE_16 0x30000000 // Multiple Trans. Size is 16 +#define FIFOTH_MSIZE_32 0x40000000 // Multiple Trans. Size is 32 +#define FIFOTH_MSIZE_64 0x50000000 // Multiple Trans. Size is 64 +#define FIFOTH_MSIZE_128 0x60000000 // Multiple Trans. Size is 128 +#define FIFOTH_MSIZE_256 0x70000000 // Multiple Trans. Size is 256 +// #endif //#endif --#ifdef IDMAC_SUPPORT + + +/********************************************************************** +** Misc Defines +**********************************************************************/ +#define SDMMC_MAX_BUFF_SIZE_IDMAC 8192 +#define SDMMC_DEFAULT_DEBNCE_VAL 0x0FFFFFF /* Specifies how often in millisecs to poll for card removal-insertion changes * when the timer switch is open */ #define RK_SDMMC0_SWITCH_POLL_DELAY 35 - - /* SDMMC progress return value */ #define SDM_SUCCESS (0) #define SDM_FALSE (1) -- 2.34.1