diff options
author | Tony Lindgren <tony@atomide.com> | 2012-05-08 19:23:33 -0400 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2012-05-08 19:23:33 -0400 |
commit | ad1b6662eb5fe293e8b402497b3835710848c389 (patch) | |
tree | 99295b6160eed041bf8301533084712b9754e61e /arch/arm | |
parent | 0135f6a04642c192bdf4b36e06937d3387e174ff (diff) |
ARM: OMAP2420: hwmod data: Add MMC hwmod data for 2420
Add MMC for 2420 so we can pass the DMA request lines the same
way as we already do on omap2430 and later.
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
[paul@pwsan.com: updated to apply on top of the 3.5 hwmod cleanup;
changed mmc hwmod name/class to "msdi" as documented in the 2420 TRM Rev X;
added sysconfig register information; added 16 bit register width flag;
added MSDI custom reset code]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-omap2/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap2/msdi.c | 88 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_2420_data.c | 64 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/mmc.h | 4 |
4 files changed, 159 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index d8604a3e490e..4eee0f139cbd 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -189,6 +189,9 @@ ifneq ($(CONFIG_TIDSPBRIDGE),) | |||
189 | obj-y += dsp.o | 189 | obj-y += dsp.o |
190 | endif | 190 | endif |
191 | 191 | ||
192 | # OMAP2420 MSDI controller integration support ("MMC") | ||
193 | obj-$(CONFIG_SOC_OMAP2420) += msdi.o | ||
194 | |||
192 | # Specific board support | 195 | # Specific board support |
193 | obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o | 196 | obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o |
194 | obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o | 197 | obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o |
diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c new file mode 100644 index 000000000000..ef2a6924731a --- /dev/null +++ b/arch/arm/mach-omap2/msdi.c | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * MSDI IP block reset | ||
3 | * | ||
4 | * Copyright (C) 2012 Texas Instruments, Inc. | ||
5 | * Paul Walmsley | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
19 | * 02110-1301 USA | ||
20 | * | ||
21 | * XXX What about pad muxing? | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | |||
26 | #include <plat/omap_hwmod.h> | ||
27 | #include <plat/mmc.h> | ||
28 | |||
29 | #include "common.h" | ||
30 | |||
31 | /* | ||
32 | * MSDI_CON_OFFSET: offset in bytes of the MSDI IP block's CON register | ||
33 | * from the IP block's base address | ||
34 | */ | ||
35 | #define MSDI_CON_OFFSET 0x0c | ||
36 | |||
37 | /* Register bitfields in the CON register */ | ||
38 | #define MSDI_CON_POW_MASK BIT(11) | ||
39 | #define MSDI_CON_CLKD_MASK (0x3f << 0) | ||
40 | #define MSDI_CON_CLKD_SHIFT 0 | ||
41 | |||
42 | /* Maximum microseconds to wait for OMAP module to softreset */ | ||
43 | #define MAX_MODULE_SOFTRESET_WAIT 10000 | ||
44 | |||
45 | /* MSDI_TARGET_RESET_CLKD: clock divisor to use throughout the reset */ | ||
46 | #define MSDI_TARGET_RESET_CLKD 0x3ff | ||
47 | |||
48 | /** | ||
49 | * omap_msdi_reset - reset the MSDI IP block | ||
50 | * @oh: struct omap_hwmod * | ||
51 | * | ||
52 | * The MSDI IP block on OMAP2420 has to have both the POW and CLKD | ||
53 | * fields set inside its CON register for a reset to complete | ||
54 | * successfully. This is not documented in the TRM. For CLKD, we use | ||
55 | * the value that results in the lowest possible clock rate, to attempt | ||
56 | * to avoid disturbing any cards. | ||
57 | */ | ||
58 | int omap_msdi_reset(struct omap_hwmod *oh) | ||
59 | { | ||
60 | u16 v = 0; | ||
61 | int c = 0; | ||
62 | |||
63 | /* Write to the SOFTRESET bit */ | ||
64 | omap_hwmod_softreset(oh); | ||
65 | |||
66 | /* Enable the MSDI core and internal clock */ | ||
67 | v |= MSDI_CON_POW_MASK; | ||
68 | v |= MSDI_TARGET_RESET_CLKD << MSDI_CON_CLKD_SHIFT; | ||
69 | omap_hwmod_write(v, oh, MSDI_CON_OFFSET); | ||
70 | |||
71 | /* Poll on RESETDONE bit */ | ||
72 | omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs) | ||
73 | & SYSS_RESETDONE_MASK), | ||
74 | MAX_MODULE_SOFTRESET_WAIT, c); | ||
75 | |||
76 | if (c == MAX_MODULE_SOFTRESET_WAIT) | ||
77 | pr_warning("%s: %s: softreset failed (waited %d usec)\n", | ||
78 | __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT); | ||
79 | else | ||
80 | pr_debug("%s: %s: softreset in %d usec\n", __func__, | ||
81 | oh->name, c); | ||
82 | |||
83 | /* Disable the MSDI internal clock */ | ||
84 | v &= ~MSDI_CON_CLKD_MASK; | ||
85 | omap_hwmod_write(v, oh, MSDI_CON_OFFSET); | ||
86 | |||
87 | return 0; | ||
88 | } | ||
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index 2c087ffc6a92..0c08d3f11f69 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <plat/dmtimer.h> | 23 | #include <plat/dmtimer.h> |
24 | #include <plat/l3_2xxx.h> | 24 | #include <plat/l3_2xxx.h> |
25 | #include <plat/l4_2xxx.h> | 25 | #include <plat/l4_2xxx.h> |
26 | #include <plat/mmc.h> | ||
26 | 27 | ||
27 | #include "omap_hwmod_common_data.h" | 28 | #include "omap_hwmod_common_data.h" |
28 | 29 | ||
@@ -239,6 +240,50 @@ static struct omap_hwmod omap2420_mcbsp2_hwmod = { | |||
239 | }, | 240 | }, |
240 | }; | 241 | }; |
241 | 242 | ||
243 | static struct omap_hwmod_class_sysconfig omap2420_msdi_sysc = { | ||
244 | .rev_offs = 0x3c, | ||
245 | .sysc_offs = 0x64, | ||
246 | .syss_offs = 0x68, | ||
247 | .sysc_flags = (SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), | ||
248 | .sysc_fields = &omap_hwmod_sysc_type1, | ||
249 | }; | ||
250 | |||
251 | static struct omap_hwmod_class omap2420_msdi_hwmod_class = { | ||
252 | .name = "msdi", | ||
253 | .sysc = &omap2420_msdi_sysc, | ||
254 | .reset = &omap_msdi_reset, | ||
255 | }; | ||
256 | |||
257 | /* msdi1 */ | ||
258 | static struct omap_hwmod_irq_info omap2420_msdi1_irqs[] = { | ||
259 | { .irq = 83 }, | ||
260 | { .irq = -1 } | ||
261 | }; | ||
262 | |||
263 | static struct omap_hwmod_dma_info omap2420_msdi1_sdma_reqs[] = { | ||
264 | { .name = "tx", .dma_req = 61 }, /* OMAP24XX_DMA_MMC1_TX */ | ||
265 | { .name = "rx", .dma_req = 62 }, /* OMAP24XX_DMA_MMC1_RX */ | ||
266 | { .dma_req = -1 } | ||
267 | }; | ||
268 | |||
269 | static struct omap_hwmod omap2420_msdi1_hwmod = { | ||
270 | .name = "msdi1", | ||
271 | .class = &omap2420_msdi_hwmod_class, | ||
272 | .mpu_irqs = omap2420_msdi1_irqs, | ||
273 | .sdma_reqs = omap2420_msdi1_sdma_reqs, | ||
274 | .main_clk = "mmc_fck", | ||
275 | .prcm = { | ||
276 | .omap2 = { | ||
277 | .prcm_reg_id = 1, | ||
278 | .module_bit = OMAP2420_EN_MMC_SHIFT, | ||
279 | .module_offs = CORE_MOD, | ||
280 | .idlest_reg_id = 1, | ||
281 | .idlest_idle_bit = OMAP2420_ST_MMC_SHIFT, | ||
282 | }, | ||
283 | }, | ||
284 | .flags = HWMOD_16BIT_REG, | ||
285 | }; | ||
286 | |||
242 | /* | 287 | /* |
243 | * interfaces | 288 | * interfaces |
244 | */ | 289 | */ |
@@ -428,6 +473,24 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp2 = { | |||
428 | .user = OCP_USER_MPU | OCP_USER_SDMA, | 473 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
429 | }; | 474 | }; |
430 | 475 | ||
476 | static struct omap_hwmod_addr_space omap2420_msdi1_addrs[] = { | ||
477 | { | ||
478 | .pa_start = 0x4809c000, | ||
479 | .pa_end = 0x4809c000 + SZ_128 - 1, | ||
480 | .flags = ADDR_TYPE_RT, | ||
481 | }, | ||
482 | { } | ||
483 | }; | ||
484 | |||
485 | /* l4_core -> msdi1 */ | ||
486 | static struct omap_hwmod_ocp_if omap2420_l4_core__msdi1 = { | ||
487 | .master = &omap2xxx_l4_core_hwmod, | ||
488 | .slave = &omap2420_msdi1_hwmod, | ||
489 | .clk = "mmc_ick", | ||
490 | .addr = omap2420_msdi1_addrs, | ||
491 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
492 | }; | ||
493 | |||
431 | static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = { | 494 | static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = { |
432 | &omap2xxx_l3_main__l4_core, | 495 | &omap2xxx_l3_main__l4_core, |
433 | &omap2xxx_mpu__l3_main, | 496 | &omap2xxx_mpu__l3_main, |
@@ -468,6 +531,7 @@ static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = { | |||
468 | &omap2420_l4_core__mailbox, | 531 | &omap2420_l4_core__mailbox, |
469 | &omap2420_l4_core__mcbsp1, | 532 | &omap2420_l4_core__mcbsp1, |
470 | &omap2420_l4_core__mcbsp2, | 533 | &omap2420_l4_core__mcbsp2, |
534 | &omap2420_l4_core__msdi1, | ||
471 | NULL, | 535 | NULL, |
472 | }; | 536 | }; |
473 | 537 | ||
diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h index 7a38750c0079..3e7ae0f0215f 100644 --- a/arch/arm/plat-omap/include/plat/mmc.h +++ b/arch/arm/plat-omap/include/plat/mmc.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/mmc/host.h> | 16 | #include <linux/mmc/host.h> |
17 | 17 | ||
18 | #include <plat/board.h> | 18 | #include <plat/board.h> |
19 | #include <plat/omap_hwmod.h> | ||
19 | 20 | ||
20 | #define OMAP15XX_NR_MMC 1 | 21 | #define OMAP15XX_NR_MMC 1 |
21 | #define OMAP16XX_NR_MMC 2 | 22 | #define OMAP16XX_NR_MMC 2 |
@@ -195,4 +196,7 @@ static inline int omap_mmc_add(const char *name, int id, unsigned long base, | |||
195 | } | 196 | } |
196 | 197 | ||
197 | #endif | 198 | #endif |
199 | |||
200 | extern int omap_msdi_reset(struct omap_hwmod *oh); | ||
201 | |||
198 | #endif | 202 | #endif |