1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2560424e9SKalle Valo /*
3560424e9SKalle Valo * Low-level device IO routines for ST-Ericsson CW1200 drivers
4560424e9SKalle Valo *
5560424e9SKalle Valo * Copyright (c) 2010, ST-Ericsson
6560424e9SKalle Valo * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
7560424e9SKalle Valo *
8560424e9SKalle Valo * Based on:
9560424e9SKalle Valo * ST-Ericsson UMAC CW1200 driver, which is
10560424e9SKalle Valo * Copyright (c) 2010, ST-Ericsson
11560424e9SKalle Valo * Author: Ajitpal Singh <ajitpal.singh@lockless.no>
12560424e9SKalle Valo */
13560424e9SKalle Valo
14560424e9SKalle Valo #include <linux/types.h>
15560424e9SKalle Valo
16560424e9SKalle Valo #include "cw1200.h"
17560424e9SKalle Valo #include "hwio.h"
18560424e9SKalle Valo #include "hwbus.h"
19560424e9SKalle Valo
20560424e9SKalle Valo /* Sdio addr is 4*spi_addr */
21560424e9SKalle Valo #define SPI_REG_ADDR_TO_SDIO(spi_reg_addr) ((spi_reg_addr) << 2)
22560424e9SKalle Valo #define SDIO_ADDR17BIT(buf_id, mpf, rfu, reg_id_ofs) \
23560424e9SKalle Valo ((((buf_id) & 0x1F) << 7) \
24560424e9SKalle Valo | (((mpf) & 1) << 6) \
25560424e9SKalle Valo | (((rfu) & 1) << 5) \
26560424e9SKalle Valo | (((reg_id_ofs) & 0x1F) << 0))
27560424e9SKalle Valo #define MAX_RETRY 3
28560424e9SKalle Valo
29560424e9SKalle Valo
__cw1200_reg_read(struct cw1200_common * priv,u16 addr,void * buf,size_t buf_len,int buf_id)30560424e9SKalle Valo static int __cw1200_reg_read(struct cw1200_common *priv, u16 addr,
31560424e9SKalle Valo void *buf, size_t buf_len, int buf_id)
32560424e9SKalle Valo {
33560424e9SKalle Valo u16 addr_sdio;
34560424e9SKalle Valo u32 sdio_reg_addr_17bit;
35560424e9SKalle Valo
36560424e9SKalle Valo /* Check if buffer is aligned to 4 byte boundary */
37560424e9SKalle Valo if (WARN_ON(((unsigned long)buf & 3) && (buf_len > 4))) {
38560424e9SKalle Valo pr_err("buffer is not aligned.\n");
39560424e9SKalle Valo return -EINVAL;
40560424e9SKalle Valo }
41560424e9SKalle Valo
42560424e9SKalle Valo /* Convert to SDIO Register Address */
43560424e9SKalle Valo addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
44560424e9SKalle Valo sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
45560424e9SKalle Valo
46560424e9SKalle Valo return priv->hwbus_ops->hwbus_memcpy_fromio(priv->hwbus_priv,
47560424e9SKalle Valo sdio_reg_addr_17bit,
48560424e9SKalle Valo buf, buf_len);
49560424e9SKalle Valo }
50560424e9SKalle Valo
__cw1200_reg_write(struct cw1200_common * priv,u16 addr,const void * buf,size_t buf_len,int buf_id)51560424e9SKalle Valo static int __cw1200_reg_write(struct cw1200_common *priv, u16 addr,
52560424e9SKalle Valo const void *buf, size_t buf_len, int buf_id)
53560424e9SKalle Valo {
54560424e9SKalle Valo u16 addr_sdio;
55560424e9SKalle Valo u32 sdio_reg_addr_17bit;
56560424e9SKalle Valo
57560424e9SKalle Valo /* Convert to SDIO Register Address */
58560424e9SKalle Valo addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
59560424e9SKalle Valo sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
60560424e9SKalle Valo
61560424e9SKalle Valo return priv->hwbus_ops->hwbus_memcpy_toio(priv->hwbus_priv,
62560424e9SKalle Valo sdio_reg_addr_17bit,
63560424e9SKalle Valo buf, buf_len);
64560424e9SKalle Valo }
65560424e9SKalle Valo
__cw1200_reg_read_32(struct cw1200_common * priv,u16 addr,u32 * val)66560424e9SKalle Valo static inline int __cw1200_reg_read_32(struct cw1200_common *priv,
67560424e9SKalle Valo u16 addr, u32 *val)
68560424e9SKalle Valo {
69560424e9SKalle Valo __le32 tmp;
70560424e9SKalle Valo int i = __cw1200_reg_read(priv, addr, &tmp, sizeof(tmp), 0);
71560424e9SKalle Valo *val = le32_to_cpu(tmp);
72560424e9SKalle Valo return i;
73560424e9SKalle Valo }
74560424e9SKalle Valo
__cw1200_reg_write_32(struct cw1200_common * priv,u16 addr,u32 val)75560424e9SKalle Valo static inline int __cw1200_reg_write_32(struct cw1200_common *priv,
76560424e9SKalle Valo u16 addr, u32 val)
77560424e9SKalle Valo {
78560424e9SKalle Valo __le32 tmp = cpu_to_le32(val);
79560424e9SKalle Valo return __cw1200_reg_write(priv, addr, &tmp, sizeof(tmp), 0);
80560424e9SKalle Valo }
81560424e9SKalle Valo
__cw1200_reg_read_16(struct cw1200_common * priv,u16 addr,u16 * val)82560424e9SKalle Valo static inline int __cw1200_reg_read_16(struct cw1200_common *priv,
83560424e9SKalle Valo u16 addr, u16 *val)
84560424e9SKalle Valo {
85560424e9SKalle Valo __le16 tmp;
86560424e9SKalle Valo int i = __cw1200_reg_read(priv, addr, &tmp, sizeof(tmp), 0);
87560424e9SKalle Valo *val = le16_to_cpu(tmp);
88560424e9SKalle Valo return i;
89560424e9SKalle Valo }
90560424e9SKalle Valo
__cw1200_reg_write_16(struct cw1200_common * priv,u16 addr,u16 val)91560424e9SKalle Valo static inline int __cw1200_reg_write_16(struct cw1200_common *priv,
92560424e9SKalle Valo u16 addr, u16 val)
93560424e9SKalle Valo {
94560424e9SKalle Valo __le16 tmp = cpu_to_le16(val);
95560424e9SKalle Valo return __cw1200_reg_write(priv, addr, &tmp, sizeof(tmp), 0);
96560424e9SKalle Valo }
97560424e9SKalle Valo
cw1200_reg_read(struct cw1200_common * priv,u16 addr,void * buf,size_t buf_len)98560424e9SKalle Valo int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf,
99560424e9SKalle Valo size_t buf_len)
100560424e9SKalle Valo {
101560424e9SKalle Valo int ret;
102560424e9SKalle Valo priv->hwbus_ops->lock(priv->hwbus_priv);
103560424e9SKalle Valo ret = __cw1200_reg_read(priv, addr, buf, buf_len, 0);
104560424e9SKalle Valo priv->hwbus_ops->unlock(priv->hwbus_priv);
105560424e9SKalle Valo return ret;
106560424e9SKalle Valo }
107560424e9SKalle Valo
cw1200_reg_write(struct cw1200_common * priv,u16 addr,const void * buf,size_t buf_len)108560424e9SKalle Valo int cw1200_reg_write(struct cw1200_common *priv, u16 addr, const void *buf,
109560424e9SKalle Valo size_t buf_len)
110560424e9SKalle Valo {
111560424e9SKalle Valo int ret;
112560424e9SKalle Valo priv->hwbus_ops->lock(priv->hwbus_priv);
113560424e9SKalle Valo ret = __cw1200_reg_write(priv, addr, buf, buf_len, 0);
114560424e9SKalle Valo priv->hwbus_ops->unlock(priv->hwbus_priv);
115560424e9SKalle Valo return ret;
116560424e9SKalle Valo }
117560424e9SKalle Valo
cw1200_data_read(struct cw1200_common * priv,void * buf,size_t buf_len)118560424e9SKalle Valo int cw1200_data_read(struct cw1200_common *priv, void *buf, size_t buf_len)
119560424e9SKalle Valo {
120560424e9SKalle Valo int ret, retry = 1;
121560424e9SKalle Valo int buf_id_rx = priv->buf_id_rx;
122560424e9SKalle Valo
123560424e9SKalle Valo priv->hwbus_ops->lock(priv->hwbus_priv);
124560424e9SKalle Valo
125560424e9SKalle Valo while (retry <= MAX_RETRY) {
126560424e9SKalle Valo ret = __cw1200_reg_read(priv,
127560424e9SKalle Valo ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
128560424e9SKalle Valo buf_len, buf_id_rx + 1);
129560424e9SKalle Valo if (!ret) {
130560424e9SKalle Valo buf_id_rx = (buf_id_rx + 1) & 3;
131560424e9SKalle Valo priv->buf_id_rx = buf_id_rx;
132560424e9SKalle Valo break;
133560424e9SKalle Valo } else {
134560424e9SKalle Valo retry++;
135560424e9SKalle Valo mdelay(1);
136560424e9SKalle Valo pr_err("error :[%d]\n", ret);
137560424e9SKalle Valo }
138560424e9SKalle Valo }
139560424e9SKalle Valo
140560424e9SKalle Valo priv->hwbus_ops->unlock(priv->hwbus_priv);
141560424e9SKalle Valo return ret;
142560424e9SKalle Valo }
143560424e9SKalle Valo
cw1200_data_write(struct cw1200_common * priv,const void * buf,size_t buf_len)144560424e9SKalle Valo int cw1200_data_write(struct cw1200_common *priv, const void *buf,
145560424e9SKalle Valo size_t buf_len)
146560424e9SKalle Valo {
147560424e9SKalle Valo int ret, retry = 1;
148560424e9SKalle Valo int buf_id_tx = priv->buf_id_tx;
149560424e9SKalle Valo
150560424e9SKalle Valo priv->hwbus_ops->lock(priv->hwbus_priv);
151560424e9SKalle Valo
152560424e9SKalle Valo while (retry <= MAX_RETRY) {
153560424e9SKalle Valo ret = __cw1200_reg_write(priv,
154560424e9SKalle Valo ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
155560424e9SKalle Valo buf_len, buf_id_tx);
156560424e9SKalle Valo if (!ret) {
157560424e9SKalle Valo buf_id_tx = (buf_id_tx + 1) & 31;
158560424e9SKalle Valo priv->buf_id_tx = buf_id_tx;
159560424e9SKalle Valo break;
160560424e9SKalle Valo } else {
161560424e9SKalle Valo retry++;
162560424e9SKalle Valo mdelay(1);
163560424e9SKalle Valo pr_err("error :[%d]\n", ret);
164560424e9SKalle Valo }
165560424e9SKalle Valo }
166560424e9SKalle Valo
167560424e9SKalle Valo priv->hwbus_ops->unlock(priv->hwbus_priv);
168560424e9SKalle Valo return ret;
169560424e9SKalle Valo }
170560424e9SKalle Valo
cw1200_indirect_read(struct cw1200_common * priv,u32 addr,void * buf,size_t buf_len,u32 prefetch,u16 port_addr)171560424e9SKalle Valo int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
172560424e9SKalle Valo size_t buf_len, u32 prefetch, u16 port_addr)
173560424e9SKalle Valo {
174560424e9SKalle Valo u32 val32 = 0;
175560424e9SKalle Valo int i, ret;
176560424e9SKalle Valo
177560424e9SKalle Valo if ((buf_len / 2) >= 0x1000) {
178560424e9SKalle Valo pr_err("Can't read more than 0xfff words.\n");
179560424e9SKalle Valo return -EINVAL;
180560424e9SKalle Valo }
181560424e9SKalle Valo
182560424e9SKalle Valo priv->hwbus_ops->lock(priv->hwbus_priv);
183560424e9SKalle Valo /* Write address */
184560424e9SKalle Valo ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
185560424e9SKalle Valo if (ret < 0) {
186560424e9SKalle Valo pr_err("Can't write address register.\n");
187560424e9SKalle Valo goto out;
188560424e9SKalle Valo }
189560424e9SKalle Valo
190560424e9SKalle Valo /* Read CONFIG Register Value - We will read 32 bits */
191560424e9SKalle Valo ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
192560424e9SKalle Valo if (ret < 0) {
193560424e9SKalle Valo pr_err("Can't read config register.\n");
194560424e9SKalle Valo goto out;
195560424e9SKalle Valo }
196560424e9SKalle Valo
197560424e9SKalle Valo /* Set PREFETCH bit */
198560424e9SKalle Valo ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID,
199560424e9SKalle Valo val32 | prefetch);
200560424e9SKalle Valo if (ret < 0) {
201560424e9SKalle Valo pr_err("Can't write prefetch bit.\n");
202560424e9SKalle Valo goto out;
203560424e9SKalle Valo }
204560424e9SKalle Valo
205560424e9SKalle Valo /* Check for PRE-FETCH bit to be cleared */
206560424e9SKalle Valo for (i = 0; i < 20; i++) {
207560424e9SKalle Valo ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
208560424e9SKalle Valo if (ret < 0) {
209560424e9SKalle Valo pr_err("Can't check prefetch bit.\n");
210560424e9SKalle Valo goto out;
211560424e9SKalle Valo }
212560424e9SKalle Valo if (!(val32 & prefetch))
213560424e9SKalle Valo break;
214560424e9SKalle Valo
215560424e9SKalle Valo mdelay(i);
216560424e9SKalle Valo }
217560424e9SKalle Valo
218560424e9SKalle Valo if (val32 & prefetch) {
219560424e9SKalle Valo pr_err("Prefetch bit is not cleared.\n");
220560424e9SKalle Valo goto out;
221560424e9SKalle Valo }
222560424e9SKalle Valo
223560424e9SKalle Valo /* Read data port */
224560424e9SKalle Valo ret = __cw1200_reg_read(priv, port_addr, buf, buf_len, 0);
225560424e9SKalle Valo if (ret < 0) {
226560424e9SKalle Valo pr_err("Can't read data port.\n");
227560424e9SKalle Valo goto out;
228560424e9SKalle Valo }
229560424e9SKalle Valo
230560424e9SKalle Valo out:
231560424e9SKalle Valo priv->hwbus_ops->unlock(priv->hwbus_priv);
232560424e9SKalle Valo return ret;
233560424e9SKalle Valo }
234560424e9SKalle Valo
cw1200_apb_write(struct cw1200_common * priv,u32 addr,const void * buf,size_t buf_len)235560424e9SKalle Valo int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
236560424e9SKalle Valo size_t buf_len)
237560424e9SKalle Valo {
238560424e9SKalle Valo int ret;
239560424e9SKalle Valo
240560424e9SKalle Valo if ((buf_len / 2) >= 0x1000) {
241560424e9SKalle Valo pr_err("Can't write more than 0xfff words.\n");
242560424e9SKalle Valo return -EINVAL;
243560424e9SKalle Valo }
244560424e9SKalle Valo
245560424e9SKalle Valo priv->hwbus_ops->lock(priv->hwbus_priv);
246560424e9SKalle Valo
247560424e9SKalle Valo /* Write address */
248560424e9SKalle Valo ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
249560424e9SKalle Valo if (ret < 0) {
250560424e9SKalle Valo pr_err("Can't write address register.\n");
251560424e9SKalle Valo goto out;
252560424e9SKalle Valo }
253560424e9SKalle Valo
254560424e9SKalle Valo /* Write data port */
255560424e9SKalle Valo ret = __cw1200_reg_write(priv, ST90TDS_SRAM_DPORT_REG_ID,
256560424e9SKalle Valo buf, buf_len, 0);
257560424e9SKalle Valo if (ret < 0) {
258560424e9SKalle Valo pr_err("Can't write data port.\n");
259560424e9SKalle Valo goto out;
260560424e9SKalle Valo }
261560424e9SKalle Valo
262560424e9SKalle Valo out:
263560424e9SKalle Valo priv->hwbus_ops->unlock(priv->hwbus_priv);
264560424e9SKalle Valo return ret;
265560424e9SKalle Valo }
266560424e9SKalle Valo
__cw1200_irq_enable(struct cw1200_common * priv,int enable)267560424e9SKalle Valo int __cw1200_irq_enable(struct cw1200_common *priv, int enable)
268560424e9SKalle Valo {
269560424e9SKalle Valo u32 val32;
270560424e9SKalle Valo u16 val16;
271560424e9SKalle Valo int ret;
272560424e9SKalle Valo
273560424e9SKalle Valo if (HIF_8601_SILICON == priv->hw_type) {
274560424e9SKalle Valo ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
275560424e9SKalle Valo if (ret < 0) {
276560424e9SKalle Valo pr_err("Can't read config register.\n");
277560424e9SKalle Valo return ret;
278560424e9SKalle Valo }
279560424e9SKalle Valo
280560424e9SKalle Valo if (enable)
281560424e9SKalle Valo val32 |= ST90TDS_CONF_IRQ_RDY_ENABLE;
282560424e9SKalle Valo else
283560424e9SKalle Valo val32 &= ~ST90TDS_CONF_IRQ_RDY_ENABLE;
284560424e9SKalle Valo
285560424e9SKalle Valo ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val32);
286560424e9SKalle Valo if (ret < 0) {
287560424e9SKalle Valo pr_err("Can't write config register.\n");
288560424e9SKalle Valo return ret;
289560424e9SKalle Valo }
290560424e9SKalle Valo } else {
291560424e9SKalle Valo ret = __cw1200_reg_read_16(priv, ST90TDS_CONFIG_REG_ID, &val16);
292560424e9SKalle Valo if (ret < 0) {
293560424e9SKalle Valo pr_err("Can't read control register.\n");
294560424e9SKalle Valo return ret;
295560424e9SKalle Valo }
296560424e9SKalle Valo
297560424e9SKalle Valo if (enable)
298560424e9SKalle Valo val16 |= ST90TDS_CONT_IRQ_RDY_ENABLE;
299560424e9SKalle Valo else
300560424e9SKalle Valo val16 &= ~ST90TDS_CONT_IRQ_RDY_ENABLE;
301560424e9SKalle Valo
302560424e9SKalle Valo ret = __cw1200_reg_write_16(priv, ST90TDS_CONFIG_REG_ID, val16);
303560424e9SKalle Valo if (ret < 0) {
304560424e9SKalle Valo pr_err("Can't write control register.\n");
305560424e9SKalle Valo return ret;
306560424e9SKalle Valo }
307560424e9SKalle Valo }
308560424e9SKalle Valo return 0;
309560424e9SKalle Valo }
310