diff options
Diffstat (limited to 'arch/arm/plat-omap/fb.c')
| -rw-r--r-- | arch/arm/plat-omap/fb.c | 77 |
1 files changed, 56 insertions, 21 deletions
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c index d3eea4f4753..0054b9501a5 100644 --- a/arch/arm/plat-omap/fb.c +++ b/arch/arm/plat-omap/fb.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
| 27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
| 28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
| 29 | #include <linux/bootmem.h> | 29 | #include <linux/memblock.h> |
| 30 | #include <linux/io.h> | 30 | #include <linux/io.h> |
| 31 | #include <linux/omapfb.h> | 31 | #include <linux/omapfb.h> |
| 32 | 32 | ||
| @@ -171,49 +171,78 @@ static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg, | |||
| 171 | return 0; | 171 | return 0; |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | static int valid_sdram(unsigned long addr, unsigned long size) | ||
| 175 | { | ||
| 176 | struct memblock_property res; | ||
| 177 | |||
| 178 | res.base = addr; | ||
| 179 | res.size = size; | ||
| 180 | return !memblock_find(&res) && res.base == addr && res.size == size; | ||
| 181 | } | ||
| 182 | |||
| 183 | static int reserve_sdram(unsigned long addr, unsigned long size) | ||
| 184 | { | ||
| 185 | if (memblock_is_region_reserved(addr, size)) | ||
| 186 | return -EBUSY; | ||
| 187 | if (memblock_reserve(addr, size)) | ||
| 188 | return -ENOMEM; | ||
| 189 | return 0; | ||
| 190 | } | ||
| 191 | |||
| 174 | /* | 192 | /* |
| 175 | * Called from map_io. We need to call to this early enough so that we | 193 | * Called from map_io. We need to call to this early enough so that we |
| 176 | * can reserve the fixed SDRAM regions before VM could get hold of them. | 194 | * can reserve the fixed SDRAM regions before VM could get hold of them. |
| 177 | */ | 195 | */ |
| 178 | void __init omapfb_reserve_sdram(void) | 196 | void __init omapfb_reserve_sdram_memblock(void) |
| 179 | { | 197 | { |
| 180 | struct bootmem_data *bdata; | 198 | unsigned long reserved = 0; |
| 181 | unsigned long sdram_start, sdram_size; | 199 | int i; |
| 182 | unsigned long reserved; | ||
| 183 | int i; | ||
| 184 | 200 | ||
| 185 | if (config_invalid) | 201 | if (config_invalid) |
| 186 | return; | 202 | return; |
| 187 | 203 | ||
| 188 | bdata = NODE_DATA(0)->bdata; | ||
| 189 | sdram_start = bdata->node_min_pfn << PAGE_SHIFT; | ||
| 190 | sdram_size = (bdata->node_low_pfn << PAGE_SHIFT) - sdram_start; | ||
| 191 | reserved = 0; | ||
| 192 | for (i = 0; ; i++) { | 204 | for (i = 0; ; i++) { |
| 193 | struct omapfb_mem_region rg; | 205 | struct omapfb_mem_region rg; |
| 194 | 206 | ||
| 195 | if (get_fbmem_region(i, &rg) < 0) | 207 | if (get_fbmem_region(i, &rg) < 0) |
| 196 | break; | 208 | break; |
| 209 | |||
| 197 | if (i == OMAPFB_PLANE_NUM) { | 210 | if (i == OMAPFB_PLANE_NUM) { |
| 198 | printk(KERN_ERR | 211 | pr_err("Extraneous FB mem configuration entries\n"); |
| 199 | "Extraneous FB mem configuration entries\n"); | ||
| 200 | config_invalid = 1; | 212 | config_invalid = 1; |
| 201 | return; | 213 | return; |
| 202 | } | 214 | } |
| 215 | |||
| 203 | /* Check if it's our memory type. */ | 216 | /* Check if it's our memory type. */ |
| 204 | if (set_fbmem_region_type(&rg, OMAPFB_MEMTYPE_SDRAM, | 217 | if (rg.type != OMAPFB_MEMTYPE_SDRAM) |
| 205 | sdram_start, sdram_size) < 0 || | ||
| 206 | (rg.type != OMAPFB_MEMTYPE_SDRAM)) | ||
| 207 | continue; | 218 | continue; |
| 208 | BUG_ON(omapfb_config.mem_desc.region[i].size); | 219 | |
| 209 | if (check_fbmem_region(i, &rg, sdram_start, sdram_size) < 0) { | 220 | /* Check if the region falls within SDRAM */ |
| 221 | if (rg.paddr && !valid_sdram(rg.paddr, rg.size)) | ||
| 222 | continue; | ||
| 223 | |||
| 224 | if (rg.size == 0) { | ||
| 225 | pr_err("Zero size for FB region %d\n", i); | ||
| 210 | config_invalid = 1; | 226 | config_invalid = 1; |
| 211 | return; | 227 | return; |
| 212 | } | 228 | } |
| 229 | |||
| 213 | if (rg.paddr) { | 230 | if (rg.paddr) { |
| 214 | reserve_bootmem(rg.paddr, rg.size, BOOTMEM_DEFAULT); | 231 | if (reserve_sdram(rg.paddr, rg.size)) { |
| 232 | pr_err("Trying to use reserved memory for FB region %d\n", | ||
| 233 | i); | ||
| 234 | config_invalid = 1; | ||
| 235 | return; | ||
| 236 | } | ||
| 215 | reserved += rg.size; | 237 | reserved += rg.size; |
| 216 | } | 238 | } |
| 239 | |||
| 240 | if (omapfb_config.mem_desc.region[i].size) { | ||
| 241 | pr_err("FB region %d already set\n", i); | ||
| 242 | config_invalid = 1; | ||
| 243 | return; | ||
| 244 | } | ||
| 245 | |||
| 217 | omapfb_config.mem_desc.region[i] = rg; | 246 | omapfb_config.mem_desc.region[i] = rg; |
| 218 | configured_regions++; | 247 | configured_regions++; |
| 219 | } | 248 | } |
| @@ -359,7 +388,10 @@ static inline int omap_init_fb(void) | |||
| 359 | 388 | ||
| 360 | arch_initcall(omap_init_fb); | 389 | arch_initcall(omap_init_fb); |
| 361 | 390 | ||
| 362 | void omapfb_reserve_sdram(void) {} | 391 | void omapfb_reserve_sdram_memblock(void) |
| 392 | { | ||
| 393 | } | ||
| 394 | |||
| 363 | unsigned long omapfb_reserve_sram(unsigned long sram_pstart, | 395 | unsigned long omapfb_reserve_sram(unsigned long sram_pstart, |
| 364 | unsigned long sram_vstart, | 396 | unsigned long sram_vstart, |
| 365 | unsigned long sram_size, | 397 | unsigned long sram_size, |
| @@ -375,7 +407,10 @@ void omapfb_set_platform_data(struct omapfb_platform_data *data) | |||
| 375 | { | 407 | { |
| 376 | } | 408 | } |
| 377 | 409 | ||
| 378 | void omapfb_reserve_sdram(void) {} | 410 | void omapfb_reserve_sdram_memblock(void) |
| 411 | { | ||
| 412 | } | ||
| 413 | |||
| 379 | unsigned long omapfb_reserve_sram(unsigned long sram_pstart, | 414 | unsigned long omapfb_reserve_sram(unsigned long sram_pstart, |
| 380 | unsigned long sram_vstart, | 415 | unsigned long sram_vstart, |
| 381 | unsigned long sram_size, | 416 | unsigned long sram_size, |
