pci_gt64120.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * Copyright (C) 2013 Gabor Juhos <juhosg@openwrt.org>
  3. *
  4. * Based on the Linux implementation.
  5. * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc.
  6. * Authors: Carsten Langgaard <carstenl@mips.com>
  7. * Maciej W. Rozycki <macro@mips.com>
  8. *
  9. * SPDX-License-Identifier: GPL-2.0
  10. */
  11. #include <common.h>
  12. #include <gt64120.h>
  13. #include <pci.h>
  14. #include <pci_gt64120.h>
  15. #include <asm/io.h>
  16. #define PCI_ACCESS_READ 0
  17. #define PCI_ACCESS_WRITE 1
  18. struct gt64120_regs {
  19. u8 unused_000[0xc18];
  20. u32 intrcause;
  21. u8 unused_c1c[0x0dc];
  22. u32 pci0_cfgaddr;
  23. u32 pci0_cfgdata;
  24. };
  25. struct gt64120_pci_controller {
  26. struct pci_controller hose;
  27. struct gt64120_regs *regs;
  28. };
  29. static inline struct gt64120_pci_controller *
  30. hose_to_gt64120(struct pci_controller *hose)
  31. {
  32. return container_of(hose, struct gt64120_pci_controller, hose);
  33. }
  34. #define GT_INTRCAUSE_ABORT_BITS \
  35. (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)
  36. static int gt_config_access(struct gt64120_pci_controller *gt,
  37. unsigned char access_type, pci_dev_t bdf,
  38. int where, u32 *data)
  39. {
  40. unsigned int bus = PCI_BUS(bdf);
  41. unsigned int dev = PCI_DEV(bdf);
  42. unsigned int devfn = PCI_DEV(bdf) << 3 | PCI_FUNC(bdf);
  43. u32 intr;
  44. u32 addr;
  45. u32 val;
  46. if (bus == 0 && dev >= 31) {
  47. /* Because of a bug in the galileo (for slot 31). */
  48. return -1;
  49. }
  50. if (access_type == PCI_ACCESS_WRITE)
  51. debug("PCI WR %02x:%02x.%x reg:%02d data:%08x\n",
  52. PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), where, *data);
  53. /* Clear cause register bits */
  54. writel(~GT_INTRCAUSE_ABORT_BITS, &gt->regs->intrcause);
  55. addr = GT_PCI0_CFGADDR_CONFIGEN_BIT;
  56. addr |= bus << GT_PCI0_CFGADDR_BUSNUM_SHF;
  57. addr |= devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF;
  58. addr |= (where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF;
  59. /* Setup address */
  60. writel(addr, &gt->regs->pci0_cfgaddr);
  61. if (access_type == PCI_ACCESS_WRITE) {
  62. if (bus == 0 && dev == 0) {
  63. /*
  64. * The Galileo system controller is acting
  65. * differently than other devices.
  66. */
  67. val = *data;
  68. } else {
  69. val = cpu_to_le32(*data);
  70. }
  71. writel(val, &gt->regs->pci0_cfgdata);
  72. } else {
  73. val = readl(&gt->regs->pci0_cfgdata);
  74. if (bus == 0 && dev == 0) {
  75. /*
  76. * The Galileo system controller is acting
  77. * differently than other devices.
  78. */
  79. *data = val;
  80. } else {
  81. *data = le32_to_cpu(val);
  82. }
  83. }
  84. /* Check for master or target abort */
  85. intr = readl(&gt->regs->intrcause);
  86. if (intr & GT_INTRCAUSE_ABORT_BITS) {
  87. /* Error occurred, clear abort bits */
  88. writel(~GT_INTRCAUSE_ABORT_BITS, &gt->regs->intrcause);
  89. return -1;
  90. }
  91. if (access_type == PCI_ACCESS_READ)
  92. debug("PCI RD %02x:%02x.%x reg:%02d data:%08x\n",
  93. PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), where, *data);
  94. return 0;
  95. }
  96. static int gt_read_config_dword(struct pci_controller *hose, pci_dev_t dev,
  97. int where, u32 *value)
  98. {
  99. struct gt64120_pci_controller *gt = hose_to_gt64120(hose);
  100. *value = 0xffffffff;
  101. return gt_config_access(gt, PCI_ACCESS_READ, dev, where, value);
  102. }
  103. static int gt_write_config_dword(struct pci_controller *hose, pci_dev_t dev,
  104. int where, u32 value)
  105. {
  106. struct gt64120_pci_controller *gt = hose_to_gt64120(hose);
  107. u32 data = value;
  108. return gt_config_access(gt, PCI_ACCESS_WRITE, dev, where, &data);
  109. }
  110. void gt64120_pci_init(void *regs, unsigned long sys_bus, unsigned long sys_phys,
  111. unsigned long sys_size, unsigned long mem_bus,
  112. unsigned long mem_phys, unsigned long mem_size,
  113. unsigned long io_bus, unsigned long io_phys,
  114. unsigned long io_size)
  115. {
  116. static struct gt64120_pci_controller global_gt;
  117. struct gt64120_pci_controller *gt;
  118. struct pci_controller *hose;
  119. gt = &global_gt;
  120. gt->regs = regs;
  121. hose = &gt->hose;
  122. hose->first_busno = 0;
  123. hose->last_busno = 0;
  124. /* System memory space */
  125. pci_set_region(&hose->regions[0], sys_bus, sys_phys, sys_size,
  126. PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
  127. /* PCI memory space */
  128. pci_set_region(&hose->regions[1], mem_bus, mem_phys, mem_size,
  129. PCI_REGION_MEM);
  130. /* PCI I/O space */
  131. pci_set_region(&hose->regions[2], io_bus, io_phys, io_size,
  132. PCI_REGION_IO);
  133. hose->region_count = 3;
  134. pci_set_ops(hose,
  135. pci_hose_read_config_byte_via_dword,
  136. pci_hose_read_config_word_via_dword,
  137. gt_read_config_dword,
  138. pci_hose_write_config_byte_via_dword,
  139. pci_hose_write_config_word_via_dword,
  140. gt_write_config_dword);
  141. pci_register_hose(hose);
  142. hose->last_busno = pci_hose_scan(hose);
  143. }