diff options
Diffstat (limited to 'arch/blackfin/kernel/cplb-nompu/cplbinit.c')
| -rw-r--r-- | arch/blackfin/kernel/cplb-nompu/cplbinit.c | 121 |
1 files changed, 79 insertions, 42 deletions
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index d6c067782e6..b49a53b583d 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -1,24 +1,9 @@ /* * Blackfin CPLB initialization * - * Copyright 2004-2007 Analog Devices Inc. + * Copyright 2007-2009 Analog Devices Inc. * - * 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/module.h> @@ -36,7 +21,7 @@ int first_switched_icplb PDT_ATTR; int first_switched_dcplb PDT_ATTR; struct cplb_boundary dcplb_bounds[9] PDT_ATTR; -struct cplb_boundary icplb_bounds[7] PDT_ATTR; +struct cplb_boundary icplb_bounds[9] PDT_ATTR; int icplb_nr_bounds PDT_ATTR; int dcplb_nr_bounds PDT_ATTR; @@ -45,6 +30,7 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) { int i_d, i_i; unsigned long addr; + unsigned long cplb_pageflags, cplb_pagesize; struct cplb_entry *d_tbl = dcplb_tbl[cpu]; struct cplb_entry *i_tbl = icplb_tbl[cpu]; @@ -64,21 +50,58 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) /* Cover kernel memory with 4M pages. */ addr = 0; - for (; addr < memory_start; addr += 4 * 1024 * 1024) { +#ifdef PAGE_SIZE_16MB + cplb_pageflags = PAGE_SIZE_16MB; + cplb_pagesize = SIZE_16M; +#else + cplb_pageflags = PAGE_SIZE_4MB; + cplb_pagesize = SIZE_4M; +#endif + + + for (; addr < memory_start; addr += cplb_pagesize) { d_tbl[i_d].addr = addr; - d_tbl[i_d++].data = SDRAM_DGENERIC | PAGE_SIZE_4MB; + d_tbl[i_d++].data = SDRAM_DGENERIC | cplb_pageflags; i_tbl[i_i].addr = addr; - i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB; + i_tbl[i_i++].data = SDRAM_IGENERIC | cplb_pageflags; } +#ifdef CONFIG_ROMKERNEL + /* Cover kernel XIP flash area */ +#ifdef CONFIG_BF60x + addr = CONFIG_ROM_BASE & ~(16 * 1024 * 1024 - 1); + d_tbl[i_d].addr = addr; + d_tbl[i_d++].data = SDRAM_DGENERIC | PAGE_SIZE_16MB; + i_tbl[i_i].addr = addr; + i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_16MB; +#else + addr = CONFIG_ROM_BASE & ~(4 * 1024 * 1024 - 1); + d_tbl[i_d].addr = addr; + d_tbl[i_d++].data = SDRAM_DGENERIC | PAGE_SIZE_4MB; + i_tbl[i_i].addr = addr; + i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB; +#endif +#endif + /* Cover L1 memory. One 4M area for code and data each is enough. */ - if (L1_DATA_A_LENGTH || L1_DATA_B_LENGTH) { - d_tbl[i_d].addr = L1_DATA_A_START; - d_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB; + if (cpu == 0) { + if (L1_DATA_A_LENGTH || L1_DATA_B_LENGTH) { + d_tbl[i_d].addr = L1_DATA_A_START; + d_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB; + } + i_tbl[i_i].addr = L1_CODE_START; + i_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB; } - i_tbl[i_i].addr = L1_CODE_START; - i_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB; - +#ifdef CONFIG_SMP + else { + if (L1_DATA_A_LENGTH || L1_DATA_B_LENGTH) { + d_tbl[i_d].addr = COREB_L1_DATA_A_START; + d_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB; + } + i_tbl[i_i].addr = COREB_L1_CODE_START; + i_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB; + } +#endif first_switched_dcplb = i_d; first_switched_icplb = i_i; @@ -93,15 +116,25 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) void __init generate_cplb_tables_all(void) { + unsigned long uncached_end; int i_d, i_i; i_d = 0; /* Normal RAM, including MTD FS. */ #ifdef CONFIG_MTD_UCLINUX - dcplb_bounds[i_d].eaddr = memory_mtd_start + mtd_size; + uncached_end = memory_mtd_start + mtd_size; #else - dcplb_bounds[i_d].eaddr = memory_end; + uncached_end = memory_end; #endif + /* + * if DMA uncached is less than 1MB, mark the 1MB chunk as uncached + * so that we don't have to use 4kB pages and cause CPLB thrashing + */ + if ((DMA_UNCACHED_REGION >= 1 * 1024 * 1024) || !DMA_UNCACHED_REGION || + ((_ramend - uncached_end) >= 1 * 1024 * 1024)) + dcplb_bounds[i_d].eaddr = uncached_end; + else + dcplb_bounds[i_d].eaddr = uncached_end & ~(1 * 1024 * 1024 - 1); dcplb_bounds[i_d++].data = SDRAM_DGENERIC; /* DMA uncached region. */ if (DMA_UNCACHED_REGION) { @@ -124,7 +157,7 @@ void __init generate_cplb_tables_all(void) dcplb_bounds[i_d].eaddr = BOOT_ROM_START; dcplb_bounds[i_d++].data = 0; /* BootROM -- largest one should be less than 1 meg. */ - dcplb_bounds[i_d].eaddr = BOOT_ROM_START + (1 * 1024 * 1024); + dcplb_bounds[i_d].eaddr = BOOT_ROM_START + BOOT_ROM_LENGTH; dcplb_bounds[i_d++].data = SDRAM_DGENERIC; if (L2_LENGTH) { /* Addressing hole up to L2 SRAM. */ @@ -139,31 +172,35 @@ void __init generate_cplb_tables_all(void) i_i = 0; /* Normal RAM, including MTD FS. */ -#ifdef CONFIG_MTD_UCLINUX - icplb_bounds[i_i].eaddr = memory_mtd_start + mtd_size; -#else - icplb_bounds[i_i].eaddr = memory_end; -#endif + icplb_bounds[i_i].eaddr = uncached_end; icplb_bounds[i_i++].data = SDRAM_IGENERIC; - /* DMA uncached region. */ - if (DMA_UNCACHED_REGION) { - icplb_bounds[i_i].eaddr = _ramend; - icplb_bounds[i_i++].data = 0; - } if (_ramend != physical_mem_end) { + /* DMA uncached region. */ + if (DMA_UNCACHED_REGION) { + /* Normally this hole is caught by the async below. */ + icplb_bounds[i_i].eaddr = _ramend; + icplb_bounds[i_i++].data = 0; + } /* Reserved memory. */ icplb_bounds[i_i].eaddr = physical_mem_end; icplb_bounds[i_i++].data = (reserved_mem_icache_on ? SDRAM_IGENERIC : SDRAM_INON_CHBL); } + /* Addressing hole up to the async bank. */ + icplb_bounds[i_i].eaddr = ASYNC_BANK0_BASE; + icplb_bounds[i_i++].data = 0; + /* ASYNC banks. */ + icplb_bounds[i_i].eaddr = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE; + icplb_bounds[i_i++].data = SDRAM_EBIU; /* Addressing hole up to BootROM. */ icplb_bounds[i_i].eaddr = BOOT_ROM_START; icplb_bounds[i_i++].data = 0; /* BootROM -- largest one should be less than 1 meg. */ - icplb_bounds[i_i].eaddr = BOOT_ROM_START + (1 * 1024 * 1024); + icplb_bounds[i_i].eaddr = BOOT_ROM_START + BOOT_ROM_LENGTH; icplb_bounds[i_i++].data = SDRAM_IGENERIC; + if (L2_LENGTH) { - /* Addressing hole up to L2 SRAM, including the async bank. */ + /* Addressing hole up to L2 SRAM. */ icplb_bounds[i_i].eaddr = L2_START; icplb_bounds[i_i++].data = 0; /* L2 SRAM. */ |
