void __init arch_init_irq(void) { /* by default, we disable all interrupts and route all vrc5477 * interrupts to pin 0 (irq 2) */ ddb_out32(DDB_INTCTRL0, 0); ddb_out32(DDB_INTCTRL1, 0); ddb_out32(DDB_INTCTRL2, 0); ddb_out32(DDB_INTCTRL3, 0); clear_c0_status(0xff00); set_c0_status(0x0400); /* setup PCI interrupt attributes */ set_pci_int_attr(PCI0, INTA, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI0, INTB, ACTIVE_LOW, LEVEL_SENSE); if (mips_machtype == MACH_NEC_ROCKHOPPERII) set_pci_int_attr(PCI0, INTC, ACTIVE_HIGH, LEVEL_SENSE); else set_pci_int_attr(PCI0, INTC, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI0, INTD, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI0, INTE, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI1, INTA, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI1, INTB, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI1, INTC, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI1, INTD, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI1, INTE, ACTIVE_LOW, LEVEL_SENSE); /* * for debugging purpose, we enable several error interrupts * and route them to pin 1. (IP3) */ /* cpu parity check - 0 */ ll_vrc5477_irq_route(0, 1); ll_vrc5477_irq_enable(0); /* cpu no-target decode - 1 */ ll_vrc5477_irq_route(1, 1); ll_vrc5477_irq_enable(1); /* local bus read time-out - 7 */ ll_vrc5477_irq_route(7, 1); ll_vrc5477_irq_enable(7); /* PCI SERR# - 14 */ ll_vrc5477_irq_route(14, 1); ll_vrc5477_irq_enable(14); /* PCI internal error - 15 */ ll_vrc5477_irq_route(15, 1); ll_vrc5477_irq_enable(15); /* IOPCI SERR# - 30 */ ll_vrc5477_irq_route(30, 1); ll_vrc5477_irq_enable(30); /* IOPCI internal error - 31 */ ll_vrc5477_irq_route(31, 1); ll_vrc5477_irq_enable(31); /* init all controllers */ init_i8259_irqs(); mips_cpu_irq_init(); vrc5477_irq_init(VRC5477_IRQ_BASE); /* setup cascade interrupts */ setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade); setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade); }
void ddb5477_irq_setup(void) { db_run(printk("ddb5477_irq_setup invoked.\n")); /* by default, we disable all interrupts and route all vrc5477 * interrupts to pin 0 (irq 2) */ ddb_out32(DDB_INTCTRL0, 0); ddb_out32(DDB_INTCTRL1, 0); ddb_out32(DDB_INTCTRL2, 0); ddb_out32(DDB_INTCTRL3, 0); clear_cp0_status(0xff00); set_cp0_status(0x0400); /* setup PCI interrupt attributes */ set_pci_int_attr(PCI0, INTA, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI0, INTB, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI0, INTC, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI0, INTD, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI0, INTE, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI1, INTA, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI1, INTB, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI1, INTC, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI1, INTD, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI1, INTE, ACTIVE_LOW, LEVEL_SENSE); /* * for debugging purpose, we enable several error interrupts * and route them to pin 1. (IP3) */ /* cpu parity check - 0 */ ll_vrc5477_irq_route(0, 1); ll_vrc5477_irq_enable(0); /* cpu no-target decode - 1 */ ll_vrc5477_irq_route(1, 1); ll_vrc5477_irq_enable(1); /* local bus read time-out - 7 */ ll_vrc5477_irq_route(7, 1); ll_vrc5477_irq_enable(7); /* PCI SERR# - 14 */ ll_vrc5477_irq_route(14, 1); ll_vrc5477_irq_enable(14); /* PCI internal error - 15 */ ll_vrc5477_irq_route(15, 1); ll_vrc5477_irq_enable(15); /* IOPCI SERR# - 30 */ ll_vrc5477_irq_route(30, 1); ll_vrc5477_irq_enable(30); /* IOPCI internal error - 31 */ ll_vrc5477_irq_route(31, 1); ll_vrc5477_irq_enable(31); /* init all controllers */ mips_cpu_irq_init(0); vrc5477_irq_init(8); /* hook up the first-level interrupt handler */ set_except_vector(0, ddb5477_handle_int); }
void __init ddb_pci_reset_bus(void) { u32 temp; /* * I am not sure about the "official" procedure, the following * steps work as far as I know: * We first set PCI cold reset bit (bit 31) in PCICTRL-H. * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H. * The same is true for both PCI channels. */ temp = ddb_in32(DDB_PCICTRL+4); temp |= 0x80000000; ddb_out32(DDB_PCICTRL+4, temp); temp &= ~0xc0000000; ddb_out32(DDB_PCICTRL+4, temp); }
static inline void set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger) { u32 reg_value; u32 reg_bitmask; reg_value = ddb_in32(pci); reg_bitmask = 0x3 << (intn * 2); reg_value &= ~reg_bitmask; reg_value |= (active | trigger) << (intn * 2); ddb_out32(pci, reg_value); }
u8 i8259_interrupt_ack(void) { u8 irq; u32 reg; /* Set window 0 for interrupt acknowledge */ reg = ddb_in32(DDB_PCIINIT10); ddb_set_pmr(DDB_PCIINIT10, DDB_PCICMD_IACK, 0, DDB_PCI_ACCESS_32); irq = *(volatile u8 *) KSEG1ADDR(DDB_PCI_IACK_BASE); ddb_out32(DDB_PCIINIT10, reg); return irq; }
void ll_vrc5477_irq_enable(int vrc5477_irq) { u32 reg_value; u32 reg_bitmask; u32 reg_index; db_assert(vrc5477_irq >= 0); db_assert(vrc5477_irq < NUM_5477_IRQ); reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4; reg_value = ddb_in32(reg_index); reg_bitmask = 8 << (vrc5477_irq % 8 * 4); db_assert((reg_value & reg_bitmask) == 0); ddb_out32(reg_index, reg_value | reg_bitmask); }
static void vrc5477_irq_ack(unsigned int irq) { db_assert(vrc5477_irq_base != -1); db_assert(irq >= vrc5477_irq_base); db_assert(irq < vrc5477_irq_base+ NUM_5477_IRQ); /* clear the interrupt bit */ /* some irqs require the driver to clear the sources */ ddb_out32(DDB_INTCLR32, 1 << (irq - vrc5477_irq_base)); /* disable interrupt - some handler will re-enable the irq * and if the interrupt is leveled, we will have infinite loop */ ll_vrc5477_irq_disable(irq - vrc5477_irq_base); }
void ll_vrc5477_irq_disable(int vrc5477_irq) { u32 reg_value; u32 reg_bitmask; u32 reg_index; db_assert(vrc5477_irq >= 0); db_assert(vrc5477_irq < NUM_5477_IRQ); reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4; reg_value = ddb_in32(reg_index); reg_bitmask = 8 << (vrc5477_irq % 8 * 4); /* we assert that the interrupt is enabled (perhaps over-zealous) */ db_assert( (reg_value & reg_bitmask) != 0); ddb_out32(reg_index, reg_value & ~reg_bitmask); }
void ll_vrc5477_irq_route(int vrc5477_irq, int ip) { u32 reg_value; u32 reg_bitmask; u32 reg_index; db_assert(vrc5477_irq >= 0); db_assert(vrc5477_irq < NUM_5477_IRQ); db_assert(ip >= 0); db_assert((ip < 5) || (ip == 6)); reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4; reg_value = ddb_in32(reg_index); reg_bitmask = 7 << (vrc5477_irq % 8 * 4); reg_value &= ~reg_bitmask; reg_value |= ip << (vrc5477_irq % 8 * 4); ddb_out32(reg_index, reg_value); }
void __init plat_setup(void) { set_io_port_base(NILE4_PCI_IO_BASE); isa_slot_offset = NILE4_PCI_MEM_BASE; board_timer_setup = ddb_timer_init; board_time_init = ddb_time_init; _machine_restart = ddb_machine_restart; _machine_halt = ddb_machine_halt; pm_power_off = ddb_machine_power_off; ddb_out32(DDB_BAR0, 0); ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, 0x10); ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE , 0x10); /* Reboot on panic */ panic_timeout = 180; }