1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2018, 2019 Rubicon Communications, LLC (Netgate) 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 /* 32 * Driver for Armada 37x0 i2c controller. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/lock.h> 39 #include <sys/module.h> 40 #include <sys/mutex.h> 41 #include <sys/bus.h> 42 #include <machine/resource.h> 43 #include <machine/bus.h> 44 #include <sys/rman.h> 45 #include <sys/sysctl.h> 46 47 #include <dev/iicbus/iicbus.h> 48 #include <dev/iicbus/iiconf.h> 49 #include <dev/ofw/ofw_bus.h> 50 #include <dev/ofw/ofw_bus_subr.h> 51 52 #include <arm/mv/a37x0_iicreg.h> 53 54 #include "iicbus_if.h" 55 56 struct a37x0_iic_softc { 57 boolean_t sc_fast_mode; 58 bus_space_tag_t sc_bst; 59 bus_space_handle_t sc_bsh; 60 device_t sc_dev; 61 device_t sc_iicbus; 62 struct mtx sc_mtx; 63 struct resource *sc_mem_res; 64 struct resource *sc_irq_res; 65 void *sc_intrhand; 66 }; 67 68 #define A37X0_IIC_WRITE(_sc, _off, _val) \ 69 bus_space_write_4((_sc)->sc_bst, (_sc)->sc_bsh, _off, _val) 70 #define A37X0_IIC_READ(_sc, _off) \ 71 bus_space_read_4((_sc)->sc_bst, (_sc)->sc_bsh, _off) 72 #define A37X0_IIC_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 73 #define A37X0_IIC_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 74 75 static struct ofw_compat_data compat_data[] = { 76 { "marvell,armada-3700-i2c", 1 }, 77 { NULL, 0 } 78 }; 79 80 #undef A37x0_IIC_DEBUG 81 82 static void a37x0_iic_intr(void *); 83 static int a37x0_iic_detach(device_t); 84 85 static void 86 a37x0_iic_rmw(struct a37x0_iic_softc *sc, uint32_t off, uint32_t mask, 87 uint32_t value) 88 { 89 uint32_t reg; 90 91 mtx_assert(&sc->sc_mtx, MA_OWNED); 92 reg = A37X0_IIC_READ(sc, off); 93 reg &= ~mask; 94 reg |= value; 95 A37X0_IIC_WRITE(sc, off, reg); 96 } 97 98 static int 99 a37x0_iic_wait_clear(struct a37x0_iic_softc *sc, uint32_t mask) 100 { 101 int timeout; 102 uint32_t status; 103 104 mtx_assert(&sc->sc_mtx, MA_OWNED); 105 timeout = 1000; 106 do { 107 DELAY(10); 108 status = A37X0_IIC_READ(sc, A37X0_IIC_ISR); 109 if (--timeout == 0) 110 return (0); 111 } while ((status & mask) != 0); 112 113 return (1); 114 } 115 116 static int 117 a37x0_iic_wait_set(struct a37x0_iic_softc *sc, uint32_t mask) 118 { 119 int timeout; 120 uint32_t status; 121 122 mtx_assert(&sc->sc_mtx, MA_OWNED); 123 timeout = 1000; 124 do { 125 DELAY(10); 126 status = A37X0_IIC_READ(sc, A37X0_IIC_ISR); 127 if (--timeout == 0) 128 return (0); 129 } while ((status & mask) != mask); 130 131 return (1); 132 } 133 134 #ifdef A37x0_IIC_DEBUG 135 static void 136 a37x0_iic_regdump(struct a37x0_iic_softc *sc) 137 { 138 139 mtx_assert(&sc->sc_mtx, MA_OWNED); 140 printf("%s: IBMR: %#x\n", __func__, A37X0_IIC_READ(sc, A37X0_IIC_IBMR)); 141 printf("%s: ICR: %#x\n", __func__, A37X0_IIC_READ(sc, A37X0_IIC_ICR)); 142 printf("%s: ISR: %#x\n", __func__, A37X0_IIC_READ(sc, A37X0_IIC_ISR)); 143 } 144 #endif 145 146 static void 147 a37x0_iic_reset(struct a37x0_iic_softc *sc) 148 { 149 uint32_t mode, reg; 150 151 mtx_assert(&sc->sc_mtx, MA_OWNED); 152 153 /* Disable the controller. */ 154 reg = A37X0_IIC_READ(sc, A37X0_IIC_ICR); 155 mode = reg & ICR_MODE_MASK; 156 A37X0_IIC_WRITE(sc, A37X0_IIC_ICR, reg & ~ICR_IUE); 157 A37X0_IIC_WRITE(sc, A37X0_IIC_ICR, reg | ICR_UR); 158 DELAY(100); 159 A37X0_IIC_WRITE(sc, A37X0_IIC_ICR, reg & ~ICR_IUE); 160 161 /* Enable the controller. */ 162 reg = A37X0_IIC_READ(sc, A37X0_IIC_ICR); 163 reg |= mode | ICR_IUE | ICR_GCD | ICR_SCLE; 164 A37X0_IIC_WRITE(sc, A37X0_IIC_ICR, reg); 165 #ifdef A37x0_IIC_DEBUG 166 a37x0_iic_regdump(sc); 167 #endif 168 } 169 170 static int 171 a37x0_iic_probe(device_t dev) 172 { 173 174 if (!ofw_bus_status_okay(dev)) 175 return (ENXIO); 176 177 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) 178 return (ENXIO); 179 180 device_set_desc(dev, "Marvell Armada 37x0 IIC controller"); 181 182 return (BUS_PROBE_DEFAULT); 183 } 184 185 static int 186 a37x0_iic_attach(device_t dev) 187 { 188 int rid; 189 phandle_t node; 190 struct a37x0_iic_softc *sc; 191 192 sc = device_get_softc(dev); 193 sc->sc_dev = dev; 194 195 rid = 0; 196 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 197 RF_ACTIVE); 198 if (!sc->sc_mem_res) { 199 device_printf(dev, "cannot allocate memory window\n"); 200 return (ENXIO); 201 } 202 203 sc->sc_bst = rman_get_bustag(sc->sc_mem_res); 204 sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); 205 206 rid = 0; 207 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 208 RF_ACTIVE | RF_SHAREABLE); 209 if (!sc->sc_irq_res) { 210 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 211 device_printf(dev, "cannot allocate interrupt\n"); 212 return (ENXIO); 213 } 214 215 /* Hook up our interrupt handler. */ 216 if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, 217 NULL, a37x0_iic_intr, sc, &sc->sc_intrhand)) { 218 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 219 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 220 device_printf(dev, "cannot setup the interrupt handler\n"); 221 return (ENXIO); 222 } 223 224 mtx_init(&sc->sc_mtx, "a37x0_iic", NULL, MTX_DEF); 225 226 node = ofw_bus_get_node(dev); 227 if (OF_hasprop(node, "mrvl,i2c-fast-mode")) 228 sc->sc_fast_mode = true; 229 230 /* Enable the controller. */ 231 A37X0_IIC_LOCK(sc); 232 a37x0_iic_reset(sc); 233 A37X0_IIC_UNLOCK(sc); 234 235 sc->sc_iicbus = device_add_child(dev, "iicbus", -1); 236 if (sc->sc_iicbus == NULL) { 237 a37x0_iic_detach(dev); 238 return (ENXIO); 239 } 240 241 /* Probe and attach the iicbus. */ 242 return (bus_generic_attach(dev)); 243 } 244 245 static int 246 a37x0_iic_detach(device_t dev) 247 { 248 struct a37x0_iic_softc *sc; 249 250 bus_generic_detach(dev); 251 252 sc = device_get_softc(dev); 253 if (sc->sc_iicbus != NULL) 254 device_delete_child(dev, sc->sc_iicbus); 255 mtx_destroy(&sc->sc_mtx); 256 if (sc->sc_intrhand) 257 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand); 258 if (sc->sc_irq_res) 259 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 260 if (sc->sc_mem_res) 261 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 262 263 return (0); 264 } 265 266 static void 267 a37x0_iic_intr(void *arg) 268 { 269 struct a37x0_iic_softc *sc; 270 uint32_t status; 271 272 /* Not used, the interrupts are not enabled. */ 273 sc = (struct a37x0_iic_softc *)arg; 274 A37X0_IIC_LOCK(sc); 275 status = A37X0_IIC_READ(sc, A37X0_IIC_ISR); 276 #ifdef A37x0_IIC_DEBUG 277 a37x0_iic_regdump(sc); 278 #endif 279 280 /* Clear pending interrrupts. */ 281 A37X0_IIC_WRITE(sc, A37X0_IIC_ISR, status); 282 A37X0_IIC_UNLOCK(sc); 283 } 284 285 static int 286 a37x0_iic_stop(device_t dev) 287 { 288 struct a37x0_iic_softc *sc; 289 uint32_t reg; 290 291 sc = device_get_softc(dev); 292 A37X0_IIC_LOCK(sc); 293 /* Clear the STOP condition. */ 294 reg = A37X0_IIC_READ(sc, A37X0_IIC_ICR); 295 if (reg & (ICR_ACKNAK | ICR_STOP)) { 296 reg &= ~(ICR_START | ICR_ACKNAK | ICR_STOP); 297 A37X0_IIC_WRITE(sc, A37X0_IIC_ICR, reg); 298 } 299 /* Clear interrupts. */ 300 reg = A37X0_IIC_READ(sc, A37X0_IIC_ISR); 301 A37X0_IIC_WRITE(sc, A37X0_IIC_ISR, reg); 302 A37X0_IIC_UNLOCK(sc); 303 304 return (IIC_NOERR); 305 } 306 307 static int 308 a37x0_iic_start(device_t dev, u_char slave, int timeout) 309 { 310 int rv; 311 struct a37x0_iic_softc *sc; 312 uint32_t reg, status; 313 314 sc = device_get_softc(dev); 315 A37X0_IIC_LOCK(sc); 316 317 /* Wait for the bus to be free before start a transaction. */ 318 if (a37x0_iic_wait_clear(sc, ISR_IBB) == 0) { 319 A37X0_IIC_UNLOCK(sc); 320 return (IIC_ETIMEOUT); 321 } 322 323 /* Write the slave address. */ 324 A37X0_IIC_WRITE(sc, A37X0_IIC_IDBR, slave); 325 326 /* Send Start condition (with slave address). */ 327 reg = A37X0_IIC_READ(sc, A37X0_IIC_ICR); 328 reg &= ~(ICR_STOP | ICR_ACKNAK); 329 A37X0_IIC_WRITE(sc, A37X0_IIC_ICR, reg | ICR_START | ICR_TB); 330 331 rv = IIC_NOERR; 332 if (a37x0_iic_wait_set(sc, ISR_ITE) == 0) 333 rv = IIC_ETIMEOUT; 334 if (rv == IIC_NOERR) { 335 status = A37X0_IIC_READ(sc, A37X0_IIC_ISR); 336 A37X0_IIC_WRITE(sc, A37X0_IIC_ISR, status | ISR_ITE); 337 if (a37x0_iic_wait_clear(sc, ISR_ACKNAK) == 0) 338 rv = IIC_ENOACK; 339 } 340 341 A37X0_IIC_UNLOCK(sc); 342 if (rv != IIC_NOERR) 343 a37x0_iic_stop(dev); 344 345 return (rv); 346 } 347 348 static int 349 a37x0_iic_bus_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) 350 { 351 struct a37x0_iic_softc *sc; 352 uint32_t busfreq; 353 354 sc = device_get_softc(dev); 355 A37X0_IIC_LOCK(sc); 356 a37x0_iic_reset(sc); 357 if (sc->sc_iicbus == NULL) 358 busfreq = 100000; 359 else 360 busfreq = IICBUS_GET_FREQUENCY(sc->sc_iicbus, speed); 361 a37x0_iic_rmw(sc, A37X0_IIC_ICR, ICR_MODE_MASK, 362 (busfreq > 100000) ? ICR_FAST_MODE : 0); 363 A37X0_IIC_UNLOCK(sc); 364 365 return (IIC_ENOADDR); 366 } 367 368 static int 369 a37x0_iic_read(device_t dev, char *buf, int len, int *read, int last, int delay) 370 { 371 int rv; 372 struct a37x0_iic_softc *sc; 373 uint32_t reg, status; 374 375 sc = device_get_softc(dev); 376 A37X0_IIC_LOCK(sc); 377 reg = A37X0_IIC_READ(sc, A37X0_IIC_ISR); 378 if ((reg & (ISR_UB | ISR_IBB)) != ISR_UB) { 379 A37X0_IIC_UNLOCK(sc); 380 return (IIC_EBUSERR); 381 } 382 383 *read = 0; 384 rv = IIC_NOERR; 385 while (*read < len) { 386 reg = A37X0_IIC_READ(sc, A37X0_IIC_ICR); 387 reg &= ~(ICR_START | ICR_STOP | ICR_ACKNAK); 388 if (*read == len - 1) 389 reg |= ICR_ACKNAK | ICR_STOP; 390 A37X0_IIC_WRITE(sc, A37X0_IIC_ICR, reg | ICR_TB); 391 if (a37x0_iic_wait_set(sc, ISR_IRF) == 0) { 392 rv = IIC_ETIMEOUT; 393 break; 394 } 395 *buf++ = A37X0_IIC_READ(sc, A37X0_IIC_IDBR); 396 (*read)++; 397 status = A37X0_IIC_READ(sc, A37X0_IIC_ISR); 398 A37X0_IIC_WRITE(sc, A37X0_IIC_ISR, status | ISR_IRF); 399 } 400 A37X0_IIC_UNLOCK(sc); 401 402 return (rv); 403 } 404 405 static int 406 a37x0_iic_write(device_t dev, const char *buf, int len, int *sent, int timeout) 407 { 408 int rv; 409 struct a37x0_iic_softc *sc; 410 uint32_t reg, status; 411 412 sc = device_get_softc(dev); 413 A37X0_IIC_LOCK(sc); 414 reg = A37X0_IIC_READ(sc, A37X0_IIC_ISR); 415 if ((reg & (ISR_UB | ISR_IBB)) != ISR_UB) { 416 A37X0_IIC_UNLOCK(sc); 417 return (IIC_EBUSERR); 418 } 419 420 rv = IIC_NOERR; 421 *sent = 0; 422 while (*sent < len) { 423 A37X0_IIC_WRITE(sc, A37X0_IIC_IDBR, *buf++); 424 reg = A37X0_IIC_READ(sc, A37X0_IIC_ICR); 425 reg &= ~(ICR_START | ICR_STOP | ICR_ACKNAK); 426 if (*sent == len - 1) 427 reg |= ICR_STOP; 428 A37X0_IIC_WRITE(sc, A37X0_IIC_ICR, reg | ICR_TB); 429 if (a37x0_iic_wait_set(sc, ISR_ITE) == 0) { 430 rv = IIC_ETIMEOUT; 431 break; 432 } 433 (*sent)++; 434 status = A37X0_IIC_READ(sc, A37X0_IIC_ISR); 435 A37X0_IIC_WRITE(sc, A37X0_IIC_ISR, status | ISR_ITE); 436 if (a37x0_iic_wait_clear(sc, ISR_ACKNAK) == 0) { 437 rv = IIC_ENOACK; 438 break; 439 } 440 } 441 A37X0_IIC_UNLOCK(sc); 442 443 return (rv); 444 } 445 446 static phandle_t 447 a37x0_iic_get_node(device_t bus, device_t dev) 448 { 449 450 return (ofw_bus_get_node(bus)); 451 } 452 453 static device_method_t a37x0_iic_methods[] = { 454 /* Device interface */ 455 DEVMETHOD(device_probe, a37x0_iic_probe), 456 DEVMETHOD(device_attach, a37x0_iic_attach), 457 DEVMETHOD(device_detach, a37x0_iic_detach), 458 459 /* iicbus interface */ 460 DEVMETHOD(iicbus_reset, a37x0_iic_bus_reset), 461 DEVMETHOD(iicbus_callback, iicbus_null_callback), 462 DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), 463 DEVMETHOD(iicbus_repeated_start, a37x0_iic_start), 464 DEVMETHOD(iicbus_start, a37x0_iic_start), 465 DEVMETHOD(iicbus_stop, a37x0_iic_stop), 466 DEVMETHOD(iicbus_read, a37x0_iic_read), 467 DEVMETHOD(iicbus_write, a37x0_iic_write), 468 469 /* ofw_bus interface */ 470 DEVMETHOD(ofw_bus_get_node, a37x0_iic_get_node), 471 472 DEVMETHOD_END 473 }; 474 475 static driver_t a37x0_iic_driver = { 476 "iichb", 477 a37x0_iic_methods, 478 sizeof(struct a37x0_iic_softc), 479 }; 480 481 DRIVER_MODULE(iicbus, a37x0_iic, iicbus_driver, 0, 0); 482 DRIVER_MODULE(a37x0_iic, simplebus, a37x0_iic_driver, 0, 0); 483