dat_v1.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // SPDX-License-Identifier: BSD-3-Clause
  2. /*
  3. * Copyright (c) 2020, MIPI Alliance, Inc.
  4. *
  5. * Author: Nicolas Pitre <[email protected]>
  6. */
  7. #include <linux/bitfield.h>
  8. #include <linux/bitmap.h>
  9. #include <linux/device.h>
  10. #include <linux/errno.h>
  11. #include <linux/i3c/master.h>
  12. #include <linux/io.h>
  13. #include "hci.h"
  14. #include "dat.h"
  15. /*
  16. * Device Address Table Structure
  17. */
  18. #define DAT_1_AUTOCMD_HDR_CODE W1_MASK(58, 51)
  19. #define DAT_1_AUTOCMD_MODE W1_MASK(50, 48)
  20. #define DAT_1_AUTOCMD_VALUE W1_MASK(47, 40)
  21. #define DAT_1_AUTOCMD_MASK W1_MASK(39, 32)
  22. /* DAT_0_I2C_DEVICE W0_BIT_(31) */
  23. #define DAT_0_DEV_NACK_RETRY_CNT W0_MASK(30, 29)
  24. #define DAT_0_RING_ID W0_MASK(28, 26)
  25. #define DAT_0_DYNADDR_PARITY W0_BIT_(23)
  26. #define DAT_0_DYNAMIC_ADDRESS W0_MASK(22, 16)
  27. #define DAT_0_TS W0_BIT_(15)
  28. #define DAT_0_MR_REJECT W0_BIT_(14)
  29. /* DAT_0_SIR_REJECT W0_BIT_(13) */
  30. /* DAT_0_IBI_PAYLOAD W0_BIT_(12) */
  31. #define DAT_0_STATIC_ADDRESS W0_MASK(6, 0)
  32. #define dat_w0_read(i) readl(hci->DAT_regs + (i) * 8)
  33. #define dat_w1_read(i) readl(hci->DAT_regs + (i) * 8 + 4)
  34. #define dat_w0_write(i, v) writel(v, hci->DAT_regs + (i) * 8)
  35. #define dat_w1_write(i, v) writel(v, hci->DAT_regs + (i) * 8 + 4)
  36. static inline bool dynaddr_parity(unsigned int addr)
  37. {
  38. addr |= 1 << 7;
  39. addr += addr >> 4;
  40. addr += addr >> 2;
  41. addr += addr >> 1;
  42. return (addr & 1);
  43. }
  44. static int hci_dat_v1_init(struct i3c_hci *hci)
  45. {
  46. unsigned int dat_idx;
  47. if (!hci->DAT_regs) {
  48. dev_err(&hci->master.dev,
  49. "only DAT in register space is supported at the moment\n");
  50. return -EOPNOTSUPP;
  51. }
  52. if (hci->DAT_entry_size != 8) {
  53. dev_err(&hci->master.dev,
  54. "only 8-bytes DAT entries are supported at the moment\n");
  55. return -EOPNOTSUPP;
  56. }
  57. if (!hci->DAT_data) {
  58. /* use a bitmap for faster free slot search */
  59. hci->DAT_data = bitmap_zalloc(hci->DAT_entries, GFP_KERNEL);
  60. if (!hci->DAT_data)
  61. return -ENOMEM;
  62. /* clear them */
  63. for (dat_idx = 0; dat_idx < hci->DAT_entries; dat_idx++) {
  64. dat_w0_write(dat_idx, 0);
  65. dat_w1_write(dat_idx, 0);
  66. }
  67. }
  68. return 0;
  69. }
  70. static void hci_dat_v1_cleanup(struct i3c_hci *hci)
  71. {
  72. bitmap_free(hci->DAT_data);
  73. hci->DAT_data = NULL;
  74. }
  75. static int hci_dat_v1_alloc_entry(struct i3c_hci *hci)
  76. {
  77. unsigned int dat_idx;
  78. int ret;
  79. if (!hci->DAT_data) {
  80. ret = hci_dat_v1_init(hci);
  81. if (ret)
  82. return ret;
  83. }
  84. dat_idx = find_first_zero_bit(hci->DAT_data, hci->DAT_entries);
  85. if (dat_idx >= hci->DAT_entries)
  86. return -ENOENT;
  87. __set_bit(dat_idx, hci->DAT_data);
  88. /* default flags */
  89. dat_w0_write(dat_idx, DAT_0_SIR_REJECT | DAT_0_MR_REJECT);
  90. return dat_idx;
  91. }
  92. static void hci_dat_v1_free_entry(struct i3c_hci *hci, unsigned int dat_idx)
  93. {
  94. dat_w0_write(dat_idx, 0);
  95. dat_w1_write(dat_idx, 0);
  96. if (hci->DAT_data)
  97. __clear_bit(dat_idx, hci->DAT_data);
  98. }
  99. static void hci_dat_v1_set_dynamic_addr(struct i3c_hci *hci,
  100. unsigned int dat_idx, u8 address)
  101. {
  102. u32 dat_w0;
  103. dat_w0 = dat_w0_read(dat_idx);
  104. dat_w0 &= ~(DAT_0_DYNAMIC_ADDRESS | DAT_0_DYNADDR_PARITY);
  105. dat_w0 |= FIELD_PREP(DAT_0_DYNAMIC_ADDRESS, address) |
  106. (dynaddr_parity(address) ? DAT_0_DYNADDR_PARITY : 0);
  107. dat_w0_write(dat_idx, dat_w0);
  108. }
  109. static void hci_dat_v1_set_static_addr(struct i3c_hci *hci,
  110. unsigned int dat_idx, u8 address)
  111. {
  112. u32 dat_w0;
  113. dat_w0 = dat_w0_read(dat_idx);
  114. dat_w0 &= ~DAT_0_STATIC_ADDRESS;
  115. dat_w0 |= FIELD_PREP(DAT_0_STATIC_ADDRESS, address);
  116. dat_w0_write(dat_idx, dat_w0);
  117. }
  118. static void hci_dat_v1_set_flags(struct i3c_hci *hci, unsigned int dat_idx,
  119. u32 w0_flags, u32 w1_flags)
  120. {
  121. u32 dat_w0, dat_w1;
  122. dat_w0 = dat_w0_read(dat_idx);
  123. dat_w1 = dat_w1_read(dat_idx);
  124. dat_w0 |= w0_flags;
  125. dat_w1 |= w1_flags;
  126. dat_w0_write(dat_idx, dat_w0);
  127. dat_w1_write(dat_idx, dat_w1);
  128. }
  129. static void hci_dat_v1_clear_flags(struct i3c_hci *hci, unsigned int dat_idx,
  130. u32 w0_flags, u32 w1_flags)
  131. {
  132. u32 dat_w0, dat_w1;
  133. dat_w0 = dat_w0_read(dat_idx);
  134. dat_w1 = dat_w1_read(dat_idx);
  135. dat_w0 &= ~w0_flags;
  136. dat_w1 &= ~w1_flags;
  137. dat_w0_write(dat_idx, dat_w0);
  138. dat_w1_write(dat_idx, dat_w1);
  139. }
  140. static int hci_dat_v1_get_index(struct i3c_hci *hci, u8 dev_addr)
  141. {
  142. unsigned int dat_idx;
  143. u32 dat_w0;
  144. for_each_set_bit(dat_idx, hci->DAT_data, hci->DAT_entries) {
  145. dat_w0 = dat_w0_read(dat_idx);
  146. if (FIELD_GET(DAT_0_DYNAMIC_ADDRESS, dat_w0) == dev_addr)
  147. return dat_idx;
  148. }
  149. return -ENODEV;
  150. }
  151. const struct hci_dat_ops mipi_i3c_hci_dat_v1 = {
  152. .init = hci_dat_v1_init,
  153. .cleanup = hci_dat_v1_cleanup,
  154. .alloc_entry = hci_dat_v1_alloc_entry,
  155. .free_entry = hci_dat_v1_free_entry,
  156. .set_dynamic_addr = hci_dat_v1_set_dynamic_addr,
  157. .set_static_addr = hci_dat_v1_set_static_addr,
  158. .set_flags = hci_dat_v1_set_flags,
  159. .clear_flags = hci_dat_v1_clear_flags,
  160. .get_index = hci_dat_v1_get_index,
  161. };