Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/allwinner/aw_rsb.c
39507 views
1
/*-
2
* Copyright (c) 2016 Jared McNeill <[email protected]>
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
12
*
13
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
20
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
* SUCH DAMAGE.
24
*/
25
26
/*
27
* Allwinner RSB (Reduced Serial Bus) and P2WI (Push-Pull Two Wire Interface)
28
*/
29
30
#include <sys/param.h>
31
#include <sys/systm.h>
32
#include <sys/bus.h>
33
#include <sys/rman.h>
34
#include <sys/kernel.h>
35
#include <sys/lock.h>
36
#include <sys/module.h>
37
#include <sys/mutex.h>
38
#include <machine/bus.h>
39
40
#include <dev/ofw/ofw_bus.h>
41
#include <dev/ofw/ofw_bus_subr.h>
42
43
#include <dev/iicbus/iiconf.h>
44
#include <dev/iicbus/iicbus.h>
45
46
#include <dev/clk/clk.h>
47
#include <dev/hwreset/hwreset.h>
48
49
#include "iicbus_if.h"
50
51
#define RSB_CTRL 0x00
52
#define START_TRANS (1 << 7)
53
#define GLOBAL_INT_ENB (1 << 1)
54
#define SOFT_RESET (1 << 0)
55
#define RSB_CCR 0x04
56
#define RSB_INTE 0x08
57
#define RSB_INTS 0x0c
58
#define INT_TRANS_ERR_ID(x) (((x) >> 8) & 0xf)
59
#define INT_LOAD_BSY (1 << 2)
60
#define INT_TRANS_ERR (1 << 1)
61
#define INT_TRANS_OVER (1 << 0)
62
#define INT_MASK (INT_LOAD_BSY|INT_TRANS_ERR|INT_TRANS_OVER)
63
#define RSB_DADDR0 0x10
64
#define RSB_DADDR1 0x14
65
#define RSB_DLEN 0x18
66
#define DLEN_READ (1 << 4)
67
#define RSB_DATA0 0x1c
68
#define RSB_DATA1 0x20
69
#define RSB_PMCR 0x28
70
#define RSB_PMCR_START (1 << 31)
71
#define RSB_PMCR_DATA(x) (x << 16)
72
#define RSB_PMCR_REG(x) (x << 8)
73
#define RSB_CMD 0x2c
74
#define CMD_SRTA 0xe8
75
#define CMD_RD8 0x8b
76
#define CMD_RD16 0x9c
77
#define CMD_RD32 0xa6
78
#define CMD_WR8 0x4e
79
#define CMD_WR16 0x59
80
#define CMD_WR32 0x63
81
#define RSB_DAR 0x30
82
#define DAR_RTA (0xff << 16)
83
#define DAR_RTA_SHIFT 16
84
#define DAR_DA (0xffff << 0)
85
#define DAR_DA_SHIFT 0
86
87
#define RSB_MAXLEN 8
88
#define RSB_RESET_RETRY 100
89
#define RSB_I2C_TIMEOUT hz
90
91
#define RSB_ADDR_PMIC_PRIMARY 0x3a3
92
#define RSB_ADDR_PMIC_SECONDARY 0x745
93
#define RSB_ADDR_PERIPH_IC 0xe89
94
95
#define PMIC_MODE_REG 0x3e
96
#define PMIC_MODE_I2C 0x00
97
#define PMIC_MODE_RSB 0x7c
98
99
#define A31_P2WI 1
100
#define A23_RSB 2
101
102
static struct ofw_compat_data compat_data[] = {
103
{ "allwinner,sun6i-a31-p2wi", A31_P2WI },
104
{ "allwinner,sun8i-a23-rsb", A23_RSB },
105
{ NULL, 0 }
106
};
107
108
static struct resource_spec rsb_spec[] = {
109
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
110
{ -1, 0 }
111
};
112
113
/*
114
* Device address to Run-time address mappings.
115
*
116
* Run-time address (RTA) is an 8-bit value used to address the device during
117
* a read or write transaction. The following are valid RTAs:
118
* 0x17 0x2d 0x3a 0x4e 0x59 0x63 0x74 0x8b 0x9c 0xa6 0xb1 0xc5 0xd2 0xe8 0xff
119
*
120
* Allwinner uses RTA 0x2d for the primary PMIC, 0x3a for the secondary PMIC,
121
* and 0x4e for the peripheral IC (where applicable).
122
*/
123
static const struct {
124
uint16_t addr;
125
uint8_t rta;
126
} rsb_rtamap[] = {
127
{ .addr = RSB_ADDR_PMIC_PRIMARY, .rta = 0x2d },
128
{ .addr = RSB_ADDR_PMIC_SECONDARY, .rta = 0x3a },
129
{ .addr = RSB_ADDR_PERIPH_IC, .rta = 0x4e },
130
{ .addr = 0, .rta = 0 }
131
};
132
133
struct rsb_softc {
134
struct resource *res;
135
struct mtx mtx;
136
clk_t clk;
137
hwreset_t rst;
138
device_t iicbus;
139
int busy;
140
uint32_t status;
141
uint16_t cur_addr;
142
int type;
143
144
struct iic_msg *msg;
145
};
146
147
#define RSB_LOCK(sc) mtx_lock(&(sc)->mtx)
148
#define RSB_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
149
#define RSB_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED)
150
#define RSB_READ(sc, reg) bus_read_4((sc)->res, (reg))
151
#define RSB_WRITE(sc, reg, val) bus_write_4((sc)->res, (reg), (val))
152
153
static phandle_t
154
rsb_get_node(device_t bus, device_t dev)
155
{
156
return (ofw_bus_get_node(bus));
157
}
158
159
static int
160
rsb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
161
{
162
struct rsb_softc *sc;
163
int retry;
164
165
sc = device_get_softc(dev);
166
167
RSB_LOCK(sc);
168
169
/* Write soft-reset bit and wait for it to self-clear. */
170
RSB_WRITE(sc, RSB_CTRL, SOFT_RESET);
171
for (retry = RSB_RESET_RETRY; retry > 0; retry--)
172
if ((RSB_READ(sc, RSB_CTRL) & SOFT_RESET) == 0)
173
break;
174
175
RSB_UNLOCK(sc);
176
177
if (retry == 0) {
178
device_printf(dev, "soft reset timeout\n");
179
return (ETIMEDOUT);
180
}
181
182
return (IIC_ENOADDR);
183
}
184
185
static uint32_t
186
rsb_encode(const uint8_t *buf, u_int len, u_int off)
187
{
188
uint32_t val;
189
u_int n;
190
191
val = 0;
192
for (n = off; n < MIN(len, 4 + off); n++)
193
val |= ((uint32_t)buf[n] << ((n - off) * NBBY));
194
195
return val;
196
}
197
198
static void
199
rsb_decode(const uint32_t val, uint8_t *buf, u_int len, u_int off)
200
{
201
u_int n;
202
203
for (n = off; n < MIN(len, 4 + off); n++)
204
buf[n] = (val >> ((n - off) * NBBY)) & 0xff;
205
}
206
207
static int
208
rsb_start(device_t dev)
209
{
210
struct rsb_softc *sc;
211
int error, retry;
212
213
sc = device_get_softc(dev);
214
215
RSB_ASSERT_LOCKED(sc);
216
217
/* Start the transfer */
218
RSB_WRITE(sc, RSB_CTRL, GLOBAL_INT_ENB | START_TRANS);
219
220
/* Wait for transfer to complete */
221
error = ETIMEDOUT;
222
for (retry = RSB_I2C_TIMEOUT; retry > 0; retry--) {
223
sc->status |= RSB_READ(sc, RSB_INTS);
224
if ((sc->status & INT_TRANS_OVER) != 0) {
225
error = 0;
226
break;
227
}
228
DELAY((1000 * hz) / RSB_I2C_TIMEOUT);
229
}
230
if (error == 0 && (sc->status & INT_TRANS_OVER) == 0) {
231
device_printf(dev, "transfer error, status 0x%08x\n",
232
sc->status);
233
error = EIO;
234
}
235
236
return (error);
237
238
}
239
240
static int
241
rsb_set_rta(device_t dev, uint16_t addr)
242
{
243
struct rsb_softc *sc;
244
uint8_t rta;
245
int i;
246
247
sc = device_get_softc(dev);
248
249
RSB_ASSERT_LOCKED(sc);
250
251
/* Lookup run-time address for given device address */
252
for (rta = 0, i = 0; rsb_rtamap[i].rta != 0; i++)
253
if (rsb_rtamap[i].addr == addr) {
254
rta = rsb_rtamap[i].rta;
255
break;
256
}
257
if (rta == 0) {
258
device_printf(dev, "RTA not known for address %#x\n", addr);
259
return (ENXIO);
260
}
261
262
/* Set run-time address */
263
RSB_WRITE(sc, RSB_INTS, RSB_READ(sc, RSB_INTS));
264
RSB_WRITE(sc, RSB_DAR, (addr << DAR_DA_SHIFT) | (rta << DAR_RTA_SHIFT));
265
RSB_WRITE(sc, RSB_CMD, CMD_SRTA);
266
267
return (rsb_start(dev));
268
}
269
270
static int
271
rsb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
272
{
273
struct rsb_softc *sc;
274
uint32_t daddr[2], data[2], dlen;
275
uint16_t device_addr;
276
uint8_t cmd;
277
int error;
278
279
sc = device_get_softc(dev);
280
281
/*
282
* P2WI and RSB are not really I2C or SMBus controllers, so there are
283
* some restrictions imposed by the driver.
284
*
285
* Transfers must contain exactly two messages. The first is always
286
* a write, containing a single data byte offset. Data will either
287
* be read from or written to the corresponding data byte in the
288
* second message. The slave address in both messages must be the
289
* same.
290
*/
291
if (nmsgs != 2 || (msgs[0].flags & IIC_M_RD) == IIC_M_RD ||
292
(msgs[0].slave >> 1) != (msgs[1].slave >> 1) ||
293
msgs[0].len != 1 || msgs[1].len > RSB_MAXLEN)
294
return (EINVAL);
295
296
/* The RSB controller can read or write 1, 2, or 4 bytes at a time. */
297
if (sc->type == A23_RSB) {
298
if ((msgs[1].flags & IIC_M_RD) != 0) {
299
switch (msgs[1].len) {
300
case 1:
301
cmd = CMD_RD8;
302
break;
303
case 2:
304
cmd = CMD_RD16;
305
break;
306
case 4:
307
cmd = CMD_RD32;
308
break;
309
default:
310
return (EINVAL);
311
}
312
} else {
313
switch (msgs[1].len) {
314
case 1:
315
cmd = CMD_WR8;
316
break;
317
case 2:
318
cmd = CMD_WR16;
319
break;
320
case 4:
321
cmd = CMD_WR32;
322
break;
323
default:
324
return (EINVAL);
325
}
326
}
327
}
328
329
RSB_LOCK(sc);
330
while (sc->busy)
331
mtx_sleep(sc, &sc->mtx, 0, "i2cbuswait", 0);
332
sc->busy = 1;
333
sc->status = 0;
334
335
/* Select current run-time address if necessary */
336
if (sc->type == A23_RSB) {
337
device_addr = msgs[0].slave >> 1;
338
if (sc->cur_addr != device_addr) {
339
error = rsb_set_rta(dev, device_addr);
340
if (error != 0)
341
goto done;
342
sc->cur_addr = device_addr;
343
sc->status = 0;
344
}
345
}
346
347
/* Clear interrupt status */
348
RSB_WRITE(sc, RSB_INTS, RSB_READ(sc, RSB_INTS));
349
350
/* Program data access address registers */
351
daddr[0] = rsb_encode(msgs[0].buf, msgs[0].len, 0);
352
RSB_WRITE(sc, RSB_DADDR0, daddr[0]);
353
354
/* Write data */
355
if ((msgs[1].flags & IIC_M_RD) == 0) {
356
data[0] = rsb_encode(msgs[1].buf, msgs[1].len, 0);
357
RSB_WRITE(sc, RSB_DATA0, data[0]);
358
}
359
360
/* Set command type for RSB */
361
if (sc->type == A23_RSB)
362
RSB_WRITE(sc, RSB_CMD, cmd);
363
364
/* Program data length register and transfer direction */
365
dlen = msgs[0].len - 1;
366
if ((msgs[1].flags & IIC_M_RD) == IIC_M_RD)
367
dlen |= DLEN_READ;
368
RSB_WRITE(sc, RSB_DLEN, dlen);
369
370
/* Start transfer */
371
error = rsb_start(dev);
372
if (error != 0)
373
goto done;
374
375
/* Read data */
376
if ((msgs[1].flags & IIC_M_RD) == IIC_M_RD) {
377
data[0] = RSB_READ(sc, RSB_DATA0);
378
rsb_decode(data[0], msgs[1].buf, msgs[1].len, 0);
379
}
380
381
done:
382
sc->msg = NULL;
383
sc->busy = 0;
384
wakeup(sc);
385
RSB_UNLOCK(sc);
386
387
return (error);
388
}
389
390
static int
391
rsb_probe(device_t dev)
392
{
393
if (!ofw_bus_status_okay(dev))
394
return (ENXIO);
395
396
switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
397
case A23_RSB:
398
device_set_desc(dev, "Allwinner RSB");
399
break;
400
case A31_P2WI:
401
device_set_desc(dev, "Allwinner P2WI");
402
break;
403
default:
404
return (ENXIO);
405
}
406
407
return (BUS_PROBE_DEFAULT);
408
}
409
410
static int
411
rsb_attach(device_t dev)
412
{
413
struct rsb_softc *sc;
414
int error;
415
416
sc = device_get_softc(dev);
417
mtx_init(&sc->mtx, device_get_nameunit(dev), "rsb", MTX_DEF);
418
419
sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
420
421
if (clk_get_by_ofw_index(dev, 0, 0, &sc->clk) == 0) {
422
error = clk_enable(sc->clk);
423
if (error != 0) {
424
device_printf(dev, "cannot enable clock\n");
425
goto fail;
426
}
427
}
428
if (hwreset_get_by_ofw_idx(dev, 0, 0, &sc->rst) == 0) {
429
error = hwreset_deassert(sc->rst);
430
if (error != 0) {
431
device_printf(dev, "cannot de-assert reset\n");
432
goto fail;
433
}
434
}
435
436
if (bus_alloc_resources(dev, rsb_spec, &sc->res) != 0) {
437
device_printf(dev, "cannot allocate resources for device\n");
438
error = ENXIO;
439
goto fail;
440
}
441
442
/* Set the PMIC into RSB mode as ATF might have leave it in I2C mode */
443
RSB_WRITE(sc, RSB_PMCR, RSB_PMCR_REG(PMIC_MODE_REG) | RSB_PMCR_DATA(PMIC_MODE_RSB) | RSB_PMCR_START);
444
445
sc->iicbus = device_add_child(dev, "iicbus", DEVICE_UNIT_ANY);
446
if (sc->iicbus == NULL) {
447
device_printf(dev, "cannot add iicbus child device\n");
448
error = ENXIO;
449
goto fail;
450
}
451
452
bus_attach_children(dev);
453
454
return (0);
455
456
fail:
457
bus_release_resources(dev, rsb_spec, &sc->res);
458
if (sc->rst != NULL)
459
hwreset_release(sc->rst);
460
if (sc->clk != NULL)
461
clk_release(sc->clk);
462
mtx_destroy(&sc->mtx);
463
return (error);
464
}
465
466
static device_method_t rsb_methods[] = {
467
/* Device interface */
468
DEVMETHOD(device_probe, rsb_probe),
469
DEVMETHOD(device_attach, rsb_attach),
470
471
/* Bus interface */
472
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
473
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
474
DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
475
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
476
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
477
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
478
DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
479
DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
480
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
481
482
/* OFW methods */
483
DEVMETHOD(ofw_bus_get_node, rsb_get_node),
484
485
/* iicbus interface */
486
DEVMETHOD(iicbus_callback, iicbus_null_callback),
487
DEVMETHOD(iicbus_reset, rsb_reset),
488
DEVMETHOD(iicbus_transfer, rsb_transfer),
489
490
DEVMETHOD_END
491
};
492
493
static driver_t rsb_driver = {
494
"iichb",
495
rsb_methods,
496
sizeof(struct rsb_softc),
497
};
498
499
EARLY_DRIVER_MODULE(iicbus, rsb, iicbus_driver, 0, 0,
500
BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE);
501
EARLY_DRIVER_MODULE(rsb, simplebus, rsb_driver, 0, 0,
502
BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE);
503
MODULE_VERSION(rsb, 1);
504
MODULE_DEPEND(rsb, iicbus, 1, 1, 1);
505
SIMPLEBUS_PNP_INFO(compat_data);
506
507