pci_gt64120.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2013 Gabor Juhos <juhosg@openwrt.org>
  4. *
  5. * Based on the Linux implementation.
  6. * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc.
  7. * Authors: Carsten Langgaard <carstenl@mips.com>
  8. * Maciej W. Rozycki <macro@mips.com>
  9. */
  10. #include <dm.h>
  11. #include <gt64120.h>
  12. #include <init.h>
  13. #include <log.h>
  14. #include <pci.h>
  15. #include <pci_gt64120.h>
  16. #include <asm/io.h>
  17. #define PCI_ACCESS_READ 0
  18. #define PCI_ACCESS_WRITE 1
  19. struct gt64120_regs {
  20. u8 unused_000[0xc18];
  21. u32 intrcause;
  22. u8 unused_c1c[0x0dc];
  23. u32 pci0_cfgaddr;
  24. u32 pci0_cfgdata;
  25. };
  26. struct gt64120_pci_controller {
  27. struct pci_controller hose;
  28. struct gt64120_regs *regs;
  29. };
  30. static inline struct gt64120_pci_controller *
  31. hose_to_gt64120(struct pci_controller *hose)
  32. {
  33. return container_of(hose, struct gt64120_pci_controller, hose);
  34. }
  35. #define GT_INTRCAUSE_ABORT_BITS \
  36. (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)
  37. static int gt_config_access(struct gt64120_pci_controller *gt,
  38. unsigned char access_type, pci_dev_t bdf,
  39. int where, u32 *data)
  40. {
  41. unsigned int bus = PCI_BUS(bdf);
  42. unsigned int dev = PCI_DEV(bdf);
  43. unsigned int devfn = PCI_DEV(bdf) << 3 | PCI_FUNC(bdf);
  44. u32 intr;
  45. u32 addr;
  46. u32 val;
  47. if (bus == 0 && dev >= 31) {
  48. /* Because of a bug in the galileo (for slot 31). */
  49. return -1;
  50. }
  51. if (access_type == PCI_ACCESS_WRITE)
  52. debug("PCI WR %02x:%02x.%x reg:%02d data:%08x\n",
  53. PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), where, *data);
  54. /* Clear cause register bits */
  55. writel(~GT_INTRCAUSE_ABORT_BITS, &gt->regs->intrcause);
  56. addr = GT_PCI0_CFGADDR_CONFIGEN_BIT;
  57. addr |= bus << GT_PCI0_CFGADDR_BUSNUM_SHF;
  58. addr |= devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF;
  59. addr |= (where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF;
  60. /* Setup address */
  61. writel(addr, &gt->regs->pci0_cfgaddr);
  62. if (access_type == PCI_ACCESS_WRITE) {
  63. if (bus == 0 && dev == 0) {
  64. /*
  65. * The Galileo system controller is acting
  66. * differently than other devices.
  67. */
  68. val = *data;
  69. } else {
  70. val = cpu_to_le32(*data);
  71. }
  72. writel(val, &gt->regs->pci0_cfgdata);
  73. } else {
  74. val = readl(&gt->regs->pci0_cfgdata);
  75. if (bus == 0 && dev == 0) {
  76. /*
  77. * The Galileo system controller is acting
  78. * differently than other devices.
  79. */
  80. *data = val;
  81. } else {
  82. *data = le32_to_cpu(val);
  83. }
  84. }
  85. /* Check for master or target abort */
  86. intr = readl(&gt->regs->intrcause);
  87. if (intr & GT_INTRCAUSE_ABORT_BITS) {
  88. /* Error occurred, clear abort bits */
  89. writel(~GT_INTRCAUSE_ABORT_BITS, &gt->regs->intrcause);
  90. return -1;
  91. }
  92. if (access_type == PCI_ACCESS_READ)
  93. debug("PCI RD %02x:%02x.%x reg:%02d data:%08x\n",
  94. PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), where, *data);
  95. return 0;
  96. }
  97. static int gt64120_pci_read_config(const struct udevice *dev, pci_dev_t bdf,
  98. uint where, ulong *val,
  99. enum pci_size_t size)
  100. {
  101. struct gt64120_pci_controller *gt = dev_get_priv(dev);
  102. u32 data = 0;
  103. if (gt_config_access(gt, PCI_ACCESS_READ, bdf, where, &data)) {
  104. *val = pci_get_ff(size);
  105. return 0;
  106. }
  107. *val = pci_conv_32_to_size(data, where, size);
  108. return 0;
  109. }
  110. static int gt64120_pci_write_config(struct udevice *dev, pci_dev_t bdf,
  111. uint where, ulong val,
  112. enum pci_size_t size)
  113. {
  114. struct gt64120_pci_controller *gt = dev_get_priv(dev);
  115. u32 data = 0;
  116. if (size == PCI_SIZE_32) {
  117. data = val;
  118. } else {
  119. u32 old;
  120. if (gt_config_access(gt, PCI_ACCESS_READ, bdf, where, &old))
  121. return 0;
  122. data = pci_conv_size_to_32(old, val, where, size);
  123. }
  124. gt_config_access(gt, PCI_ACCESS_WRITE, bdf, where, &data);
  125. return 0;
  126. }
  127. static int gt64120_pci_probe(struct udevice *dev)
  128. {
  129. struct gt64120_pci_controller *gt = dev_get_priv(dev);
  130. gt->regs = dev_remap_addr(dev);
  131. if (!gt->regs)
  132. return -EINVAL;
  133. return 0;
  134. }
  135. static const struct dm_pci_ops gt64120_pci_ops = {
  136. .read_config = gt64120_pci_read_config,
  137. .write_config = gt64120_pci_write_config,
  138. };
  139. static const struct udevice_id gt64120_pci_ids[] = {
  140. { .compatible = "marvell,pci-gt64120" },
  141. { }
  142. };
  143. U_BOOT_DRIVER(gt64120_pci) = {
  144. .name = "gt64120_pci",
  145. .id = UCLASS_PCI,
  146. .of_match = gt64120_pci_ids,
  147. .ops = &gt64120_pci_ops,
  148. .probe = gt64120_pci_probe,
  149. .priv_auto = sizeof(struct gt64120_pci_controller),
  150. };