hwio.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Low-level I/O functions.
  4. *
  5. * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
  6. * Copyright (c) 2010, ST-Ericsson
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/delay.h>
  10. #include <linux/slab.h>
  11. #include "hwio.h"
  12. #include "wfx.h"
  13. #include "bus.h"
  14. #include "traces.h"
  15. /*
  16. * Internal helpers.
  17. *
  18. * About CONFIG_VMAP_STACK:
  19. * When CONFIG_VMAP_STACK is enabled, it is not possible to run DMA on stack
  20. * allocated data. Functions below that work with registers (aka functions
  21. * ending with "32") automatically reallocate buffers with kmalloc. However,
  22. * functions that work with arbitrary length buffers let's caller to handle
  23. * memory location. In doubt, enable CONFIG_DEBUG_SG to detect badly located
  24. * buffer.
  25. */
  26. static int read32(struct wfx_dev *wdev, int reg, u32 *val)
  27. {
  28. int ret;
  29. __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL);
  30. *val = ~0; // Never return undefined value
  31. if (!tmp)
  32. return -ENOMEM;
  33. ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv, reg, tmp,
  34. sizeof(u32));
  35. if (ret >= 0)
  36. *val = le32_to_cpu(*tmp);
  37. kfree(tmp);
  38. if (ret)
  39. dev_err(wdev->dev, "%s: bus communication error: %d\n",
  40. __func__, ret);
  41. return ret;
  42. }
  43. static int write32(struct wfx_dev *wdev, int reg, u32 val)
  44. {
  45. int ret;
  46. __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL);
  47. if (!tmp)
  48. return -ENOMEM;
  49. *tmp = cpu_to_le32(val);
  50. ret = wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv, reg, tmp,
  51. sizeof(u32));
  52. kfree(tmp);
  53. if (ret)
  54. dev_err(wdev->dev, "%s: bus communication error: %d\n",
  55. __func__, ret);
  56. return ret;
  57. }
  58. static int read32_locked(struct wfx_dev *wdev, int reg, u32 *val)
  59. {
  60. int ret;
  61. wdev->hwbus_ops->lock(wdev->hwbus_priv);
  62. ret = read32(wdev, reg, val);
  63. _trace_io_read32(reg, *val);
  64. wdev->hwbus_ops->unlock(wdev->hwbus_priv);
  65. return ret;
  66. }
  67. static int write32_locked(struct wfx_dev *wdev, int reg, u32 val)
  68. {
  69. int ret;
  70. wdev->hwbus_ops->lock(wdev->hwbus_priv);
  71. ret = write32(wdev, reg, val);
  72. _trace_io_write32(reg, val);
  73. wdev->hwbus_ops->unlock(wdev->hwbus_priv);
  74. return ret;
  75. }
  76. static int write32_bits_locked(struct wfx_dev *wdev, int reg, u32 mask, u32 val)
  77. {
  78. int ret;
  79. u32 val_r, val_w;
  80. WARN_ON(~mask & val);
  81. val &= mask;
  82. wdev->hwbus_ops->lock(wdev->hwbus_priv);
  83. ret = read32(wdev, reg, &val_r);
  84. _trace_io_read32(reg, val_r);
  85. if (ret < 0)
  86. goto err;
  87. val_w = (val_r & ~mask) | val;
  88. if (val_w != val_r) {
  89. ret = write32(wdev, reg, val_w);
  90. _trace_io_write32(reg, val_w);
  91. }
  92. err:
  93. wdev->hwbus_ops->unlock(wdev->hwbus_priv);
  94. return ret;
  95. }
  96. static int indirect_read(struct wfx_dev *wdev, int reg, u32 addr,
  97. void *buf, size_t len)
  98. {
  99. int ret;
  100. int i;
  101. u32 cfg;
  102. u32 prefetch;
  103. WARN_ON(len >= 0x2000);
  104. WARN_ON(reg != WFX_REG_AHB_DPORT && reg != WFX_REG_SRAM_DPORT);
  105. if (reg == WFX_REG_AHB_DPORT)
  106. prefetch = CFG_PREFETCH_AHB;
  107. else if (reg == WFX_REG_SRAM_DPORT)
  108. prefetch = CFG_PREFETCH_SRAM;
  109. else
  110. return -ENODEV;
  111. ret = write32(wdev, WFX_REG_BASE_ADDR, addr);
  112. if (ret < 0)
  113. goto err;
  114. ret = read32(wdev, WFX_REG_CONFIG, &cfg);
  115. if (ret < 0)
  116. goto err;
  117. ret = write32(wdev, WFX_REG_CONFIG, cfg | prefetch);
  118. if (ret < 0)
  119. goto err;
  120. for (i = 0; i < 20; i++) {
  121. ret = read32(wdev, WFX_REG_CONFIG, &cfg);
  122. if (ret < 0)
  123. goto err;
  124. if (!(cfg & prefetch))
  125. break;
  126. usleep_range(200, 250);
  127. }
  128. if (i == 20) {
  129. ret = -ETIMEDOUT;
  130. goto err;
  131. }
  132. ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv, reg, buf, len);
  133. err:
  134. if (ret < 0)
  135. memset(buf, 0xFF, len); // Never return undefined value
  136. return ret;
  137. }
  138. static int indirect_write(struct wfx_dev *wdev, int reg, u32 addr,
  139. const void *buf, size_t len)
  140. {
  141. int ret;
  142. WARN_ON(len >= 0x2000);
  143. WARN_ON(reg != WFX_REG_AHB_DPORT && reg != WFX_REG_SRAM_DPORT);
  144. ret = write32(wdev, WFX_REG_BASE_ADDR, addr);
  145. if (ret < 0)
  146. return ret;
  147. return wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv, reg, buf, len);
  148. }
  149. static int indirect_read_locked(struct wfx_dev *wdev, int reg, u32 addr,
  150. void *buf, size_t len)
  151. {
  152. int ret;
  153. wdev->hwbus_ops->lock(wdev->hwbus_priv);
  154. ret = indirect_read(wdev, reg, addr, buf, len);
  155. _trace_io_ind_read(reg, addr, buf, len);
  156. wdev->hwbus_ops->unlock(wdev->hwbus_priv);
  157. return ret;
  158. }
  159. static int indirect_write_locked(struct wfx_dev *wdev, int reg, u32 addr,
  160. const void *buf, size_t len)
  161. {
  162. int ret;
  163. wdev->hwbus_ops->lock(wdev->hwbus_priv);
  164. ret = indirect_write(wdev, reg, addr, buf, len);
  165. _trace_io_ind_write(reg, addr, buf, len);
  166. wdev->hwbus_ops->unlock(wdev->hwbus_priv);
  167. return ret;
  168. }
  169. static int indirect_read32_locked(struct wfx_dev *wdev, int reg,
  170. u32 addr, u32 *val)
  171. {
  172. int ret;
  173. __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL);
  174. if (!tmp)
  175. return -ENOMEM;
  176. wdev->hwbus_ops->lock(wdev->hwbus_priv);
  177. ret = indirect_read(wdev, reg, addr, tmp, sizeof(u32));
  178. *val = le32_to_cpu(*tmp);
  179. _trace_io_ind_read32(reg, addr, *val);
  180. wdev->hwbus_ops->unlock(wdev->hwbus_priv);
  181. kfree(tmp);
  182. return ret;
  183. }
  184. static int indirect_write32_locked(struct wfx_dev *wdev, int reg,
  185. u32 addr, u32 val)
  186. {
  187. int ret;
  188. __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL);
  189. if (!tmp)
  190. return -ENOMEM;
  191. *tmp = cpu_to_le32(val);
  192. wdev->hwbus_ops->lock(wdev->hwbus_priv);
  193. ret = indirect_write(wdev, reg, addr, tmp, sizeof(u32));
  194. _trace_io_ind_write32(reg, addr, val);
  195. wdev->hwbus_ops->unlock(wdev->hwbus_priv);
  196. kfree(tmp);
  197. return ret;
  198. }
  199. int wfx_data_read(struct wfx_dev *wdev, void *buf, size_t len)
  200. {
  201. int ret;
  202. WARN((long)buf & 3, "%s: unaligned buffer", __func__);
  203. wdev->hwbus_ops->lock(wdev->hwbus_priv);
  204. ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv,
  205. WFX_REG_IN_OUT_QUEUE, buf, len);
  206. _trace_io_read(WFX_REG_IN_OUT_QUEUE, buf, len);
  207. wdev->hwbus_ops->unlock(wdev->hwbus_priv);
  208. if (ret)
  209. dev_err(wdev->dev, "%s: bus communication error: %d\n",
  210. __func__, ret);
  211. return ret;
  212. }
  213. int wfx_data_write(struct wfx_dev *wdev, const void *buf, size_t len)
  214. {
  215. int ret;
  216. WARN((long)buf & 3, "%s: unaligned buffer", __func__);
  217. wdev->hwbus_ops->lock(wdev->hwbus_priv);
  218. ret = wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv,
  219. WFX_REG_IN_OUT_QUEUE, buf, len);
  220. _trace_io_write(WFX_REG_IN_OUT_QUEUE, buf, len);
  221. wdev->hwbus_ops->unlock(wdev->hwbus_priv);
  222. if (ret)
  223. dev_err(wdev->dev, "%s: bus communication error: %d\n",
  224. __func__, ret);
  225. return ret;
  226. }
  227. int sram_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len)
  228. {
  229. return indirect_read_locked(wdev, WFX_REG_SRAM_DPORT, addr, buf, len);
  230. }
  231. int ahb_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len)
  232. {
  233. return indirect_read_locked(wdev, WFX_REG_AHB_DPORT, addr, buf, len);
  234. }
  235. int sram_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len)
  236. {
  237. return indirect_write_locked(wdev, WFX_REG_SRAM_DPORT, addr, buf, len);
  238. }
  239. int ahb_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len)
  240. {
  241. return indirect_write_locked(wdev, WFX_REG_AHB_DPORT, addr, buf, len);
  242. }
  243. int sram_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val)
  244. {
  245. return indirect_read32_locked(wdev, WFX_REG_SRAM_DPORT, addr, val);
  246. }
  247. int ahb_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val)
  248. {
  249. return indirect_read32_locked(wdev, WFX_REG_AHB_DPORT, addr, val);
  250. }
  251. int sram_reg_write(struct wfx_dev *wdev, u32 addr, u32 val)
  252. {
  253. return indirect_write32_locked(wdev, WFX_REG_SRAM_DPORT, addr, val);
  254. }
  255. int ahb_reg_write(struct wfx_dev *wdev, u32 addr, u32 val)
  256. {
  257. return indirect_write32_locked(wdev, WFX_REG_AHB_DPORT, addr, val);
  258. }
  259. int config_reg_read(struct wfx_dev *wdev, u32 *val)
  260. {
  261. return read32_locked(wdev, WFX_REG_CONFIG, val);
  262. }
  263. int config_reg_write(struct wfx_dev *wdev, u32 val)
  264. {
  265. return write32_locked(wdev, WFX_REG_CONFIG, val);
  266. }
  267. int config_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val)
  268. {
  269. return write32_bits_locked(wdev, WFX_REG_CONFIG, mask, val);
  270. }
  271. int control_reg_read(struct wfx_dev *wdev, u32 *val)
  272. {
  273. return read32_locked(wdev, WFX_REG_CONTROL, val);
  274. }
  275. int control_reg_write(struct wfx_dev *wdev, u32 val)
  276. {
  277. return write32_locked(wdev, WFX_REG_CONTROL, val);
  278. }
  279. int control_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val)
  280. {
  281. return write32_bits_locked(wdev, WFX_REG_CONTROL, mask, val);
  282. }
  283. int igpr_reg_read(struct wfx_dev *wdev, int index, u32 *val)
  284. {
  285. int ret;
  286. *val = ~0; // Never return undefined value
  287. ret = write32_locked(wdev, WFX_REG_SET_GEN_R_W, IGPR_RW | index << 24);
  288. if (ret)
  289. return ret;
  290. ret = read32_locked(wdev, WFX_REG_SET_GEN_R_W, val);
  291. if (ret)
  292. return ret;
  293. *val &= IGPR_VALUE;
  294. return ret;
  295. }
  296. int igpr_reg_write(struct wfx_dev *wdev, int index, u32 val)
  297. {
  298. return write32_locked(wdev, WFX_REG_SET_GEN_R_W, index << 24 | val);
  299. }