修訂 | 64abfc9b6bb3721621d5132e112ae2e91c57d8bb (tree) |
---|---|
時間 | 2019-01-10 23:28:28 |
作者 | Tom Rini <trini@kons...> |
Commiter | Tom Rini |
Merge branch 'master' of git://git.denx.de/u-boot-sunxi
@@ -19,6 +19,13 @@ | ||
19 | 19 | #include <asm/arch/mmc.h> |
20 | 20 | #include <asm-generic/gpio.h> |
21 | 21 | |
22 | +#ifdef CONFIG_DM_MMC | |
23 | +struct sunxi_mmc_variant { | |
24 | + u16 gate_offset; | |
25 | + u16 mclk_offset; | |
26 | +}; | |
27 | +#endif | |
28 | + | |
22 | 29 | struct sunxi_mmc_plat { |
23 | 30 | struct mmc_config cfg; |
24 | 31 | struct mmc mmc; |
@@ -32,6 +39,9 @@ struct sunxi_mmc_priv { | ||
32 | 39 | int cd_inverted; /* Inverted Card Detect */ |
33 | 40 | struct sunxi_mmc *reg; |
34 | 41 | struct mmc_config cfg; |
42 | +#ifdef CONFIG_DM_MMC | |
43 | + const struct sunxi_mmc_variant *variant; | |
44 | +#endif | |
35 | 45 | }; |
36 | 46 | |
37 | 47 | #if !CONFIG_IS_ENABLED(DM_MMC) |
@@ -599,7 +609,7 @@ static int sunxi_mmc_probe(struct udevice *dev) | ||
599 | 609 | struct sunxi_mmc_priv *priv = dev_get_priv(dev); |
600 | 610 | struct mmc_config *cfg = &plat->cfg; |
601 | 611 | struct ofnode_phandle_args args; |
602 | - u32 *gate_reg; | |
612 | + u32 *gate_reg, *ccu_reg; | |
603 | 613 | int bus_width, ret; |
604 | 614 | |
605 | 615 | cfg->name = dev->name; |
@@ -618,21 +628,21 @@ static int sunxi_mmc_probe(struct udevice *dev) | ||
618 | 628 | cfg->f_max = 52000000; |
619 | 629 | |
620 | 630 | priv->reg = (void *)dev_read_addr(dev); |
631 | + priv->variant = | |
632 | + (const struct sunxi_mmc_variant *)dev_get_driver_data(dev); | |
621 | 633 | |
622 | 634 | /* We don't have a sunxi clock driver so find the clock address here */ |
623 | 635 | ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0, |
624 | 636 | 1, &args); |
625 | 637 | if (ret) |
626 | 638 | return ret; |
627 | - priv->mclkreg = (u32 *)ofnode_get_addr(args.node); | |
639 | + ccu_reg = (u32 *)ofnode_get_addr(args.node); | |
628 | 640 | |
629 | - ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0, | |
630 | - 0, &args); | |
631 | - if (ret) | |
632 | - return ret; | |
633 | - gate_reg = (u32 *)ofnode_get_addr(args.node); | |
634 | - setbits_le32(gate_reg, 1 << args.args[0]); | |
635 | - priv->mmc_no = args.args[0] - 8; | |
641 | + priv->mmc_no = ((uintptr_t)priv->reg - SUNXI_MMC0_BASE) / 0x1000; | |
642 | + priv->mclkreg = (void *)ccu_reg + | |
643 | + (priv->variant->mclk_offset + (priv->mmc_no * 4)); | |
644 | + gate_reg = (void *)ccu_reg + priv->variant->gate_offset; | |
645 | + setbits_le32(gate_reg, BIT(AHB_GATE_OFFSET_MMC(priv->mmc_no))); | |
636 | 646 | |
637 | 647 | ret = mmc_set_mod_clk(priv, 24000000); |
638 | 648 | if (ret) |
@@ -665,11 +675,25 @@ static int sunxi_mmc_bind(struct udevice *dev) | ||
665 | 675 | return mmc_bind(dev, &plat->mmc, &plat->cfg); |
666 | 676 | } |
667 | 677 | |
678 | +static const struct sunxi_mmc_variant sun4i_a10_variant = { | |
679 | + .gate_offset = 0x60, | |
680 | + .mclk_offset = 0x88, | |
681 | +}; | |
682 | + | |
668 | 683 | static const struct udevice_id sunxi_mmc_ids[] = { |
669 | - { .compatible = "allwinner,sun4i-a10-mmc" }, | |
670 | - { .compatible = "allwinner,sun5i-a13-mmc" }, | |
671 | - { .compatible = "allwinner,sun7i-a20-mmc" }, | |
672 | - { } | |
684 | + { | |
685 | + .compatible = "allwinner,sun4i-a10-mmc", | |
686 | + .data = (ulong)&sun4i_a10_variant, | |
687 | + }, | |
688 | + { | |
689 | + .compatible = "allwinner,sun5i-a13-mmc", | |
690 | + .data = (ulong)&sun4i_a10_variant, | |
691 | + }, | |
692 | + { | |
693 | + .compatible = "allwinner,sun7i-a20-mmc", | |
694 | + .data = (ulong)&sun4i_a10_variant, | |
695 | + }, | |
696 | + { /* sentinel */ } | |
673 | 697 | }; |
674 | 698 | |
675 | 699 | U_BOOT_DRIVER(sunxi_mmc_drv) = { |