11032bce3SWu Zhangjin /* 21032bce3SWu Zhangjin * Copyright (C) 2008 Lemote Technology 31032bce3SWu Zhangjin * Copyright (C) 2004 ICT CAS 41032bce3SWu Zhangjin * Author: Li xiaoyu, lixy@ict.ac.cn 51032bce3SWu Zhangjin * 61032bce3SWu Zhangjin * Copyright (C) 2007 Lemote, Inc. 71032bce3SWu Zhangjin * Author: Fuxin Zhang, zhangfx@lemote.com 81032bce3SWu Zhangjin * 91032bce3SWu Zhangjin * This program is free software; you can redistribute it and/or modify it 101032bce3SWu Zhangjin * under the terms of the GNU General Public License as published by the 111032bce3SWu Zhangjin * Free Software Foundation; either version 2 of the License, or (at your 121032bce3SWu Zhangjin * option) any later version. 131032bce3SWu Zhangjin */ 141032bce3SWu Zhangjin #include <linux/init.h> 151032bce3SWu Zhangjin #include <linux/pci.h> 161032bce3SWu Zhangjin 171032bce3SWu Zhangjin #include <loongson.h> 181032bce3SWu Zhangjin #include <cs5536/cs5536.h> 191032bce3SWu Zhangjin #include <cs5536/cs5536_pci.h> 201032bce3SWu Zhangjin 211032bce3SWu Zhangjin /* PCI interrupt pins 221032bce3SWu Zhangjin * 231032bce3SWu Zhangjin * These should not be changed, or you should consider loongson2f interrupt 241032bce3SWu Zhangjin * register and your pci card dispatch 251032bce3SWu Zhangjin */ 261032bce3SWu Zhangjin 271032bce3SWu Zhangjin #define PCIA 4 281032bce3SWu Zhangjin #define PCIB 5 291032bce3SWu Zhangjin #define PCIC 6 301032bce3SWu Zhangjin #define PCID 7 311032bce3SWu Zhangjin 321032bce3SWu Zhangjin /* all the pci device has the PCIA pin, check the datasheet. */ 331032bce3SWu Zhangjin static char irq_tab[][5] __initdata = { 341032bce3SWu Zhangjin /* INTA INTB INTC INTD */ 351032bce3SWu Zhangjin {0, 0, 0, 0, 0}, /* 11: Unused */ 361032bce3SWu Zhangjin {0, 0, 0, 0, 0}, /* 12: Unused */ 371032bce3SWu Zhangjin {0, 0, 0, 0, 0}, /* 13: Unused */ 381032bce3SWu Zhangjin {0, 0, 0, 0, 0}, /* 14: Unused */ 391032bce3SWu Zhangjin {0, 0, 0, 0, 0}, /* 15: Unused */ 401032bce3SWu Zhangjin {0, 0, 0, 0, 0}, /* 16: Unused */ 411032bce3SWu Zhangjin {0, PCIA, 0, 0, 0}, /* 17: RTL8110-0 */ 421032bce3SWu Zhangjin {0, PCIB, 0, 0, 0}, /* 18: RTL8110-1 */ 431032bce3SWu Zhangjin {0, PCIC, 0, 0, 0}, /* 19: SiI3114 */ 441032bce3SWu Zhangjin {0, PCID, 0, 0, 0}, /* 20: 3-ports nec usb */ 451032bce3SWu Zhangjin {0, PCIA, PCIB, PCIC, PCID}, /* 21: PCI-SLOT */ 461032bce3SWu Zhangjin {0, 0, 0, 0, 0}, /* 22: Unused */ 471032bce3SWu Zhangjin {0, 0, 0, 0, 0}, /* 23: Unused */ 481032bce3SWu Zhangjin {0, 0, 0, 0, 0}, /* 24: Unused */ 491032bce3SWu Zhangjin {0, 0, 0, 0, 0}, /* 25: Unused */ 501032bce3SWu Zhangjin {0, 0, 0, 0, 0}, /* 26: Unused */ 511032bce3SWu Zhangjin {0, 0, 0, 0, 0}, /* 27: Unused */ 521032bce3SWu Zhangjin }; 531032bce3SWu Zhangjin 541032bce3SWu Zhangjin int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 551032bce3SWu Zhangjin { 561032bce3SWu Zhangjin int virq; 571032bce3SWu Zhangjin 581032bce3SWu Zhangjin if ((PCI_SLOT(dev->devfn) != PCI_IDSEL_CS5536) 591032bce3SWu Zhangjin && (PCI_SLOT(dev->devfn) < 32)) { 601032bce3SWu Zhangjin virq = irq_tab[slot][pin]; 611032bce3SWu Zhangjin printk(KERN_INFO "slot: %d, pin: %d, irq: %d\n", slot, pin, 621032bce3SWu Zhangjin virq + LOONGSON_IRQ_BASE); 631032bce3SWu Zhangjin if (virq != 0) 641032bce3SWu Zhangjin return LOONGSON_IRQ_BASE + virq; 651032bce3SWu Zhangjin else 661032bce3SWu Zhangjin return 0; 671032bce3SWu Zhangjin } else if (PCI_SLOT(dev->devfn) == PCI_IDSEL_CS5536) { /* cs5536 */ 681032bce3SWu Zhangjin switch (PCI_FUNC(dev->devfn)) { 691032bce3SWu Zhangjin case 2: 701032bce3SWu Zhangjin pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 711032bce3SWu Zhangjin CS5536_IDE_INTR); 721032bce3SWu Zhangjin return CS5536_IDE_INTR; /* for IDE */ 731032bce3SWu Zhangjin case 3: 741032bce3SWu Zhangjin pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 751032bce3SWu Zhangjin CS5536_ACC_INTR); 761032bce3SWu Zhangjin return CS5536_ACC_INTR; /* for AUDIO */ 771032bce3SWu Zhangjin case 4: /* for OHCI */ 781032bce3SWu Zhangjin case 5: /* for EHCI */ 791032bce3SWu Zhangjin case 6: /* for UDC */ 801032bce3SWu Zhangjin case 7: /* for OTG */ 811032bce3SWu Zhangjin pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 821032bce3SWu Zhangjin CS5536_USB_INTR); 831032bce3SWu Zhangjin return CS5536_USB_INTR; 841032bce3SWu Zhangjin } 851032bce3SWu Zhangjin return dev->irq; 861032bce3SWu Zhangjin } else { 871032bce3SWu Zhangjin printk(KERN_INFO " strange pci slot number.\n"); 881032bce3SWu Zhangjin return 0; 891032bce3SWu Zhangjin } 901032bce3SWu Zhangjin } 911032bce3SWu Zhangjin 921032bce3SWu Zhangjin /* Do platform specific device initialization at pci_enable_device() time */ 931032bce3SWu Zhangjin int pcibios_plat_dev_init(struct pci_dev *dev) 941032bce3SWu Zhangjin { 951032bce3SWu Zhangjin return 0; 961032bce3SWu Zhangjin } 971032bce3SWu Zhangjin 981032bce3SWu Zhangjin /* CS5536 SPEC. fixup */ 99*28eb0e46SGreg Kroah-Hartman static void loongson_cs5536_isa_fixup(struct pci_dev *pdev) 1001032bce3SWu Zhangjin { 1011032bce3SWu Zhangjin /* the uart1 and uart2 interrupt in PIC is enabled as default */ 1021032bce3SWu Zhangjin pci_write_config_dword(pdev, PCI_UART1_INT_REG, 1); 1031032bce3SWu Zhangjin pci_write_config_dword(pdev, PCI_UART2_INT_REG, 1); 1041032bce3SWu Zhangjin } 1051032bce3SWu Zhangjin 106*28eb0e46SGreg Kroah-Hartman static void loongson_cs5536_ide_fixup(struct pci_dev *pdev) 1071032bce3SWu Zhangjin { 1081032bce3SWu Zhangjin /* setting the mutex pin as IDE function */ 1091032bce3SWu Zhangjin pci_write_config_dword(pdev, PCI_IDE_CFG_REG, 1101032bce3SWu Zhangjin CS5536_IDE_FLASH_SIGNATURE); 1111032bce3SWu Zhangjin } 1121032bce3SWu Zhangjin 113*28eb0e46SGreg Kroah-Hartman static void loongson_cs5536_acc_fixup(struct pci_dev *pdev) 1141032bce3SWu Zhangjin { 1151032bce3SWu Zhangjin /* enable the AUDIO interrupt in PIC */ 1161032bce3SWu Zhangjin pci_write_config_dword(pdev, PCI_ACC_INT_REG, 1); 1171032bce3SWu Zhangjin 1181032bce3SWu Zhangjin pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0); 1191032bce3SWu Zhangjin } 1201032bce3SWu Zhangjin 121*28eb0e46SGreg Kroah-Hartman static void loongson_cs5536_ohci_fixup(struct pci_dev *pdev) 1221032bce3SWu Zhangjin { 1231032bce3SWu Zhangjin /* enable the OHCI interrupt in PIC */ 1241032bce3SWu Zhangjin /* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */ 1251032bce3SWu Zhangjin pci_write_config_dword(pdev, PCI_OHCI_INT_REG, 1); 1261032bce3SWu Zhangjin } 1271032bce3SWu Zhangjin 128*28eb0e46SGreg Kroah-Hartman static void loongson_cs5536_ehci_fixup(struct pci_dev *pdev) 1291032bce3SWu Zhangjin { 1301032bce3SWu Zhangjin u32 hi, lo; 1311032bce3SWu Zhangjin 1321032bce3SWu Zhangjin /* Serial short detect enable */ 1331032bce3SWu Zhangjin _rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo); 134c70798f1SWu Zhangjin _wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 3), lo); 1351032bce3SWu Zhangjin 1361032bce3SWu Zhangjin /* setting the USB2.0 micro frame length */ 1371032bce3SWu Zhangjin pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000); 1381032bce3SWu Zhangjin } 1391032bce3SWu Zhangjin 140*28eb0e46SGreg Kroah-Hartman static void loongson_nec_fixup(struct pci_dev *pdev) 1411032bce3SWu Zhangjin { 1421032bce3SWu Zhangjin unsigned int val; 1431032bce3SWu Zhangjin 1441032bce3SWu Zhangjin pci_read_config_dword(pdev, 0xe0, &val); 1451032bce3SWu Zhangjin /* Only 2 port be used */ 1461032bce3SWu Zhangjin pci_write_config_dword(pdev, 0xe0, (val & ~3) | 0x2); 1471032bce3SWu Zhangjin } 1481032bce3SWu Zhangjin 1491032bce3SWu Zhangjin DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, 1501032bce3SWu Zhangjin loongson_cs5536_isa_fixup); 1511032bce3SWu Zhangjin DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_OHC, 1521032bce3SWu Zhangjin loongson_cs5536_ohci_fixup); 1531032bce3SWu Zhangjin DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_EHC, 1541032bce3SWu Zhangjin loongson_cs5536_ehci_fixup); 1551032bce3SWu Zhangjin DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO, 1561032bce3SWu Zhangjin loongson_cs5536_acc_fixup); 1571032bce3SWu Zhangjin DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, 1581032bce3SWu Zhangjin loongson_cs5536_ide_fixup); 1591032bce3SWu Zhangjin DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, 1601032bce3SWu Zhangjin loongson_nec_fixup); 161