p2sb-uclass.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Uclass for Primary-to-sideband bus, used to access various peripherals
  4. *
  5. * Copyright 2019 Google LLC
  6. * Written by Simon Glass <sjg@chromium.org>
  7. */
  8. #include <common.h>
  9. #include <dm.h>
  10. #include <mapmem.h>
  11. #include <p2sb.h>
  12. #include <spl.h>
  13. #include <asm/io.h>
  14. #include <dm/uclass-internal.h>
  15. #define PCR_COMMON_IOSF_1_0 1
  16. static void *_pcr_reg_address(struct udevice *dev, uint offset)
  17. {
  18. struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev);
  19. struct udevice *p2sb = dev_get_parent(dev);
  20. struct p2sb_uc_priv *upriv = dev_get_uclass_priv(p2sb);
  21. uintptr_t reg_addr;
  22. /* Create an address based off of port id and offset */
  23. reg_addr = upriv->mmio_base;
  24. reg_addr += pplat->pid << PCR_PORTID_SHIFT;
  25. reg_addr += offset;
  26. return map_sysmem(reg_addr, 4);
  27. }
  28. /*
  29. * The mapping of addresses via the SBREG_BAR assumes the IOSF-SB
  30. * agents are using 32-bit aligned accesses for their configuration
  31. * registers. For IOSF versions greater than 1_0, IOSF-SB
  32. * agents can use any access (8/16/32 bit aligned) for their
  33. * configuration registers
  34. */
  35. static inline void check_pcr_offset_align(uint offset, uint size)
  36. {
  37. const size_t align = PCR_COMMON_IOSF_1_0 ? sizeof(uint32_t) : size;
  38. assert(IS_ALIGNED(offset, align));
  39. }
  40. uint pcr_read32(struct udevice *dev, uint offset)
  41. {
  42. void *ptr;
  43. uint val;
  44. /* Ensure the PCR offset is correctly aligned */
  45. assert(IS_ALIGNED(offset, sizeof(uint32_t)));
  46. ptr = _pcr_reg_address(dev, offset);
  47. val = readl(ptr);
  48. unmap_sysmem(ptr);
  49. return val;
  50. }
  51. uint pcr_read16(struct udevice *dev, uint offset)
  52. {
  53. /* Ensure the PCR offset is correctly aligned */
  54. check_pcr_offset_align(offset, sizeof(uint16_t));
  55. return readw(_pcr_reg_address(dev, offset));
  56. }
  57. uint pcr_read8(struct udevice *dev, uint offset)
  58. {
  59. /* Ensure the PCR offset is correctly aligned */
  60. check_pcr_offset_align(offset, sizeof(uint8_t));
  61. return readb(_pcr_reg_address(dev, offset));
  62. }
  63. /*
  64. * After every write one needs to perform a read an innocuous register to
  65. * ensure the writes are completed for certain ports. This is done for
  66. * all ports so that the callers don't need the per-port knowledge for
  67. * each transaction.
  68. */
  69. static void write_completion(struct udevice *dev, uint offset)
  70. {
  71. readl(_pcr_reg_address(dev, ALIGN_DOWN(offset, sizeof(uint32_t))));
  72. }
  73. void pcr_write32(struct udevice *dev, uint offset, uint indata)
  74. {
  75. /* Ensure the PCR offset is correctly aligned */
  76. assert(IS_ALIGNED(offset, sizeof(indata)));
  77. writel(indata, _pcr_reg_address(dev, offset));
  78. /* Ensure the writes complete */
  79. write_completion(dev, offset);
  80. }
  81. void pcr_write16(struct udevice *dev, uint offset, uint indata)
  82. {
  83. /* Ensure the PCR offset is correctly aligned */
  84. check_pcr_offset_align(offset, sizeof(uint16_t));
  85. writew(indata, _pcr_reg_address(dev, offset));
  86. /* Ensure the writes complete */
  87. write_completion(dev, offset);
  88. }
  89. void pcr_write8(struct udevice *dev, uint offset, uint indata)
  90. {
  91. /* Ensure the PCR offset is correctly aligned */
  92. check_pcr_offset_align(offset, sizeof(uint8_t));
  93. writeb(indata, _pcr_reg_address(dev, offset));
  94. /* Ensure the writes complete */
  95. write_completion(dev, offset);
  96. }
  97. void pcr_clrsetbits32(struct udevice *dev, uint offset, uint clr, uint set)
  98. {
  99. uint data32;
  100. data32 = pcr_read32(dev, offset);
  101. data32 &= ~clr;
  102. data32 |= set;
  103. pcr_write32(dev, offset, data32);
  104. }
  105. void pcr_clrsetbits16(struct udevice *dev, uint offset, uint clr, uint set)
  106. {
  107. uint data16;
  108. data16 = pcr_read16(dev, offset);
  109. data16 &= ~clr;
  110. data16 |= set;
  111. pcr_write16(dev, offset, data16);
  112. }
  113. void pcr_clrsetbits8(struct udevice *dev, uint offset, uint clr, uint set)
  114. {
  115. uint data8;
  116. data8 = pcr_read8(dev, offset);
  117. data8 &= ~clr;
  118. data8 |= set;
  119. pcr_write8(dev, offset, data8);
  120. }
  121. int p2sb_get_port_id(struct udevice *dev)
  122. {
  123. struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev);
  124. return pplat->pid;
  125. }
  126. int p2sb_set_port_id(struct udevice *dev, int portid)
  127. {
  128. struct udevice *ps2b;
  129. struct p2sb_child_platdata *pplat;
  130. if (!CONFIG_IS_ENABLED(OF_PLATDATA))
  131. return -ENOSYS;
  132. uclass_find_first_device(UCLASS_P2SB, &ps2b);
  133. if (!ps2b)
  134. return -EDEADLK;
  135. dev->parent = ps2b;
  136. /*
  137. * We must allocate this, since when the device was bound it did not
  138. * have a parent.
  139. * TODO(sjg@chromium.org): Add a parent pointer to child devices in dtoc
  140. */
  141. dev->parent_platdata = malloc(sizeof(*pplat));
  142. if (!dev->parent_platdata)
  143. return -ENOMEM;
  144. pplat = dev_get_parent_platdata(dev);
  145. pplat->pid = portid;
  146. return 0;
  147. }
  148. static int p2sb_child_post_bind(struct udevice *dev)
  149. {
  150. #if !CONFIG_IS_ENABLED(OF_PLATDATA)
  151. struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev);
  152. int ret;
  153. u32 pid;
  154. ret = dev_read_u32(dev, "intel,p2sb-port-id", &pid);
  155. if (ret)
  156. return ret;
  157. pplat->pid = pid;
  158. #endif
  159. return 0;
  160. }
  161. static int p2sb_post_bind(struct udevice *dev)
  162. {
  163. if (spl_phase() > PHASE_TPL && !CONFIG_IS_ENABLED(OF_PLATDATA))
  164. return dm_scan_fdt_dev(dev);
  165. return 0;
  166. }
  167. UCLASS_DRIVER(p2sb) = {
  168. .id = UCLASS_P2SB,
  169. .name = "p2sb",
  170. .per_device_auto_alloc_size = sizeof(struct p2sb_uc_priv),
  171. .post_bind = p2sb_post_bind,
  172. .child_post_bind = p2sb_child_post_bind,
  173. .per_child_platdata_auto_alloc_size =
  174. sizeof(struct p2sb_child_platdata),
  175. };