|
@@ -58,7 +58,6 @@
|
|
|
#include <linux/debugfs.h>
|
|
|
#include <linux/log2.h>
|
|
|
#include <linux/syscore_ops.h>
|
|
|
-#include <linux/memblock.h>
|
|
|
|
|
|
/*
|
|
|
* DDR target is the same on all platforms.
|
|
@@ -103,9 +102,7 @@
|
|
|
|
|
|
/* Relative to mbusbridge_base */
|
|
|
#define MBUS_BRIDGE_CTRL_OFF 0x0
|
|
|
-#define MBUS_BRIDGE_SIZE_MASK 0xffff0000
|
|
|
#define MBUS_BRIDGE_BASE_OFF 0x4
|
|
|
-#define MBUS_BRIDGE_BASE_MASK 0xffff0000
|
|
|
|
|
|
/* Maximum number of windows, for all known platforms */
|
|
|
#define MBUS_WINS_MAX 20
|
|
@@ -579,106 +576,36 @@ static unsigned int armada_xp_mbus_win_remap_offset(int win)
|
|
|
return MVEBU_MBUS_NO_REMAP;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Use the memblock information to find the MBus bridge hole in the
|
|
|
- * physical address space.
|
|
|
- */
|
|
|
-static void __init
|
|
|
-mvebu_mbus_find_bridge_hole(uint64_t *start, uint64_t *end)
|
|
|
-{
|
|
|
- struct memblock_region *r;
|
|
|
- uint64_t s = 0;
|
|
|
-
|
|
|
- for_each_memblock(memory, r) {
|
|
|
- /*
|
|
|
- * This part of the memory is above 4 GB, so we don't
|
|
|
- * care for the MBus bridge hole.
|
|
|
- */
|
|
|
- if (r->base >= 0x100000000)
|
|
|
- continue;
|
|
|
-
|
|
|
- /*
|
|
|
- * The MBus bridge hole is at the end of the RAM under
|
|
|
- * the 4 GB limit.
|
|
|
- */
|
|
|
- if (r->base + r->size > s)
|
|
|
- s = r->base + r->size;
|
|
|
- }
|
|
|
-
|
|
|
- *start = s;
|
|
|
- *end = 0x100000000;
|
|
|
-}
|
|
|
-
|
|
|
static void __init
|
|
|
mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
|
|
|
{
|
|
|
int i;
|
|
|
int cs;
|
|
|
- uint64_t mbus_bridge_base, mbus_bridge_end;
|
|
|
|
|
|
mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
|
|
|
|
|
|
- mvebu_mbus_find_bridge_hole(&mbus_bridge_base, &mbus_bridge_end);
|
|
|
-
|
|
|
for (i = 0, cs = 0; i < 4; i++) {
|
|
|
- u64 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
|
|
|
- u64 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
|
|
|
- u64 end;
|
|
|
- struct mbus_dram_window *w;
|
|
|
-
|
|
|
- /* Ignore entries that are not enabled */
|
|
|
- if (!(size & DDR_SIZE_ENABLED))
|
|
|
- continue;
|
|
|
-
|
|
|
- /*
|
|
|
- * Ignore entries whose base address is above 2^32,
|
|
|
- * since devices cannot DMA to such high addresses
|
|
|
- */
|
|
|
- if (base & DDR_BASE_CS_HIGH_MASK)
|
|
|
- continue;
|
|
|
-
|
|
|
- base = base & DDR_BASE_CS_LOW_MASK;
|
|
|
- size = (size | ~DDR_SIZE_MASK) + 1;
|
|
|
- end = base + size;
|
|
|
-
|
|
|
- /*
|
|
|
- * Adjust base/size of the current CS to make sure it
|
|
|
- * doesn't overlap with the MBus bridge hole. This is
|
|
|
- * particularly important for devices that do DMA from
|
|
|
- * DRAM to a SRAM mapped in a MBus window, such as the
|
|
|
- * CESA cryptographic engine.
|
|
|
- */
|
|
|
+ u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
|
|
|
+ u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
|
|
|
|
|
|
/*
|
|
|
- * The CS is fully enclosed inside the MBus bridge
|
|
|
- * area, so ignore it.
|
|
|
+ * We only take care of entries for which the chip
|
|
|
+ * select is enabled, and that don't have high base
|
|
|
+ * address bits set (devices can only access the first
|
|
|
+ * 32 bits of the memory).
|
|
|
*/
|
|
|
- if (base >= mbus_bridge_base && end <= mbus_bridge_end)
|
|
|
- continue;
|
|
|
+ if ((size & DDR_SIZE_ENABLED) &&
|
|
|
+ !(base & DDR_BASE_CS_HIGH_MASK)) {
|
|
|
+ struct mbus_dram_window *w;
|
|
|
|
|
|
- /*
|
|
|
- * Beginning of CS overlaps with end of MBus, raise CS
|
|
|
- * base address, and shrink its size.
|
|
|
- */
|
|
|
- if (base >= mbus_bridge_base && end > mbus_bridge_end) {
|
|
|
- size -= mbus_bridge_end - base;
|
|
|
- base = mbus_bridge_end;
|
|
|
+ w = &mvebu_mbus_dram_info.cs[cs++];
|
|
|
+ w->cs_index = i;
|
|
|
+ w->mbus_attr = 0xf & ~(1 << i);
|
|
|
+ if (mbus->hw_io_coherency)
|
|
|
+ w->mbus_attr |= ATTR_HW_COHERENCY;
|
|
|
+ w->base = base & DDR_BASE_CS_LOW_MASK;
|
|
|
+ w->size = (size | ~DDR_SIZE_MASK) + 1;
|
|
|
}
|
|
|
-
|
|
|
- /*
|
|
|
- * End of CS overlaps with beginning of MBus, shrink
|
|
|
- * CS size.
|
|
|
- */
|
|
|
- if (base < mbus_bridge_base && end > mbus_bridge_base)
|
|
|
- size -= end - mbus_bridge_base;
|
|
|
-
|
|
|
- w = &mvebu_mbus_dram_info.cs[cs++];
|
|
|
- w->cs_index = i;
|
|
|
- w->mbus_attr = 0xf & ~(1 << i);
|
|
|
- if (mbus->hw_io_coherency)
|
|
|
- w->mbus_attr |= ATTR_HW_COHERENCY;
|
|
|
- w->base = base;
|
|
|
- w->size = size;
|
|
|
}
|
|
|
mvebu_mbus_dram_info.num_cs = cs;
|
|
|
}
|