diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 15:33:45 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 15:33:45 -0800 |
commit | 04a94babd68952a4e3cdd54ebf8ce8891f9b0f2e (patch) | |
tree | 9d4a01f6b6d0093397c2122c4d85abbb57f3e349 | |
parent | 765cdb6cef63c0b41c3f6c9285769080b3f41bb0 (diff) | |
parent | 920e526f93009a81e09809edb7a755a5b22e907d (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6: (24 commits)
[Blackfin] arch: import defines for BF547 -- it is just like the BF548, but no CAN
[Blackfin] arch: fix build fails only include header files when enabled
[Blackfin] arch: declare default INSTALL_PATH for Blackfin ports
[Blackfin] arch: Encourage users to use the spidev character driver: Provide platform support
[Blackfin] arch: Enable UART2 and UART3 for bf548
[Blackfin] arch: Enable NET2272 on BF561-EZkit - remove request_mem_region
[Blackfin] arch:Fix BUG [#3876] pfbutton test for BTN3 on bf533 don't show complete info
[Blackfin] arch: remove duplicated definitions of the line discipline numbers N_* in asm-blackfin/termios.h
[Blackfin] arch: fix building with mtd uclinux by putting the mtd_phys option into the function it actually gets used in
[Blackfin] arch: simpler header and update dates
[Blackfin] arch: move the init sections to the end of memory
[Blackfin] arch: change the trace buffer control start/stop logic in the exception handlers
[Blackfin] arch: fix typo in printk message
[Blackfin] arch: this is an ezkit, not a stamp, so fixup the init function name
[Blackfin] arch: add slightly better help text for CPLB_INFO
[Blackfin] arch: Fix BUG - Enable ISP1362 driver to work ok with BF561
[Blackfin] arch: Fix header file information
[Blackfin] arch: Add Support for ISP1362
[Blackfin] arch: add support for cmdline partitioning to the BF533-STAMP flash map driver and enable it as a module by default
[Blackfin] arch: hook up set_irq_wake in Blackfin's irq code
...
38 files changed, 3185 insertions, 866 deletions
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index ba21e33b8b1..368bc7fe167 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -544,7 +544,7 @@ config EXCPT_IRQ_SYSC_L1 default y help If enabled, the entire ASM lowlevel exception and interrupt entry code - (STORE/RESTORE CONTEXT) is linked into L1 instruction memory. + (STORE/RESTORE CONTEXT) is linked into L1 instruction memory. (less latency) config DO_IRQ_L1 @@ -904,29 +904,38 @@ config ARCH_SUSPEND_POSSIBLE depends on !SMP choice - prompt "Select PM Wakeup Event Source" - default PM_WAKEUP_GPIO_BY_SIC_IWR + prompt "Default Power Saving Mode" depends on PM - help - If you have a GPIO already configured as input with the corresponding PORTx_MASK - bit set - "Specify Wakeup Event by SIC_IWR value" + default PM_BFIN_SLEEP_DEEPER +config PM_BFIN_SLEEP_DEEPER + bool "Sleep Deeper" + help + Sleep "Deeper" Mode (High Power Savings) - This mode reduces dynamic + power dissipation by disabling the clock to the processor core (CCLK). + Furthermore, Standby sets the internal power supply voltage (VDDINT) + to 0.85 V to provide the greatest power savings, while preserving the + processor state. + The PLL and system clock (SCLK) continue to operate at a very low + frequency of about 3.3 MHz. To preserve data integrity in the SDRAM, + the SDRAM is put into Self Refresh Mode. Typically an external event + such as GPIO interrupt or RTC activity wakes up the processor. + Various Peripherals such as UART, SPORT, PPI may not function as + normal during Sleep Deeper, due to the reduced SCLK frequency. + When in the sleep mode, system DMA access to L1 memory is not supported. + +config PM_BFIN_SLEEP + bool "Sleep" + help + Sleep Mode (High Power Savings) - The sleep mode reduces power + dissipation by disabling the clock to the processor core (CCLK). + The PLL and system clock (SCLK), however, continue to operate in + this mode. Typically an external event or RTC activity will wake + up the processor. When in the sleep mode, + system DMA access to L1 memory is not supported. +endchoice -config PM_WAKEUP_GPIO_BY_SIC_IWR - bool "Specify Wakeup Event by SIC_IWR value" config PM_WAKEUP_BY_GPIO bool "Cause Wakeup Event by GPIO" -config PM_WAKEUP_GPIO_API - bool "Configure Wakeup Event by PM GPIO API" - -endchoice - -config PM_WAKEUP_SIC_IWR - hex "Wakeup Events (SIC_IWR)" - depends on PM_WAKEUP_GPIO_BY_SIC_IWR - default 0x8 if (BF537 || BF536 || BF534) - default 0x80 if (BF533 || BF532 || BF531) - default 0x80 if (BF54x) - default 0x80 if (BF52x) config PM_WAKEUP_GPIO_NUMBER int "Wakeup GPIO number" diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug index 59b87a483c6..c61bdebb997 100644 --- a/arch/blackfin/Kconfig.debug +++ b/arch/blackfin/Kconfig.debug @@ -164,7 +164,7 @@ config DUAL_CORE_TEST_MODULE config CPLB_INFO bool "Display the CPLB information" help - Display the CPLB information. + Display the CPLB information via /proc/cplbinfo. config ACCESS_CHECK bool "Check the user pointer address" diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index 0edc402fef5..fe254f886a6 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile @@ -119,6 +119,7 @@ archclean: $(Q)$(MAKE) $(clean)=$(boot) +INSTALL_PATH ?= /tftpboot boot := arch/$(ARCH)/boot BOOT_TARGETS = vmImage PHONY += $(BOOT_TARGETS) install diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig index 9b7123cf27a..198f4123af4 100644 --- a/arch/blackfin/configs/BF533-STAMP_defconfig +++ b/arch/blackfin/configs/BF533-STAMP_defconfig @@ -216,8 +216,6 @@ CONFIG_MEM_SIZE=128 CONFIG_MEM_ADD_WIDTH=11 CONFIG_ENET_FLASH_PIN=0 CONFIG_BOOT_LOAD=0x1000 - - CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -483,7 +481,7 @@ CONFIG_MTD=y # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y # # User Modules And Translation Layers @@ -500,8 +498,8 @@ CONFIG_MTD_BLOCK=y # # RAM/ROM/Flash chip drivers # -# CONFIG_MTD_CFI is not set -CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_JEDECPROBE is not set CONFIG_MTD_GEN_PROBE=m # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_MAP_BANK_WIDTH_1=y @@ -515,8 +513,9 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_I4 is not set # CONFIG_MTD_CFI_I8 is not set # CONFIG_MTD_CFI_INTELEXT is not set -# CONFIG_MTD_CFI_AMDSTD is not set +CONFIG_MTD_CFI_AMDSTD=m # CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=m CONFIG_MTD_RAM=y CONFIG_MTD_ROM=m # CONFIG_MTD_ABSENT is not set @@ -526,6 +525,11 @@ CONFIG_MTD_ROM=m # CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_BF5xx=m +CONFIG_BFIN_FLASH_BANK_0=0x7BB0 +CONFIG_BFIN_FLASH_BANK_1=0x7BB0 +CONFIG_BFIN_FLASH_BANK_2=0x7BB0 +CONFIG_BFIN_FLASH_BANK_3=0x7BB0 # CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index fa9debe8d5f..5453bc3664f 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -104,6 +104,16 @@ int request_dma(unsigned int channel, char *device_id) mutex_unlock(&(dma_ch[channel].dmalock)); +#ifdef CONFIG_BF54x + if (channel >= CH_UART2_RX && channel <= CH_UART3_TX && + strncmp(device_id, "BFIN_UART", 9) == 0) + dma_ch[channel].regs->peripheral_map |= + (channel - CH_UART2_RX + 0xC); + else + dma_ch[channel].regs->peripheral_map |= + (channel - CH_UART2_RX + 0x6); +#endif + dma_ch[channel].device_id = device_id; dma_ch[channel].irq_callback = NULL; diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 6bbe0a2fccb..08788f7bbfb 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -186,7 +186,7 @@ static struct str_ident { char name[RESOURCE_LABEL_SIZE]; } str_ident[MAX_RESOURCES]; -#ifdef CONFIG_PM +#if defined(CONFIG_PM) && !defined(CONFIG_BF54x) static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; @@ -696,9 +696,8 @@ static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type) return 0; } -u32 gpio_pm_setup(void) +u32 bfin_pm_setup(void) { - u32 sic_iwr = 0; u16 bank, mask, i, gpio; for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { @@ -723,7 +722,8 @@ u32 gpio_pm_setup(void) gpio = i; while (mask) { - if (mask & 1) { + if ((mask & 1) && (wakeup_flags_map[gpio] != + PM_WAKE_IGNORE)) { reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); bfin_gpio_wakeup_type(gpio, @@ -734,21 +734,17 @@ u32 gpio_pm_setup(void) mask >>= 1; } - sic_iwr |= 1 << - (sic_iwr_irqs[bank] - (IRQ_CORETMR + 1)); + bfin_internal_set_wake(sic_iwr_irqs[bank], 1); gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)]; } } AWA_DUMMY_READ(maskb_set); - if (sic_iwr) - return sic_iwr; - else - return IWR_ENABLE_ALL; + return 0; } -void gpio_pm_restore(void) +void bfin_pm_restore(void) { u16 bank, mask, i; @@ -768,7 +764,7 @@ void gpio_pm_restore(void) reserved_gpio_map[bank] = gpio_bank_saved[bank].reserved; - + bfin_internal_set_wake(sic_iwr_irqs[bank], 0); } gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb; diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c index e2e2b5079f5..dc6e8a7a8bd 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c @@ -26,6 +26,10 @@ #include <asm/cplb.h> #include <asm/cplbinit.h> +#if ANOMALY_05000263 +# error the MPU will not function safely while Anomaly 05000263 applies +#endif + struct cplb_entry icplb_tbl[MAX_CPLBS]; struct cplb_entry dcplb_tbl[MAX_CPLBS]; diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c index 673c860ffc2..c640154030e 100644 --- a/arch/blackfin/kernel/init_task.c +++ b/arch/blackfin/kernel/init_task.c @@ -57,5 +57,5 @@ EXPORT_SYMBOL(init_task); * "init_task" linker map entry. */ union thread_union init_thread_union - __attribute__ ((__section__(".data.init_task"))) = { + __attribute__ ((__section__(".init_task.data"))) = { INIT_THREAD_INFO(init_task)}; diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 289ea9d7fcd..8229b1090eb 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -1,30 +1,11 @@ /* - * File: arch/blackfin/kernel/setup.c - * Based on: - * Author: + * arch/blackfin/kernel/setup.c * - * Created: - * Description: + * Copyright 2004-2006 Analog Devices Inc. * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. + * Enter bugs at http://blackfin.uclinux.org/ * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Licensed under the GPL-2 or later. */ #include <linux/delay.h> @@ -34,6 +15,7 @@ #include <linux/cpu.h> #include <linux/module.h> #include <linux/tty.h> +#include <linux/pfn.h> #include <linux/ext2_fs.h> #include <linux/cramfs_fs.h> @@ -47,6 +29,8 @@ #include <asm/fixed_code.h> #include <asm/early_printk.h> +static DEFINE_PER_CPU(struct cpu, cpu_devices); + u16 _bfin_swrst; unsigned long memory_start, memory_end, physical_mem_end; @@ -67,6 +51,29 @@ EXPORT_SYMBOL(mtd_size); char __initdata command_line[COMMAND_LINE_SIZE]; +/* boot memmap, for parsing "memmap=" */ +#define BFIN_MEMMAP_MAX 128 /* number of entries in bfin_memmap */ +#define BFIN_MEMMAP_RAM 1 +#define BFIN_MEMMAP_RESERVED 2 +struct bfin_memmap { + int nr_map; + struct bfin_memmap_entry { + unsigned long long addr; /* start of memory segment */ + unsigned long long size; + unsigned long type; + } map[BFIN_MEMMAP_MAX]; +} bfin_memmap __initdata; + +/* for memmap sanitization */ +struct change_member { + struct bfin_memmap_entry *pentry; /* pointer to original entry */ + unsigned long long addr; /* address for this change point */ +}; +static struct change_member change_point_list[2*BFIN_MEMMAP_MAX] __initdata; +static struct change_member *change_point[2*BFIN_MEMMAP_MAX] __initdata; +static struct bfin_memmap_entry *overlap_list[BFIN_MEMMAP_MAX] __initdata; +static struct bfin_memmap_entry new_map[BFIN_MEMMAP_MAX] __initdata; + void __init bf53x_cache_init(void) { #if defined(CONFIG_BFIN_DCACHE) || defined(CONFIG_BFIN_ICACHE) @@ -123,12 +130,224 @@ void __init bf53x_relocate_l1_mem(void) } +/* add_memory_region to memmap */ +static void __init add_memory_region(unsigned long long start, + unsigned long long size, int type) +{ + int i; + + i = bfin_memmap.nr_map; + + if (i == BFIN_MEMMAP_MAX) { + printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); + return; + } + + bfin_memmap.map[i].addr = start; + bfin_memmap.map[i].size = size; + bfin_memmap.map[i].type = type; + bfin_memmap.nr_map++; +} + +/* + * Sanitize the boot memmap, removing overlaps. + */ +static int __init sanitize_memmap(struct bfin_memmap_entry *map, int *pnr_map) +{ + struct change_member *change_tmp; + unsigned long current_type, last_type; + unsigned long long last_addr; + int chgidx, still_changing; + int overlap_entries; + int new_entry; + int old_nr, new_nr, chg_nr; + int i; + + /* + Visually we're performing the following (1,2,3,4 = memory types) + + Sample memory map (w/overlaps): + ____22__________________ + ______________________4_ + ____1111________________ + _44_____________________ + 11111111________________ + ____________________33__ + ___________44___________ + __________33333_________ + ______________22________ + ___________________2222_ + _________111111111______ + _____________________11_ + _________________4______ + + Sanitized equivalent (no overlap): + 1_______________________ + _44_____________________ + ___1____________________ + ____22__________________ + ______11________________ + _________1______________ + __________3_____________ + ___________44___________ + _____________33_________ + _______________2________ + ________________1_______ + _________________4______ + ___________________2____ + ____________________33__ + ______________________4_ + */ + /* if there's only one memory region, don't bother */ + if (*pnr_map < 2) + return -1; + + old_nr = *pnr_map; + + /* bail out if we find any unreasonable addresses in memmap */ + for (i = 0; i < old_nr; i++) + if (map[i].addr + map[i].size < map[i].addr) + return -1; + + /* create pointers for initial change-point information (for sorting) */ + for (i = 0; i < 2*old_nr; i++) + change_point[i] = &change_point_list[i]; + + /* record all known change-points (starting and ending addresses), + omitting those that are for empty memory regions */ + chgidx = 0; + for (i = 0; i < old_nr; i++) { + if (map[i].size != 0) { + change_point[chgidx]->addr = map[i].addr; + change_point[chgidx++]->pentry = &map[i]; + change_point[chgidx]->addr = map[i].addr + map[i].size; + change_point[chgidx++]->pentry = &map[i]; + } + } + chg_nr = chgidx; /* true number of change-points */ + + /* sort change-point list by memory addresses (low -> high) */ + still_changing = 1; + while (still_changing) { + still_changing = 0; + for (i = 1; i < chg_nr; i++) { + /* if <current_addr> > <last_addr>, swap */ + /* or, if current=<start_addr> & last=<end_addr>, swap */ + if ((change_point[i]->addr < change_point[i-1]->addr) || + ((change_point[i]->addr == change_point[i-1]->addr) && + (change_point[i]->addr == change_point[i]->pentry->addr) && + (change_point[i-1]->addr != change_point[i-1]->pentry->addr)) + ) { + change_tmp = change_point[i]; + change_point[i] = change_point[i-1]; + change_point[i-1] = change_tmp; + still_changing = 1; + } + } + } + + /* create a new memmap, removing overlaps */ + overlap_entries = 0; /* number of entries in the overlap table */ + new_entry = 0; /* index for creating new memmap entries */ + last_type = 0; /* start with undefined memory type */ + last_addr = 0; /* start with 0 as last starting address */ + /* loop through change-points, determining affect on the new memmap */ + for (chgidx = 0; chgidx < chg_nr; chgidx++) { + /* keep track of all overlapping memmap entries */ + if (change_point[chgidx]->addr == change_point[chgidx]->pentry->addr) { + /* add map entry to overlap list (> 1 entry implies an overlap) */ + overlap_list[overlap_entries++] = change_point[chgidx]->pentry; + } else { + /* remove entry from list (order independent, so swap with last) */ + for (i = 0; i < overlap_entries; i++) { + if (overlap_list[i] == change_point[chgidx]->pentry) + overlap_list[i] = overlap_list[overlap_entries-1]; + } + overlap_entries--; + } + /* if there are overlapping entries, decide which "type" to use */ + /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */ + current_type = 0; + for (i = 0; i < overlap_entries; i++) + if (overlap_list[i]->type > current_type) + current_type = overlap_list[i]->type; + /* continue building up new memmap based on this information */ + if (current_type != last_type) { + if (last_type != 0) { + new_map[new_entry].size = + change_point[chgidx]->addr - last_addr; + /* move forward only if the new size was non-zero */ + if (new_map[new_entry].size != 0) + if (++new_entry >= BFIN_MEMMAP_MAX) + break; /* no more space left for new entries */ + } + if (current_type != 0) { + new_map[new_entry].addr = change_point[chgidx]->addr; + new_map[new_entry].type = current_type; + last_addr = change_point[chgidx]->addr; + } + last_type = current_type; + } + } + new_nr = new_entry; /* retain count for new entries */ + + /* copy new mapping into original location */ + memcpy(map, new_map, new_nr*sizeof(struct bfin_memmap_entry)); + *pnr_map = new_nr; + + return 0; +} + +static void __init print_memory_map(char *who) +{ + int i; + + for (i = 0; i < bfin_memmap.nr_map; i++) { + printk(KERN_DEBUG " %s: %016Lx - %016Lx ", who, + bfin_memmap.map[i].addr, + bfin_memmap.map[i].addr + bfin_memmap.map[i].size); + switch (bfin_memmap.map[i].type) { + case BFIN_MEMMAP_RAM: + printk("(usable)\n"); + break; + case BFIN_MEMMAP_RESERVED: + printk("(reserved)\n"); + break; + default: printk("type %lu\n", bfin_memmap.map[i].type); + break; + } + } +} + +static __init int parse_memmap(char *arg) +{ + unsigned long long start_at, mem_size; + + if (!arg) + return -EINVAL; + + mem_size = memparse(arg, &arg); + if (*arg == '@') { + start_at = memparse(arg+1, &arg); + add_memory_region(start_at, mem_size, BFIN_MEMMAP_RAM); + } else if (*arg == '$') { + start_at = memparse(arg+1, &arg); + add_memory_region(start_at, mem_size, BFIN_MEMMAP_RESERVED); + } + + return 0; +} + /* * Initial parsing of the command line. Currently, we support: * - Controlling the linux memory size: mem=xxx[KMG] * - Controlling the physical memory size: max_mem=xxx[KMG][$][#] * $ -> reserved memory is dcacheable * # -> reserved memory is icacheable + * - "memmap=XXX[KkmM][@][$]XXX[KkmM]" defines a memory region + * @ from <start> to <start>+<mem>, type RAM + * $ from <start> to <start>+<mem>, type RESERVED + * */ static __init void parse_cmdline_early(char *cmdline_p) { @@ -136,7 +355,6 @@ static __init void parse_cmdline_early(char *cmdline_p) unsigned int memsize; for (;;) { if (c == ' ') { - if (!memcmp(to, "mem=", 4)) { to += 4; memsize = memparse(to, &to); @@ -162,6 +380,9 @@ static __init void parse_cmdline_early(char *cmdline_p) } else if (!memcmp(to, "earlyprintk=", 12)) { to += 12; setup_early_printk(to); + } else if (!memcmp(to, "memmap=", 7)) { + to += 7; + parse_memmap(to); } } c = *(to++); @@ -170,75 +391,36 @@ static __init void parse_cmdline_early(char *cmdline_p) } } -void __init setup_arch(char **cmdline_p) +/* + * Setup memory defaults from user config. + * The physical memory layout looks like: + * + * [_rambase, _ramstart]: kernel image + * [memory_start, memory_end]: dynamic memory managed by kernel + * [memory_end, _ramend]: reserved memory + * [meory_mtd_start(memory_end), + * memory_mtd_start + mtd_size]: rootfs (if any) + * [_ramend - DMA_UNCACHED_REGION, + * _ramend]: uncached DMA region + * [_ramend, physical_mem_end]: memory not managed by kernel + * + */ +static __init void memory_setup(void) { - int bootmap_size; - unsigned long l1_length, sclk, cclk; #ifdef CONFIG_MTD_UCLINUX unsigned long mtd_phys = 0; #endif -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif - -#if defined(CONFIG_CMDLINE_BOOL) - strncpy(&command_line[0], CONFIG_CMDLINE, sizeof(command_line)); - command_line[sizeof(command_line) - 1] = 0; -#endif - - /* Keep a copy of command line */ - *cmdline_p = &command_line[0]; - memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - boot_command_line[COMMAND_LINE_SIZE - 1] = '\0'; - - /* setup memory defaults from the user config */ - physical_mem_end = 0; - _ramend = CONFIG_MEM_SIZE * 1024 * 1024; - - parse_cmdline_early(&command_line[0]); - - cclk = get_cclk(); - sclk = get_sclk(); - -#if !defined(CONFIG_BFIN_KERNEL_CLOCK) - if (ANOMALY_05000273 && cclk == sclk) - panic("ANOMALY 05000273, SCLK can not be same as CCLK"); -#endif + _rambase = (unsigned long)_stext; + _ramstart = (unsigned long)_end; -#ifdef BF561_FAMILY - if (ANOMALY_05000266) { - bfin_read_IMDMA_D0_IRQ_STATUS(); - bfin_read_IMDMA_D1_IRQ_STATUS(); + if (DMA_UNCACHED_REGION > (_ramend - _ramstart)) { + console_init(); + panic("DMA region exceeds memory limit: %lu.\n", + _ramend - _ramstart); } -#endif - - printk(KERN_INFO "Hardware Trace "); - if (bfin_read_TBUFCTL() & 0x1 ) - printk("Active "); - else - printk("Off "); - if (bfin_read_TBUFCTL() & 0x2) - printk("and Enabled\n"); - else - printk("and Disabled\n"); - - -#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) - /* we need to initialize the Flashrom device here since we might - * do things with flash early on in the boot - */ - flash_probe(); -#endif - - if (physical_mem_end == 0) - physical_mem_end = _ramend; - - /* by now the stack is part of the init task */ memory_end = _ramend - DMA_UNCACHED_REGION; - _ramstart = (unsigned long)__bss_stop; - _rambase = (unsigned long)_stext; #ifdef CONFIG_MPU /* Round up to multiple of 4MB. */ memory_start = (_ramstart + 0x3fffff) & ~0x3fffff; @@ -292,7 +474,7 @@ void __init setup_arch(char **cmdline_p) } /* Relocate MTD image to the top of memory after the uncached memory area */ - dma_memcpy((char *)memory_end, __bss_stop, mtd_size); + dma_memcpy((char *)memory_end, _end, mtd_size); memory_mtd_start = memory_end; _ebss = memory_mtd_start; /* define _ebss for compatible */ @@ -319,13 +501,175 @@ void __init setup_arch(char **cmdline_p) #endif #if !defined(CONFIG_MTD_UCLINUX) - memory_end -= SIZE_4K; /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/ + /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/ + memory_end -= SIZE_4K; #endif + init_mm.start_code = (unsigned long)_stext; init_mm.end_code = (unsigned long)_etext; init_mm.end_data = (unsigned long)_edata; init_mm.brk = (unsigned long)0; + printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20); + printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20); + + printk(KERN_INFO "Memory map:\n" + KERN_INFO " text = 0x%p-0x%p\n" + KERN_INFO " rodata = 0x%p-0x%p\n" + KERN_INFO " bss = 0x%p-0x%p\n" + KERN_INFO " data = 0x%p-0x%p\n" + KERN_INFO " stack = 0x%p-0x%p\n" + KERN_INFO " init = 0x%p-0x%p\n" + KERN_INFO " available = 0x%p-0x%p\n" +#ifdef CONFIG_MTD_UCLINUX + KERN_INFO " rootfs = 0x%p-0x%p\n" +#endif +#if DMA_UNCACHED_REGION > |