From: James Hogan <james.hogan@imgtec.com>
To: James Hogan <james.hogan@imgtec.com>
Cc: Chris Ball <cjb@laptop.org>, Will Newton <will.newton@imgtec.com>,
Jaehoon Chung <jh80.chung@samsung.com>,
Kyungmin Park <kyungmin.park@samsung.com>,
Matt Fleming <matt@console-pimps.org>,
linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org,
james@albanarts.com
Subject: [PATCH 5/6] mmc: dw_mmc: don't hard code fifo depth, fix usage
Date: Fri, 24 Jun 2011 13:57:18 +0100 [thread overview]
Message-ID: <4E0489AE.2080405@imgtec.com> (raw)
In-Reply-To: <4E0488A9.6050109@imgtec.com>
The FIFO_DEPTH hardware configuration parameter can be found from the
power-on value of RX_WMark in the FIFOTH register. This is used to
initialise the watermarks, but when calculating the number of free fifo
spaces a preprocessor definition is used which is hard coded to 32.
Fix reading the value out of FIFOTH (the default value in the RX_WMark
field is FIFO_DEPTH-1 not FIFO_DEPTH). Allow the fifo depth to be
overriden by platform data (since a bootloader may have changed FIFOTH
making auto-detection unreliable). Store the fifo_depth for later use.
Also fix the calculation to find the number of free bytes in the fifo to
include the fifo depth in the left shift by the data shift, since the
fifo depth is measured in fifo items not bytes.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
---
drivers/mmc/host/dw_mmc.c | 23 ++++++++++++++++++-----
drivers/mmc/host/dw_mmc.h | 1 -
include/linux/mmc/dw_mmc.h | 8 ++++++++
3 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 3f610d5..3832312 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1116,8 +1116,8 @@ static void dw_mci_write_data_pio(struct dw_mci *host)
unsigned int nbytes = 0, len;
do {
- len = SDMMC_FIFO_SZ -
- (SDMMC_GET_FCNT(mci_readl(host, STATUS)) << shift);
+ len = (host->fifo_depth -
+ SDMMC_GET_FCNT(mci_readl(host, STATUS))) << shift;
if (offset + len <= sg->length) {
host->push_data(host, (void *)(buf + offset), len);
@@ -1659,8 +1659,19 @@ static int dw_mci_probe(struct platform_device *pdev)
* FIFO threshold settings RxMark = fifo_size / 2 - 1,
* Tx Mark = fifo_size / 2 DMA Size = 8
*/
- fifo_size = mci_readl(host, FIFOTH);
- fifo_size = (fifo_size >> 16) & 0x7ff;
+ if (!host->pdata->fifo_depth) {
+ /*
+ * Power-on value of RX_WMark is FIFO_DEPTH-1, but this may
+ * have been overwritten by the bootloader, just like we're
+ * about to do, so if you know the value for your hardware, you
+ * should put it in the platform data.
+ */
+ fifo_size = mci_readl(host, FIFOTH);
+ fifo_size = 1 + ((fifo_size >> 16) & 0x7ff);
+ } else {
+ fifo_size = host->pdata->fifo_depth;
+ }
+ host->fifo_depth = fifo_size;
host->fifoth_val = ((0x2 << 28) | ((fifo_size/2 - 1) << 16) |
((fifo_size/2) << 0));
mci_writel(host, FIFOTH, host->fifoth_val);
@@ -1707,7 +1718,9 @@ static int dw_mci_probe(struct platform_device *pdev)
mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */
dev_info(&pdev->dev, "DW MMC controller at irq %d, "
- "%d bit host data width\n", irq, width);
+ "%d bit host data width, "
+ "%u deep fifo\n",
+ irq, width, fifo_size);
if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO)
dev_info(&pdev->dev, "Internal DMAC interrupt fix enabled.\n");
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index bb9e5de..027d377 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -118,7 +118,6 @@
#define SDMMC_CMD_INDX(n) ((n) & 0x1F)
/* Status register defines */
#define SDMMC_GET_FCNT(x) (((x)>>17) & 0x1FF)
-#define SDMMC_FIFO_SZ 32
/* Internal DMAC interrupt defines */
#define SDMMC_IDMAC_INT_AI BIT(9)
#define SDMMC_IDMAC_INT_NI BIT(8)
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index dea4847..01db1a0 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -74,6 +74,7 @@ struct mmc_data;
* @pdev: Platform device associated with the MMC controller.
* @pdata: Platform data associated with the MMC controller.
* @slot: Slots sharing this MMC controller.
+ * @fifo_depth: depth of FIFO.
* @data_shift: log2 of FIFO item size.
* @push_data: Pointer to FIFO push function.
* @pull_data: Pointer to FIFO pull function.
@@ -146,6 +147,7 @@ struct dw_mci {
struct dw_mci_slot *slot[MAX_MCI_SLOTS];
/* FIFO push and pull */
+ int fifo_depth;
int data_shift;
void (*push_data)(struct dw_mci *host, void *buf, int cnt);
void (*pull_data)(struct dw_mci *host, void *buf, int cnt);
@@ -196,6 +198,12 @@ struct dw_mci_board {
unsigned int bus_hz; /* Bus speed */
unsigned int caps; /* Capabilities */
+ /*
+ * Override fifo depth. If 0, autodetect it from the FIFOTH register,
+ * but note that this may not be reliable after a bootloader has used
+ * it.
+ */
+ unsigned int fifo_depth;
/* delay in mS before detecting cards after interrupt */
u32 detect_delay_ms;
--
1.7.2.3
next prev parent reply other threads:[~2011-06-24 13:13 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-24 12:52 [PATCH 0/6] mmc: dw_mmc: misc fixes and improvements James Hogan
2011-06-24 12:54 ` [PATCH 1/6] mmc: dw_mmc: clear TXDR/RXDR ints before enabling James Hogan
2011-06-24 12:55 ` [PATCH 2/6] mmc: dw_mmc: fix race with request and removal James Hogan
2011-06-24 12:55 ` [PATCH 3/6] mmc: dw_mmc: convert card tasklet to workqueue James Hogan
2011-06-24 12:56 ` [PATCH 4/6] mmc: dw_mmc: brackets in register access macros James Hogan
2011-06-24 12:57 ` James Hogan [this message]
2011-06-24 12:57 ` [PATCH 6/6] mmc: dw_mmc: handle unaligned buffers and sizes James Hogan
2011-06-24 14:53 ` [PATCH 0/6] mmc: dw_mmc: misc fixes and improvements Will Newton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4E0489AE.2080405@imgtec.com \
--to=james.hogan@imgtec.com \
--cc=cjb@laptop.org \
--cc=james@albanarts.com \
--cc=jh80.chung@samsung.com \
--cc=kyungmin.park@samsung.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=matt@console-pimps.org \
--cc=will.newton@imgtec.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox