]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
davinci: add SRAM allocator
authorDavid Brownell <dbrownell@users.sourceforge.net>
Thu, 7 May 2009 16:31:42 +0000 (09:31 -0700)
committerKevin Hilman <khilman@deeprootsystems.com>
Thu, 28 May 2009 22:18:13 +0000 (15:18 -0700)
Provide a generic SRAM allocator using genalloc, and vaguely
modeled after what AVR32 uses.  This builds on top of the
static CPU mapping set up in the previous patch, and returns
DMA mappings as requested (if possible).

Compared to its OMAP cousin, there's no current support for
(currently non-existent) DaVinci power management code running
in SRAM; and this has ways to deallocate, instead of being
allocate-only.

The initial user of this should probably be the audio code,
because EDMA from DDR is subject to various dropouts on at
least DM355 and DM6446 chips.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
arch/arm/Kconfig
arch/arm/mach-davinci/Makefile
arch/arm/mach-davinci/include/mach/sram.h [new file with mode: 0644]
arch/arm/mach-davinci/sram.c [new file with mode: 0644]

index 9d02cdb15b23dc6d4524cf61db4153c810639580..915b39382e65979f71bfbafd209602da9f7480d3 100644 (file)
@@ -587,6 +587,7 @@ config ARCH_DAVINCI
        select ZONE_DMA
        select HAVE_IDE
        select COMMON_CLKDEV
+       select GENERIC_ALLOCATOR
        help
          Support for TI's DaVinci platform.
 
index 5b62d8a4b180cd608b2517a48b33d864c3985e85..059ab78084baa32e04cf723efc2e2684dcc763d7 100644 (file)
@@ -5,7 +5,7 @@
 
 # Common objects
 obj-y                  := time.o clock.o serial.o io.o psc.o \
-                          gpio.o devices.o dma.o usb.o common.o
+                          gpio.o devices.o dma.o usb.o common.o sram.o
 
 obj-$(CONFIG_DAVINCI_MUX)              += mux.o
 
diff --git a/arch/arm/mach-davinci/include/mach/sram.h b/arch/arm/mach-davinci/include/mach/sram.h
new file mode 100644 (file)
index 0000000..111f7cc
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * mach/sram.h - DaVinci simple SRAM allocator
+ *
+ * Copyright (C) 2009 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __MACH_SRAM_H
+#define __MACH_SRAM_H
+
+/* ARBITRARY:  SRAM allocations are multiples of this 2^N size */
+#define SRAM_GRANULARITY       512
+
+/*
+ * SRAM allocations return a CPU virtual address, or NULL on error.
+ * If a DMA address is requested and the SRAM supports DMA, its
+ * mapped address is also returned.
+ *
+ * Errors include SRAM memory not being available, and requesting
+ * DMA mapped SRAM on systems which don't allow that.
+ */
+extern void *sram_alloc(size_t len, dma_addr_t *dma);
+extern void sram_free(void *addr, size_t len);
+
+#endif /* __MACH_SRAM_H */
diff --git a/arch/arm/mach-davinci/sram.c b/arch/arm/mach-davinci/sram.c
new file mode 100644 (file)
index 0000000..db54b2a
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * mach-davinci/sram.c - DaVinci simple SRAM allocator
+ *
+ * Copyright (C) 2009 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/genalloc.h>
+
+#include <mach/common.h>
+#include <mach/memory.h>
+#include <mach/sram.h>
+
+
+static struct gen_pool *sram_pool;
+
+void *sram_alloc(size_t len, dma_addr_t *dma)
+{
+       unsigned long vaddr;
+       dma_addr_t dma_base = davinci_soc_info.sram_dma;
+
+       if (dma)
+               *dma = 0;
+       if (!sram_pool || (dma && !dma_base))
+               return NULL;
+
+       vaddr = gen_pool_alloc(sram_pool, len);
+       if (!vaddr)
+               return NULL;
+
+       if (dma)
+               *dma = dma_base + (vaddr - SRAM_VIRT);
+       return (void *)vaddr;
+
+}
+EXPORT_SYMBOL(sram_alloc);
+
+void sram_free(void *addr, size_t len)
+{
+       gen_pool_free(sram_pool, (unsigned long) addr, len);
+}
+EXPORT_SYMBOL(sram_free);
+
+
+/*
+ * REVISIT This supports CPU and DMA access to/from SRAM, but it
+ * doesn't (yet?) support some other notable uses of SRAM:  as TCM
+ * for data and/or instructions; and holding code needed to enter
+ * and exit suspend states (while DRAM can't be used).
+ */
+static int __init sram_init(void)
+{
+       unsigned len = davinci_soc_info.sram_len;
+       int status = 0;
+
+       if (len) {
+               len = min(len, SRAM_SIZE);
+               sram_pool = gen_pool_create(ilog2(SRAM_GRANULARITY), -1);
+               if (!sram_pool)
+                       status = -ENOMEM;
+       }
+       if (sram_pool)
+               status = gen_pool_add(sram_pool, SRAM_VIRT, len, -1);
+       WARN_ON(status < 0);
+       return status;
+}
+core_initcall(sram_init);
+