diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2015-06-01 11:03:44 -0400 |
|---|---|---|
| committer | Arnd Bergmann <arnd@arndb.de> | 2015-06-01 11:03:44 -0400 |
| commit | 8f1ab524b1b97e91356e1b34322b27c304e39e7f (patch) | |
| tree | 534b0f02334e068f16ec6287c2ffe334e68b694a /drivers/bus | |
| parent | e9d57102ba7d8576f28970075f6df04650d72355 (diff) | |
| parent | 885dbd154b2f2ee305cec6fd0a162e1a77ae2b06 (diff) | |
Merge tag 'mvebu-fixes-4.1-3' of git://git.infradead.org/linux-mvebu into fixes
Merge "mvebu fixes for 4.1 (part 3)" from Gregory CLEMENT:
Disable unused internal RTC for Mamba from linksys (Armada XP)
And 2 commits fixing regressions on mvebu-mbus:
- the first one for Kirkwood or Orion SoC
- the second one for DMA when the platform have more than 4GB (only
possible on Armada XP as far as I know)
* tag 'mvebu-fixes-4.1-3' of git://git.infradead.org/linux-mvebu:
Revert "bus: mvebu-mbus: make sure SDRAM CS for DMA don't overlap the MBus bridge window"
bus: mvebu-mbus: do not set WIN_CTRL_SYNCBARRIER on non io-coherent platforms.
ARM: mvebu: armada-xp-linksys-mamba: Disable internal RTC
Diffstat (limited to 'drivers/bus')
| -rw-r--r-- | drivers/bus/mvebu-mbus.c | 109 |
1 files changed, 19 insertions, 90 deletions
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index fb9ec6221730..6f047dcb94c2 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c | |||
| @@ -58,7 +58,6 @@ | |||
| 58 | #include <linux/debugfs.h> | 58 | #include <linux/debugfs.h> |
| 59 | #include <linux/log2.h> | 59 | #include <linux/log2.h> |
| 60 | #include <linux/syscore_ops.h> | 60 | #include <linux/syscore_ops.h> |
| 61 | #include <linux/memblock.h> | ||
| 62 | 61 | ||
| 63 | /* | 62 | /* |
| 64 | * DDR target is the same on all platforms. | 63 | * DDR target is the same on all platforms. |
| @@ -70,6 +69,7 @@ | |||
| 70 | */ | 69 | */ |
| 71 | #define WIN_CTRL_OFF 0x0000 | 70 | #define WIN_CTRL_OFF 0x0000 |
| 72 | #define WIN_CTRL_ENABLE BIT(0) | 71 | #define WIN_CTRL_ENABLE BIT(0) |
| 72 | /* Only on HW I/O coherency capable platforms */ | ||
| 73 | #define WIN_CTRL_SYNCBARRIER BIT(1) | 73 | #define WIN_CTRL_SYNCBARRIER BIT(1) |
| 74 | #define WIN_CTRL_TGT_MASK 0xf0 | 74 | #define WIN_CTRL_TGT_MASK 0xf0 |
| 75 | #define WIN_CTRL_TGT_SHIFT 4 | 75 | #define WIN_CTRL_TGT_SHIFT 4 |
| @@ -102,9 +102,7 @@ | |||
| 102 | 102 | ||
| 103 | /* Relative to mbusbridge_base */ | 103 | /* Relative to mbusbridge_base */ |
| 104 | #define MBUS_BRIDGE_CTRL_OFF 0x0 | 104 | #define MBUS_BRIDGE_CTRL_OFF 0x0 |
| 105 | #define MBUS_BRIDGE_SIZE_MASK 0xffff0000 | ||
| 106 | #define MBUS_BRIDGE_BASE_OFF 0x4 | 105 | #define MBUS_BRIDGE_BASE_OFF 0x4 |
| 107 | #define MBUS_BRIDGE_BASE_MASK 0xffff0000 | ||
| 108 | 106 | ||
| 109 | /* Maximum number of windows, for all known platforms */ | 107 | /* Maximum number of windows, for all known platforms */ |
| 110 | #define MBUS_WINS_MAX 20 | 108 | #define MBUS_WINS_MAX 20 |
| @@ -323,8 +321,9 @@ static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus, | |||
| 323 | ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) | | 321 | ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) | |
| 324 | (attr << WIN_CTRL_ATTR_SHIFT) | | 322 | (attr << WIN_CTRL_ATTR_SHIFT) | |
| 325 | (target << WIN_CTRL_TGT_SHIFT) | | 323 | (target << WIN_CTRL_TGT_SHIFT) | |
| 326 | WIN_CTRL_SYNCBARRIER | | ||
| 327 | WIN_CTRL_ENABLE; | 324 | WIN_CTRL_ENABLE; |
| 325 | if (mbus->hw_io_coherency) | ||
| 326 | ctrl |= WIN_CTRL_SYNCBARRIER; | ||
| 328 | 327 | ||
| 329 | writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF); | 328 | writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF); |
| 330 | writel(ctrl, addr + WIN_CTRL_OFF); | 329 | writel(ctrl, addr + WIN_CTRL_OFF); |
| @@ -577,106 +576,36 @@ static unsigned int armada_xp_mbus_win_remap_offset(int win) | |||
| 577 | return MVEBU_MBUS_NO_REMAP; | 576 | return MVEBU_MBUS_NO_REMAP; |
| 578 | } | 577 | } |
| 579 | 578 | ||
| 580 | /* | ||
| 581 | * Use the memblock information to find the MBus bridge hole in the | ||
| 582 | * physical address space. | ||
| 583 | */ | ||
| 584 | static void __init | ||
| 585 | mvebu_mbus_find_bridge_hole(uint64_t *start, uint64_t *end) | ||
| 586 | { | ||
| 587 | struct memblock_region *r; | ||
| 588 | uint64_t s = 0; | ||
| 589 | |||
| 590 | for_each_memblock(memory, r) { | ||
| 591 | /* | ||
| 592 | * This part of the memory is above 4 GB, so we don't | ||
| 593 | * care for the MBus bridge hole. | ||
| 594 | */ | ||
| 595 | if (r->base >= 0x100000000) | ||
| 596 | continue; | ||
| 597 | |||
| 598 | /* | ||
| 599 | * The MBus bridge hole is at the end of the RAM under | ||
| 600 | * the 4 GB limit. | ||
| 601 | */ | ||
| 602 | if (r->base + r->size > s) | ||
| 603 | s = r->base + r->size; | ||
| 604 | } | ||
| 605 | |||
| 606 | *start = s; | ||
| 607 | *end = 0x100000000; | ||
| 608 | } | ||
| 609 | |||
| 610 | static void __init | 579 | static void __init |
| 611 | mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus) | 580 | mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus) |
| 612 | { | 581 | { |
| 613 | int i; | 582 | int i; |
| 614 | int cs; | 583 | int cs; |
| 615 | uint64_t mbus_bridge_base, mbus_bridge_end; | ||
| 616 | 584 | ||
| 617 | mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; | 585 | mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; |
| 618 | 586 | ||
| 619 | mvebu_mbus_find_bridge_hole(&mbus_bridge_base, &mbus_bridge_end); | ||
| 620 | |||
| 621 | for (i = 0, cs = 0; i < 4; i++) { | 587 | for (i = 0, cs = 0; i < 4; i++) { |
| 622 | u64 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i)); | 588 | u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i)); |
| 623 | u64 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i)); | 589 | u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i)); |
| 624 | u64 end; | ||
| 625 | struct mbus_dram_window *w; | ||
| 626 | |||
| 627 | /* Ignore entries that are not enabled */ | ||
| 628 | if (!(size & DDR_SIZE_ENABLED)) | ||
| 629 | continue; | ||
| 630 | |||
| 631 | /* | ||
| 632 | * Ignore entries whose base address is above 2^32, | ||
| 633 | * since devices cannot DMA to such high addresses | ||
| 634 | */ | ||
| 635 | if (base & DDR_BASE_CS_HIGH_MASK) | ||
| 636 | continue; | ||
| 637 | |||
| 638 | base = base & DDR_BASE_CS_LOW_MASK; | ||
| 639 | size = (size | ~DDR_SIZE_MASK) + 1; | ||
| 640 | end = base + size; | ||
| 641 | |||
| 642 | /* | ||
| 643 | * Adjust base/size of the current CS to make sure it | ||
| 644 | * doesn't overlap with the MBus bridge hole. This is | ||
| 645 | * particularly important for devices that do DMA from | ||
| 646 | * DRAM to a SRAM mapped in a MBus window, such as the | ||
| 647 | * CESA cryptographic engine. | ||
| 648 | */ | ||
| 649 | 590 | ||
| 650 | /* | 591 | /* |
| 651 | * The CS is fully enclosed inside the MBus bridge | 592 | * We only take care of entries for which the chip |
| 652 | * area, so ignore it. | 593 | * select is enabled, and that don't have high base |
| 594 | * address bits set (devices can only access the first | ||
| 595 | * 32 bits of the memory). | ||
| 653 | */ | 596 | */ |
| 654 | if (base >= mbus_bridge_base && end <= mbus_bridge_end) | 597 | if ((size & DDR_SIZE_ENABLED) && |
| 655 | continue; | 598 | !(base & DDR_BASE_CS_HIGH_MASK)) { |
| 599 | struct mbus_dram_window *w; | ||
| 656 | 600 | ||
| 657 | /* | 601 | w = &mvebu_mbus_dram_info.cs[cs++]; |
| 658 | * Beginning of CS overlaps with end of MBus, raise CS | 602 | w->cs_index = i; |
| 659 | * base address, and shrink its size. | 603 | w->mbus_attr = 0xf & ~(1 << i); |
| 660 | */ | 604 | if (mbus->hw_io_coherency) |
| 661 | if (base >= mbus_bridge_base && end > mbus_bridge_end) { | 605 | w->mbus_attr |= ATTR_HW_COHERENCY; |
| 662 | size -= mbus_bridge_end - base; | 606 | w->base = base & DDR_BASE_CS_LOW_MASK; |
| 663 | base = mbus_bridge_end; | 607 | w->size = (size | ~DDR_SIZE_MASK) + 1; |
| 664 | } | 608 | } |
| 665 | |||
| 666 | /* | ||
| 667 | * End of CS overlaps with beginning of MBus, shrink | ||
| 668 | * CS size. | ||
| 669 | */ | ||
| 670 | if (base < mbus_bridge_base && end > mbus_bridge_base) | ||
| 671 | size -= end - mbus_bridge_base; | ||
| 672 | |||
| 673 | w = &mvebu_mbus_dram_info.cs[cs++]; | ||
| 674 | w->cs_index = i; | ||
| 675 | w->mbus_attr = 0xf & ~(1 << i); | ||
| 676 | if (mbus->hw_io_coherency) | ||
| 677 | w->mbus_attr |= ATTR_HW_COHERENCY; | ||
| 678 | w->base = base; | ||
| 679 | w->size = size; | ||
| 680 | } | 609 | } |
| 681 | mvebu_mbus_dram_info.num_cs = cs; | 610 | mvebu_mbus_dram_info.num_cs = cs; |
| 682 | } | 611 | } |
