0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/init.h>
0011 #include <linux/pci.h>
0012
0013 #include <loongson.h>
0014 #include <cs5536/cs5536.h>
0015 #include <cs5536/cs5536_pci.h>
0016
0017
0018
0019
0020
0021
0022
0023 #define PCIA 4
0024 #define PCIB 5
0025 #define PCIC 6
0026 #define PCID 7
0027
0028
0029 static char irq_tab[][5] = {
0030
0031 {0, 0, 0, 0, 0},
0032 {0, 0, 0, 0, 0},
0033 {0, 0, 0, 0, 0},
0034 {0, 0, 0, 0, 0},
0035 {0, 0, 0, 0, 0},
0036 {0, 0, 0, 0, 0},
0037 {0, PCIA, 0, 0, 0},
0038 {0, PCIB, 0, 0, 0},
0039 {0, PCIC, 0, 0, 0},
0040 {0, PCID, 0, 0, 0},
0041 {0, PCIA, PCIB, PCIC, PCID},
0042 {0, 0, 0, 0, 0},
0043 {0, 0, 0, 0, 0},
0044 {0, 0, 0, 0, 0},
0045 {0, 0, 0, 0, 0},
0046 {0, 0, 0, 0, 0},
0047 {0, 0, 0, 0, 0},
0048 };
0049
0050 int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
0051 {
0052 int virq;
0053
0054 if ((PCI_SLOT(dev->devfn) != PCI_IDSEL_CS5536)
0055 && (PCI_SLOT(dev->devfn) < 32)) {
0056 virq = irq_tab[slot][pin];
0057 printk(KERN_INFO "slot: %d, pin: %d, irq: %d\n", slot, pin,
0058 virq + LOONGSON_IRQ_BASE);
0059 if (virq != 0)
0060 return LOONGSON_IRQ_BASE + virq;
0061 else
0062 return 0;
0063 } else if (PCI_SLOT(dev->devfn) == PCI_IDSEL_CS5536) {
0064 switch (PCI_FUNC(dev->devfn)) {
0065 case 2:
0066 pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
0067 CS5536_IDE_INTR);
0068 return CS5536_IDE_INTR;
0069 case 3:
0070 pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
0071 CS5536_ACC_INTR);
0072 return CS5536_ACC_INTR;
0073 case 4:
0074 case 5:
0075 case 6:
0076 case 7:
0077 pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
0078 CS5536_USB_INTR);
0079 return CS5536_USB_INTR;
0080 }
0081 return dev->irq;
0082 } else {
0083 printk(KERN_INFO "strange PCI slot number.\n");
0084 return 0;
0085 }
0086 }
0087
0088
0089 int pcibios_plat_dev_init(struct pci_dev *dev)
0090 {
0091 return 0;
0092 }
0093
0094
0095 static void loongson_cs5536_isa_fixup(struct pci_dev *pdev)
0096 {
0097
0098 pci_write_config_dword(pdev, PCI_UART1_INT_REG, 1);
0099 pci_write_config_dword(pdev, PCI_UART2_INT_REG, 1);
0100 }
0101
0102 static void loongson_cs5536_ide_fixup(struct pci_dev *pdev)
0103 {
0104
0105 pci_write_config_dword(pdev, PCI_IDE_CFG_REG,
0106 CS5536_IDE_FLASH_SIGNATURE);
0107 }
0108
0109 static void loongson_cs5536_acc_fixup(struct pci_dev *pdev)
0110 {
0111
0112 pci_write_config_dword(pdev, PCI_ACC_INT_REG, 1);
0113
0114 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0);
0115 }
0116
0117 static void loongson_cs5536_ohci_fixup(struct pci_dev *pdev)
0118 {
0119
0120
0121 pci_write_config_dword(pdev, PCI_OHCI_INT_REG, 1);
0122 }
0123
0124 static void loongson_cs5536_ehci_fixup(struct pci_dev *pdev)
0125 {
0126 u32 hi, lo;
0127
0128
0129 _rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo);
0130 _wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 3), lo);
0131
0132
0133 pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000);
0134 }
0135
0136 static void loongson_nec_fixup(struct pci_dev *pdev)
0137 {
0138 unsigned int val;
0139
0140 pci_read_config_dword(pdev, 0xe0, &val);
0141
0142 pci_write_config_dword(pdev, 0xe0, (val & ~3) | 0x2);
0143 }
0144
0145 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
0146 loongson_cs5536_isa_fixup);
0147 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_OHC,
0148 loongson_cs5536_ohci_fixup);
0149 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_EHC,
0150 loongson_cs5536_ehci_fixup);
0151 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO,
0152 loongson_cs5536_acc_fixup);
0153 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE,
0154 loongson_cs5536_ide_fixup);
0155 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
0156 loongson_nec_fixup);