* [PATCH 00/21] mci: SDHCI helper functions and arasan driver
@ 2019-11-19 10:50 Sascha Hauer
2019-11-19 10:50 ` [PATCH 01/21] mci: Add sdhci helper Sascha Hauer
` (20 more replies)
0 siblings, 21 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
As we have several drivers for different SDHCI controller variants it's
time to start sharing some code. This series creates some generic SDHCI
helper functions and starts using them drom the different drivers.
There's more to share, this series is only a start. Finally the Arasan
SDHCI driver is added which is used on zynq(mp) SoCs.
Sascha
Sascha Hauer (20):
mci: Add sdhci helper
mci: sdhci: Add missing command type defines
mci: imx-esdhc: use sdhci helpers
mci: bcm2835: use sdhci helpers
mci: tegra: use sdhci helpers
mci: dove: use sdhci helpers
mci: imx-esdhc: Use 16bit register definitions
mci: mci-bcm2835: Use 16bit register definitions
mci: tegra: Use 16bit register definitions
mci: imx-esdhc-pbl: Use 16bit register definitions
mci: sdhci: remove 32bit register defines
mci: sdhci: remove duplicate transfer mode register defines
mci: sdhci: remove duplicate register defines for interrupt bits
mci: sdhci: remove duplicate register defines for prsstat bits
mci: dove: Use sdhci_set_cmd_xfer_mode()
mci: imx-esdhc: Use sdhci_set_cmd_xfer_mode()
mci: bcm2835: Use sdhci_set_cmd_xfer_mode()
mci: tegra: Use sdhci_set_cmd_xfer_mode()
mci: imx-esdhci: Use generic PIO transfer function
mci: mci-bcm2835: Use generic PIO transfer function
Thomas Haemmerle (1):
mci: add Arasan SDHCI controller driver
drivers/mci/Kconfig | 13 ++
drivers/mci/Makefile | 2 +
drivers/mci/arasan-sdhci.c | 423 ++++++++++++++++++++++++++++++++++++
drivers/mci/dove-sdhci.c | 144 ++++++------
drivers/mci/imx-esdhc-pbl.c | 41 ++--
drivers/mci/imx-esdhc.c | 263 ++++++++--------------
drivers/mci/imx-esdhc.h | 4 +-
drivers/mci/mci-bcm2835.c | 227 ++++++-------------
drivers/mci/sdhci.c | 127 +++++++++++
drivers/mci/sdhci.h | 127 ++++++-----
drivers/mci/tegra-sdmmc.c | 159 ++++++--------
11 files changed, 937 insertions(+), 593 deletions(-)
create mode 100644 drivers/mci/arasan-sdhci.c
create mode 100644 drivers/mci/sdhci.c
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 01/21] mci: Add sdhci helper
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 11:10 ` Ahmad Fatoum
2019-11-19 10:50 ` [PATCH 02/21] mci: sdhci: Add missing command type defines Sascha Hauer
` (19 subsequent siblings)
20 siblings, 1 reply; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
We have several SDHCI compatible drivers in the tree. This starts
with a set of generic helper functions for these drivers to share
some common functionality.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/Kconfig | 3 +
drivers/mci/Makefile | 1 +
drivers/mci/sdhci.c | 127 +++++++++++++++++++++++++++++++++++++++++++
drivers/mci/sdhci.h | 45 +++++++++++++++
4 files changed, 176 insertions(+)
create mode 100644 drivers/mci/sdhci.c
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 4a71a46097..c37d40195a 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -34,6 +34,9 @@ config MCI_MMC_BOOT_PARTITIONS
comment "--- MCI host drivers ---"
+config MCI_SDHCI
+ bool
+
config MCI_DW
bool "Synopsys DesignWare Memory Card Interface"
depends on HAS_DMA
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index 04c1287fee..9efdbd651e 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_MCI_SPI) += mci_spi.o
obj-$(CONFIG_MCI_DW) += dw_mmc.o
obj-$(CONFIG_MCI_MMCI) += mmci.o
obj-$(CONFIG_MCI_STM32_SDMMC2) += stm32_sdmmc2.o
+obj-$(CONFIG_MCI_SDHCI) += sdhci.o
diff --git a/drivers/mci/sdhci.c b/drivers/mci/sdhci.c
new file mode 100644
index 0000000000..1ab1c0f236
--- /dev/null
+++ b/drivers/mci/sdhci.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <common.h>
+#include <driver.h>
+#include <mci.h>
+#include <io.h>
+
+#include "sdhci.h"
+
+void sdhci_read_response(struct sdhci *sdhci, struct mci_cmd *cmd)
+{
+ if (cmd->resp_type & MMC_RSP_136) {
+ u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0;
+
+ cmdrsp3 = sdhci_read32(sdhci, SDHCI_RESPONSE_3);
+ cmdrsp2 = sdhci_read32(sdhci, SDHCI_RESPONSE_2);
+ cmdrsp1 = sdhci_read32(sdhci, SDHCI_RESPONSE_1);
+ cmdrsp0 = sdhci_read32(sdhci, SDHCI_RESPONSE_0);
+ cmd->response[0] = (cmdrsp3 << 8) | (cmdrsp2 >> 24);
+ cmd->response[1] = (cmdrsp2 << 8) | (cmdrsp1 >> 24);
+ cmd->response[2] = (cmdrsp1 << 8) | (cmdrsp0 >> 24);
+ cmd->response[3] = (cmdrsp0 << 8);
+ } else {
+ cmd->response[0] = sdhci_read32(sdhci, SDHCI_RESPONSE_0);
+ }
+}
+
+void sdhci_set_cmd_xfer_mode(struct sdhci *host, struct mci_cmd *cmd,
+ struct mci_data *data, bool dma, u32 *command,
+ u32 *xfer)
+{
+ *command = 0;
+ *xfer = 0;
+
+ if (!(cmd->resp_type & MMC_RSP_PRESENT))
+ *command |= SDHCI_RESP_NONE;
+ else if (cmd->resp_type & MMC_RSP_136)
+ *command |= SDHCI_RESP_TYPE_136;
+ else if (cmd->resp_type & MMC_RSP_BUSY)
+ *command |= SDHCI_RESP_TYPE_48_BUSY;
+ else
+ *command |= SDHCI_RESP_TYPE_48;
+
+ if (cmd->resp_type & MMC_RSP_CRC)
+ *command |= SDHCI_CMD_CRC_CHECK_EN;
+ if (cmd->resp_type & MMC_RSP_OPCODE)
+ *command |= SDHCI_CMD_INDEX_CHECK_EN;
+
+ *command |= SDHCI_CMD_INDEX(cmd->cmdidx);
+
+ if (data) {
+ *command |= SDHCI_DATA_PRESENT;
+
+ *xfer |= SDHCI_BLOCK_COUNT_EN;
+
+ if (data->blocks > 1)
+ *xfer |= SDHCI_MULTIPLE_BLOCKS;
+
+ if (data->flags & MMC_DATA_READ)
+ *xfer |= SDHCI_DATA_TO_HOST;
+
+ if (dma)
+ *xfer |= SDHCI_DMA_EN;
+ }
+}
+
+static void sdhci_rx_pio(struct sdhci *sdhci, struct mci_data *data,
+ unsigned int block)
+{
+ u32 *buf = (u32 *)data->dest;
+ int i;
+
+ buf += block * data->blocksize / sizeof(u32);
+
+ for (i = 0; i < data->blocksize / sizeof(u32); i++)
+ buf[i] = sdhci_read32(sdhci, SDHCI_BUFFER);
+}
+
+static void sdhci_tx_pio(struct sdhci *sdhci, struct mci_data *data,
+ unsigned int block)
+{
+ const u32 *buf = (const u32 *)data->src;
+ int i;
+
+ buf += block * data->blocksize / sizeof(u32);
+
+ for (i = 0; i < data->blocksize / sizeof(u32); i++)
+ sdhci_write32(sdhci, SDHCI_BUFFER, buf[i]);
+}
+
+int sdhci_transfer_data(struct sdhci *sdhci, struct mci_data *data)
+{
+ unsigned int block = 0;
+ u32 stat, prs;
+ uint64_t start = get_time_ns();
+
+ do {
+ stat = sdhci_read32(sdhci, SDHCI_INT_STATUS);
+ if (stat & SDHCI_INT_ERROR)
+ return -EIO;
+
+ if (block >= data->blocks)
+ continue;
+
+ prs = sdhci_read32(sdhci, SDHCI_PRESENT_STATE);
+
+ if (prs & SDHCI_BUFFER_READ_ENABLE &&
+ data->flags & MMC_DATA_READ) {
+ sdhci_rx_pio(sdhci, data, block);
+ block++;
+ start = get_time_ns();
+ }
+
+ if (prs & SDHCI_BUFFER_WRITE_ENABLE &&
+ !(data->flags & MMC_DATA_READ)) {
+ sdhci_tx_pio(sdhci, data, block);
+ block++;
+ start = get_time_ns();
+ }
+
+ if (is_timeout(start, 10 * SECOND))
+ return -ETIMEDOUT;
+
+ } while (!(stat & SDHCI_INT_XFER_COMPLETE));
+
+ return 0;
+}
diff --git a/drivers/mci/sdhci.h b/drivers/mci/sdhci.h
index 90595e6433..640398d9d8 100644
--- a/drivers/mci/sdhci.h
+++ b/drivers/mci/sdhci.h
@@ -149,4 +149,49 @@
#define PRSSTAT_CIDHB 0x00000002
#define PRSSTAT_CICHB 0x00000001
+struct sdhci {
+ u32 (*read32)(struct sdhci *host, int reg);
+ u16 (*read16)(struct sdhci *host, int reg);
+ u8 (*read8)(struct sdhci *host, int reg);
+ void (*write32)(struct sdhci *host, int reg, u32 val);
+ void (*write16)(struct sdhci *host, int reg, u16 val);
+ void (*write8)(struct sdhci *host, int reg, u8 val);
+};
+
+static inline u32 sdhci_read32(struct sdhci *host, int reg)
+{
+ return host->read32(host, reg);
+}
+
+static inline u32 sdhci_read16(struct sdhci *host, int reg)
+{
+ return host->read16(host, reg);
+}
+
+static inline u32 sdhci_read8(struct sdhci *host, int reg)
+{
+ return host->read8(host, reg);
+}
+
+static inline void sdhci_write32(struct sdhci *host, int reg, u32 val)
+{
+ host->write32(host, reg, val);
+}
+
+static inline void sdhci_write16(struct sdhci *host, int reg, u32 val)
+{
+ host->write16(host, reg, val);
+}
+
+static inline void sdhci_write8(struct sdhci *host, int reg, u32 val)
+{
+ host->write8(host, reg, val);
+}
+
+void sdhci_read_response(struct sdhci *host, struct mci_cmd *cmd);
+void sdhci_set_cmd_xfer_mode(struct sdhci *host, struct mci_cmd *cmd,
+ struct mci_data *data, bool dma, u32 *command,
+ u32 *xfer);
+int sdhci_transfer_data(struct sdhci *sdhci, struct mci_data *data);
+
#endif /* __MCI_SDHCI_H */
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 02/21] mci: sdhci: Add missing command type defines
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
2019-11-19 10:50 ` [PATCH 01/21] mci: Add sdhci helper Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 03/21] mci: imx-esdhc: use sdhci helpers Sascha Hauer
` (18 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
Add some missing register definitions.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/sdhci.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/mci/sdhci.h b/drivers/mci/sdhci.h
index 640398d9d8..bd98c96060 100644
--- a/drivers/mci/sdhci.h
+++ b/drivers/mci/sdhci.h
@@ -24,6 +24,9 @@
#define SDHCI_DMA_EN BIT(0)
#define SDHCI_COMMAND 0x0e
#define SDHCI_CMD_INDEX(c) (((c) & 0x3f) << 8)
+#define SDHCI_COMMAND_CMDTYP_SUSPEND (1 << 6)
+#define SDHCI_COMMAND_CMDTYP_RESUME (2 << 6)
+#define SDHCI_COMMAND_CMDTYP_ABORT (3 << 6)
#define SDHCI_DATA_PRESENT BIT(5)
#define SDHCI_CMD_INDEX_CHECK_EN BIT(4)
#define SDHCI_CMD_CRC_CHECK_EN BIT(3)
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 03/21] mci: imx-esdhc: use sdhci helpers
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
2019-11-19 10:50 ` [PATCH 01/21] mci: Add sdhci helper Sascha Hauer
2019-11-19 10:50 ` [PATCH 02/21] mci: sdhci: Add missing command type defines Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 04/21] mci: bcm2835: " Sascha Hauer
` (17 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
To use the sdhci helpers we have to switch to the sdhci accessors.
Also use sdhci_read_response().
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/Kconfig | 1 +
drivers/mci/imx-esdhc.c | 140 ++++++++++++++++++++++------------------
2 files changed, 77 insertions(+), 64 deletions(-)
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index c37d40195a..9e7494de96 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -90,6 +90,7 @@ config MCI_IMX
config MCI_IMX_ESDHC
bool "i.MX esdhc"
depends on ARCH_IMX || ARCH_LAYERSCAPE
+ select MCI_SDHCI
help
Enable this entry to add support to read and write SD cards on a
Freescale i.MX25/35/51 based system.
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index db3450a26d..7ae4fb4fd8 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -95,6 +95,7 @@ struct fsl_esdhc_host {
struct device_d *dev;
struct clk *clk;
const struct esdhc_soc_data *socdata;
+ struct sdhci sdhci;
};
#define to_fsl_esdhc(mci) container_of(mci, struct fsl_esdhc_host, mci)
@@ -106,21 +107,37 @@ static inline int esdhc_is_usdhc(struct fsl_esdhc_host *data)
return !!(data->socdata->flags & ESDHC_FLAG_USDHC);
}
-static inline u32 esdhc_read32(struct fsl_esdhc_host *host, unsigned int reg)
+static inline struct fsl_esdhc_host *sdhci_to_esdhc(struct sdhci *sdhci)
{
- if (host->socdata->flags & ESDHC_FLAG_BIGENDIAN)
- return in_be32(host->regs + reg);
- else
- return readl(host->regs + reg);
+ return container_of(sdhci, struct fsl_esdhc_host, sdhci);
}
-static inline void esdhc_write32(struct fsl_esdhc_host *host, unsigned int reg,
- u32 val)
+static u32 esdhc_op_read32_le(struct sdhci *sdhci, int reg)
{
- if (host->socdata->flags & ESDHC_FLAG_BIGENDIAN)
- out_be32(host->regs + reg, val);
- else
- writel(val, host->regs + reg);
+ struct fsl_esdhc_host *host = sdhci_to_esdhc(sdhci);
+
+ return readl(host->regs + reg);
+}
+
+static u32 esdhc_op_read32_be(struct sdhci *sdhci, int reg)
+{
+ struct fsl_esdhc_host *host = sdhci_to_esdhc(sdhci);
+
+ return in_be32(host->regs + reg);
+}
+
+static void esdhc_op_write32_le(struct sdhci *sdhci, int reg, u32 val)
+{
+ struct fsl_esdhc_host *host = sdhci_to_esdhc(sdhci);
+
+ writel(val, host->regs + reg);
+}
+
+static void esdhc_op_write32_be(struct sdhci *sdhci, int reg, u32 val)
+{
+ struct fsl_esdhc_host *host = sdhci_to_esdhc(sdhci);
+
+ out_be32(host->regs + reg, val);
}
static inline void esdhc_clrsetbits32(struct fsl_esdhc_host *host, unsigned int reg,
@@ -128,10 +145,10 @@ static inline void esdhc_clrsetbits32(struct fsl_esdhc_host *host, unsigned int
{
u32 val;
- val = esdhc_read32(host, reg);
+ val = sdhci_read32(&host->sdhci, reg);
val &= ~clear;
val |= set;
- esdhc_write32(host, reg, val);
+ sdhci_write32(&host->sdhci, reg, val);
}
static inline void esdhc_clrbits32(struct fsl_esdhc_host *host, unsigned int reg,
@@ -204,8 +221,8 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
while (blocks) {
timeout = PIO_TIMEOUT;
size = data->blocksize;
- irqstat = esdhc_read32(host, SDHCI_INT_STATUS);
- while (!(esdhc_read32(host, SDHCI_PRESENT_STATE) & PRSSTAT_BREN)
+ irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
+ while (!(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_BREN)
&& --timeout);
if (timeout <= 0) {
dev_err(host->dev, "Data Read Failed\n");
@@ -213,8 +230,8 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
}
while (size && (!(irqstat & IRQSTAT_TC))) {
udelay(100); /* Wait before last byte transfer complete */
- irqstat = esdhc_read32(host, SDHCI_INT_STATUS);
- databuf = esdhc_read32(host, SDHCI_BUFFER);
+ irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
+ databuf = sdhci_read32(&host->sdhci, SDHCI_BUFFER);
*((u32 *)buffer) = databuf;
buffer += 4;
size -= 4;
@@ -227,8 +244,8 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
while (blocks) {
timeout = PIO_TIMEOUT;
size = data->blocksize;
- irqstat = esdhc_read32(host, SDHCI_INT_STATUS);
- while (!(esdhc_read32(host, SDHCI_PRESENT_STATE) & PRSSTAT_BWEN)
+ irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
+ while (!(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_BWEN)
&& --timeout);
if (timeout <= 0) {
dev_err(host->dev, "Data Write Failed\n");
@@ -239,8 +256,8 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
databuf = *((u32 *)buffer);
buffer += 4;
size -= 4;
- irqstat = esdhc_read32(host, SDHCI_INT_STATUS);
- esdhc_write32(host, SDHCI_BUFFER, databuf);
+ irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
+ sdhci_write32(&host->sdhci, SDHCI_BUFFER, databuf);
}
blocks--;
}
@@ -270,10 +287,10 @@ static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data,
esdhc_clrsetbits32(host, IMX_SDHCI_WML, WML_WR_WML_MASK,
wml_value << 16);
}
- esdhc_write32(host, SDHCI_DMA_ADDRESS, dma);
+ sdhci_write32(&host->sdhci, SDHCI_DMA_ADDRESS, dma);
}
- esdhc_write32(host, SDHCI_BLOCK_SIZE__BLOCK_COUNT, data->blocks << 16 | data->blocksize);
+ sdhci_write32(&host->sdhci, SDHCI_BLOCK_SIZE__BLOCK_COUNT, data->blocks << 16 | data->blocksize);
return 0;
}
@@ -287,7 +304,7 @@ static int esdhc_do_data(struct mci_host *mci, struct mci_data *data)
return esdhc_pio_read_write(mci, data);
do {
- irqstat = esdhc_read32(host, SDHCI_INT_STATUS);
+ irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
if (irqstat & DATA_ERR)
return -EIO;
@@ -295,7 +312,7 @@ static int esdhc_do_data(struct mci_host *mci, struct mci_data *data)
if (irqstat & IRQSTAT_DTOE)
return -ETIMEDOUT;
} while (!(irqstat & IRQSTAT_TC) &&
- (esdhc_read32(host, SDHCI_PRESENT_STATE) & PRSSTAT_DLA));
+ (sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_DLA));
return 0;
}
@@ -316,7 +333,7 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
enum dma_data_direction dir = 0;
dma_addr_t dma = 0;
- esdhc_write32(host, SDHCI_INT_STATUS, -1);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, -1);
/* Wait at least 8 SD clock cycles before the next command */
udelay(1);
@@ -350,28 +367,28 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
xfertyp = esdhc_xfertyp(host, cmd, data);
/* Send the command */
- esdhc_write32(host, SDHCI_ARGUMENT, cmd->cmdarg);
+ sdhci_write32(&host->sdhci, SDHCI_ARGUMENT, cmd->cmdarg);
if (esdhc_is_usdhc(host)) {
/* write lower-half of xfertyp to mixctrl */
mixctrl = xfertyp & 0xFFFF;
/* Keep the bits 22-25 of the register as is */
- mixctrl |= (esdhc_read32(host, IMX_SDHCI_MIXCTRL) & (0xF << 22));
- esdhc_write32(host, IMX_SDHCI_MIXCTRL, mixctrl);
+ mixctrl |= (sdhci_read32(&host->sdhci, IMX_SDHCI_MIXCTRL) & (0xF << 22));
+ sdhci_write32(&host->sdhci, IMX_SDHCI_MIXCTRL, mixctrl);
}
- esdhc_write32(host, SDHCI_TRANSFER_MODE__COMMAND, xfertyp);
+ sdhci_write32(&host->sdhci, SDHCI_TRANSFER_MODE__COMMAND, xfertyp);
/* Wait for the command to complete */
ret = wait_on_timeout(100 * MSECOND,
- esdhc_read32(host, SDHCI_INT_STATUS) & IRQSTAT_CC);
+ sdhci_read32(&host->sdhci, SDHCI_INT_STATUS) & IRQSTAT_CC);
if (ret) {
dev_dbg(host->dev, "timeout 1\n");
return -ETIMEDOUT;
}
- irqstat = esdhc_read32(host, SDHCI_INT_STATUS);
- esdhc_write32(host, SDHCI_INT_STATUS, irqstat);
+ irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, irqstat);
if (irqstat & CMD_ERR)
return -EIO;
@@ -386,7 +403,7 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
* timout / 10 usec since DLA polling can be insecure.
*/
ret = wait_on_timeout(2500 * MSECOND,
- (esdhc_read32(host, SDHCI_PRESENT_STATE) & PRSSTAT_DAT0));
+ (sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_DAT0));
if (ret) {
dev_err(host->dev, "timeout PRSSTAT_DAT0\n");
@@ -394,20 +411,7 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
}
}
- /* Copy the response to the response buffer */
- if (cmd->resp_type & MMC_RSP_136) {
- u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0;
-
- cmdrsp3 = esdhc_read32(host, SDHCI_RESPONSE_3);
- cmdrsp2 = esdhc_read32(host, SDHCI_RESPONSE_2);
- cmdrsp1 = esdhc_read32(host, SDHCI_RESPONSE_1);
- cmdrsp0 = esdhc_read32(host, SDHCI_RESPONSE_0);
- cmd->response[0] = (cmdrsp3 << 8) | (cmdrsp2 >> 24);
- cmd->response[1] = (cmdrsp2 << 8) | (cmdrsp1 >> 24);
- cmd->response[2] = (cmdrsp1 << 8) | (cmdrsp0 >> 24);
- cmd->response[3] = (cmdrsp0 << 8);
- } else
- cmd->response[0] = esdhc_read32(host, SDHCI_RESPONSE_0);
+ sdhci_read_response(&host->sdhci, cmd);
/* Wait until all of the blocks are transferred */
if (data) {
@@ -419,11 +423,11 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
dma_unmap_single(host->dev, dma, num_bytes, dir);
}
- esdhc_write32(host, SDHCI_INT_STATUS, -1);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, -1);
/* Wait for the bus to be idle */
ret = wait_on_timeout(SECOND,
- !(esdhc_read32(host, SDHCI_PRESENT_STATE) &
+ !(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) &
(PRSSTAT_CICHB | PRSSTAT_CIDHB)));
if (ret) {
dev_err(host->dev, "timeout 2\n");
@@ -431,7 +435,7 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
}
ret = wait_on_timeout(100 * MSECOND,
- !(esdhc_read32(host, SDHCI_PRESENT_STATE) & PRSSTAT_DLA));
+ !(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_DLA));
if (ret) {
dev_err(host->dev, "timeout 3\n");
return -ETIMEDOUT;
@@ -487,7 +491,7 @@ static void set_sysctl(struct mci_host *mci, u32 clock)
SYSCTL_CLOCK_MASK, clk);
wait_on_timeout(10 * MSECOND,
- esdhc_read32(host, SDHCI_PRESENT_STATE) & PRSSTAT_SDSTB);
+ sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_SDSTB);
clk = SYSCTL_PEREN | SYSCTL_CKEN | SYSCTL_INITA;
@@ -495,7 +499,7 @@ static void set_sysctl(struct mci_host *mci, u32 clock)
clk);
wait_on_timeout(1 * MSECOND,
- !(esdhc_read32(host, SDHCI_CLOCK_CONTROL) & SYSCTL_INITA));
+ !(sdhci_read32(&host->sdhci, SDHCI_CLOCK_CONTROL) & SYSCTL_INITA));
}
static void esdhc_set_ios(struct mci_host *mci, struct mci_ios *ios)
@@ -540,7 +544,7 @@ static int esdhc_card_present(struct mci_host *mci)
case ESDHC_CD_PERMANENT:
return 1;
case ESDHC_CD_CONTROLLER:
- return !(esdhc_read32(host, SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL);
+ return !(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL);
case ESDHC_CD_GPIO:
ret = gpio_direction_input(pdata->cd_gpio);
if (ret)
@@ -557,24 +561,24 @@ static int esdhc_reset(struct fsl_esdhc_host *host)
int val;
/* reset the controller */
- esdhc_write32(host, SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ sdhci_write32(&host->sdhci, SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
SYSCTL_RSTA);
/* extra register reset for i.MX6 Solo/DualLite */
if (esdhc_is_usdhc(host)) {
/* reset bit FBCLK_SEL */
- val = esdhc_read32(host, IMX_SDHCI_MIXCTRL);
+ val = sdhci_read32(&host->sdhci, IMX_SDHCI_MIXCTRL);
val &= ~IMX_SDHCI_MIX_CTRL_FBCLK_SEL;
- esdhc_write32(host, IMX_SDHCI_MIXCTRL, val);
+ sdhci_write32(&host->sdhci, IMX_SDHCI_MIXCTRL, val);
/* reset delay line settings in IMX_SDHCI_DLL_CTRL */
- esdhc_write32(host, IMX_SDHCI_DLL_CTRL, 0x0);
+ sdhci_write32(&host->sdhci, IMX_SDHCI_DLL_CTRL, 0x0);
}
start = get_time_ns();
/* hardware clears the bit when it is done */
while (1) {
- if (!(esdhc_read32(host, SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET)
+ if (!(sdhci_read32(&host->sdhci, SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET)
& SYSCTL_RSTA))
break;
if (is_timeout(start, 100 * MSECOND)) {
@@ -595,11 +599,11 @@ static int esdhc_init(struct mci_host *mci, struct device_d *dev)
if (ret)
return ret;
- esdhc_write32(host, SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ sdhci_write32(&host->sdhci, SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
SYSCTL_HCKEN | SYSCTL_IPGEN);
/* RSTA doesn't reset MMC_BOOT register, so manually reset it */
- esdhc_write32(host, SDHCI_MMC_BOOT, 0);
+ sdhci_write32(&host->sdhci, SDHCI_MMC_BOOT, 0);
/* Enable cache snooping */
if (host->socdata->flags & ESDHC_FLAG_CACHE_SNOOPING)
@@ -608,13 +612,13 @@ static int esdhc_init(struct mci_host *mci, struct device_d *dev)
/* Set the initial clock speed */
set_sysctl(mci, 400000);
- esdhc_write32(host, SDHCI_INT_ENABLE, IRQSTATEN_CC | IRQSTATEN_TC |
+ sdhci_write32(&host->sdhci, SDHCI_INT_ENABLE, IRQSTATEN_CC | IRQSTATEN_TC |
IRQSTATEN_CINT | IRQSTATEN_CTOE | IRQSTATEN_CCE |
IRQSTATEN_CEBE | IRQSTATEN_CIE | IRQSTATEN_DTOE |
IRQSTATEN_DCE | IRQSTATEN_DEBE | IRQSTATEN_DINT);
/* Put the PROCTL reg back to the default */
- esdhc_write32(host, SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
+ sdhci_write32(&host->sdhci, SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
PROCTL_INIT);
/* Set timout to the maximum value */
@@ -673,7 +677,15 @@ static int fsl_esdhc_probe(struct device_d *dev)
}
host->regs = IOMEM(iores->start);
- caps = esdhc_read32(host, SDHCI_CAPABILITIES);
+ if (host->socdata->flags & ESDHC_FLAG_BIGENDIAN) {
+ host->sdhci.read32 = esdhc_op_read32_be;
+ host->sdhci.write32 = esdhc_op_write32_be;
+ } else {
+ host->sdhci.read32 = esdhc_op_read32_le;
+ host->sdhci.write32 = esdhc_op_write32_le;
+ }
+
+ caps = sdhci_read32(&host->sdhci, SDHCI_CAPABILITIES);
if (caps & ESDHC_HOSTCAPBLT_VS18)
mci->voltages |= MMC_VDD_165_195;
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 04/21] mci: bcm2835: use sdhci helpers
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (2 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 03/21] mci: imx-esdhc: use sdhci helpers Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 05/21] mci: tegra: " Sascha Hauer
` (16 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
To use the sdhci helpers we have to switch to the sdhci accessors.
Also use sdhci_read_response().
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/Kconfig | 1 +
drivers/mci/mci-bcm2835.c | 119 +++++++++++++++++---------------------
2 files changed, 55 insertions(+), 65 deletions(-)
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 9e7494de96..23a38721aa 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -72,6 +72,7 @@ config MCI_BCM283X
config MCI_BCM283X_SDHOST
bool "BCM283X sdhost"
depends on ARCH_BCM283X
+ select MCI_SDHCI
config MCI_DOVE
bool "Marvell Dove SDHCI"
diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c
index 2ed1251672..7037cbf7b8 100644
--- a/drivers/mci/mci-bcm2835.c
+++ b/drivers/mci/mci-bcm2835.c
@@ -51,10 +51,13 @@ struct bcm2835_mci_host {
u32 max_clock;
u32 version;
uint64_t last_write;
+ struct sdhci sdhci;
};
-static void bcm2835_mci_write(struct bcm2835_mci_host *host, u32 reg, u32 val)
+static void bcm2835_sdhci_write32(struct sdhci *sdhci, int reg, u32 val)
{
+ struct bcm2835_mci_host *host = container_of(sdhci, struct bcm2835_mci_host, sdhci);
+
/*
* The Arasan has a bugette whereby it may lose the content of
* successive writes to registers that are within two SD-card clock
@@ -71,8 +74,10 @@ static void bcm2835_mci_write(struct bcm2835_mci_host *host, u32 reg, u32 val)
writel(val, host->regs + reg);
}
-static u32 bcm2835_mci_read(struct bcm2835_mci_host *host, u32 reg)
+static u32 bcm2835_sdhci_read32(struct sdhci *sdhci, int reg)
{
+ struct bcm2835_mci_host *host = container_of(sdhci, struct bcm2835_mci_host, sdhci);
+
return readl(host->regs + reg);
}
@@ -80,13 +85,13 @@ static u32 bcm2835_mci_read(struct bcm2835_mci_host *host, u32 reg)
* register is not affected by the twoticks_delay bug
* and we can thus get better speed here
*/
-static void bcm2835_mci_write_data(struct bcm2835_mci_host *host, u32 *p)
+static void sdhci_write32_data(struct bcm2835_mci_host *host, u32 *p)
{
writel(*p, host->regs + SDHCI_BUFFER);
}
/* Make a read data functions as well just to keep structure */
-static void bcm2835_mci_read_data(struct bcm2835_mci_host *host, u32 *p)
+static void sdhci_read32_data(struct bcm2835_mci_host *host, u32 *p)
{
*p = readl(host->regs + SDHCI_BUFFER);
}
@@ -106,15 +111,15 @@ static int bcm2835_mci_transfer_data(struct bcm2835_mci_host *host,
p = (u32 *) data->dest;
data_ready_intr_mask = IRQSTAT_BRR;
data_ready_status_mask = PRSSTAT_BREN;
- read_write_func = &bcm2835_mci_read_data;
+ read_write_func = &sdhci_read32_data;
} else {
p = (u32 *) data->src;
data_ready_intr_mask = IRQSTAT_BWR;
data_ready_status_mask = PRSSTAT_BWEN;
- read_write_func = &bcm2835_mci_write_data;
+ read_write_func = &sdhci_write32_data;
}
do {
- intr_status = bcm2835_mci_read(host, SDHCI_INT_STATUS);
+ intr_status = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
if (intr_status & IRQSTAT_CIE) {
dev_err(host->hw_dev,
"Error occured while transferring data: 0x%X\n",
@@ -122,11 +127,11 @@ static int bcm2835_mci_transfer_data(struct bcm2835_mci_host *host,
return -EPERM;
}
if (intr_status & data_ready_intr_mask) {
- status = bcm2835_mci_read(host, SDHCI_PRESENT_STATE);
+ status = sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE);
if ((status & data_ready_status_mask) == 0)
continue;
/*Clear latest int and transfer one block size of data*/
- bcm2835_mci_write(host, SDHCI_INT_STATUS,
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS,
data_ready_intr_mask);
for (i = 0; i < data->blocksize; i += 4) {
read_write_func(host, p);
@@ -147,8 +152,8 @@ static int bcm2835_mci_transfer_data(struct bcm2835_mci_host *host,
data->blocksize * data->blocks);
dev_err(host->hw_dev, "Status: 0x%X, Interrupt: 0x%X\n",
- bcm2835_mci_read(host, SDHCI_PRESENT_STATE),
- bcm2835_mci_read(host, SDHCI_INT_STATUS));
+ sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE),
+ sdhci_read32(&host->sdhci, SDHCI_INT_STATUS));
return -EPERM;
}
@@ -160,8 +165,7 @@ static u32 bcm2835_mci_wait_command_done(struct bcm2835_mci_host *host)
u32 interrupt = 0;
while (true) {
- interrupt = bcm2835_mci_read(
- host, SDHCI_INT_STATUS);
+ interrupt = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
if (interrupt & IRQSTAT_CIE)
return -EPERM;
if (interrupt & IRQSTAT_CC)
@@ -174,15 +178,15 @@ static void bcm2835_mci_reset_emmc(struct bcm2835_mci_host *host, u32 reset,
u32 wait_for)
{
u32 ret;
- u32 current = bcm2835_mci_read(host,
+ u32 current = sdhci_read32(&host->sdhci,
SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET);
- bcm2835_mci_write(host,
+ sdhci_write32(&host->sdhci,
SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
current | reset);
while (true) {
- ret = bcm2835_mci_read(host,
+ ret = sdhci_read32(&host->sdhci,
SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET);
if (ret & wait_for)
continue;
@@ -234,52 +238,35 @@ static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
wait_inhibit_mask = PRSSTAT_CICHB;
/*Wait for old command*/
- while (bcm2835_mci_read(host, SDHCI_PRESENT_STATE)
+ while (sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE)
& wait_inhibit_mask)
;
- bcm2835_mci_write(host, SDHCI_INT_ENABLE, 0xFFFFFFFF);
- bcm2835_mci_write(host, SDHCI_INT_STATUS, 0xFFFFFFFF);
+ sdhci_write32(&host->sdhci, SDHCI_INT_ENABLE, 0xFFFFFFFF);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, 0xFFFFFFFF);
- bcm2835_mci_write(host, SDHCI_BLOCK_SIZE__BLOCK_COUNT, block_data);
- bcm2835_mci_write(host, SDHCI_ARGUMENT, cmd->cmdarg);
- bcm2835_mci_write(host, SDHCI_TRANSFER_MODE__COMMAND, command);
+ sdhci_write32(&host->sdhci, SDHCI_BLOCK_SIZE__BLOCK_COUNT, block_data);
+ sdhci_write32(&host->sdhci, SDHCI_ARGUMENT, cmd->cmdarg);
+ sdhci_write32(&host->sdhci, SDHCI_TRANSFER_MODE__COMMAND, command);
ret = bcm2835_mci_wait_command_done(host);
if (ret) {
dev_err(host->hw_dev, "Error while executing command %d\n",
cmd->cmdidx);
dev_err(host->hw_dev, "Status: 0x%X, Interrupt: 0x%X\n",
- bcm2835_mci_read(host, SDHCI_PRESENT_STATE),
- bcm2835_mci_read(host, SDHCI_INT_STATUS));
+ sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE),
+ sdhci_read32(&host->sdhci, SDHCI_INT_STATUS));
}
if (cmd->resp_type != 0 && ret != -1) {
- int i = 0;
-
- /* CRC is stripped so we need to do some shifting. */
- if (cmd->resp_type & MMC_RSP_136) {
- for (i = 0; i < 4; i++) {
- cmd->response[i] = bcm2835_mci_read(
- host,
- SDHCI_RESPONSE_0 + (3 - i) * 4) << 8;
- if (i != 3)
- cmd->response[i] |=
- readb((u32) (host->regs) +
- SDHCI_RESPONSE_0 +
- (3 - i) * 4 - 1);
- }
- } else {
- cmd->response[0] = bcm2835_mci_read(
- host, SDHCI_RESPONSE_0);
- }
- bcm2835_mci_write(host, SDHCI_INT_STATUS,
- IRQSTAT_CC);
+ sdhci_read_response(&host->sdhci, cmd);
+
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, IRQSTAT_CC);
}
if (!ret && data)
ret = bcm2835_mci_transfer_data(host, cmd, data);
- bcm2835_mci_write(host, SDHCI_INT_STATUS, 0xFFFFFFFF);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, 0xFFFFFFFF);
if (ret) {
bcm2835_mci_reset_emmc(host, CONTROL1_CMDRST,
CONTROL1_CMDRST);
@@ -343,19 +330,19 @@ static void bcm2835_mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
struct bcm2835_mci_host *host = to_bcm2835_host(mci);
- current_val = bcm2835_mci_read(host,
+ current_val = sdhci_read32(&host->sdhci,
SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL);
switch (ios->bus_width) {
case MMC_BUS_WIDTH_4:
- bcm2835_mci_write(host,
+ sdhci_write32(&host->sdhci,
SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
current_val | CONTROL0_4DATA);
host->bus_width = 1;
dev_dbg(host->hw_dev, "Changing bus width to 4\n");
break;
case MMC_BUS_WIDTH_1:
- bcm2835_mci_write(host,
+ sdhci_write32(&host->sdhci,
SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
current_val & ~CONTROL0_4DATA);
host->bus_width = 0;
@@ -367,15 +354,15 @@ static void bcm2835_mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
return;
}
if (ios->clock != host->clock && ios->clock != 0) {
- bcm2835_mci_write(host,
+ sdhci_write32(&host->sdhci,
SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
0x00);
if (ios->clock > 26000000) {
- enable = bcm2835_mci_read(host,
+ enable = sdhci_read32(&host->sdhci,
SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL);
enable |= CONTROL0_HISPEED;
- bcm2835_mci_write(host,
+ sdhci_write32(&host->sdhci,
SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
enable);
}
@@ -388,18 +375,18 @@ static void bcm2835_mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
enable |= (divider_msb << CONTROL1_CLKMSB);
enable |= CONTROL1_INTCLKENA | CONTROL1_TIMEOUT;
- bcm2835_mci_write(host,
+ sdhci_write32(&host->sdhci,
SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
enable);
while (true) {
- u32 ret = bcm2835_mci_read(host,
+ u32 ret = sdhci_read32(&host->sdhci,
SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET);
if (ret & CONTROL1_CLK_STABLE)
break;
}
enable |= CONTROL1_CLKENA;
- bcm2835_mci_write(host,
+ sdhci_write32(&host->sdhci,
SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
enable);
@@ -437,37 +424,37 @@ static int bcm2835_mci_reset(struct mci_host *mci, struct device_d *mci_dev)
bcm2835_mci_reset_emmc(host, enable | reset, CONTROL1_HOSTRST);
- bcm2835_mci_write(host,
+ sdhci_write32(&host->sdhci,
SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
0x00);
- bcm2835_mci_write(host, SDHCI_ACMD12_ERR__HOST_CONTROL2,
+ sdhci_write32(&host->sdhci, SDHCI_ACMD12_ERR__HOST_CONTROL2,
0x00);
- bcm2835_mci_write(host,
+ sdhci_write32(&host->sdhci,
SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
enable);
while (true) {
- ret = bcm2835_mci_read(host,
+ ret = sdhci_read32(&host->sdhci,
SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET);
if (ret & CONTROL1_CLK_STABLE)
break;
}
enable |= CONTROL1_CLKENA;
- bcm2835_mci_write(host,
+ sdhci_write32(&host->sdhci,
SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
enable);
/*Delay atelast 74 clk cycles for card init*/
mdelay(100);
- bcm2835_mci_write(host, SDHCI_INT_ENABLE,
+ sdhci_write32(&host->sdhci, SDHCI_INT_ENABLE,
0xFFFFFFFF);
- bcm2835_mci_write(host, SDHCI_INT_STATUS,
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS,
0xFFFFFFFF);
/*Now write command 0 and see if we get response*/
- bcm2835_mci_write(host, SDHCI_ARGUMENT, 0x0);
- bcm2835_mci_write(host, SDHCI_TRANSFER_MODE__COMMAND, 0x0);
+ sdhci_write32(&host->sdhci, SDHCI_ARGUMENT, 0x0);
+ sdhci_write32(&host->sdhci, SDHCI_TRANSFER_MODE__COMMAND, 0x0);
return bcm2835_mci_wait_command_done(host);
}
@@ -507,6 +494,9 @@ static int bcm2835_mci_probe(struct device_d *hw_dev)
host->hw_dev = hw_dev;
host->max_clock = clk_get_rate(clk);
+ host->sdhci.read32 = bcm2835_sdhci_read32;
+ host->sdhci.write32 = bcm2835_sdhci_write32;
+
mci_of_parse(&host->mci);
iores = dev_request_mem_resource(hw_dev, 0);
@@ -540,8 +530,7 @@ static int bcm2835_mci_probe(struct device_d *hw_dev)
twoticks_delay = ((2 * 1000000000) / MIN_FREQ) + 1;
- host->version = bcm2835_mci_read(
- host, BCM2835_MCI_SLOTISR_VER);
+ host->version = sdhci_read32(&host->sdhci, BCM2835_MCI_SLOTISR_VER);
host->version = (host->version >> 16) & 0xFF;
return mci_register(&host->mci);
}
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 05/21] mci: tegra: use sdhci helpers
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (3 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 04/21] mci: bcm2835: " Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 06/21] mci: dove: " Sascha Hauer
` (15 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
To use the sdhci helpers we have to switch to the sdhci accessors.
Also use sdhci_read_response().
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/Kconfig | 1 +
drivers/mci/tegra-sdmmc.c | 122 ++++++++++++++++++++------------------
2 files changed, 65 insertions(+), 58 deletions(-)
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 23a38721aa..7c5310deaf 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -136,6 +136,7 @@ config MCI_MMCI
config MCI_TEGRA
bool "Tegra SD/MMC"
depends on ARCH_TEGRA
+ select MCI_SDHCI
help
Enable this to support SD and MMC card read/write on a Tegra based
systems.
diff --git a/drivers/mci/tegra-sdmmc.c b/drivers/mci/tegra-sdmmc.c
index 4c47918076..7618d831b1 100644
--- a/drivers/mci/tegra-sdmmc.c
+++ b/drivers/mci/tegra-sdmmc.c
@@ -74,9 +74,24 @@ struct tegra_sdmmc_host {
struct clk *clk;
struct reset_control *reset;
int gpio_cd, gpio_pwr;
+ struct sdhci sdhci;
};
#define to_tegra_sdmmc_host(mci) container_of(mci, struct tegra_sdmmc_host, mci)
+static u32 tegra_sdmmc_read32(struct sdhci *sdhci, int reg)
+{
+ struct tegra_sdmmc_host *host = container_of(sdhci, struct tegra_sdmmc_host, sdhci);
+
+ return readl(host->regs + reg);
+}
+
+static void tegra_sdmmc_write32(struct sdhci *sdhci, int reg, u32 val)
+{
+ struct tegra_sdmmc_host *host = container_of(sdhci, struct tegra_sdmmc_host, sdhci);
+
+ writel(val, host->regs + reg);
+}
+
static int tegra_sdmmc_wait_inhibit(struct tegra_sdmmc_host *host,
struct mci_cmd *cmd, struct mci_data *data,
unsigned int timeout)
@@ -91,7 +106,7 @@ static int tegra_sdmmc_wait_inhibit(struct tegra_sdmmc_host *host,
val |= TEGRA_SDMMC_PRESENT_STATE_CMD_INHIBIT_DAT;
wait_on_timeout(timeout * MSECOND,
- !(readl(host->regs + TEGRA_SDMMC_PRESENT_STATE) & val));
+ !(sdhci_read32(&host->sdhci, TEGRA_SDMMC_PRESENT_STATE) & val));
return 0;
}
@@ -115,18 +130,18 @@ static int tegra_sdmmc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
if (data->flags & MMC_DATA_WRITE) {
dma_sync_single_for_device((unsigned long)data->src,
num_bytes, DMA_TO_DEVICE);
- writel((u32)data->src, host->regs + SDHCI_DMA_ADDRESS);
+ sdhci_write32(&host->sdhci, SDHCI_DMA_ADDRESS, (u32)data->src);
} else {
dma_sync_single_for_device((unsigned long)data->dest,
num_bytes, DMA_FROM_DEVICE);
- writel((u32)data->dest, host->regs + SDHCI_DMA_ADDRESS);
+ sdhci_write32(&host->sdhci, SDHCI_DMA_ADDRESS, (u32)data->dest);
}
- writel((7 << 12) | data->blocks << 16 | data->blocksize,
- host->regs + SDHCI_BLOCK_SIZE__BLOCK_COUNT);
+ sdhci_write32(&host->sdhci, SDHCI_BLOCK_SIZE__BLOCK_COUNT,
+ (7 << 12) | data->blocks << 16 | data->blocksize);
}
- writel(cmd->cmdarg, host->regs + SDHCI_ARGUMENT);
+ sdhci_write32(&host->sdhci, SDHCI_ARGUMENT, cmd->cmdarg);
if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY))
return -1;
@@ -158,59 +173,48 @@ static int tegra_sdmmc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
if (data)
val |= COMMAND_DPSEL;
- writel(COMMAND_CMD(cmd->cmdidx) | val,
- host->regs + SDHCI_TRANSFER_MODE__COMMAND);
+ sdhci_write32(&host->sdhci, SDHCI_TRANSFER_MODE__COMMAND,
+ COMMAND_CMD(cmd->cmdidx) | val);
ret = wait_on_timeout(100 * MSECOND,
- (val = readl(host->regs + SDHCI_INT_STATUS))
+ (val = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS))
& IRQSTAT_CC);
if (ret) {
- writel(val, host->regs + SDHCI_INT_STATUS);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, val);
return ret;
}
if ((val & IRQSTAT_CC) && !data)
- writel(val, host->regs + SDHCI_INT_STATUS);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, val);
if (val & TEGRA_SDMMC_INTERRUPT_STATUS_CMD_TIMEOUT) {
/* Timeout Error */
dev_dbg(mci->hw_dev, "timeout: %08x cmd %d\n", val, cmd->cmdidx);
- writel(val, host->regs + SDHCI_INT_STATUS);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, val);
return -ETIMEDOUT;
} else if (val & TEGRA_SDMMC_INTERRUPT_STATUS_ERR_INTERRUPT) {
/* Error Interrupt */
dev_dbg(mci->hw_dev, "error: %08x cmd %d\n", val, cmd->cmdidx);
- writel(val, host->regs + SDHCI_INT_STATUS);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, val);
return -EIO;
}
if (cmd->resp_type & MMC_RSP_PRESENT) {
- if (cmd->resp_type & MMC_RSP_136) {
- u32 cmdrsp[4];
-
- cmdrsp[3] = readl(host->regs + SDHCI_RESPONSE_3);
- cmdrsp[2] = readl(host->regs + SDHCI_RESPONSE_2);
- cmdrsp[1] = readl(host->regs + SDHCI_RESPONSE_1);
- cmdrsp[0] = readl(host->regs + SDHCI_RESPONSE_0);
- cmd->response[0] = (cmdrsp[3] << 8) | (cmdrsp[2] >> 24);
- cmd->response[1] = (cmdrsp[2] << 8) | (cmdrsp[1] >> 24);
- cmd->response[2] = (cmdrsp[1] << 8) | (cmdrsp[0] >> 24);
- cmd->response[3] = (cmdrsp[0] << 8);
- } else if (cmd->resp_type & MMC_RSP_BUSY) {
+ sdhci_read_response(&host->sdhci, cmd);
+
+ if (cmd->resp_type & MMC_RSP_BUSY) {
ret = wait_on_timeout(100 * MSECOND,
- readl(host->regs + TEGRA_SDMMC_PRESENT_STATE)
+ sdhci_read32(&host->sdhci, TEGRA_SDMMC_PRESENT_STATE)
& (1 << 20));
if (ret) {
dev_err(mci->hw_dev, "card is still busy\n");
- writel(val, host->regs + SDHCI_INT_STATUS);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, val);
return ret;
}
- cmd->response[0] = readl(host->regs + SDHCI_RESPONSE_0);
- } else {
- cmd->response[0] = readl(host->regs + SDHCI_RESPONSE_0);
+ cmd->response[0] = sdhci_read32(&host->sdhci, SDHCI_RESPONSE_0);
}
}
@@ -218,11 +222,11 @@ static int tegra_sdmmc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
uint64_t start = get_time_ns();
while (1) {
- val = readl(host->regs + SDHCI_INT_STATUS);
+ val = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
if (val & TEGRA_SDMMC_INTERRUPT_STATUS_ERR_INTERRUPT) {
/* Error Interrupt */
- writel(val, host->regs + SDHCI_INT_STATUS);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, val);
dev_err(mci->hw_dev,
"error during transfer: 0x%08x\n", val);
return -EIO;
@@ -234,27 +238,26 @@ static int tegra_sdmmc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
u32 address = readl(host->regs +
SDHCI_DMA_ADDRESS);
- writel(IRQSTAT_DINT,
- host->regs + SDHCI_INT_STATUS);
- writel(address, host->regs + SDHCI_DMA_ADDRESS);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, IRQSTAT_DINT);
+ sdhci_write32(&host->sdhci, SDHCI_DMA_ADDRESS, address);
} else if (val & IRQSTAT_TC) {
/* Transfer Complete */;
break;
} else if (is_timeout(start, 2 * SECOND)) {
- writel(val, host->regs + SDHCI_INT_STATUS);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, val);
dev_err(mci->hw_dev, "MMC Timeout\n"
" Interrupt status 0x%08x\n"
" Interrupt status enable 0x%08x\n"
" Interrupt signal enable 0x%08x\n"
" Present status 0x%08x\n",
val,
- readl(host->regs + SDHCI_INT_ENABLE),
- readl(host->regs + SDHCI_SIGNAL_ENABLE),
- readl(host->regs + SDHCI_PRESENT_STATE));
+ sdhci_read32(&host->sdhci, SDHCI_INT_ENABLE),
+ sdhci_read32(&host->sdhci, SDHCI_SIGNAL_ENABLE),
+ sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE));
return -ETIMEDOUT;
}
}
- writel(val, host->regs + SDHCI_INT_STATUS);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, val);
if (data->flags & MMC_DATA_WRITE)
dma_sync_single_for_cpu((unsigned long)data->src,
@@ -277,25 +280,25 @@ static void tegra_sdmmc_set_clock(struct tegra_sdmmc_host *host, u32 clock)
}
/* clear clock related bits */
- val = readl(host->regs + TEGRA_SDMMC_CLK_CNTL);
+ val = sdhci_read32(&host->sdhci, TEGRA_SDMMC_CLK_CNTL);
val &= 0xffff0000;
- writel(val, host->regs + TEGRA_SDMMC_CLK_CNTL);
+ sdhci_write32(&host->sdhci, TEGRA_SDMMC_CLK_CNTL, val);
/* set new frequency */
val |= prediv << 8;
val |= TEGRA_SDMMC_CLK_CNTL_INTERNAL_CLOCK_EN;
- writel(val, host->regs + TEGRA_SDMMC_CLK_CNTL);
+ sdhci_write32(&host->sdhci, TEGRA_SDMMC_CLK_CNTL, val);
clk_set_rate(host->clk, adjusted_clock);
/* wait for controller to settle */
wait_on_timeout(10 * MSECOND,
- !(readl(host->regs + TEGRA_SDMMC_CLK_CNTL) &
+ !(sdhci_read32(&host->sdhci, TEGRA_SDMMC_CLK_CNTL) &
TEGRA_SDMMC_CLK_INTERNAL_CLOCK_STABLE));
/* enable card clock */
val |= TEGRA_SDMMC_CLK_CNTL_SD_CLOCK_EN;
- writel(val, host->regs + TEGRA_SDMMC_CLK_CNTL);
+ sdhci_write32(&host->sdhci, TEGRA_SDMMC_CLK_CNTL, val);
}
static void tegra_sdmmc_set_ios(struct mci_host *mci, struct mci_ios *ios)
@@ -308,7 +311,7 @@ static void tegra_sdmmc_set_ios(struct mci_host *mci, struct mci_ios *ios)
tegra_sdmmc_set_clock(host, ios->clock);
/* set bus width */
- val = readl(host->regs + TEGRA_SDMMC_PWR_CNTL);
+ val = sdhci_read32(&host->sdhci, TEGRA_SDMMC_PWR_CNTL);
val &= ~(0x21);
if (ios->bus_width == MMC_BUS_WIDTH_8)
@@ -316,7 +319,7 @@ static void tegra_sdmmc_set_ios(struct mci_host *mci, struct mci_ios *ios)
else if (ios->bus_width == MMC_BUS_WIDTH_4)
val |= (1 << 1);
- writel(val, host->regs + TEGRA_SDMMC_PWR_CNTL);
+ sdhci_write32(&host->sdhci, TEGRA_SDMMC_PWR_CNTL, val);
}
static int tegra_sdmmc_init(struct mci_host *mci, struct device_d *dev)
@@ -327,8 +330,8 @@ static int tegra_sdmmc_init(struct mci_host *mci, struct device_d *dev)
int ret;
/* reset controller */
- writel(TEGRA_SDMMC_CLK_CNTL_SW_RESET_FOR_ALL,
- regs + TEGRA_SDMMC_CLK_CNTL);
+ sdhci_write32(&host->sdhci, TEGRA_SDMMC_CLK_CNTL,
+ TEGRA_SDMMC_CLK_CNTL_SW_RESET_FOR_ALL);
ret = wait_on_timeout(100 * MSECOND,
!(readl(regs + TEGRA_SDMMC_CLK_CNTL) &
@@ -342,7 +345,7 @@ static int tegra_sdmmc_init(struct mci_host *mci, struct device_d *dev)
val = readl(regs + TEGRA_SDMMC_PWR_CNTL);
val &= ~(0xff << 8);
val |= TEGRA_SDMMC_PWR_CNTL_33_V | TEGRA_SDMMC_PWR_CNTL_SD_BUS;
- writel(val, regs + TEGRA_SDMMC_PWR_CNTL);
+ sdhci_write32(&host->sdhci, TEGRA_SDMMC_PWR_CNTL, val);
/* sdmmc1 and sdmmc3 on T30 need a bit of padctrl init */
if (of_device_is_compatible(mci->hw_dev->device_node,
@@ -351,21 +354,21 @@ static int tegra_sdmmc_init(struct mci_host *mci, struct device_d *dev)
val = readl(regs + TEGRA_SDMMC_SDMEMCOMPPADCTRL);
val &= 0xfffffff0;
val |= 0x7 << TEGRA_SDMMC_SDMEMCOMPPADCTRL_VREF_SEL_SHIFT;
- writel(val, regs + TEGRA_SDMMC_SDMEMCOMPPADCTRL);
+ sdhci_write32(&host->sdhci, TEGRA_SDMMC_SDMEMCOMPPADCTRL, val);
val = readl(regs + TEGRA_SDMMC_AUTO_CAL_CONFIG);
val &= 0xffff0000;
val |= (0x62 << TEGRA_SDMMC_AUTO_CAL_CONFIG_PU_OFFSET_SHIFT) |
(0x70 << TEGRA_SDMMC_AUTO_CAL_CONFIG_PD_OFFSET_SHIFT) |
TEGRA_SDMMC_AUTO_CAL_CONFIG_ENABLE;
- writel(val, regs + TEGRA_SDMMC_AUTO_CAL_CONFIG);
+ sdhci_write32(&host->sdhci, TEGRA_SDMMC_AUTO_CAL_CONFIG, val);
}
/* setup signaling */
- writel(0xffffffff, regs + TEGRA_SDMMC_INT_STAT_EN);
- writel(0xffffffff, regs + TEGRA_SDMMC_INT_SIG_EN);
+ sdhci_write32(&host->sdhci, TEGRA_SDMMC_INT_STAT_EN, 0xffffffff);
+ sdhci_write32(&host->sdhci, TEGRA_SDMMC_INT_SIG_EN, 0xffffffff);
- writel(0xe << 16, regs + TEGRA_SDMMC_CLK_CNTL);
+ sdhci_write32(&host->sdhci, TEGRA_SDMMC_CLK_CNTL, 0xe << 16);
val = readl(regs + TEGRA_SDMMC_INT_STAT_EN);
val &= ~(0xffff);
@@ -374,12 +377,12 @@ static int tegra_sdmmc_init(struct mci_host *mci, struct device_d *dev)
TEGRA_SDMMC_INT_STAT_EN_DMA_INTERRUPT |
TEGRA_SDMMC_INT_STAT_EN_BUFFER_WRITE_READY |
TEGRA_SDMMC_INT_STAT_EN_BUFFER_READ_READY);
- writel(val, regs + TEGRA_SDMMC_INT_STAT_EN);
+ sdhci_write32(&host->sdhci, TEGRA_SDMMC_INT_STAT_EN, val);
val = readl(regs + TEGRA_SDMMC_INT_SIG_EN);
val &= ~(0xffff);
val |= TEGRA_SDMMC_INT_SIG_EN_XFER_COMPLETE;
- writel(val, regs + TEGRA_SDMMC_INT_SIG_EN);
+ sdhci_write32(&host->sdhci, TEGRA_SDMMC_INT_SIG_EN, val);
tegra_sdmmc_set_clock(host, 400000);
@@ -398,7 +401,7 @@ static int tegra_sdmmc_card_present(struct mci_host *mci)
return gpio_get_value(host->gpio_cd) ? 0 : 1;
}
- return !(readl(host->regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL);
+ return !(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL);
}
static int tegra_sdmmc_detect(struct device_d *dev)
@@ -442,6 +445,9 @@ static int tegra_sdmmc_probe(struct device_d *dev)
}
host->regs = IOMEM(iores->start);
+ host->sdhci.read32 = tegra_sdmmc_read32;
+ host->sdhci.write32 = tegra_sdmmc_write32;
+
mci->hw_dev = dev;
mci->f_max = 48000000;
mci->f_min = 375000;
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 06/21] mci: dove: use sdhci helpers
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (4 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 05/21] mci: tegra: " Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 07/21] mci: imx-esdhc: Use 16bit register definitions Sascha Hauer
` (14 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
To use the sdhci helpers we have to switch to the sdhci accessors.
Also use sdhci_read_response().
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/Kconfig | 1 +
drivers/mci/dove-sdhci.c | 116 +++++++++++++++++++++------------------
2 files changed, 63 insertions(+), 54 deletions(-)
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 7c5310deaf..526600556b 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -77,6 +77,7 @@ config MCI_BCM283X_SDHOST
config MCI_DOVE
bool "Marvell Dove SDHCI"
depends on ARCH_DOVE
+ select MCI_SDHCI
help
Enable this entry to add support to read and write SD cards on a
Marvell Dove SoC based system.
diff --git a/drivers/mci/dove-sdhci.c b/drivers/mci/dove-sdhci.c
index caee4107eb..7818bef0d9 100644
--- a/drivers/mci/dove-sdhci.c
+++ b/drivers/mci/dove-sdhci.c
@@ -33,38 +33,51 @@
struct dove_sdhci {
struct mci_host mci;
void __iomem *base;
+ struct sdhci sdhci;
};
#define priv_from_mci_host(h) \
container_of(h, struct dove_sdhci, mci);
-static inline void dove_sdhci_writel(struct dove_sdhci *p, int reg, u32 val)
+static void dove_sdhci_writel(struct sdhci *sdhci, int reg, u32 val)
{
+ struct dove_sdhci *p = container_of(sdhci, struct dove_sdhci, sdhci);
+
writel(val, p->base + reg);
}
-static inline void dove_sdhci_writew(struct dove_sdhci *p, int reg, u16 val)
+static void dove_sdhci_writew(struct sdhci *sdhci, int reg, u16 val)
{
+ struct dove_sdhci *p = container_of(sdhci, struct dove_sdhci, sdhci);
+
writew(val, p->base + reg);
}
-static inline void dove_sdhci_writeb(struct dove_sdhci *p, int reg, u8 val)
+static void dove_sdhci_writeb(struct sdhci *sdhci, int reg, u8 val)
{
+ struct dove_sdhci *p = container_of(sdhci, struct dove_sdhci, sdhci);
+
writeb(val, p->base + reg);
}
-static inline u32 dove_sdhci_readl(struct dove_sdhci *p, int reg)
+static u32 dove_sdhci_readl(struct sdhci *sdhci, int reg)
{
+ struct dove_sdhci *p = container_of(sdhci, struct dove_sdhci, sdhci);
+
return readl(p->base + reg);
}
-static inline u16 dove_sdhci_readw(struct dove_sdhci *p, int reg)
+static u16 dove_sdhci_readw(struct sdhci *sdhci, int reg)
{
+ struct dove_sdhci *p = container_of(sdhci, struct dove_sdhci, sdhci);
+
return readw(p->base + reg);
}
-static inline u8 dove_sdhci_readb(struct dove_sdhci *p, int reg)
+static u8 dove_sdhci_readb(struct sdhci *sdhci, int reg)
{
+ struct dove_sdhci *p = container_of(sdhci, struct dove_sdhci, sdhci);
+
return readb(p->base + reg);
}
@@ -75,7 +88,7 @@ static int dove_sdhci_wait_for_done(struct dove_sdhci *host, u16 mask)
start = get_time_ns();
while (1) {
- status = dove_sdhci_readw(host, SDHCI_INT_NORMAL_STATUS);
+ status = sdhci_read16(&host->sdhci, SDHCI_INT_NORMAL_STATUS);
if (status & SDHCI_INT_ERROR)
return -EPERM;
/* this special quirk is necessary, as the dma
@@ -83,8 +96,8 @@ static int dove_sdhci_wait_for_done(struct dove_sdhci *host, u16 mask)
* restart after acknowledging it this way.
*/
if (status & SDHCI_INT_DMA) {
- u32 addr = dove_sdhci_readl(host, SDHCI_DMA_ADDRESS);
- dove_sdhci_writel(host, SDHCI_DMA_ADDRESS, addr);
+ u32 addr = sdhci_read32(&host->sdhci, SDHCI_DMA_ADDRESS);
+ sdhci_write32(&host->sdhci, SDHCI_DMA_ADDRESS, addr);
}
if (status & mask)
break;
@@ -105,7 +118,7 @@ static int dove_sdhci_mci_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
unsigned int num_bytes = data->blocks * data->blocksize;
struct dove_sdhci *host = priv_from_mci_host(mci);
- dove_sdhci_writel(host, SDHCI_INT_STATUS, ~0);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, ~0);
/* Do not wait for CMD_INHIBIT_DAT on stop commands */
if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
@@ -116,7 +129,7 @@ static int dove_sdhci_mci_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
/* Wait for bus idle */
start = get_time_ns();
while (1) {
- if (!(dove_sdhci_readw(host, SDHCI_PRESENT_STATE) & val))
+ if (!(sdhci_read16(&host->sdhci, SDHCI_PRESENT_STATE) & val))
break;
if (is_timeout(start, 10 * MSECOND)) {
dev_err(host->mci.hw_dev, "SDHCI timeout while waiting for idle\n");
@@ -127,13 +140,13 @@ static int dove_sdhci_mci_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
/* setup transfer data */
if (data) {
if (data->flags & MMC_DATA_READ)
- dove_sdhci_writel(host, SDHCI_DMA_ADDRESS, (u32)data->dest);
+ sdhci_write32(&host->sdhci, SDHCI_DMA_ADDRESS, (u32)data->dest);
else
- dove_sdhci_writel(host, SDHCI_DMA_ADDRESS, (u32)data->src);
- dove_sdhci_writew(host, SDHCI_BLOCK_SIZE, SDHCI_DMA_BOUNDARY_512K |
+ sdhci_write32(&host->sdhci, SDHCI_DMA_ADDRESS, (u32)data->src);
+ sdhci_write16(&host->sdhci, SDHCI_BLOCK_SIZE, SDHCI_DMA_BOUNDARY_512K |
SDHCI_TRANSFER_BLOCK_SIZE(data->blocksize));
- dove_sdhci_writew(host, SDHCI_BLOCK_COUNT, data->blocks);
- dove_sdhci_writeb(host, SDHCI_TIMEOUT_CONTROL, 0xe);
+ sdhci_write16(&host->sdhci, SDHCI_BLOCK_COUNT, data->blocks);
+ sdhci_write8(&host->sdhci, SDHCI_TIMEOUT_CONTROL, 0xe);
if (data->flags & MMC_DATA_WRITE)
@@ -153,9 +166,9 @@ static int dove_sdhci_mci_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
if (data->flags & MMC_DATA_READ)
val |= SDHCI_DATA_TO_HOST;
}
- dove_sdhci_writew(host, SDHCI_TRANSFER_MODE, val);
+ sdhci_write16(&host->sdhci, SDHCI_TRANSFER_MODE, val);
- dove_sdhci_writel(host, SDHCI_ARGUMENT, cmd->cmdarg);
+ sdhci_write32(&host->sdhci, SDHCI_ARGUMENT, cmd->cmdarg);
if (!(cmd->resp_type & MMC_RSP_PRESENT))
val = SDHCI_RESP_NONE;
@@ -174,31 +187,20 @@ static int dove_sdhci_mci_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
val |= SDHCI_DATA_PRESENT;
val |= SDHCI_CMD_INDEX(cmd->cmdidx);
- dove_sdhci_writew(host, SDHCI_COMMAND, val);
+ sdhci_write16(&host->sdhci, SDHCI_COMMAND, val);
ret = dove_sdhci_wait_for_done(host, SDHCI_INT_CMD_COMPLETE);
if (ret) {
dev_err(host->mci.hw_dev, "error on command %d\n", cmd->cmdidx);
dev_err(host->mci.hw_dev, "state = %04x %04x, interrupt = %04x %04x\n",
- dove_sdhci_readw(host, SDHCI_PRESENT_STATE),
- dove_sdhci_readw(host, SDHCI_PRESENT_STATE1),
- dove_sdhci_readw(host, SDHCI_INT_NORMAL_STATUS),
- dove_sdhci_readw(host, SDHCI_INT_ERROR_STATUS));
+ sdhci_read16(&host->sdhci, SDHCI_PRESENT_STATE),
+ sdhci_read16(&host->sdhci, SDHCI_PRESENT_STATE1),
+ sdhci_read16(&host->sdhci, SDHCI_INT_NORMAL_STATUS),
+ sdhci_read16(&host->sdhci, SDHCI_INT_ERROR_STATUS));
goto cmd_error;
}
- /* CRC is stripped so we need to do some shifting. */
- if (cmd->resp_type & MMC_RSP_136) {
- int i;
- for (i = 0; i < 4; i++) {
- cmd->response[i] = dove_sdhci_readl(host,
- SDHCI_RESPONSE_0 + 4*(3-i)) << 8;
- if (i != 3)
- cmd->response[i] |= dove_sdhci_readb(host,
- SDHCI_RESPONSE_0 + 4*(3-i) - 1);
- }
- } else
- cmd->response[0] = dove_sdhci_readl(host, SDHCI_RESPONSE_0);
+ sdhci_read_response(&host->sdhci, cmd);
if (data->flags & MMC_DATA_WRITE)
dma_sync_single_for_cpu((unsigned long)data->src,
@@ -213,16 +215,16 @@ static int dove_sdhci_mci_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
dev_err(host->mci.hw_dev, "error while transfering data for command %d\n",
cmd->cmdidx);
dev_err(host->mci.hw_dev, "state = %04x %04x, interrupt = %04x %04x\n",
- dove_sdhci_readw(host, SDHCI_PRESENT_STATE),
- dove_sdhci_readw(host, SDHCI_PRESENT_STATE1),
- dove_sdhci_readw(host, SDHCI_INT_NORMAL_STATUS),
- dove_sdhci_readw(host, SDHCI_INT_ERROR_STATUS));
+ sdhci_read16(&host->sdhci, SDHCI_PRESENT_STATE),
+ sdhci_read16(&host->sdhci, SDHCI_PRESENT_STATE1),
+ sdhci_read16(&host->sdhci, SDHCI_INT_NORMAL_STATUS),
+ sdhci_read16(&host->sdhci, SDHCI_INT_ERROR_STATUS));
goto cmd_error;
}
}
cmd_error:
- dove_sdhci_writel(host, SDHCI_INT_STATUS, ~0);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, ~0);
return ret;
}
@@ -252,11 +254,11 @@ static void dove_sdhci_mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
/* enable bus power */
val = SDHCI_BUS_VOLTAGE_330;
- dove_sdhci_writeb(host, SDHCI_POWER_CONTROL, val | SDHCI_BUS_POWER_EN);
+ sdhci_write8(&host->sdhci, SDHCI_POWER_CONTROL, val | SDHCI_BUS_POWER_EN);
udelay(400);
/* set bus width */
- val = dove_sdhci_readb(host, SDHCI_HOST_CONTROL) &
+ val = sdhci_read8(&host->sdhci, SDHCI_HOST_CONTROL) &
~(SDHCI_DATA_WIDTH_4BIT | SDHCI_DATA_WIDTH_8BIT);
switch (ios->bus_width) {
case MMC_BUS_WIDTH_8:
@@ -272,17 +274,17 @@ static void dove_sdhci_mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
else
val &= ~SDHCI_HIGHSPEED_EN;
- dove_sdhci_writeb(host, SDHCI_HOST_CONTROL, val);
+ sdhci_write8(&host->sdhci, SDHCI_HOST_CONTROL, val);
/* set bus clock */
- dove_sdhci_writew(host, SDHCI_CLOCK_CONTROL, 0);
+ sdhci_write16(&host->sdhci, SDHCI_CLOCK_CONTROL, 0);
val = dove_sdhci_get_clock_divider(host, ios->clock);
val = SDHCI_INTCLOCK_EN | SDHCI_FREQ_SEL(val);
- dove_sdhci_writew(host, SDHCI_CLOCK_CONTROL, val);
+ sdhci_write16(&host->sdhci, SDHCI_CLOCK_CONTROL, val);
/* wait for internal clock stable */
start = get_time_ns();
- while (!(dove_sdhci_readw(host, SDHCI_CLOCK_CONTROL) &
+ while (!(sdhci_read16(&host->sdhci, SDHCI_CLOCK_CONTROL) &
SDHCI_INTCLOCK_STABLE)) {
if (is_timeout(start, 20 * MSECOND)) {
dev_err(host->mci.hw_dev, "SDHCI clock stable timeout\n");
@@ -291,7 +293,7 @@ static void dove_sdhci_mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
}
/* enable bus clock */
- dove_sdhci_writew(host, SDHCI_CLOCK_CONTROL, val | SDHCI_SDCLOCK_EN);
+ sdhci_write16(&host->sdhci, SDHCI_CLOCK_CONTROL, val | SDHCI_SDCLOCK_EN);
}
static int dove_sdhci_mci_init(struct mci_host *mci, struct device_d *dev)
@@ -300,12 +302,12 @@ static int dove_sdhci_mci_init(struct mci_host *mci, struct device_d *dev)
struct dove_sdhci *host = priv_from_mci_host(mci);
/* reset sdhci controller */
- dove_sdhci_writeb(host, SDHCI_SOFTWARE_RESET, SDHCI_RESET_ALL);
+ sdhci_write8(&host->sdhci, SDHCI_SOFTWARE_RESET, SDHCI_RESET_ALL);
/* wait for reset completion */
start = get_time_ns();
while (1) {
- if ((dove_sdhci_readb(host, SDHCI_SOFTWARE_RESET) &
+ if ((sdhci_read8(&host->sdhci, SDHCI_SOFTWARE_RESET) &
SDHCI_RESET_ALL) == 0)
break;
if (is_timeout(start, 100 * MSECOND)) {
@@ -314,9 +316,9 @@ static int dove_sdhci_mci_init(struct mci_host *mci, struct device_d *dev)
}
}
- dove_sdhci_writel(host, SDHCI_INT_STATUS, ~0);
- dove_sdhci_writel(host, SDHCI_INT_ENABLE, ~0);
- dove_sdhci_writel(host, SDHCI_SIGNAL_ENABLE, ~0);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, ~0);
+ sdhci_write32(&host->sdhci, SDHCI_INT_ENABLE, ~0);
+ sdhci_write32(&host->sdhci, SDHCI_SIGNAL_ENABLE, ~0);
return 0;
}
@@ -325,8 +327,8 @@ static void dove_sdhci_set_mci_caps(struct dove_sdhci *host)
{
u16 caps[2];
- caps[0] = dove_sdhci_readw(host, SDHCI_CAPABILITIES);
- caps[1] = dove_sdhci_readw(host, SDHCI_CAPABILITIES_1);
+ caps[0] = sdhci_read16(&host->sdhci, SDHCI_CAPABILITIES);
+ caps[1] = sdhci_read16(&host->sdhci, SDHCI_CAPABILITIES_1);
if (caps[1] & SDHCI_HOSTCAP_VOLTAGE_180)
host->mci.voltages |= MMC_VDD_165_195;
@@ -368,6 +370,12 @@ static int dove_sdhci_probe(struct device_d *dev)
host->mci.init = dove_sdhci_mci_init;
host->mci.f_max = 50000000;
host->mci.f_min = host->mci.f_max / 256;
+ host->sdhci.read32 = dove_sdhci_readl;
+ host->sdhci.read16 = dove_sdhci_readw;
+ host->sdhci.read8 = dove_sdhci_readb;
+ host->sdhci.write32 = dove_sdhci_writel;
+ host->sdhci.write16 = dove_sdhci_writew;
+ host->sdhci.write8 = dove_sdhci_writeb;
dev->priv = host;
dev->detect = dove_sdhci_detect;
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 07/21] mci: imx-esdhc: Use 16bit register definitions
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (5 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 06/21] mci: dove: " Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 08/21] mci: mci-bcm2835: " Sascha Hauer
` (13 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
We have some register defines in a 16bit access version and a 32bit
access version. Use the former to get rid of the latter later.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/imx-esdhc.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 7ae4fb4fd8..11ece677d3 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -100,8 +100,6 @@ struct fsl_esdhc_host {
#define to_fsl_esdhc(mci) container_of(mci, struct fsl_esdhc_host, mci)
-#define SDHCI_CMD_ABORTCMD (0xC0 << 16)
-
static inline int esdhc_is_usdhc(struct fsl_esdhc_host *data)
{
return !!(data->socdata->flags & ESDHC_FLAG_USDHC);
@@ -168,9 +166,10 @@ static u32 esdhc_xfertyp(struct fsl_esdhc_host *host,
struct mci_cmd *cmd, struct mci_data *data)
{
u32 xfertyp = 0;
+ u32 command = 0;
if (data) {
- xfertyp |= COMMAND_DPSEL;
+ command |= SDHCI_DATA_PRESENT;
if (!IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO))
xfertyp |= TRANSFER_MODE_DMAEN;
@@ -185,20 +184,22 @@ static u32 esdhc_xfertyp(struct fsl_esdhc_host *host,
}
if (cmd->resp_type & MMC_RSP_CRC)
- xfertyp |= COMMAND_CCCEN;
+ command |= SDHCI_CMD_CRC_CHECK_EN;
if (cmd->resp_type & MMC_RSP_OPCODE)
- xfertyp |= COMMAND_CICEN;
+ command |= SDHCI_CMD_INDEX_CHECK_EN;
if (cmd->resp_type & MMC_RSP_136)
- xfertyp |= COMMAND_RSPTYP_136;
+ command |= SDHCI_RESP_TYPE_136;
else if (cmd->resp_type & MMC_RSP_BUSY)
- xfertyp |= COMMAND_RSPTYP_48_BUSY;
+ command |= SDHCI_RESP_TYPE_48_BUSY;
else if (cmd->resp_type & MMC_RSP_PRESENT)
- xfertyp |= COMMAND_RSPTYP_48;
+ command |= SDHCI_RESP_TYPE_48;
if ((host->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) &&
(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION))
- xfertyp |= SDHCI_CMD_ABORTCMD;
+ command |= SDHCI_COMMAND_CMDTYP_ABORT;
+
+ command |= SDHCI_CMD_INDEX(cmd->cmdidx);
- return COMMAND_CMD(cmd->cmdidx) | xfertyp;
+ return command << 16 | xfertyp;
}
/*
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 08/21] mci: mci-bcm2835: Use 16bit register definitions
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (6 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 07/21] mci: imx-esdhc: Use 16bit register definitions Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 09/21] mci: tegra: " Sascha Hauer
` (12 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
We have some register defines in a 16bit access version and a 32bit
access version. Use the former to get rid of the latter later.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/mci-bcm2835.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c
index 7037cbf7b8..d154dfa46d 100644
--- a/drivers/mci/mci-bcm2835.c
+++ b/drivers/mci/mci-bcm2835.c
@@ -203,30 +203,31 @@ static void bcm2835_mci_reset_emmc(struct bcm2835_mci_host *host, u32 reset,
*/
static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
struct mci_data *data) {
- u32 command, block_data = 0, ret = 0;
+ u32 command, block_data = 0, ret = 0, transfer_mode = 0;
u32 wait_inhibit_mask = PRSSTAT_CICHB | PRSSTAT_CIDHB;
struct bcm2835_mci_host *host = to_bcm2835_host(mci);
- command = COMMAND_CMD(cmd->cmdidx);
+ command = SDHCI_CMD_INDEX(cmd->cmdidx);
if (cmd->resp_type != MMC_RSP_NONE) {
if (cmd->resp_type & MMC_RSP_136)
- command |= COMMAND_RSPTYP_136;
+ command |= SDHCI_RESP_TYPE_136;
else if (cmd->resp_type & MMC_RSP_BUSY)
- command |= COMMAND_RSPTYP_48_BUSY;
+ command |= SDHCI_RESP_TYPE_48_BUSY;
else
- command |= COMMAND_RSPTYP_48;
+ command |= SDHCI_RESP_TYPE_48;
if (cmd->resp_type & MMC_RSP_CRC)
- command |= COMMAND_CCCEN;
+ command |= SDHCI_CMD_CRC_CHECK_EN;
}
if (data != NULL) {
- command |= COMMAND_DPSEL | TRANSFER_MODE_BCEN;
+ command |= SDHCI_DATA_PRESENT;
+ transfer_mode |= TRANSFER_MODE_BCEN;
if (data->blocks > 1)
- command |= TRANSFER_MODE_MSBSEL;
+ transfer_mode |= TRANSFER_MODE_MSBSEL;
if (data->flags & MMC_DATA_READ)
- command |= TRANSFER_MODE_DTDSEL;
+ transfer_mode |= TRANSFER_MODE_DTDSEL;
block_data = (data->blocks << BLOCK_SHIFT);
block_data |= data->blocksize;
@@ -247,7 +248,8 @@ static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
sdhci_write32(&host->sdhci, SDHCI_BLOCK_SIZE__BLOCK_COUNT, block_data);
sdhci_write32(&host->sdhci, SDHCI_ARGUMENT, cmd->cmdarg);
- sdhci_write32(&host->sdhci, SDHCI_TRANSFER_MODE__COMMAND, command);
+ sdhci_write32(&host->sdhci, SDHCI_TRANSFER_MODE__COMMAND,
+ command << 16 | transfer_mode);
ret = bcm2835_mci_wait_command_done(host);
if (ret) {
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 09/21] mci: tegra: Use 16bit register definitions
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (7 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 08/21] mci: mci-bcm2835: " Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 10/21] mci: imx-esdhc-pbl: " Sascha Hauer
` (11 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
We have some register defines in a 16bit access version and a 32bit
access version. Use the former to get rid of the latter later.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/tegra-sdmmc.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/mci/tegra-sdmmc.c b/drivers/mci/tegra-sdmmc.c
index 7618d831b1..79c76bbb0f 100644
--- a/drivers/mci/tegra-sdmmc.c
+++ b/drivers/mci/tegra-sdmmc.c
@@ -116,7 +116,7 @@ static int tegra_sdmmc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
{
struct tegra_sdmmc_host *host = to_tegra_sdmmc_host(mci);
unsigned int num_bytes = 0;
- u32 val = 0;
+ u32 val = 0, command = 0;
int ret;
ret = tegra_sdmmc_wait_inhibit(host, cmd, data, 10);
@@ -157,24 +157,26 @@ static int tegra_sdmmc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
}
if (!(cmd->resp_type & MMC_RSP_PRESENT))
- val |= COMMAND_RSPTYP_NONE;
+ command |= SDHCI_RESP_NONE;
else if (cmd->resp_type & MMC_RSP_136)
- val |= COMMAND_RSPTYP_136;
+ command |= SDHCI_RESP_TYPE_136;
else if (cmd->resp_type & MMC_RSP_BUSY)
- val |= COMMAND_RSPTYP_48_BUSY;
+ command |= SDHCI_RESP_TYPE_48_BUSY;
else
- val |= COMMAND_RSPTYP_48;
+ command |= SDHCI_RESP_TYPE_48;
if (cmd->resp_type & MMC_RSP_CRC)
- val |= COMMAND_CCCEN;
+ command |= SDHCI_CMD_CRC_CHECK_EN;
if (cmd->resp_type & MMC_RSP_OPCODE)
- val |= COMMAND_CICEN;
+ command |= SDHCI_CMD_INDEX_CHECK_EN;
if (data)
- val |= COMMAND_DPSEL;
+ command |= SDHCI_DATA_PRESENT;
+
+ command |= SDHCI_CMD_INDEX(cmd->cmdidx);
sdhci_write32(&host->sdhci, SDHCI_TRANSFER_MODE__COMMAND,
- COMMAND_CMD(cmd->cmdidx) | val);
+ command << 16 | val);
ret = wait_on_timeout(100 * MSECOND,
(val = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS))
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 10/21] mci: imx-esdhc-pbl: Use 16bit register definitions
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (8 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 09/21] mci: tegra: " Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 11/21] mci: sdhci: remove 32bit register defines Sascha Hauer
` (10 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
We have some register defines in a 16bit access version and a 32bit
access version. Use the former to get rid of the latter later.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/imx-esdhc-pbl.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c
index f93ddfa0d5..0d15668fbe 100644
--- a/drivers/mci/imx-esdhc-pbl.c
+++ b/drivers/mci/imx-esdhc-pbl.c
@@ -63,23 +63,28 @@ static void __udelay(int us)
static u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
{
u32 xfertyp = 0;
+ u32 command = 0;
- if (data)
- xfertyp |= COMMAND_DPSEL | TRANSFER_MODE_MSBSEL |
- TRANSFER_MODE_BCEN |TRANSFER_MODE_DTDSEL;
+ if (data) {
+ command |= SDHCI_DATA_PRESENT;
+ xfertyp |= TRANSFER_MODE_MSBSEL | TRANSFER_MODE_BCEN |
+ TRANSFER_MODE_DTDSEL;
+ }
if (cmd->resp_type & MMC_RSP_CRC)
- xfertyp |= COMMAND_CCCEN;
+ command |= SDHCI_CMD_CRC_CHECK_EN;
if (cmd->resp_type & MMC_RSP_OPCODE)
- xfertyp |= COMMAND_CICEN;
+ xfertyp |= SDHCI_CMD_INDEX_CHECK_EN;
if (cmd->resp_type & MMC_RSP_136)
- xfertyp |= COMMAND_RSPTYP_136;
+ command |= SDHCI_RESP_TYPE_136;
else if (cmd->resp_type & MMC_RSP_BUSY)
- xfertyp |= COMMAND_RSPTYP_48_BUSY;
+ command |= SDHCI_RESP_TYPE_48_BUSY;
else if (cmd->resp_type & MMC_RSP_PRESENT)
- xfertyp |= COMMAND_RSPTYP_48;
+ command |= SDHCI_RESP_TYPE_48;
+
+ command |= SDHCI_CMD_INDEX(cmd->cmdidx);
- return COMMAND_CMD(cmd->cmdidx) | xfertyp;
+ return command << 16 | xfertyp;
}
static int esdhc_do_data(struct esdhc *esdhc, struct mci_data *data)
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 11/21] mci: sdhci: remove 32bit register defines
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (9 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 10/21] mci: imx-esdhc-pbl: " Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 12/21] mci: sdhci: remove duplicate transfer mode " Sascha Hauer
` (9 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
The 32bit register defines are no longer used. Remove them.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/sdhci.h | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/drivers/mci/sdhci.h b/drivers/mci/sdhci.h
index bd98c96060..c1e4f06606 100644
--- a/drivers/mci/sdhci.h
+++ b/drivers/mci/sdhci.h
@@ -82,18 +82,6 @@
#define SDHCI_SPEC_200_MAX_CLK_DIVIDER 256
#define SDHCI_MMC_BOOT 0xC4
-#define COMMAND_CMD(x) ((x & 0x3f) << 24)
-#define COMMAND_CMDTYP_NORMAL 0x0
-#define COMMAND_CMDTYP_SUSPEND 0x00400000
-#define COMMAND_CMDTYP_RESUME 0x00800000
-#define COMMAND_CMDTYP_ABORT 0x00c00000
-#define COMMAND_DPSEL 0x00200000
-#define COMMAND_CICEN 0x00100000
-#define COMMAND_CCCEN 0x00080000
-#define COMMAND_RSPTYP_NONE 0
-#define COMMAND_RSPTYP_136 0x00010000
-#define COMMAND_RSPTYP_48 0x00020000
-#define COMMAND_RSPTYP_48_BUSY 0x00030000
#define TRANSFER_MODE_MSBSEL 0x00000020
#define TRANSFER_MODE_DTDSEL 0x00000010
#define TRANSFER_MODE_AC12EN 0x00000004
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 12/21] mci: sdhci: remove duplicate transfer mode register defines
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (10 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 11/21] mci: sdhci: remove 32bit register defines Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 13/21] mci: sdhci: remove duplicate register defines for interrupt bits Sascha Hauer
` (8 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
We have duplicate register bit defines for the transfer mode register.
Remove the duplicates.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/imx-esdhc-pbl.c | 4 ++--
drivers/mci/imx-esdhc.c | 8 ++++----
drivers/mci/mci-bcm2835.c | 6 +++---
drivers/mci/sdhci.h | 6 ------
drivers/mci/tegra-sdmmc.c | 6 +++---
5 files changed, 12 insertions(+), 18 deletions(-)
diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c
index 0d15668fbe..82e1d83d2a 100644
--- a/drivers/mci/imx-esdhc-pbl.c
+++ b/drivers/mci/imx-esdhc-pbl.c
@@ -67,8 +67,8 @@ static u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
if (data) {
command |= SDHCI_DATA_PRESENT;
- xfertyp |= TRANSFER_MODE_MSBSEL | TRANSFER_MODE_BCEN |
- TRANSFER_MODE_DTDSEL;
+ xfertyp |= SDHCI_MULTIPLE_BLOCKS | SDHCI_BLOCK_COUNT_EN |
+ SDHCI_DATA_TO_HOST;
}
if (cmd->resp_type & MMC_RSP_CRC)
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 11ece677d3..9f797bf7b1 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -172,15 +172,15 @@ static u32 esdhc_xfertyp(struct fsl_esdhc_host *host,
command |= SDHCI_DATA_PRESENT;
if (!IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO))
- xfertyp |= TRANSFER_MODE_DMAEN;
+ xfertyp |= SDHCI_DMA_EN;
if (data->blocks > 1) {
- xfertyp |= TRANSFER_MODE_MSBSEL;
- xfertyp |= TRANSFER_MODE_BCEN;
+ xfertyp |= SDHCI_MULTIPLE_BLOCKS;
+ xfertyp |= SDHCI_BLOCK_COUNT_EN;
}
if (data->flags & MMC_DATA_READ)
- xfertyp |= TRANSFER_MODE_DTDSEL;
+ xfertyp |= SDHCI_DATA_TO_HOST;
}
if (cmd->resp_type & MMC_RSP_CRC)
diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c
index d154dfa46d..a16d192832 100644
--- a/drivers/mci/mci-bcm2835.c
+++ b/drivers/mci/mci-bcm2835.c
@@ -221,13 +221,13 @@ static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
}
if (data != NULL) {
command |= SDHCI_DATA_PRESENT;
- transfer_mode |= TRANSFER_MODE_BCEN;
+ transfer_mode |= SDHCI_BLOCK_COUNT_EN;
if (data->blocks > 1)
- transfer_mode |= TRANSFER_MODE_MSBSEL;
+ transfer_mode |= SDHCI_MULTIPLE_BLOCKS;
if (data->flags & MMC_DATA_READ)
- transfer_mode |= TRANSFER_MODE_DTDSEL;
+ transfer_mode |= SDHCI_DATA_TO_HOST;
block_data = (data->blocks << BLOCK_SHIFT);
block_data |= data->blocksize;
diff --git a/drivers/mci/sdhci.h b/drivers/mci/sdhci.h
index c1e4f06606..9ee8d6ff02 100644
--- a/drivers/mci/sdhci.h
+++ b/drivers/mci/sdhci.h
@@ -82,12 +82,6 @@
#define SDHCI_SPEC_200_MAX_CLK_DIVIDER 256
#define SDHCI_MMC_BOOT 0xC4
-#define TRANSFER_MODE_MSBSEL 0x00000020
-#define TRANSFER_MODE_DTDSEL 0x00000010
-#define TRANSFER_MODE_AC12EN 0x00000004
-#define TRANSFER_MODE_BCEN 0x00000002
-#define TRANSFER_MODE_DMAEN 0x00000001
-
#define IRQSTAT_TE 0x04000000
#define IRQSTAT_DMAE 0x02000000
#define IRQSTAT_AC12E 0x01000000
diff --git a/drivers/mci/tegra-sdmmc.c b/drivers/mci/tegra-sdmmc.c
index 79c76bbb0f..034081ec62 100644
--- a/drivers/mci/tegra-sdmmc.c
+++ b/drivers/mci/tegra-sdmmc.c
@@ -148,12 +148,12 @@ static int tegra_sdmmc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
if (data) {
if (data->blocks > 1)
- val |= TRANSFER_MODE_MSBSEL;
+ val |= SDHCI_MULTIPLE_BLOCKS;
if (data->flags & MMC_DATA_READ)
- val |= TRANSFER_MODE_DTDSEL;
+ val |= SDHCI_DATA_TO_HOST;
- val |= TRANSFER_MODE_DMAEN | TRANSFER_MODE_BCEN;
+ val |= SDHCI_DMA_EN | SDHCI_BLOCK_COUNT_EN;
}
if (!(cmd->resp_type & MMC_RSP_PRESENT))
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 13/21] mci: sdhci: remove duplicate register defines for interrupt bits
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (11 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 12/21] mci: sdhci: remove duplicate transfer mode " Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 14/21] mci: sdhci: remove duplicate register defines for prsstat bits Sascha Hauer
` (7 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
We have duplicate bit defines for the interrupt bits. Remove the duplicates.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/imx-esdhc-pbl.c | 12 ++++-----
drivers/mci/imx-esdhc.c | 21 ++++++++--------
drivers/mci/imx-esdhc.h | 4 +--
drivers/mci/mci-bcm2835.c | 14 +++++------
drivers/mci/sdhci.h | 50 ++++++++-----------------------------
drivers/mci/tegra-sdmmc.c | 10 ++++----
6 files changed, 41 insertions(+), 70 deletions(-)
diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c
index 82e1d83d2a..91390bd3aa 100644
--- a/drivers/mci/imx-esdhc-pbl.c
+++ b/drivers/mci/imx-esdhc-pbl.c
@@ -167,7 +167,7 @@ esdhc_send_cmd(struct esdhc *esdhc, struct mci_cmd *cmd, struct mci_data *data)
/* Wait for the command to complete */
timeout = 10000;
- while (!(esdhc_read32(esdhc, SDHCI_INT_STATUS) & IRQSTAT_CC)) {
+ while (!(esdhc_read32(esdhc, SDHCI_INT_STATUS) & SDHCI_INT_CMD_COMPLETE)) {
__udelay(1);
if (!timeout--)
return -ETIMEDOUT;
@@ -179,7 +179,7 @@ esdhc_send_cmd(struct esdhc *esdhc, struct mci_cmd *cmd, struct mci_data *data)
if (irqstat & CMD_ERR)
return -EIO;
- if (irqstat & IRQSTAT_CTOE)
+ if (irqstat & SDHCI_INT_TIMEOUT)
return -ETIMEDOUT;
/* Copy the response to the response buffer */
@@ -214,10 +214,10 @@ static int esdhc_read_blocks(struct esdhc *esdhc, void *dst, size_t len)
int ret;
esdhc_write32(esdhc, SDHCI_INT_ENABLE,
- IRQSTATEN_CC | IRQSTATEN_TC | IRQSTATEN_CINT | IRQSTATEN_CTOE |
- IRQSTATEN_CCE | IRQSTATEN_CEBE | IRQSTATEN_CIE |
- IRQSTATEN_DTOE | IRQSTATEN_DCE | IRQSTATEN_DEBE |
- IRQSTATEN_DINT);
+ SDHCI_INT_CMD_COMPLETE | SDHCI_INT_XFER_COMPLETE |
+ SDHCI_INT_CARD_INT | SDHCI_INT_TIMEOUT | SDHCI_INT_CRC |
+ SDHCI_INT_END_BIT | SDHCI_INT_INDEX | SDHCI_INT_DATA_TIMEOUT |
+ SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT | SDHCI_INT_DMA);
wml = FIELD_PREP(WML_WR_BRST_LEN, 16) |
FIELD_PREP(WML_WR_WML_MASK, SECTOR_WML) |
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 9f797bf7b1..5a553eebbc 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -229,7 +229,7 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
dev_err(host->dev, "Data Read Failed\n");
return -ETIMEDOUT;
}
- while (size && (!(irqstat & IRQSTAT_TC))) {
+ while (size && (!(irqstat & SDHCI_INT_XFER_COMPLETE))) {
udelay(100); /* Wait before last byte transfer complete */
irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
databuf = sdhci_read32(&host->sdhci, SDHCI_BUFFER);
@@ -252,7 +252,7 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
dev_err(host->dev, "Data Write Failed\n");
return -ETIMEDOUT;
}
- while (size && (!(irqstat & IRQSTAT_TC))) {
+ while (size && (!(irqstat & SDHCI_INT_XFER_COMPLETE))) {
udelay(100); /* Wait before last byte transfer complete */
databuf = *((u32 *)buffer);
buffer += 4;
@@ -310,9 +310,9 @@ static int esdhc_do_data(struct mci_host *mci, struct mci_data *data)
if (irqstat & DATA_ERR)
return -EIO;
- if (irqstat & IRQSTAT_DTOE)
+ if (irqstat & SDHCI_INT_DATA_TIMEOUT)
return -ETIMEDOUT;
- } while (!(irqstat & IRQSTAT_TC) &&
+ } while (!(irqstat & SDHCI_INT_XFER_COMPLETE) &&
(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_DLA));
return 0;
@@ -382,7 +382,7 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
/* Wait for the command to complete */
ret = wait_on_timeout(100 * MSECOND,
- sdhci_read32(&host->sdhci, SDHCI_INT_STATUS) & IRQSTAT_CC);
+ sdhci_read32(&host->sdhci, SDHCI_INT_STATUS) & SDHCI_INT_CMD_COMPLETE);
if (ret) {
dev_dbg(host->dev, "timeout 1\n");
return -ETIMEDOUT;
@@ -394,7 +394,7 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
if (irqstat & CMD_ERR)
return -EIO;
- if (irqstat & IRQSTAT_CTOE)
+ if (irqstat & SDHCI_INT_TIMEOUT)
return -ETIMEDOUT;
/* Workaround for ESDHC errata ENGcm03648 / ENGcm12360 */
@@ -613,10 +613,11 @@ static int esdhc_init(struct mci_host *mci, struct device_d *dev)
/* Set the initial clock speed */
set_sysctl(mci, 400000);
- sdhci_write32(&host->sdhci, SDHCI_INT_ENABLE, IRQSTATEN_CC | IRQSTATEN_TC |
- IRQSTATEN_CINT | IRQSTATEN_CTOE | IRQSTATEN_CCE |
- IRQSTATEN_CEBE | IRQSTATEN_CIE | IRQSTATEN_DTOE |
- IRQSTATEN_DCE | IRQSTATEN_DEBE | IRQSTATEN_DINT);
+ sdhci_write32(&host->sdhci, SDHCI_INT_ENABLE, SDHCI_INT_CMD_COMPLETE |
+ SDHCI_INT_XFER_COMPLETE | SDHCI_INT_CARD_INT |
+ SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | SDHCI_INT_END_BIT |
+ SDHCI_INT_INDEX | SDHCI_INT_DATA_TIMEOUT |
+ SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT | SDHCI_INT_DMA);
/* Put the PROCTL reg back to the default */
sdhci_write32(&host->sdhci, SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
diff --git a/drivers/mci/imx-esdhc.h b/drivers/mci/imx-esdhc.h
index 2d5471969d..46f592e496 100644
--- a/drivers/mci/imx-esdhc.h
+++ b/drivers/mci/imx-esdhc.h
@@ -35,8 +35,8 @@
#define SYSCTL_HCKEN 0x00000002
#define SYSCTL_IPGEN 0x00000001
-#define CMD_ERR (IRQSTAT_CIE | IRQSTAT_CEBE | IRQSTAT_CCE)
-#define DATA_ERR (IRQSTAT_DEBE | IRQSTAT_DCE | IRQSTAT_DTOE)
+#define CMD_ERR (SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC)
+#define DATA_ERR (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT)
#define PROCTL_INIT 0x00000020
#define PROCTL_DTW_4 0x00000002
diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c
index a16d192832..cb72235807 100644
--- a/drivers/mci/mci-bcm2835.c
+++ b/drivers/mci/mci-bcm2835.c
@@ -109,18 +109,18 @@ static int bcm2835_mci_transfer_data(struct bcm2835_mci_host *host,
if (data->flags & MMC_DATA_READ) {
p = (u32 *) data->dest;
- data_ready_intr_mask = IRQSTAT_BRR;
+ data_ready_intr_mask = SDHCI_INT_DATA_AVAIL;
data_ready_status_mask = PRSSTAT_BREN;
read_write_func = &sdhci_read32_data;
} else {
p = (u32 *) data->src;
- data_ready_intr_mask = IRQSTAT_BWR;
+ data_ready_intr_mask = SDHCI_INT_SPACE_AVAIL;
data_ready_status_mask = PRSSTAT_BWEN;
read_write_func = &sdhci_write32_data;
}
do {
intr_status = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
- if (intr_status & IRQSTAT_CIE) {
+ if (intr_status & SDHCI_INT_INDEX) {
dev_err(host->hw_dev,
"Error occured while transferring data: 0x%X\n",
intr_status);
@@ -139,7 +139,7 @@ static int bcm2835_mci_transfer_data(struct bcm2835_mci_host *host,
data_size -= 4;
}
}
- } while ((intr_status & IRQSTAT_TC) == 0);
+ } while ((intr_status & SDHCI_INT_XFER_COMPLETE) == 0);
if (data_size != 0) {
if (data->flags & MMC_DATA_READ)
@@ -166,9 +166,9 @@ static u32 bcm2835_mci_wait_command_done(struct bcm2835_mci_host *host)
while (true) {
interrupt = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
- if (interrupt & IRQSTAT_CIE)
+ if (interrupt & SDHCI_INT_INDEX)
return -EPERM;
- if (interrupt & IRQSTAT_CC)
+ if (interrupt & SDHCI_INT_CMD_COMPLETE)
break;
}
return 0;
@@ -262,7 +262,7 @@ static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
if (cmd->resp_type != 0 && ret != -1) {
sdhci_read_response(&host->sdhci, cmd);
- sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, IRQSTAT_CC);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, SDHCI_INT_CMD_COMPLETE);
}
if (!ret && data)
diff --git a/drivers/mci/sdhci.h b/drivers/mci/sdhci.h
index 9ee8d6ff02..18db9a5c34 100644
--- a/drivers/mci/sdhci.h
+++ b/drivers/mci/sdhci.h
@@ -63,7 +63,17 @@
#define SDHCI_RESET_ALL BIT(0)
#define SDHCI_INT_STATUS 0x30
#define SDHCI_INT_NORMAL_STATUS 0x30
+#define SDHCI_INT_DATA_END_BIT BIT(22)
+#define SDHCI_INT_DATA_CRC BIT(21)
+#define SDHCI_INT_DATA_TIMEOUT BIT(20)
+#define SDHCI_INT_INDEX BIT(19)
+#define SDHCI_INT_END_BIT BIT(18)
+#define SDHCI_INT_CRC BIT(17)
+#define SDHCI_INT_TIMEOUT BIT(16)
#define SDHCI_INT_ERROR BIT(15)
+#define SDHCI_INT_CARD_INT BIT(8)
+#define SDHCI_INT_DATA_AVAIL BIT(5)
+#define SDHCI_INT_SPACE_AVAIL BIT(4)
#define SDHCI_INT_DMA BIT(3)
#define SDHCI_INT_XFER_COMPLETE BIT(1)
#define SDHCI_INT_CMD_COMPLETE BIT(0)
@@ -82,46 +92,6 @@
#define SDHCI_SPEC_200_MAX_CLK_DIVIDER 256
#define SDHCI_MMC_BOOT 0xC4
-#define IRQSTAT_TE 0x04000000
-#define IRQSTAT_DMAE 0x02000000
-#define IRQSTAT_AC12E 0x01000000
-#define IRQSTAT_CLE 0x00800000
-#define IRQSTAT_DEBE 0x00400000
-#define IRQSTAT_DCE 0x00200000
-#define IRQSTAT_DTOE 0x00100000
-#define IRQSTAT_CIE 0x00080000
-#define IRQSTAT_CEBE 0x00040000
-#define IRQSTAT_CCE 0x00020000
-#define IRQSTAT_CTOE 0x00010000
-#define IRQSTAT_CINT 0x00000100
-#define IRQSTAT_CRM 0x00000080
-#define IRQSTAT_CINS 0x00000040
-#define IRQSTAT_BRR 0x00000020
-#define IRQSTAT_BWR 0x00000010
-#define IRQSTAT_DINT 0x00000008
-#define IRQSTAT_BGE 0x00000004
-#define IRQSTAT_TC 0x00000002
-#define IRQSTAT_CC 0x00000001
-
-#define IRQSTATEN_DMAE 0x10000000
-#define IRQSTATEN_AC12E 0x01000000
-#define IRQSTATEN_DEBE 0x00400000
-#define IRQSTATEN_DCE 0x00200000
-#define IRQSTATEN_DTOE 0x00100000
-#define IRQSTATEN_CIE 0x00080000
-#define IRQSTATEN_CEBE 0x00040000
-#define IRQSTATEN_CCE 0x00020000
-#define IRQSTATEN_CTOE 0x00010000
-#define IRQSTATEN_CINT 0x00000100
-#define IRQSTATEN_CRM 0x00000080
-#define IRQSTATEN_CINS 0x00000040
-#define IRQSTATEN_BRR 0x00000020
-#define IRQSTATEN_BWR 0x00000010
-#define IRQSTATEN_DINT 0x00000008
-#define IRQSTATEN_BGE 0x00000004
-#define IRQSTATEN_TC 0x00000002
-#define IRQSTATEN_CC 0x00000001
-
#define PRSSTAT_DAT0 0x01000000
#define PRSSTAT_CLSL 0x00800000
#define PRSSTAT_WPSPL 0x00080000
diff --git a/drivers/mci/tegra-sdmmc.c b/drivers/mci/tegra-sdmmc.c
index 034081ec62..6cdf808f16 100644
--- a/drivers/mci/tegra-sdmmc.c
+++ b/drivers/mci/tegra-sdmmc.c
@@ -180,14 +180,14 @@ static int tegra_sdmmc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
ret = wait_on_timeout(100 * MSECOND,
(val = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS))
- & IRQSTAT_CC);
+ & SDHCI_INT_CMD_COMPLETE);
if (ret) {
sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, val);
return ret;
}
- if ((val & IRQSTAT_CC) && !data)
+ if ((val & SDHCI_INT_CMD_COMPLETE) && !data)
sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, val);
if (val & TEGRA_SDMMC_INTERRUPT_STATUS_CMD_TIMEOUT) {
@@ -232,7 +232,7 @@ static int tegra_sdmmc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
dev_err(mci->hw_dev,
"error during transfer: 0x%08x\n", val);
return -EIO;
- } else if (val & IRQSTAT_DINT) {
+ } else if (val & SDHCI_INT_DMA) {
/*
* DMA Interrupt, restart the transfer where
* it was interrupted.
@@ -240,9 +240,9 @@ static int tegra_sdmmc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
u32 address = readl(host->regs +
SDHCI_DMA_ADDRESS);
- sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, IRQSTAT_DINT);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, SDHCI_INT_DMA);
sdhci_write32(&host->sdhci, SDHCI_DMA_ADDRESS, address);
- } else if (val & IRQSTAT_TC) {
+ } else if (val & SDHCI_INT_XFER_COMPLETE) {
/* Transfer Complete */;
break;
} else if (is_timeout(start, 2 * SECOND)) {
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 14/21] mci: sdhci: remove duplicate register defines for prsstat bits
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (12 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 13/21] mci: sdhci: remove duplicate register defines for interrupt bits Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 15/21] mci: dove: Use sdhci_set_cmd_xfer_mode() Sascha Hauer
` (6 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
We have duplicate register bit defines for the prsstat register.
Remove the duplicates.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/imx-esdhc-pbl.c | 6 +++---
drivers/mci/imx-esdhc.c | 17 +++++++++++------
drivers/mci/mci-bcm2835.c | 8 ++++----
drivers/mci/sdhci.h | 16 ++++------------
drivers/mci/tegra-sdmmc.c | 2 +-
5 files changed, 23 insertions(+), 26 deletions(-)
diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c
index 91390bd3aa..5e3157e6cd 100644
--- a/drivers/mci/imx-esdhc-pbl.c
+++ b/drivers/mci/imx-esdhc-pbl.c
@@ -105,7 +105,7 @@ static int esdhc_do_data(struct esdhc *esdhc, struct mci_data *data)
int timeout = 1000000;
while (1) {
- present = esdhc_read32(esdhc, SDHCI_PRESENT_STATE) & PRSSTAT_BREN;
+ present = esdhc_read32(esdhc, SDHCI_PRESENT_STATE) & SDHCI_BUFFER_READ_ENABLE;
if (present)
break;
if (!--timeout) {
@@ -196,8 +196,8 @@ esdhc_send_cmd(struct esdhc *esdhc, struct mci_cmd *cmd, struct mci_data *data)
/* Wait for the bus to be idle */
timeout = 10000;
- while (esdhc_read32(esdhc, SDHCI_PRESENT_STATE) &
- (PRSSTAT_CICHB | PRSSTAT_CIDHB | PRSSTAT_DLA)) {
+ while (esdhc_read32(esdhc, SDHCI_PRESENT_STATE) & (SDHCI_CMD_INHIBIT_CMD |
+ SDHCI_CMD_INHIBIT_DATA | SDHCI_DATA_LINE_ACTIVE)) {
__udelay(1);
if (!timeout--)
return -ETIMEDOUT;
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 5a553eebbc..c2c9d1e24c 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -84,6 +84,9 @@
/* Enable cache snooping */
#define ESDHC_FLAG_CACHE_SNOOPING BIT(11)
+#define PRSSTAT_DAT0 0x01000000
+#define PRSSTAT_SDSTB 0x00000008
+
struct esdhc_soc_data {
u32 flags;
const char *clkidx;
@@ -223,7 +226,8 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
timeout = PIO_TIMEOUT;
size = data->blocksize;
irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
- while (!(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_BREN)
+ while (!(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) &
+ SDHCI_BUFFER_READ_ENABLE)
&& --timeout);
if (timeout <= 0) {
dev_err(host->dev, "Data Read Failed\n");
@@ -246,7 +250,8 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
timeout = PIO_TIMEOUT;
size = data->blocksize;
irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
- while (!(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_BWEN)
+ while (!(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) &
+ SDHCI_BUFFER_WRITE_ENABLE)
&& --timeout);
if (timeout <= 0) {
dev_err(host->dev, "Data Write Failed\n");
@@ -313,7 +318,7 @@ static int esdhc_do_data(struct mci_host *mci, struct mci_data *data)
if (irqstat & SDHCI_INT_DATA_TIMEOUT)
return -ETIMEDOUT;
} while (!(irqstat & SDHCI_INT_XFER_COMPLETE) &&
- (sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_DLA));
+ (sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & SDHCI_DATA_LINE_ACTIVE));
return 0;
}
@@ -429,14 +434,14 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
/* Wait for the bus to be idle */
ret = wait_on_timeout(SECOND,
!(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) &
- (PRSSTAT_CICHB | PRSSTAT_CIDHB)));
+ (SDHCI_CMD_INHIBIT_CMD | SDHCI_CMD_INHIBIT_DATA)));
if (ret) {
dev_err(host->dev, "timeout 2\n");
return -ETIMEDOUT;
}
ret = wait_on_timeout(100 * MSECOND,
- !(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_DLA));
+ !(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & SDHCI_DATA_LINE_ACTIVE));
if (ret) {
dev_err(host->dev, "timeout 3\n");
return -ETIMEDOUT;
@@ -545,7 +550,7 @@ static int esdhc_card_present(struct mci_host *mci)
case ESDHC_CD_PERMANENT:
return 1;
case ESDHC_CD_CONTROLLER:
- return !(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL);
+ return !(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & SDHCI_WRITE_PROTECT);
case ESDHC_CD_GPIO:
ret = gpio_direction_input(pdata->cd_gpio);
if (ret)
diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c
index cb72235807..61995a2883 100644
--- a/drivers/mci/mci-bcm2835.c
+++ b/drivers/mci/mci-bcm2835.c
@@ -110,12 +110,12 @@ static int bcm2835_mci_transfer_data(struct bcm2835_mci_host *host,
if (data->flags & MMC_DATA_READ) {
p = (u32 *) data->dest;
data_ready_intr_mask = SDHCI_INT_DATA_AVAIL;
- data_ready_status_mask = PRSSTAT_BREN;
+ data_ready_status_mask = SDHCI_BUFFER_READ_ENABLE;
read_write_func = &sdhci_read32_data;
} else {
p = (u32 *) data->src;
data_ready_intr_mask = SDHCI_INT_SPACE_AVAIL;
- data_ready_status_mask = PRSSTAT_BWEN;
+ data_ready_status_mask = SDHCI_BUFFER_WRITE_ENABLE;
read_write_func = &sdhci_write32_data;
}
do {
@@ -204,7 +204,7 @@ static void bcm2835_mci_reset_emmc(struct bcm2835_mci_host *host, u32 reset,
static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
struct mci_data *data) {
u32 command, block_data = 0, ret = 0, transfer_mode = 0;
- u32 wait_inhibit_mask = PRSSTAT_CICHB | PRSSTAT_CIDHB;
+ u32 wait_inhibit_mask = SDHCI_CMD_INHIBIT_CMD | SDHCI_CMD_INHIBIT_DATA;
struct bcm2835_mci_host *host = to_bcm2835_host(mci);
command = SDHCI_CMD_INDEX(cmd->cmdidx);
@@ -236,7 +236,7 @@ static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
/* We shouldn't wait for data inihibit for stop commands, even
though they might use busy signaling */
if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
- wait_inhibit_mask = PRSSTAT_CICHB;
+ wait_inhibit_mask = SDHCI_CMD_INHIBIT_CMD;
/*Wait for old command*/
while (sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE)
diff --git a/drivers/mci/sdhci.h b/drivers/mci/sdhci.h
index 18db9a5c34..7071fc8d52 100644
--- a/drivers/mci/sdhci.h
+++ b/drivers/mci/sdhci.h
@@ -40,6 +40,10 @@
#define SDHCI_RESPONSE_3 0x1c
#define SDHCI_BUFFER 0x20
#define SDHCI_PRESENT_STATE 0x24
+#define SDHCI_WRITE_PROTECT BIT(19)
+#define SDHCI_BUFFER_READ_ENABLE BIT(11)
+#define SDHCI_BUFFER_WRITE_ENABLE BIT(10)
+#define SDHCI_DATA_LINE_ACTIVE BIT(2)
#define SDHCI_CMD_INHIBIT_DATA BIT(1)
#define SDHCI_CMD_INHIBIT_CMD BIT(0)
#define SDHCI_PRESENT_STATE1 0x26
@@ -92,18 +96,6 @@
#define SDHCI_SPEC_200_MAX_CLK_DIVIDER 256
#define SDHCI_MMC_BOOT 0xC4
-#define PRSSTAT_DAT0 0x01000000
-#define PRSSTAT_CLSL 0x00800000
-#define PRSSTAT_WPSPL 0x00080000
-#define PRSSTAT_CDPL 0x00040000
-#define PRSSTAT_CINS 0x00010000
-#define PRSSTAT_BREN 0x00000800
-#define PRSSTAT_BWEN 0x00000400
-#define PRSSTAT_SDSTB 0x00000008
-#define PRSSTAT_DLA 0x00000004
-#define PRSSTAT_CIDHB 0x00000002
-#define PRSSTAT_CICHB 0x00000001
-
struct sdhci {
u32 (*read32)(struct sdhci *host, int reg);
u16 (*read16)(struct sdhci *host, int reg);
diff --git a/drivers/mci/tegra-sdmmc.c b/drivers/mci/tegra-sdmmc.c
index 6cdf808f16..69de39b180 100644
--- a/drivers/mci/tegra-sdmmc.c
+++ b/drivers/mci/tegra-sdmmc.c
@@ -403,7 +403,7 @@ static int tegra_sdmmc_card_present(struct mci_host *mci)
return gpio_get_value(host->gpio_cd) ? 0 : 1;
}
- return !(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL);
+ return !(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & SDHCI_WRITE_PROTECT);
}
static int tegra_sdmmc_detect(struct device_d *dev)
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 15/21] mci: dove: Use sdhci_set_cmd_xfer_mode()
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (13 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 14/21] mci: sdhci: remove duplicate register defines for prsstat bits Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 16/21] mci: imx-esdhc: " Sascha Hauer
` (5 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
Use sdhci_set_cmd_xfer_mode() to share more code.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/dove-sdhci.c | 32 ++++----------------------------
1 file changed, 4 insertions(+), 28 deletions(-)
diff --git a/drivers/mci/dove-sdhci.c b/drivers/mci/dove-sdhci.c
index 7818bef0d9..e71a27ce4f 100644
--- a/drivers/mci/dove-sdhci.c
+++ b/drivers/mci/dove-sdhci.c
@@ -113,6 +113,7 @@ static int dove_sdhci_mci_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
struct mci_data *data)
{
u16 val;
+ u32 command, xfer;
u64 start;
int ret;
unsigned int num_bytes = data->blocks * data->blocksize;
@@ -158,36 +159,11 @@ static int dove_sdhci_mci_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
}
/* setup transfer mode */
- val = 0;
- if (data) {
- val |= SDHCI_DMA_EN | SDHCI_BLOCK_COUNT_EN;
- if (data->blocks > 1)
- val |= SDHCI_MULTIPLE_BLOCKS;
- if (data->flags & MMC_DATA_READ)
- val |= SDHCI_DATA_TO_HOST;
- }
- sdhci_write16(&host->sdhci, SDHCI_TRANSFER_MODE, val);
+ sdhci_set_cmd_xfer_mode(&host->sdhci, cmd, data, true, &command, &xfer);
+ sdhci_write16(&host->sdhci, SDHCI_TRANSFER_MODE, xfer);
sdhci_write32(&host->sdhci, SDHCI_ARGUMENT, cmd->cmdarg);
-
- if (!(cmd->resp_type & MMC_RSP_PRESENT))
- val = SDHCI_RESP_NONE;
- else if (cmd->resp_type & MMC_RSP_136)
- val = SDHCI_RESP_TYPE_136;
- else if (cmd->resp_type & MMC_RSP_BUSY)
- val = SDHCI_RESP_TYPE_48_BUSY;
- else
- val = SDHCI_RESP_TYPE_48;
-
- if (cmd->resp_type & MMC_RSP_CRC)
- val |= SDHCI_CMD_CRC_CHECK_EN;
- if (cmd->resp_type & MMC_RSP_OPCODE)
- val |= SDHCI_CMD_INDEX_CHECK_EN;
- if (data)
- val |= SDHCI_DATA_PRESENT;
- val |= SDHCI_CMD_INDEX(cmd->cmdidx);
-
- sdhci_write16(&host->sdhci, SDHCI_COMMAND, val);
+ sdhci_write16(&host->sdhci, SDHCI_COMMAND, command);
ret = dove_sdhci_wait_for_done(host, SDHCI_INT_CMD_COMPLETE);
if (ret) {
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 16/21] mci: imx-esdhc: Use sdhci_set_cmd_xfer_mode()
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (14 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 15/21] mci: dove: Use sdhci_set_cmd_xfer_mode() Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 17/21] mci: bcm2835: " Sascha Hauer
` (4 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
Use sdhci_set_cmd_xfer_mode() to share more code.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/imx-esdhc.c | 57 ++++++++---------------------------------
1 file changed, 11 insertions(+), 46 deletions(-)
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index c2c9d1e24c..4d23788eec 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -164,47 +164,6 @@ static inline void esdhc_setbits32(struct fsl_esdhc_host *host, unsigned int reg
esdhc_clrsetbits32(host, reg, 0, set);
}
-/* Return the XFERTYP flags for a given command and data packet */
-static u32 esdhc_xfertyp(struct fsl_esdhc_host *host,
- struct mci_cmd *cmd, struct mci_data *data)
-{
- u32 xfertyp = 0;
- u32 command = 0;
-
- if (data) {
- command |= SDHCI_DATA_PRESENT;
-
- if (!IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO))
- xfertyp |= SDHCI_DMA_EN;
-
- if (data->blocks > 1) {
- xfertyp |= SDHCI_MULTIPLE_BLOCKS;
- xfertyp |= SDHCI_BLOCK_COUNT_EN;
- }
-
- if (data->flags & MMC_DATA_READ)
- xfertyp |= SDHCI_DATA_TO_HOST;
- }
-
- if (cmd->resp_type & MMC_RSP_CRC)
- command |= SDHCI_CMD_CRC_CHECK_EN;
- if (cmd->resp_type & MMC_RSP_OPCODE)
- command |= SDHCI_CMD_INDEX_CHECK_EN;
- if (cmd->resp_type & MMC_RSP_136)
- command |= SDHCI_RESP_TYPE_136;
- else if (cmd->resp_type & MMC_RSP_BUSY)
- command |= SDHCI_RESP_TYPE_48_BUSY;
- else if (cmd->resp_type & MMC_RSP_PRESENT)
- command |= SDHCI_RESP_TYPE_48;
- if ((host->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) &&
- (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION))
- command |= SDHCI_COMMAND_CMDTYP_ABORT;
-
- command |= SDHCI_CMD_INDEX(cmd->cmdidx);
-
- return command << 16 | xfertyp;
-}
-
/*
* PIO Read/Write Mode reduce the performace as DMA is not used in this mode.
*/
@@ -330,7 +289,7 @@ static int esdhc_do_data(struct mci_host *mci, struct mci_data *data)
static int
esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
{
- u32 xfertyp, mixctrl;
+ u32 xfertyp, mixctrl, command;
u32 irqstat;
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
unsigned int num_bytes = 0;
@@ -369,21 +328,27 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
return err;
}
- /* Figure out the transfer arguments */
- xfertyp = esdhc_xfertyp(host, cmd, data);
+ sdhci_set_cmd_xfer_mode(&host->sdhci, cmd, data,
+ !IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO), &command,
+ &xfertyp);
+
+ if ((host->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) &&
+ (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION))
+ command |= SDHCI_COMMAND_CMDTYP_ABORT;
/* Send the command */
sdhci_write32(&host->sdhci, SDHCI_ARGUMENT, cmd->cmdarg);
if (esdhc_is_usdhc(host)) {
/* write lower-half of xfertyp to mixctrl */
- mixctrl = xfertyp & 0xFFFF;
+ mixctrl = xfertyp;
/* Keep the bits 22-25 of the register as is */
mixctrl |= (sdhci_read32(&host->sdhci, IMX_SDHCI_MIXCTRL) & (0xF << 22));
sdhci_write32(&host->sdhci, IMX_SDHCI_MIXCTRL, mixctrl);
}
- sdhci_write32(&host->sdhci, SDHCI_TRANSFER_MODE__COMMAND, xfertyp);
+ sdhci_write32(&host->sdhci, SDHCI_TRANSFER_MODE__COMMAND,
+ command << 16 | xfertyp);
/* Wait for the command to complete */
ret = wait_on_timeout(100 * MSECOND,
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 17/21] mci: bcm2835: Use sdhci_set_cmd_xfer_mode()
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (15 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 16/21] mci: imx-esdhc: " Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 18/21] mci: tegra: " Sascha Hauer
` (3 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
Use sdhci_set_cmd_xfer_mode() to share more code.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/mci-bcm2835.c | 22 ++--------------------
1 file changed, 2 insertions(+), 20 deletions(-)
diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c
index 61995a2883..f17bae7c8d 100644
--- a/drivers/mci/mci-bcm2835.c
+++ b/drivers/mci/mci-bcm2835.c
@@ -207,28 +207,10 @@ static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
u32 wait_inhibit_mask = SDHCI_CMD_INHIBIT_CMD | SDHCI_CMD_INHIBIT_DATA;
struct bcm2835_mci_host *host = to_bcm2835_host(mci);
- command = SDHCI_CMD_INDEX(cmd->cmdidx);
+ sdhci_set_cmd_xfer_mode(&host->sdhci, cmd, data, false,
+ &command, &transfer_mode);
- if (cmd->resp_type != MMC_RSP_NONE) {
- if (cmd->resp_type & MMC_RSP_136)
- command |= SDHCI_RESP_TYPE_136;
- else if (cmd->resp_type & MMC_RSP_BUSY)
- command |= SDHCI_RESP_TYPE_48_BUSY;
- else
- command |= SDHCI_RESP_TYPE_48;
- if (cmd->resp_type & MMC_RSP_CRC)
- command |= SDHCI_CMD_CRC_CHECK_EN;
- }
if (data != NULL) {
- command |= SDHCI_DATA_PRESENT;
- transfer_mode |= SDHCI_BLOCK_COUNT_EN;
-
- if (data->blocks > 1)
- transfer_mode |= SDHCI_MULTIPLE_BLOCKS;
-
- if (data->flags & MMC_DATA_READ)
- transfer_mode |= SDHCI_DATA_TO_HOST;
-
block_data = (data->blocks << BLOCK_SHIFT);
block_data |= data->blocksize;
}
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 18/21] mci: tegra: Use sdhci_set_cmd_xfer_mode()
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (16 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 17/21] mci: bcm2835: " Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 19/21] mci: imx-esdhci: Use generic PIO transfer function Sascha Hauer
` (2 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
Use sdhci_set_cmd_xfer_mode() to share more code.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/tegra-sdmmc.c | 33 +++------------------------------
1 file changed, 3 insertions(+), 30 deletions(-)
diff --git a/drivers/mci/tegra-sdmmc.c b/drivers/mci/tegra-sdmmc.c
index 69de39b180..1cc75dc524 100644
--- a/drivers/mci/tegra-sdmmc.c
+++ b/drivers/mci/tegra-sdmmc.c
@@ -116,7 +116,7 @@ static int tegra_sdmmc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
{
struct tegra_sdmmc_host *host = to_tegra_sdmmc_host(mci);
unsigned int num_bytes = 0;
- u32 val = 0, command = 0;
+ u32 val = 0, command, xfer;
int ret;
ret = tegra_sdmmc_wait_inhibit(host, cmd, data, 10);
@@ -146,37 +146,10 @@ static int tegra_sdmmc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY))
return -1;
- if (data) {
- if (data->blocks > 1)
- val |= SDHCI_MULTIPLE_BLOCKS;
-
- if (data->flags & MMC_DATA_READ)
- val |= SDHCI_DATA_TO_HOST;
-
- val |= SDHCI_DMA_EN | SDHCI_BLOCK_COUNT_EN;
- }
-
- if (!(cmd->resp_type & MMC_RSP_PRESENT))
- command |= SDHCI_RESP_NONE;
- else if (cmd->resp_type & MMC_RSP_136)
- command |= SDHCI_RESP_TYPE_136;
- else if (cmd->resp_type & MMC_RSP_BUSY)
- command |= SDHCI_RESP_TYPE_48_BUSY;
- else
- command |= SDHCI_RESP_TYPE_48;
-
- if (cmd->resp_type & MMC_RSP_CRC)
- command |= SDHCI_CMD_CRC_CHECK_EN;
- if (cmd->resp_type & MMC_RSP_OPCODE)
- command |= SDHCI_CMD_INDEX_CHECK_EN;
-
- if (data)
- command |= SDHCI_DATA_PRESENT;
-
- command |= SDHCI_CMD_INDEX(cmd->cmdidx);
+ sdhci_set_cmd_xfer_mode(&host->sdhci, cmd, data, true, &command, &xfer);
sdhci_write32(&host->sdhci, SDHCI_TRANSFER_MODE__COMMAND,
- command << 16 | val);
+ command << 16 | xfer);
ret = wait_on_timeout(100 * MSECOND,
(val = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS))
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 19/21] mci: imx-esdhci: Use generic PIO transfer function
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (17 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 18/21] mci: tegra: " Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 20/21] mci: mci-bcm2835: " Sascha Hauer
2019-11-19 10:50 ` [PATCH 21/21] mci: add Arasan SDHCI controller driver Sascha Hauer
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
Use sdhci_transfer_data() in PIO mode to share mode code.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/imx-esdhc.c | 69 +----------------------------------------
1 file changed, 1 insertion(+), 68 deletions(-)
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 4d23788eec..bebc36d0b6 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -164,73 +164,6 @@ static inline void esdhc_setbits32(struct fsl_esdhc_host *host, unsigned int reg
esdhc_clrsetbits32(host, reg, 0, set);
}
-/*
- * PIO Read/Write Mode reduce the performace as DMA is not used in this mode.
- */
-static int
-esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
-{
- struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
- u32 blocks;
- char *buffer;
- u32 databuf;
- u32 size;
- u32 irqstat;
- u32 timeout;
-
- if (data->flags & MMC_DATA_READ) {
- blocks = data->blocks;
- buffer = data->dest;
- while (blocks) {
- timeout = PIO_TIMEOUT;
- size = data->blocksize;
- irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
- while (!(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) &
- SDHCI_BUFFER_READ_ENABLE)
- && --timeout);
- if (timeout <= 0) {
- dev_err(host->dev, "Data Read Failed\n");
- return -ETIMEDOUT;
- }
- while (size && (!(irqstat & SDHCI_INT_XFER_COMPLETE))) {
- udelay(100); /* Wait before last byte transfer complete */
- irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
- databuf = sdhci_read32(&host->sdhci, SDHCI_BUFFER);
- *((u32 *)buffer) = databuf;
- buffer += 4;
- size -= 4;
- }
- blocks--;
- }
- } else {
- blocks = data->blocks;
- buffer = (char *)data->src;
- while (blocks) {
- timeout = PIO_TIMEOUT;
- size = data->blocksize;
- irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
- while (!(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) &
- SDHCI_BUFFER_WRITE_ENABLE)
- && --timeout);
- if (timeout <= 0) {
- dev_err(host->dev, "Data Write Failed\n");
- return -ETIMEDOUT;
- }
- while (size && (!(irqstat & SDHCI_INT_XFER_COMPLETE))) {
- udelay(100); /* Wait before last byte transfer complete */
- databuf = *((u32 *)buffer);
- buffer += 4;
- size -= 4;
- irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
- sdhci_write32(&host->sdhci, SDHCI_BUFFER, databuf);
- }
- blocks--;
- }
- }
-
- return 0;
-}
-
static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data,
dma_addr_t dma)
{
@@ -266,7 +199,7 @@ static int esdhc_do_data(struct mci_host *mci, struct mci_data *data)
u32 irqstat;
if (IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO))
- return esdhc_pio_read_write(mci, data);
+ return sdhci_transfer_data(&host->sdhci, data);
do {
irqstat = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 20/21] mci: mci-bcm2835: Use generic PIO transfer function
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (18 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 19/21] mci: imx-esdhci: Use generic PIO transfer function Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 21/21] mci: add Arasan SDHCI controller driver Sascha Hauer
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List
Use sdhci_transfer_data() to share more code.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/mci-bcm2835.c | 92 ++++-----------------------------------
1 file changed, 8 insertions(+), 84 deletions(-)
diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c
index f17bae7c8d..b18d681870 100644
--- a/drivers/mci/mci-bcm2835.c
+++ b/drivers/mci/mci-bcm2835.c
@@ -67,10 +67,13 @@ static void bcm2835_sdhci_write32(struct sdhci *sdhci, int reg, u32 val)
* too)
*/
- if (host->last_write != 0)
- while ((get_time_ns() - host->last_write) < twoticks_delay)
- ;
- host->last_write = get_time_ns();
+ if (reg != SDHCI_BUFFER) {
+ if (host->last_write != 0)
+ while ((get_time_ns() - host->last_write) < twoticks_delay)
+ ;
+ host->last_write = get_time_ns();
+ }
+
writel(val, host->regs + reg);
}
@@ -81,85 +84,6 @@ static u32 bcm2835_sdhci_read32(struct sdhci *sdhci, int reg)
return readl(host->regs + reg);
}
-/* Create special write data function since the data
- * register is not affected by the twoticks_delay bug
- * and we can thus get better speed here
- */
-static void sdhci_write32_data(struct bcm2835_mci_host *host, u32 *p)
-{
- writel(*p, host->regs + SDHCI_BUFFER);
-}
-
-/* Make a read data functions as well just to keep structure */
-static void sdhci_read32_data(struct bcm2835_mci_host *host, u32 *p)
-{
- *p = readl(host->regs + SDHCI_BUFFER);
-}
-
-static int bcm2835_mci_transfer_data(struct bcm2835_mci_host *host,
- struct mci_cmd *cmd, struct mci_data *data) {
- u32 *p;
- u32 data_size, status, intr_status = 0;
- u32 data_ready_intr_mask;
- u32 data_ready_status_mask;
- int i = 0;
- void (*read_write_func)(struct bcm2835_mci_host*, u32*);
-
- data_size = data->blocksize * data->blocks;
-
- if (data->flags & MMC_DATA_READ) {
- p = (u32 *) data->dest;
- data_ready_intr_mask = SDHCI_INT_DATA_AVAIL;
- data_ready_status_mask = SDHCI_BUFFER_READ_ENABLE;
- read_write_func = &sdhci_read32_data;
- } else {
- p = (u32 *) data->src;
- data_ready_intr_mask = SDHCI_INT_SPACE_AVAIL;
- data_ready_status_mask = SDHCI_BUFFER_WRITE_ENABLE;
- read_write_func = &sdhci_write32_data;
- }
- do {
- intr_status = sdhci_read32(&host->sdhci, SDHCI_INT_STATUS);
- if (intr_status & SDHCI_INT_INDEX) {
- dev_err(host->hw_dev,
- "Error occured while transferring data: 0x%X\n",
- intr_status);
- return -EPERM;
- }
- if (intr_status & data_ready_intr_mask) {
- status = sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE);
- if ((status & data_ready_status_mask) == 0)
- continue;
- /*Clear latest int and transfer one block size of data*/
- sdhci_write32(&host->sdhci, SDHCI_INT_STATUS,
- data_ready_intr_mask);
- for (i = 0; i < data->blocksize; i += 4) {
- read_write_func(host, p);
- p++;
- data_size -= 4;
- }
- }
- } while ((intr_status & SDHCI_INT_XFER_COMPLETE) == 0);
-
- if (data_size != 0) {
- if (data->flags & MMC_DATA_READ)
- dev_err(host->hw_dev, "Error while reading:\n");
- else
- dev_err(host->hw_dev, "Error while writing:\n");
-
- dev_err(host->hw_dev, "Transferred %d bytes of data, wanted %d\n",
- (data->blocksize * data->blocks) - data_size,
- data->blocksize * data->blocks);
-
- dev_err(host->hw_dev, "Status: 0x%X, Interrupt: 0x%X\n",
- sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE),
- sdhci_read32(&host->sdhci, SDHCI_INT_STATUS));
-
- return -EPERM;
- }
- return 0;
-}
-
static u32 bcm2835_mci_wait_command_done(struct bcm2835_mci_host *host)
{
u32 interrupt = 0;
@@ -248,7 +172,7 @@ static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
}
if (!ret && data)
- ret = bcm2835_mci_transfer_data(host, cmd, data);
+ ret = sdhci_transfer_data(&host->sdhci, data);
sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, 0xFFFFFFFF);
if (ret) {
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 21/21] mci: add Arasan SDHCI controller driver
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
` (19 preceding siblings ...)
2019-11-19 10:50 ` [PATCH 20/21] mci: mci-bcm2835: " Sascha Hauer
@ 2019-11-19 10:50 ` Sascha Hauer
20 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 10:50 UTC (permalink / raw)
To: Barebox List; +Cc: Thomas Haemmerle, Michael Tretter
From: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
This adds support for the Arasan SDHCI controller, which is found on
the Xilinx Zynq 7000 and ZynqMP SoCs. This just adds very basic
PIO read/write support.
This submission is also missing the tap delay configuration, which is
required for the high speed modes on the ZynqMP, but this can be
added in a separate patch once it is clear how the interface for this
feature should look like.
The driver skeleton was provided by Michael, most of the actual driver
porting work was done by Thomas and some coding style fixes and write
support bug fixes added by Lucas.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Signed-off-by: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
Signed-off-by: Lucas Stach <dev@lynxeye.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/Kconfig | 6 +
drivers/mci/Makefile | 1 +
drivers/mci/arasan-sdhci.c | 423 +++++++++++++++++++++++++++++++++++++
drivers/mci/sdhci.h | 3 +
4 files changed, 433 insertions(+)
create mode 100644 drivers/mci/arasan-sdhci.c
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 526600556b..c269b71e89 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -142,6 +142,12 @@ config MCI_TEGRA
Enable this to support SD and MMC card read/write on a Tegra based
systems.
+config MCI_ARASAN
+ bool "Arasan SDHCI Controller"
+ help
+ Enable this to support SD and MMC card read/write on systems with
+ the Arasan SD3.0 / SDIO3.0 / eMMC4.51 host controller.
+
config MCI_SPI
bool "MMC/SD over SPI"
select CRC7
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index 9efdbd651e..e2e3ba7ef4 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_MCI) += mci-core.o
+obj-$(CONFIG_MCI_ARASAN) += arasan-sdhci.o
obj-$(CONFIG_MCI_ATMEL) += atmel_mci.o
obj-$(CONFIG_MCI_BCM283X) += mci-bcm2835.o
obj-$(CONFIG_MCI_BCM283X_SDHOST) += bcm2835-sdhost.o
diff --git a/drivers/mci/arasan-sdhci.c b/drivers/mci/arasan-sdhci.c
new file mode 100644
index 0000000000..b43a4f8ddf
--- /dev/null
+++ b/drivers/mci/arasan-sdhci.c
@@ -0,0 +1,423 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <clock.h>
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <linux/clk.h>
+#include <mci.h>
+
+#include "sdhci.h"
+
+#define SDHCI_ARASAN_HCAP_CLK_FREQ_MASK 0xFF00
+#define SDHCI_ARASAN_HCAP_CLK_FREQ_SHIFT 8
+#define SDHCI_INT_ADMAE BIT(29)
+#define SDHCI_ARASAN_INT_DATA_MASK SDHCI_INT_XFER_COMPLETE | \
+ SDHCI_INT_DMA | \
+ SDHCI_INT_SPACE_AVAIL | \
+ SDHCI_INT_DATA_AVAIL | \
+ SDHCI_INT_DATA_TIMEOUT | \
+ SDHCI_INT_DATA_CRC | \
+ SDHCI_INT_DATA_END_BIT | \
+ SDHCI_INT_ADMAE
+
+#define SDHCI_ARASAN_INT_CMD_MASK SDHCI_INT_CMD_COMPLETE | \
+ SDHCI_INT_TIMEOUT | \
+ SDHCI_INT_CRC | \
+ SDHCI_INT_END_BIT | \
+ SDHCI_INT_INDEX
+
+#define SDHCI_ARASAN_BUS_WIDTH 4
+#define TIMEOUT_VAL 0xE
+
+struct arasan_sdhci_host {
+ struct mci_host mci;
+ struct sdhci sdhci;
+ void __iomem *ioaddr;
+ unsigned int quirks; /* Arasan deviations from spec */
+/* Controller does not have CD wired and will not function normally without */
+#define SDHCI_ARASAN_QUIRK_FORCE_CDTEST BIT(0)
+#define SDHCI_ARASAN_QUIRK_NO_1_8_V BIT(1)
+};
+
+
+static inline
+struct arasan_sdhci_host *to_arasan_sdhci_host(struct mci_host *mci)
+{
+ return container_of(mci, struct arasan_sdhci_host, mci);
+}
+
+static inline
+struct arasan_sdhci_host *sdhci_to_arasan(struct sdhci *sdhci)
+{
+ return container_of(sdhci, struct arasan_sdhci_host, sdhci);
+}
+
+static void arasan_sdhci_writel(struct sdhci *sdhci, int reg, u32 val)
+{
+ struct arasan_sdhci_host *p = sdhci_to_arasan(sdhci);
+
+ writel(val, p->ioaddr + reg);
+}
+
+static void arasan_sdhci_writew(struct sdhci *sdhci, int reg, u16 val)
+{
+ struct arasan_sdhci_host *p = sdhci_to_arasan(sdhci);
+
+ writew(val, p->ioaddr + reg);
+}
+
+static void arasan_sdhci_writeb(struct sdhci *sdhci, int reg, u8 val)
+{
+ struct arasan_sdhci_host *p = sdhci_to_arasan(sdhci);
+
+ writeb(val, p->ioaddr + reg);
+}
+
+static u32 arasan_sdhci_readl(struct sdhci *sdhci, int reg)
+{
+ struct arasan_sdhci_host *p = sdhci_to_arasan(sdhci);
+
+ return readl(p->ioaddr + reg);
+}
+
+static u16 arasan_sdhci_readw(struct sdhci *sdhci, int reg)
+{
+ struct arasan_sdhci_host *p = sdhci_to_arasan(sdhci);
+
+ return readw(p->ioaddr + reg);
+}
+
+static u8 arasan_sdhci_readb(struct sdhci *sdhci, int reg)
+{
+ struct arasan_sdhci_host *p = sdhci_to_arasan(sdhci);
+
+ return readb(p->ioaddr + reg);
+}
+
+static int arasan_sdhci_card_present(struct mci_host *mci)
+{
+ struct arasan_sdhci_host *host = to_arasan_sdhci_host(mci);
+
+ return !!(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & SDHCI_CARD_DETECT);
+}
+
+static int arasan_sdhci_card_write_protected(struct mci_host *mci)
+{
+ struct arasan_sdhci_host *host = to_arasan_sdhci_host(mci);
+
+ return !(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & SDHCI_WRITE_PROTECT);
+}
+
+static int arasan_sdhci_reset(struct arasan_sdhci_host *host, u8 mask)
+{
+ sdhci_write8(&host->sdhci, SDHCI_SOFTWARE_RESET, mask);
+
+ /* wait for reset completion */
+ if (wait_on_timeout(100 * MSECOND,
+ !(sdhci_read8(&host->sdhci, SDHCI_SOFTWARE_RESET) & mask))){
+ dev_err(host->mci.hw_dev, "SDHCI reset timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ if (host->quirks & SDHCI_ARASAN_QUIRK_FORCE_CDTEST) {
+ u8 ctrl;
+
+ ctrl = sdhci_read8(&host->sdhci, SDHCI_HOST_CONTROL);
+ ctrl |= SDHCI_CARD_DETECT_TEST_LEVEL | SDHCI_CARD_DETECT_SIGNAL_SELECTION;
+ sdhci_write8(&host->sdhci, ctrl, SDHCI_HOST_CONTROL);
+ }
+
+ return 0;
+}
+
+static int arasan_sdhci_init(struct mci_host *mci, struct device_d *dev)
+{
+ struct arasan_sdhci_host *host = to_arasan_sdhci_host(mci);
+ int ret;
+
+ ret = arasan_sdhci_reset(host, SDHCI_RESET_ALL);
+ if (ret)
+ return ret;
+
+ sdhci_write8(&host->sdhci, SDHCI_POWER_CONTROL,
+ SDHCI_BUS_VOLTAGE_330 | SDHCI_BUS_POWER_EN);
+ udelay(400);
+
+ sdhci_write32(&host->sdhci, SDHCI_INT_ENABLE,
+ SDHCI_ARASAN_INT_DATA_MASK |
+ SDHCI_ARASAN_INT_CMD_MASK);
+ sdhci_write32(&host->sdhci, SDHCI_SIGNAL_ENABLE, 0x00);
+
+ return 0;
+}
+
+#define SDHCI_MAX_DIV_SPEC_300 2046
+
+static u16 arasan_sdhci_get_clock_divider(struct arasan_sdhci_host *host,
+ unsigned int reqclk)
+{
+ u16 div;
+
+ for (div = 1; div < SDHCI_MAX_DIV_SPEC_300; div += 2)
+ if ((host->mci.f_max / div) <= reqclk)
+ break;
+ div /= 2;
+
+ return div;
+}
+
+#define SDHCI_FREQ_SEL_10_BIT(x) (((x) & 0x300) >> 2)
+
+static void arasan_sdhci_set_ios(struct mci_host *mci, struct mci_ios *ios)
+{
+ struct arasan_sdhci_host *host = to_arasan_sdhci_host(mci);
+ u16 val;
+
+ /* stop clock */
+ sdhci_write16(&host->sdhci, SDHCI_CLOCK_CONTROL, 0);
+
+ if (ios->clock) {
+ u64 start;
+
+ /* set & start clock */
+ val = arasan_sdhci_get_clock_divider(host, ios->clock);
+ /* Bit 6 & 7 are upperbits of 10bit divider */
+ val = SDHCI_FREQ_SEL(val) | SDHCI_FREQ_SEL_10_BIT(val);
+ val |= SDHCI_INTCLOCK_EN;
+ sdhci_write16(&host->sdhci, SDHCI_CLOCK_CONTROL, val);
+
+ start = get_time_ns();
+ while (!(sdhci_read16(&host->sdhci, SDHCI_CLOCK_CONTROL) &
+ SDHCI_INTCLOCK_STABLE)) {
+ if (is_timeout(start, 20 * MSECOND)) {
+ dev_err(host->mci.hw_dev,
+ "SDHCI clock stable timeout\n");
+ return;
+ }
+ }
+ /* enable bus clock */
+ sdhci_write16(&host->sdhci, SDHCI_CLOCK_CONTROL,
+ val | SDHCI_SDCLOCK_EN);
+ }
+
+ val = sdhci_read8(&host->sdhci, SDHCI_HOST_CONTROL) &
+ ~(SDHCI_DATA_WIDTH_4BIT | SDHCI_DATA_WIDTH_8BIT);
+
+ switch (ios->bus_width) {
+ case MMC_BUS_WIDTH_8:
+ val |= SDHCI_DATA_WIDTH_8BIT;
+ break;
+ case MMC_BUS_WIDTH_4:
+ val |= SDHCI_DATA_WIDTH_4BIT;
+ break;
+ }
+
+ if (ios->clock > 26000000)
+ val |= SDHCI_HIGHSPEED_EN;
+ else
+ val &= ~SDHCI_HIGHSPEED_EN;
+
+ sdhci_write8(&host->sdhci, SDHCI_HOST_CONTROL, val);
+}
+
+static int arasan_sdhci_wait_for_done(struct arasan_sdhci_host *host, u32 mask)
+{
+ u64 start = get_time_ns();
+ u16 stat;
+
+ do {
+ stat = sdhci_read16(&host->sdhci, SDHCI_INT_NORMAL_STATUS);
+ if (stat & SDHCI_INT_ERROR) {
+ dev_err(host->mci.hw_dev, "SDHCI_INT_ERROR: 0x%08x\n",
+ sdhci_read16(&host->sdhci, SDHCI_INT_ERROR_STATUS));
+ return -EPERM;
+ }
+
+ if (is_timeout(start, 1000 * MSECOND)) {
+ dev_err(host->mci.hw_dev,
+ "SDHCI timeout while waiting for done\n");
+ return -ETIMEDOUT;
+ }
+ } while ((stat & mask) != mask);
+
+ return 0;
+}
+
+static void print_error(struct arasan_sdhci_host *host, int cmdidx)
+{
+ dev_err(host->mci.hw_dev,
+ "error while transfering data for command %d\n", cmdidx);
+ dev_err(host->mci.hw_dev, "state = 0x%08x , interrupt = 0x%08x\n",
+ sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE),
+ sdhci_read32(&host->sdhci, SDHCI_INT_NORMAL_STATUS));
+}
+
+static int arasan_sdhci_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
+ struct mci_data *data)
+{
+ struct arasan_sdhci_host *host = to_arasan_sdhci_host(mci);
+ u32 mask, command, xfer;
+ int ret;
+
+ /* Wait for idle before next command */
+ mask = SDHCI_CMD_INHIBIT_CMD;
+ if (cmd->cmdidx != MMC_CMD_STOP_TRANSMISSION)
+ mask |= SDHCI_CMD_INHIBIT_DATA;
+
+ ret = wait_on_timeout(10 * MSECOND,
+ !(sdhci_read32(&host->sdhci, SDHCI_PRESENT_STATE) & mask));
+
+ if (ret) {
+ dev_err(host->mci.hw_dev,
+ "SDHCI timeout while waiting for idle\n");
+ return ret;
+ }
+
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, ~0);
+
+ mask = SDHCI_INT_CMD_COMPLETE;
+ if (data)
+ mask |= SDHCI_INT_XFER_COMPLETE;
+
+ sdhci_set_cmd_xfer_mode(&host->sdhci, cmd, data, false, &command, &xfer);
+
+ sdhci_write8(&host->sdhci, SDHCI_TIMEOUT_CONTROL, TIMEOUT_VAL);
+ sdhci_write16(&host->sdhci, SDHCI_TRANSFER_MODE, xfer);
+ sdhci_write16(&host->sdhci, SDHCI_BLOCK_SIZE, SDHCI_DMA_BOUNDARY_512K |
+ SDHCI_TRANSFER_BLOCK_SIZE(data->blocksize));
+ sdhci_write16(&host->sdhci, SDHCI_BLOCK_COUNT, data->blocks);
+ sdhci_write32(&host->sdhci, SDHCI_ARGUMENT, cmd->cmdarg);
+ sdhci_write16(&host->sdhci, SDHCI_COMMAND, command);
+
+ ret = arasan_sdhci_wait_for_done(host, mask);
+ if (ret == -EPERM)
+ goto error;
+ else if (ret)
+ return ret;
+
+ sdhci_read_response(&host->sdhci, cmd);
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, mask);
+
+ if (data)
+ ret = sdhci_transfer_data(&host->sdhci, data);
+
+error:
+ if (ret) {
+ print_error(host, cmd->cmdidx);
+ arasan_sdhci_reset(host, BIT(1)); // SDHCI_RESET_CMD
+ arasan_sdhci_reset(host, BIT(2)); // SDHCI_RESET_DATA
+ }
+
+ sdhci_write32(&host->sdhci, SDHCI_INT_STATUS, ~0);
+ return ret;
+}
+
+
+static void arasan_sdhci_set_mci_caps(struct arasan_sdhci_host *host)
+{
+ u16 caps = sdhci_read16(&host->sdhci, SDHCI_CAPABILITIES_1);
+
+ if ((caps & SDHCI_HOSTCAP_VOLTAGE_180) &&
+ !(host->quirks & SDHCI_ARASAN_QUIRK_NO_1_8_V))
+ host->mci.voltages |= MMC_VDD_165_195;
+ if (caps & SDHCI_HOSTCAP_VOLTAGE_300)
+ host->mci.voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
+ if (caps & SDHCI_HOSTCAP_VOLTAGE_330)
+ host->mci.voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
+
+ if (caps & SDHCI_HOSTCAP_HIGHSPEED)
+ host->mci.host_caps |= (MMC_CAP_MMC_HIGHSPEED_52MHZ |
+ MMC_CAP_MMC_HIGHSPEED |
+ MMC_CAP_SD_HIGHSPEED);
+
+ /* parse board supported bus width capabilities */
+ mci_of_parse(&host->mci);
+
+ /* limit bus widths to controller capabilities */
+ if (!(caps & SDHCI_HOSTCAP_8BIT))
+ host->mci.host_caps &= ~MMC_CAP_8_BIT_DATA;
+}
+
+static int arasan_sdhci_probe(struct device_d *dev)
+{
+ struct device_node *np = dev->device_node;
+ struct arasan_sdhci_host *arasan_sdhci;
+ struct clk *clk_xin, *clk_ahb;
+ struct resource *iores;
+ struct mci_host *mci;
+ int ret;
+
+ arasan_sdhci = xzalloc(sizeof(*arasan_sdhci));
+
+ mci = &arasan_sdhci->mci;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ arasan_sdhci->ioaddr = IOMEM(iores->start);
+
+ clk_ahb = clk_get(dev, "clk_ahb");
+ if (IS_ERR(clk_ahb)) {
+ dev_err(dev, "clk_ahb clock not found.\n");
+ return PTR_ERR(clk_ahb);
+ }
+
+ clk_xin = clk_get(dev, "clk_xin");
+ if (IS_ERR(clk_xin)) {
+ dev_err(dev, "clk_xin clock not found.\n");
+ return PTR_ERR(clk_xin);
+ }
+ ret = clk_enable(clk_ahb);
+ if (ret) {
+ dev_err(dev, "Failed to enable AHB clock: %s\n",
+ strerror(ret));
+ return ret;
+ }
+
+ ret = clk_enable(clk_xin);
+ if (ret) {
+ dev_err(dev, "Failed to enable SD clock: %s\n", strerror(ret));
+ return ret;
+ }
+
+ if (of_property_read_bool(np, "xlnx,fails-without-test-cd"))
+ arasan_sdhci->quirks |= SDHCI_ARASAN_QUIRK_FORCE_CDTEST;
+
+ if (of_property_read_bool(np, "no-1-8-v"))
+ arasan_sdhci->quirks |= SDHCI_ARASAN_QUIRK_NO_1_8_V;
+
+ arasan_sdhci->sdhci.read32 = arasan_sdhci_readl;
+ arasan_sdhci->sdhci.read16 = arasan_sdhci_readw;
+ arasan_sdhci->sdhci.read8 = arasan_sdhci_readb;
+ arasan_sdhci->sdhci.write32 = arasan_sdhci_writel;
+ arasan_sdhci->sdhci.write16 = arasan_sdhci_writew;
+ arasan_sdhci->sdhci.write8 = arasan_sdhci_writeb;
+ mci->send_cmd = arasan_sdhci_send_cmd;
+ mci->set_ios = arasan_sdhci_set_ios;
+ mci->init = arasan_sdhci_init;
+ mci->card_present = arasan_sdhci_card_present;
+ mci->card_write_protected = arasan_sdhci_card_write_protected;
+ mci->hw_dev = dev;
+
+ mci->f_max = clk_get_rate(clk_xin);
+ mci->f_min = 50000000 / 256;
+
+ arasan_sdhci_set_mci_caps(arasan_sdhci);
+
+ dev->priv = arasan_sdhci;
+
+ return mci_register(&arasan_sdhci->mci);
+}
+
+static __maybe_unused struct of_device_id arasan_sdhci_compatible[] = {
+ { .compatible = "arasan,sdhci-8.9a" },
+ { /* sentinel */ }
+};
+
+static struct driver_d arasan_sdhci_driver = {
+ .name = "arasan-sdhci",
+ .probe = arasan_sdhci_probe,
+ .of_compatible = DRV_OF_COMPAT(arasan_sdhci_compatible),
+};
+device_platform_driver(arasan_sdhci_driver);
diff --git a/drivers/mci/sdhci.h b/drivers/mci/sdhci.h
index 7071fc8d52..a307dc97cd 100644
--- a/drivers/mci/sdhci.h
+++ b/drivers/mci/sdhci.h
@@ -41,6 +41,7 @@
#define SDHCI_BUFFER 0x20
#define SDHCI_PRESENT_STATE 0x24
#define SDHCI_WRITE_PROTECT BIT(19)
+#define SDHCI_CARD_DETECT BIT(18)
#define SDHCI_BUFFER_READ_ENABLE BIT(11)
#define SDHCI_BUFFER_WRITE_ENABLE BIT(10)
#define SDHCI_DATA_LINE_ACTIVE BIT(2)
@@ -49,6 +50,8 @@
#define SDHCI_PRESENT_STATE1 0x26
#define SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL 0x28
#define SDHCI_HOST_CONTROL 0x28
+#define SDHCI_CARD_DETECT_SIGNAL_SELECTION BIT(7)
+#define SDHCI_CARD_DETECT_TEST_LEVEL BIT(6)
#define SDHCI_DATA_WIDTH_8BIT BIT(5)
#define SDHCI_HIGHSPEED_EN BIT(2)
#define SDHCI_DATA_WIDTH_4BIT BIT(1)
--
2.24.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 01/21] mci: Add sdhci helper
2019-11-19 10:50 ` [PATCH 01/21] mci: Add sdhci helper Sascha Hauer
@ 2019-11-19 11:10 ` Ahmad Fatoum
2019-11-19 13:09 ` Sascha Hauer
0 siblings, 1 reply; 24+ messages in thread
From: Ahmad Fatoum @ 2019-11-19 11:10 UTC (permalink / raw)
To: barebox
On 11/19/19 11:50 AM, Sascha Hauer wrote:
> We have several SDHCI compatible drivers in the tree. This starts
> with a set of generic helper functions for these drivers to share
> some common functionality.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> drivers/mci/Kconfig | 3 +
> drivers/mci/Makefile | 1 +
> drivers/mci/sdhci.c | 127 +++++++++++++++++++++++++++++++++++++++++++
> drivers/mci/sdhci.h | 45 +++++++++++++++
> 4 files changed, 176 insertions(+)
> create mode 100644 drivers/mci/sdhci.c
>
> diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
> index 4a71a46097..c37d40195a 100644
> --- a/drivers/mci/Kconfig
> +++ b/drivers/mci/Kconfig
> @@ -34,6 +34,9 @@ config MCI_MMC_BOOT_PARTITIONS
>
> comment "--- MCI host drivers ---"
>
> +config MCI_SDHCI
> + bool
> +
> config MCI_DW
> bool "Synopsys DesignWare Memory Card Interface"
> depends on HAS_DMA
> diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
> index 04c1287fee..9efdbd651e 100644
> --- a/drivers/mci/Makefile
> +++ b/drivers/mci/Makefile
> @@ -15,3 +15,4 @@ obj-$(CONFIG_MCI_SPI) += mci_spi.o
> obj-$(CONFIG_MCI_DW) += dw_mmc.o
> obj-$(CONFIG_MCI_MMCI) += mmci.o
> obj-$(CONFIG_MCI_STM32_SDMMC2) += stm32_sdmmc2.o
> +obj-$(CONFIG_MCI_SDHCI) += sdhci.o
> diff --git a/drivers/mci/sdhci.c b/drivers/mci/sdhci.c
> new file mode 100644
> index 0000000000..1ab1c0f236
> --- /dev/null
> +++ b/drivers/mci/sdhci.c
> @@ -0,0 +1,127 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <common.h>
> +#include <driver.h>
> +#include <mci.h>
> +#include <io.h>
> +
> +#include "sdhci.h"
> +
> +void sdhci_read_response(struct sdhci *sdhci, struct mci_cmd *cmd)
> +{
> + if (cmd->resp_type & MMC_RSP_136) {
> + u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0;
> +
> + cmdrsp3 = sdhci_read32(sdhci, SDHCI_RESPONSE_3);
> + cmdrsp2 = sdhci_read32(sdhci, SDHCI_RESPONSE_2);
> + cmdrsp1 = sdhci_read32(sdhci, SDHCI_RESPONSE_1);
> + cmdrsp0 = sdhci_read32(sdhci, SDHCI_RESPONSE_0);
> + cmd->response[0] = (cmdrsp3 << 8) | (cmdrsp2 >> 24);
> + cmd->response[1] = (cmdrsp2 << 8) | (cmdrsp1 >> 24);
> + cmd->response[2] = (cmdrsp1 << 8) | (cmdrsp0 >> 24);
> + cmd->response[3] = (cmdrsp0 << 8);
> + } else {
> + cmd->response[0] = sdhci_read32(sdhci, SDHCI_RESPONSE_0);
> + }
> +}
> +
> +void sdhci_set_cmd_xfer_mode(struct sdhci *host, struct mci_cmd *cmd,
> + struct mci_data *data, bool dma, u32 *command,
> + u32 *xfer)
> +{
> + *command = 0;
> + *xfer = 0;
> +
> + if (!(cmd->resp_type & MMC_RSP_PRESENT))
> + *command |= SDHCI_RESP_NONE;
> + else if (cmd->resp_type & MMC_RSP_136)
> + *command |= SDHCI_RESP_TYPE_136;
> + else if (cmd->resp_type & MMC_RSP_BUSY)
> + *command |= SDHCI_RESP_TYPE_48_BUSY;
> + else
> + *command |= SDHCI_RESP_TYPE_48;
> +
> + if (cmd->resp_type & MMC_RSP_CRC)
> + *command |= SDHCI_CMD_CRC_CHECK_EN;
> + if (cmd->resp_type & MMC_RSP_OPCODE)
> + *command |= SDHCI_CMD_INDEX_CHECK_EN;
> +
> + *command |= SDHCI_CMD_INDEX(cmd->cmdidx);
> +
> + if (data) {
> + *command |= SDHCI_DATA_PRESENT;
> +
> + *xfer |= SDHCI_BLOCK_COUNT_EN;
> +
> + if (data->blocks > 1)
> + *xfer |= SDHCI_MULTIPLE_BLOCKS;
> +
> + if (data->flags & MMC_DATA_READ)
> + *xfer |= SDHCI_DATA_TO_HOST;
> +
> + if (dma)
> + *xfer |= SDHCI_DMA_EN;
> + }
> +}
> +
> +static void sdhci_rx_pio(struct sdhci *sdhci, struct mci_data *data,
> + unsigned int block)
> +{
> + u32 *buf = (u32 *)data->dest;
> + int i;
> +
> + buf += block * data->blocksize / sizeof(u32);
> +
> + for (i = 0; i < data->blocksize / sizeof(u32); i++)
> + buf[i] = sdhci_read32(sdhci, SDHCI_BUFFER);
> +}
> +
> +static void sdhci_tx_pio(struct sdhci *sdhci, struct mci_data *data,
> + unsigned int block)
> +{
> + const u32 *buf = (const u32 *)data->src;
> + int i;
> +
> + buf += block * data->blocksize / sizeof(u32);
> +
> + for (i = 0; i < data->blocksize / sizeof(u32); i++)
> + sdhci_write32(sdhci, SDHCI_BUFFER, buf[i]);
> +}
> +
> +int sdhci_transfer_data(struct sdhci *sdhci, struct mci_data *data)
> +{
> + unsigned int block = 0;
> + u32 stat, prs;
> + uint64_t start = get_time_ns();
> +
> + do {
> + stat = sdhci_read32(sdhci, SDHCI_INT_STATUS);
> + if (stat & SDHCI_INT_ERROR)
> + return -EIO;
> +
> + if (block >= data->blocks)
> + continue;
> +
> + prs = sdhci_read32(sdhci, SDHCI_PRESENT_STATE);
> +
> + if (prs & SDHCI_BUFFER_READ_ENABLE &&
> + data->flags & MMC_DATA_READ) {
> + sdhci_rx_pio(sdhci, data, block);
> + block++;
> + start = get_time_ns();
> + }
> +
> + if (prs & SDHCI_BUFFER_WRITE_ENABLE &&
> + !(data->flags & MMC_DATA_READ)) {
> + sdhci_tx_pio(sdhci, data, block);
> + block++;
> + start = get_time_ns();
> + }
> +
> + if (is_timeout(start, 10 * SECOND))
10 seconds are a lot, should we call into barebox poller meanwhile?
> + return -ETIMEDOUT;
> +
> + } while (!(stat & SDHCI_INT_XFER_COMPLETE));
> +
> + return 0;
> +}
> diff --git a/drivers/mci/sdhci.h b/drivers/mci/sdhci.h
> index 90595e6433..640398d9d8 100644
> --- a/drivers/mci/sdhci.h
> +++ b/drivers/mci/sdhci.h
> @@ -149,4 +149,49 @@
> #define PRSSTAT_CIDHB 0x00000002
> #define PRSSTAT_CICHB 0x00000001
>
> +struct sdhci {
> + u32 (*read32)(struct sdhci *host, int reg);
> + u16 (*read16)(struct sdhci *host, int reg);
> + u8 (*read8)(struct sdhci *host, int reg);
> + void (*write32)(struct sdhci *host, int reg, u32 val);
> + void (*write16)(struct sdhci *host, int reg, u16 val);
> + void (*write8)(struct sdhci *host, int reg, u8 val);
> +};
> +
> +static inline u32 sdhci_read32(struct sdhci *host, int reg)
> +{
> + return host->read32(host, reg);
> +}
> +
> +static inline u32 sdhci_read16(struct sdhci *host, int reg)
> +{
> + return host->read16(host, reg);
> +}
> +
> +static inline u32 sdhci_read8(struct sdhci *host, int reg)
> +{
> + return host->read8(host, reg);
> +}
> +
> +static inline void sdhci_write32(struct sdhci *host, int reg, u32 val)
> +{
> + host->write32(host, reg, val);
> +}
> +
> +static inline void sdhci_write16(struct sdhci *host, int reg, u32 val)
> +{
> + host->write16(host, reg, val);
> +}
> +
> +static inline void sdhci_write8(struct sdhci *host, int reg, u32 val)
> +{
> + host->write8(host, reg, val);
> +}
> +
> +void sdhci_read_response(struct sdhci *host, struct mci_cmd *cmd);
> +void sdhci_set_cmd_xfer_mode(struct sdhci *host, struct mci_cmd *cmd,
> + struct mci_data *data, bool dma, u32 *command,
> + u32 *xfer);
> +int sdhci_transfer_data(struct sdhci *sdhci, struct mci_data *data);
> +
> #endif /* __MCI_SDHCI_H */
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 01/21] mci: Add sdhci helper
2019-11-19 11:10 ` Ahmad Fatoum
@ 2019-11-19 13:09 ` Sascha Hauer
0 siblings, 0 replies; 24+ messages in thread
From: Sascha Hauer @ 2019-11-19 13:09 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
On Tue, Nov 19, 2019 at 12:10:39PM +0100, Ahmad Fatoum wrote:
> > + if (prs & SDHCI_BUFFER_WRITE_ENABLE &&
> > + !(data->flags & MMC_DATA_READ)) {
> > + sdhci_tx_pio(sdhci, data, block);
> > + block++;
> > + start = get_time_ns();
> > + }
> > +
> > + if (is_timeout(start, 10 * SECOND))
>
> 10 seconds are a lot, should we call into barebox poller meanwhile?
is_timeout() does that.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2019-11-19 13:10 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-19 10:50 [PATCH 00/21] mci: SDHCI helper functions and arasan driver Sascha Hauer
2019-11-19 10:50 ` [PATCH 01/21] mci: Add sdhci helper Sascha Hauer
2019-11-19 11:10 ` Ahmad Fatoum
2019-11-19 13:09 ` Sascha Hauer
2019-11-19 10:50 ` [PATCH 02/21] mci: sdhci: Add missing command type defines Sascha Hauer
2019-11-19 10:50 ` [PATCH 03/21] mci: imx-esdhc: use sdhci helpers Sascha Hauer
2019-11-19 10:50 ` [PATCH 04/21] mci: bcm2835: " Sascha Hauer
2019-11-19 10:50 ` [PATCH 05/21] mci: tegra: " Sascha Hauer
2019-11-19 10:50 ` [PATCH 06/21] mci: dove: " Sascha Hauer
2019-11-19 10:50 ` [PATCH 07/21] mci: imx-esdhc: Use 16bit register definitions Sascha Hauer
2019-11-19 10:50 ` [PATCH 08/21] mci: mci-bcm2835: " Sascha Hauer
2019-11-19 10:50 ` [PATCH 09/21] mci: tegra: " Sascha Hauer
2019-11-19 10:50 ` [PATCH 10/21] mci: imx-esdhc-pbl: " Sascha Hauer
2019-11-19 10:50 ` [PATCH 11/21] mci: sdhci: remove 32bit register defines Sascha Hauer
2019-11-19 10:50 ` [PATCH 12/21] mci: sdhci: remove duplicate transfer mode " Sascha Hauer
2019-11-19 10:50 ` [PATCH 13/21] mci: sdhci: remove duplicate register defines for interrupt bits Sascha Hauer
2019-11-19 10:50 ` [PATCH 14/21] mci: sdhci: remove duplicate register defines for prsstat bits Sascha Hauer
2019-11-19 10:50 ` [PATCH 15/21] mci: dove: Use sdhci_set_cmd_xfer_mode() Sascha Hauer
2019-11-19 10:50 ` [PATCH 16/21] mci: imx-esdhc: " Sascha Hauer
2019-11-19 10:50 ` [PATCH 17/21] mci: bcm2835: " Sascha Hauer
2019-11-19 10:50 ` [PATCH 18/21] mci: tegra: " Sascha Hauer
2019-11-19 10:50 ` [PATCH 19/21] mci: imx-esdhci: Use generic PIO transfer function Sascha Hauer
2019-11-19 10:50 ` [PATCH 20/21] mci: mci-bcm2835: " Sascha Hauer
2019-11-19 10:50 ` [PATCH 21/21] mci: add Arasan SDHCI controller driver Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox