^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2008 Lemote Technology
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2004 ICT CAS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author: Li xiaoyu, lixy@ict.ac.cn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2007 Lemote, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Author: Fuxin Zhang, zhangfx@lemote.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <loongson.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <cs5536/cs5536.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <cs5536/cs5536_pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* PCI interrupt pins
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * These should not be changed, or you should consider loongson2f interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * register and your pci card dispatch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define PCIA 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define PCIB 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define PCIC 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define PCID 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* all the pci device has the PCIA pin, check the datasheet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static char irq_tab[][5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* INTA INTB INTC INTD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {0, 0, 0, 0, 0}, /* 11: Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {0, 0, 0, 0, 0}, /* 12: Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {0, 0, 0, 0, 0}, /* 13: Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {0, 0, 0, 0, 0}, /* 14: Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {0, 0, 0, 0, 0}, /* 15: Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {0, 0, 0, 0, 0}, /* 16: Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {0, PCIA, 0, 0, 0}, /* 17: RTL8110-0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {0, PCIB, 0, 0, 0}, /* 18: RTL8110-1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {0, PCIC, 0, 0, 0}, /* 19: SiI3114 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {0, PCID, 0, 0, 0}, /* 20: 3-ports nec usb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {0, PCIA, PCIB, PCIC, PCID}, /* 21: PCI-SLOT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {0, 0, 0, 0, 0}, /* 22: Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {0, 0, 0, 0, 0}, /* 23: Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {0, 0, 0, 0, 0}, /* 24: Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {0, 0, 0, 0, 0}, /* 25: Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {0, 0, 0, 0, 0}, /* 26: Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {0, 0, 0, 0, 0}, /* 27: Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int virq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if ((PCI_SLOT(dev->devfn) != PCI_IDSEL_CS5536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) && (PCI_SLOT(dev->devfn) < 32)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) virq = irq_tab[slot][pin];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) printk(KERN_INFO "slot: %d, pin: %d, irq: %d\n", slot, pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) virq + LOONGSON_IRQ_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (virq != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return LOONGSON_IRQ_BASE + virq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) } else if (PCI_SLOT(dev->devfn) == PCI_IDSEL_CS5536) { /* cs5536 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) switch (PCI_FUNC(dev->devfn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) CS5536_IDE_INTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return CS5536_IDE_INTR; /* for IDE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) CS5536_ACC_INTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return CS5536_ACC_INTR; /* for AUDIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) case 4: /* for OHCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) case 5: /* for EHCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) case 6: /* for UDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) case 7: /* for OTG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) CS5536_USB_INTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return CS5536_USB_INTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return dev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) printk(KERN_INFO " strange pci slot number.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^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) /* Do platform specific device initialization at pci_enable_device() time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int pcibios_plat_dev_init(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* CS5536 SPEC. fixup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static void loongson_cs5536_isa_fixup(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* the uart1 and uart2 interrupt in PIC is enabled as default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) pci_write_config_dword(pdev, PCI_UART1_INT_REG, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) pci_write_config_dword(pdev, PCI_UART2_INT_REG, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void loongson_cs5536_ide_fixup(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* setting the mutex pin as IDE function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) pci_write_config_dword(pdev, PCI_IDE_CFG_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) CS5536_IDE_FLASH_SIGNATURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static void loongson_cs5536_acc_fixup(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* enable the AUDIO interrupt in PIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) pci_write_config_dword(pdev, PCI_ACC_INT_REG, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0);
^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) static void loongson_cs5536_ohci_fixup(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* enable the OHCI interrupt in PIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) pci_write_config_dword(pdev, PCI_OHCI_INT_REG, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static void loongson_cs5536_ehci_fixup(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u32 hi, lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* Serial short detect enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) _rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) _wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 3), lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* setting the USB2.0 micro frame length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static void loongson_nec_fixup(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) pci_read_config_dword(pdev, 0xe0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* Only 2 port be used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) pci_write_config_dword(pdev, 0xe0, (val & ~3) | 0x2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) loongson_cs5536_isa_fixup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_OHC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) loongson_cs5536_ohci_fixup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_EHC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) loongson_cs5536_ehci_fixup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) loongson_cs5536_acc_fixup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) loongson_cs5536_ide_fixup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) loongson_nec_fixup);