#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
#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,
}
#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;
}
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
return SDM_WAIT_FOR_CMDSTART_TIMEOUT;
}
host->errorstep = 0xfe;
-
+
return SDM_SUCCESS;
}
}
+/**
+ * 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
/****************************************************************/
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",\
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);
}
}
+ /*
+ ** 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;
}
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, \
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[] = {
.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,
//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;
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))
{
#ifndef __RK2918_SDMMC_H
#define __RK2918_SDMMC_H
+#include <linux/bitops.h>
+
#define MAX_SG_CHN 2
#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) */
/* 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) */
#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)*/
#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)
#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)