p2sb-uclass.c 5.3 KB

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