Skip to contentSkip to conversation

atmel_mci: fixes and cleanup

PATCH In review Jean-Christophe PLAGNIOL-VILLARD 2 participants 17 messages Jan 25, 2013

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover atmel_mci: fixes and cleanup

HI,

the following patche series clean and fixes the atmel mci driver

- highspeed support
- use fixup for each IP version
- fix new IP clk div
- sync with linux
- request and configure cd gpio

the atmel mci still does not work on rm9200

The following changes since commit 50d1b2de8ea0f3b8d89fe3a97ce64315996ed4cb:

ARM v7: Fix register corruption in v7_mmu_cache_off (2013-01-23 20:37:56 +0100)

are available in the git repository at:

git://git.jcrosoft.org/barebox.git delivery/atmel_mci

for you to fetch changes up to 282d19eb0d93141fcc50e5c68039a4d1452771d4:

atmel_mci: gpio: request and configure card detect (2013-01-21 16:36:13 +0800)

----------------------------------------------------------------
Jean-Christophe PLAGNIOL-VILLARD (14):
atmel_mci: rename atmel_mci_host tp atmel_mci
atmel_mci: rename atmel_mci_readl/writel to atmci_readl/writel
atmel_mci: rename all function to start with atmci
atmel_mci: use linux regs define
atmel_mci: detect IP version
atmel_mci: version 0x5xx of the IP have a different clk div
atmel_mci: fix host init
atmel_mci: rwproof is only needed since IP version 0x200
atmel_mci: on version 0x0 we need to reset the IP at each request
atmel_mci: after a software timeout the IP need to be reset
atmel_mci: support the SD highspeed since IP version 0x300
atmel_mci: update the SD/SDIO Card Register at request time
atmel_mci: drop board host caps
atmel_mci: gpio: request and configure card detect

 arch/arm/boards/at91sam9m10g45ek/init.c |    1 -
 arch/arm/boards/dss11/init.c            |    1 -
 arch/arm/mach-at91/include/mach/board.h |    1 -
 drivers/mci/at91_mci.h                  |  121 ----------------------------------
 drivers/mci/atmel-mci-regs.h            |  166 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/mci/atmel_mci.c                 |  391 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------
 6 files changed, 421 insertions(+), 260 deletions(-)
 delete mode 100644 drivers/mci/at91_mci.h
 create mode 100644 drivers/mci/atmel-mci-regs.h

Best Regards,
J.

_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

#1 lore raw

PATCH 1/14 atmel_mci: rename atmel_mci_host tp atmel_mci

to be consistent with the kernel

---
 drivers/mci/atmel_mci.c |   42 +++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)
drivers/mci/atmel_mci.c +21 -21
index 4065355..d6ac458 100644
@@ -27,7 +27,7 @@
 
 #include "at91_mci.h"
 
