linux-mmc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2/3] mmc: sdhci-pxa: Add SDHCI driver for PXA16x
@ 2011-10-25 12:37 Tanmay Upadhyay
  2011-11-10 20:09 ` Chris Ball
  0 siblings, 1 reply; 27+ messages in thread
From: Tanmay Upadhyay @ 2011-10-25 12:37 UTC (permalink / raw)
  To: zhangfei.gao, dwang4, njun, wuqm, prakity
  Cc: cjb, linux-mmc, Tanmay Upadhyay, linux-arm-kernel

Signed-off-by: Philip Rakity <prakity@marvell.com>
Signed-off-by: Tanmay Upadhyay <tanmay.upadhyay@einfochips.com>
---
 drivers/mmc/host/Kconfig                |   13 ++
 drivers/mmc/host/Makefile               |    1 +
 drivers/mmc/host/sdhci-pxav1.c          |  256 +++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci.c                |    3 +
 drivers/mmc/host/sdhci.h                |    1 +
 include/linux/platform_data/pxa_sdhci.h |    1 +
 6 files changed, 275 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mmc/host/sdhci-pxav1.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 8c87096..9c9b73a 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -207,6 +207,19 @@ config MMC_SDHCI_PXAV2
 
 	  If unsure, say N.
 
+config MMC_SDHCI_PXAV1
+	tristate "Marvell PXA16X SD Host Controller support (PXAV1)"
+	depends on CLKDEV_LOOKUP
+	select MMC_SDHCI
+	select MMC_SDHCI_PLTFM
+	default CPU_PXA168
+	help
+	  This selects the Marvell(R) PXAV1 SD Host Controller.
+	  If you have a PXA16X platform with SD Host Controller
+	  and a card slot, say Y or M here.
+
+	  If unsure, say N.
+
 config MMC_SDHCI_SPEAR
 	tristate "SDHCI support on ST SPEAr platform"
 	depends on MMC_SDHCI && PLAT_SPEAR
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index b4b83f3..5094af8 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_MMC_SDHCI)		+= sdhci.o
 obj-$(CONFIG_MMC_SDHCI_PCI)	+= sdhci-pci.o
 obj-$(CONFIG_MMC_SDHCI_PXAV3)	+= sdhci-pxav3.o
 obj-$(CONFIG_MMC_SDHCI_PXAV2)	+= sdhci-pxav2.o
+obj-$(CONFIG_MMC_SDHCI_PXAV1)	+= sdhci-pxav1.o
 obj-$(CONFIG_MMC_SDHCI_S3C)	+= sdhci-s3c.o
 obj-$(CONFIG_MMC_SDHCI_SPEAR)	+= sdhci-spear.o
 obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
diff --git a/drivers/mmc/host/sdhci-pxav1.c b/drivers/mmc/host/sdhci-pxav1.c
new file mode 100644
index 0000000..a0f6285
--- /dev/null
+++ b/drivers/mmc/host/sdhci-pxav1.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2011 Marvell International Ltd.
+ *		Zhangfei Gao <zhangfei.gao@marvell.com>
+ *		Kevin Wang <dwang4@marvell.com>
+ *		Jun Nie <njun@marvell.com>
+ *		Qiming Wu <wuqm@marvell.com>
+ *		Philip Rakity <prakity@marvell.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_data/pxa_sdhci.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "sdhci.h"
+#include "sdhci-pltfm.h"
+
+#define SD_FIFO_PARAM		0xe0
+#define DIS_PAD_SD_CLK_GATE	0x0400 /* Turn on/off Dynamic SD Clock Gating */
+#define CLK_GATE_SETTING_BITS	DIS_PAD_SD_CLK_GATE
+
+#define SD_CLOCK_BURST_SIZE_SETUP	0xe6
+#define SDCLK_SEL_SHIFT		8
+#define SDCLK_SEL_MASK		0x3
+#define SDCLK_DELAY_SHIFT	10
+#define SDCLK_DELAY_MASK	0x3c
+
+#define SD_CE_ATA_2		0xea
+#define MMC_CARD		0x1000
+#define MMC_WIDTH		0x0100
+
+
+static void pxav1_set_private_registers(struct sdhci_host *host, u8 mask)
+{
+	struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
+	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
+
+	if (mask == SDHCI_RESET_ALL) {
+		u16 tmp = 0;
+
+		/*
+		 * tune timing of read data/command when crc error happen
+		 * no performance impact
+		 */
+		if (pdata && pdata->clk_delay_sel) {
+			tmp = readw(host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
+
+			tmp &= ~(SDCLK_DELAY_MASK << SDCLK_DELAY_SHIFT);
+			tmp |= (pdata->clk_delay_cycles & SDCLK_DELAY_MASK)
+				<< SDCLK_DELAY_SHIFT;
+			tmp &= ~(SDCLK_SEL_MASK << SDCLK_SEL_SHIFT);
+			tmp |= (pdata->clk_delay_sel & SDCLK_SEL_MASK)
+				<< SDCLK_SEL_SHIFT;
+
+			writew(tmp, host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
+		}
+
+		/* no clock gating */
+		tmp = readw(host->ioaddr + SD_FIFO_PARAM);
+		tmp |= DIS_PAD_SD_CLK_GATE;
+		writew(tmp, host->ioaddr + SD_FIFO_PARAM);
+	}
+}
+
+static int pxav1_mmc_set_width(struct sdhci_host *host, int width)
+{
+	u8 ctrl;
+	u16 tmp;
+
+	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+	tmp = readw(host->ioaddr + SD_CE_ATA_2);
+	if (width == MMC_BUS_WIDTH_8) {
+		ctrl &= ~SDHCI_CTRL_4BITBUS;
+		tmp |= MMC_CARD | MMC_WIDTH;
+	} else {
+		tmp &= ~(MMC_CARD | MMC_WIDTH);
+		if (width == MMC_BUS_WIDTH_4)
+			ctrl |= SDHCI_CTRL_4BITBUS;
+		else
+			ctrl &= ~SDHCI_CTRL_4BITBUS;
+	}
+	writew(tmp, host->ioaddr + SD_CE_ATA_2);
+	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+
+	return 0;
+}
+
+static u32 pxav1_get_max_clock(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+	return clk_get_rate(pltfm_host->clk);
+}
+
+/*
+ * we cannot talk to controller for 8 bus cycles according to sdio spec
+ * at lowest speed this is 100,000 HZ per cycle or 800,000 cycles
+ * which is quite a LONG TIME on a fast cpu -- so delay if needed
+ */
+static void platform_specific_completion(struct sdhci_host *host)
+{
+	struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
+	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
+
+	if (host->clock < 3200000 && pdata && pdata->delay_in_ms)
+		mdelay(pdata->delay_in_ms);
+}
+
+
+static struct sdhci_ops pxav1_sdhci_ops = {
+	.get_max_clock = pxav1_get_max_clock,
+	.platform_reset_exit = pxav1_set_private_registers,
+	.platform_8bit_width = pxav1_mmc_set_width,
+	.platform_specific_completion = &platform_specific_completion,
+};
+
+static int __devinit sdhci_pxav1_probe(struct platform_device *pdev)
+{
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
+	struct device *dev = &pdev->dev;
+	struct sdhci_host *host = NULL;
+	struct sdhci_pxa *pxa = NULL;
+	int ret;
+	struct clk *clk;
+
+	pxa = kzalloc(sizeof(struct sdhci_pxa), GFP_KERNEL);
+	if (!pxa)
+		return -ENOMEM;
+
+	host = sdhci_pltfm_init(pdev, NULL);
+	if (IS_ERR(host)) {
+		kfree(pxa);
+		return PTR_ERR(host);
+	}
+	pltfm_host = sdhci_priv(host);
+	pltfm_host->priv = pxa;
+
+	clk = clk_get(dev, "PXA-SDHCLK");
+	if (IS_ERR(clk)) {
+		dev_err(dev, "failed to get io clock\n");
+		ret = PTR_ERR(clk);
+		goto err_clk_get;
+	}
+	pltfm_host->clk = clk;
+	clk_enable(clk);
+
+	host->quirks = SDHCI_QUIRK_BROKEN_ADMA
+		| SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
+		| SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN
+		| SDHCI_QUIRK_NO_BUSY_IRQ
+		| SDHCI_QUIRK_32BIT_DMA_SIZE;
+
+	if (pdata) {
+		if (pdata->flags & PXA_FLAG_CARD_PERMANENT) {
+			/* on-chip device */
+			host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+			host->mmc->caps |= MMC_CAP_NONREMOVABLE;
+		}
+
+		/* If slot design supports 8 bit data, indicate this to MMC. */
+		if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
+			host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+
+		if (pdata->quirks)
+			host->quirks |= pdata->quirks;
+		if (pdata->host_caps)
+			host->mmc->caps |= pdata->host_caps;
+		if (pdata->pm_caps)
+			host->mmc->pm_caps |= pdata->pm_caps;
+	}
+
+	host->ops = &pxav1_sdhci_ops;
+
+	ret = sdhci_add_host(host);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to add host\n");
+		goto err_add_host;
+	}
+
+	platform_set_drvdata(pdev, host);
+
+	return 0;
+
+err_add_host:
+	clk_disable(clk);
+	clk_put(clk);
+err_clk_get:
+	sdhci_pltfm_free(pdev);
+	kfree(pxa);
+	return ret;
+}
+
+static int __devexit sdhci_pxav1_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_pxa *pxa = pltfm_host->priv;
+
+	sdhci_remove_host(host, 1);
+
+	clk_disable(pltfm_host->clk);
+	clk_put(pltfm_host->clk);
+	sdhci_pltfm_free(pdev);
+	kfree(pxa);
+
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver sdhci_pxav1_driver = {
+	.driver		= {
+		.name	= "sdhci-pxav1",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sdhci_pxav1_probe,
+	.remove		= __devexit_p(sdhci_pxav1_remove),
+#ifdef CONFIG_PM
+	.suspend	= sdhci_pltfm_suspend,
+	.resume		= sdhci_pltfm_resume,
+#endif
+};
+static int __init sdhci_pxav1_init(void)
+{
+	return platform_driver_register(&sdhci_pxav1_driver);
+}
+
+static void __exit sdhci_pxav1_exit(void)
+{
+	platform_driver_unregister(&sdhci_pxav1_driver);
+}
+
+module_init(sdhci_pxav1_init);
+module_exit(sdhci_pxav1_exit);
+
+MODULE_DESCRIPTION("SDHCI driver for pxav1");
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 0e02cc1..26043aa 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -960,6 +960,9 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
 		mdelay(1);
 	}
 
+	if (host->ops->platform_specific_completion)
+		host->ops->platform_specific_completion(host);
+
 	mod_timer(&host->timer, jiffies + 10 * HZ);
 
 	host->cmd = cmd;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 745c42f..363eebc 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -274,6 +274,7 @@ struct sdhci_ops {
 	void	(*platform_reset_exit)(struct sdhci_host *host, u8 mask);
 	int	(*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
 
+	void	(*platform_specific_completion)(struct sdhci_host *host);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
diff --git a/include/linux/platform_data/pxa_sdhci.h b/include/linux/platform_data/pxa_sdhci.h
index 51ad099..b77f017 100644
--- a/include/linux/platform_data/pxa_sdhci.h
+++ b/include/linux/platform_data/pxa_sdhci.h
@@ -51,6 +51,7 @@ struct sdhci_pxa_platdata {
 	unsigned int	host_caps;
 	unsigned int	quirks;
 	unsigned int	pm_caps;
+	unsigned int	delay_in_ms;
 };
 
 struct sdhci_pxa {
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [PATCH 0/4] Add SD support for PXA168 & gplugD
@ 2013-03-17 18:16 Tanmay Upadhyay
  2013-03-17 18:18 ` [PATCH 1/4] mmc: sdhci-pxa: Trivial fix in Kconfig Tanmay Upadhyay
  0 siblings, 1 reply; 27+ messages in thread
