pcie-rcar.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * PCIe driver for Renesas R-Car SoCs
  4. * Copyright (C) 2014-2020 Renesas Electronics Europe Ltd
  5. *
  6. * Author: Phil Edworthy <phil.edworthy@renesas.com>
  7. */
  8. #include <linux/delay.h>
  9. #include <linux/pci.h>
  10. #include "pcie-rcar.h"
  11. void rcar_pci_write_reg(struct rcar_pcie *pcie, u32 val, unsigned int reg)
  12. {
  13. writel(val, pcie->base + reg);
  14. }
  15. u32 rcar_pci_read_reg(struct rcar_pcie *pcie, unsigned int reg)
  16. {
  17. return readl(pcie->base + reg);
  18. }
  19. void rcar_rmw32(struct rcar_pcie *pcie, int where, u32 mask, u32 data)
  20. {
  21. unsigned int shift = BITS_PER_BYTE * (where & 3);
  22. u32 val = rcar_pci_read_reg(pcie, where & ~3);
  23. val &= ~(mask << shift);
  24. val |= data << shift;
  25. rcar_pci_write_reg(pcie, val, where & ~3);
  26. }
  27. int rcar_pcie_wait_for_phyrdy(struct rcar_pcie *pcie)
  28. {
  29. unsigned int timeout = 10;
  30. while (timeout--) {
  31. if (rcar_pci_read_reg(pcie, PCIEPHYSR) & PHYRDY)
  32. return 0;
  33. msleep(5);
  34. }
  35. return -ETIMEDOUT;
  36. }
  37. int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie)
  38. {
  39. unsigned int timeout = 10000;
  40. while (timeout--) {
  41. if ((rcar_pci_read_reg(pcie, PCIETSTR) & DATA_LINK_ACTIVE))
  42. return 0;
  43. udelay(5);
  44. cpu_relax();
  45. }
  46. return -ETIMEDOUT;
  47. }
  48. void rcar_pcie_set_outbound(struct rcar_pcie *pcie, int win,
  49. struct resource_entry *window)
  50. {
  51. /* Setup PCIe address space mappings for each resource */
  52. struct resource *res = window->res;
  53. resource_size_t res_start;
  54. resource_size_t size;
  55. u32 mask;
  56. rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
  57. /*
  58. * The PAMR mask is calculated in units of 128Bytes, which
  59. * keeps things pretty simple.
  60. */
  61. size = resource_size(res);
  62. if (size > 128)
  63. mask = (roundup_pow_of_two(size) / SZ_128) - 1;
  64. else
  65. mask = 0x0;
  66. rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
  67. if (res->flags & IORESOURCE_IO)
  68. res_start = pci_pio_to_address(res->start) - window->offset;
  69. else
  70. res_start = res->start - window->offset;
  71. rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPAUR(win));
  72. rcar_pci_write_reg(pcie, lower_32_bits(res_start) & ~0x7F,
  73. PCIEPALR(win));
  74. /* First resource is for IO */
  75. mask = PAR_ENABLE;
  76. if (res->flags & IORESOURCE_IO)
  77. mask |= IO_SPACE;
  78. rcar_pci_write_reg(pcie, mask, PCIEPTCTLR(win));
  79. }
  80. void rcar_pcie_set_inbound(struct rcar_pcie *pcie, u64 cpu_addr,
  81. u64 pci_addr, u64 flags, int idx, bool host)
  82. {
  83. /*
  84. * Set up 64-bit inbound regions as the range parser doesn't
  85. * distinguish between 32 and 64-bit types.
  86. */
  87. if (host)
  88. rcar_pci_write_reg(pcie, lower_32_bits(pci_addr),
  89. PCIEPRAR(idx));
  90. rcar_pci_write_reg(pcie, lower_32_bits(cpu_addr), PCIELAR(idx));
  91. rcar_pci_write_reg(pcie, flags, PCIELAMR(idx));
  92. if (host)
  93. rcar_pci_write_reg(pcie, upper_32_bits(pci_addr),
  94. PCIEPRAR(idx + 1));
  95. rcar_pci_write_reg(pcie, upper_32_bits(cpu_addr), PCIELAR(idx + 1));
  96. rcar_pci_write_reg(pcie, 0, PCIELAMR(idx + 1));
  97. }