From: Juergen Beisert <jbe@pengutronix.de>
To: barebox@lists.infradead.org
Subject: [PATCH 10/14] STM378x: Adapt the MCI driver to support i.MX23 and i.MX28
Date: Mon, 13 Dec 2010 11:53:33 +0100 [thread overview]
Message-ID: <1292237617-7064-11-git-send-email-jbe@pengutronix.de> (raw)
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
drivers/mci/Kconfig | 4 +-
drivers/mci/stm378x.c | 139 +++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 124 insertions(+), 19 deletions(-)
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index b1f2773..ee04079 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -28,11 +28,11 @@ config MCI_INFO
comment "--- MCI host drivers ---"
config MCI_STM378X
- bool "i.MX23"
+ bool "i.MX23/i.MX28"
depends on ARCH_STM
help
Enable this entry to add support to read and write SD cards on a
- i.MX23 based system.
+ i.MX23/i.MX28 based system.
config MCI_S3C
bool "S3C"
diff --git a/drivers/mci/stm378x.c b/drivers/mci/stm378x.c
index fb74822..94b0f4a 100644
--- a/drivers/mci/stm378x.c
+++ b/drivers/mci/stm378x.c
@@ -61,37 +61,77 @@
# define SSP_CTRL0_LONG_RESP (1 << 19)
# define SSP_CTRL0_GET_RESP (1 << 17)
# define SSP_CTRL0_ENABLE (1 << 16)
+#ifdef CONFIG_ARCH_IMX23
# define SSP_CTRL0_XFER_COUNT(x) ((x) & 0xffff)
+#endif
#define HW_SSP_CMD0 0x010
# define SSP_CMD0_SLOW_CLK (1 << 22)
# define SSP_CMD0_CONT_CLK (1 << 21)
# define SSP_CMD0_APPEND_8CYC (1 << 20)
+#ifdef CONFIG_ARCH_IMX23
# define SSP_CMD0_BLOCK_SIZE(x) (((x) & 0xf) << 16)
# define SSP_CMD0_BLOCK_COUNT(x) (((x) & 0xff) << 8)
+#endif
# define SSP_CMD0_CMD(x) ((x) & 0xff)
#define HW_SSP_CMD1 0x020
-#define HW_SSP_COMPREF 0x030
-#define HW_SSP_COMPMASK 0x040
-#define HW_SSP_TIMING 0x050
+
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_COMPREF 0x030
+# define HW_SSP_COMPMASK 0x040
+# define HW_SSP_TIMING 0x050
+# define HW_SSP_CTRL1 0x060
+# define HW_SSP_DATA 0x070
+#endif
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_XFER_COUNT 0x30
+# define HW_SSP_BLOCK_SIZE 0x40
+# define SSP_BLOCK_SIZE(x) ((x) & 0xf)
+# define SSP_BLOCK_COUNT(x) (((x) & 0xffffff) << 4)
+# define HW_SSP_COMPREF 0x050
+# define HW_SSP_COMPMASK 0x060
+# define HW_SSP_TIMING 0x070
+# define HW_SSP_CTRL1 0x080
+# define HW_SSP_DATA 0x090
+#endif
+/* bit definition for register HW_SSP_TIMING */
# define SSP_TIMING_TIMEOUT_MASK (0xffff0000)
# define SSP_TIMING_TIMEOUT(x) ((x) << 16)
# define SSP_TIMING_CLOCK_DIVIDE(x) (((x) & 0xff) << 8)
# define SSP_TIMING_CLOCK_RATE(x) ((x) & 0xff)
-#define HW_SSP_CTRL1 0x060
+/* bit definition for register HW_SSP_CTRL1 */
# define SSP_CTRL1_POLARITY (1 << 9)
# define SSP_CTRL1_WORD_LENGTH(x) (((x) & 0xf) << 4)
# define SSP_CTRL1_SSP_MODE(x) ((x) & 0xf)
-#define HW_SSP_DATA 0x070
-#define HW_SSP_SDRESP0 0x080
-#define HW_SSP_SDRESP1 0x090
-#define HW_SSP_SDRESP2 0x0A0
-#define HW_SSP_SDRESP3 0x0B0
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_SDRESP0 0x080
+# define HW_SSP_SDRESP1 0x090
+# define HW_SSP_SDRESP2 0x0A0
+# define HW_SSP_SDRESP3 0x0B0
+#endif
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_SDRESP0 0x0A0
+# define HW_SSP_SDRESP1 0x0B0
+# define HW_SSP_SDRESP2 0x0C0
+# define HW_SSP_SDRESP3 0x0D0
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_DDR_CTRL 0x0E0
+# define HW_SSP_DLL_CTRL 0x0F0
+#endif
+
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_STATUS 0x0C0
+#endif
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_STATUS 0x100
+#endif
-#define HW_SSP_STATUS 0x0C0
+/* bit definition for register HW_SSP_STATUS */
# define SSP_STATUS_PRESENT (1 << 31)
# define SSP_STATUS_SD_PRESENT (1 << 29)
# define SSP_STATUS_CARD_DETECT (1 << 28)
@@ -111,11 +151,23 @@
SSP_STATUS_RESP_CRC_ERR | SSP_STATUS_RESP_ERR | \
SSP_STATUS_RESP_TIMEOUT | SSP_STATUS_DATA_CRC_ERR | SSP_STATUS_TIMEOUT)
-#define HW_SSP_DEBUG 0x100
-#define HW_SSP_VERSION 0x110
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_DLL_STS 0x110
+#endif
+
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_DEBUG 0x100
+# define HW_SSP_VERSION 0x110
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_DEBUG 0x120
+# define HW_SSP_VERSION 0x130
+#endif
struct stm_mci_host {
unsigned clock; /* current clock speed in Hz ("0" if disabled) */
+ unsigned index;
#ifdef CONFIG_MCI_INFO
unsigned f_min;
unsigned f_max;
@@ -124,6 +176,18 @@ struct stm_mci_host {
};
/**
+ * Get the SSP clock rate
+ * @param hw_dev Host interface device instance
+ * @return Unit's clock in [Hz]
+ */
+static unsigned get_unit_clock(struct device_d *hw_dev)
+{
+ struct stm_mci_host *host_data = GET_HOST_DATA(hw_dev);
+
+ return imx_get_sspclk(host_data->index);
+}
+
+/**
* Get MCI cards response if defined for the type of command
* @param hw_dev Host interface device instance
* @param cmd Command description
@@ -417,6 +481,7 @@ static int stm_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd,
xfer_cnt = log2blocksize = block_cnt = 0;
/* setup command and transfer parameters */
+#ifdef CONFIG_ARCH_IMX23
writel(prepare_transfer_setup(cmd->resp_type, data != NULL ? data->flags : 0) |
SSP_CTRL0_BUS_WIDTH(host_data->bus_width) |
(xfer_cnt != 0 ? SSP_CTRL0_DATA_XFER : 0) | /* command plus data */
@@ -430,6 +495,23 @@ static int stm_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd,
SSP_CMD0_BLOCK_COUNT(block_cnt) |
(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ? SSP_CMD0_APPEND_8CYC : 0),
hw_dev->map_base + HW_SSP_CMD0);
+#endif
+#ifdef CONFIG_ARCH_IMX28
+ writel(prepare_transfer_setup(cmd->resp_type, data != NULL ? data->flags : 0) |
+ SSP_CTRL0_BUS_WIDTH(host_data->bus_width) |
+ (xfer_cnt != 0 ? SSP_CTRL0_DATA_XFER : 0) | /* command plus data */
+ SSP_CTRL0_ENABLE,
+ hw_dev->map_base + HW_SSP_CTRL0);
+ writel(xfer_cnt, hw_dev->map_base + HW_SSP_XFER_COUNT);
+
+ /* prepare the command and the transfered data count */
+ writel(SSP_CMD0_CMD(cmd->cmdidx) |
+ (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ? SSP_CMD0_APPEND_8CYC : 0),
+ hw_dev->map_base + HW_SSP_CMD0);
+ writel(SSP_BLOCK_SIZE(log2blocksize) |
+ SSP_BLOCK_COUNT(block_cnt),
+ hw_dev->map_base + HW_SSP_BLOCK_SIZE);
+#endif
/* prepare command's arguments */
writel(cmd->cmdarg, hw_dev->map_base + HW_SSP_CMD1);
@@ -481,7 +563,7 @@ static unsigned setup_clock_speed(struct device_d *hw_dev, unsigned nc)
return 0;
}
- ssp = imx_get_sspclk(0);
+ ssp = get_unit_clock(hw_dev);
for (div = 2; div < 255; div += 2) {
rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(ssp, nc), div);
@@ -657,21 +739,44 @@ static int stm_mci_probe(struct device_d *hw_dev)
host->voltages = pd->voltages;
host->host_caps = pd->caps;
+#ifdef CONFIG_ARCH_IMX23
+ host_data->index = 0; /* there is only one clock for all */
+#endif
+#ifdef CONFIG_ARCH_IMX28
+ /* one dedicated clock per unit */
+ switch (hw_dev->map_base) {
+ case IMX_SSP0_BASE:
+ host_data->index = 0;
+ break;
+ case IMX_SSP1_BASE:
+ host_data->index = 1;
+ break;
+ case IMX_SSP2_BASE:
+ host_data->index = 2;
+ break;
+ case IMX_SSP3_BASE:
+ host_data->index = 3;
+ break;
+ default:
+ pr_debug("Unknown SSP unit at address 0x%08x\n", hw_dev->map_base);
+ return 0;
+ }
+#endif
if (pd->f_min == 0) {
- host->f_min = imx_get_sspclk(0) / 254U / 256U;
+ host->f_min = get_unit_clock(hw_dev) / 254 / 256;
pr_debug("Min. frequency is %u Hz\n", host->f_min);
} else {
host->f_min = pd->f_min;
pr_debug("Min. frequency is %u Hz, could be %u Hz\n",
- host->f_min, imx_get_sspclk(0) / 254U / 256U);
+ host->f_min, get_unit_clock(hw_dev) / 254 / 256);
}
if (pd->f_max == 0) {
- host->f_max = imx_get_sspclk(0) / 2U / 1U;
+ host->f_max = get_unit_clock(hw_dev) / 2 / 1;
pr_debug("Max. frequency is %u Hz\n", host->f_max);
} else {
host->f_max = pd->f_max;
pr_debug("Max. frequency is %u Hz, could be %u Hz\n",
- host->f_max, imx_get_sspclk(0) / 2U / 1U);
+ host->f_max, get_unit_clock(hw_dev) / 2 / 1);
}
#ifdef CONFIG_MCI_INFO
--
1.7.2.3
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2010-12-13 10:53 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
2010-12-13 10:53 ` [PATCH 01/14] Make DIV_ROUND_UP macro globally available Juergen Beisert
2010-12-13 10:53 ` [PATCH 02/14] Add macro for correct rounding in integer devisions Juergen Beisert
2010-12-13 10:53 ` [PATCH 03/14] STM378x: Use Hz as the clock unit like in all other arch Juergen Beisert
2010-12-13 10:53 ` [PATCH 04/14] STM378x: Do not configure any pin usage in the driver Juergen Beisert
2010-12-13 10:53 ` [PATCH 05/14] STM378x: Parameterize the max. possible GPIO number Juergen Beisert
2010-12-13 10:53 ` [PATCH 06/14] STM378x: Separate i.MX23 clock handling Juergen Beisert
2010-12-13 10:53 ` [PATCH 07/14] IMX: Ignore i.MX23/i.MX28 related code in shared devices Juergen Beisert
2010-12-13 10:53 ` [PATCH 08/14] STM378x: Add i.MX28 architecture Juergen Beisert
2010-12-13 10:53 ` [PATCH 09/14] STM378x: Adapt the serial driver to support i.MX23 and i.MX28 Juergen Beisert
2010-12-13 10:53 ` Juergen Beisert [this message]
2010-12-13 10:53 ` [PATCH 11/14] Fixup the FEC driver files Juergen Beisert
2010-12-13 10:53 ` [PATCH 12/14] MX28: add FEC support Juergen Beisert
2010-12-13 10:53 ` [PATCH 13/14] STM378x: Add TX28 CPU module Juergen Beisert
2010-12-13 10:53 ` [PATCH 14/14] STM378x: Add the TX28 Starterkit-5 baseboard Juergen Beisert
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=1292237617-7064-11-git-send-email-jbe@pengutronix.de \
--to=jbe@pengutronix.de \
--cc=barebox@lists.infradead.org \
/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