aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha/kernel/core_titan.c
diff options
context:
space:
mode:
authorJay Estabrook <jay.estabrook@hp.com>2007-06-01 03:47:03 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-06-01 11:18:29 -0400
commit025a22151c41890e5d30a1d4fb84c547b84d7671 (patch)
tree9effd8ca9ceed994a03d252d4a1d28fa07ae93a1 /arch/alpha/kernel/core_titan.c
parent8778beb981b7e5df3472b05475e4c7905dad1f3d (diff)
ALPHA: support graphics on non-zero PCI domains
This code replaces earlier and incomplete handling of graphics on non-zero PCI domains (aka hoses or peer PCI buses). An option (CONFIG_VGA_HOSE) is set TRUE if configuring a GENERIC kernel, or a kernel for MARVEL, TITAN, or TSUNAMI machines, as these are the machines whose SRM consoles are capable of configuring and handling graphics options on non-zero hoses. All other machines have the option set FALSE. A routine, "find_console_vga_hose()", is used to find the graphics device which the machine's firmware believes is the console device, and it sets a global (pci_vga_hose) for later use in managing access to the device. This is called in "init_arch" on TITAN and TSUNAMI machines; MARVEL machines use a custom version of this routine because of extra complexity. A routine, "locate_and_init_vga()", is used to find the graphics device and set a global (pci_vga_hose) for later use in managing access to the device, in the case where "find_console_vga_hose" has failed. Various adjustments are made to the ioremap and ioportmap routines for detecting and translating "legacy" VGA register and memory references to the real PCI domain. [akpm@linux-foundation.org: don't statically init bss] [akpm@linux-foundation.org: build fix] Signed-off-by: Jay Estabrook <jay.estabrook@hp.com> Signed-off-by: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Richard Henderson <rth@twiddle.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/alpha/kernel/core_titan.c')
-rw-r--r--arch/alpha/kernel/core_titan.c70
1 files changed, 30 insertions, 40 deletions
diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c
index 3662fef7db9a..819326627b96 100644
--- a/arch/alpha/kernel/core_titan.c
+++ b/arch/alpha/kernel/core_titan.c
@@ -21,6 +21,7 @@
21#include <asm/smp.h> 21#include <asm/smp.h>
22#include <asm/pgalloc.h> 22#include <asm/pgalloc.h>
23#include <asm/tlbflush.h> 23#include <asm/tlbflush.h>
24#include <asm/vga.h>
24 25
25#include "proto.h" 26#include "proto.h"
26#include "pci_impl.h" 27#include "pci_impl.h"
@@ -35,6 +36,11 @@ struct
35} saved_config[4] __attribute__((common)); 36} saved_config[4] __attribute__((common));
36 37
37/* 38/*
39 * Is PChip 1 present? No need to query it more than once.
40 */
41static int titan_pchip1_present;
42
43/*
38 * BIOS32-style PCI interface: 44 * BIOS32-style PCI interface:
39 */ 45 */
40 46
@@ -344,43 +350,17 @@ titan_init_one_pachip_port(titan_pachip_port *port, int index)
344static void __init 350static void __init
345titan_init_pachips(titan_pachip *pachip0, titan_pachip *pachip1) 351titan_init_pachips(titan_pachip *pachip0, titan_pachip *pachip1)
346{ 352{
347 int pchip1_present = TITAN_cchip->csc.csr & 1L<<14; 353 titan_pchip1_present = TITAN_cchip->csc.csr & 1L<<14;
348 354
349 /* Init the ports in hose order... */ 355 /* Init the ports in hose order... */
350 titan_init_one_pachip_port(&pachip0->g_port, 0); /* hose 0 */ 356 titan_init_one_pachip_port(&pachip0->g_port, 0); /* hose 0 */
351 if (pchip1_present) 357 if (titan_pchip1_present)
352 titan_init_one_pachip_port(&pachip1->g_port, 1);/* hose 1 */ 358 titan_init_one_pachip_port(&pachip1->g_port, 1);/* hose 1 */
353 titan_init_one_pachip_port(&pachip0->a_port, 2); /* hose 2 */ 359 titan_init_one_pachip_port(&pachip0->a_port, 2); /* hose 2 */
354 if (pchip1_present) 360 if (titan_pchip1_present)
355 titan_init_one_pachip_port(&pachip1->a_port, 3);/* hose 3 */ 361 titan_init_one_pachip_port(&pachip1->a_port, 3);/* hose 3 */
356} 362}
357 363
358static void __init
359titan_init_vga_hose(void)
360{
361#ifdef CONFIG_VGA_HOSE
362 u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);
363
364 if (pu64[7] == 3) { /* TERM_TYPE == graphics */
365 struct pci_controller *hose;
366 int h = (pu64[30] >> 24) & 0xff; /* console hose # */
367
368 /*
369 * Our hose numbering matches the console's, so just find
370 * the right one...
371 */
372 for (hose = hose_head; hose; hose = hose->next) {
373 if (hose->index == h) break;
374 }
375
376 if (hose) {
377 printk("Console graphics on hose %d\n", hose->index);
378 pci_vga_hose = hose;
379 }
380 }
381#endif /* CONFIG_VGA_HOSE */
382}
383
384void __init 364void __init
385titan_init_arch(void) 365titan_init_arch(void)
386{ 366{
@@ -406,6 +386,7 @@ titan_init_arch(void)
406 386
407 /* With multiple PCI busses, we play with I/O as physical addrs. */ 387 /* With multiple PCI busses, we play with I/O as physical addrs. */
408 ioport_resource.end = ~0UL; 388 ioport_resource.end = ~0UL;
389 iomem_resource.end = ~0UL;
409 390
410 /* PCI DMA Direct Mapping is 1GB at 2GB. */ 391 /* PCI DMA Direct Mapping is 1GB at 2GB. */
411 __direct_map_base = 0x80000000; 392 __direct_map_base = 0x80000000;
@@ -415,7 +396,7 @@ titan_init_arch(void)
415 titan_init_pachips(TITAN_pachip0, TITAN_pachip1); 396 titan_init_pachips(TITAN_pachip0, TITAN_pachip1);
416 397
417 /* Check for graphic console location (if any). */ 398 /* Check for graphic console location (if any). */
418 titan_init_vga_hose(); 399 find_console_vga_hose();
419} 400}
420 401
421static void 402static void
@@ -441,9 +422,7 @@ titan_kill_one_pachip_port(titan_pachip_port *port, int index)
441static void 422static void
442titan_kill_pachips(titan_pachip *pachip0, titan_pachip *pachip1) 423titan_kill_pachips(titan_pachip *pachip0, titan_pachip *pachip1)
443{ 424{
444 int pchip1_present = TITAN_cchip->csc.csr & 1L<<14; 425 if (titan_pchip1_present) {
445
446 if (pchip1_present) {
447 titan_kill_one_pachip_port(&pachip1->g_port, 1); 426 titan_kill_one_pachip_port(&pachip1->g_port, 1);
448 titan_kill_one_pachip_port(&pachip1->a_port, 3); 427 titan_kill_one_pachip_port(&pachip1->a_port, 3);
449 } 428 }
@@ -463,6 +442,14 @@ titan_kill_arch(int mode)
463 */ 442 */
464 443
465void __iomem * 444void __iomem *
445titan_ioportmap(unsigned long addr)
446{
447 FIXUP_IOADDR_VGA(addr);
448 return (void __iomem *)(addr + TITAN_IO_BIAS);
449}
450
451
452void __iomem *
466titan_ioremap(unsigned long addr, unsigned long size) 453titan_ioremap(unsigned long addr, unsigned long size)
467{ 454{
468 int h = (addr & TITAN_HOSE_MASK) >> TITAN_HOSE_SHIFT; 455 int h = (addr & TITAN_HOSE_MASK) >> TITAN_HOSE_SHIFT;
@@ -475,14 +462,12 @@ titan_ioremap(unsigned long addr, unsigned long size)
475 unsigned long pfn; 462 unsigned long pfn;
476 463
477 /* 464 /*
478 * Adjust the addr. 465 * Adjust the address and hose, if necessary.
479 */ 466 */
480#ifdef CONFIG_VGA_HOSE 467 if (pci_vga_hose && __is_mem_vga(addr)) {
481 if (pci_vga_hose && __titan_is_mem_vga(addr)) {
482 h = pci_vga_hose->index; 468 h = pci_vga_hose->index;
483 addr += pci_vga_hose->mem_space->start; 469 addr += pci_vga_hose->mem_space->start;
484 } 470 }
485#endif
486 471
487 /* 472 /*
488 * Find the hose. 473 * Find the hose.
@@ -521,8 +506,10 @@ titan_ioremap(unsigned long addr, unsigned long size)
521 * Map it 506 * Map it
522 */ 507 */
523 area = get_vm_area(size, VM_IOREMAP); 508 area = get_vm_area(size, VM_IOREMAP);
524 if (!area) 509 if (!area) {
510 printk("ioremap failed... no vm_area...\n");
525 return NULL; 511 return NULL;
512 }
526 513
527 ptes = hose->sg_pci->ptes; 514 ptes = hose->sg_pci->ptes;
528 for (vaddr = (unsigned long)area->addr; 515 for (vaddr = (unsigned long)area->addr;
@@ -539,7 +526,7 @@ titan_ioremap(unsigned long addr, unsigned long size)
539 if (__alpha_remap_area_pages(vaddr, 526 if (__alpha_remap_area_pages(vaddr,
540 pfn << PAGE_SHIFT, 527 pfn << PAGE_SHIFT,
541 PAGE_SIZE, 0)) { 528 PAGE_SIZE, 0)) {
542 printk("FAILED to map...\n"); 529 printk("FAILED to remap_area_pages...\n");
543 vfree(area->addr); 530 vfree(area->addr);
544 return NULL; 531 return NULL;
545 } 532 }
@@ -551,7 +538,8 @@ titan_ioremap(unsigned long addr, unsigned long size)
551 return (void __iomem *) vaddr; 538 return (void __iomem *) vaddr;
552 } 539 }
553 540
554 return NULL; 541 /* Assume a legacy (read: VGA) address, and return appropriately. */
542 return (void __iomem *)(addr + TITAN_MEM_BIAS);
555} 543}
556 544
557void 545void
@@ -574,6 +562,7 @@ titan_is_mmio(const volatile void __iomem *xaddr)
574} 562}
575 563
576#ifndef CONFIG_ALPHA_GENERIC 564#ifndef CONFIG_ALPHA_GENERIC
565EXPORT_SYMBOL(titan_ioportmap);
577EXPORT_SYMBOL(titan_ioremap); 566EXPORT_SYMBOL(titan_ioremap);
578EXPORT_SYMBOL(titan_iounmap); 567EXPORT_SYMBOL(titan_iounmap);
579EXPORT_SYMBOL(titan_is_mmio); 568EXPORT_SYMBOL(titan_is_mmio);
@@ -750,6 +739,7 @@ titan_agp_info(void)
750 if (titan_query_agp(port)) 739 if (titan_query_agp(port))
751 hosenum = 2; 740 hosenum = 2;
752 if (hosenum < 0 && 741 if (hosenum < 0 &&
742 titan_pchip1_present &&
753 titan_query_agp(port = &TITAN_pachip1->a_port)) 743 titan_query_agp(port = &TITAN_pachip1->a_port))
754 hosenum = 3; 744 hosenum = 3;
755 745