From: Tanmay Upadhyay @ 2013-03-17 18:16 UTC (permalink / raw)
  To: zhangfei.gao, dwang4, njun, wuqm, prakity, eric.y.miao,
	haojian.zhuang
  Cc: cjb, linux-mmc, Tanmay Upadhyay, linux-arm-kernel

This patch series adds support for on-chip SD controller on PXA168

Tanmay Upadhyay (4):
  mmc: sdhci-pxa: Trivial fix in Kconfig
  ARM: pxa168: Add SDHCI support
  mmc: sdhci-pxa: Add SDHCI driver for PXA16x
  ARM: pxa168/gplugd: Add support for SD port 1

 arch/arm/mach-mmp/Kconfig               |    1 -
 arch/arm/mach-mmp/clock-pxa168.c        |   47 +++++++++++++++++++++++++++++++
 arch/arm/mach-mmp/gplugd.c              |    6 ++++
 arch/arm/mach-mmp/include/mach/pxa168.h |   20 +++++++++++++
 arch/arm/mach-mmp/pxa168.c              |    4 +++
 drivers/mmc/host/Kconfig                |   11 ++++----
 drivers/mmc/host/sdhci-pxav2.c          |   30 +++++++++++++++++++-
 drivers/mmc/host/sdhci.c                |    3 ++
 drivers/mmc/host/sdhci.h                |    1 +
 include/linux/platform_data/pxa_sdhci.h |    2 ++
 10 files changed, 118 insertions(+), 7 deletions(-)