-struct atmel_mci_host {
+struct atmel_mci {
 	struct mci_host		mci;
 	void  __iomem		*base;
 	struct device_d		*hw_dev;
@@ -39,7 +39,7 @@ struct atmel_mci_host {
 	unsigned		slot_b;
 };
 
-#define to_mci_host(mci)	container_of(mci, struct atmel_mci_host, mci)
+#define to_mci_host(mci)	container_of(mci, struct atmel_mci, mci)
 
 #define STATUS_ERROR_MASK	(AT91_MCI_RINDE  \
 				| AT91_MCI_RDIRE \
@@ -51,25 +51,25 @@ struct atmel_mci_host {
 				| AT91_MCI_OVRE  \
 				| AT91_MCI_UNRE)
 
-static inline u32 atmel_mci_readl(struct atmel_mci_host *host, u32 offset)
+static inline u32 atmel_mci_readl(struct atmel_mci *host, u32 offset)
 {
 	return readl(host->base + offset);
 }
 
-static inline void atmel_mci_writel(struct atmel_mci_host *host, u32 offset,
+static inline void atmel_mci_writel(struct atmel_mci *host, u32 offset,
 				    u32 value)
 {
 	writel(value, host->base + offset);
 }
 
-static void atmel_mci_reset(struct atmel_mci_host *host)
+static void atmel_mci_reset(struct atmel_mci *host)
 {
 	atmel_mci_writel(host, AT91_MCI_CR, AT91_MCI_SWRST | AT91_MCI_MCIDIS);
 	atmel_mci_writel(host, AT91_MCI_DTOR, 0x7f);
 	atmel_mci_writel(host, AT91_MCI_IDR, ~0UL);
 }
 
-static void atmel_set_clk_rate(struct atmel_mci_host *host,
+static void atmel_set_clk_rate(struct atmel_mci *host,
 			       unsigned int clk_ios)
 {
 	unsigned int divider;
@@ -91,7 +91,7 @@ static void atmel_set_clk_rate(struct atmel_mci_host *host,
 		| AT91_MCI_RDPROOF | AT91_MCI_WRPROOF);
 }
 
-static int atmel_poll_status(struct atmel_mci_host *host, u32 mask)
+static int atmel_poll_status(struct atmel_mci *host, u32 mask)
 {
 	u32 stat;
 	uint64_t start = get_time_ns();
@@ -109,7 +109,7 @@ static int atmel_poll_status(struct atmel_mci_host *host, u32 mask)
 	} while (1);
 }
 
-static int atmel_pull(struct atmel_mci_host *host, void *_buf, int bytes)
+static int atmel_pull(struct atmel_mci *host, void *_buf, int bytes)
 {
 	unsigned int stat;
 	u32 *buf = _buf;
@@ -130,7 +130,7 @@ static int atmel_pull(struct atmel_mci_host *host, void *_buf, int bytes)
 }
 
 #ifdef CONFIG_MCI_WRITE
-static int atmel_push(struct atmel_mci_host *host, const void *_buf, int bytes)
+static int atmel_push(struct atmel_mci *host, const void *_buf, int bytes)
 {
 	unsigned int stat;
 	const u32 *buf = _buf;
@@ -155,7 +155,7 @@ static int atmel_push(struct atmel_mci_host *host, const void *_buf, int bytes)
 }
 #endif /* CONFIG_MCI_WRITE */
 
-static int atmel_transfer_data(struct atmel_mci_host *host)
+static int atmel_transfer_data(struct atmel_mci *host)
 {
 	struct mci_data *data = host->data;
 	int stat;
@@ -189,13 +189,13 @@ static int atmel_transfer_data(struct atmel_mci_host *host)
 	return 0;
 }
 
-static void atmel_finish_request(struct atmel_mci_host *host)
+static void atmel_finish_request(struct atmel_mci *host)
 {
 	host->cmd = NULL;
 	host->data = NULL;
 }
 
-static int atmel_finish_data(struct atmel_mci_host *host, unsigned int stat)
+static int atmel_finish_data(struct atmel_mci *host, unsigned int stat)
 {
 	int data_error = 0;
 
@@ -214,7 +214,7 @@ static int atmel_finish_data(struct atmel_mci_host *host, unsigned int stat)
 	return data_error;
 }
 
-static void atmel_setup_data(struct atmel_mci_host *host, struct mci_data *data)
+static void atmel_setup_data(struct atmel_mci *host, struct mci_data *data)
 {
 	unsigned int nob = data->blocks;
 	unsigned int blksz = data->blocksize;
@@ -234,7 +234,7 @@ static void atmel_setup_data(struct atmel_mci_host *host, struct mci_data *data)
 	host->datasize = datasize;
 }
 
-static int atmel_read_response(struct atmel_mci_host *host, unsigned int stat)
+static int atmel_read_response(struct atmel_mci *host, unsigned int stat)
 {
 	struct mci_cmd *cmd = host->cmd;
 	int i;
@@ -263,7 +263,7 @@ static int atmel_read_response(struct atmel_mci_host *host, unsigned int stat)
 	return 0;
 }
 
-static int atmel_cmd_done(struct atmel_mci_host *host, unsigned int stat)
+static int atmel_cmd_done(struct atmel_mci *host, unsigned int stat)
 {
 	int datastat;
 	int ret;
@@ -286,7 +286,7 @@ static int atmel_cmd_done(struct atmel_mci_host *host, unsigned int stat)
 	return ret;
 }
 
-static int atmel_start_cmd(struct atmel_mci_host *host, struct mci_cmd *cmd,
+static int atmel_start_cmd(struct atmel_mci *host, struct mci_cmd *cmd,
 			   unsigned int cmdat)
 {
 	unsigned flags = 0;
@@ -335,7 +335,7 @@ static int atmel_start_cmd(struct atmel_mci_host *host, struct mci_cmd *cmd,
 static int mci_reset(struct mci_host *mci, struct device_d *mci_dev)
 {
 	int ret;
-	struct atmel_mci_host *host = to_mci_host(mci);
+	struct atmel_mci *host = to_mci_host(mci);
 	struct atmel_mci_platform_data *pd = host->hw_dev->platform_data;
 
 	ret = gpio_get_value(pd->detect_pin);
@@ -353,7 +353,7 @@ static int mci_reset(struct mci_host *mci, struct device_d *mci_dev)
 /** change host interface settings */
 static void mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
 {
-	struct atmel_mci_host *host = to_mci_host(mci);
+	struct atmel_mci *host = to_mci_host(mci);
 
 	dev_dbg(host->hw_dev, "atmel_mci_set_ios: bus_width=%d clk=%d\n",
 		ios->bus_width, ios->clock);
@@ -388,7 +388,7 @@ static void mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
 /** handle a command */
 static int mci_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
 {
-	struct atmel_mci_host *host = to_mci_host(mci);
+	struct atmel_mci *host = to_mci_host(mci);
 	u32 stat, cmdat = 0;
 	int ret;
 
@@ -417,7 +417,7 @@ static int mci_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_dat
 #ifdef CONFIG_MCI_INFO
 static void mci_info(struct device_d *mci_dev)
 {
-	struct atmel_mci_host *host = mci_dev->priv;
+	struct atmel_mci *host = mci_dev->priv;
 	struct atmel_mci_platform_data *pd = host->hw_dev->platform_data;
 
 	printf("  Bus data width: %d bit\n", host->mci.bus_width);
@@ -442,7 +442,7 @@ static void mci_info(struct device_d *mci_dev)
 static int mci_probe(struct device_d *hw_dev)
 {
 	unsigned long clk_rate;
-	struct atmel_mci_host *host;
+	struct atmel_mci *host;
 	struct atmel_mci_platform_data *pd = hw_dev->platform_data;
 
 	if (!pd) {
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#2 lore raw

PATCH 2/14 atmel_mci: rename atmel_mci_readl/writel to atmci_readl/writel

to be consistent with the kernel
This also reduce the ligne length

---
 drivers/mci/atmel_mci.c |   43 +++++++++++++++++++++----------------------
 1 file changed, 21 insertions(+), 22 deletions(-)
drivers/mci/atmel_mci.c +21 -22
index d6ac458..ca5cd5c 100644
@@ -51,12 +51,12 @@ struct atmel_mci {
 				| AT91_MCI_OVRE  \
 				| AT91_MCI_UNRE)
 
-static inline u32 atmel_mci_readl(struct atmel_mci *host, u32 offset)
+static inline u32 atmci_readl(struct atmel_mci *host, u32 offset)
 {
 	return readl(host->base + offset);
 }
 
-static inline void atmel_mci_writel(struct atmel_mci *host, u32 offset,
+static inline void atmci_writel(struct atmel_mci *host, u32 offset,
 				    u32 value)
 {
 	writel(value, host->base + offset);
@@ -64,9 +64,9 @@ static inline void atmel_mci_writel(struct atmel_mci *host, u32 offset,
 
 static void atmel_mci_reset(struct atmel_mci *host)
 {
-	atmel_mci_writel(host, AT91_MCI_CR, AT91_MCI_SWRST | AT91_MCI_MCIDIS);
-	atmel_mci_writel(host, AT91_MCI_DTOR, 0x7f);
-	atmel_mci_writel(host, AT91_MCI_IDR, ~0UL);
+	atmci_writel(host, AT91_MCI_CR, AT91_MCI_SWRST | AT91_MCI_MCIDIS);
+	atmci_writel(host, AT91_MCI_DTOR, 0x7f);
+	atmci_writel(host, AT91_MCI_IDR, ~0UL);
 }
 
 static void atmel_set_clk_rate(struct atmel_mci *host,
@@ -87,7 +87,7 @@ static void atmel_set_clk_rate(struct atmel_mci *host,
 	dev_dbg(host->hw_dev, "atmel_set_clk_rate: clkIn=%d clkIos=%d divider=%d\n",
 		clk_in, clk_ios, divider);
 
-	atmel_mci_writel(host, AT91_MCI_MR, (AT91_MCI_CLKDIV & divider)
+	atmci_writel(host, AT91_MCI_MR, (AT91_MCI_CLKDIV & divider)
 		| AT91_MCI_RDPROOF | AT91_MCI_WRPROOF);
 }
 
@@ -97,7 +97,7 @@ static int atmel_poll_status(struct atmel_mci *host, u32 mask)
 	uint64_t start = get_time_ns();
 
 	do {
-		stat = atmel_mci_readl(host, AT91_MCI_SR);
+		stat = atmci_readl(host, AT91_MCI_SR);
 		if (stat & STATUS_ERROR_MASK)
 			return stat;
 		if (is_timeout(start, SECOND)) {
@@ -119,7 +119,7 @@ static int atmel_pull(struct atmel_mci *host, void *_buf, int bytes)
 		if (stat)
 			return stat;
 
-		*buf++ = atmel_mci_readl(host, AT91_MCI_RDR);
+		*buf++ = atmci_readl(host, AT91_MCI_RDR);
 		bytes -= 4;
 	}
 
@@ -140,7 +140,7 @@ static int atmel_push(struct atmel_mci *host, const void *_buf, int bytes)
 		if (stat)
 			return stat;
 
-		atmel_mci_writel(host, AT91_MCI_TDR, *buf++);
+		atmci_writel(host, AT91_MCI_TDR, *buf++);
 		bytes -= 4;
 	}
 
@@ -228,7 +228,7 @@ static void atmel_setup_data(struct atmel_mci *host, struct mci_data *data)
 	dev_dbg(host->hw_dev, "atmel_setup_data: nob=%d blksz=%d\n",
 		nob, blksz);
 
-	atmel_mci_writel(host, AT91_MCI_BLKR, AT91_MCI_BLKR_BCNT(nob)
+	atmci_writel(host, AT91_MCI_BLKR, AT91_MCI_BLKR_BCNT(nob)
 		| AT91_MCI_BLKR_BLKLEN(blksz));
 
 	host->datasize = datasize;
@@ -254,9 +254,9 @@ static int atmel_read_response(struct atmel_mci *host, unsigned int stat)
 	if (cmd->resp_type & MMC_RSP_PRESENT) {
 		if (cmd->resp_type & MMC_RSP_136) {
 			for (i = 0; i < 4; i++)
-				resp[i] = atmel_mci_readl(host, AT91_MCI_RSPR(0));
+				resp[i] = atmci_readl(host, AT91_MCI_RSPR(0));
 		} else {
-			resp[0] = atmel_mci_readl(host, AT91_MCI_RSPR(0));
+			resp[0] = atmci_readl(host, AT91_MCI_RSPR(0));
 		}
 	}
 
@@ -295,7 +295,7 @@ static int atmel_start_cmd(struct atmel_mci *host, struct mci_cmd *cmd,
 	if (host->cmd != NULL)
 		dev_err(host->hw_dev, "error!\n");
 
-	if ((atmel_mci_readl(host, AT91_MCI_SR) & AT91_MCI_CMDRDY) == 0) {
+	if ((atmci_readl(host, AT91_MCI_SR) & AT91_MCI_CMDRDY) == 0) {
 		dev_err(host->hw_dev, "mci not ready!\n");
 		return -EBUSY;
 	}
@@ -325,8 +325,8 @@ static int atmel_start_cmd(struct atmel_mci *host, struct mci_cmd *cmd,
 	cmdval |= AT91_MCI_RSPTYP & flags;
 	cmdval |= cmdat & ~(AT91_MCI_CMDNB | AT91_MCI_RSPTYP);
 
-	atmel_mci_writel(host, AT91_MCI_ARGR, cmd->cmdarg);
-	atmel_mci_writel(host, AT91_MCI_CMDR, cmdval);
+	atmci_writel(host, AT91_MCI_ARGR, cmd->cmdarg);
+	atmci_writel(host, AT91_MCI_CMDR, cmdval);
 
 	return 0;
 }
@@ -360,26 +360,25 @@ static void mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
 
 	switch (ios->bus_width) {
 	case MMC_BUS_WIDTH_4:
-		atmel_mci_writel(host, AT91_MCI_SDCR, AT91_MCI_SDCBUS_4BIT);
+		atmci_writel(host, AT91_MCI_SDCR, AT91_MCI_SDCBUS_4BIT);
 		break;
 	case MMC_BUS_WIDTH_8:
-		atmel_mci_writel(host, AT91_MCI_SDCR, AT91_MCI_SDCBUS_8BIT);
+		atmci_writel(host, AT91_MCI_SDCR, AT91_MCI_SDCBUS_8BIT);
 		break;
 	case MMC_BUS_WIDTH_1:
-		atmel_mci_writel(host, AT91_MCI_SDCR, AT91_MCI_SDCBUS_1BIT);
+		atmci_writel(host, AT91_MCI_SDCR, AT91_MCI_SDCBUS_1BIT);
 		break;
 	default:
 		return;
 	}
-	atmel_mci_writel(host, AT91_MCI_SDCR, atmel_mci_readl(host, AT91_MCI_SDCR)
+	atmci_writel(host, AT91_MCI_SDCR, atmci_readl(host, AT91_MCI_SDCR)
 		| host->slot_b);
 
 	if (ios->clock) {
 		atmel_set_clk_rate(host, ios->clock);
-		atmel_mci_writel(host, AT91_MCI_CR, AT91_MCI_MCIEN
-		);
+		atmci_writel(host, AT91_MCI_CR, AT91_MCI_MCIEN);
 	} else {
-		atmel_mci_writel(host, AT91_MCI_CR, AT91_MCI_MCIDIS);
+		atmci_writel(host, AT91_MCI_CR, AT91_MCI_MCIDIS);
 	}
 
 	return;
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#3 lore raw

PATCH 3/14 atmel_mci: rename all function to start with atmci

In reply to Jean-Christophe PLAGNIOL-VILLARD

to be consistent and have a unique naming convention be in sync with the kernel too

---
 drivers/mci/atmel_mci.c |   93 +++++++++++++++++++++++------------------------
 1 file changed, 46 insertions(+), 47 deletions(-)
drivers/mci/atmel_mci.c +46 -47
index ca5cd5c..c8af76a 100644
@@ -62,14 +62,14 @@ static inline void atmci_writel(struct atmel_mci *host, u32 offset,
 	writel(value, host->base + offset);
 }
 
-static void atmel_mci_reset(struct atmel_mci *host)
+static void atmci_ip_reset(struct atmel_mci *host)
 {
 	atmci_writel(host, AT91_MCI_CR, AT91_MCI_SWRST | AT91_MCI_MCIDIS);
 	atmci_writel(host, AT91_MCI_DTOR, 0x7f);
 	atmci_writel(host, AT91_MCI_IDR, ~0UL);
 }
 
-static void atmel_set_clk_rate(struct atmel_mci *host,
+static void atmci_set_clk_rate(struct atmel_mci *host,
 			       unsigned int clk_ios)
 {
 	unsigned int divider;
@@ -91,7 +91,7 @@ static void atmel_set_clk_rate(struct atmel_mci *host,
 		| AT91_MCI_RDPROOF | AT91_MCI_WRPROOF);
 }
 
-static int atmel_poll_status(struct atmel_mci *host, u32 mask)
+static int atmci_poll_status(struct atmel_mci *host, u32 mask)
 {
 	u32 stat;
 	uint64_t start = get_time_ns();
@@ -109,13 +109,13 @@ static int atmel_poll_status(struct atmel_mci *host, u32 mask)
 	} while (1);
 }
 
-static int atmel_pull(struct atmel_mci *host, void *_buf, int bytes)
+static int atmci_pull(struct atmel_mci *host, void *_buf, int bytes)
 {
 	unsigned int stat;
 	u32 *buf = _buf;
 
 	while (bytes > 3) {
-		stat = atmel_poll_status(host, AT91_MCI_RXRDY);
+		stat = atmci_poll_status(host, AT91_MCI_RXRDY);
 		if (stat)
 			return stat;
 
@@ -130,13 +130,13 @@ static int atmel_pull(struct atmel_mci *host, void *_buf, int bytes)
 }
 
 #ifdef CONFIG_MCI_WRITE
-static int atmel_push(struct atmel_mci *host, const void *_buf, int bytes)
+static int atmci_push(struct atmel_mci *host, const void *_buf, int bytes)
 {
 	unsigned int stat;
 	const u32 *buf = _buf;
 
 	while (bytes > 3) {
-		stat = atmel_poll_status(host, AT91_MCI_TXRDY);
+		stat = atmci_poll_status(host, AT91_MCI_TXRDY);
 		if (stat)
 			return stat;
 
@@ -144,7 +144,7 @@ static int atmel_push(struct atmel_mci *host, const void *_buf, int bytes)
 		bytes -= 4;
 	}
 
-	stat = atmel_poll_status(host, AT91_MCI_TXRDY);
+	stat = atmci_poll_status(host, AT91_MCI_TXRDY);
 	if (stat)
 		return stat;
 
@@ -155,7 +155,7 @@ static int atmel_push(struct atmel_mci *host, const void *_buf, int bytes)
 }
 #endif /* CONFIG_MCI_WRITE */
 
-static int atmel_transfer_data(struct atmel_mci *host)
+static int atmci_transfer_data(struct atmel_mci *host)
 {
 	struct mci_data *data = host->data;
 	int stat;
@@ -165,23 +165,23 @@ static int atmel_transfer_data(struct atmel_mci *host)
 	host->datasize = 0;
 
 	if (data->flags & MMC_DATA_READ) {
-		stat = atmel_pull(host, data->dest, length);
+		stat = atmci_pull(host, data->dest, length);
 		if (stat)
 			return stat;
 
-		stat = atmel_poll_status(host, AT91_MCI_NOTBUSY);
+		stat = atmci_poll_status(host, AT91_MCI_NOTBUSY);
 		if (stat)
 			return stat;
 
 		host->datasize += length;
 	} else {
 #ifdef CONFIG_MCI_WRITE
-		stat = atmel_push(host, (const void *)(data->src), length);
+		stat = atmci_push(host, (const void *)(data->src), length);
 		if (stat)
 			return stat;
 
 		host->datasize += length;
-		stat = atmel_poll_status(host, AT91_MCI_NOTBUSY);
+		stat = atmci_poll_status(host, AT91_MCI_NOTBUSY);
 		if (stat)
 			return stat;
 #endif /* CONFIG_MCI_WRITE */
@@ -189,13 +189,13 @@ static int atmel_transfer_data(struct atmel_mci *host)
 	return 0;
 }
 
-static void atmel_finish_request(struct atmel_mci *host)
+static void atmci_finish_request(struct atmel_mci *host)
 {
 	host->cmd = NULL;
 	host->data = NULL;
 }
 
-static int atmel_finish_data(struct atmel_mci *host, unsigned int stat)
+static int atmci_finish_data(struct atmel_mci *host, unsigned int stat)
 {
 	int data_error = 0;
 
@@ -214,7 +214,7 @@ static int atmel_finish_data(struct atmel_mci *host, unsigned int stat)
 	return data_error;
 }
 
-static void atmel_setup_data(struct atmel_mci *host, struct mci_data *data)
+static void atmci_setup_data(struct atmel_mci *host, struct mci_data *data)
 {
 	unsigned int nob = data->blocks;
 	unsigned int blksz = data->blocksize;
@@ -234,7 +234,7 @@ static void atmel_setup_data(struct atmel_mci *host, struct mci_data *data)
 	host->datasize = datasize;
 }
 
-static int atmel_read_response(struct atmel_mci *host, unsigned int stat)
+static int atmci_read_response(struct atmel_mci *host, unsigned int stat)
 {
 	struct mci_cmd *cmd = host->cmd;
 	int i;
@@ -263,30 +263,30 @@ static int atmel_read_response(struct atmel_mci *host, unsigned int stat)
 	return 0;
 }
 
-static int atmel_cmd_done(struct atmel_mci *host, unsigned int stat)
+static int atmci_cmd_done(struct atmel_mci *host, unsigned int stat)
 {
 	int datastat;
 	int ret;
 
-	ret = atmel_read_response(host, stat);
+	ret = atmci_read_response(host, stat);
 
 	if (ret) {
-		atmel_finish_request(host);
+		atmci_finish_request(host);
 		return ret;
 	}
 
 	if (!host->data) {
-		atmel_finish_request(host);
+		atmci_finish_request(host);
 		return 0;
 	}
 
-	datastat = atmel_transfer_data(host);
-	ret = atmel_finish_data(host, datastat);
-	atmel_finish_request(host);
+	datastat = atmci_transfer_data(host);
+	ret = atmci_finish_data(host, datastat);
+	atmci_finish_request(host);
 	return ret;
 }
 
-static int atmel_start_cmd(struct atmel_mci *host, struct mci_cmd *cmd,
+static int atmci_start_cmd(struct atmel_mci *host, struct mci_cmd *cmd,
 			   unsigned int cmdat)
 {
 	unsigned flags = 0;
@@ -332,7 +332,7 @@ static int atmel_start_cmd(struct atmel_mci *host, struct mci_cmd *cmd,
 }
 
 /** init the host interface */
-static int mci_reset(struct mci_host *mci, struct device_d *mci_dev)
+static int atmci_reset(struct mci_host *mci, struct device_d *mci_dev)
 {
 	int ret;
 	struct atmel_mci *host = to_mci_host(mci);
@@ -345,13 +345,13 @@ static int mci_reset(struct mci_host *mci, struct device_d *mci_dev)
 		return -ENODEV;
 
 	clk_enable(host->clk);
-	atmel_mci_reset(host);
+	atmci_ip_reset(host);
 
 	return 0;
 }
 
 /** change host interface settings */
-static void mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
+static void atmci_set_ios(struct mci_host *mci, struct mci_ios *ios)
 {
 	struct atmel_mci *host = to_mci_host(mci);
 
@@ -375,7 +375,7 @@ static void mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
 		| host->slot_b);
 
 	if (ios->clock) {
-		atmel_set_clk_rate(host, ios->clock);
+		atmci_set_clk_rate(host, ios->clock);
 		atmci_writel(host, AT91_MCI_CR, AT91_MCI_MCIEN);
 	} else {
 		atmci_writel(host, AT91_MCI_CR, AT91_MCI_MCIDIS);
@@ -385,7 +385,7 @@ static void mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
 }
 
 /** handle a command */
-static int mci_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
+static int atmci_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
 {
 	struct atmel_mci *host = to_mci_host(mci);
 	u32 stat, cmdat = 0;
@@ -395,7 +395,7 @@ static int mci_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_dat
 		cmdat |= AT91_MCI_MAXLAT;
 
 	if (data) {
-		atmel_setup_data(host, data);
+		atmci_setup_data(host, data);
 
 		cmdat |= AT91_MCI_TRCMD_START | AT91_MCI_TRTYP_MULTIPLE;
 
@@ -403,18 +403,18 @@ static int mci_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_dat
 			cmdat |= AT91_MCI_TRDIR_RX;
 	}
 
-	ret = atmel_start_cmd(host, cmd, cmdat);
+	ret = atmci_start_cmd(host, cmd, cmdat);
 	if (ret) {
-		atmel_finish_request(host);
+		atmci_finish_request(host);
 		return ret;
 	}
 
-	stat = atmel_poll_status(host, AT91_MCI_CMDRDY);
-	return atmel_cmd_done(host, stat);
+	stat = atmci_poll_status(host, AT91_MCI_CMDRDY);
+	return atmci_cmd_done(host, stat);
 }
 
 #ifdef CONFIG_MCI_INFO
-static void mci_info(struct device_d *mci_dev)
+static void atmci_info(struct device_d *mci_dev)
 {
 	struct atmel_mci *host = mci_dev->priv;
 	struct atmel_mci_platform_data *pd = host->hw_dev->platform_data;
@@ -438,7 +438,7 @@ static void mci_info(struct device_d *mci_dev)
 }
 #endif /* CONFIG_MCI_INFO */
 
-static int mci_probe(struct device_d *hw_dev)
+static int atmci_probe(struct device_d *hw_dev)
 {
 	unsigned long clk_rate;
 	struct atmel_mci *host;
@@ -450,9 +450,9 @@ static int mci_probe(struct device_d *hw_dev)
 	}
 
 	host = xzalloc(sizeof(*host));
-	host->mci.send_cmd = mci_request;
-	host->mci.set_ios = mci_set_ios;
-	host->mci.init = mci_reset;
+	host->mci.send_cmd = atmci_request;
+	host->mci.set_ios = atmci_set_ios;
+	host->mci.init = atmci_reset;
 	host->mci.hw_dev = hw_dev;
 
 	host->mci.host_caps = pd->host_caps;
@@ -483,18 +483,17 @@ static int mci_probe(struct device_d *hw_dev)
 	return 0;
 }
 
-static struct driver_d atmel_mci_driver = {
+static struct driver_d atmci_driver = {
 	.name	= "atmel_mci",
-	.probe	= mci_probe,
+	.probe	= atmci_probe,
 #ifdef CONFIG_MCI_INFO
-	.info	= mci_info,
+	.info	= atmci_info,
 #endif
 };
 
-static int atmel_mci_init_driver(void)
+static int atmci_init_driver(void)
 {
-	platform_driver_register(&atmel_mci_driver);
+	platform_driver_register(&atmci_driver);
 	return 0;
 }
-
-device_initcall(atmel_mci_init_driver);
+device_initcall(atmci_init_driver);
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#4 lore raw

PATCH 4/14 atmel_mci: use linux regs define

In reply to Jean-Christophe PLAGNIOL-VILLARD

to simplify sync and share code

---
 drivers/mci/at91_mci.h       |  121 ------------------------------
 drivers/mci/atmel-mci-regs.h |  166 ++++++++++++++++++++++++++++++++++++++++++
 drivers/mci/atmel_mci.c      |  121 ++++++++++++++----------------
 3 files changed, 221 insertions(+), 187 deletions(-)
 delete mode 100644 drivers/mci/at91_mci.h
 create mode 100644 drivers/mci/atmel-mci-regs.h
drivers/mci/at91_mci.h deleted +0 -121
deleted file mode 100644
index 4025aeb..0000000
@@ -1,121 +0,0 @@
-/*
- * [origin: Linux kernel arch/arm/mach-at91/include/mach/at91_mci.h]
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * MultiMedia Card Interface (MCI) registers.
- * Based on AT91RM9200 datasheet revision F.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef AT91_MCI_H
-#define AT91_MCI_H
-
-#define AT91_MCI_CR		0x00		/* Control Register */
-#define		AT91_MCI_MCIEN		(1 <<  0)	/* Multi-Media Interface Enable */
-#define		AT91_MCI_MCIDIS		(1 <<  1)	/* Multi-Media Interface Disable */
-#define		AT91_MCI_PWSEN		(1 <<  2)	/* Power Save Mode Enable */
-#define		AT91_MCI_PWSDIS		(1 <<  3)	/* Power Save Mode Disable */
-#define		AT91_MCI_SWRST		(1 <<  7)	/* Software Reset */
-
-#define AT91_MCI_MR		0x04		/* Mode Register */
-#define		AT91_MCI_CLKDIV		(0xff  <<  0)	/* Clock Divider */
-#define		AT91_MCI_PWSDIV		(7     <<  8)	/* Power Saving Divider */
-#define		AT91_MCI_RDPROOF	(1     << 11)	/* Read Proof Enable [SAM926[03] only] */
-#define		AT91_MCI_WRPROOF	(1     << 12)	/* Write Proof Enable [SAM926[03] only] */
-#define		AT91_MCI_PDCFBYTE	(1     << 13)	/* PDC Force Byte Transfer [SAM926[03] only] */
-#define		AT91_MCI_PDCPADV	(1     << 14)	/* PDC Padding Value */
-#define		AT91_MCI_PDCMODE	(1     << 15)	/* PDC-orientated Mode */
-#define		AT91_MCI_BLKLEN		(0xfff << 18)	/* Data Block Length */
-
-#define AT91_MCI_DTOR		0x08		/* Data Timeout Register */
-#define		AT91_MCI_DTOCYC		(0xf << 0)	/* Data Timeout Cycle Number */
-#define		AT91_MCI_DTOMUL		(7   << 4)	/* Data Timeout Multiplier */
-#define		AT91_MCI_DTOMUL_1		(0 <<  4)
-#define		AT91_MCI_DTOMUL_16		(1 <<  4)
-#define		AT91_MCI_DTOMUL_128		(2 <<  4)
-#define		AT91_MCI_DTOMUL_256		(3 <<  4)
-#define		AT91_MCI_DTOMUL_1K		(4 <<  4)
-#define		AT91_MCI_DTOMUL_4K		(5 <<  4)
-#define		AT91_MCI_DTOMUL_64K		(6 <<  4)
-#define		AT91_MCI_DTOMUL_1M		(7 <<  4)
-
-#define AT91_MCI_SDCR		0x0c		/* SD Card Register */
-#define		AT91_MCI_SDCSEL		(3 << 0)	/* SD Card Selector */
-#define		AT91_MCI_SDCBUS		(3 << 6)	/* 1-bit, 4-bit, or 8-bit bus */
-#define			AT91_MCI_SDCBUS_1BIT	(0 << 6)	/* 1-bit bus */
-#define			AT91_MCI_SDCBUS_4BIT	(2 << 6)	/* 4-bit bus */
-#define			AT91_MCI_SDCBUS_8BIT	(3 << 6)	/* 8-bit bus */
-
-#define AT91_MCI_ARGR		0x10		/* Argument Register */
-
-#define AT91_MCI_CMDR		0x14		/* Command Register */
-#define		AT91_MCI_CMDNB		(0x3f << 0)	/* Command Number */
-#define		AT91_MCI_RSPTYP		(3    << 6)	/* Response Type */
-#define			AT91_MCI_RSPTYP_NONE	(0 <<  6)
-#define			AT91_MCI_RSPTYP_48	(1 <<  6)
-#define			AT91_MCI_RSPTYP_136	(2 <<  6)
-#define			AT91_MCI_RSPTYP_R1B	(3 <<  6)
-#define		AT91_MCI_SPCMD		(7    << 8)	/* Special Command */
-#define			AT91_MCI_SPCMD_NONE	(0 <<  8)
-#define			AT91_MCI_SPCMD_INIT	(1 <<  8)
-#define			AT91_MCI_SPCMD_SYNC	(2 <<  8)
-#define			AT91_MCI_SPCMD_ICMD	(4 <<  8)
-#define			AT91_MCI_SPCMD_IRESP	(5 <<  8)
-#define		AT91_MCI_OPDCMD		(1 << 11)	/* Open Drain Command */
-#define		AT91_MCI_MAXLAT		(1 << 12)	/* Max Latency for Command to Response */
-#define		AT91_MCI_TRCMD		(3 << 16)	/* Transfer Command */
-#define			AT91_MCI_TRCMD_NONE	(0 << 16)
-#define			AT91_MCI_TRCMD_START	(1 << 16)
-#define			AT91_MCI_TRCMD_STOP	(2 << 16)
-#define		AT91_MCI_TRDIR		(1 << 18)	/* Transfer Direction */
-#define			AT91_MCI_TRDIR_RX	(1 << 18)	/* Read Transfer Direction */
-#define			AT91_MCI_TRDIR_TX	(0 << 18)	/* Write Transfer Direction */
-#define		AT91_MCI_TRTYP		(3 << 19)	/* Transfer Type */
-#define			AT91_MCI_TRTYP_BLOCK	(0 << 19)
-#define			AT91_MCI_TRTYP_MULTIPLE	(1 << 19)
-#define			AT91_MCI_TRTYP_STREAM	(2 << 19)
-#define			AT91_MCI_TRTYP_SDIO_BYTE	(4 << 19)
-#define			AT91_MCI_TRTYP_SDIO_BLOCK	(5 << 19)
-
-#define AT91_MCI_BLKR		0x18		/* Block Register */
-#define		AT91_MCI_BLKR_BCNT(n)	((0xffff & (n)) << 0)	/* Block count */
-#define		AT91_MCI_BLKR_BLKLEN(n)	((0xffff & (n)) << 16)	/* Block length */
-
-#define AT91_MCI_RSPR(n)	(0x20 + ((n) * 4))	/* Response Registers 0-3 */
-#define AT91_MCI_RDR		0x30		/* Receive Data Register */
-#define AT91_MCI_TDR		0x34		/* Transmit Data Register */
-
-#define AT91_MCI_SR		0x40		/* Status Register */
-#define		AT91_MCI_CMDRDY		(1 <<  0)	/* Command Ready */
-#define		AT91_MCI_RXRDY		(1 <<  1)	/* Receiver Ready */
-#define		AT91_MCI_TXRDY		(1 <<  2)	/* Transmit Ready */
-#define		AT91_MCI_BLKE		(1 <<  3)	/* Data Block Ended */
-#define		AT91_MCI_DTIP		(1 <<  4)	/* Data Transfer in Progress */
-#define		AT91_MCI_NOTBUSY	(1 <<  5)	/* Data Not Busy */
-#define		AT91_MCI_ENDRX		(1 <<  6)	/* End of RX Buffer */
-#define		AT91_MCI_ENDTX		(1 <<  7)	/* End fo TX Buffer */
-#define		AT91_MCI_SDIOIRQA	(1 <<  8)	/* SDIO Interrupt for Slot A */
-#define		AT91_MCI_SDIOIRQB	(1 <<  9)	/* SDIO Interrupt for Slot B */
-#define		AT91_MCI_RXBUFF		(1 << 14)	/* RX Buffer Full */
-#define		AT91_MCI_TXBUFE		(1 << 15)	/* TX Buffer Empty */
-#define		AT91_MCI_RINDE		(1 << 16)	/* Response Index Error */
-#define		AT91_MCI_RDIRE		(1 << 17)	/* Response Direction Error */
-#define		AT91_MCI_RCRCE		(1 << 18)	/* Response CRC Error */
-#define		AT91_MCI_RENDE		(1 << 19)	/* Response End Bit Error */
-#define		AT91_MCI_RTOE		(1 << 20)	/* Response Time-out Error */
-#define		AT91_MCI_DCRCE		(1 << 21)	/* Data CRC Error */
-#define		AT91_MCI_DTOE		(1 << 22)	/* Data Time-out Error */
-#define		AT91_MCI_OVRE		(1 << 30)	/* Overrun */
-#define		AT91_MCI_UNRE		(1 << 31)	/* Underrun */
-
-#define AT91_MCI_IER		0x44		/* Interrupt Enable Register */
-#define AT91_MCI_IDR		0x48		/* Interrupt Disable Register */
-#define AT91_MCI_IMR		0x4c		/* Interrupt Mask Register */
-
-#endif
drivers/mci/atmel-mci-regs.h new file +166 -0

166 lines not on this page · raw message

drivers/mci/atmel_mci.c +55 -66

291 lines not on this page · raw message

Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#5 lore raw

PATCH 5/14 atmel_mci: detect IP version

In reply to Jean-Christophe PLAGNIOL-VILLARD
---
 drivers/mci/atmel_mci.c |   32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)
drivers/mci/atmel_mci.c +32 -0
index 21c314c..b9b0668 100644
@@ -37,6 +37,7 @@ struct atmel_mci {
 	struct mci_cmd		*cmd;
 	struct mci_data		*data;
 	unsigned		slot_b;
+	int			version;
 };
 
 #define to_mci_host(mci)	container_of(mci, struct atmel_mci, mci)
@@ -426,6 +427,34 @@ static void atmci_info(struct device_d *mci_dev)
 
 }
 #endif /* CONFIG_MCI_INFO */
+/*
+ * HSMCI (High Speed MCI) module is not fully compatible with MCI module.
+ * HSMCI provides DMA support and a new config register but no more supports
+ * PDC.
+ */
+static void atmci_get_cap(struct atmel_mci *host)
+{
+	unsigned int version;
+
+	version = atmci_readl(host, ATMCI_VERSION) & 0x00000fff;
+	host->version = version;
+
+	dev_info(host->hw_dev, "version: 0x%x\n", version);
+
+	switch (version & 0xf00) {
+	case 0x500:
+	case 0x400:
+	case 0x300:
+	case 0x200:
+	case 0x100:
+	case 0x0:
+		break;
+	default:
+		dev_warn(host->hw_dev,
+				"Unmanaged mci version, set minimum capabilities\n");
+		break;
+	}
+}
 
 static int atmci_probe(struct device_d *hw_dev)
 {
@@ -438,6 +467,7 @@ static int atmci_probe(struct device_d *hw_dev)
 		return -EINVAL;
 	}
 
+
 	host = xzalloc(sizeof(*host));
 	host->mci.send_cmd = atmci_request;
 	host->mci.set_ios = atmci_set_ios;
@@ -467,6 +497,8 @@ static int atmci_probe(struct device_d *hw_dev)
 	host->mci.f_min = clk_rate >> 9;
 	host->mci.f_max = clk_rate >> 1;
 
+	atmci_get_cap(host);
+
 	mci_register(&host->mci);
 
 	return 0;
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#6 lore raw

PATCH 6/14 atmel_mci: version 0x5xx of the IP have a different clk div

In reply to Jean-Christophe PLAGNIOL-VILLARD

so detect and support it

---
 drivers/mci/atmel_mci.c |   65 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 47 insertions(+), 18 deletions(-)
drivers/mci/atmel_mci.c +47 -18
index b9b0668..72d92dc 100644
@@ -27,6 +27,10 @@
 
 #include "atmel-mci-regs.h"
 
+struct atmel_mci_caps {
+	bool	has_odd_clk_div;
+};
+
 struct atmel_mci {
 	struct mci_host		mci;
 	void  __iomem		*regs;
@@ -38,6 +42,10 @@ struct atmel_mci {
 	struct mci_data		*data;
 	unsigned		slot_b;
 	int			version;
+	struct atmel_mci_caps	caps;
+
+	unsigned long		bus_hz;
+	u32			mode_reg;
 };
 
 #define to_mci_host(mci)	container_of(mci, struct atmel_mci, mci)
@@ -60,25 +68,42 @@ static void atmci_ip_reset(struct atmel_mci *host)
 }
 
 static void atmci_set_clk_rate(struct atmel_mci *host,
-			       unsigned int clk_ios)
+			       unsigned int clock_min)
 {
-	unsigned int divider;
-	unsigned int clk_in = clk_get_rate(host->clk);
+	unsigned int clkdiv;
 
-	if (clk_ios > 0) {
-		divider = (clk_in / clk_ios) / 2;
-		if (divider > 0)
-			divider -= 1;
+	if (!host->mode_reg) {
+		clk_enable(host->clk);
+		atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
 	}
 
-	if (clk_ios == 0 || divider > 255)
-		divider = 255;
+	if (host->caps.has_odd_clk_div) {
+		clkdiv = DIV_ROUND_UP(host->bus_hz, clock_min) - 2;
+		if (clkdiv > 511) {
+			dev_dbg(host->hw_dev,
+			         "clock %u too slow; using %lu\n",
+			         clock_min, host->bus_hz / (511 + 2));
+			clkdiv = 511;
+		}
+		host->mode_reg = ATMCI_MR_CLKDIV(clkdiv >> 1)
+				 | ATMCI_MR_CLKODD(clkdiv & 1);
+	} else {
+		clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1;
+		if (clkdiv > 255) {
+			dev_dbg(host->hw_dev,
+				 "clock %u too slow; using %lu\n",
+				 clock_min, host->bus_hz / (2 * 256));
+			clkdiv = 255;
+		}
+		host->mode_reg = ATMCI_MR_CLKDIV(clkdiv);
+	}
+
+	dev_dbg(host->hw_dev, "atmel_set_clk_rate: clkIn=%ld clkIos=%d divider=%d\n",
+		host->bus_hz, clock_min, clkdiv);
 
-	dev_dbg(host->hw_dev, "atmel_set_clk_rate: clkIn=%d clkIos=%d divider=%d\n",
-		clk_in, clk_ios, divider);
+	host->mode_reg |= ATMCI_MR_RDPROOF | ATMCI_MR_WRPROOF;
 
-	atmci_writel(host, ATMCI_MR, ATMCI_MR_CLKDIV(divider)
-		| ATMCI_MR_RDPROOF | ATMCI_MR_WRPROOF);
+	atmci_writel(host, ATMCI_MR, host->mode_reg);
 }
 
 static int atmci_poll_status(struct atmel_mci *host, u32 mask)
@@ -366,9 +391,13 @@ static void atmci_set_ios(struct mci_host *mci, struct mci_ios *ios)
 
 	if (ios->clock) {
 		atmci_set_clk_rate(host, ios->clock);
-		atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
 	} else {
 		atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS);
+		if (host->mode_reg) {
+			atmci_readl(host, ATMCI_MR);
+			clk_disable(host->clk);
+		}
+		host->mode_reg = 0;
 	}
 
 	return;
@@ -443,6 +472,7 @@ static void atmci_get_cap(struct atmel_mci *host)
 
 	switch (version & 0xf00) {
 	case 0x500:
+		host->caps.has_odd_clk_div = 1;
 	case 0x400:
 	case 0x300:
 	case 0x200:
@@ -458,7 +488,6 @@ static void atmci_get_cap(struct atmel_mci *host)
 
 static int atmci_probe(struct device_d *hw_dev)
 {
-	unsigned long clk_rate;
 	struct atmel_mci *host;
 	struct atmel_mci_platform_data *pd = hw_dev->platform_data;
 
@@ -490,12 +519,12 @@ static int atmci_probe(struct device_d *hw_dev)
 		return PTR_ERR(host->clk);
 	}
 
-	clk_rate = clk_get_rate(host->clk);
+	host->bus_hz = clk_get_rate(host->clk);
 
 	host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 
-	host->mci.f_min = clk_rate >> 9;
-	host->mci.f_max = clk_rate >> 1;
+	host->mci.f_min = DIV_ROUND_UP(host->bus_hz, 512);
+	host->mci.f_max = host->bus_hz >> 1;
 
 	atmci_get_cap(host);
 
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#7 lore raw

PATCH 7/14 atmel_mci: fix host init

In reply to Jean-Christophe PLAGNIOL-VILLARD

disable interrupt and reset the IP at the probe
set timout at the host init

---
 drivers/mci/atmel_mci.c |   14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)
drivers/mci/atmel_mci.c +6 -8
index 72d92dc..d5fdd1d 100644
@@ -60,13 +60,6 @@ struct atmel_mci {
 				| ATMCI_OVRE  \
 				| ATMCI_UNRE)
 
-static void atmci_ip_reset(struct atmel_mci *host)
-{
-	atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST | ATMCI_CR_MCIDIS);
-	atmci_writel(host, ATMCI_DTOR, 0x7f);
-	atmci_writel(host, ATMCI_IDR, ~0UL);
-}
-
 static void atmci_set_clk_rate(struct atmel_mci *host,
 			       unsigned int clock_min)
 {
@@ -360,7 +353,8 @@ static int atmci_reset(struct mci_host *mci, struct device_d *mci_dev)
 		return -ENODEV;
 
 	clk_enable(host->clk);
-	atmci_ip_reset(host);
+	atmci_writel(host, ATMCI_DTOR, 0x7f);
+	clk_disable(host->clk);
 
 	return 0;
 }
@@ -519,7 +513,11 @@ static int atmci_probe(struct device_d *hw_dev)
 		return PTR_ERR(host->clk);
 	}
 
+	clk_enable(host->clk);
+	atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
+	atmci_writel(host, ATMCI_IDR, ~0UL);
 	host->bus_hz = clk_get_rate(host->clk);
+	clk_disable(host->clk);
 
 	host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#8 lore raw

PATCH 8/14 atmel_mci: rwproof is only needed since IP version 0x200

In reply to Jean-Christophe PLAGNIOL-VILLARD
---
 drivers/mci/atmel_mci.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/mci/atmel_mci.c +9 -1
index d5fdd1d..bf0adb0 100644
@@ -28,6 +28,7 @@
 #include "atmel-mci-regs.h"
 
 struct atmel_mci_caps {
+	bool    has_rwproof;
 	bool	has_odd_clk_div;
 };
 
@@ -94,7 +95,13 @@ static void atmci_set_clk_rate(struct atmel_mci *host,
 	dev_dbg(host->hw_dev, "atmel_set_clk_rate: clkIn=%ld clkIos=%d divider=%d\n",
 		host->bus_hz, clock_min, clkdiv);
 
-	host->mode_reg |= ATMCI_MR_RDPROOF | ATMCI_MR_WRPROOF;
+	/*
+	 * WRPROOF and RDPROOF prevent overruns/underruns by
+	 * stopping the clock when the FIFO is full/empty.
+	 * This state is not expected to last for long.
+	 */
+	if (host->caps.has_rwproof)
+		host->mode_reg |= ATMCI_MR_RDPROOF | ATMCI_MR_WRPROOF;
 
 	atmci_writel(host, ATMCI_MR, host->mode_reg);
 }
@@ -470,6 +477,7 @@ static void atmci_get_cap(struct atmel_mci *host)
 	case 0x400:
 	case 0x300:
 	case 0x200:
+		host->caps.has_rwproof = 1;
 	case 0x100:
 	case 0x0:
 		break;
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#9 lore raw

Re: [PATCH 08/14] atmel_mci: rwproof is only needed since IP version 0x200

Quoted 33 lines · Jean-Christophe PLAGNIOL-VILLARD
---
 drivers/mci/atmel_mci.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/mci/atmel_mci.c +8 -1
index d5fdd1d..bf0adb0 100644
@@ -28,6 +28,7 @@
 #include "atmel-mci-regs.h"
 
 struct atmel_mci_caps {
+	bool    has_rwproof;
 	bool	has_odd_clk_div;
 };
 
@@ -94,7 +95,13 @@ static void atmci_set_clk_rate(struct atmel_mci *host,
 	dev_dbg(host->hw_dev, "atmel_set_clk_rate: clkIn=%ld clkIos=%d divider=%d\n",
 		host->bus_hz, clock_min, clkdiv);
 
-	host->mode_reg |= ATMCI_MR_RDPROOF | ATMCI_MR_WRPROOF;
+	/*
+	 * WRPROOF and RDPROOF prevent overruns/underruns by
+	 * stopping the clock when the FIFO is full/empty.
+	 * This state is not expected to last for long.
+	 */
+	if (host->caps.has_rwproof)
+		host->mode_reg |= ATMCI_MR_RDPROOF | ATMCI_MR_WRPROOF;
 
 	atmci_writel(host, ATMCI_MR, host->mode_reg);
 }

drivers/mci/atmel_mci.c static void atmci_get_cap(struct atmel_mci *host) · line 482

Quoted 6 lines
drivers/mci/atmel_mci.c +1 -0
@@ -470,6 +477,7 @@ static void atmci_get_cap(struct atmel_mci *host)
 	case 0x400:
 	case 0x300:
 	case 0x200:
+		host->caps.has_rwproof = 1;
 	case 0x100:
 	case 0x0:

By 'since' in the subject do you mean 'up to'?

Sascha

Signature · 9 lines
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#10 lore raw

Re: [PATCH 08/14] atmel_mci: rwproof is only needed since IP version 0x200

Quoted 31 lines · Sascha Hauer
Quoted 30 lines · Jean-Christophe PLAGNIOL-VILLARD
---
 drivers/mci/atmel_mci.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/mci/atmel_mci.c +8 -1
index d5fdd1d..bf0adb0 100644
@@ -28,6 +28,7 @@
 #include "atmel-mci-regs.h"
 
 struct atmel_mci_caps {
+	bool    has_rwproof;
 	bool	has_odd_clk_div;
 };
 
@@ -94,7 +95,13 @@ static void atmci_set_clk_rate(struct atmel_mci *host,
 	dev_dbg(host->hw_dev, "atmel_set_clk_rate: clkIn=%ld clkIos=%d divider=%d\n",
 		host->bus_hz, clock_min, clkdiv);
 
-	host->mode_reg |= ATMCI_MR_RDPROOF | ATMCI_MR_WRPROOF;
+	/*
+	 * WRPROOF and RDPROOF prevent overruns/underruns by
+	 * stopping the clock when the FIFO is full/empty.
+	 * This state is not expected to last for long.
+	 */
+	if (host->caps.has_rwproof)
+		host->mode_reg |= ATMCI_MR_RDPROOF | ATMCI_MR_WRPROOF;
 
Quoted 11 lines

drivers/mci/atmel_mci.c static void atmci_get_cap(struct atmel_mci *host) · line 482

Quoted 9 lines
drivers/mci/atmel_mci.c +1 -0
 	atmci_writel(host, ATMCI_MR, host->mode_reg);
 }
@@ -470,6 +477,7 @@ static void atmci_get_cap(struct atmel_mci *host)
 	case 0x400:
 	case 0x300:
 	case 0x200:
+		host->caps.has_rwproof = 1;
 	case 0x100:
 	case 0x0:

By 'since' in the subject do you mean 'up to'?

yeah to code is right no the subject

Best Regards,
J.

Quoted 8 lines

Sascha

Signature · 4 lines
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

#11 lore raw

PATCH 9/14 atmel_mci: on version 0x0 we need to reset the IP at each request

In reply to Jean-Christophe PLAGNIOL-VILLARD
---
 drivers/mci/atmel_mci.c |   10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/mci/atmel_mci.c +10 -0
index bf0adb0..1b60348 100644
@@ -30,6 +30,7 @@
 struct atmel_mci_caps {
 	bool    has_rwproof;
 	bool	has_odd_clk_div;
+	bool	need_reset_after_xfer;
 };
 
 struct atmel_mci {
@@ -411,6 +412,12 @@ static int atmci_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_d
 	u32 stat, cmdat = 0;
 	int ret;
 
+	if (host->caps.need_reset_after_xfer) {
+		atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
+		atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
+		atmci_writel(host, ATMCI_MR, host->mode_reg);
+	}
+
 	if (cmd->resp_type != MMC_RSP_NONE)
 		cmdat |= ATMCI_CMDR_MAXLAT_64CYC;
 
@@ -471,6 +478,8 @@ static void atmci_get_cap(struct atmel_mci *host)
 
 	dev_info(host->hw_dev, "version: 0x%x\n", version);
 
+	host->caps.need_reset_after_xfer = 1;
+
 	switch (version & 0xf00) {
 	case 0x500:
 		host->caps.has_odd_clk_div = 1;
@@ -479,6 +488,7 @@ static void atmci_get_cap(struct atmel_mci *host)
 	case 0x200:
 		host->caps.has_rwproof = 1;
 	case 0x100:
+		host->caps.need_reset_after_xfer = 0;
 	case 0x0:
 		break;
 	default:
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#12 lore raw

PATCH 10/14 atmel_mci: after a software timeout the IP need to be reset

In reply to Jean-Christophe PLAGNIOL-VILLARD
---
 drivers/mci/atmel_mci.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/mci/atmel_mci.c +4 -1
index 1b60348..53df2e3 100644
@@ -48,6 +48,7 @@ struct atmel_mci {
 
 	unsigned long		bus_hz;
 	u32			mode_reg;
+	bool			need_reset;
 };
 
 #define to_mci_host(mci)	container_of(mci, struct atmel_mci, mci)
@@ -118,6 +119,7 @@ static int atmci_poll_status(struct atmel_mci *host, u32 mask)
 			return stat;
 		if (is_timeout(start, SECOND)) {
 			dev_err(host->hw_dev, "timeout\n");
+			host->need_reset = true;
 			return ATMCI_RTOE | stat;
 		}
 		if (stat & mask)
@@ -412,10 +414,11 @@ static int atmci_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_d
 	u32 stat, cmdat = 0;
 	int ret;
 
-	if (host->caps.need_reset_after_xfer) {
+	if (host->need_reset || host->caps.need_reset_after_xfer) {
 		atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
 		atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
 		atmci_writel(host, ATMCI_MR, host->mode_reg);
+		host->need_reset = false;
 	}
 
 	if (cmd->resp_type != MMC_RSP_NONE)
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#13 lore raw

PATCH 11/14 atmel_mci: support the SD highspeed since IP version 0x300

In reply to Jean-Christophe PLAGNIOL-VILLARD
---
 drivers/mci/atmel_mci.c |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
drivers/mci/atmel_mci.c +24 -0
index 53df2e3..3f24217 100644
@@ -28,6 +28,8 @@
 #include "atmel-mci-regs.h"
 
 struct atmel_mci_caps {
+	bool	has_cfg_reg;
+	bool	has_highspeed;
 	bool    has_rwproof;
 	bool	has_odd_clk_div;
 	bool	need_reset_after_xfer;
@@ -48,6 +50,7 @@ struct atmel_mci {
 
 	unsigned long		bus_hz;
 	u32			mode_reg;
+	u32			cfg_reg;
 	bool			need_reset;
 };
 
@@ -71,6 +74,8 @@ static void atmci_set_clk_rate(struct atmel_mci *host,
 	if (!host->mode_reg) {
 		clk_enable(host->clk);
 		atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
+		if (host->caps.has_cfg_reg)
+			atmci_writel(host, ATMCI_CFG, host->cfg_reg);
 	}
 
 	if (host->caps.has_odd_clk_div) {
@@ -395,6 +400,16 @@ static void atmci_set_ios(struct mci_host *mci, struct mci_ios *ios)
 
 	if (ios->clock) {
 		atmci_set_clk_rate(host, ios->clock);
+
+		if (host->caps.has_cfg_reg) {
+			/* setup High Speed mode in relation with card capacity */
+			if (ios->timing == MMC_TIMING_SD_HS)
+				host->cfg_reg |= ATMCI_CFG_HSMODE;
+			else
+				host->cfg_reg &= ~ATMCI_CFG_HSMODE;
+
+			atmci_writel(host, ATMCI_CFG, host->cfg_reg);
+		}
 	} else {
 		atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS);
 		if (host->mode_reg) {
@@ -418,6 +433,8 @@ static int atmci_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_d
 		atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
 		atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
 		atmci_writel(host, ATMCI_MR, host->mode_reg);
+		if (host->caps.has_cfg_reg)
+			atmci_writel(host, ATMCI_CFG, host->cfg_reg);
 		host->need_reset = false;
 	}
 
@@ -481,6 +498,8 @@ static void atmci_get_cap(struct atmel_mci *host)
 
 	dev_info(host->hw_dev, "version: 0x%x\n", version);
 
+	host->caps.has_cfg_reg = 0;
+	host->caps.has_highspeed = 0;
 	host->caps.need_reset_after_xfer = 1;
 
 	switch (version & 0xf00) {
@@ -488,6 +507,8 @@ static void atmci_get_cap(struct atmel_mci *host)
 		host->caps.has_odd_clk_div = 1;
 	case 0x400:
 	case 0x300:
+		host->caps.has_cfg_reg = 1;
+		host->caps.has_highspeed = 1;
 	case 0x200:
 		host->caps.has_rwproof = 1;
 	case 0x100:
@@ -547,6 +568,9 @@ static int atmci_probe(struct device_d *hw_dev)
 
 	atmci_get_cap(host);
 
+	if (host->caps.has_highspeed)
+		host->mci.host_caps |= MMC_MODE_HS;
+
 	mci_register(&host->mci);
 
 	return 0;
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#14 lore raw

PATCH 12/14 atmel_mci: update the SD/SDIO Card Register at request time

In reply to Jean-Christophe PLAGNIOL-VILLARD

as we need to reset the IP

---
 drivers/mci/atmel_mci.c |   16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)
drivers/mci/atmel_mci.c +11 -5
index 3f24217..8ad0e8a 100644
@@ -51,6 +51,7 @@ struct atmel_mci {
 	unsigned long		bus_hz;
 	u32			mode_reg;
 	u32			cfg_reg;
+	u32			sdc_reg;
 	bool			need_reset;
 };
 
@@ -382,21 +383,20 @@ static void atmci_set_ios(struct mci_host *mci, struct mci_ios *ios)
 	dev_dbg(host->hw_dev, "atmel_mci_set_ios: bus_width=%d clk=%d\n",
 		ios->bus_width, ios->clock);
 
+	host->sdc_reg &= ~ATMCI_SDCBUS_MASK;
 	switch (ios->bus_width) {
 	case MMC_BUS_WIDTH_4:
-		atmci_writel(host, ATMCI_SDCR, ATMCI_SDCBUS_4BIT);
+		host->sdc_reg |= ATMCI_SDCBUS_4BIT;
 		break;
 	case MMC_BUS_WIDTH_8:
-		atmci_writel(host, ATMCI_SDCR, ATMCI_SDCBUS_8BIT);
+		host->sdc_reg |= ATMCI_SDCBUS_8BIT;
 		break;
 	case MMC_BUS_WIDTH_1:
-		atmci_writel(host, ATMCI_SDCR, ATMCI_SDCBUS_1BIT);
+		host->sdc_reg |= ATMCI_SDCBUS_1BIT;
 		break;
 	default:
 		return;
 	}
-	atmci_writel(host, ATMCI_SDCR, atmci_readl(host, ATMCI_SDCR)
-		| host->slot_b);
 
 	if (ios->clock) {
 		atmci_set_clk_rate(host, ios->clock);
@@ -437,6 +437,7 @@ static int atmci_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_d
 			atmci_writel(host, ATMCI_CFG, host->cfg_reg);
 		host->need_reset = false;
 	}
+	atmci_writel(host, ATMCI_SDCR, host->sdc_reg);
 
 	if (cmd->resp_type != MMC_RSP_NONE)
 		cmdat |= ATMCI_CMDR_MAXLAT_64CYC;
@@ -571,6 +572,11 @@ static int atmci_probe(struct device_d *hw_dev)
 	if (host->caps.has_highspeed)
 		host->mci.host_caps |= MMC_MODE_HS;
 
+	if (host->slot_b)
+		host->sdc_reg = ATMCI_SDCSEL_SLOT_B;
+	else
+		host->sdc_reg = ATMCI_SDCSEL_SLOT_A;
+
 	mci_register(&host->mci);
 
 	return 0;
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#15 lore raw

PATCH 13/14 atmel_mci: drop board host caps

In reply to Jean-Christophe PLAGNIOL-VILLARD

as it's handle by detecting the IP version and bus with

---
 arch/arm/boards/at91sam9m10g45ek/init.c |    1 -
 arch/arm/boards/dss11/init.c            |    1 -
 arch/arm/mach-at91/include/mach/board.h |    1 -
 drivers/mci/atmel_mci.c                 |    1 -
 4 files changed, 4 deletions(-)
arch/arm/boards/at91sam9m10g45ek/init.c +0 -1
index d77b2bf..053c85b 100644
@@ -113,7 +113,6 @@ static struct at91_ether_platform_data macb_pdata = {
 #if defined(CONFIG_MCI_ATMEL)
 static struct atmel_mci_platform_data ek_mci_data = {
 	.bus_width	= 4,
-	.host_caps	= MMC_MODE_HS,
 	.detect_pin	= AT91_PIN_PD10,
 };
 
arch/arm/boards/dss11/init.c +0 -1
index a2e9825..2920d5e 100644
@@ -113,7 +113,6 @@ static void dss11_phy_reset(void)
 static struct atmel_mci_platform_data dss11_mci_data = {
 	.slot_b		= 1,
 	.bus_width	= 4,
-	.host_caps	= MMC_MODE_HS,
 };
 
 static struct at91_usbh_data dss11_usbh_data = {
arch/arm/mach-at91/include/mach/board.h +0 -1
index b18f1c0..9a72474 100644
@@ -147,7 +147,6 @@ static inline struct device_d * at91_register_uart(unsigned id, unsigned pins)
 struct atmel_mci_platform_data {
 	unsigned slot_b;
 	unsigned bus_width;
-	unsigned host_caps; /* MCI_MODE_* from mci.h */
 	int detect_pin;
 	int wp_pin;
 };
drivers/mci/atmel_mci.c +0 -1
index 8ad0e8a..647683b 100644
@@ -540,7 +540,6 @@ static int atmci_probe(struct device_d *hw_dev)
 	host->mci.init = atmci_reset;
 	host->mci.hw_dev = hw_dev;
 
-	host->mci.host_caps = pd->host_caps;
 	if (pd->bus_width >= 4)
 		host->mci.host_caps |= MMC_MODE_4BIT;
 	if (pd->bus_width == 8)
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#16 lore raw

PATCH 14/14 atmel_mci: gpio: request and configure card detect

In reply to Jean-Christophe PLAGNIOL-VILLARD
---
 drivers/mci/atmel_mci.c |   27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)
drivers/mci/atmel_mci.c +25 -2
index 647683b..9de079d 100644
@@ -481,7 +481,7 @@ static void atmci_info(struct device_d *mci_dev)
 		printf("- %u Hz upper limit", host->mci.f_max);
 
 	printf("\n  Card detection support: %s\n",
-		pd->detect_pin != 0 ? "yes" : "no");
+		gpio_is_valid(pd->detect_pin) ? "yes" : "no");
 
 }
 #endif /* CONFIG_MCI_INFO */
@@ -527,12 +527,28 @@ static int atmci_probe(struct device_d *hw_dev)
 {
 	struct atmel_mci *host;
 	struct atmel_mci_platform_data *pd = hw_dev->platform_data;
+	int ret;
 
 	if (!pd) {
 		dev_err(hw_dev, "missing platform data\n");
 		return -EINVAL;
 	}
 
+	if (gpio_is_valid(pd->detect_pin)) {
+		ret = gpio_request(pd->detect_pin, "mci_cd");
+		if (ret) {
+			dev_err(hw_dev, "Impossible to request CD gpio %d (%d)\n",
+				ret, pd->detect_pin);
+			return ret;
+		}
+
+		ret = gpio_direction_input(pd->detect_pin);
+		if (ret) {
+			dev_err(hw_dev, "Impossible to configure CD gpio %d as input (%d)\n",
+				ret, pd->detect_pin);
+			goto err_gpio_cd_request;
+		}
+	}
 
 	host = xzalloc(sizeof(*host));
 	host->mci.send_cmd = atmci_request;
@@ -552,7 +568,8 @@ static int atmci_probe(struct device_d *hw_dev)
 	host->clk = clk_get(hw_dev, "mci_clk");
 	if (IS_ERR(host->clk)) {
 		dev_err(hw_dev, "no mci_clk\n");
-		return PTR_ERR(host->clk);
+		ret = PTR_ERR(host->clk);
+		goto err_gpio_cd_request;
 	}
 
 	clk_enable(host->clk);
@@ -579,6 +596,12 @@ static int atmci_probe(struct device_d *hw_dev)
 	mci_register(&host->mci);
 
 	return 0;
+
+err_gpio_cd_request:
+	if (gpio_is_valid(pd->detect_pin))
+		gpio_free(pd->detect_pin);
+
+	return ret;
 }
 
 static struct driver_d atmci_driver = {
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox