From: Pete P. <pp...@us...> - 2001-11-11 00:24:45
|
Update of /cvsroot/linux-mips/linux/arch/mips/galileo-boards/ev96100 In directory usw-pr-cvs1:/tmp/cvs-serv12683/arch/mips/galileo-boards/ev96100 Modified Files: irq.c pci_fixups.c pci_ops.c setup.c Log Message: Added EV96100A support. Differences between EV96100A and EV96100: * boot code does not enable gt pci master (ev96100A) * interrupt lines are routed differently * gt96100eth ethernet driver required modifications to make it work with both system controllers. Index: irq.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/galileo-boards/ev96100/irq.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- irq.c 2001/08/25 02:19:27 1.5 +++ irq.c 2001/11/11 00:24:38 1.6 @@ -56,8 +56,6 @@ #ifdef CONFIG_REMOTE_DEBUG extern void breakpoint(void); -extern int ev96100_remote_debug; -extern int ev96100_remote_debug_line; #endif extern void puts(unsigned char *cp); @@ -320,11 +318,9 @@ #ifdef CONFIG_REMOTE_DEBUG /* If local serial I/O used for debug port, enter kgdb at once */ - if (ev96100_remote_debug) { - puts("Waiting for kgdb to connect..."); - set_debug_traps(); - breakpoint(); - } + puts("Waiting for kgdb to connect..."); + set_debug_traps(); + breakpoint(); #endif } Index: pci_fixups.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/galileo-boards/ev96100/pci_fixups.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- pci_fixups.c 2001/09/07 18:43:41 1.3 +++ pci_fixups.c 2001/11/11 00:24:38 1.4 @@ -35,76 +35,67 @@ #include <linux/pci.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/pci_ids.h> #include <asm/gt64120.h> #include <asm/galileo-boards/ev96100.h> +extern unsigned short get_gt_devid(void); + void __init pcibios_fixup_resources(struct pci_dev *dev) { } void __init pcibios_fixup(void) { - /* - * Due to a bug in the Galileo system controller, we need to setup - * the PCI BAR for the Galileo internal registers. - * This should be done in the bios/bootprom and will be fixed in - * a later revision of YAMON (the MIPS boards boot prom). - */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, cpu_to_le32( - (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */ - (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 device */ - (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0 */ - ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4 */ - GT_PCI0_CFGADDR_CONFIGEN_BIT )); - - /* Perform the write */ - GT_WRITE( GT_PCI0_CFGDATA_OFS, cpu_to_le32(PHYSADDR(MIPS_GT_BASE))); } void __init pcibios_fixup_irqs(void) { struct pci_dev *dev; unsigned int slot; - unsigned char irq; - unsigned long vendor; + u32 vendor; + unsigned short gt_devid = get_gt_devid(); /* - ** EV96100 interrupt routing for pci bus 0 - ** NOTE: this are my experimental findings, since I do not - ** have Galileo's latest PLD equations. - ** - ** The functions in irq.c assume the following irq numbering: - ** irq 2: CPU cause register bit IP2 - ** irq 3: CPU cause register bit IP3 - ** irq 4: CPU cause register bit IP4 - ** irq 5: CPU cause register bit IP5 - ** irq 6: CPU cause register bit IP6 - ** irq 7: CPU cause register bit IP7 + ** EV96100/A interrupt routing for pci bus 0 ** + ** Note: EV96100A board with irq jumper set on 'linux' */ - pci_for_each_dev(dev) { if (dev->bus->number != 0) return; slot = PCI_SLOT(dev->devfn); - pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &vendor); + pci_read_config_dword(dev, PCI_SUBSYSTEM_VENDOR_ID, &vendor); //#ifdef DEBUG - printk("devfn %x, slot %d vendor %x\n", dev->devfn, slot, vendor); + printk("devfn %x, slot %d devid %x\n", + dev->devfn, slot, gt_devid); //#endif /* fixup irq line based on slot # */ if (slot == 8) { - dev->irq = 5; - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + if (gt_devid == PCI_DEVICE_ID_GALILEO_GT96100) + dev->irq = 5; + else if (gt_devid == PCI_DEVICE_ID_GALILEO_GT96100A) + dev->irq = 3; + else { + printk(KERN_ERR "unknown GT controller id %x\n", + gt_devid); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + 0xff); + continue; + } + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + dev->irq); } else if (slot == 9) { - dev->irq = 2; - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + dev->irq = 2; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + dev->irq); } } } Index: pci_ops.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/galileo-boards/ev96100/pci_ops.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- pci_ops.c 2001/07/06 01:25:33 1.1 +++ pci_ops.c 2001/11/11 00:24:38 1.2 @@ -42,6 +42,7 @@ #include <linux/kernel.h> #include <linux/init.h> +#include <asm/delay.h> #include <asm//gt64120.h> #include <asm/galileo-boards/ev96100.h> #include <asm/pci_channel.h> @@ -80,8 +81,8 @@ { NULL, NULL, NULL, NULL, NULL} }; -static int -gt96100_config_access(unsigned char access_type, struct pci_dev *dev, +int +static gt96100_config_access(unsigned char access_type, struct pci_dev *dev, unsigned char where, u32 *data) { unsigned char bus = dev->bus->number; @@ -103,21 +104,24 @@ (dev_fn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | GT_PCI0_CFGADDR_CONFIGEN_BIT); + udelay(2); if (access_type == PCI_ACCESS_WRITE) { - if (dev_fn != 0) { - *data = le32_to_cpu(*data); - } - GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); + if (dev_fn != 0) { + *data = le32_to_cpu(*data); + } + GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); } else { - GT_READ(GT_PCI0_CFGDATA_OFS, *data); - if (dev_fn != 0) { - *data = le32_to_cpu(*data); - } + GT_READ(GT_PCI0_CFGDATA_OFS, *data); + if (dev_fn != 0) { + *data = le32_to_cpu(*data); + } } + udelay(2); + /* Check for master or target abort */ GT_READ(GT_INTRCAUSE_OFS, intr); @@ -266,31 +270,5 @@ write_config_word, write_config_dword }; - -#if 0 -void __init pcibios_init(void) -{ - - DBG("PCI: Probing PCI hardware on host bus 0.\n"); - pci_scan_bus(0, &mips_pci_ops, NULL); - - /* - * Due to a bug in the Galileo system controller, we need to setup - * the PCI BAR for the Galileo internal registers. - * This should be done in the bios/bootprom and will be fixed in - * a later revision of YAMON (the MIPS boards boot prom). - */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, cpu_to_le32( - (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */ - (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 device */ - (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0 */ - ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4 */ - GT_PCI0_CFGADDR_CONFIGEN_BIT )); - - /* Perform the write */ - GT_WRITE( GT_PCI0_CFGDATA_OFS, cpu_to_le32(PHYSADDR(MIPS_GT_BASE))); - -} -#endif #endif /* CONFIG_PCI */ Index: setup.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/galileo-boards/ev96100/setup.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- setup.c 2001/08/25 02:19:27 1.3 +++ setup.c 2001/11/11 00:24:38 1.4 @@ -40,11 +40,13 @@ #include <linux/mc146818rtc.h> #include <linux/string.h> #include <linux/ctype.h> +#include <linux/pci.h> #include <asm/cpu.h> #include <asm/bootinfo.h> #include <asm/mipsregs.h> #include <asm/irq.h> +#include <asm/delay.h> #include <asm/gt64120.h> #include <asm/galileo-boards/ev96100.h> #include <asm/galileo-boards/ev96100int.h> @@ -57,14 +59,6 @@ char serial_console[20]; #endif -#ifdef CONFIG_REMOTE_DEBUG -extern void breakpoint(void); -int ev96100_remote_debug; -int ev96100_remote_debug_line; -#endif - -void (*board_time_init)(struct irqaction *irq); -extern void ev96100_time_init(struct irqaction *irq); extern char * __init prom_getcmdline(void); extern void mips_reboot_setup(void); @@ -78,12 +72,13 @@ unsigned char mac_0_1[12]; + void __init ev96100_setup(void) { - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); unsigned long status = read_32bit_cp0_register(CP0_STATUS); unsigned long info = read_32bit_cp0_register(CP0_INFO); + u32 tmp; char *argptr; @@ -151,25 +146,6 @@ } #endif - -#ifdef CONFIG_REMOTE_DEBUG - if (strstr(argptr, "kgdb=ttyS") != NULL) { - int line; - argptr += strlen("kgdb=ttyS"); - if (*argptr == '0') - ev96100_remote_debug_line = 0; - else if (*argptr == '1') - ev96100_remote_debug_line = 1; - else - puts("Unknown serial line /dev/ttyS%c\n", *argptr); - - debugInitUart(ev96100_remote_debug_line); - ev96100_remote_debug = 1; - /* Breakpoints and stuff are in init_IRQ() */ - } -#endif - - board_time_init = ev96100_time_init; rtc_ops = &no_rtc_ops; mips_reboot_setup(); mips_io_port_base = KSEG1; @@ -179,4 +155,59 @@ #ifdef CONFIG_BLK_DEV_INITRD ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); #endif + + + /* + * setup gt controller master bit so we can do config cycles + */ + + /* Clear cause register bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + udelay(2); + tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS)); + + tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SERR); + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + udelay(2); + *(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS) = cpu_to_le32(tmp); + + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + udelay(2); + tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS)); +} + +unsigned short get_gt_devid() +{ + u32 gt_devid; + + /* Figure out if this is a gt96100 or gt96100A */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_VENDOR_ID / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + udelay(4); + gt_devid = le32_to_cpu(*(volatile u32 *) + (MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS)); + return (unsigned short)(gt_devid>>16); } |