diff options
Diffstat (limited to 'drivers/video/offb.c')
-rw-r--r-- | drivers/video/offb.c | 122 |
1 files changed, 64 insertions, 58 deletions
diff --git a/drivers/video/offb.c b/drivers/video/offb.c index 00d87f5bb7be..ad1434e3f227 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c | |||
@@ -223,6 +223,7 @@ static int offb_blank(int blank, struct fb_info *info) | |||
223 | int __init offb_init(void) | 223 | int __init offb_init(void) |
224 | { | 224 | { |
225 | struct device_node *dp = NULL, *boot_disp = NULL; | 225 | struct device_node *dp = NULL, *boot_disp = NULL; |
226 | |||
226 | #if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) | 227 | #if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) |
227 | struct device_node *macos_display = NULL; | 228 | struct device_node *macos_display = NULL; |
228 | #endif | 229 | #endif |
@@ -234,60 +235,54 @@ int __init offb_init(void) | |||
234 | if (boot_infos != 0) { | 235 | if (boot_infos != 0) { |
235 | unsigned long addr = | 236 | unsigned long addr = |
236 | (unsigned long) boot_infos->dispDeviceBase; | 237 | (unsigned long) boot_infos->dispDeviceBase; |
238 | u32 *addrp; | ||
239 | u64 daddr, dsize; | ||
240 | unsigned int flags; | ||
241 | |||
237 | /* find the device node corresponding to the macos display */ | 242 | /* find the device node corresponding to the macos display */ |
238 | while ((dp = of_find_node_by_type(dp, "display"))) { | 243 | while ((dp = of_find_node_by_type(dp, "display"))) { |
239 | int i; | 244 | int i; |
240 | /* | ||
241 | * Grrr... It looks like the MacOS ATI driver | ||
242 | * munges the assigned-addresses property (but | ||
243 | * the AAPL,address value is OK). | ||
244 | */ | ||
245 | if (strncmp(dp->name, "ATY,", 4) == 0 | ||
246 | && dp->n_addrs == 1) { | ||
247 | unsigned int *ap = | ||
248 | (unsigned int *) get_property(dp, | ||
249 | "AAPL,address", | ||
250 | NULL); | ||
251 | if (ap != NULL) { | ||
252 | dp->addrs[0].address = *ap; | ||
253 | dp->addrs[0].size = 0x01000000; | ||
254 | } | ||
255 | } | ||
256 | 245 | ||
257 | /* | 246 | /* |
258 | * The LTPro on the Lombard powerbook has no addresses | 247 | * Look for an AAPL,address property first. |
259 | * on the display nodes, they are on their parent. | ||
260 | */ | 248 | */ |
261 | if (dp->n_addrs == 0 | 249 | unsigned int na; |
262 | && device_is_compatible(dp, "ATY,264LTPro")) { | 250 | unsigned int *ap = |
263 | int na; | 251 | (unsigned int *)get_property(dp, "AAPL,address", |
264 | unsigned int *ap = (unsigned int *) | 252 | &na); |
265 | get_property(dp, "AAPL,address", &na); | 253 | if (ap != 0) { |
266 | if (ap != 0) | 254 | for (na /= sizeof(unsigned int); na > 0; |
267 | for (na /= sizeof(unsigned int); | 255 | --na, ++ap) |
268 | na > 0; --na, ++ap) | 256 | if (*ap <= addr && |
269 | if (*ap <= addr | 257 | addr < *ap + 0x1000000) { |
270 | && addr < | 258 | macos_display = dp; |
271 | *ap + 0x1000000) | 259 | goto foundit; |
272 | goto foundit; | 260 | } |
273 | } | 261 | } |
274 | 262 | ||
275 | /* | 263 | /* |
276 | * See if the display address is in one of the address | 264 | * See if the display address is in one of the address |
277 | * ranges for this display. | 265 | * ranges for this display. |
278 | */ | 266 | */ |
279 | for (i = 0; i < dp->n_addrs; ++i) { | 267 | i = 0; |
280 | if (dp->addrs[i].address <= addr | 268 | for (;;) { |
281 | && addr < | 269 | addrp = of_get_address(dp, i++, &dsize, &flags); |
282 | dp->addrs[i].address + | 270 | if (addrp == NULL) |
283 | dp->addrs[i].size) | ||
284 | break; | 271 | break; |
272 | if (!(flags & IORESOURCE_MEM)) | ||
273 | continue; | ||
274 | daddr = of_translate_address(dp, addrp); | ||
275 | if (daddr == OF_BAD_ADDR) | ||
276 | continue; | ||
277 | if (daddr <= addr && addr < (daddr + dsize)) { | ||
278 | macos_display = dp; | ||
279 | goto foundit; | ||
280 | } | ||
285 | } | 281 | } |
286 | if (i < dp->n_addrs) { | 282 | foundit: |
287 | foundit: | 283 | if (macos_display) { |
288 | printk(KERN_INFO "MacOS display is %s\n", | 284 | printk(KERN_INFO "MacOS display is %s\n", |
289 | dp->full_name); | 285 | dp->full_name); |
290 | macos_display = dp; | ||
291 | break; | 286 | break; |
292 | } | 287 | } |
293 | } | 288 | } |
@@ -326,8 +321,10 @@ static void __init offb_init_nodriver(struct device_node *dp) | |||
326 | int *pp, i; | 321 | int *pp, i; |
327 | unsigned int len; | 322 | unsigned int len; |
328 | int width = 640, height = 480, depth = 8, pitch; | 323 | int width = 640, height = 480, depth = 8, pitch; |
329 | unsigned int rsize, *up; | 324 | unsigned int flags, rsize, *up; |
330 | unsigned long address = 0; | 325 | u64 address = OF_BAD_ADDR; |
326 | u32 *addrp; | ||
327 | u64 asize; | ||
331 | 328 | ||
332 | if ((pp = (int *) get_property(dp, "depth", &len)) != NULL | 329 | if ((pp = (int *) get_property(dp, "depth", &len)) != NULL |
333 | && len == sizeof(int)) | 330 | && len == sizeof(int)) |
@@ -363,7 +360,7 @@ static void __init offb_init_nodriver(struct device_node *dp) | |||
363 | break; | 360 | break; |
364 | } | 361 | } |
365 | if (pdev) { | 362 | if (pdev) { |
366 | for (i = 0; i < 6 && address == 0; i++) { | 363 | for (i = 0; i < 6 && address == OF_BAD_ADDR; i++) { |
367 | if ((pci_resource_flags(pdev, i) & | 364 | if ((pci_resource_flags(pdev, i) & |
368 | IORESOURCE_MEM) && | 365 | IORESOURCE_MEM) && |
369 | (pci_resource_len(pdev, i) >= rsize)) | 366 | (pci_resource_len(pdev, i) >= rsize)) |
@@ -374,27 +371,33 @@ static void __init offb_init_nodriver(struct device_node *dp) | |||
374 | } | 371 | } |
375 | #endif /* CONFIG_PCI */ | 372 | #endif /* CONFIG_PCI */ |
376 | 373 | ||
377 | if (address == 0 && | 374 | /* This one is dodgy, we may drop it ... */ |
378 | (up = (unsigned *) get_property(dp, "address", &len)) != NULL && | 375 | if (address == OF_BAD_ADDR && |
379 | len == sizeof(unsigned)) | 376 | (up = (unsigned *) get_property(dp, "address", &len)) != NULL && |
380 | address = (u_long) * up; | 377 | len == sizeof(unsigned int)) |
381 | if (address == 0) { | 378 | address = (u64) * up; |
382 | for (i = 0; i < dp->n_addrs; ++i) | 379 | |
383 | if (dp->addrs[i].size >= | 380 | if (address == OF_BAD_ADDR) { |
384 | pitch * height * depth / 8) | 381 | for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) |
385 | break; | 382 | != NULL; i++) { |
386 | if (i >= dp->n_addrs) { | 383 | if (!(flags & IORESOURCE_MEM)) |
384 | continue; | ||
385 | if (asize >= pitch * height * depth / 8) | ||
386 | break; | ||
387 | } | ||
388 | if (addrp == NULL) { | ||
387 | printk(KERN_ERR | 389 | printk(KERN_ERR |
388 | "no framebuffer address found for %s\n", | 390 | "no framebuffer address found for %s\n", |
389 | dp->full_name); | 391 | dp->full_name); |
390 | return; | 392 | return; |
391 | } | 393 | } |
392 | 394 | address = of_translate_address(dp, addrp); | |
393 | address = (u_long) dp->addrs[i].address; | 395 | if (address == OF_BAD_ADDR) { |
394 | 396 | printk(KERN_ERR | |
395 | #ifdef CONFIG_PPC64 | 397 | "can't translate framebuffer address for %s\n", |
396 | address += ((struct pci_dn *)dp->data)->phb->pci_mem_offset; | 398 | dp->full_name); |
397 | #endif | 399 | return; |
400 | } | ||
398 | 401 | ||
399 | /* kludge for valkyrie */ | 402 | /* kludge for valkyrie */ |
400 | if (strcmp(dp->name, "valkyrie") == 0) | 403 | if (strcmp(dp->name, "valkyrie") == 0) |
@@ -459,7 +462,9 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
459 | 462 | ||
460 | par->cmap_type = cmap_unknown; | 463 | par->cmap_type = cmap_unknown; |
461 | if (depth == 8) { | 464 | if (depth == 8) { |
462 | /* XXX kludge for ati */ | 465 | |
466 | /* Palette hacks disabled for now */ | ||
467 | #if 0 | ||
463 | if (dp && !strncmp(name, "ATY,Rage128", 11)) { | 468 | if (dp && !strncmp(name, "ATY,Rage128", 11)) { |
464 | unsigned long regbase = dp->addrs[2].address; | 469 | unsigned long regbase = dp->addrs[2].address; |
465 | par->cmap_adr = ioremap(regbase, 0x1FFF); | 470 | par->cmap_adr = ioremap(regbase, 0x1FFF); |
@@ -490,6 +495,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
490 | par->cmap_adr = ioremap(regbase + 0x6000, 0x1000); | 495 | par->cmap_adr = ioremap(regbase + 0x6000, 0x1000); |
491 | par->cmap_type = cmap_gxt2000; | 496 | par->cmap_type = cmap_gxt2000; |
492 | } | 497 | } |
498 | #endif | ||
493 | fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR | 499 | fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR |
494 | : FB_VISUAL_STATIC_PSEUDOCOLOR; | 500 | : FB_VISUAL_STATIC_PSEUDOCOLOR; |
495 | } else | 501 | } else |