staging: mt7621-mmc: Cleanup source of base address for io

Currently the base address for all io operations is hidden behind a
macro, REG_ADD. This macro uses the symbol "base" as the base address
and all functions set base = host->base. This is hard to read, so the
whole wrapping is removed and host->base is directly inserted in the
io access.

Signed-off-by: Christian Lütke-Stetzkamp <christian@lkamp.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Christian Lütke-Stetzkamp 2018-06-16 16:14:59 +02:00 committed by Greg Kroah-Hartman
parent 8a5b9f049b
commit 2dfc73d5bb
2 changed files with 236 additions and 303 deletions

View File

@ -41,11 +41,6 @@
// #include <mach/mt6575_reg_base.h> /* --- by chhung */
/*--------------------------------------------------------------------------*/
/* Common Macro */
/*--------------------------------------------------------------------------*/
#define REG_ADDR(x) (base + OFFSET_##x)
/*--------------------------------------------------------------------------*/
/* Common Definition */
/*--------------------------------------------------------------------------*/
@ -95,117 +90,51 @@ enum {
/*--------------------------------------------------------------------------*/
/* Register Offset */
/*--------------------------------------------------------------------------*/
#define OFFSET_MSDC_CFG (0x0)
#define OFFSET_MSDC_IOCON (0x04)
#define OFFSET_MSDC_PS (0x08)
#define OFFSET_MSDC_INT (0x0c)
#define OFFSET_MSDC_INTEN (0x10)
#define OFFSET_MSDC_FIFOCS (0x14)
#define OFFSET_MSDC_TXDATA (0x18)
#define OFFSET_MSDC_RXDATA (0x1c)
#define OFFSET_SDC_CFG (0x30)
#define OFFSET_SDC_CMD (0x34)
#define OFFSET_SDC_ARG (0x38)
#define OFFSET_SDC_STS (0x3c)
#define OFFSET_SDC_RESP0 (0x40)
#define OFFSET_SDC_RESP1 (0x44)
#define OFFSET_SDC_RESP2 (0x48)
#define OFFSET_SDC_RESP3 (0x4c)
#define OFFSET_SDC_BLK_NUM (0x50)
#define OFFSET_SDC_CSTS (0x58)
#define OFFSET_SDC_CSTS_EN (0x5c)
#define OFFSET_SDC_DCRC_STS (0x60)
#define OFFSET_EMMC_CFG0 (0x70)
#define OFFSET_EMMC_CFG1 (0x74)
#define OFFSET_EMMC_STS (0x78)
#define OFFSET_EMMC_IOCON (0x7c)
#define OFFSET_SDC_ACMD_RESP (0x80)
#define OFFSET_SDC_ACMD19_TRG (0x84)
#define OFFSET_SDC_ACMD19_STS (0x88)
#define OFFSET_MSDC_DMA_SA (0x90)
#define OFFSET_MSDC_DMA_CA (0x94)
#define OFFSET_MSDC_DMA_CTRL (0x98)
#define OFFSET_MSDC_DMA_CFG (0x9c)
#define OFFSET_MSDC_DBG_SEL (0xa0)
#define OFFSET_MSDC_DBG_OUT (0xa4)
#define OFFSET_MSDC_PATCH_BIT (0xb0)
#define OFFSET_MSDC_PATCH_BIT1 (0xb4)
#define OFFSET_MSDC_PAD_CTL0 (0xe0)
#define OFFSET_MSDC_PAD_CTL1 (0xe4)
#define OFFSET_MSDC_PAD_CTL2 (0xe8)
#define OFFSET_MSDC_PAD_TUNE (0xec)
#define OFFSET_MSDC_DAT_RDDLY0 (0xf0)
#define OFFSET_MSDC_DAT_RDDLY1 (0xf4)
#define OFFSET_MSDC_HW_DBG (0xf8)
#define OFFSET_MSDC_VERSION (0x100)
#define OFFSET_MSDC_ECO_VER (0x104)
/*--------------------------------------------------------------------------*/
/* Register Address */
/*--------------------------------------------------------------------------*/
/* common register */
#define MSDC_CFG REG_ADDR(MSDC_CFG)
#define MSDC_IOCON REG_ADDR(MSDC_IOCON)
#define MSDC_PS REG_ADDR(MSDC_PS)
#define MSDC_INT REG_ADDR(MSDC_INT)
#define MSDC_INTEN REG_ADDR(MSDC_INTEN)
#define MSDC_FIFOCS REG_ADDR(MSDC_FIFOCS)
#define MSDC_TXDATA REG_ADDR(MSDC_TXDATA)
#define MSDC_RXDATA REG_ADDR(MSDC_RXDATA)
#define MSDC_PATCH_BIT0 REG_ADDR(MSDC_PATCH_BIT)
/* sdmmc register */
#define SDC_CFG REG_ADDR(SDC_CFG)
#define SDC_CMD REG_ADDR(SDC_CMD)
#define SDC_ARG REG_ADDR(SDC_ARG)
#define SDC_STS REG_ADDR(SDC_STS)
#define SDC_RESP0 REG_ADDR(SDC_RESP0)
#define SDC_RESP1 REG_ADDR(SDC_RESP1)
#define SDC_RESP2 REG_ADDR(SDC_RESP2)
#define SDC_RESP3 REG_ADDR(SDC_RESP3)
#define SDC_BLK_NUM REG_ADDR(SDC_BLK_NUM)
#define SDC_CSTS REG_ADDR(SDC_CSTS)
#define SDC_CSTS_EN REG_ADDR(SDC_CSTS_EN)
#define SDC_DCRC_STS REG_ADDR(SDC_DCRC_STS)
/* emmc register*/
#define EMMC_CFG0 REG_ADDR(EMMC_CFG0)
#define EMMC_CFG1 REG_ADDR(EMMC_CFG1)
#define EMMC_STS REG_ADDR(EMMC_STS)
#define EMMC_IOCON REG_ADDR(EMMC_IOCON)
/* auto command register */
#define SDC_ACMD_RESP REG_ADDR(SDC_ACMD_RESP)
#define SDC_ACMD19_TRG REG_ADDR(SDC_ACMD19_TRG)
#define SDC_ACMD19_STS REG_ADDR(SDC_ACMD19_STS)
/* dma register */
#define MSDC_DMA_SA REG_ADDR(MSDC_DMA_SA)
#define MSDC_DMA_CA REG_ADDR(MSDC_DMA_CA)
#define MSDC_DMA_CTRL REG_ADDR(MSDC_DMA_CTRL)
#define MSDC_DMA_CFG REG_ADDR(MSDC_DMA_CFG)
/* pad ctrl register */
#define MSDC_PAD_CTL0 REG_ADDR(MSDC_PAD_CTL0)
#define MSDC_PAD_CTL1 REG_ADDR(MSDC_PAD_CTL1)
#define MSDC_PAD_CTL2 REG_ADDR(MSDC_PAD_CTL2)
/* data read delay */
#define MSDC_DAT_RDDLY0 REG_ADDR(MSDC_DAT_RDDLY0)
#define MSDC_DAT_RDDLY1 REG_ADDR(MSDC_DAT_RDDLY1)
/* debug register */
#define MSDC_DBG_SEL REG_ADDR(MSDC_DBG_SEL)
#define MSDC_DBG_OUT REG_ADDR(MSDC_DBG_OUT)
/* misc register */
#define MSDC_PATCH_BIT REG_ADDR(MSDC_PATCH_BIT)
#define MSDC_PATCH_BIT1 REG_ADDR(MSDC_PATCH_BIT1)
#define MSDC_PAD_TUNE REG_ADDR(MSDC_PAD_TUNE)
#define MSDC_HW_DBG REG_ADDR(MSDC_HW_DBG)
#define MSDC_VERSION REG_ADDR(MSDC_VERSION)
#define MSDC_ECO_VER REG_ADDR(MSDC_ECO_VER) /* ECO Version */
#define MSDC_CFG (0x0)
#define MSDC_IOCON (0x04)
#define MSDC_PS (0x08)
#define MSDC_INT (0x0c)
#define MSDC_INTEN (0x10)
#define MSDC_FIFOCS (0x14)
#define MSDC_TXDATA (0x18)
#define MSDC_RXDATA (0x1c)
#define SDC_CFG (0x30)
#define SDC_CMD (0x34)
#define SDC_ARG (0x38)
#define SDC_STS (0x3c)
#define SDC_RESP0 (0x40)
#define SDC_RESP1 (0x44)
#define SDC_RESP2 (0x48)
#define SDC_RESP3 (0x4c)
#define SDC_BLK_NUM (0x50)
#define SDC_CSTS (0x58)
#define SDC_CSTS_EN (0x5c)
#define SDC_DCRC_STS (0x60)
#define EMMC_CFG0 (0x70)
#define EMMC_CFG1 (0x74)
#define EMMC_STS (0x78)
#define EMMC_IOCON (0x7c)
#define SDC_ACMD_RESP (0x80)
#define SDC_ACMD19_TRG (0x84)
#define SDC_ACMD19_STS (0x88)
#define MSDC_DMA_SA (0x90)
#define MSDC_DMA_CA (0x94)
#define MSDC_DMA_CTRL (0x98)
#define MSDC_DMA_CFG (0x9c)
#define MSDC_DBG_SEL (0xa0)
#define MSDC_DBG_OUT (0xa4)
#define MSDC_PATCH_BIT (0xb0)
#define MSDC_PATCH_BIT0 MSDC_PATCH_BIT
#define MSDC_PATCH_BIT1 (0xb4)
#define MSDC_PAD_CTL0 (0xe0)
#define MSDC_PAD_CTL1 (0xe4)
#define MSDC_PAD_CTL2 (0xe8)
#define MSDC_PAD_TUNE (0xec)
#define MSDC_DAT_RDDLY0 (0xf0)
#define MSDC_DAT_RDDLY1 (0xf4)
#define MSDC_HW_DBG (0xf8)
#define MSDC_VERSION (0x100)
#define MSDC_ECO_VER (0x104)
/*--------------------------------------------------------------------------*/
/* Register Mask */

View File

@ -146,41 +146,37 @@ static int msdc_rsp[] = {
7, /* RESP_R1b */
};
#define msdc_dma_on() sdr_clr_bits(MSDC_CFG, MSDC_CFG_PIO)
#define msdc_dma_on() sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_PIO)
static void msdc_reset_hw(struct msdc_host *host)
{
void __iomem *base = host->base;
sdr_set_bits(MSDC_CFG, MSDC_CFG_RST);
while (readl(MSDC_CFG) & MSDC_CFG_RST)
sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST);
while (readl(host->base + MSDC_CFG) & MSDC_CFG_RST)
cpu_relax();
}
#define msdc_clr_int() \
do { \
volatile u32 val = readl(MSDC_INT); \
writel(val, MSDC_INT); \
volatile u32 val = readl(host->base + MSDC_INT); \
writel(val, host->base + MSDC_INT); \
} while (0)
static void msdc_clr_fifo(struct msdc_host *host)
{
void __iomem *base = host->base;
sdr_set_bits(MSDC_FIFOCS, MSDC_FIFOCS_CLR);
while (readl(MSDC_FIFOCS) & MSDC_FIFOCS_CLR)
sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR);
while (readl(host->base + MSDC_FIFOCS) & MSDC_FIFOCS_CLR)
cpu_relax();
}
#define msdc_irq_save(val) \
do { \
val = readl(MSDC_INTEN); \
sdr_clr_bits(MSDC_INTEN, val); \
val = readl(host->base + MSDC_INTEN); \
sdr_clr_bits(host->base + MSDC_INTEN, val); \
} while (0)
#define msdc_irq_restore(val) \
do { \
sdr_set_bits(MSDC_INTEN, val); \
sdr_set_bits(host->base + MSDC_INTEN, val); \
} while (0)
/* clock source for host: global */
@ -218,13 +214,13 @@ static u32 hclks[] = {50000000}; /* +/- by chhung */
(void)hwPowerDown(MT65XX_POWER_LDO_VMCH, "SD"); \
} while (0)
#define sdc_is_busy() (readl(SDC_STS) & SDC_STS_SDCBUSY)
#define sdc_is_cmd_busy() (readl(SDC_STS) & SDC_STS_CMDBUSY)
#define sdc_is_busy() (readl(host->base + SDC_STS) & SDC_STS_SDCBUSY)
#define sdc_is_cmd_busy() (readl(host->base + SDC_STS) & SDC_STS_CMDBUSY)
#define sdc_send_cmd(cmd, arg) \
do { \
writel((arg), SDC_ARG); \
writel((cmd), SDC_CMD); \
writel((arg), host->base + SDC_ARG); \
writel((cmd), host->base + SDC_CMD); \
} while (0)
// can modify to read h/w register.
@ -385,7 +381,6 @@ static void msdc_dump_io_resp(struct msdc_host *host, u32 resp)
static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
{
void __iomem *base = host->base;
u32 timeout, clk_ns;
host->timeout_ns = ns;
@ -397,7 +392,7 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
timeout = timeout > 1 ? timeout - 1 : 0;
timeout = timeout > 255 ? 255 : timeout;
sdr_set_field(SDC_CFG, SDC_CFG_DTOC, timeout);
sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, timeout);
N_MSG(OPS, "Set read data timeout: %dns %dclks -> %d x 65536 cycles",
ns, clks, timeout + 1);
@ -407,14 +402,13 @@ static void msdc_tasklet_card(struct work_struct *work)
{
struct msdc_host *host = (struct msdc_host *)container_of(work,
struct msdc_host, card_delaywork.work);
void __iomem *base = host->base;
u32 inserted;
u32 status = 0;
//u32 change = 0;
spin_lock(&host->lock);
status = readl(MSDC_PS);
status = readl(host->base + MSDC_PS);
if (cd_active_low)
inserted = (status & MSDC_PS_CDSTS) ? 0 : 1;
else
@ -452,19 +446,18 @@ static u8 clk_src_bit[4] = {
static void msdc_select_clksrc(struct msdc_host *host, unsigned char clksrc)
{
u32 val;
void __iomem *base = host->base;
BUG_ON(clksrc > 3);
INIT_MSG("set clock source to <%d>", clksrc);
val = readl(MSDC_CLKSRC_REG);
if (readl(MSDC_ECO_VER) >= 4) {
val = readl(host->base + MSDC_CLKSRC_REG);
if (readl(host->base + MSDC_ECO_VER) >= 4) {
val &= ~(0x3 << clk_src_bit[host->id]);
val |= clksrc << clk_src_bit[host->id];
} else {
val &= ~0x3; val |= clksrc;
}
writel(val, MSDC_CLKSRC_REG);
writel(val, host->base + MSDC_CLKSRC_REG);
host->hclk = hclks[clksrc];
host->hw->clk_src = clksrc;
@ -474,7 +467,6 @@ static void msdc_select_clksrc(struct msdc_host *host, unsigned char clksrc)
static void msdc_set_mclk(struct msdc_host *host, int ddr, unsigned int hz)
{
//struct msdc_hw *hw = host->hw;
void __iomem *base = host->base;
u32 mode;
u32 flags;
u32 div;
@ -515,11 +507,11 @@ static void msdc_set_mclk(struct msdc_host *host, int ddr, unsigned int hz)
}
/* set clock mode and divisor */
sdr_set_field(MSDC_CFG, MSDC_CFG_CKMOD, mode);
sdr_set_field(MSDC_CFG, MSDC_CFG_CKDIV, div);
sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD, mode);
sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKDIV, div);
/* wait clock stable */
while (!(readl(MSDC_CFG) & MSDC_CFG_CKSTB))
while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
cpu_relax();
host->sclk = sclk;
@ -536,7 +528,6 @@ static void msdc_set_mclk(struct msdc_host *host, int ddr, unsigned int hz)
/* Fix me. when need to abort */
static void msdc_abort_data(struct msdc_host *host)
{
void __iomem *base = host->base;
struct mmc_command *stop = host->mrq->stop;
ERR_MSG("Need to Abort.");
@ -561,7 +552,6 @@ static void msdc_abort_data(struct msdc_host *host)
static void msdc_pin_config(struct msdc_host *host, int mode)
{
struct msdc_hw *hw = host->hw;
void __iomem *base = host->base;
int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN;
/* Config WP pin */
@ -574,27 +564,27 @@ static void msdc_pin_config(struct msdc_host *host, int mode)
case MSDC_PIN_PULL_UP:
//sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 1); /* Check & FIXME */
//sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */
sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 1);
sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0);
sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 1);
sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0);
sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 1);
sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0);
sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 1);
sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0);
break;
case MSDC_PIN_PULL_DOWN:
//sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */
//sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 1); /* Check & FIXME */
sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0);
sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 1);
sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0);
sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 1);
sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0);
sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 1);
sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0);
sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 1);
break;
case MSDC_PIN_PULL_NONE:
default:
//sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */
//sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */
sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0);
sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0);
sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0);
sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0);
sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0);
sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0);
sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0);
sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0);
break;
}
@ -605,7 +595,6 @@ static void msdc_pin_config(struct msdc_host *host, int mode)
void msdc_pin_reset(struct msdc_host *host, int mode)
{
struct msdc_hw *hw = (struct msdc_hw *)host->hw;
void __iomem *base = host->base;
int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN;
/* Config reset pin */
@ -614,9 +603,9 @@ void msdc_pin_reset(struct msdc_host *host, int mode)
hw->config_gpio_pin(MSDC_RST_PIN, pull);
if (mode == MSDC_PIN_PULL_UP)
sdr_clr_bits(EMMC_IOCON, EMMC_IOCON_BOOTRST);
sdr_clr_bits(host->base + EMMC_IOCON, EMMC_IOCON_BOOTRST);
else
sdr_set_bits(EMMC_IOCON, EMMC_IOCON_BOOTRST);
sdr_set_bits(host->base + EMMC_IOCON, EMMC_IOCON_BOOTRST);
}
}
@ -733,7 +722,6 @@ static unsigned int msdc_command_start(struct msdc_host *host,
int tune, /* not used */
unsigned long timeout)
{
void __iomem *base = host->base;
u32 opcode = cmd->opcode;
u32 rawcmd;
u32 wints = MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO |
@ -851,7 +839,7 @@ static unsigned int msdc_command_start(struct msdc_host *host,
init_completion(&host->cmd_done);
sdr_set_bits(MSDC_INTEN, wints);
sdr_set_bits(host->base + MSDC_INTEN, wints);
sdc_send_cmd(rawcmd, cmd->arg);
end:
@ -864,7 +852,6 @@ static unsigned int msdc_command_resp(struct msdc_host *host,
unsigned long timeout)
__must_hold(&host->lock)
{
void __iomem *base = host->base;
u32 opcode = cmd->opcode;
//u32 rawcmd;
u32 wints = MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO |
@ -873,7 +860,7 @@ static unsigned int msdc_command_resp(struct msdc_host *host,
BUG_ON(in_interrupt());
//init_completion(&host->cmd_done);
//sdr_set_bits(MSDC_INTEN, wints);
//sdr_set_bits(host->base + MSDC_INTEN, wints);
spin_unlock(&host->lock);
if (!wait_for_completion_timeout(&host->cmd_done, 10 * timeout)) {
@ -883,7 +870,7 @@ static unsigned int msdc_command_resp(struct msdc_host *host,
}
spin_lock(&host->lock);
sdr_clr_bits(MSDC_INTEN, wints);
sdr_clr_bits(host->base + MSDC_INTEN, wints);
host->cmd = NULL;
//end:
@ -928,7 +915,8 @@ static unsigned int msdc_command_resp(struct msdc_host *host,
/* memory card CRC */
if (host->hw->flags & MSDC_REMOVABLE && cmd->error == -EIO) {
if (readl(SDC_CMD) & 0x1800) { /* check if has data phase */
/* check if has data phase */
if (readl(host->base + SDC_CMD) & 0x1800) {
msdc_abort_data(host);
} else {
/* do basic: reset*/
@ -941,7 +929,7 @@ static unsigned int msdc_command_resp(struct msdc_host *host,
// check DAT0
/* if (resp == RESP_R1B) {
while ((readl(MSDC_PS) & 0x10000) != 0x10000);
while ((readl(host->base + MSDC_PS) & 0x10000) != 0x10000);
} */
/* CMD12 Error Handle */
@ -969,9 +957,7 @@ end:
// DMA resume / start / stop
static void msdc_dma_resume(struct msdc_host *host)
{
void __iomem *base = host->base;
sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_RESUME, 1);
sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_RESUME, 1);
N_MSG(DMA, "DMA resume");
}
@ -979,31 +965,29 @@ static void msdc_dma_resume(struct msdc_host *host)
static void msdc_dma_start(struct msdc_host *host)
{
void __iomem *base = host->base;
u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR;
sdr_set_bits(MSDC_INTEN, wints);
sdr_set_bits(host->base + MSDC_INTEN, wints);
//dsb(); /* --- by chhung */
sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_START, 1);
sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_START, 1);
N_MSG(DMA, "DMA start");
}
static void msdc_dma_stop(struct msdc_host *host)
{
void __iomem *base = host->base;
//u32 retries=500;
u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR;
N_MSG(DMA, "DMA status: 0x%.8x", readl(MSDC_DMA_CFG));
//while (readl(MSDC_DMA_CFG) & MSDC_DMA_CFG_STS);
N_MSG(DMA, "DMA status: 0x%.8x", readl(host->base + MSDC_DMA_CFG));
//while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS);
sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, 1);
while (readl(MSDC_DMA_CFG) & MSDC_DMA_CFG_STS)
sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, 1);
while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS)
;
//dsb(); /* --- by chhung */
sdr_clr_bits(MSDC_INTEN, wints); /* Not just xfer_comp */
sdr_clr_bits(host->base + MSDC_INTEN, wints); /* Not just xfer_comp */
N_MSG(DMA, "DMA stop");
}
@ -1021,7 +1005,6 @@ static u8 msdc_dma_calcs(u8 *buf, u32 len)
static void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma,
struct scatterlist *sg_cmd, unsigned int sglen)
{
void __iomem *base = host->base;
struct scatterlist *sg;
struct gpd *gpd;
struct bd *bd;
@ -1057,16 +1040,16 @@ static void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma,
bd[j].chksum = msdc_dma_calcs((u8 *)(&bd[j]), 16);
}
sdr_set_field(MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 1);
sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_BRUSTSZ,
sdr_set_field(host->base + MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 1);
sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_BRUSTSZ,
MSDC_BRUST_64B);
sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_MODE, 1);
sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_MODE, 1);
writel(PHYSADDR((u32)dma->gpd_addr), MSDC_DMA_SA);
writel(PHYSADDR((u32)dma->gpd_addr), host->base + MSDC_DMA_SA);
N_MSG(DMA, "DMA_CTRL = 0x%x", readl(MSDC_DMA_CTRL));
N_MSG(DMA, "DMA_CFG = 0x%x", readl(MSDC_DMA_CFG));
N_MSG(DMA, "DMA_SA = 0x%x", readl(MSDC_DMA_SA));
N_MSG(DMA, "DMA_CTRL = 0x%x", readl(host->base + MSDC_DMA_CTRL));
N_MSG(DMA, "DMA_CFG = 0x%x", readl(host->base + MSDC_DMA_CFG));
N_MSG(DMA, "DMA_SA = 0x%x", readl(host->base + MSDC_DMA_SA));
}
static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq)
@ -1075,7 +1058,6 @@ static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq)
struct msdc_host *host = mmc_priv(mmc);
struct mmc_command *cmd;
struct mmc_data *data;
void __iomem *base = host->base;
//u32 intsts = 0;
int read = 1, send_type = 0;
@ -1118,7 +1100,7 @@ static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq)
}
}
writel(data->blocks, SDC_BLK_NUM);
writel(data->blocks, host->base + SDC_BLK_NUM);
//msdc_clr_fifo(host); /* no need */
msdc_dma_on(); /* enable DMA mode first!! */
@ -1146,10 +1128,14 @@ static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq)
spin_unlock(&host->lock);
if (!wait_for_completion_timeout(&host->xfer_done, DAT_TIMEOUT)) {
ERR_MSG("XXX CMD<%d> wait xfer_done<%d> timeout!!", cmd->opcode, data->blocks * data->blksz);
ERR_MSG(" DMA_SA = 0x%x", readl(MSDC_DMA_SA));
ERR_MSG(" DMA_CA = 0x%x", readl(MSDC_DMA_CA));
ERR_MSG(" DMA_CTRL = 0x%x", readl(MSDC_DMA_CTRL));
ERR_MSG(" DMA_CFG = 0x%x", readl(MSDC_DMA_CFG));
ERR_MSG(" DMA_SA = 0x%x",
readl(host->base + MSDC_DMA_SA));
ERR_MSG(" DMA_CA = 0x%x",
readl(host->base + MSDC_DMA_CA));
ERR_MSG(" DMA_CTRL = 0x%x",
readl(host->base + MSDC_DMA_CTRL));
ERR_MSG(" DMA_CFG = 0x%x",
readl(host->base + MSDC_DMA_CFG));
data->error = -ETIMEDOUT;
msdc_reset_hw(host);
@ -1247,7 +1233,6 @@ static int msdc_app_cmd(struct mmc_host *mmc, struct msdc_host *host)
static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd)
{
int result = -1;
void __iomem *base = host->base;
u32 rsmpl, cur_rsmpl, orig_rsmpl;
u32 rrdly, cur_rrdly = 0xffffffff, orig_rrdly;
u32 skip = 1;
@ -1258,8 +1243,9 @@ static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd)
==========================*/
// save the previous tune result
sdr_get_field(MSDC_IOCON, MSDC_IOCON_RSPL, &orig_rsmpl);
sdr_get_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY, &orig_rrdly);
sdr_get_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, &orig_rsmpl);
sdr_get_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY,
&orig_rrdly);
rrdly = 0;
do {
@ -1270,7 +1256,8 @@ static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd)
skip = 0;
continue;
}
sdr_set_field(MSDC_IOCON, MSDC_IOCON_RSPL, cur_rsmpl);
sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL,
cur_rsmpl);
if (host->app_cmd) {
result = msdc_app_cmd(host->mmc, host);
@ -1292,14 +1279,15 @@ static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd)
}
/* should be EIO */
if (readl(SDC_CMD) & 0x1800) { /* check if has data phase */
/* check if has data phase */
if (readl(host->base + SDC_CMD) & 0x1800)
msdc_abort_data(host);
}
}
/* Lv2: PAD_CMD_RESP_RXDLY[26:22] */
cur_rrdly = (orig_rrdly + rrdly + 1) % 32;
sdr_set_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY, cur_rrdly);
sdr_set_field(host->base + MSDC_PAD_TUNE,
MSDC_PAD_TUNE_CMDRRDLY, cur_rrdly);
} while (++rrdly < 32);
return result;
@ -1309,7 +1297,6 @@ static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd)
static int msdc_tune_bread(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct msdc_host *host = mmc_priv(mmc);
void __iomem *base = host->base;
u32 ddr = 0;
u32 dcrc = 0;
u32 rxdly, cur_rxdly0, cur_rxdly1;
@ -1321,10 +1308,10 @@ static int msdc_tune_bread(struct mmc_host *mmc, struct mmc_request *mrq)
int result = -1;
u32 skip = 1;
sdr_get_field(MSDC_IOCON, MSDC_IOCON_DSPL, &orig_dsmpl);
sdr_get_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL, &orig_dsmpl);
/* Tune Method 2. */
sdr_set_field(MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
rxdly = 0;
do {
@ -1334,7 +1321,8 @@ static int msdc_tune_bread(struct mmc_host *mmc, struct mmc_request *mrq)
skip = 0;
continue;
}
sdr_set_field(MSDC_IOCON, MSDC_IOCON_DSPL, cur_dsmpl);
sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL,
cur_dsmpl);
if (host->app_cmd) {
result = msdc_app_cmd(host->mmc, host);
@ -1345,14 +1333,15 @@ static int msdc_tune_bread(struct mmc_host *mmc, struct mmc_request *mrq)
}
result = msdc_do_request(mmc, mrq);
sdr_get_field(SDC_DCRC_STS,
sdr_get_field(host->base + SDC_DCRC_STS,
SDC_DCRC_STS_POS | SDC_DCRC_STS_NEG,
&dcrc); /* RO */
if (!ddr)
dcrc &= ~SDC_DCRC_STS_NEG;
ERR_MSG("TUNE_BREAD<%s> dcrc<0x%x> DATRDDLY0/1<0x%x><0x%x> dsmpl<0x%x>",
(result == 0 && dcrc == 0) ? "PASS" : "FAIL", dcrc,
readl(MSDC_DAT_RDDLY0), readl(MSDC_DAT_RDDLY1), cur_dsmpl);
readl(host->base + MSDC_DAT_RDDLY0),
readl(host->base + MSDC_DAT_RDDLY1), cur_dsmpl);
/* Fix me: result is 0, but dcrc is still exist */
if (result == 0 && dcrc == 0) {
@ -1368,11 +1357,11 @@ static int msdc_tune_bread(struct mmc_host *mmc, struct mmc_request *mrq)
}
}
cur_rxdly0 = readl(MSDC_DAT_RDDLY0);
cur_rxdly1 = readl(MSDC_DAT_RDDLY1);
cur_rxdly0 = readl(host->base + MSDC_DAT_RDDLY0);
cur_rxdly1 = readl(host->base + MSDC_DAT_RDDLY1);
/* E1 ECO. YD: Reverse */
if (readl(MSDC_ECO_VER) >= 4) {
if (readl(host->base + MSDC_ECO_VER) >= 4) {
orig_dat0 = (cur_rxdly0 >> 24) & 0x1F;
orig_dat1 = (cur_rxdly0 >> 16) & 0x1F;
orig_dat2 = (cur_rxdly0 >> 8) & 0x1F;
@ -1411,8 +1400,8 @@ static int msdc_tune_bread(struct mmc_host *mmc, struct mmc_request *mrq)
cur_rxdly0 = (cur_dat0 << 24) | (cur_dat1 << 16) | (cur_dat2 << 8) | (cur_dat3 << 0);
cur_rxdly1 = (cur_dat4 << 24) | (cur_dat5 << 16) | (cur_dat6 << 8) | (cur_dat7 << 0);
writel(cur_rxdly0, MSDC_DAT_RDDLY0);
writel(cur_rxdly1, MSDC_DAT_RDDLY1);
writel(cur_rxdly0, host->base + MSDC_DAT_RDDLY0);
writel(cur_rxdly1, host->base + MSDC_DAT_RDDLY1);
} while (++rxdly < 32);
@ -1423,7 +1412,6 @@ done:
static int msdc_tune_bwrite(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct msdc_host *host = mmc_priv(mmc);
void __iomem *base = host->base;
u32 wrrdly, cur_wrrdly = 0xffffffff, orig_wrrdly;
u32 dsmpl, cur_dsmpl, orig_dsmpl;
@ -1435,15 +1423,16 @@ static int msdc_tune_bwrite(struct mmc_host *mmc, struct mmc_request *mrq)
// MSDC_IOCON_DDR50CKD need to check. [Fix me]
sdr_get_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, &orig_wrrdly);
sdr_get_field(MSDC_IOCON, MSDC_IOCON_DSPL, &orig_dsmpl);
sdr_get_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY,
&orig_wrrdly);
sdr_get_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL, &orig_dsmpl);
/* Tune Method 2. just DAT0 */
sdr_set_field(MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
cur_rxdly0 = readl(MSDC_DAT_RDDLY0);
sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
cur_rxdly0 = readl(host->base + MSDC_DAT_RDDLY0);
/* E1 ECO. YD: Reverse */
if (readl(MSDC_ECO_VER) >= 4) {
if (readl(host->base + MSDC_ECO_VER) >= 4) {
orig_dat0 = (cur_rxdly0 >> 24) & 0x1F;
orig_dat1 = (cur_rxdly0 >> 16) & 0x1F;
orig_dat2 = (cur_rxdly0 >> 8) & 0x1F;
@ -1465,7 +1454,8 @@ static int msdc_tune_bwrite(struct mmc_host *mmc, struct mmc_request *mrq)
skip = 0;
continue;
}
sdr_set_field(MSDC_IOCON, MSDC_IOCON_DSPL, cur_dsmpl);
sdr_set_field(host->base + MSDC_IOCON,
MSDC_IOCON_DSPL, cur_dsmpl);
if (host->app_cmd) {
result = msdc_app_cmd(host->mmc, host);
@ -1492,7 +1482,8 @@ static int msdc_tune_bwrite(struct mmc_host *mmc, struct mmc_request *mrq)
}
}
cur_wrrdly = (orig_wrrdly + wrrdly + 1) % 32;
sdr_set_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, cur_wrrdly);
sdr_set_field(host->base + MSDC_PAD_TUNE,
MSDC_PAD_TUNE_DATWRDLY, cur_wrrdly);
} while (++wrrdly < 32);
cur_dat0 = (orig_dat0 + rxdly) % 32; /* only adjust bit-1 for crc */
@ -1501,7 +1492,7 @@ static int msdc_tune_bwrite(struct mmc_host *mmc, struct mmc_request *mrq)
cur_dat3 = orig_dat3;
cur_rxdly0 = (cur_dat0 << 24) | (cur_dat1 << 16) | (cur_dat2 << 8) | (cur_dat3 << 0);
writel(cur_rxdly0, MSDC_DAT_RDDLY0);
writel(cur_rxdly0, host->base + MSDC_DAT_RDDLY0);
} while (++rxdly < 32);
done:
@ -1651,8 +1642,7 @@ static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq)
/* called by ops.set_ios */
static void msdc_set_buswidth(struct msdc_host *host, u32 width)
{
void __iomem *base = host->base;
u32 val = readl(SDC_CFG);
u32 val = readl(host->base + SDC_CFG);
val &= ~SDC_CFG_BUSWIDTH;
@ -1670,7 +1660,7 @@ static void msdc_set_buswidth(struct msdc_host *host, u32 width)
break;
}
writel(val, SDC_CFG);
writel(val, host->base + SDC_CFG);
N_MSG(CFG, "Bus Width = %d", width);
}
@ -1679,7 +1669,6 @@ static void msdc_set_buswidth(struct msdc_host *host, u32 width)
static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct msdc_host *host = mmc_priv(mmc);
void __iomem *base = host->base;
u32 ddr = 0;
#ifdef MT6575_SD_DEBUG
@ -1725,18 +1714,23 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (ios->clock > 25000000) {
//if (!(host->hw->flags & MSDC_REMOVABLE)) {
INIT_MSG("SD data latch edge<%d>", MSDC_SMPL_FALLING);
sdr_set_field(MSDC_IOCON, MSDC_IOCON_RSPL,
sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL,
MSDC_SMPL_FALLING);
sdr_set_field(MSDC_IOCON, MSDC_IOCON_DSPL,
sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL,
MSDC_SMPL_FALLING);
//} /* for tuning debug */
} else { /* default value */
writel(0x00000000, MSDC_IOCON);
// writel(0x00000000, MSDC_DAT_RDDLY0);
writel(0x10101010, MSDC_DAT_RDDLY0); // for MT7620 E2 and afterward
writel(0x00000000, MSDC_DAT_RDDLY1);
// writel(0x00000000, MSDC_PAD_TUNE);
writel(0x84101010, MSDC_PAD_TUNE); // for MT7620 E2 and afterward
writel(0x00000000, host->base + MSDC_IOCON);
// writel(0x00000000, host->base + MSDC_DAT_RDDLY0);
// for MT7620 E2 and afterward
writel(0x10101010, host->base + MSDC_DAT_RDDLY0);
writel(0x00000000, host->base + MSDC_DAT_RDDLY1);
// writel(0x00000000, host->base + MSDC_PAD_TUNE);
// for MT7620 E2 and afterward
writel(0x84101010, host->base + MSDC_PAD_TUNE);
}
msdc_set_mclk(host, ddr, ios->clock);
}
@ -1746,13 +1740,12 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
static int msdc_ops_get_ro(struct mmc_host *mmc)
{
struct msdc_host *host = mmc_priv(mmc);
void __iomem *base = host->base;
unsigned long flags;
int ro = 0;
if (host->hw->flags & MSDC_WP_PIN_EN) { /* set for card */
spin_lock_irqsave(&host->lock, flags);
ro = (readl(MSDC_PS) >> 31);
ro = (readl(host->base + MSDC_PS) >> 31);
spin_unlock_irqrestore(&host->lock, flags);
}
return ro;
@ -1762,7 +1755,6 @@ static int msdc_ops_get_ro(struct mmc_host *mmc)
static int msdc_ops_get_cd(struct mmc_host *mmc)
{
struct msdc_host *host = mmc_priv(mmc);
void __iomem *base = host->base;
unsigned long flags;
int present = 1;
@ -1786,10 +1778,11 @@ static int msdc_ops_get_cd(struct mmc_host *mmc)
present = host->card_inserted; /* why not read from H/W: Fix me*/
#else
// CD
present = readl(host->base + MSDC_PS) & MSDC_PS_CDSTS;
if (cd_active_low)
present = (readl(MSDC_PS) & MSDC_PS_CDSTS) ? 0 : 1;
present = present ? 0 : 1;
else
present = (readl(MSDC_PS) & MSDC_PS_CDSTS) ? 1 : 0;
present = present ? 1 : 0;
host->card_inserted = present;
#endif
spin_unlock_irqrestore(&host->lock, flags);
@ -1816,17 +1809,16 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
struct msdc_host *host = (struct msdc_host *)dev_id;
struct mmc_data *data = host->data;
struct mmc_command *cmd = host->cmd;
void __iomem *base = host->base;
u32 cmdsts = MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO | MSDC_INT_CMDRDY |
MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | MSDC_INT_ACMDRDY |
MSDC_INT_ACMD19_DONE;
u32 datsts = MSDC_INT_DATCRCERR | MSDC_INT_DATTMO;
u32 intsts = readl(MSDC_INT);
u32 inten = readl(MSDC_INTEN); inten &= intsts;
u32 intsts = readl(host->base + MSDC_INT);
u32 inten = readl(host->base + MSDC_INTEN); inten &= intsts;
writel(intsts, MSDC_INT); /* clear interrupts */
writel(intsts, host->base + MSDC_INT); /* clear interrupts */
/* MSG will cause fatal error */
/* card change interrupt */
@ -1861,7 +1853,7 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
IRQ_MSG("XXX CMD<%d> MSDC_INT_DATTMO", host->mrq->cmd->opcode);
data->error = -ETIMEDOUT;
} else if (intsts & MSDC_INT_DATCRCERR) {
IRQ_MSG("XXX CMD<%d> MSDC_INT_DATCRCERR, SDC_DCRC_STS<0x%x>", host->mrq->cmd->opcode, readl(SDC_DCRC_STS));
IRQ_MSG("XXX CMD<%d> MSDC_INT_DATCRCERR, SDC_DCRC_STS<0x%x>", host->mrq->cmd->opcode, readl(host->base + SDC_DCRC_STS));
data->error = -EIO;
}
@ -1880,14 +1872,16 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
case RESP_NONE:
break;
case RESP_R2:
*rsp++ = readl(SDC_RESP3); *rsp++ = readl(SDC_RESP2);
*rsp++ = readl(SDC_RESP1); *rsp++ = readl(SDC_RESP0);
*rsp++ = readl(host->base + SDC_RESP3);
*rsp++ = readl(host->base + SDC_RESP2);
*rsp++ = readl(host->base + SDC_RESP1);
*rsp++ = readl(host->base + SDC_RESP0);
break;
default: /* Response types 1, 3, 4, 5, 6, 7(1b) */
if ((intsts & MSDC_INT_ACMDRDY) || (intsts & MSDC_INT_ACMD19_DONE))
*rsp = readl(SDC_ACMD_RESP);
*rsp = readl(host->base + SDC_ACMD_RESP);
else
*rsp = readl(SDC_RESP0);
*rsp = readl(host->base + SDC_RESP0);
break;
}
} else if ((intsts & MSDC_INT_RSPCRCERR) || (intsts & MSDC_INT_ACMDCRCERR)) {
@ -1911,7 +1905,8 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
/* mmc irq interrupts */
if (intsts & MSDC_INT_MMCIRQ)
printk(KERN_INFO "msdc[%d] MMCIRQ: SDC_CSTS=0x%.8x\r\n", host->id, readl(SDC_CSTS));
printk(KERN_INFO "msdc[%d] MMCIRQ: SDC_CSTS=0x%.8x\r\n",
host->id, readl(host->base + SDC_CSTS));
#ifdef MT6575_SD_DEBUG
{
@ -1951,7 +1946,6 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
static void msdc_enable_cd_irq(struct msdc_host *host, int enable)
{
struct msdc_hw *hw = host->hw;
void __iomem *base = host->base;
/* for sdio, not set */
if ((hw->flags & MSDC_CD_PIN_EN) == 0) {
@ -1960,9 +1954,9 @@ static void msdc_enable_cd_irq(struct msdc_host *host, int enable)
if (hw->config_gpio_pin)
hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_DOWN);
*/
sdr_clr_bits(MSDC_PS, MSDC_PS_CDEN);
sdr_clr_bits(MSDC_INTEN, MSDC_INTEN_CDSC);
sdr_clr_bits(SDC_CFG, SDC_CFG_INSWKUP);
sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN);
sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CDSC);
sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP);
return;
}
@ -1978,17 +1972,20 @@ static void msdc_enable_cd_irq(struct msdc_host *host, int enable)
if (hw->config_gpio_pin) /* NULL */
hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_UP);
sdr_set_field(MSDC_PS, MSDC_PS_CDDEBOUNCE, DEFAULT_DEBOUNCE);
sdr_set_bits(MSDC_PS, MSDC_PS_CDEN);
sdr_set_bits(MSDC_INTEN, MSDC_INTEN_CDSC);
sdr_set_bits(SDC_CFG, SDC_CFG_INSWKUP); /* not in document! Fix me */
sdr_set_field(host->base + MSDC_PS, MSDC_PS_CDDEBOUNCE,
DEFAULT_DEBOUNCE);
sdr_set_bits(host->base + MSDC_PS, MSDC_PS_CDEN);
sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_CDSC);
/* not in document! Fix me */
sdr_set_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP);
} else {
if (hw->config_gpio_pin) /* NULL */
hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_DOWN);
sdr_clr_bits(SDC_CFG, SDC_CFG_INSWKUP);
sdr_clr_bits(MSDC_PS, MSDC_PS_CDEN);
sdr_clr_bits(MSDC_INTEN, MSDC_INTEN_CDSC);
sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP);
sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN);
sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CDSC);
/* Here decreases a reference count to core power since card
* detection circuit is shutdown.
@ -2000,7 +1997,6 @@ static void msdc_enable_cd_irq(struct msdc_host *host, int enable)
/* called by msdc_drv_probe */
static void msdc_init_hw(struct msdc_host *host)
{
void __iomem *base = host->base;
/* Power on */
#if 0 /* --- by chhung */
@ -2011,41 +2007,51 @@ static void msdc_init_hw(struct msdc_host *host)
msdc_vdd_on(host);
#endif /* end of --- */
/* Configure to MMC/SD mode */
sdr_set_field(MSDC_CFG, MSDC_CFG_MODE, MSDC_SDMMC);
sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_MODE, MSDC_SDMMC);
/* Reset */
msdc_reset_hw(host);
msdc_clr_fifo(host);
/* Disable card detection */
sdr_clr_bits(MSDC_PS, MSDC_PS_CDEN);
sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN);
/* Disable and clear all interrupts */
sdr_clr_bits(MSDC_INTEN, readl(MSDC_INTEN));
writel(readl(MSDC_INT), MSDC_INT);
sdr_clr_bits(host->base + MSDC_INTEN, readl(host->base + MSDC_INTEN));
writel(readl(host->base + MSDC_INT), host->base + MSDC_INT);
#if 1
/* reset tuning parameter */
writel(0x00090000, MSDC_PAD_CTL0);
writel(0x000A0000, MSDC_PAD_CTL1);
writel(0x000A0000, MSDC_PAD_CTL2);
// writel( 0x00000000, MSDC_PAD_TUNE);
writel(0x84101010, MSDC_PAD_TUNE); // for MT7620 E2 and afterward
// writel(0x00000000, MSDC_DAT_RDDLY0);
writel(0x10101010, MSDC_DAT_RDDLY0); // for MT7620 E2 and afterward
writel(0x00000000, MSDC_DAT_RDDLY1);
writel(0x00000000, MSDC_IOCON);
writel(0x00090000, host->base + MSDC_PAD_CTL0);
writel(0x000A0000, host->base + MSDC_PAD_CTL1);
writel(0x000A0000, host->base + MSDC_PAD_CTL2);
// writel( 0x00000000, host->base + MSDC_PAD_TUNE);
// for MT7620 E2 and afterward
writel(0x84101010, host->base + MSDC_PAD_TUNE);
// writel(0x00000000, host->base + MSDC_DAT_RDDLY0);
// for MT7620 E2 and afterward
writel(0x10101010, host->base + MSDC_DAT_RDDLY0);
writel(0x00000000, host->base + MSDC_DAT_RDDLY1);
writel(0x00000000, host->base + MSDC_IOCON);
#if 0 // use MT7620 default value: 0x403c004f
writel(0x003C000F, MSDC_PATCH_BIT0); /* bit0 modified: Rx Data Clock Source: 1 -> 2.0*/
/* bit0 modified: Rx Data Clock Source: 1 -> 2.0*/
writel(0x003C000F, host->base + MSDC_PATCH_BIT0);
#endif
if (readl(MSDC_ECO_VER) >= 4) {
if (readl(host->base + MSDC_ECO_VER) >= 4) {
if (host->id == 1) {
sdr_set_field(MSDC_PATCH_BIT1, MSDC_PATCH_BIT1_WRDAT_CRCS, 1);
sdr_set_field(MSDC_PATCH_BIT1, MSDC_PATCH_BIT1_CMD_RSP, 1);
sdr_set_field(host->base + MSDC_PATCH_BIT1,
MSDC_PATCH_BIT1_WRDAT_CRCS, 1);
sdr_set_field(host->base + MSDC_PATCH_BIT1,
MSDC_PATCH_BIT1_CMD_RSP, 1);
/* internal clock: latch read data */
sdr_set_bits(MSDC_PATCH_BIT0, MSDC_PATCH_BIT_CKGEN_CK);
sdr_set_bits(host->base + MSDC_PATCH_BIT0,
MSDC_PATCH_BIT_CKGEN_CK);
}
}
#endif
@ -2054,40 +2060,40 @@ static void msdc_init_hw(struct msdc_host *host)
pre-loader,uboot,kernel drivers. and SDC_CFG.SDIO_INT_DET_EN will be only
set when kernel driver wants to use SDIO bus interrupt */
/* Configure to enable SDIO mode. it's must otherwise sdio cmd5 failed */
sdr_set_bits(SDC_CFG, SDC_CFG_SDIO);
sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIO);
/* disable detect SDIO device interupt function */
sdr_clr_bits(SDC_CFG, SDC_CFG_SDIOIDE);
sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
/* eneable SMT for glitch filter */
sdr_set_bits(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKSMT);
sdr_set_bits(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDSMT);
sdr_set_bits(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATSMT);
sdr_set_bits(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKSMT);
sdr_set_bits(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDSMT);
sdr_set_bits(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATSMT);
#if 1
/* set clk, cmd, dat pad driving */
sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, 4);
sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, 4);
sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, 4);
sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, 4);
sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, 4);
sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, 4);
sdr_set_field(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, 4);
sdr_set_field(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, 4);
sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, 4);
sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, 4);
sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, 4);
sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, 4);
#else
sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, 0);
sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, 0);
sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, 0);
sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, 0);
sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, 0);
sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, 0);
sdr_set_field(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, 0);
sdr_set_field(host->base + MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, 0);
sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, 0);
sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, 0);
sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, 0);
sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, 0);
#endif
/* set sampling edge */
/* write crc timeout detection */
sdr_set_field(MSDC_PATCH_BIT0, 1 << 30, 1);
sdr_set_field(host->base + MSDC_PATCH_BIT0, 1 << 30, 1);
/* Configure to default data timeout */
sdr_set_field(SDC_CFG, SDC_CFG_DTOC, DEFAULT_DTOC);
sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, DEFAULT_DTOC);
msdc_set_buswidth(host, MMC_BUS_WIDTH_1);
@ -2097,11 +2103,9 @@ static void msdc_init_hw(struct msdc_host *host)
/* called by msdc_drv_remove */
static void msdc_deinit_hw(struct msdc_host *host)
{
void __iomem *base = host->base;
/* Disable and clear all interrupts */
sdr_clr_bits(MSDC_INTEN, readl(MSDC_INTEN));
writel(readl(MSDC_INT), MSDC_INT);
sdr_clr_bits(host->base + MSDC_INTEN, readl(host->base + MSDC_INTEN));
writel(readl(host->base + MSDC_INT), host->base + MSDC_INT);
/* Disable card detection */
msdc_enable_cd_irq(host, 0);