Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/allwinner/aw_rsb.c
107242 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
#define H616_P2WI 3
102
103
static struct ofw_compat_data compat_data[] = {
104
{ "allwinner,sun6i-a31-p2wi", A31_P2WI },
105
{ "allwinner,sun8i-a23-rsb", A23_RSB },
106
{ "allwinner,sun50i-h616-rsb", H616_P2WI },
107
{ NULL, 0 }
108
};
109
110
static struct resource_spec rsb_spec[] = {
111
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
112
{ -1, 0 }
113
};
114
115
/*
116
* Device address to Run-time address mappings.
117
*
118
* Run-time address (RTA) is an 8-bit value used to address the device during
119
* a read or write transaction. The following are valid RTAs:
120
* 0x17 0x2d 0x3a 0x4e 0x59 0x63 0x74 0x8b 0x9c 0xa6 0xb1 0xc5 0xd2 0xe8 0xff
121
*
122
* Allwinner uses RTA 0x2d for the primary PMIC, 0x3a for the secondary PMIC,
123
* and 0x4e for the peripheral IC (where applicable).
124
*/
125
static const struct {
126
uint16_t addr;
127
uint8_t rta;
128
} rsb_rtamap[] = {
129
{ .addr = RSB_ADDR_PMIC_PRIMARY, .rta = 0x2d },
130
{ .addr = RSB_ADDR_PMIC_SECONDARY, .rta = 0x3a },
131
{ .addr = RSB_ADDR_PERIPH_IC, .rta = 0x4e },
132
{ .addr = 0, .rta = 0 }
133
};
134
135
struct rsb_softc {
136
struct resource *res;
137
struct mtx mtx;
138
clk_t clk;
139
hwreset_t rst;
140
device_t iicbus;
141
int busy;
142
uint32_t status;
143
uint16_t cur_addr;
144
int type;
145
146
struct iic_msg *msg;
147
};
148
149
#define RSB_LOCK(sc) mtx_lock(&(sc)->mtx)
150
#define RSB_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
151
#define RSB_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED)
152
#define RSB_READ(sc, reg) bus_read_4((sc)->res, (reg))
153
#define RSB_WRITE(sc, reg, val) bus_write_4((sc)->res, (reg), (val))
154
155
static phandle_t
156
rsb_get_node(device_t bus, device_t dev)
157
{
158
return (ofw_bus_get_node(bus));
159
}
160
161
static int
162
rsb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
163
{
164
struct rsb_softc *sc;
165
int retry;
166
167
sc = device_get_softc(dev);
168
169
RSB_LOCK(sc);
170
171
/* Write soft-reset bit and wait for it to self-clear. */
172
RSB_WRITE(sc, RSB_CTRL, SOFT_RESET);
173
for (retry = RSB_RESET_RETRY; retry > 0; retry--)
174
if ((RSB_READ(sc, RSB_CTRL) & SOFT_RESET) == 0)
175
break;
176
177
RSB_UNLOCK(sc);
178
179
if (retry == 0) {
180
device_printf(dev, "soft reset timeout\n");
181
return (ETIMEDOUT);
182
}
183
184
return (IIC_ENOADDR);
185
}
186
187
static uint32_t
188
rsb_encode(const uint8_t *buf, u_int len, u_int off)
189
{
190
uint32_t val;
191
u_int n;
192
193
val = 0;
194
for (n = off; n < MIN(len, 4 + off); n++)
195
val |= ((uint32_t)buf[n] << ((n - off) * NBBY));
196
197
return val;
198
}
199
200
static void
201
rsb_decode(const uint32_t val, uint8_t *buf, u_int len, u_int off)
202
{
203
u_int n;
204
205
for (n = off; n < MIN(len, 4 + off); n++)
206
buf[n] = (val >> ((n - off) * NBBY)) & 0xff;
207
}
208
209
static int
210
rsb_start(device_t dev)
211
{
212
struct rsb_softc *sc;
213
int error, retry;
214
215
sc = device_get_softc(dev);
216
217
RSB_ASSERT_LOCKED(sc);
218
219
/* Start the transfer */
220
RSB_WRITE(sc, RSB_CTRL, GLOBAL_INT_ENB | START_TRANS);
221
222
/* Wait for transfer to complete */
223
error = ETIMEDOUT;
224
for (retry = RSB_I2C_TIMEOUT; retry > 0; retry--) {
225
sc->status |= RSB_READ(sc, RSB_INTS);
226
if ((sc->status & INT_TRANS_OVER) != 0) {
227
error = 0;
228
break;
229
}
230
DELAY((1000 * hz) / RSB_I2C_TIMEOUT);
231
}
232
if (error == 0 && (sc->status & INT_TRANS_OVER) == 0) {
233
device_printf(dev, "transfer error, status 0x%08x\n",
234
sc->status);
235
error = EIO;
236
}
237
238
return (error);
239
240
}
241
242
static int
243
rsb_set_rta(device_t dev, uint16_t addr)
244
{
245
struct rsb_softc *sc;
246
uint8_t rta;
247
int i;
248
249
sc = device_get_softc(dev);
250
251
RSB_ASSERT_LOCKED(sc);
252
253
/* Lookup run-time address for given device address */
254
for (rta = 0, i = 0; rsb_rtamap[i].rta != 0; i++)
255
if (rsb_rtamap[i].addr == addr) {
256
rta = rsb_rtamap[i].rta;
257
break;
258
}
259
if (rta == 0) {
260
device_printf(dev, "RTA not known for address %#x\n", addr);
261
return (ENXIO);
262
}
263
264
/* Set run-time address */
265
RSB_WRITE(sc, RSB_INTS, RSB_READ(sc, RSB_INTS));
266
RSB_WRITE(sc, RSB_DAR, (addr << DAR_DA_SHIFT) | (rta << DAR_RTA_SHIFT));
267
RSB_WRITE(sc, RSB_CMD, CMD_SRTA);
268
269
return (rsb_start(dev));
270
}
271
272
static int
273
rsb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
274
{
275
struct rsb_softc *sc;
276
uint32_t daddr[2], data[2], dlen;
277
uint16_t device_addr;
278
uint8_t cmd;
279
int error;
280
281
sc = device_get_softc(dev);
282
283
/*
284
* P2WI and RSB are not really I2C or SMBus controllers, so there are
285
* some restrictions imposed by the driver.
286
*
287
* Transfers must contain exactly two messages. The first is always
288
* a write, containing a single data byte offset. Data will either
289
* be read from or written to the corresponding data byte in the
290
* second message. The slave address in both messages must be the
291
* same.
292
*/
293
if (nmsgs != 2 || (msgs[0].flags & IIC_M_RD) == IIC_M_RD ||
294
(msgs[0].slave >> 1) != (msgs[1].slave >> 1) ||
295
msgs[0].len != 1 || msgs[1].len > RSB_MAXLEN)
296
return (EINVAL);
297
298
/* The RSB controller can read or write 1, 2, or 4 bytes at a time. */
299
if (sc->type == A23_RSB) {
300
if ((msgs[1].flags & IIC_M_RD) != 0) {
301
switch (msgs[1].len) {
302
case 1:
303
cmd = CMD_RD8;
304
break;
305
case 2:
306
cmd = CMD_RD16;
307
break;
308
case 4:
309
cmd = CMD_RD32;
310
break;
311
default:
312
return (EINVAL);
313
}
314
} else {
315
switch (msgs[1].len) {
316
case 1:
317
cmd = CMD_WR8;
318
break;
319
case 2:
320
cmd = CMD_WR16;
321
break;
322
case 4:
323
cmd = CMD_WR32;
324
break;
325
default:
326
return (EINVAL);
327
}
328
}
329
}
330
331
RSB_LOCK(sc);
332
while (sc->busy)
333
mtx_sleep(sc, &sc->mtx, 0, "i2cbuswait", 0);
334
sc->busy = 1;
335
sc->status = 0;
336
337
/* Select current run-time address if necessary */
338
if (sc->type == A23_RSB) {
339
device_addr = msgs[0].slave >> 1;
340
if (sc->cur_addr != device_addr) {
341
error = rsb_set_rta(dev, device_addr);
342
if (error != 0)
343
goto done;
344
sc->cur_addr = device_addr;
345
sc->status = 0;
346
}
347
}
348
349
/* Clear interrupt status */
350
RSB_WRITE(sc, RSB_INTS, RSB_READ(sc, RSB_INTS));
351
352
/* Program data access address registers */
353
daddr[0] = rsb_encode(msgs[0].buf, msgs[0].len, 0);
354
RSB_WRITE(sc, RSB_DADDR0, daddr[0]);
355
356
/* Write data */
357
if ((msgs[1].flags & IIC_M_RD) == 0) {
358
data[0] = rsb_encode(msgs[1].buf, msgs[1].len, 0);
359
RSB_WRITE(sc, RSB_DATA0, data[0]);
360
}
361
362
/* Set command type for RSB */
363
if (sc->type == A23_RSB)
364
RSB_WRITE(sc, RSB_CMD, cmd);
365
366
/* Program data length register and transfer direction */
367
dlen = msgs[0].len - 1;
368
if ((msgs[1].flags & IIC_M_RD) == IIC_M_RD)
369
dlen |= DLEN_READ;
370
RSB_WRITE(sc, RSB_DLEN, dlen);
371
372
/* Start transfer */
373
error = rsb_start(dev);
374
if (error != 0)
375
goto done;
376
377
/* Read data */
378
if ((msgs[1].flags & IIC_M_RD) == IIC_M_RD) {
379
data[0] = RSB_READ(sc, RSB_DATA0);
380
rsb_decode(data[0], msgs[1].buf, msgs[1].len, 0);
381
}
382
383
done:
384
sc->msg = NULL;
385
sc->busy = 0;
386
wakeup(sc);
387
RSB_UNLOCK(sc);
388
389
return (error);
390
}
391
392
static int
393
rsb_probe(device_t dev)
394
{
395
if (!ofw_bus_status_okay(dev))
396
return (ENXIO);
397
398
switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
399
case A23_RSB:
400
device_set_desc(dev, "Allwinner RSB");
401
break;
402
case A31_P2WI:
403
case H616_P2WI:
404
device_set_desc(dev, "Allwinner P2WI");
405
break;
406
default:
407
return (ENXIO);
408
}
409
410
return (BUS_PROBE_DEFAULT);
411
}
412
413
static int
414
rsb_attach(device_t dev)
415
{
416
struct rsb_softc *sc;
417
int error;
418
419
sc = device_get_softc(dev);
420
mtx_init(&sc->mtx, device_get_nameunit(dev), "rsb", MTX_DEF);
421
422
sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
423
424
if (clk_get_by_ofw_index(dev, 0, 0, &sc->clk) == 0) {
425
error = clk_enable(sc->clk);
426
if (error != 0) {
427
device_printf(dev, "cannot enable clock\n");
428
goto fail;
429
}
430
}
431
if (hwreset_get_by_ofw_idx(dev, 0, 0, &sc->rst) == 0) {
432
error = hwreset_deassert(sc->rst);
433
if (error != 0) {
434
device_printf(dev, "cannot de-assert reset\n");
435
goto fail;
436
}
437
}
438
439
if (bus_alloc_resources(dev, rsb_spec, &sc->res) != 0) {
440
device_printf(dev, "cannot allocate resources for device\n");
441
error = ENXIO;
442
goto fail;
443
}
444
445
/* Set the PMIC into RSB mode as ATF might have leave it in I2C mode */
446
RSB_WRITE(sc, RSB_PMCR, RSB_PMCR_REG(PMIC_MODE_REG) | RSB_PMCR_DATA(PMIC_MODE_RSB) | RSB_PMCR_START);
447
448
sc->iicbus = device_add_child(dev, "iicbus", DEVICE_UNIT_ANY);
449
if (sc->iicbus == NULL) {
450
device_printf(dev, "cannot add iicbus child device\n");
451
error = ENXIO;
452
goto fail;
453
}
454
455
bus_attach_children(dev);
456
457
return (0);
458
459
fail:
460
bus_release_resources(dev, rsb_spec, &sc->res);
461
if (sc->rst != NULL)
462
hwreset_release(sc->rst);
463
if (sc->clk != NULL)
464
clk_release(sc->clk);
465
mtx_destroy(&sc->mtx);
466
return (error);
467
}
468
469
static device_method_t rsb_methods[] = {
470
/* Device interface */
471
DEVMETHOD(device_probe, rsb_probe),
472
DEVMETHOD(device_attach, rsb_attach),
473
474
/* Bus interface */
475
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
476
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
477
DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
478
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
479
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
480
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
481
DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
482
DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
483
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
484
485
/* OFW methods */
486
DEVMETHOD(ofw_bus_get_node, rsb_get_node),
487
488
/* iicbus interface */
489
DEVMETHOD(iicbus_callback, iicbus_null_callback),
490
DEVMETHOD(iicbus_reset, rsb_reset),
491
DEVMETHOD(iicbus_transfer, rsb_transfer),
492
493
DEVMETHOD_END
494
};
495
496
static driver_t rsb_driver = {
497
"iichb",
498
rsb_methods,
499
sizeof(struct rsb_softc),
500
};
501
502
EARLY_DRIVER_MODULE(iicbus, rsb, iicbus_driver, 0, 0,
503
BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE);
504
EARLY_DRIVER_MODULE(rsb, simplebus, rsb_driver, 0, 0,
505
BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE);
506
MODULE_VERSION(rsb, 1);
507
MODULE_DEPEND(rsb, iicbus, 1, 1, 1);
508
SIMPLEBUS_PNP_INFO(compat_data);
509
510