pci-common.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2005-2007 Cavium Networks
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/init.h>
  10. #include <linux/pci.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/time.h>
  13. #include <linux/delay.h>
  14. #include "pci-common.h"
  15. typeof(pcibios_map_irq) *octeon_pcibios_map_irq;
  16. enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID;
  17. /**
  18. * Map a PCI device to the appropriate interrupt line
  19. *
  20. * @param dev The Linux PCI device structure for the device to map
  21. * @param slot The slot number for this device on __BUS 0__. Linux
  22. * enumerates through all the bridges and figures out the
  23. * slot on Bus 0 where this device eventually hooks to.
  24. * @param pin The PCI interrupt pin read from the device, then swizzled
  25. * as it goes through each bridge.
  26. * @return Interrupt number for the device
  27. */
  28. int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
  29. {
  30. if (octeon_pcibios_map_irq)
  31. return octeon_pcibios_map_irq(dev, slot, pin);
  32. else
  33. panic("octeon_pcibios_map_irq doesn't point to a "
  34. "pcibios_map_irq() function");
  35. }
  36. /**
  37. * Called to perform platform specific PCI setup
  38. *
  39. * @param dev
  40. * @return
  41. */
  42. int pcibios_plat_dev_init(struct pci_dev *dev)
  43. {
  44. uint16_t config;
  45. uint32_t dconfig;
  46. int pos;
  47. /*
  48. * Force the Cache line setting to 64 bytes. The standard
  49. * Linux bus scan doesn't seem to set it. Octeon really has
  50. * 128 byte lines, but Intel bridges get really upset if you
  51. * try and set values above 64 bytes. Value is specified in
  52. * 32bit words.
  53. */
  54. pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 64 / 4);
  55. /* Set latency timers for all devices */
  56. pci_write_config_byte(dev, PCI_LATENCY_TIMER, 48);
  57. /* Enable reporting System errors and parity errors on all devices */
  58. /* Enable parity checking and error reporting */
  59. pci_read_config_word(dev, PCI_COMMAND, &config);
  60. config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
  61. pci_write_config_word(dev, PCI_COMMAND, config);
  62. if (dev->subordinate) {
  63. /* Set latency timers on sub bridges */
  64. pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 48);
  65. /* More bridge error detection */
  66. pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config);
  67. config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
  68. pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config);
  69. }
  70. /* Enable the PCIe normal error reporting */
  71. pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
  72. if (pos) {
  73. /* Update Device Control */
  74. pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config);
  75. /* Correctable Error Reporting */
  76. config |= PCI_EXP_DEVCTL_CERE;
  77. /* Non-Fatal Error Reporting */
  78. config |= PCI_EXP_DEVCTL_NFERE;
  79. /* Fatal Error Reporting */
  80. config |= PCI_EXP_DEVCTL_FERE;
  81. /* Unsupported Request */
  82. config |= PCI_EXP_DEVCTL_URRE;
  83. pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
  84. }
  85. /* Find the Advanced Error Reporting capability */
  86. pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
  87. if (pos) {
  88. /* Clear Uncorrectable Error Status */
  89. pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
  90. &dconfig);
  91. pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
  92. dconfig);
  93. /* Enable reporting of all uncorrectable errors */
  94. /* Uncorrectable Error Mask - turned on bits disable errors */
  95. pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0);
  96. /*
  97. * Leave severity at HW default. This only controls if
  98. * errors are reported as uncorrectable or
  99. * correctable, not if the error is reported.
  100. */
  101. /* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */
  102. /* Clear Correctable Error Status */
  103. pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig);
  104. pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig);
  105. /* Enable reporting of all correctable errors */
  106. /* Correctable Error Mask - turned on bits disable errors */
  107. pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0);
  108. /* Advanced Error Capabilities */
  109. pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig);
  110. /* ECRC Generation Enable */
  111. if (config & PCI_ERR_CAP_ECRC_GENC)
  112. config |= PCI_ERR_CAP_ECRC_GENE;
  113. /* ECRC Check Enable */
  114. if (config & PCI_ERR_CAP_ECRC_CHKC)
  115. config |= PCI_ERR_CAP_ECRC_CHKE;
  116. pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig);
  117. /* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */
  118. /* Report all errors to the root complex */
  119. pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND,
  120. PCI_ERR_ROOT_CMD_COR_EN |
  121. PCI_ERR_ROOT_CMD_NONFATAL_EN |
  122. PCI_ERR_ROOT_CMD_FATAL_EN);
  123. /* Clear the Root status register */
  124. pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig);
  125. pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig);
  126. }
  127. return 0;
  128. }