imx51_iomux.c revision 259065
1105464Sphk/* $NetBSD: imx51_iomux.c,v 1.3 2012/04/15 09:51:31 bsh Exp $ */ 2105464Sphk 3105464Sphk/* 4105464Sphk * Copyright (c) 2009, 2010 Genetec Corporation. All rights reserved. 5105464Sphk * Written by Hashimoto Kenichi for Genetec Corporation. 6105464Sphk * 7105464Sphk * Redistribution and use in source and binary forms, with or without 8105464Sphk * modification, are permitted provided that the following conditions 9105464Sphk * are met: 10105464Sphk * 1. Redistributions of source code must retain the above copyright 11105464Sphk * notice, this list of conditions and the following disclaimer. 12105464Sphk * 2. Redistributions in binary form must reproduce the above copyright 13105464Sphk * notice, this list of conditions and the following disclaimer in the 14105464Sphk * documentation and/or other materials provided with the distribution. 15105464Sphk * 16105464Sphk * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND 17105464Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18105464Sphk * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19105464Sphk * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION 20105464Sphk * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21105464Sphk * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22105464Sphk * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23105464Sphk * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24105464Sphk * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25105464Sphk * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26105464Sphk * POSSIBILITY OF SUCH DAMAGE. 27105464Sphk */ 28105464Sphk 29105464Sphk/*- 30105464Sphk * Copyright (c) 2012, 2013 The FreeBSD Foundation 31105464Sphk * All rights reserved. 32105464Sphk * 33105464Sphk * Portions of this software were developed by Oleksandr Rybalko 34105464Sphk * under sponsorship from the FreeBSD Foundation. 35105464Sphk * 36105464Sphk * Redistribution and use in source and binary forms, with or without 37105464Sphk * modification, are permitted provided that the following conditions 38105464Sphk * are met: 39105464Sphk * 1. Redistributions of source code must retain the above copyright 40105464Sphk * notice, this list of conditions and the following disclaimer. 41105464Sphk * 2. Redistributions in binary form must reproduce the above copyright 42105464Sphk * notice, this list of conditions and the following disclaimer in the 43105464Sphk * documentation and/or other materials provided with the distribution. 44105464Sphk * 45143418Sume * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 46106407Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47106407Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48106407Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 49105464Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50105464Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51105464Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52105464Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53105464Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54105464Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55105464Sphk * SUCH DAMAGE. 56105464Sphk */ 57105464Sphk 58105464Sphk#include <sys/cdefs.h> 59105464Sphk__FBSDID("$FreeBSD: releng/10.0/sys/arm/freescale/imx/imx51_iomux.c 255130 2013-09-01 20:15:35Z rpaulo $"); 60105464Sphk 61105464Sphk#include <sys/param.h> 62105464Sphk#include <sys/systm.h> 63105464Sphk#include <sys/bus.h> 64105464Sphk#include <sys/kernel.h> 65105464Sphk#include <sys/module.h> 66105464Sphk#include <sys/malloc.h> 67105464Sphk#include <sys/rman.h> 68105464Sphk 69105464Sphk#include <machine/bus.h> 70105464Sphk#include <machine/fdt.h> 71105464Sphk 72105464Sphk#include <dev/fdt/fdt_common.h> 73105464Sphk#include <dev/ofw/openfirm.h> 74105464Sphk#include <dev/ofw/ofw_bus.h> 75105464Sphk#include <dev/ofw/ofw_bus_subr.h> 76105464Sphk 77105464Sphk#include <arm/freescale/imx/imx51_iomuxvar.h> 78105464Sphk#include <arm/freescale/imx/imx51_iomuxreg.h> 79105464Sphk 80105464Sphk 81105464Sphk#define IOMUX_WRITE(_sc, _r, _v) \ 82105464Sphk bus_write_4((_sc)->sc_res, (_r), (_v)) 83105464Sphk#define IOMUX_READ(_sc, _r) \ 84105464Sphk bus_read_4((_sc)->sc_res, (_r)) 85105464Sphk#define IOMUX_SET(_sc, _r, _m) \ 86105464Sphk IOMUX_WRITE((_sc), (_r), IOMUX_READ((_sc), (_r)) | (_m)) 87105464Sphk#define IOMUX_CLEAR(_sc, _r, _m) \ 88105464Sphk IOMUX_WRITE((_sc), (_r), IOMUX_READ((_sc), (_r)) & ~(_m)) 89105464Sphk 90105464Sphkstruct iomux_softc { 91105464Sphk struct resource *sc_res; 92105464Sphk device_t sc_dev; 93105464Sphk}; 94105464Sphk 95105464Sphkstatic int iomux_probe(device_t); 96105464Sphkstatic int iomux_attach(device_t); 97105464Sphk 98105464Sphkstatic struct iomux_softc *iomuxsc = NULL; 99105464Sphk 100105464Sphkstatic struct resource_spec imx_iomux_spec[] = { 101105464Sphk { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Global registers */ 102105464Sphk { -1, 0 } 103105464Sphk}; 104105464Sphk 105105464Sphkstatic int 106105464Sphkiomux_probe(device_t dev) 107105464Sphk{ 108105464Sphk 109105464Sphk if (!ofw_bus_is_compatible(dev, "fsl,imx51-iomux") && 110105464Sphk !ofw_bus_is_compatible(dev, "fsl,imx53-iomux")) 111125755Sphk return (ENXIO); 112105464Sphk 113105464Sphk device_set_desc(dev, "Freescale i.MX51 IO pins multiplexor"); 114115624Sphk return (BUS_PROBE_DEFAULT); 115112828Sphk} 116112828Sphk 117112828Sphkstatic int 118112828Sphkiomux_attach(device_t dev) 119112828Sphk{ 120112828Sphk struct iomux_softc * sc; 121112828Sphk 122112828Sphk sc = device_get_softc(dev); 123112828Sphk 124112828Sphk if (bus_alloc_resources(dev, imx_iomux_spec, &sc->sc_res)) { 125112828Sphk device_printf(dev, "could not allocate resources\n"); 126112828Sphk return (ENXIO); 127112828Sphk } 128112828Sphk 129112828Sphk iomuxsc = sc; 130112828Sphk 131112828Sphk /* 132112828Sphk * XXX: place to fetch all info about pinmuxing from loader data 133112828Sphk * (FDT blob) and apply. Loader (1st one) must care about 134112828Sphk * device-to-device difference. 135125755Sphk */ 136112828Sphk 137112828Sphk return (0); 138112828Sphk} 139112828Sphk 140115624Sphkstatic void 141125590Sphkiomux_set_function_sub(struct iomux_softc *sc, uint32_t pin, uint32_t fn) 142112828Sphk{ 143114720Sphk bus_size_t mux_ctl_reg = IOMUX_PIN_TO_MUX_ADDRESS(pin); 144114720Sphk 145114720Sphk if (mux_ctl_reg != IOMUX_MUX_NONE) 146114720Sphk IOMUX_WRITE(sc, mux_ctl_reg, fn); 147114720Sphk} 148115624Sphk 149114720Sphkvoid 150114720Sphkiomux_set_function(unsigned int pin, unsigned int fn) 151114720Sphk{ 152114720Sphk 153115624Sphk if (iomuxsc == NULL) 154114720Sphk return; 155114720Sphk iomux_set_function_sub(iomuxsc, pin, fn); 156112828Sphk} 157112828Sphk 158112828Sphkstatic void 159112828Sphkiomux_set_pad_sub(struct iomux_softc *sc, uint32_t pin, uint32_t config) 160112828Sphk{ 161112828Sphk bus_size_t pad_ctl_reg = IOMUX_PIN_TO_PAD_ADDRESS(pin); 162112828Sphk 163112828Sphk if (pad_ctl_reg != IOMUX_PAD_NONE) 164112828Sphk IOMUX_WRITE(sc, pad_ctl_reg, config); 165112828Sphk} 166112828Sphk 167112828Sphkvoid 168112828Sphkiomux_set_pad(unsigned int pin, unsigned int config) 169112828Sphk{ 170112828Sphk 171112828Sphk if (iomuxsc == NULL) 172112828Sphk return; 173112828Sphk iomux_set_pad_sub(iomuxsc, pin, config); 174112828Sphk} 175112828Sphk 176112828Sphk#ifdef notyet 177112828Sphkvoid 178112828Sphkiomux_set_input(unsigned int input, unsigned int config) 179112828Sphk{ 180112828Sphk bus_size_t input_ctl_reg = input; 181112828Sphk 182112828Sphk bus_space_write_4(iomuxsc->iomux_memt, iomuxsc->iomux_memh, 183112828Sphk input_ctl_reg, config); 184112828Sphk} 185112828Sphk#endif 186112828Sphk 187112828Sphkvoid 188112828Sphkiomux_mux_config(const struct iomux_conf *conflist) 189114087Sphk{ 190114087Sphk int i; 191114087Sphk 192114087Sphk if (iomuxsc == NULL) 193114087Sphk return; 194114087Sphk for (i = 0; conflist[i].pin != IOMUX_CONF_EOT; i++) { 195112828Sphk iomux_set_pad_sub(iomuxsc, conflist[i].pin, conflist[i].pad); 196114087Sphk iomux_set_function_sub(iomuxsc, conflist[i].pin, 197112828Sphk conflist[i].mux); 198112828Sphk } 199112828Sphk} 200112828Sphk 201112828Sphk#ifdef notyet 202112828Sphkvoid 203114720Sphkiomux_input_config(const struct iomux_input_conf *conflist) 204115624Sphk{ 205114720Sphk int i; 206115624Sphk 207114720Sphk if (iomuxsc == NULL) 208115624Sphk return; 209115624Sphk for (i = 0; conflist[i].inout != -1; i++) { 210125755Sphk iomux_set_inout(iomuxsc, conflist[i].inout, 211112828Sphk conflist[i].inout_mode); 212112828Sphk } 213112828Sphk} 214112828Sphk#endif 215112828Sphk 216115624Sphkstatic device_method_t imx_iomux_methods[] = { 217112828Sphk DEVMETHOD(device_probe, iomux_probe), 218112828Sphk DEVMETHOD(device_attach, iomux_attach), 219112828Sphk 220112828Sphk DEVMETHOD_END 221112828Sphk}; 222112828Sphk 223112828Sphkstatic driver_t imx_iomux_driver = { 224112828Sphk "imx_iomux", 225112828Sphk imx_iomux_methods, 226112828Sphk sizeof(struct iomux_softc), 227112828Sphk}; 228112828Sphk 229112828Sphkstatic devclass_t imx_iomux_devclass; 230112828Sphk 231112828SphkEARLY_DRIVER_MODULE(imx_iomux, simplebus, imx_iomux_driver, 232112828Sphk imx_iomux_devclass, 0, 0, BUS_PASS_BUS - 1); 233112828Sphk 234112828Sphk