Skip to content

Commit

Permalink
ALPHA: support graphics on non-zero PCI domains
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jay Estabrook authored and Linus Torvalds committed Jun 1, 2007
1 parent 8778beb commit 025a221
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 112 deletions.
16 changes: 16 additions & 0 deletions arch/alpha/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,15 @@ config ALPHA_BROKEN_IRQ_MASK
depends on ALPHA_GENERIC || ALPHA_PC164
default y

config VGA_HOSE
bool
depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI
default y
help
Support VGA on an arbitrary hose; needed for several platforms
which always have multiple hoses, and whose consoles support it.


config ALPHA_SRM
bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME
default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_LYNX || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL
Expand Down Expand Up @@ -644,6 +653,13 @@ source "arch/alpha/oprofile/Kconfig"

source "arch/alpha/Kconfig.debug"

# DUMMY_CONSOLE may be defined in drivers/video/console/Kconfig
# but we also need it if VGA_HOSE is set
config DUMMY_CONSOLE
bool
depends on VGA_HOSE
default y

source "security/Kconfig"

source "crypto/Kconfig"
Expand Down
70 changes: 48 additions & 22 deletions arch/alpha/kernel/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/vt.h>
#include <asm/vga.h>
#include <asm/machvec.h>

#include "pci_impl.h"

#ifdef CONFIG_VGA_HOSE

/*
* Externally-visible vga hose bases
*/
unsigned long __vga_hose_io_base = 0; /* base for default hose */
unsigned long __vga_hose_mem_base = 0; /* base for default hose */
struct pci_controller *pci_vga_hose;
static struct resource alpha_vga = {
.name = "alpha-vga+",
.start = 0x3C0,
.end = 0x3DF
};

static struct pci_controller * __init
default_vga_hose_select(struct pci_controller *h1, struct pci_controller *h2)
Expand All @@ -29,37 +33,59 @@ default_vga_hose_select(struct pci_controller *h1, struct pci_controller *h2)
return h1;
}

void __init
set_vga_hose(struct pci_controller *hose)
{
if (hose) {
__vga_hose_io_base = hose->io_space->start;
__vga_hose_mem_base = hose->mem_space->start;
}
}

void __init
locate_and_init_vga(void *(*sel_func)(void *, void *))
{
struct pci_controller *hose = NULL;
struct pci_dev *dev = NULL;

/* Default the select function */
if (!sel_func) sel_func = (void *)default_vga_hose_select;

/* Find the console VGA device */
for(dev=NULL; (dev=pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, dev));) {
if (!hose) hose = dev->sysdata;
else hose = sel_func(hose, dev->sysdata);
if (!hose)
hose = dev->sysdata;
else
hose = sel_func(hose, dev->sysdata);
}

/* Did we already inititialize the correct one? */
if (conswitchp == &vga_con &&
__vga_hose_io_base == hose->io_space->start &&
__vga_hose_mem_base == hose->mem_space->start)
/* Did we already initialize the correct one? Is there one? */
if (!hose || (conswitchp == &vga_con && pci_vga_hose == hose))
return;

/* Set the VGA hose and init the new console */
set_vga_hose(hose);
/* Create a new VGA ioport resource WRT the hose it is on. */
alpha_vga.start += hose->io_space->start;
alpha_vga.end += hose->io_space->start;
request_resource(hose->io_space, &alpha_vga);

/* Set the VGA hose and init the new console. */
pci_vga_hose = hose;
take_over_console(&vga_con, 0, MAX_NR_CONSOLES-1, 1);
}

void __init
find_console_vga_hose(void)
{
u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);

if (pu64[7] == 3) { /* TERM_TYPE == graphics */
struct pci_controller *hose;
int h = (pu64[30] >> 24) & 0xff; /* console hose # */

/*
* Our hose numbering DOES match the console's, so find
* the right one...
*/
for (hose = hose_head; hose; hose = hose->next) {
if (hose->index == h) break;
}

if (hose) {
printk("Console graphics on hose %d\n", h);
pci_vga_hose = hose;
}
}
}

