]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
Xilinx: ARM: BSP: prevent DMA into lower memory
authorJohn Linn <john.linn@xilinx.com>
Tue, 13 Dec 2011 05:28:34 +0000 (21:28 -0800)
committerJohn Linn <john.linn@xilinx.com>
Tue, 13 Dec 2011 05:28:34 +0000 (21:28 -0800)
The DMA zone from 2.6.39 is no longer supported such that
a new method was needed. The old method was lost in the
move to 3.0 and USB was seeing failures.

arch/arm/mach-zynq/board_ep107.c
arch/arm/mach-zynq/board_zc770.c
arch/arm/mach-zynq/board_zc770_xm010.c
arch/arm/mach-zynq/common.c
arch/arm/mach-zynq/common.h
arch/arm/mm/init.c

index c1c7d31bc90f8084ae1c6d9486540472bf391853..e6446af77ae48dc88af683fdab30a42b6031b81d 100644 (file)
@@ -259,4 +259,5 @@ MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform")
        .init_machine   = board_ep107_init,
        .timer          = &xttcpss_sys_timer,
        .dt_compat      = xilinx_dt_match,
+       .reserve        = xilinx_memory_init,
 MACHINE_END
index 5ba14e1aa27b6f04cfce92dc119835dd99795c25..1b13cf0bee1f78072f5a3a73d12c212e93a1f566 100644 (file)
@@ -44,4 +44,5 @@ MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform")
        .init_machine   = board_zc770_init,
        .timer          = &xttcpss_sys_timer,
        .dt_compat      = xilinx_dt_match,
+       .reserve        = xilinx_memory_init,
 MACHINE_END
index e2de869dee9f7d9719d97ba25f49d4af908d1fba..c638bb954a5ccbfafd21800f6709677f2068a51b 100644 (file)
@@ -177,10 +177,11 @@ static const char *xilinx_dt_match[] = {
        NULL
 };
 
-MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform")
+MACHINE_START(XILINX, "Xilinx Zynq Platform")
        .map_io         = xilinx_map_io,
        .init_irq       = xilinx_irq_init,
        .init_machine   = board_zc770_xm010_init,
        .timer          = &xttcpss_sys_timer,
        .dt_compat      = xilinx_dt_match,
+       .reserve        = xilinx_memory_init,
 MACHINE_END
index 016104da95824f8e661e89737a2ae9154196d9e3..5fcdbdee624abfa9d4f462266664ed1a6ebf8f06 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/of.h>
-#include <linux/mmzone.h>
+#include <linux/memblock.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -47,35 +47,6 @@ static struct of_device_id zynq_of_bus_ids[] __initdata = {
        {}
 };
 
-#define DMA_ZONE_PAGES                 (SZ_32M >> PAGE_SHIFT)
-#define DMA_ZONE_HOLE_PAGES    (SZ_512K >> PAGE_SHIFT)
-
-/* Setup a special DMA memory zone to deal with the fact the from 0 - 512K cannot
- * be DMA-ed into. The size of the DMA zone is a bit arbitrary but doesn't hurt to
- * be larger as the memory allocator will use the DMA zone for normal if needed.
- */
-void xilinx_adjust_zones(unsigned long *zone_size, unsigned long *zhole_size)
-{
-       /* the normal zone has already been setup when this function is called and is
-        * assumed to be the only zone, this code is a bit confusing
-        */
-
-       pr_info("Xilinx: Adjusting memory zones to add DMA zone\n");
-
-       /* setup the zone sizes reducing the normal zone by the size
-        * of the DMA zone
-        */
-       zone_size[ZONE_NORMAL] = zone_size[0] - DMA_ZONE_PAGES;
-       zone_size[ZONE_DMA] = DMA_ZONE_PAGES;
-
-       /* setup the holes in each zone, the normal zone has the same hole it had
-        * on entry to this function which should be no hole
-        * the dma zone has a hole where DMA can't be done
-        */
-       zhole_size[ZONE_NORMAL] = zhole_size[0];
-       zhole_size[ZONE_DMA] = DMA_ZONE_HOLE_PAGES;     
-}
-
 /**
  * xilinx_init_machine() - System specific initialization, intended to be
  *                        called from board specific initialization.
@@ -183,3 +154,22 @@ void __init xilinx_map_io(void)
 {
        iotable_init(io_desc, ARRAY_SIZE(io_desc));
 }
+
+/**
+ * xilinx_memory_init() - Initialize special memory 
+ * 
+ * We need to stop things allocating the low memory as DMA can't work in
+ * the 1st 512K of memory.  Using reserve vs remove is not totally clear yet.
+ */
+void __init xilinx_memory_init()
+{
+       /* Reserve the 0-0x4000 addresses (before page tables and kernel)
+        * which can't be used for DMA
+        */ 
+       memblock_reserve(0, 0x4000);
+
+       /* the video frame buffer is in DDR and shouldn't be used by the kernel
+        * as it will be ioremapped by the frame buffer driver
+        */
+       memblock_remove(0xF000000, 0x1000000);
+}
index c2521a84ce7e66d9d110fc52008ec7c24efc4d20..ed453ffc1bd806f746cb61654c695d3434439dd8 100644 (file)
@@ -28,5 +28,6 @@ void platform_device_init(void);
 void xilinx_init_machine(void);
 void xilinx_irq_init(void);
 void xilinx_map_io(void);
+void xilinx_memory_init(void);
 
 #endif
index c19571c40a21ca62902d65cd01dcb8db9ea4f178..d12dfb9dc6087f23aa12a56ce1913301d0222167 100644 (file)
@@ -709,10 +709,16 @@ void free_initmem(void)
                                    "TCM link");
 #endif
 
+/* for Zynq, don't let the kernel free up this init memory as it will get
+ * used for DMAs (lower 512K) which is not allowed, the ARCH_ZYNQ isn't
+ * setup right to allow machine_is_zynq to work
+ */
+#ifndef CONFIG_ARCH_ZYNQ
        if (!machine_is_integrator() && !machine_is_cintegrator())
                totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)),
                                            __phys_to_pfn(__pa(__init_end)),
                                            "init");
+#endif
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD