forked from archlinuxarm/PKGBUILDs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
0006-mmp-mmc-adding-sdhc-support-for-pxa168-based-gplugd.patch
181 lines (166 loc) · 6.47 KB
/
0006-mmp-mmc-adding-sdhc-support-for-pxa168-based-gplugd.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
From 3175fb4aa7624e068ebca34ca4a7bb2f659a0b34 Mon Sep 17 00:00:00 2001
From: Ashokkumar G <0xfee1dead.sa@gmail.com>
Date: Mon, 26 Jan 2015 11:40:41 -0700
Subject: [PATCH 6/9] mmp:mmc: adding sdhc support for pxa168 based gplugd
Fixing can't talk to controller for sdhci PXAV2
1. Fixing can't talk to controller for 8bus cycles at lowest speed
2. Changing clock name from PXA-SDHCLK to NULL
3. Adding MACH_GPLUGD dependency for SDHCI_PXAV2, SDHCI_IO_ACCESSORIES
Signed-off-by: Ashokkumar G <0xfee1dead.sa@gmail.com>
---
arch/arm/mach-mmp/Kconfig | 1 +
arch/arm/mach-mmp/gplugd.c | 8 ++++++++
arch/arm/mach-mmp/include/mach/pxa168.h | 21 ++++++++++++++++++++-
arch/arm/mach-mmp/pxa168.c | 4 ++++
drivers/mmc/host/Kconfig | 4 +++-
drivers/mmc/host/sdhci-pxav2.c | 19 ++++++++++++++++++-
6 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index ebdba87b9671..5843def24351 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -80,6 +80,7 @@ config MACH_TETON_BGA
config MACH_GPLUGD
bool "Marvell's PXA168 GuruPlug Display (gplugD) Board"
select CPU_PXA168
+ select MMC
help
Say 'Y' here if you want to support the Marvell PXA168-based
GuruPlug Display (gplugD) Board
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index 2981c8878ee7..ba4ce4e63bbe 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/gpio-pxa.h>
+#include <linux/mmc/sdhci.h>
#include <linux/spi/spi.h>
#include <linux/spi/pxa2xx_spi.h>
@@ -148,6 +149,10 @@ static struct i2c_board_info gplugd_i2c_board_info[] = {
}
};
+struct sdhci_pxa_platdata gplugd_sdh_platdata = {
+ .quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_NO_BUSY_IRQ | SDHCI_QUIRK_32BIT_DMA_SIZE,
+};
+
static void __init select_disp_freq(void)
{
/* set GPIO 35 & clear GPIO 85 to set LCD External Clock to 74.25 MHz */
@@ -332,6 +337,9 @@ static void __init gplugd_init(void)
pxa168_add_ssp(2);
+ pxa168_add_sdh(1, &gplugd_sdh_platdata);
+ pxa168_add_sdh(2, &gplugd_sdh_platdata);
+
pxa168_add_eth(&gplugd_eth_platform_data);
}
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h
index a83ba7cb525d..def8f462943d 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -17,6 +17,7 @@ extern void pxa168_clear_keypad_wakeup(void);
#include <linux/platform_data/keypad-pxa27x.h>
#include <mach/cputype.h>
#include <linux/pxa168_eth.h>
+#include <linux/platform_data/pxa_sdhci.h>
#include <linux/platform_data/mv_usb.h>
extern struct pxa_device_desc pxa168_device_uart1;
@@ -37,7 +38,10 @@ extern struct pxa_device_desc pxa168_device_nand;
extern struct pxa_device_desc pxa168_device_fb;
extern struct pxa_device_desc pxa168_device_keypad;
extern struct pxa_device_desc pxa168_device_eth;
-
+extern struct pxa_device_desc pxa168_device_sdh1;
+extern struct pxa_device_desc pxa168_device_sdh2;
+extern struct pxa_device_desc pxa168_device_sdh3;
+extern struct pxa_device_desc pxa168_device_sdh4;
/* pdata can be NULL */
extern int __init pxa168_add_usb_host(struct mv_usb_platform_data *pdata);
@@ -134,4 +138,19 @@ static inline int pxa168_add_eth(struct pxa168_eth_platform_data *data)
{
return pxa_register_device(&pxa168_device_eth, data, sizeof(*data));
}
+
+static inline int pxa168_add_sdh(int id, struct sdhci_pxa_platdata *data)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 1: d = &pxa168_device_sdh1; break;
+ case 2: d = &pxa168_device_sdh2; break;
+ case 3: d = &pxa168_device_sdh3; break;
+ case 4: d = &pxa168_device_sdh4; break;
+ default:
+ return -EINVAL;
+ }
+ return pxa_register_device(d, data, sizeof(*data));
+}
#endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 144e997624c0..e7dee43e6458 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -110,6 +110,10 @@ PXA168_DEVICE(ssp5, "pxa168-ssp", 4, SSP5, 0xd4021000, 0x40, 60, 61);
PXA168_DEVICE(fb, "pxa168-fb", -1, LCD, 0xd420b000, 0x1c8);
PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c);
PXA168_DEVICE(eth, "pxa168-eth", -1, MFU, 0xc0800000, 0x0fff);
+PXA168_DEVICE(sdh1, "sdhci-pxav2", 0, SDH1, 0xd4280000, 0x100);
+PXA168_DEVICE(sdh2, "sdhci-pxav2", 1, SDH1, 0xd4281000, 0x100);
+PXA168_DEVICE(sdh3, "sdhci-pxav2", 2, SDH2, 0xd427e000, 0x100);
+PXA168_DEVICE(sdh4, "sdhci-pxav2", 3, SDH2, 0xd427f000, 0x100);
struct resource pxa168_resource_gpio[] = {
{
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 13860656104b..02f8e4d08854 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -240,7 +240,9 @@ config MMC_SDHCI_PXAV2
tristate "Marvell PXA9XX SD Host Controller support (PXAV2)"
depends on CLKDEV_LOOKUP
depends on MMC_SDHCI_PLTFM
- default CPU_PXA910
+ select MMC_SDHCI_IO_ACCESSORS if MACH_GPLUGD
+ default y if (CPU_PXA910 || MACH_GPLUGD)
+
help
This selects the Marvell(R) PXAV2 SD Host Controller.
If you have a PXA9XX platform with SD Host Controller
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index b4c23e983baf..f0f36c9a803a 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -111,7 +111,24 @@ static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
}
+/*
+ * 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 inline u16 pxa168_readw(struct sdhci_host *host, int reg)
+{
+ u32 temp;
+ if (reg == SDHCI_HOST_VERSION) {
+ temp = readl (host->ioaddr + SDHCI_HOST_VERSION - 2) >> 16;
+ return temp & 0xffff;
+ }
+
+ return readw(host->ioaddr + reg);
+}
+
static const struct sdhci_ops pxav2_sdhci_ops = {
+ .read_w = &pxa168_readw,
.set_clock = sdhci_set_clock,
.get_max_clock = sdhci_pltfm_clk_get_max_clock,
.set_bus_width = pxav2_mmc_set_bus_width,
@@ -185,7 +202,7 @@ static int sdhci_pxav2_probe(struct platform_device *pdev)
pltfm_host = sdhci_priv(host);
pltfm_host->priv = pxa;
- clk = clk_get(dev, "PXA-SDHCLK");
+ clk = clk_get(dev, "NULL");
if (IS_ERR(clk)) {
dev_err(dev, "failed to get io clock\n");
ret = PTR_ERR(clk);
--
2.14.1