File indexing completed on 2025-05-11 08:24:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <sys/cdefs.h>
0037 #ifndef __rtems__
0038 __FBSDID("$FreeBSD$");
0039 #endif
0040
0041 #include <sys/param.h>
0042 #ifndef __rtems__
0043 #include <sys/systm.h>
0044 #include <sys/kernel.h>
0045 #include <sys/module.h>
0046 #include <sys/bus.h>
0047 #include <sys/resource.h>
0048 #include <sys/rman.h>
0049 #include <sys/lock.h>
0050 #include <sys/mutex.h>
0051
0052 #include <machine/bus.h>
0053 #include <machine/resource.h>
0054
0055 #include <dev/ofw/openfirm.h>
0056 #include <dev/ofw/ofw_bus.h>
0057 #include <dev/ofw/ofw_bus_subr.h>
0058 #include <dev/fdt/fdt_pinctrl.h>
0059
0060 #include <arm/ti/omap4/omap4_scm_padconf.h>
0061 #else
0062 #include <ofw/ofw_compat.h>
0063 #endif
0064 #include <arm/ti/am335x/am335x_scm_padconf.h>
0065 #include <arm/ti/ti_cpuid.h>
0066 #ifndef __rtems__
0067 #include "ti_pinmux.h"
0068 #else
0069 #include <stdio.h>
0070 #include <string.h>
0071 #include <errno.h>
0072 #include <libfdt.h>
0073 #include <rtems/bspIo.h>
0074 #include <rtems/sysinit.h>
0075 #include <arm/ti/ti_pinmux.h>
0076 #endif
0077
0078 struct pincfg {
0079 uint32_t reg;
0080 uint32_t conf;
0081 };
0082
0083 #ifndef __rtems__
0084 static struct resource_spec ti_pinmux_res_spec[] = {
0085 { SYS_RES_MEMORY, 0, RF_ACTIVE },
0086 { -1, 0 }
0087 };
0088 #endif
0089
0090 #ifdef __rtems__
0091 struct ti_pinmux_softc {
0092 #ifndef __rtems__
0093 device_t sc_dev;
0094 struct resource * sc_res[4];
0095 bus_space_tag_t sc_bst;
0096 bus_space_handle_t sc_bsh;
0097 #else
0098 int sc_bst;
0099 uintptr_t sc_bsh;
0100 #endif
0101 };
0102 #endif
0103
0104 static struct ti_pinmux_softc *ti_pinmux_sc;
0105
0106 #ifndef __rtems__
0107 #define ti_pinmux_read_2(sc, reg) \
0108 bus_space_read_2((sc)->sc_bst, (sc)->sc_bsh, (reg))
0109 #define ti_pinmux_write_2(sc, reg, val) \
0110 bus_space_write_2((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
0111 #define ti_pinmux_read_4(sc, reg) \
0112 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
0113 #define ti_pinmux_write_4(sc, reg, val) \
0114 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
0115 #else
0116 static uint16_t
0117 ti_pinmux_read_2(struct ti_pinmux_softc *sc, uintptr_t ofs) {
0118 uintptr_t bsh = sc->sc_bsh;
0119 return *(uint16_t volatile *)(bsh + ofs);
0120 }
0121 static void
0122 ti_pinmux_write_2(struct ti_pinmux_softc *sc, uintptr_t ofs, uint16_t val) {
0123 uintptr_t bsh = sc->sc_bsh;
0124 uint16_t volatile *bsp = (uint16_t volatile *)(bsh + ofs);
0125 *bsp = val;
0126 }
0127 #endif
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 static const struct ti_pinmux_device *ti_pinmux_dev;
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 static const struct ti_pinmux_padconf*
0149 ti_pinmux_padconf_from_name(const char *ballname)
0150 {
0151 const struct ti_pinmux_padconf *padconf;
0152
0153 padconf = ti_pinmux_dev->padconf;
0154 while (padconf->ballname != NULL) {
0155 if (strcmp(ballname, padconf->ballname) == 0)
0156 return(padconf);
0157 padconf++;
0158 }
0159
0160 return (NULL);
0161 }
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177 static int
0178 ti_pinmux_padconf_set_internal(struct ti_pinmux_softc *sc,
0179 const struct ti_pinmux_padconf *padconf,
0180 const char *muxmode, unsigned int state)
0181 {
0182 unsigned int mode;
0183 uint16_t reg_val;
0184
0185
0186 reg_val = (uint16_t)(state & ti_pinmux_dev->padconf_sate_mask);
0187
0188
0189 for (mode = 0; mode < 8; mode++) {
0190 if ((padconf->muxmodes[mode] != NULL) &&
0191 (strcmp(padconf->muxmodes[mode], muxmode) == 0)) {
0192 break;
0193 }
0194 }
0195
0196
0197 if (mode >= 8) {
0198 #ifndef __rtems__
0199 printf("Invalid mode \"%s\"\n", muxmode);
0200 #else
0201 printk("Invalid mode \"%s\"\n", muxmode);
0202 #endif
0203 return (EINVAL);
0204 }
0205
0206
0207 reg_val |= (uint16_t)(mode & ti_pinmux_dev->padconf_muxmode_mask);
0208
0209 #ifndef __rtems__
0210 if (bootverbose)
0211 device_printf(sc->sc_dev, "setting internal %x for %s\n",
0212 reg_val, muxmode);
0213 #endif
0214
0215 ti_pinmux_write_2(sc, padconf->reg_off, reg_val);
0216
0217 return (0);
0218 }
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234 int
0235 ti_pinmux_padconf_set(const char *padname, const char *muxmode, unsigned int state)
0236 {
0237 const struct ti_pinmux_padconf *padconf;
0238
0239 if (!ti_pinmux_sc)
0240 return (ENXIO);
0241
0242
0243 padconf = ti_pinmux_padconf_from_name(padname);
0244 if (padconf == NULL)
0245 return (EINVAL);
0246
0247 return (ti_pinmux_padconf_set_internal(ti_pinmux_sc, padconf, muxmode, state));
0248 }
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264 int
0265 ti_pinmux_padconf_get(const char *padname, const char **muxmode,
0266 unsigned int *state)
0267 {
0268 const struct ti_pinmux_padconf *padconf;
0269 uint16_t reg_val;
0270
0271 if (!ti_pinmux_sc)
0272 return (ENXIO);
0273
0274
0275 padconf = ti_pinmux_padconf_from_name(padname);
0276 if (padconf == NULL)
0277 return (EINVAL);
0278
0279
0280 reg_val = ti_pinmux_read_2(ti_pinmux_sc, padconf->reg_off);
0281
0282
0283 if (state)
0284 *state = (reg_val & ti_pinmux_dev->padconf_sate_mask);
0285
0286
0287 if (muxmode)
0288 *muxmode = padconf->muxmodes[(reg_val & ti_pinmux_dev->padconf_muxmode_mask)];
0289
0290 return (0);
0291 }
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307 int
0308 ti_pinmux_padconf_set_gpiomode(uint32_t gpio, unsigned int state)
0309 {
0310 const struct ti_pinmux_padconf *padconf;
0311 uint16_t reg_val;
0312
0313 if (!ti_pinmux_sc)
0314 return (ENXIO);
0315
0316
0317 padconf = ti_pinmux_dev->padconf;
0318 while (padconf->ballname != NULL) {
0319 if (padconf->gpio_pin == gpio)
0320 break;
0321 padconf++;
0322 }
0323 if (padconf->ballname == NULL)
0324 return (EINVAL);
0325
0326
0327 reg_val = (uint16_t)(state & ti_pinmux_dev->padconf_sate_mask);
0328
0329
0330 reg_val |= (uint16_t)(padconf->gpio_mode & ti_pinmux_dev->padconf_muxmode_mask);
0331
0332
0333 ti_pinmux_write_2(ti_pinmux_sc, padconf->reg_off, reg_val);
0334
0335 return (0);
0336 }
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352 int
0353 ti_pinmux_padconf_get_gpiomode(uint32_t gpio, unsigned int *state)
0354 {
0355 const struct ti_pinmux_padconf *padconf;
0356 uint16_t reg_val;
0357
0358 if (!ti_pinmux_sc)
0359 return (ENXIO);
0360
0361
0362 padconf = ti_pinmux_dev->padconf;
0363 while (padconf->ballname != NULL) {
0364 if (padconf->gpio_pin == gpio)
0365 break;
0366 padconf++;
0367 }
0368 if (padconf->ballname == NULL)
0369 return (EINVAL);
0370
0371
0372 reg_val = ti_pinmux_read_2(ti_pinmux_sc, padconf->reg_off);
0373
0374
0375 if ((reg_val & ti_pinmux_dev->padconf_muxmode_mask) != padconf->gpio_mode)
0376 return (EINVAL);
0377
0378
0379 if (state)
0380 *state = (reg_val & ti_pinmux_dev->padconf_sate_mask);
0381
0382 return (0);
0383 }
0384
0385 static int
0386 #ifndef __rtems__
0387 ti_pinmux_configure_pins(device_t dev, phandle_t cfgxref)
0388 #else
0389 ti_pinmux_configure_pins(struct ti_pinmux_softc *sc, phandle_t cfgxref)
0390 #endif
0391 {
0392 struct pincfg *cfgtuples, *cfg;
0393 phandle_t cfgnode;
0394 int i, ntuples;
0395 #ifndef __rtems__
0396 static struct ti_pinmux_softc *sc;
0397
0398 sc = device_get_softc(dev);
0399 #endif
0400 cfgnode = OF_node_from_xref(cfgxref);
0401 ntuples = OF_getencprop_alloc_multi(cfgnode, "pinctrl-single,pins",
0402 sizeof(*cfgtuples), (void **)&cfgtuples);
0403
0404 if (ntuples < 0)
0405 return (ENOENT);
0406
0407 if (ntuples == 0)
0408 return (0);
0409
0410 for (i = 0, cfg = cfgtuples; i < ntuples; i++, cfg++) {
0411 #ifndef __rtems__
0412 if (bootverbose) {
0413 char name[32];
0414 OF_getprop(cfgnode, "name", &name, sizeof(name));
0415 printf("%16s: muxreg 0x%04x muxval 0x%02x\n",
0416 name, cfg->reg, cfg->conf);
0417 }
0418 #endif
0419
0420
0421 ti_pinmux_write_2(sc, cfg->reg, cfg->conf);
0422 }
0423
0424 OF_prop_free(cfgtuples);
0425
0426 return (0);
0427 }
0428
0429
0430
0431
0432
0433 #ifndef __rtems__
0434 static int
0435 ti_pinmux_probe(device_t dev)
0436 {
0437 if (!ofw_bus_status_okay(dev))
0438 return (ENXIO);
0439
0440 if (!ofw_bus_is_compatible(dev, "pinctrl-single"))
0441 return (ENXIO);
0442
0443 if (ti_pinmux_sc) {
0444 printf("%s: multiple pinctrl modules in device tree data, ignoring\n",
0445 __func__);
0446 return (EEXIST);
0447 }
0448 switch (ti_chip()) {
0449 #ifdef SOC_OMAP4
0450 case CHIP_OMAP_4:
0451 ti_pinmux_dev = &omap4_pinmux_dev;
0452 break;
0453 #endif
0454 #ifdef SOC_TI_AM335X
0455 case CHIP_AM335X:
0456 ti_pinmux_dev = &ti_am335x_pinmux_dev;
0457 break;
0458 #endif
0459 default:
0460 printf("Unknown CPU in pinmux\n");
0461 return (ENXIO);
0462 }
0463
0464
0465 device_set_desc(dev, "TI Pinmux Module");
0466 return (BUS_PROBE_DEFAULT);
0467 }
0468 #endif
0469
0470 static void
0471 beagle_pinctrl_configure_children(struct ti_pinmux_softc *sc, phandle_t parent)
0472 {
0473 phandle_t node;
0474 int len;
0475 uint32_t phandle;
0476
0477 for (node = OF_child(parent); node != 0; node = OF_peer(node)) {
0478 if (rtems_ofw_node_status(node)) {
0479 beagle_pinctrl_configure_children(sc, node);
0480 len = OF_getencprop(node, "pinctrl-0", &phandle, sizeof(phandle));
0481 if (len == sizeof(phandle)) {
0482 ti_pinmux_configure_pins(sc, phandle);
0483 }
0484 }
0485 }
0486 }
0487
0488 #ifndef __rtems__
0489
0490
0491
0492
0493
0494
0495
0496 static int
0497 ti_pinmux_attach(device_t dev)
0498 {
0499 struct ti_pinmux_softc *sc = device_get_softc(dev);
0500
0501 #if 0
0502 if (ti_pinmux_sc)
0503 return (ENXIO);
0504 #endif
0505
0506 sc->sc_dev = dev;
0507
0508 if (bus_alloc_resources(dev, ti_pinmux_res_spec, sc->sc_res)) {
0509 device_printf(dev, "could not allocate resources\n");
0510 return (ENXIO);
0511 }
0512
0513 sc->sc_bst = rman_get_bustag(sc->sc_res[0]);
0514 sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]);
0515
0516 if (ti_pinmux_sc == NULL)
0517 ti_pinmux_sc = sc;
0518
0519 fdt_pinctrl_register(dev, "pinctrl-single,pins");
0520 fdt_pinctrl_configure_tree(dev);
0521
0522 return (0);
0523 }
0524 #endif
0525
0526 void
0527 beagle_pinmux_init(phandle_t node)
0528 {
0529 static struct ti_pinmux_softc pinmux_softc;
0530 rtems_ofw_memory_area reg;
0531 int rv;
0532
0533 if (!rtems_ofw_is_node_compatible(node, "pinctrl-single"))
0534 return ;
0535
0536 switch (ti_chip()) {
0537 case CHIP_AM335X:
0538 ti_pinmux_dev = &ti_am335x_pinmux_dev;
0539 break;
0540 default:
0541 printk("Unknown CPU in pinmux\n");
0542 return ;
0543 }
0544
0545 rv = rtems_ofw_get_reg(node, ®, sizeof(reg));
0546 if (rv == -1) {
0547 printk("pinmux_init: rtems_ofw_get_reg failed %d\n", rv);
0548 return ;
0549 }
0550 pinmux_softc.sc_bsh = reg.start;
0551
0552 beagle_pinctrl_configure_children(&pinmux_softc, OF_peer(0));
0553 }
0554
0555 #ifndef __rtems__
0556 static device_method_t ti_pinmux_methods[] = {
0557 DEVMETHOD(device_probe, ti_pinmux_probe),
0558 DEVMETHOD(device_attach, ti_pinmux_attach),
0559
0560
0561 DEVMETHOD(fdt_pinctrl_configure, ti_pinmux_configure_pins),
0562 { 0, 0 }
0563 };
0564
0565 static driver_t ti_pinmux_driver = {
0566 "ti_pinmux",
0567 ti_pinmux_methods,
0568 sizeof(struct ti_pinmux_softc),
0569 };
0570
0571 static devclass_t ti_pinmux_devclass;
0572
0573 DRIVER_MODULE(ti_pinmux, simplebus, ti_pinmux_driver, ti_pinmux_devclass, 0, 0);
0574 #endif