^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) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * These functions are used early on before PCI scanning is done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * and all of the pci_dev and pci_bus structures have been created.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) static struct pci_dev *fake_pci_dev(struct pci_channel *hose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) int top_bus, int busnr, int devfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) static struct pci_dev dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static struct pci_bus bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) dev.bus = &bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) dev.sysdata = hose;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) dev.devfn = devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) bus.number = busnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) bus.sysdata = hose;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) bus.ops = hose->pci_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) if(busnr != top_bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* Fake a parent bus structure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) bus.parent = &bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) bus.parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return &dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define EARLY_PCI_OP(rw, size, type) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int __init early_##rw##_config_##size(struct pci_channel *hose, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int top_bus, int bus, int devfn, int offset, type value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return pci_##rw##_config_##size( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) fake_pci_dev(hose, top_bus, bus, devfn), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) offset, value); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) EARLY_PCI_OP(read, byte, u8 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) EARLY_PCI_OP(read, word, u16 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) EARLY_PCI_OP(read, dword, u32 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) EARLY_PCI_OP(write, byte, u8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) EARLY_PCI_OP(write, word, u16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) EARLY_PCI_OP(write, dword, u32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int __init pci_is_66mhz_capable(struct pci_channel *hose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int top_bus, int current_bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u32 pci_devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned short vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int cap66 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u16 stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) pr_info("PCI: Checking 66MHz capabilities...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (PCI_FUNC(pci_devfn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (early_read_config_word(hose, top_bus, current_bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) pci_devfn, PCI_VENDOR_ID, &vid) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) PCIBIOS_SUCCESSFUL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (vid == 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* check 66MHz capability */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (cap66 < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) cap66 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (cap66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) early_read_config_word(hose, top_bus, current_bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) pci_devfn, PCI_STATUS, &stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (!(stat & PCI_STATUS_66MHZ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) "PCI: %02x:%02x not 66MHz capable.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) current_bus, pci_devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) cap66 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return cap66 > 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static void pcibios_enable_err(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct pci_channel *hose = from_timer(hose, t, err_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) del_timer(&hose->err_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) printk(KERN_DEBUG "PCI: re-enabling error IRQ.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) enable_irq(hose->err_irq);
^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) static void pcibios_enable_serr(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct pci_channel *hose = from_timer(hose, t, serr_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) del_timer(&hose->serr_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) printk(KERN_DEBUG "PCI: re-enabling system error IRQ.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) enable_irq(hose->serr_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) void pcibios_enable_timers(struct pci_channel *hose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (hose->err_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) timer_setup(&hose->err_timer, pcibios_enable_err, 0);
^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) if (hose->serr_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) timer_setup(&hose->serr_timer, pcibios_enable_serr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * A simple handler for the regular PCI status errors, called from IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned int pcibios_handle_status_errors(unsigned long addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) unsigned int status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct pci_channel *hose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned int cmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (status & PCI_STATUS_REC_MASTER_ABORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n", addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) cmd |= PCI_STATUS_REC_MASTER_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (status & PCI_STATUS_REC_TARGET_ABORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) printk(KERN_DEBUG "PCI: target abort: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) pcibios_report_status(PCI_STATUS_REC_TARGET_ABORT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) PCI_STATUS_SIG_TARGET_ABORT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) PCI_STATUS_REC_MASTER_ABORT, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) cmd |= PCI_STATUS_REC_TARGET_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (status & (PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) printk(KERN_DEBUG "PCI: parity error detected: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) pcibios_report_status(PCI_STATUS_PARITY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) PCI_STATUS_DETECTED_PARITY, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) cmd |= PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* Now back off of the IRQ for awhile */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (hose->err_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) disable_irq_nosync(hose->err_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) hose->err_timer.expires = jiffies + HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) add_timer(&hose->err_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }