[IA64-SGI] pcdp: add PCDP pci interface support
Resend 2 with changes per Bjorn Helgaas comments. Changes from original: + Change globals to vga_console_iobase/vga_console_membase and make them unconditional. + Address style-related comments. Patch to extend the PCDP vga setup code to support PCI io/mem translations for the legacy vga ioport and ram spaces on architectures (e.g. altix) which need them. Summary of the changes: drivers/firmware/pcdp.c drivers/firmware/pcdp.h ----------------------- + add declaration for the spec-defined PCI interface struct (pcdp_if_pci) as well as support macros. + extend setup_vga_console() to know about pcdp_if_pci and add a couple of globals to hold the io and mem translation offsets if present. arch/ia64/kernel/setup.c ------------------------ + tweek early_console_setup() to allow multiple early console setup routines to be called. include/asm-ia64/vga.h ---------------------- + make VGA_MAP_MEM vga_console_membase aware Signed-off-by: Mark Maule <maule@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
This commit is contained in:
parent
54522b6613
commit
66b7f8a304
4 changed files with 62 additions and 12 deletions
|
@ -72,6 +72,8 @@ DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8);
|
||||||
unsigned long ia64_cycles_per_usec;
|
unsigned long ia64_cycles_per_usec;
|
||||||
struct ia64_boot_param *ia64_boot_param;
|
struct ia64_boot_param *ia64_boot_param;
|
||||||
struct screen_info screen_info;
|
struct screen_info screen_info;
|
||||||
|
unsigned long vga_console_iobase;
|
||||||
|
unsigned long vga_console_membase;
|
||||||
|
|
||||||
unsigned long ia64_max_cacheline_size;
|
unsigned long ia64_max_cacheline_size;
|
||||||
unsigned long ia64_iobase; /* virtual address for I/O accesses */
|
unsigned long ia64_iobase; /* virtual address for I/O accesses */
|
||||||
|
@ -273,23 +275,25 @@ io_port_init (void)
|
||||||
static inline int __init
|
static inline int __init
|
||||||
early_console_setup (char *cmdline)
|
early_console_setup (char *cmdline)
|
||||||
{
|
{
|
||||||
|
int earlycons = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
|
#ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
|
||||||
{
|
{
|
||||||
extern int sn_serial_console_early_setup(void);
|
extern int sn_serial_console_early_setup(void);
|
||||||
if (!sn_serial_console_early_setup())
|
if (!sn_serial_console_early_setup())
|
||||||
return 0;
|
earlycons++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_EFI_PCDP
|
#ifdef CONFIG_EFI_PCDP
|
||||||
if (!efi_setup_pcdp_console(cmdline))
|
if (!efi_setup_pcdp_console(cmdline))
|
||||||
return 0;
|
earlycons++;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
||||||
if (!early_serial_console_init(cmdline))
|
if (!early_serial_console_init(cmdline))
|
||||||
return 0;
|
earlycons++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return -1;
|
return (earlycons) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <linux/console.h>
|
#include <linux/console.h>
|
||||||
#include <linux/efi.h>
|
#include <linux/efi.h>
|
||||||
#include <linux/serial.h>
|
#include <linux/serial.h>
|
||||||
|
#include <asm/vga.h>
|
||||||
#include "pcdp.h"
|
#include "pcdp.h"
|
||||||
|
|
||||||
static int __init
|
static int __init
|
||||||
|
@ -40,10 +41,27 @@ setup_serial_console(struct pcdp_uart *uart)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init
|
static int __init
|
||||||
setup_vga_console(struct pcdp_vga *vga)
|
setup_vga_console(struct pcdp_device *dev)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
|
#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
|
||||||
if (efi_mem_type(0xA0000) == EFI_CONVENTIONAL_MEMORY) {
|
u8 *if_ptr;
|
||||||
|
|
||||||
|
if_ptr = ((u8 *)dev + sizeof(struct pcdp_device));
|
||||||
|
if (if_ptr[0] == PCDP_IF_PCI) {
|
||||||
|
struct pcdp_if_pci if_pci;
|
||||||
|
|
||||||
|
/* struct copy since ifptr might not be correctly aligned */
|
||||||
|
|
||||||
|
memcpy(&if_pci, if_ptr, sizeof(if_pci));
|
||||||
|
|
||||||
|
if (if_pci.trans & PCDP_PCI_TRANS_IOPORT)
|
||||||
|
vga_console_iobase = if_pci.ioport_tra;
|
||||||
|
|
||||||
|
if (if_pci.trans & PCDP_PCI_TRANS_MMIO)
|
||||||
|
vga_console_membase = if_pci.mmio_tra;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (efi_mem_type(vga_console_membase + 0xA0000) == EFI_CONVENTIONAL_MEMORY) {
|
||||||
printk(KERN_ERR "PCDP: VGA selected, but frame buffer is not MMIO!\n");
|
printk(KERN_ERR "PCDP: VGA selected, but frame buffer is not MMIO!\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +113,7 @@ efi_setup_pcdp_console(char *cmdline)
|
||||||
dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) {
|
dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) {
|
||||||
if (dev->flags & PCDP_PRIMARY_CONSOLE) {
|
if (dev->flags & PCDP_PRIMARY_CONSOLE) {
|
||||||
if (dev->type == PCDP_CONSOLE_VGA) {
|
if (dev->type == PCDP_CONSOLE_VGA) {
|
||||||
return setup_vga_console((struct pcdp_vga *) dev);
|
return setup_vga_console(dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,11 +52,34 @@ struct pcdp_uart {
|
||||||
u32 clock_rate;
|
u32 clock_rate;
|
||||||
u8 pci_prog_intfc;
|
u8 pci_prog_intfc;
|
||||||
u8 flags;
|
u8 flags;
|
||||||
};
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#define PCDP_IF_PCI 1
|
||||||
|
|
||||||
|
/* pcdp_if_pci.trans */
|
||||||
|
#define PCDP_PCI_TRANS_IOPORT 0x02
|
||||||
|
#define PCDP_PCI_TRANS_MMIO 0x01
|
||||||
|
|
||||||
|
struct pcdp_if_pci {
|
||||||
|
u8 interconnect;
|
||||||
|
u8 reserved;
|
||||||
|
u16 length;
|
||||||
|
u8 segment;
|
||||||
|
u8 bus;
|
||||||
|
u8 dev;
|
||||||
|
u8 fun;
|
||||||
|
u16 dev_id;
|
||||||
|
u16 vendor_id;
|
||||||
|
u32 acpi_interrupt;
|
||||||
|
u64 mmio_tra;
|
||||||
|
u64 ioport_tra;
|
||||||
|
u8 flags;
|
||||||
|
u8 trans;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct pcdp_vga {
|
struct pcdp_vga {
|
||||||
u8 count; /* address space descriptors */
|
u8 count; /* address space descriptors */
|
||||||
};
|
} __attribute__((packed));
|
||||||
|
|
||||||
/* pcdp_device.flags */
|
/* pcdp_device.flags */
|
||||||
#define PCDP_PRIMARY_CONSOLE 1
|
#define PCDP_PRIMARY_CONSOLE 1
|
||||||
|
@ -66,7 +89,9 @@ struct pcdp_device {
|
||||||
u8 flags;
|
u8 flags;
|
||||||
u16 length;
|
u16 length;
|
||||||
u16 efi_index;
|
u16 efi_index;
|
||||||
};
|
/* next data is pcdp_if_pci or pcdp_if_acpi (not yet supported) */
|
||||||
|
/* next data is device specific type (currently only pcdp_vga) */
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct pcdp {
|
struct pcdp {
|
||||||
u8 signature[4];
|
u8 signature[4];
|
||||||
|
@ -81,4 +106,4 @@ struct pcdp {
|
||||||
u32 num_uarts;
|
u32 num_uarts;
|
||||||
struct pcdp_uart uart[0]; /* actual size is num_uarts */
|
struct pcdp_uart uart[0]; /* actual size is num_uarts */
|
||||||
/* remainder of table is pcdp_device structures */
|
/* remainder of table is pcdp_device structures */
|
||||||
};
|
} __attribute__((packed));
|
||||||
|
|
|
@ -14,7 +14,10 @@
|
||||||
* videoram directly without any black magic.
|
* videoram directly without any black magic.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VGA_MAP_MEM(x) ((unsigned long) ioremap((x), 0))
|
extern unsigned long vga_console_iobase;
|
||||||
|
extern unsigned long vga_console_membase;
|
||||||
|
|
||||||
|
#define VGA_MAP_MEM(x) ((unsigned long) ioremap(vga_console_membase + (x), 0))
|
||||||
|
|
||||||
#define vga_readb(x) (*(x))
|
#define vga_readb(x) (*(x))
|
||||||
#define vga_writeb(x,y) (*(y) = (x))
|
#define vga_writeb(x,y) (*(y) = (x))
|
||||||
|
|
Loading…
Reference in a new issue