fixup-lemote2f.c 4.7 KB

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