rk29: add sram support
author黄涛 <huangtao@rock-chips.com>
Tue, 25 Jan 2011 12:30:13 +0000 (20:30 +0800)
committer黄涛 <huangtao@rock-chips.com>
Tue, 25 Jan 2011 12:30:13 +0000 (20:30 +0800)
arch/arm/kernel/vmlinux.lds.S
arch/arm/mach-rk29/Makefile
arch/arm/mach-rk29/board-rk29-aigo.c
arch/arm/mach-rk29/board-rk29-winaccord.c
arch/arm/mach-rk29/board-rk29sdk.c
arch/arm/mach-rk29/include/mach/memory.h
arch/arm/mach-rk29/include/mach/sram.h [new file with mode: 0644]
arch/arm/mach-rk29/sram.c [new file with mode: 0644]

index aecf87dfbaec2357355889871e6bc6e43412a5f3..5d972f1c97708f259d50213b1faf4168b0b57235 100644 (file)
@@ -255,6 +255,62 @@ SECTIONS
                __tcm_end = .;
        }
 #endif
+#ifdef CONFIG_ARCH_RK29
+        /*
+        * We align everything to a page boundary so we can
+        * free it after init has commenced and SRAM contents have
+        * been copied to its destination.
+        */
+       .sram_start : {
+               . = ALIGN(PAGE_SIZE);
+               __sram_start = .;
+               __sram_code_start = .;
+       }
+
+       /*
+        * Link these to the ITCM RAM
+        * Put VMA to the TCM address and LMA to the common RAM
+        * and we'll upload the contents from RAM to TCM and free
+        * the used RAM after that.
+        */
+       .text_sram_code SRAM_CODE_OFFSET : AT(__sram_code_start)
+       {
+               __ssram_code_text = .;
+               *(.sram.text)
+               *(.sram.rodata)
+               . = ALIGN(4);
+               __esram_code_text = .;
+       }
+
+       /*
+        * Reset the dot pointer, this is needed to create the
+        * relative __dtcm_start below (to be used as extern in code).
+        */
+       . = ADDR(.sram_start) + SIZEOF(.sram_start) + SIZEOF(.text_sram_code);
+
+       .sram_data_start : {
+               __sram_data_start = .;
+       }
+
+       /* TODO: add remainder of ITCM as well, that can be used for data! */
+       .data_sram SRAM_DATA_OFFSET : AT(__sram_data_start)
+       {
+               . = ALIGN(4);
+               __ssram_data = .;
+               *(.sram.data)
+               . = ALIGN(4);
+               __esram_data = .;
+       }
+
+       /* Reset the dot pointer or the linker gets confused */
+       . = ADDR(.sram_data_start) + SIZEOF(.data_sram);
+
+       /* End marker for freeing TCM copy in linked object */
+       .sram_end : AT(ADDR(.sram_data_start) + SIZEOF(.data_sram)){
+               . = ALIGN(PAGE_SIZE);
+               __sram_end = .;
+       }
+#endif
 
        .bss : {
                __bss_start = .;        /* BSS                          */
index e8dab6f06307759628a101b74b874fe192f19df4..4d91315eb97a57ee7d9f01789d782b568e267ded 100755 (executable)
@@ -1,4 +1,4 @@
-obj-y += timer.o io.o devices.o iomux.o clock.o rk29-pl330.o dma.o gpio.o
+obj-y += timer.o io.o devices.o iomux.o clock.o rk29-pl330.o dma.o gpio.o sram.o
 obj-$(CONFIG_CPU_FREQ) += cpufreq.o
 obj-$(CONFIG_RK29_VPU) += vpu.o vpu_mem.o
 obj-$(CONFIG_MACH_RK29SDK) += board-rk29sdk.o board-rk29sdk-key.o board-rk29sdk-rfkill.o
index 6018c6bba7b9f347faeee7b19f8a5be22e85f7ad..e0fb50d881e5ed0401f585c0073bf4077009e226 100644 (file)
@@ -42,6 +42,7 @@
 #include <mach/rk29_camera.h>                          /* ddl@rock-chips.com : camera support */\r
 #include <media/soc_camera.h>                               /* ddl@rock-chips.com : camera support */\r
 #include <mach/vpu_mem.h>\r
+#include <mach/sram.h>\r
 \r
 #include <linux/regulator/rk29-pwm-regulator.h>\r
 #include <linux/regulator/machine.h>\r
@@ -1816,6 +1817,7 @@ static void __init machine_rk29_fixup(struct machine_desc *desc, struct tag *tag
 static void __init machine_rk29_mapio(void)\r
 {\r
        rk29_map_common_io();\r
+       rk29_sram_init();\r
        rk29_clock_init();\r
        rk29_iomux_init();\r
 }\r
index ea21ea7c7dd7a1e86aede14a54576057a7b4e97b..39cc2e81640c3d31d6deb456668f93e669a27254 100644 (file)
@@ -42,6 +42,7 @@
 #include <mach/rk29_camera.h>                          /* ddl@rock-chips.com : camera support */
 #include <media/soc_camera.h>                               /* ddl@rock-chips.com : camera support */
 #include <mach/vpu_mem.h>
+#include <mach/sram.h>
 
 #include <linux/regulator/rk29-pwm-regulator.h>
 #include <linux/regulator/machine.h>
@@ -1719,6 +1720,7 @@ static void __init machine_rk29_fixup(struct machine_desc *desc, struct tag *tag
 static void __init machine_rk29_mapio(void)
 {
        rk29_map_common_io();
+       rk29_sram_init();
        rk29_clock_init();
        rk29_iomux_init();
 }
index 46d7998aa8abb2fd216e66bacae0189a07b96bca..0f9d9d8a92ad70045fc07436e8485ab5a2e952ee 100755 (executable)
@@ -42,6 +42,7 @@
 #include <mach/rk29_camera.h>                          /* ddl@rock-chips.com : camera support */
 #include <media/soc_camera.h>                               /* ddl@rock-chips.com : camera support */
 #include <mach/vpu_mem.h>
+#include <mach/sram.h>
 
 #include <linux/regulator/rk29-pwm-regulator.h>
 #include <linux/regulator/machine.h>
@@ -1793,6 +1794,7 @@ static void __init machine_rk29_fixup(struct machine_desc *desc, struct tag *tag
 static void __init machine_rk29_mapio(void)
 {
        rk29_map_common_io();
+       rk29_sram_init();
        rk29_clock_init();
        rk29_iomux_init();
 }
index 3dfc5036818a186a2b160a0471f725d5711ee2df..7492e70ee306f506dc20d162cc7cf744517b4d4f 100644 (file)
 
 #define CONSISTENT_DMA_SIZE    SZ_8M
 
+/*
+ * SRAM memory whereabouts
+ */
+#define SRAM_CODE_OFFSET       0xff400000
+#define SRAM_CODE_END          0xff401fff
+#define SRAM_DATA_OFFSET       0xff402000
+#define SRAM_DATA_END          0xff403fff
+
 #endif
 
diff --git a/arch/arm/mach-rk29/include/mach/sram.h b/arch/arm/mach-rk29/include/mach/sram.h
new file mode 100644 (file)
index 0000000..a7f9149
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * TCM memory handling for ARM systems
+ *
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ * Author: Rickard Andersson <rickard.andersson@stericsson.com>
+ */
+
+#ifdef CONFIG_ARCH_RK29
+
+/* Tag variables with this */
+#define __sramdata __section(.sram.data)
+/* Tag constants with this */
+#define __sramconst __section(.sram.rodata)
+/* Tag functions inside SRAM called from outside SRAM with this */
+#define __sramfunc __attribute__((long_call)) __section(.sram.text) noinline
+/* Tag function inside SRAM called from inside SRAM  with this */
+#define __sramlocalfunc __section(.sram.text)
+
+void __init rk29_sram_init(void);
+
+static inline unsigned long ddr_save_sp(unsigned long new_sp)
+{
+       unsigned long old_sp;
+
+       asm volatile ("mov %0, sp" : "=r" (old_sp));
+       asm volatile ("mov sp, %0" :: "r" (new_sp));
+       return old_sp;
+}
+
+// save_sp ±ØÐ붨ÒåΪȫ¾Ö±äÁ¿
+#define DDR_SAVE_SP(save_sp)           do { save_sp = ddr_save_sp((SRAM_DATA_END&(~7))); } while (0)
+#define DDR_RESTORE_SP(save_sp)                do { ddr_save_sp(save_sp); } while (0)
+
+#endif
+
diff --git a/arch/arm/mach-rk29/sram.c b/arch/arm/mach-rk29/sram.c
new file mode 100644 (file)
index 0000000..5d9bd09
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * TCM memory handling for ARM systems
+ *
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ * Author: Rickard Andersson <rickard.andersson@stericsson.com>
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <linux/ioport.h>
+#include <linux/genalloc.h>
+#include <linux/string.h> /* memcpy */
+#include <asm/page.h> /* PAGE_SHIFT */
+#include <asm/cputype.h>
+#include <asm/mach/map.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+#include <mach/memory.h>\r
+#include <mach/rk29_iomap.h>
+\r
+\r
+/* SRAM section definitions from the linker */\r
+extern char __sram_code_start, __ssram_code_text, __esram_code_text;\r
+extern char __sram_data_start, __ssram_data, __esram_data;\r
+\r
+static struct map_desc sram_code_iomap[] __initdata = {\r
+       {
+               .virtual        = SRAM_CODE_OFFSET,\r
+//             .pfn            = __phys_to_pfn(RK29_SRAM_PHYS),\r
+               .pfn            = __phys_to_pfn(0x0),
+       //      .length         =  (SRAM_CODE_END - SRAM_CODE_OFFSET + 1),\r
+               .length         =  1024*1024, // (SRAM_CODE_END - SRAM_CODE_OFFSET + 1),
+               .type           =  MT_MEMORY//MT_MEMORY //MT_HIGH_VECTORS//MT_MEMORY //MT_UNCACHED
+       }
+};
+
+static struct map_desc sram_data_iomap[] __initdata = {\r
+       {
+               .virtual        = SRAM_DATA_OFFSET,\r
+       //      .pfn            = __phys_to_pfn(RK29_SRAM_PHYS+0x2000),\r
+               .pfn            = __phys_to_pfn(0x2000),
+               .length         = (SRAM_DATA_END - SRAM_DATA_OFFSET + 1),\r
+               .type           = MT_HIGH_VECTORS //MT_MEMORY //MT_UNCACHED
+       }
+};\r
+\r
+\r
+int __init rk29_sram_init(void)\r
+{\r
+       char *start;\r
+       char *end;
+       char *ram;\r
+       \r
+       iotable_init(sram_code_iomap, 1);
+//       iotable_init(sram_data_iomap, 1);
+          
+       /*
+        * Normally devicemaps_init() would flush caches and tlb after
+        * mdesc->map_io(), but since we're called from map_io(), we
+        * must do it here.
+        */
+       local_flush_tlb_all();
+       flush_cache_all();
+
+        memset((char *)SRAM_CODE_OFFSET,0x0,(SRAM_CODE_END - SRAM_CODE_OFFSET + 1));
+       memset((char *)SRAM_DATA_OFFSET,0x0,(SRAM_DATA_END - SRAM_DATA_OFFSET + 1));
+       
+       /* Copy code from RAM to SRAM CODE */\r
+       start = &__ssram_code_text;\r
+       end   = &__esram_code_text;\r
+       ram   = &__sram_code_start;\r
+       memcpy(start, ram, (end-start));\r
+       flush_icache_range((unsigned long) start, (unsigned long) end);
+\r
+       printk("CPU SRAM: copied sram code from %p to %p - %p \n", ram, start, end);
+       printk("%08x %08x\n", *(u32 *)0xFF400628, *(u32 *)0xFF40062C);
+//     extern void DDR_EnterSelfRefresh();
+//     DDR_EnterSelfRefresh();
+
+       printk("CPU SRAM: start = [%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x]\n",\r
+               start[0],start[1],start[2],start[3],start[4],start[5],start[6],start[7],start[8],start[9],start[10],start[11],start[12],start[13],start[14],start[15]);
+       start += 0x10;
+       printk("CPU SRAM: start = [%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x]\n",\r
+               start[0],start[1],start[2],start[3],start[4],start[5],start[6],start[7],start[8],start[9],start[10],start[11],start[12],start[13],start[14],start[15]);
+
+       printk("CPU SRAM: ram = [%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x]\n",
+               ram[0],ram[1],ram[2],ram[3],ram[4],ram[5],ram[6],ram[7],ram[8],ram[9],ram[10],ram[11],ram[12],ram[13],ram[14],ram[15]);
+
+               
+       /* Copy data from RAM to SRAM DATA */\r
+       start = &__ssram_data;\r
+       end   = &__esram_data;\r
+       ram   = &__sram_data_start;\r
+       memcpy(start, ram, (end-start));\r
+       \r
+       printk("CPU SRAM: copied sram data from %p to %p - %p\n", ram,start, end);\r
+\r
+       return 0;
+}