summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-08-13 16:56:05 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2018-08-13 16:56:05 +0200
commit1ec421f533610f7af4544748300296fe7728ed70 (patch)
treed70b6e63ff3d087ac30ed68a87c5199b1f568715 /drivers
parent64842a68070318c4c78e99bd69de2401e65de7a5 (diff)
parent2b8466c26a911bed1ac5aa25c463f67b3bdbf1eb (diff)
downloadbarebox-1ec421f533610f7af4544748300296fe7728ed70.tar.gz
barebox-1ec421f533610f7af4544748300296fe7728ed70.tar.xz
Merge branch 'for-next/socfpga'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mci/dw_mmc.c152
-rw-r--r--drivers/mci/dw_mmc.h140
2 files changed, 159 insertions, 133 deletions
diff --git a/drivers/mci/dw_mmc.c b/drivers/mci/dw_mmc.c
index 27c36a6377..e4c550c3ed 100644
--- a/drivers/mci/dw_mmc.c
+++ b/drivers/mci/dw_mmc.c
@@ -26,128 +26,15 @@
#include <mci.h>
#include <io.h>
#include <platform_data/dw_mmc.h>
+#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <asm-generic/errno.h>
+#include "dw_mmc.h"
-#define DWMCI_CTRL 0x000
-#define DWMCI_PWREN 0x004
-#define DWMCI_CLKDIV 0x008
-#define DWMCI_CLKSRC 0x00C
-#define DWMCI_CLKENA 0x010
-#define DWMCI_TMOUT 0x014
-#define DWMCI_CTYPE 0x018
-#define DWMCI_BLKSIZ 0x01C
-#define DWMCI_BYTCNT 0x020
-#define DWMCI_INTMASK 0x024
-#define DWMCI_CMDARG 0x028
-#define DWMCI_CMD 0x02C
-#define DWMCI_RESP0 0x030
-#define DWMCI_RESP1 0x034
-#define DWMCI_RESP2 0x038
-#define DWMCI_RESP3 0x03C
-#define DWMCI_MINTSTS 0x040
-#define DWMCI_RINTSTS 0x044
-#define DWMCI_STATUS 0x048
-#define DWMCI_FIFOTH 0x04C
-#define DWMCI_CDETECT 0x050
-#define DWMCI_WRTPRT 0x054
-#define DWMCI_GPIO 0x058
-#define DWMCI_TCMCNT 0x05C
-#define DWMCI_TBBCNT 0x060
-#define DWMCI_DEBNCE 0x064
-#define DWMCI_USRID 0x068
-#define DWMCI_VERID 0x06C
-#define DWMCI_HCON 0x070
-#define DWMCI_UHS_REG 0x074
-#define DWMCI_BMOD 0x080
-#define DWMCI_PLDMND 0x084
-#define DWMCI_DBADDR 0x088
-#define DWMCI_IDSTS 0x08C
-#define DWMCI_IDINTEN 0x090
-#define DWMCI_DSCADDR 0x094
-#define DWMCI_BUFADDR 0x098
-#define DWMCI_DATA 0x200
-
-/* Interrupt Mask register */
-#define DWMCI_INTMSK_ALL 0xffffffff
-#define DWMCI_INTMSK_RE (1 << 1)
-#define DWMCI_INTMSK_CDONE (1 << 2)
-#define DWMCI_INTMSK_DTO (1 << 3)
-#define DWMCI_INTMSK_TXDR (1 << 4)
-#define DWMCI_INTMSK_RXDR (1 << 5)
-#define DWMCI_INTMSK_RCRC (1 << 6)
-#define DWMCI_INTMSK_DCRC (1 << 7)
-#define DWMCI_INTMSK_RTO (1 << 8)
-#define DWMCI_INTMSK_DRTO (1 << 9)
-#define DWMCI_INTMSK_HTO (1 << 10)
-#define DWMCI_INTMSK_FRUN (1 << 11)
-#define DWMCI_INTMSK_HLE (1 << 12)
-#define DWMCI_INTMSK_SBE (1 << 13)
-#define DWMCI_INTMSK_ACD (1 << 14)
-#define DWMCI_INTMSK_EBE (1 << 15)
-
-/* Raw interrupt Register */
-#define DWMCI_DATA_ERR (DWMCI_INTMSK_EBE | DWMCI_INTMSK_SBE | DWMCI_INTMSK_HLE |\
- DWMCI_INTMSK_FRUN | DWMCI_INTMSK_DCRC)
-#define DWMCI_DATA_TOUT (DWMCI_INTMSK_HTO | DWMCI_INTMSK_DRTO)
-
-/* CTRL register */
-#define DWMCI_CTRL_RESET (1 << 0)
-#define DWMCI_CTRL_FIFO_RESET (1 << 1)
-#define DWMCI_CTRL_DMA_RESET (1 << 2)
-#define DWMCI_DMA_EN (1 << 5)
-#define DWMCI_CTRL_SEND_AS_CCSD (1 << 10)
-#define DWMCI_IDMAC_EN (1 << 25)
-#define DWMCI_RESET_ALL (DWMCI_CTRL_RESET | DWMCI_CTRL_FIFO_RESET |\
- DWMCI_CTRL_DMA_RESET)
-
-/* CMD register */
-#define DWMCI_CMD_RESP_EXP (1 << 6)
-#define DWMCI_CMD_RESP_LENGTH (1 << 7)
-#define DWMCI_CMD_CHECK_CRC (1 << 8)
-#define DWMCI_CMD_DATA_EXP (1 << 9)
-#define DWMCI_CMD_RW (1 << 10)
-#define DWMCI_CMD_SEND_STOP (1 << 12)
-#define DWMCI_CMD_ABORT_STOP (1 << 14)
-#define DWMCI_CMD_PRV_DAT_WAIT (1 << 13)
-#define DWMCI_CMD_UPD_CLK (1 << 21)
-#define DWMCI_CMD_USE_HOLD_REG (1 << 29)
-#define DWMCI_CMD_START (1 << 31)
-
-/* CLKENA register */
-#define DWMCI_CLKEN_ENABLE (1 << 0)
-#define DWMCI_CLKEN_LOW_PWR (1 << 16)
-
-/* Card-type register */
-#define DWMCI_CTYPE_1BIT 0
-#define DWMCI_CTYPE_4BIT (1 << 0)
-#define DWMCI_CTYPE_8BIT (1 << 16)
-
-/* Status Register */
-#define DWMCI_STATUS_FIFO_EMPTY (1 << 2)
-#define DWMCI_STATUS_FIFO_FULL (1 << 3)
-#define DWMCI_STATUS_BUSY (1 << 9)
-
-/* FIFOTH Register */
-#define DWMCI_FIFOTH_MSIZE(x) ((x) << 28)
-#define DWMCI_FIFOTH_RX_WMARK(x) ((x) << 16)
-#define DWMCI_FIFOTH_TX_WMARK(x) (x)
-#define DWMCI_FIFOTH_FIFO_DEPTH(x) ((((x) >> 16) & 0x3ff) + 1)
-
-#define DWMCI_IDMAC_OWN (1 << 31)
-#define DWMCI_IDMAC_CH (1 << 4)
-#define DWMCI_IDMAC_FS (1 << 3)
-#define DWMCI_IDMAC_LD (1 << 2)
-
-/* Bus Mode Register */
-#define DWMCI_BMOD_IDMAC_RESET (1 << 0)
-#define DWMCI_BMOD_IDMAC_FB (1 << 1)
-#define DWMCI_BMOD_IDMAC_EN (1 << 7)
struct dwmci_host {
struct mci_host mci;
- struct device_d *dev;
struct clk *clk_biu, *clk_ciu;
void *ioaddr;
unsigned int fifo_size_bytes;
@@ -271,7 +158,7 @@ static int dwmci_prepare_data_dma(struct dwmci_host *host,
desc->addr = start_addr + (i * PAGE_SIZE);
desc->next_addr = (uint32_t)(desc + 1);
- dev_dbg(host->dev, "desc@ 0x%p 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ dev_dbg(host->mci.hw_dev, "desc@ 0x%p 0x%08x 0x%08x 0x%08x 0x%08x\n",
desc, flags, cnt, desc->addr, desc->next_addr);
if (blk_cnt < 8)
break;
@@ -331,7 +218,7 @@ static int dwmci_read_data_pio(struct dwmci_host *host, struct mci_data *data)
status = dwmci_readl(host, DWMCI_STATUS);
}
if (!timeout) {
- dev_err(host->dev, "%s: FIFO underflow timeout\n",
+ dev_err(host->mci.hw_dev, "%s: FIFO underflow timeout\n",
__func__);
break;
}
@@ -360,7 +247,7 @@ static int dwmci_write_data_pio(struct dwmci_host *host, struct mci_data *data)
status = dwmci_readl(host, DWMCI_STATUS);
}
if (!timeout) {
- dev_err(host->dev, "%s: FIFO overflow timeout\n",
+ dev_err(host->mci.hw_dev, "%s: FIFO overflow timeout\n",
__func__);
break;
}
@@ -378,7 +265,7 @@ static int dwmci_write_data_pio(struct dwmci_host *host, struct mci_data *data)
status = dwmci_readl(host, DWMCI_STATUS);
}
if (!timeout) {
- dev_err(host->dev, "%s: FIFO flush timeout\n",
+ dev_err(host->mci.hw_dev, "%s: FIFO flush timeout\n",
__func__);
return -EIO;
}
@@ -403,7 +290,7 @@ dwmci_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
break;
if (is_timeout(start, 100 * MSECOND)) {
- dev_dbg(host->dev, "Timeout on data busy\n");
+ dev_dbg(host->mci.hw_dev, "Timeout on data busy\n");
return -ETIMEDOUT;
}
}
@@ -449,7 +336,7 @@ dwmci_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
flags |= (cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG);
- dev_dbg(host->dev, "Sending CMD%d\n", cmd->cmdidx);
+ dev_dbg(host->mci.hw_dev, "Sending CMD%d\n", cmd->cmdidx);
dwmci_writel(host, DWMCI_CMD, flags);
@@ -462,16 +349,16 @@ dwmci_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
break;
}
if (is_timeout(start, 100 * MSECOND)) {
- dev_dbg(host->dev, "Send command timeout..\n");
+ dev_dbg(host->mci.hw_dev, "Send command timeout..\n");
return -ETIMEDOUT;
}
}
if (mask & DWMCI_INTMSK_RTO) {
- dev_dbg(host->dev, "Response Timeout..\n");
+ dev_dbg(host->mci.hw_dev, "Response Timeout..\n");
return -ETIMEDOUT;
} else if (mask & DWMCI_INTMSK_RE) {
- dev_dbg(host->dev, "Response Error..\n");
+ dev_dbg(host->mci.hw_dev, "Response Error..\n");
return -EIO;
}
@@ -492,17 +379,17 @@ dwmci_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
mask = dwmci_readl(host, DWMCI_RINTSTS);
if (mask & (DWMCI_DATA_ERR)) {
- dev_dbg(host->dev, "DATA ERROR!\n");
+ dev_dbg(host->mci.hw_dev, "DATA ERROR!\n");
return -EIO;
}
if (!dwmci_use_pio(host) && (mask & DWMCI_DATA_TOUT)) {
- dev_dbg(host->dev, "DATA TIMEOUT!\n");
+ dev_dbg(host->mci.hw_dev, "DATA TIMEOUT!\n");
return -EIO;
}
if (is_timeout(start, SECOND * 10)) {
- dev_dbg(host->dev, "Data timeout\n");
+ dev_dbg(host->mci.hw_dev, "Data timeout\n");
return -ETIMEDOUT;
}
@@ -552,7 +439,7 @@ static int dwmci_send_cmd(struct dwmci_host *host, u32 cmd, u32 arg)
return 0;
if (is_timeout(start, 100 * MSECOND)) {
- dev_err(host->dev, "TIMEOUT error!!\n");
+ dev_err(host->mci.hw_dev, "TIMEOUT error!!\n");
return -ETIMEDOUT;
}
}
@@ -590,7 +477,7 @@ static void dwmci_set_ios(struct mci_host *mci, struct mci_ios *ios)
struct dwmci_host *host = to_dwmci_host(mci);
uint32_t ctype;
- dev_dbg(host->dev, "Buswidth = %d, clock: %d\n", ios->bus_width, ios->clock);
+ dev_dbg(host->mci.hw_dev, "Buswidth = %d, clock: %d\n", ios->bus_width, ios->clock);
if (ios->clock)
dwmci_setup_bus(host, ios->clock);
@@ -623,7 +510,7 @@ static int dwmci_init(struct mci_host *mci, struct device_d *dev)
dwmci_writel(host, DWMCI_PWREN, host->pwren_value);
if (dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
- dev_err(host->dev, "reset failed\n");
+ dev_err(host->mci.hw_dev, "reset failed\n");
return -EIO;
}
@@ -647,10 +534,10 @@ static int dwmci_init(struct mci_host *mci, struct device_d *dev)
/*
* If fifo-depth property is set, use this value
*/
- if (!of_property_read_u32(host->dev->device_node,
+ if (!of_property_read_u32(host->mci.hw_dev->device_node,
"fifo-depth", &fifo_size)) {
host->fifo_size_bytes = fifo_size;
- dev_dbg(host->dev, "Using fifo-depth=%u\n",
+ dev_dbg(host->mci.hw_dev, "Using fifo-depth=%u\n",
host->fifo_size_bytes);
}
@@ -692,7 +579,6 @@ static int dw_mmc_probe(struct device_d *dev)
clk_enable(host->clk_biu);
clk_enable(host->clk_ciu);
- host->dev = dev;
iores = dev_request_mem_resource(dev, 0);
if (IS_ERR(iores))
return PTR_ERR(iores);
diff --git a/drivers/mci/dw_mmc.h b/drivers/mci/dw_mmc.h
new file mode 100644
index 0000000000..23b0f0fe26
--- /dev/null
+++ b/drivers/mci/dw_mmc.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2013 Altera Corporation <www.altera.com>
+ *
+ * (C) Copyright 2012 SAMSUNG Electronics
+ * Jaehoon Chung <jh80.chung@samsung.com>
+ * Rajeshawari Shinde <rajeshwari.s@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __DW_MMC_H__
+#define __DW_MMC_H__
+
+#include <linux/bitops.h>
+
+#define DWMCI_CTRL 0x000
+#define DWMCI_PWREN 0x004
+#define DWMCI_CLKDIV 0x008
+#define DWMCI_CLKSRC 0x00C
+#define DWMCI_CLKENA 0x010
+#define DWMCI_TMOUT 0x014
+#define DWMCI_CTYPE 0x018
+#define DWMCI_BLKSIZ 0x01C
+#define DWMCI_BYTCNT 0x020
+#define DWMCI_INTMASK 0x024
+#define DWMCI_CMDARG 0x028
+#define DWMCI_CMD 0x02C
+#define DWMCI_RESP0 0x030
+#define DWMCI_RESP1 0x034
+#define DWMCI_RESP2 0x038
+#define DWMCI_RESP3 0x03C
+#define DWMCI_MINTSTS 0x040
+#define DWMCI_RINTSTS 0x044
+#define DWMCI_STATUS 0x048
+#define DWMCI_FIFOTH 0x04C
+#define DWMCI_CDETECT 0x050
+#define DWMCI_WRTPRT 0x054
+#define DWMCI_GPIO 0x058
+#define DWMCI_TCMCNT 0x05C
+#define DWMCI_TBBCNT 0x060
+#define DWMCI_DEBNCE 0x064
+#define DWMCI_USRID 0x068
+#define DWMCI_VERID 0x06C
+#define DWMCI_HCON 0x070
+#define DWMCI_UHS_REG 0x074
+#define DWMCI_BMOD 0x080
+#define DWMCI_PLDMND 0x084
+#define DWMCI_DBADDR 0x088
+#define DWMCI_IDSTS 0x08C
+#define DWMCI_IDINTEN 0x090
+#define DWMCI_DSCADDR 0x094
+#define DWMCI_BUFADDR 0x098
+#define DWMCI_DATA 0x200
+
+/* Interrupt Mask register */
+#define DWMCI_INTMSK_ALL 0xffffffff
+#define DWMCI_INTMSK_RE BIT(1)
+#define DWMCI_INTMSK_CDONE BIT(2)
+#define DWMCI_INTMSK_DTO BIT(3)
+#define DWMCI_INTMSK_TXDR BIT(4)
+#define DWMCI_INTMSK_RXDR BIT(5)
+#define DWMCI_INTMSK_RCRC BIT(6)
+#define DWMCI_INTMSK_DCRC BIT(7)
+#define DWMCI_INTMSK_RTO BIT(8)
+#define DWMCI_INTMSK_DRTO BIT(9)
+#define DWMCI_INTMSK_HTO BIT(10)
+#define DWMCI_INTMSK_FRUN BIT(11)
+#define DWMCI_INTMSK_HLE BIT(12)
+#define DWMCI_INTMSK_SBE BIT(13)
+#define DWMCI_INTMSK_ACD BIT(14)
+#define DWMCI_INTMSK_EBE BIT(15)
+
+/* Raw interrupt Register */
+#define DWMCI_DATA_ERR (DWMCI_INTMSK_EBE | DWMCI_INTMSK_SBE | DWMCI_INTMSK_HLE |\
+ DWMCI_INTMSK_FRUN | DWMCI_INTMSK_DCRC)
+#define DWMCI_DATA_TOUT (DWMCI_INTMSK_HTO | DWMCI_INTMSK_DRTO)
+
+/* CTRL register */
+#define DWMCI_CTRL_RESET BIT(0)
+#define DWMCI_CTRL_FIFO_RESET BIT(1)
+#define DWMCI_CTRL_DMA_RESET BIT(2)
+#define DWMCI_DMA_EN BIT(5)
+#define DWMCI_CTRL_SEND_AS_CCSD BIT(10)
+#define DWMCI_IDMAC_EN BIT(25)
+#define DWMCI_RESET_ALL (DWMCI_CTRL_RESET | DWMCI_CTRL_FIFO_RESET | \
+ DWMCI_CTRL_DMA_RESET)
+
+/* CMD register */
+#define DWMCI_CMD_RESP_EXP BIT(6)
+#define DWMCI_CMD_RESP_LENGTH BIT(7)
+#define DWMCI_CMD_CHECK_CRC BIT(8)
+#define DWMCI_CMD_DATA_EXP BIT(9)
+#define DWMCI_CMD_RW BIT(10)
+#define DWMCI_CMD_SEND_STOP BIT(12)
+#define DWMCI_CMD_ABORT_STOP BIT(14)
+#define DWMCI_CMD_PRV_DAT_WAIT BIT(13)
+#define DWMCI_CMD_UPD_CLK BIT(21)
+#define DWMCI_CMD_USE_HOLD_REG BIT(29)
+#define DWMCI_CMD_START BIT(31)
+
+/* CLKENA register */
+#define DWMCI_CLKEN_ENABLE BIT(0)
+#define DWMCI_CLKEN_LOW_PWR BIT(16)
+
+/* Card-type register */
+#define DWMCI_CTYPE_1BIT 0
+#define DWMCI_CTYPE_4BIT BIT(0)
+#define DWMCI_CTYPE_8BIT BIT(16)
+
+/* Status Register */
+#define DWMCI_STATUS_FIFO_EMPTY BIT(2)
+#define DWMCI_STATUS_FIFO_FULL BIT(3)
+#define DWMCI_STATUS_BUSY BIT(9)
+
+/* FIFOTH Register */
+#define DWMCI_FIFOTH_MSIZE(x) ((x) << 28)
+#define DWMCI_FIFOTH_RX_WMARK(x) ((x) << 16)
+#define DWMCI_FIFOTH_TX_WMARK(x) (x)
+#define DWMCI_FIFOTH_FIFO_DEPTH(x) ((((x) >> 16) & 0x3ff) + 1)
+
+#define DWMCI_IDMAC_OWN BIT(31)
+#define DWMCI_IDMAC_CH BIT(4)
+#define DWMCI_IDMAC_FS BIT(3)
+#define DWMCI_IDMAC_LD BIT(2)
+
+/* Bus Mode Register */
+#define DWMCI_BMOD_IDMAC_RESET BIT(0)
+#define DWMCI_BMOD_IDMAC_FB BIT(1)
+#define DWMCI_BMOD_IDMAC_EN BIT(7)
+
+#endif