WIP FPC-III support
[linux/fpc-iii.git] / drivers / staging / wfx / hwio.c
blob36fbc5b5d64cefe2894a3e4802f10528685c89a6
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Low-level I/O functions.
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>
12 #include "hwio.h"
13 #include "wfx.h"
14 #include "bus.h"
15 #include "traces.h"
18 * Internal helpers.
20 * About CONFIG_VMAP_STACK:
21 * When CONFIG_VMAP_STACK is enabled, it is not possible to run DMA on stack
22 * allocated data. Functions below that work with registers (aka functions
23 * ending with "32") automatically reallocate buffers with kmalloc. However,
24 * functions that work with arbitrary length buffers let's caller to handle
25 * memory location. In doubt, enable CONFIG_DEBUG_SG to detect badly located
26 * buffer.
29 static int read32(struct wfx_dev *wdev, int reg, u32 *val)
31 int ret;
32 __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL);
34 *val = ~0; // Never return undefined value
35 if (!tmp)
36 return -ENOMEM;
37 ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv, reg, tmp,
38 sizeof(u32));
39 if (ret >= 0)
40 *val = le32_to_cpu(*tmp);
41 kfree(tmp);
42 if (ret)
43 dev_err(wdev->dev, "%s: bus communication error: %d\n",
44 __func__, ret);
45 return ret;
48 static int write32(struct wfx_dev *wdev, int reg, u32 val)
50 int ret;
51 __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL);
53 if (!tmp)
54 return -ENOMEM;
55 *tmp = cpu_to_le32(val);
56 ret = wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv, reg, tmp,
57 sizeof(u32));
58 kfree(tmp);
59 if (ret)
60 dev_err(wdev->dev, "%s: bus communication error: %d\n",
61 __func__, ret);
62 return ret;
65 static int read32_locked(struct wfx_dev *wdev, int reg, u32 *val)
67 int ret;
69 wdev->hwbus_ops->lock(wdev->hwbus_priv);
70 ret = read32(wdev, reg, val);
71 _trace_io_read32(reg, *val);
72 wdev->hwbus_ops->unlock(wdev->hwbus_priv);
73 return ret;
76 static int write32_locked(struct wfx_dev *wdev, int reg, u32 val)
78 int ret;
80 wdev->hwbus_ops->lock(wdev->hwbus_priv);
81 ret = write32(wdev, reg, val);
82 _trace_io_write32(reg, val);
83 wdev->hwbus_ops->unlock(wdev->hwbus_priv);
84 return ret;
87 static int write32_bits_locked(struct wfx_dev *wdev, int reg, u32 mask, u32 val)
89 int ret;
90 u32 val_r, val_w;
92 WARN_ON(~mask & val);
93 val &= mask;
94 wdev->hwbus_ops->lock(wdev->hwbus_priv);
95 ret = read32(wdev, reg, &val_r);
96 _trace_io_read32(reg, val_r);
97 if (ret < 0)
98 goto err;
99 val_w = (val_r & ~mask) | val;
100 if (val_w != val_r) {
101 ret = write32(wdev, reg, val_w);
102 _trace_io_write32(reg, val_w);
104 err:
105 wdev->hwbus_ops->unlock(wdev->hwbus_priv);
106 return ret;
109 static int indirect_read(struct wfx_dev *wdev, int reg, u32 addr,
110 void *buf, size_t len)
112 int ret;
113 int i;
114 u32 cfg;
115 u32 prefetch;
117 WARN_ON(len >= 0x2000);
118 WARN_ON(reg != WFX_REG_AHB_DPORT && reg != WFX_REG_SRAM_DPORT);
120 if (reg == WFX_REG_AHB_DPORT)
121 prefetch = CFG_PREFETCH_AHB;
122 else if (reg == WFX_REG_SRAM_DPORT)
123 prefetch = CFG_PREFETCH_SRAM;
124 else
125 return -ENODEV;
127 ret = write32(wdev, WFX_REG_BASE_ADDR, addr);
128 if (ret < 0)
129 goto err;
131 ret = read32(wdev, WFX_REG_CONFIG, &cfg);
132 if (ret < 0)
133 goto err;
135 ret = write32(wdev, WFX_REG_CONFIG, cfg | prefetch);
136 if (ret < 0)
137 goto err;
139 for (i = 0; i < 20; i++) {
140 ret = read32(wdev, WFX_REG_CONFIG, &cfg);
141 if (ret < 0)
142 goto err;
143 if (!(cfg & prefetch))
144 break;
145 usleep_range(200, 250);
147 if (i == 20) {
148 ret = -ETIMEDOUT;
149 goto err;
152 ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv, reg, buf, len);
154 err:
155 if (ret < 0)
156 memset(buf, 0xFF, len); // Never return undefined value
157 return ret;
160 static int indirect_write(struct wfx_dev *wdev, int reg, u32 addr,
161 const void *buf, size_t len)
163 int ret;
165 WARN_ON(len >= 0x2000);
166 WARN_ON(reg != WFX_REG_AHB_DPORT && reg != WFX_REG_SRAM_DPORT);
167 ret = write32(wdev, WFX_REG_BASE_ADDR, addr);
168 if (ret < 0)
169 return ret;
171 return wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv, reg, buf, len);
174 static int indirect_read_locked(struct wfx_dev *wdev, int reg, u32 addr,
175 void *buf, size_t len)
177 int ret;
179 wdev->hwbus_ops->lock(wdev->hwbus_priv);
180 ret = indirect_read(wdev, reg, addr, buf, len);
181 _trace_io_ind_read(reg, addr, buf, len);
182 wdev->hwbus_ops->unlock(wdev->hwbus_priv);
183 return ret;
186 static int indirect_write_locked(struct wfx_dev *wdev, int reg, u32 addr,
187 const void *buf, size_t len)
189 int ret;
191 wdev->hwbus_ops->lock(wdev->hwbus_priv);
192 ret = indirect_write(wdev, reg, addr, buf, len);
193 _trace_io_ind_write(reg, addr, buf, len);
194 wdev->hwbus_ops->unlock(wdev->hwbus_priv);
195 return ret;
198 static int indirect_read32_locked(struct wfx_dev *wdev, int reg,
199 u32 addr, u32 *val)
201 int ret;
202 __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL);
204 if (!tmp)
205 return -ENOMEM;
206 wdev->hwbus_ops->lock(wdev->hwbus_priv);
207 ret = indirect_read(wdev, reg, addr, tmp, sizeof(u32));
208 *val = le32_to_cpu(*tmp);
209 _trace_io_ind_read32(reg, addr, *val);
210 wdev->hwbus_ops->unlock(wdev->hwbus_priv);
211 kfree(tmp);
212 return ret;
215 static int indirect_write32_locked(struct wfx_dev *wdev, int reg,
216 u32 addr, u32 val)
218 int ret;
219 __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL);
221 if (!tmp)
222 return -ENOMEM;
223 *tmp = cpu_to_le32(val);
224 wdev->hwbus_ops->lock(wdev->hwbus_priv);
225 ret = indirect_write(wdev, reg, addr, tmp, sizeof(u32));
226 _trace_io_ind_write32(reg, addr, val);
227 wdev->hwbus_ops->unlock(wdev->hwbus_priv);
228 kfree(tmp);
229 return ret;
232 int wfx_data_read(struct wfx_dev *wdev, void *buf, size_t len)
234 int ret;
236 WARN((long)buf & 3, "%s: unaligned buffer", __func__);
237 wdev->hwbus_ops->lock(wdev->hwbus_priv);
238 ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv,
239 WFX_REG_IN_OUT_QUEUE, buf, len);
240 _trace_io_read(WFX_REG_IN_OUT_QUEUE, buf, len);
241 wdev->hwbus_ops->unlock(wdev->hwbus_priv);
242 if (ret)
243 dev_err(wdev->dev, "%s: bus communication error: %d\n",
244 __func__, ret);
245 return ret;
248 int wfx_data_write(struct wfx_dev *wdev, const void *buf, size_t len)
250 int ret;
252 WARN((long)buf & 3, "%s: unaligned buffer", __func__);
253 wdev->hwbus_ops->lock(wdev->hwbus_priv);
254 ret = wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv,
255 WFX_REG_IN_OUT_QUEUE, buf, len);
256 _trace_io_write(WFX_REG_IN_OUT_QUEUE, buf, len);
257 wdev->hwbus_ops->unlock(wdev->hwbus_priv);
258 if (ret)
259 dev_err(wdev->dev, "%s: bus communication error: %d\n",
260 __func__, ret);
261 return ret;
264 int sram_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len)
266 return indirect_read_locked(wdev, WFX_REG_SRAM_DPORT, addr, buf, len);
269 int ahb_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len)
271 return indirect_read_locked(wdev, WFX_REG_AHB_DPORT, addr, buf, len);
274 int sram_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len)
276 return indirect_write_locked(wdev, WFX_REG_SRAM_DPORT, addr, buf, len);
279 int ahb_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len)
281 return indirect_write_locked(wdev, WFX_REG_AHB_DPORT, addr, buf, len);
284 int sram_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val)
286 return indirect_read32_locked(wdev, WFX_REG_SRAM_DPORT, addr, val);
289 int ahb_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val)
291 return indirect_read32_locked(wdev, WFX_REG_AHB_DPORT, addr, val);
294 int sram_reg_write(struct wfx_dev *wdev, u32 addr, u32 val)
296 return indirect_write32_locked(wdev, WFX_REG_SRAM_DPORT, addr, val);
299 int ahb_reg_write(struct wfx_dev *wdev, u32 addr, u32 val)
301 return indirect_write32_locked(wdev, WFX_REG_AHB_DPORT, addr, val);
304 int config_reg_read(struct wfx_dev *wdev, u32 *val)
306 return read32_locked(wdev, WFX_REG_CONFIG, val);
309 int config_reg_write(struct wfx_dev *wdev, u32 val)
311 return write32_locked(wdev, WFX_REG_CONFIG, val);
314 int config_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val)
316 return write32_bits_locked(wdev, WFX_REG_CONFIG, mask, val);
319 int control_reg_read(struct wfx_dev *wdev, u32 *val)
321 return read32_locked(wdev, WFX_REG_CONTROL, val);
324 int control_reg_write(struct wfx_dev *wdev, u32 val)
326 return write32_locked(wdev, WFX_REG_CONTROL, val);
329 int control_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val)
331 return write32_bits_locked(wdev, WFX_REG_CONTROL, mask, val);
334 int igpr_reg_read(struct wfx_dev *wdev, int index, u32 *val)
336 int ret;
338 *val = ~0; // Never return undefined value
339 ret = write32_locked(wdev, WFX_REG_SET_GEN_R_W, IGPR_RW | index << 24);
340 if (ret)
341 return ret;
342 ret = read32_locked(wdev, WFX_REG_SET_GEN_R_W, val);
343 if (ret)
344 return ret;
345 *val &= IGPR_VALUE;
346 return ret;
349 int igpr_reg_write(struct wfx_dev *wdev, int index, u32 val)
351 return write32_locked(wdev, WFX_REG_SET_GEN_R_W, index << 24 | val);