#endif
43 changes: 17 additions & 26 deletions arch/alpha/kernel/core_marvel.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/rtc.h>
#include <asm/vga.h>

#include "proto.h"
#include "pci_impl.h"
Expand Down Expand Up @@ -367,9 +368,8 @@ marvel_io7_present(gct6_node *node)
}

static void __init
marvel_init_vga_hose(void)
marvel_find_console_vga_hose(void)
{
#ifdef CONFIG_VGA_HOSE
u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);

if (pu64[7] == 3) { /* TERM_TYPE == graphics */
Expand Down Expand Up @@ -403,7 +403,6 @@ marvel_init_vga_hose(void)
pci_vga_hose = hose;
}
}
#endif /* CONFIG_VGA_HOSE */
}

gct6_search_struct gct_wanted_node_list[] = {
Expand Down Expand Up @@ -459,7 +458,7 @@ marvel_init_arch(void)
marvel_init_io7(io7);

/* Check for graphic console location (if any). */
marvel_init_vga_hose();
marvel_find_console_vga_hose();
}

void
Expand Down Expand Up @@ -684,9 +683,6 @@ __marvel_rtc_io(u8 b, unsigned long addr, int write)
/*
* IO map support.
*/

#define __marvel_is_mem_vga(a) (((a) >= 0xa0000) && ((a) <= 0xc0000))

void __iomem *
marvel_ioremap(unsigned long addr, unsigned long size)
{
Expand All @@ -698,13 +694,9 @@ marvel_ioremap(unsigned long addr, unsigned long size)
unsigned long pfn;

/*
* Adjust the addr.
* Adjust the address.
*/
#ifdef CONFIG_VGA_HOSE
if (pci_vga_hose && __marvel_is_mem_vga(addr)) {
addr += pci_vga_hose->mem_space->start;
}
#endif
FIXUP_MEMADDR_VGA(addr);

/*
* Find the hose.
Expand Down Expand Up @@ -781,7 +773,9 @@ marvel_ioremap(unsigned long addr, unsigned long size)
return (void __iomem *) vaddr;
}

return NULL;
/* Assume it was already a reasonable address */
vaddr = baddr + hose->mem_space->start;
return (void __iomem *) vaddr;
}

void
Expand All @@ -803,21 +797,12 @@ marvel_is_mmio(const volatile void __iomem *xaddr)
return (addr & 0xFF000000UL) == 0;
}

#define __marvel_is_port_vga(a) \
(((a) >= 0x3b0) && ((a) < 0x3e0) && ((a) != 0x3b3) && ((a) != 0x3d3))
#define __marvel_is_port_kbd(a) (((a) == 0x60) || ((a) == 0x64))
#define __marvel_is_port_rtc(a) (((a) == 0x70) || ((a) == 0x71))

void __iomem *marvel_ioportmap (unsigned long addr)
{
if (__marvel_is_port_rtc (addr) || __marvel_is_port_kbd(addr))
;
#ifdef CONFIG_VGA_HOSE
else if (__marvel_is_port_vga (addr) && pci_vga_hose)
addr += pci_vga_hose->io_space->start;
#endif
else
return NULL;
FIXUP_IOADDR_VGA(addr);
return (void __iomem *)addr;
}

Expand All @@ -829,8 +814,14 @@ marvel_ioread8(void __iomem *xaddr)
return 0;
else if (__marvel_is_port_rtc(addr))
return __marvel_rtc_io(0, addr, 0);
else
else if (marvel_is_ioaddr(addr))
return __kernel_ldbu(*(vucp)addr);
else
/* this should catch other legacy addresses
that would normally fail on MARVEL,
because there really is nothing there...
*/
return ~0;
}

void
Expand All @@ -841,7 +832,7 @@ marvel_iowrite8(u8 b, void __iomem *xaddr)
return;
else if (__marvel_is_port_rtc(addr))
__marvel_rtc_io(b, addr, 1);
else
else if (marvel_is_ioaddr(addr))
__kernel_stb(b, *(vucp)addr);
}

Expand Down
Loading

0 comments on commit 025a221

Please sign in to comment.