aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2011-12-16 01:30:44 -0500
committerPaul Walmsley <paul@pwsan.com>2011-12-16 03:34:46 -0500
commita52e2ab66d4a9305e1ba64d9b9d25754b6c70895 (patch)
tree64d18a452c3db39ba381f73ff5a150b1adfd1b19
parentaf88fa9aa77c5623983c29cb219d6d746cafc852 (diff)
ARM: OMAP3: hwmod data: disable multiblock reads on MMC1/2 on OMAP34xx/35xx <= ES2.1
The HSMMC1/HSMMC2 host controllers on OMAP34xx and OMAP3503/3515/3525/3530 chips at ES levels prior to 3.0 can't do multiple block reads[1]. Mark the hwmod data appropriately. Reported by Dave Hylands <dhylands@gmail.com> and Steve Sakoman <sakoman@gmail.com>. Thanks to Steve Sakoman for further help testing this patch. 1. See for example Advisory 2.1.1.128 "MMC: Multiple Block Read Operation Issue" in _OMAP3530/3525/3515/3503 Silicon Errata_ Revision F (October 2010) (SPRZ278F), available from http://focus.ti.com/lit/er/sprz278f/sprz278f.pdf Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Dave Hylands <dhylands@gmail.com> Cc: Steve Sakoman <sakoman@gmail.com>
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c94
1 files changed, 90 insertions, 4 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 905fc44ae909..27f2fad49160 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -3125,7 +3125,35 @@ static struct omap_mmc_dev_attr mmc1_dev_attr = {
3125 .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, 3125 .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
3126}; 3126};
3127 3127
3128static struct omap_hwmod omap3xxx_mmc1_hwmod = { 3128/* See 35xx errata 2.1.1.128 in SPRZ278F */
3129static struct omap_mmc_dev_attr mmc1_pre_es3_dev_attr = {
3130 .flags = (OMAP_HSMMC_SUPPORTS_DUAL_VOLT |
3131 OMAP_HSMMC_BROKEN_MULTIBLOCK_READ),
3132};
3133
3134static struct omap_hwmod omap3xxx_pre_es3_mmc1_hwmod = {
3135 .name = "mmc1",
3136 .mpu_irqs = omap34xx_mmc1_mpu_irqs,
3137 .sdma_reqs = omap34xx_mmc1_sdma_reqs,
3138 .opt_clks = omap34xx_mmc1_opt_clks,
3139 .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc1_opt_clks),
3140 .main_clk = "mmchs1_fck",
3141 .prcm = {
3142 .omap2 = {
3143 .module_offs = CORE_MOD,
3144 .prcm_reg_id = 1,
3145 .module_bit = OMAP3430_EN_MMC1_SHIFT,
3146 .idlest_reg_id = 1,
3147 .idlest_idle_bit = OMAP3430_ST_MMC1_SHIFT,
3148 },
3149 },
3150 .dev_attr = &mmc1_pre_es3_dev_attr,
3151 .slaves = omap3xxx_mmc1_slaves,
3152 .slaves_cnt = ARRAY_SIZE(omap3xxx_mmc1_slaves),
3153 .class = &omap34xx_mmc_class,
3154};
3155
3156static struct omap_hwmod omap3xxx_es3plus_mmc1_hwmod = {
3129 .name = "mmc1", 3157 .name = "mmc1",
3130 .mpu_irqs = omap34xx_mmc1_mpu_irqs, 3158 .mpu_irqs = omap34xx_mmc1_mpu_irqs,
3131 .sdma_reqs = omap34xx_mmc1_sdma_reqs, 3159 .sdma_reqs = omap34xx_mmc1_sdma_reqs,
@@ -3168,7 +3196,34 @@ static struct omap_hwmod_ocp_if *omap3xxx_mmc2_slaves[] = {
3168 &omap3xxx_l4_core__mmc2, 3196 &omap3xxx_l4_core__mmc2,
3169}; 3197};
3170 3198
3171static struct omap_hwmod omap3xxx_mmc2_hwmod = { 3199/* See 35xx errata 2.1.1.128 in SPRZ278F */
3200static struct omap_mmc_dev_attr mmc2_pre_es3_dev_attr = {
3201 .flags = OMAP_HSMMC_BROKEN_MULTIBLOCK_READ,
3202};
3203
3204static struct omap_hwmod omap3xxx_pre_es3_mmc2_hwmod = {
3205 .name = "mmc2",
3206 .mpu_irqs = omap34xx_mmc2_mpu_irqs,
3207 .sdma_reqs = omap34xx_mmc2_sdma_reqs,
3208 .opt_clks = omap34xx_mmc2_opt_clks,
3209 .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc2_opt_clks),
3210 .main_clk = "mmchs2_fck",
3211 .prcm = {
3212 .omap2 = {
3213 .module_offs = CORE_MOD,
3214 .prcm_reg_id = 1,
3215 .module_bit = OMAP3430_EN_MMC2_SHIFT,
3216 .idlest_reg_id = 1,
3217 .idlest_idle_bit = OMAP3430_ST_MMC2_SHIFT,
3218 },
3219 },
3220 .dev_attr = &mmc2_pre_es3_dev_attr,
3221 .slaves = omap3xxx_mmc2_slaves,
3222 .slaves_cnt = ARRAY_SIZE(omap3xxx_mmc2_slaves),
3223 .class = &omap34xx_mmc_class,
3224};
3225
3226static struct omap_hwmod omap3xxx_es3plus_mmc2_hwmod = {
3172 .name = "mmc2", 3227 .name = "mmc2",
3173 .mpu_irqs = omap34xx_mmc2_mpu_irqs, 3228 .mpu_irqs = omap34xx_mmc2_mpu_irqs,
3174 .sdma_reqs = omap34xx_mmc2_sdma_reqs, 3229 .sdma_reqs = omap34xx_mmc2_sdma_reqs,
@@ -3447,8 +3502,6 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
3447 &omap3xxx_l4_core_hwmod, 3502 &omap3xxx_l4_core_hwmod,
3448 &omap3xxx_l4_per_hwmod, 3503 &omap3xxx_l4_per_hwmod,
3449 &omap3xxx_l4_wkup_hwmod, 3504 &omap3xxx_l4_wkup_hwmod,
3450 &omap3xxx_mmc1_hwmod,
3451 &omap3xxx_mmc2_hwmod,
3452 &omap3xxx_mmc3_hwmod, 3505 &omap3xxx_mmc3_hwmod,
3453 &omap3xxx_mpu_hwmod, 3506 &omap3xxx_mpu_hwmod,
3454 3507
@@ -3531,6 +3584,20 @@ static __initdata struct omap_hwmod *omap3430es2plus_hwmods[] = {
3531 NULL 3584 NULL
3532}; 3585};
3533 3586
3587/* <= 3430ES3-only hwmods */
3588static struct omap_hwmod *omap3430_pre_es3_hwmods[] __initdata = {
3589 &omap3xxx_pre_es3_mmc1_hwmod,
3590 &omap3xxx_pre_es3_mmc2_hwmod,
3591 NULL
3592};
3593
3594/* 3430ES3+-only hwmods */
3595static struct omap_hwmod *omap3430_es3plus_hwmods[] __initdata = {
3596 &omap3xxx_es3plus_mmc1_hwmod,
3597 &omap3xxx_es3plus_mmc2_hwmod,
3598 NULL
3599};
3600
3534/* 34xx-only hwmods (all ES revisions) */ 3601/* 34xx-only hwmods (all ES revisions) */
3535static __initdata struct omap_hwmod *omap34xx_hwmods[] = { 3602static __initdata struct omap_hwmod *omap34xx_hwmods[] = {
3536 &omap3xxx_iva_hwmod, 3603 &omap3xxx_iva_hwmod,
@@ -3551,6 +3618,8 @@ static __initdata struct omap_hwmod *omap36xx_hwmods[] = {
3551 &omap3xxx_mailbox_hwmod, 3618 &omap3xxx_mailbox_hwmod,
3552 &omap3xxx_usb_host_hs_hwmod, 3619 &omap3xxx_usb_host_hs_hwmod,
3553 &omap3xxx_usb_tll_hs_hwmod, 3620 &omap3xxx_usb_tll_hs_hwmod,
3621 &omap3xxx_es3plus_mmc1_hwmod,
3622 &omap3xxx_es3plus_mmc2_hwmod,
3554 NULL 3623 NULL
3555}; 3624};
3556 3625
@@ -3560,6 +3629,8 @@ static __initdata struct omap_hwmod *am35xx_hwmods[] = {
3560 &am35xx_uart4_hwmod, 3629 &am35xx_uart4_hwmod,
3561 &omap3xxx_usb_host_hs_hwmod, 3630 &omap3xxx_usb_host_hs_hwmod,
3562 &omap3xxx_usb_tll_hs_hwmod, 3631 &omap3xxx_usb_tll_hs_hwmod,
3632 &omap3xxx_es3plus_mmc1_hwmod,
3633 &omap3xxx_es3plus_mmc2_hwmod,
3563 NULL 3634 NULL
3564}; 3635};
3565 3636
@@ -3619,6 +3690,21 @@ int __init omap3xxx_hwmod_init(void)
3619 h = omap3430es2plus_hwmods; 3690 h = omap3430es2plus_hwmods;
3620 }; 3691 };
3621 3692
3693 if (h) {
3694 r = omap_hwmod_register(h);
3695 if (r < 0)
3696 return r;
3697 }
3698
3699 h = NULL;
3700 if (rev == OMAP3430_REV_ES1_0 || rev == OMAP3430_REV_ES2_0 ||
3701 rev == OMAP3430_REV_ES2_1) {
3702 h = omap3430_pre_es3_hwmods;
3703 } else if (rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 ||
3704 rev == OMAP3430_REV_ES3_1_2) {
3705 h = omap3430_es3plus_hwmods;
3706 };
3707
3622 if (h) 3708 if (h)
3623 r = omap_hwmod_register(h); 3709 r = omap_hwmod_register(h);
3624 3710