1 // SPDX-License-Identifier: GPL-2.0-only
3 * Low-level I/O functions.
5 * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
6 * Copyright (c) 2010, ST-Ericsson
8 #include <linux/kernel.h>
9 #include <linux/delay.h>
10 #include <linux/slab.h>
11 #include <linux/align.h>
18 #define WFX_HIF_BUFFER_SIZE 0x2000
20 static int wfx_read32(struct wfx_dev
*wdev
, int reg
, u32
*val
)
23 __le32
*tmp
= kmalloc(sizeof(u32
), GFP_KERNEL
);
25 *val
= ~0; /* Never return undefined value */
28 ret
= wdev
->hwbus_ops
->copy_from_io(wdev
->hwbus_priv
, reg
, tmp
, sizeof(u32
));
30 *val
= le32_to_cpu(*tmp
);
33 dev_err(wdev
->dev
, "%s: bus communication error: %d\n", __func__
, ret
);
37 static int wfx_write32(struct wfx_dev
*wdev
, int reg
, u32 val
)
40 __le32
*tmp
= kmalloc(sizeof(u32
), GFP_KERNEL
);
44 *tmp
= cpu_to_le32(val
);
45 ret
= wdev
->hwbus_ops
->copy_to_io(wdev
->hwbus_priv
, reg
, tmp
, sizeof(u32
));
48 dev_err(wdev
->dev
, "%s: bus communication error: %d\n", __func__
, ret
);
52 static int wfx_read32_locked(struct wfx_dev
*wdev
, int reg
, u32
*val
)
56 wdev
->hwbus_ops
->lock(wdev
->hwbus_priv
);
57 ret
= wfx_read32(wdev
, reg
, val
);
58 _trace_io_read32(reg
, *val
);
59 wdev
->hwbus_ops
->unlock(wdev
->hwbus_priv
);
63 static int wfx_write32_locked(struct wfx_dev
*wdev
, int reg
, u32 val
)
67 wdev
->hwbus_ops
->lock(wdev
->hwbus_priv
);
68 ret
= wfx_write32(wdev
, reg
, val
);
69 _trace_io_write32(reg
, val
);
70 wdev
->hwbus_ops
->unlock(wdev
->hwbus_priv
);
74 static int wfx_write32_bits_locked(struct wfx_dev
*wdev
, int reg
, u32 mask
, u32 val
)
81 wdev
->hwbus_ops
->lock(wdev
->hwbus_priv
);
82 ret
= wfx_read32(wdev
, reg
, &val_r
);
83 _trace_io_read32(reg
, val_r
);
86 val_w
= (val_r
& ~mask
) | val
;
88 ret
= wfx_write32(wdev
, reg
, val_w
);
89 _trace_io_write32(reg
, val_w
);
92 wdev
->hwbus_ops
->unlock(wdev
->hwbus_priv
);
96 static int wfx_indirect_read(struct wfx_dev
*wdev
, int reg
, u32 addr
, void *buf
, size_t len
)
103 WARN_ON(len
>= WFX_HIF_BUFFER_SIZE
);
104 WARN_ON(reg
!= WFX_REG_AHB_DPORT
&& reg
!= WFX_REG_SRAM_DPORT
);
106 if (reg
== WFX_REG_AHB_DPORT
)
107 prefetch
= CFG_PREFETCH_AHB
;
108 else if (reg
== WFX_REG_SRAM_DPORT
)
109 prefetch
= CFG_PREFETCH_SRAM
;
113 ret
= wfx_write32(wdev
, WFX_REG_BASE_ADDR
, addr
);
117 ret
= wfx_read32(wdev
, WFX_REG_CONFIG
, &cfg
);
121 ret
= wfx_write32(wdev
, WFX_REG_CONFIG
, cfg
| prefetch
);
125 for (i
= 0; i
< 20; i
++) {
126 ret
= wfx_read32(wdev
, WFX_REG_CONFIG
, &cfg
);
129 if (!(cfg
& prefetch
))
131 usleep_range(200, 250);
138 ret
= wdev
->hwbus_ops
->copy_from_io(wdev
->hwbus_priv
, reg
, buf
, len
);
142 memset(buf
, 0xFF, len
); /* Never return undefined value */
146 static int wfx_indirect_write(struct wfx_dev
*wdev
, int reg
, u32 addr
,
147 const void *buf
, size_t len
)
151 WARN_ON(len
>= WFX_HIF_BUFFER_SIZE
);
152 WARN_ON(reg
!= WFX_REG_AHB_DPORT
&& reg
!= WFX_REG_SRAM_DPORT
);
153 ret
= wfx_write32(wdev
, WFX_REG_BASE_ADDR
, addr
);
157 return wdev
->hwbus_ops
->copy_to_io(wdev
->hwbus_priv
, reg
, buf
, len
);
160 static int wfx_indirect_read_locked(struct wfx_dev
*wdev
, int reg
, u32 addr
,
161 void *buf
, size_t len
)
165 wdev
->hwbus_ops
->lock(wdev
->hwbus_priv
);
166 ret
= wfx_indirect_read(wdev
, reg
, addr
, buf
, len
);
167 _trace_io_ind_read(reg
, addr
, buf
, len
);
168 wdev
->hwbus_ops
->unlock(wdev
->hwbus_priv
);
172 static int wfx_indirect_write_locked(struct wfx_dev
*wdev
, int reg
, u32 addr
,
173 const void *buf
, size_t len
)
177 wdev
->hwbus_ops
->lock(wdev
->hwbus_priv
);
178 ret
= wfx_indirect_write(wdev
, reg
, addr
, buf
, len
);
179 _trace_io_ind_write(reg
, addr
, buf
, len
);
180 wdev
->hwbus_ops
->unlock(wdev
->hwbus_priv
);
184 static int wfx_indirect_read32_locked(struct wfx_dev
*wdev
, int reg
, u32 addr
, u32
*val
)
187 __le32
*tmp
= kmalloc(sizeof(u32
), GFP_KERNEL
);
191 wdev
->hwbus_ops
->lock(wdev
->hwbus_priv
);
192 ret
= wfx_indirect_read(wdev
, reg
, addr
, tmp
, sizeof(u32
));
193 *val
= le32_to_cpu(*tmp
);
194 _trace_io_ind_read32(reg
, addr
, *val
);
195 wdev
->hwbus_ops
->unlock(wdev
->hwbus_priv
);
200 static int wfx_indirect_write32_locked(struct wfx_dev
*wdev
, int reg
, u32 addr
, u32 val
)
203 __le32
*tmp
= kmalloc(sizeof(u32
), GFP_KERNEL
);
207 *tmp
= cpu_to_le32(val
);
208 wdev
->hwbus_ops
->lock(wdev
->hwbus_priv
);
209 ret
= wfx_indirect_write(wdev
, reg
, addr
, tmp
, sizeof(u32
));
210 _trace_io_ind_write32(reg
, addr
, val
);
211 wdev
->hwbus_ops
->unlock(wdev
->hwbus_priv
);
216 int wfx_data_read(struct wfx_dev
*wdev
, void *buf
, size_t len
)
220 WARN(!IS_ALIGNED((uintptr_t)buf
, 4), "unaligned buffer");
221 wdev
->hwbus_ops
->lock(wdev
->hwbus_priv
);
222 ret
= wdev
->hwbus_ops
->copy_from_io(wdev
->hwbus_priv
, WFX_REG_IN_OUT_QUEUE
, buf
, len
);
223 _trace_io_read(WFX_REG_IN_OUT_QUEUE
, buf
, len
);
224 wdev
->hwbus_ops
->unlock(wdev
->hwbus_priv
);
226 dev_err(wdev
->dev
, "%s: bus communication error: %d\n", __func__
, ret
);
230 int wfx_data_write(struct wfx_dev
*wdev
, const void *buf
, size_t len
)
234 WARN(!IS_ALIGNED((uintptr_t)buf
, 4), "unaligned buffer");
235 wdev
->hwbus_ops
->lock(wdev
->hwbus_priv
);
236 ret
= wdev
->hwbus_ops
->copy_to_io(wdev
->hwbus_priv
, WFX_REG_IN_OUT_QUEUE
, buf
, len
);
237 _trace_io_write(WFX_REG_IN_OUT_QUEUE
, buf
, len
);
238 wdev
->hwbus_ops
->unlock(wdev
->hwbus_priv
);
240 dev_err(wdev
->dev
, "%s: bus communication error: %d\n", __func__
, ret
);
244 int wfx_sram_buf_read(struct wfx_dev
*wdev
, u32 addr
, void *buf
, size_t len
)
246 return wfx_indirect_read_locked(wdev
, WFX_REG_SRAM_DPORT
, addr
, buf
, len
);
249 int wfx_ahb_buf_read(struct wfx_dev
*wdev
, u32 addr
, void *buf
, size_t len
)
251 return wfx_indirect_read_locked(wdev
, WFX_REG_AHB_DPORT
, addr
, buf
, len
);
254 int wfx_sram_buf_write(struct wfx_dev
*wdev
, u32 addr
, const void *buf
, size_t len
)
256 return wfx_indirect_write_locked(wdev
, WFX_REG_SRAM_DPORT
, addr
, buf
, len
);
259 int wfx_ahb_buf_write(struct wfx_dev
*wdev
, u32 addr
, const void *buf
, size_t len
)
261 return wfx_indirect_write_locked(wdev
, WFX_REG_AHB_DPORT
, addr
, buf
, len
);
264 int wfx_sram_reg_read(struct wfx_dev
*wdev
, u32 addr
, u32
*val
)
266 return wfx_indirect_read32_locked(wdev
, WFX_REG_SRAM_DPORT
, addr
, val
);
269 int wfx_ahb_reg_read(struct wfx_dev
*wdev
, u32 addr
, u32
*val
)
271 return wfx_indirect_read32_locked(wdev
, WFX_REG_AHB_DPORT
, addr
, val
);
274 int wfx_sram_reg_write(struct wfx_dev
*wdev
, u32 addr
, u32 val
)
276 return wfx_indirect_write32_locked(wdev
, WFX_REG_SRAM_DPORT
, addr
, val
);
279 int wfx_ahb_reg_write(struct wfx_dev
*wdev
, u32 addr
, u32 val
)
281 return wfx_indirect_write32_locked(wdev
, WFX_REG_AHB_DPORT
, addr
, val
);
284 int wfx_config_reg_read(struct wfx_dev
*wdev
, u32
*val
)
286 return wfx_read32_locked(wdev
, WFX_REG_CONFIG
, val
);
289 int wfx_config_reg_write(struct wfx_dev
*wdev
, u32 val
)
291 return wfx_write32_locked(wdev
, WFX_REG_CONFIG
, val
);
294 int wfx_config_reg_write_bits(struct wfx_dev
*wdev
, u32 mask
, u32 val
)
296 return wfx_write32_bits_locked(wdev
, WFX_REG_CONFIG
, mask
, val
);
299 int wfx_control_reg_read(struct wfx_dev
*wdev
, u32
*val
)
301 return wfx_read32_locked(wdev
, WFX_REG_CONTROL
, val
);
304 int wfx_control_reg_write(struct wfx_dev
*wdev
, u32 val
)
306 return wfx_write32_locked(wdev
, WFX_REG_CONTROL
, val
);
309 int wfx_control_reg_write_bits(struct wfx_dev
*wdev
, u32 mask
, u32 val
)
311 return wfx_write32_bits_locked(wdev
, WFX_REG_CONTROL
, mask
, val
);
314 int wfx_igpr_reg_read(struct wfx_dev
*wdev
, int index
, u32
*val
)
318 *val
= ~0; /* Never return undefined value */
319 ret
= wfx_write32_locked(wdev
, WFX_REG_SET_GEN_R_W
, IGPR_RW
| index
<< 24);
322 ret
= wfx_read32_locked(wdev
, WFX_REG_SET_GEN_R_W
, val
);
329 int wfx_igpr_reg_write(struct wfx_dev
*wdev
, int index
, u32 val
)
331 return wfx_write32_locked(wdev
, WFX_REG_SET_GEN_R_W
, index
<< 24 | val
);