^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/arch/alpha/kernel/sys_eiger.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1995 David A Rusling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 1996, 1999 Jay A Estabrook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 1998, 1999 Richard Henderson
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 1999 Iain Grant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Code supporting the EIGER (EV6+TSUNAMI).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/core_tsunami.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/hwrpb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/tlbflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "proto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "irq_impl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "pci_impl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "machvec_impl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* Note that this interrupt code is identical to TAKARA. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* Note mask bit is true for DISABLED irqs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static unsigned long cached_irq_mask[2] = { -1, -1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) eiger_update_irq_hw(unsigned long irq, unsigned long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int regaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) mask = (irq >= 64 ? mask << 16 : mask >> ((irq - 16) & 0x30));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) regaddr = 0x510 + (((irq - 16) >> 2) & 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) outl(mask & 0xffff0000UL, regaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) eiger_enable_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned int irq = d->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned long mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) mask = (cached_irq_mask[irq >= 64] &= ~(1UL << (irq & 63)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) eiger_update_irq_hw(irq, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) eiger_disable_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned int irq = d->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) unsigned long mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) mask = (cached_irq_mask[irq >= 64] |= 1UL << (irq & 63));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) eiger_update_irq_hw(irq, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static struct irq_chip eiger_irq_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .name = "EIGER",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .irq_unmask = eiger_enable_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .irq_mask = eiger_disable_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .irq_mask_ack = eiger_disable_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) eiger_device_interrupt(unsigned long vector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) unsigned intstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * The PALcode will have passed us vectors 0x800 or 0x810,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * which are fairly arbitrary values and serve only to tell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * us whether an interrupt has come in on IRQ0 or IRQ1. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * it's IRQ1 it's a PCI interrupt; if it's IRQ0, it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * probably ISA, but PCI interrupts can come through IRQ0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * as well if the interrupt controller isn't in accelerated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * OTOH, the accelerator thing doesn't seem to be working
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * overly well, so what we'll do instead is try directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * examining the Master Interrupt Register to see if it's a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * PCI interrupt, and if _not_ then we'll pass it on to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * ISA handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) intstatus = inw(0x500) & 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (intstatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * This is a PCI interrupt. Check each bit and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * despatch an interrupt if it's set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (intstatus & 8) handle_irq(16+3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (intstatus & 4) handle_irq(16+2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (intstatus & 2) handle_irq(16+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (intstatus & 1) handle_irq(16+0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) isa_device_interrupt(vector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) eiger_srm_device_interrupt(unsigned long vector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int irq = (vector - 0x800) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) handle_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) eiger_init_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) outb(0, DMA1_RESET_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) outb(0, DMA2_RESET_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) outb(0, DMA2_MASK_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (alpha_using_srm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) alpha_mv.device_interrupt = eiger_srm_device_interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) for (i = 16; i < 128; i += 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) eiger_update_irq_hw(i, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) init_i8259a_irqs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) for (i = 16; i < 128; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) irq_set_chip_and_handler(i, &eiger_irq_type, handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) irq_set_status_flags(i, IRQ_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) eiger_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) u8 irq_orig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* The SRM console has already calculated out the IRQ value's for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) option cards. As this works lets just read in the value already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) set and change it to a useable value by Linux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) All the IRQ values generated by the console are greater than 90,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) so we subtract 80 because it is (90 - allocated ISA IRQ's). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return irq_orig - 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static u8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) eiger_swizzle(struct pci_dev *dev, u8 *pinp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct pci_controller *hose = dev->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int slot, pin = *pinp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int bridge_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* Find the number of backplane bridges. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int backplane = inw(0x502) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) switch (backplane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) case 0x00: bridge_count = 0; break; /* No bridges */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) case 0x01: bridge_count = 1; break; /* 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) case 0x03: bridge_count = 2; break; /* 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case 0x07: bridge_count = 3; break; /* 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case 0x0f: bridge_count = 4; break; /* 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) slot = PCI_SLOT(dev->devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) while (dev->bus->self) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* Check for built-in bridges on hose 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (hose->index == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) && (PCI_SLOT(dev->bus->self->devfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) > 20 - bridge_count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) slot = PCI_SLOT(dev->devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* Must be a card-based bridge. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) pin = pci_swizzle_interrupt_pin(dev, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* Move up the chain of bridges. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dev = dev->bus->self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) *pinp = pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * The System Vectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct alpha_machine_vector eiger_mv __initmv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .vector_name = "Eiger",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) DO_EV6_MMU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) DO_DEFAULT_RTC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) DO_TSUNAMI_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .machine_check = tsunami_machine_check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .min_io_address = DEFAULT_IO_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .min_mem_address = DEFAULT_MEM_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .pci_dac_offset = TSUNAMI_DAC_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .nr_irqs = 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .device_interrupt = eiger_device_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .init_arch = tsunami_init_arch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .init_irq = eiger_init_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .init_rtc = common_init_rtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .init_pci = common_init_pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .kill_arch = tsunami_kill_arch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .pci_map_irq = eiger_map_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .pci_swizzle = eiger_swizzle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ALIAS_MV(eiger)