-- 
1.7.9.5

*************************************************************************************************************************************************************
eInfochips Business Disclaimer : This e-mail message and all attachments transmitted with it are intended solely for the use of the addressee and may contain legally privileged and confidential information. If the reader of this message is not the intended recipient, or an employee or agent responsible for delivering this message to the intended recipient, you are hereby notified that any dissemination, distribution, copying, or other use of this message or its attachments is strictly prohibited. If you have received this message in error, please notify the sender immediately by replying to this message and please delete it from your computer. Any views expressed in this message are those of the individual sender unless otherwise stated. Company has taken enough precautions to prevent the 
 spread of viruses. However the company accepts no liability for any damage caused by any virus transmitted by this email.
*************************************************************************************************************************************************************


---------------------------------------------------------------------------------------------
Notice: 
This message has been scanned by Trend Micro Mail Security scanner and is believed to be clean
---------------------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2013-03-17 18:18 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-25 12:37 [PATCH 2/3] mmc: sdhci-pxa: Add SDHCI driver for PXA16x Tanmay Upadhyay
2011-11-10 20:09 ` Chris Ball
2011-11-21  4:23   ` [PATCH 1/4] mmc: sdhci-pxa: Trivial fix in Kconfig Tanmay Upadhyay
2011-11-21  4:26   ` [PATCH v3 2/4] ARM: pxa168: Add SDHCI support Tanmay Upadhyay
2011-12-01 18:05     ` Chris Ball
2011-12-15 23:15       ` Chris Ball
2011-12-19  4:45         ` Haojian Zhuang
2011-12-19  4:55           ` Tanmay Upadhyay
2011-12-19  5:02             ` Haojian Zhuang
2011-12-19  5:17               ` Tanmay Upadhyay
2011-12-19  5:24                 ` Haojian Zhuang
2011-12-20 13:13                   ` [PATCH v4 " Tanmay Upadhyay
2011-12-20 13:25                     ` Haojian Zhuang
2011-12-20 13:38                       ` Haojian Zhuang
2011-12-20 13:44                         ` Tanmay Upadhyay
2011-12-20 13:44                       ` Tanmay Upadhyay
2011-12-20 21:03                     ` Russell King - ARM Linux
2011-12-21  1:48                       ` Haojian Zhuang
2011-12-29 13:43                         ` [PATCH " Tanmay Upadhyay
2011-12-30  0:36                           ` Haojian Zhuang
2012-01-23 22:45                             ` Tanmay Upadhyay
2011-12-19  5:24               ` [PATCH v3 " Philip Rakity
2011-12-19  5:30                 ` Haojian Zhuang
2011-11-21  4:26   ` [PATCH v2 3/4] mmc: sdhci-pxa: Add SDHCI driver for PXA16x Tanmay Upadhyay
     [not found]     ` <CAMj5Bki3Ev8K63538-dNbyijUw1oNTLChADLd4=Ef-LeCkoacw@mail.gmail.com>
2011-11-25 18:53       ` Philip Rakity
2011-11-21  4:27   ` [PATCH v2 4/4] ARM: pxa168/gplugd: Add support for SD port 1 Tanmay Upadhyay
  -- strict thread matches above, loose matches on Subject: below --
2013-03-17 18:16 [PATCH 0/4] Add SD support for PXA168 & gplugD Tanmay Upadhyay
2013-03-17 18:18 ` [PATCH 1/4] mmc: sdhci-pxa: Trivial fix in Kconfig Tanmay Upadhyay

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).