From e00f4434281bad6d06fdc7d0f940de8710976e06 Mon Sep 17 00:00:00 2001 From: Christian Mauderer Date: Tue, 27 Oct 2020 10:00:31 +0100 Subject: imx: Move imx_iomux to arm/shared Update #4180 --- bsps/arm/imx/headers.am | 2 - .../imx/include/arm/freescale/imx/imx_iomuxreg.h | 61 --- .../imx/include/arm/freescale/imx/imx_iomuxvar.h | 49 --- bsps/arm/imx/include/bsp.h | 2 - bsps/arm/imx/spi/imx-ecspi.c | 1 + bsps/arm/imx/start/imx_iomux.c | 472 --------------------- bsps/arm/shared/headers.am | 6 + .../include/arm/freescale/imx/imx_iomuxreg.h | 61 +++ .../include/arm/freescale/imx/imx_iomuxvar.h | 49 +++ bsps/arm/shared/include/bsp/imx-iomux.h | 49 +++ bsps/arm/shared/pins/imx_iomux.c | 472 +++++++++++++++++++++ c/src/lib/libbsp/arm/imx/Makefile.am | 2 +- spec/build/bsps/arm/imx/bspimx.yml | 10 +- 13 files changed, 645 insertions(+), 591 deletions(-) delete mode 100644 bsps/arm/imx/include/arm/freescale/imx/imx_iomuxreg.h delete mode 100644 bsps/arm/imx/include/arm/freescale/imx/imx_iomuxvar.h delete mode 100644 bsps/arm/imx/start/imx_iomux.c create mode 100644 bsps/arm/shared/headers.am create mode 100644 bsps/arm/shared/include/arm/freescale/imx/imx_iomuxreg.h create mode 100644 bsps/arm/shared/include/arm/freescale/imx/imx_iomuxvar.h create mode 100644 bsps/arm/shared/include/bsp/imx-iomux.h create mode 100644 bsps/arm/shared/pins/imx_iomux.c diff --git a/bsps/arm/imx/headers.am b/bsps/arm/imx/headers.am index 9863f34300..e7a2418dea 100644 --- a/bsps/arm/imx/headers.am +++ b/bsps/arm/imx/headers.am @@ -11,8 +11,6 @@ include_arm_freescale_imx_HEADERS += ../../../../../../bsps/arm/imx/include/arm/ include_arm_freescale_imx_HEADERS += ../../../../../../bsps/arm/imx/include/arm/freescale/imx/imx_ecspireg.h include_arm_freescale_imx_HEADERS += ../../../../../../bsps/arm/imx/include/arm/freescale/imx/imx_gpcreg.h include_arm_freescale_imx_HEADERS += ../../../../../../bsps/arm/imx/include/arm/freescale/imx/imx_i2creg.h -include_arm_freescale_imx_HEADERS += ../../../../../../bsps/arm/imx/include/arm/freescale/imx/imx_iomuxreg.h -include_arm_freescale_imx_HEADERS += ../../../../../../bsps/arm/imx/include/arm/freescale/imx/imx_iomuxvar.h include_arm_freescale_imx_HEADERS += ../../../../../../bsps/arm/imx/include/arm/freescale/imx/imx_srcreg.h include_arm_freescale_imx_HEADERS += ../../../../../../bsps/arm/imx/include/arm/freescale/imx/imx_uartreg.h include_arm_freescale_imx_HEADERS += ../../../../../../bsps/arm/imx/include/arm/freescale/imx/imx_wdogreg.h diff --git a/bsps/arm/imx/include/arm/freescale/imx/imx_iomuxreg.h b/bsps/arm/imx/include/arm/freescale/imx/imx_iomuxreg.h deleted file mode 100644 index b84fde26de..0000000000 --- a/bsps/arm/imx/include/arm/freescale/imx/imx_iomuxreg.h +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * Copyright (c) 2015 Oleksandr Tymoshenko - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: head/sys/arm/freescale/imx/imx_iomuxreg.h 322015 2017-08-03 14:43:41Z ian $ - */ - -#ifndef IMX_IOMUXREG_H -#define IMX_IOMUXREG_H - -#define IMX_IOMUXREG_LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask)) -#define IMX_IOMUXREG_SHIFTIN(__x, __mask) ((__x) * IMX_IOMUXREG_LOWEST_SET_BIT(__mask)) - -#define IMX_IOMUXREG_BIT(n) (1 << (n)) -#define IMX_IOMUXREG_BITS(__m, __n) \ - ((IMX_IOMUXREG_BIT(MAX((__m), (__n)) + 1) - 1) ^ (IMX_IOMUXREG_BIT(MIN((__m), (__n))) - 1)) - -#define IOMUXC_GPR0 0x00 -#define IOMUXC_GPR1 0x04 -#define IOMUXC_GPR2 0x08 -#define IOMUXC_GPR3 0x0C -#define IOMUXC_GPR3_HDMI_MASK (3 << 2) -#define IOMUXC_GPR3_HDMI_IPU1_DI0 (0 << 2) -#define IOMUXC_GPR3_HDMI_IPU1_DI1 (1 << 2) -#define IOMUXC_GPR3_HDMI_IPU2_DI0 (2 << 2) -#define IOMUXC_GPR3_HDMI_IPU2_DI1 (3 << 2) - -#define IOMUX_GPR13 0x34 -#define IOMUX_GPR13_SATA_PHY_8(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(26, 24)) -#define IOMUX_GPR13_SATA_PHY_7(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(23, 19)) -#define IOMUX_GPR13_SATA_PHY_6(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(18, 16)) -#define IOMUX_GPR13_SATA_SPEED(n) IMX_IOMUXREG_SHIFTIN(n, (1 << 15)) -#define IOMUX_GPR13_SATA_PHY_5(n) IMX_IOMUXREG_SHIFTIN(n, (1 << 14)) -#define IOMUX_GPR13_SATA_PHY_4(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(13, 11)) -#define IOMUX_GPR13_SATA_PHY_3(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(10, 7)) -#define IOMUX_GPR13_SATA_PHY_2(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(6, 2)) -#define IOMUX_GPR13_SATA_PHY_1(n) IMX_IOMUXREG_SHIFTIN(n, (1 << 1)) -#define IOMUX_GPR13_SATA_PHY_0(n) IMX_IOMUXREG_SHIFTIN(n, (1 << 0)) - -#endif diff --git a/bsps/arm/imx/include/arm/freescale/imx/imx_iomuxvar.h b/bsps/arm/imx/include/arm/freescale/imx/imx_iomuxvar.h deleted file mode 100644 index 8050b56a84..0000000000 --- a/bsps/arm/imx/include/arm/freescale/imx/imx_iomuxvar.h +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * Copyright (c) 2014 Ian Lepore - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: head/sys/arm/freescale/imx/imx_iomuxvar.h 321938 2017-08-02 18:28:06Z ian $ - */ - -#ifndef IMX_IOMUXVAR_H -#define IMX_IOMUXVAR_H - -/* - * IOMUX interface functions - */ -void iomux_set_function(u_int pin, u_int fn); -void iomux_set_pad(u_int pin, u_int cfg); -u_int iomux_get_pad_config(u_int pin); - -/* - * The IOMUX Controller device has a small set of "general purpose registers" - * which control various aspects of SoC operation that really have nothing to do - * with IO pin assignments or pad control. These functions let other soc level - * code manipulate these values. - */ -uint32_t imx_iomux_gpr_get(u_int regaddr); -void imx_iomux_gpr_set(u_int regaddr, uint32_t val); -void imx_iomux_gpr_set_masked(u_int regaddr, uint32_t clrbits, uint32_t setbits); - -#endif diff --git a/bsps/arm/imx/include/bsp.h b/bsps/arm/imx/include/bsp.h index 99b7a0d1d7..8b95a79535 100644 --- a/bsps/arm/imx/include/bsp.h +++ b/bsps/arm/imx/include/bsp.h @@ -59,8 +59,6 @@ extern uintptr_t imx_gic_dist_base; void *imx_get_reg_of_node(const void *fdt, int node); -int imx_iomux_configure_pins(const void *fdt, uint32_t phandle); - rtems_vector_number imx_get_irq_of_node( const void *fdt, int node, diff --git a/bsps/arm/imx/spi/imx-ecspi.c b/bsps/arm/imx/spi/imx-ecspi.c index 26ba812f62..1ffc4d9798 100644 --- a/bsps/arm/imx/spi/imx-ecspi.c +++ b/bsps/arm/imx/spi/imx-ecspi.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/bsps/arm/imx/start/imx_iomux.c b/bsps/arm/imx/start/imx_iomux.c deleted file mode 100644 index d97e35deef..0000000000 --- a/bsps/arm/imx/start/imx_iomux.c +++ /dev/null @@ -1,472 +0,0 @@ -/*- - * Copyright (c) 2014 Ian Lepore - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: head/sys/arm/freescale/imx/imx_iomux.c 321938 2017-08-02 18:28:06Z ian $ - */ - -/* - * Pin mux and pad control driver for imx5 and imx6. - * - * This driver implements the fdt_pinctrl interface for configuring the gpio and - * peripheral pins based on fdt configuration data. - * - * When the driver attaches, it walks the entire fdt tree and automatically - * configures the pins for each device which has a pinctrl-0 property and whose - * status is "okay". In addition it implements the fdt_pinctrl_configure() - * method which any other driver can call at any time to reconfigure its pins. - * - * The nature of the fsl,pins property in fdt data makes this driver's job very - * easy. Instead of representing each pin and pad configuration using symbolic - * properties such as pullup-enable="true" and so on, the data simply contains - * the addresses of the registers that control the pins, and the raw values to - * store in those registers. - * - * The imx5 and imx6 SoCs also have a small number of "general purpose - * registers" in the iomuxc device which are used to control an assortment - * of completely unrelated aspects of SoC behavior. This driver provides other - * drivers with direct access to those registers via simple accessor functions. - */ - -#include -#ifndef __rtems__ -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#endif /* __rtems__ */ - -#include -#ifndef __rtems__ -#include -#else /* __rtems__ */ -#include -#include -#include -#include -#include -#include - -typedef size_t bus_size_t; -typedef int phandle_t; -#endif /* __rtems__ */ - -struct iomux_softc { -#ifndef __rtems__ - device_t dev; - struct resource *mem_res; - u_int last_gpregaddr; -#else /* __rtems__ */ - volatile uint32_t *regs; -#endif /* __rtems__ */ -}; - -#ifndef __rtems__ -static struct iomux_softc *iomux_sc; - -static struct ofw_compat_data compat_data[] = { - {"fsl,imx6dl-iomuxc", true}, - {"fsl,imx6q-iomuxc", true}, - {"fsl,imx6sl-iomuxc", true}, - {"fsl,imx6ul-iomuxc", true}, - {"fsl,imx6sx-iomuxc", true}, - {"fsl,imx53-iomuxc", true}, - {"fsl,imx51-iomuxc", true}, - {NULL, false}, -}; -#else /* __rtems__ */ -static struct iomux_softc iomux_sc_instance; - -#define iomux_sc (&iomux_sc_instance); - -/* Return true if there is no status or status is "okay" or "ok". */ -static bool -imx_fdt_node_status_okay(const void *fdt, int node) -{ - const void *status; - int len; - - status = fdt_getprop(fdt, node, "status", &len); - if ((status == NULL) || - (strncmp(status, "okay", MIN(5, len)) == 0) || - (strncmp(status, "ok", MIN(3, len)) == 0)) { - return true; - } - - return false; -} - -/* - * Walk through all subnodes and handle "pinctrl-0" if the node is enabled. This - * does roughly the same as FreeBSDs fdt_pinctrl_configure_tree but without the - * whole open firmware (OF*) functions. - */ -static void -imx_pinctrl_configure_children(const void *fdt, int parent) -{ - int node; - const uint32_t *phandle; - int len; - - fdt_for_each_subnode(node, fdt, parent) { - if (imx_fdt_node_status_okay(fdt, node)) { - imx_pinctrl_configure_children(fdt, node); - phandle = fdt_getprop(fdt, node, "pinctrl-0", &len); - if (phandle != NULL && len == sizeof(*phandle)) { - imx_iomux_configure_pins(fdt, - fdt32_to_cpu(*phandle)); - } - } - } -} - -static void -imx_iomux_init(void) -{ - const void *fdt; - int node; - struct iomux_softc *sc; - - fdt = bsp_fdt_get(); - node = fdt_node_offset_by_compatible(fdt, -1, "fsl,imx7d-iomuxc"); - if (node < 0) { - node = fdt_node_offset_by_compatible(fdt, -1, - "fsl,imx6ul-iomuxc"); - } - sc = iomux_sc; - sc->regs = imx_get_reg_of_node(fdt, node); - - node = fdt_path_offset(fdt, "/"); - imx_pinctrl_configure_children(fdt, node); -} - -RTEMS_SYSINIT_ITEM(imx_iomux_init, RTEMS_SYSINIT_BSP_START, - RTEMS_SYSINIT_ORDER_MIDDLE); - -#define OF_node_from_xref(phandle) fdt_node_offset_by_phandle(fdt, phandle) - -static int -imx_iomux_getencprop_alloc(const char *fdt, int node, const char *name, - size_t elsz, void **buf) -{ - int len; - const uint32_t *val; - int i; - uint32_t *cell; - - val = fdt_getprop(fdt, node, "fsl,pins", &len); - if (val == NULL || len < 0 || len % elsz != 0) { - return (-1); - } - - cell = malloc((size_t)len); - *buf = cell; - if (cell == NULL) { - return (-1); - } - - for (i = 0; i < len / 4; ++i) { - cell[i] = fdt32_to_cpu(val[i]); - } - - return (len / (int)elsz); -} - -#define OF_getencprop_alloc(node, name, elsz, buf) \ - imx_iomux_getencprop_alloc(fdt, node, name, elsz, buf) - -#define OF_prop_free(buf) free(buf) -#endif /* __rtems__ */ - -/* - * Each tuple in an fsl,pins property contains these fields. - */ -struct pincfg { - uint32_t mux_reg; - uint32_t padconf_reg; - uint32_t input_reg; - uint32_t mux_val; - uint32_t input_val; - uint32_t padconf_val; -}; - -#define PADCONF_NONE (1U << 31) /* Do not configure pad. */ -#define PADCONF_SION (1U << 30) /* Force SION bit in mux register. */ -#define PADMUX_SION (1U << 4) /* The SION bit in the mux register. */ - -static inline uint32_t -RD4(struct iomux_softc *sc, bus_size_t off) -{ - -#ifndef __rtems__ - return (bus_read_4(sc->mem_res, off)); -#else /* __rtems__ */ - return (sc->regs[off / 4]); -#endif /* __rtems__ */ -} - -static inline void -WR4(struct iomux_softc *sc, bus_size_t off, uint32_t val) -{ - -#ifndef __rtems__ - bus_write_4(sc->mem_res, off, val); -#else /* __rtems__ */ - sc->regs[off / 4] = val; -#endif /* __rtems__ */ -} - -static void -iomux_configure_input(struct iomux_softc *sc, uint32_t reg, uint32_t val) -{ - u_int select, mask, shift, width; - - /* If register and value are zero, there is nothing to configure. */ - if (reg == 0 && val == 0) - return; - - /* - * If the config value has 0xff in the high byte it is encoded: - * 31 23 15 7 0 - * | 0xff | shift | width | select | - * We need to mask out the old select value and OR in the new, using a - * mask of the given width and shifting the values up by shift. - */ - if ((val & 0xff000000) == 0xff000000) { - select = val & 0x000000ff; - width = (val & 0x0000ff00) >> 8; - shift = (val & 0x00ff0000) >> 16; - mask = ((1u << width) - 1) << shift; - val = (RD4(sc, reg) & ~mask) | (select << shift); - } - WR4(sc, reg, val); -} - -#ifndef __rtems__ -static int -iomux_configure_pins(device_t dev, phandle_t cfgxref) -#else /* __rtems__ */ -int imx_iomux_configure_pins(const void *fdt, uint32_t cfgxref) -#endif /* __rtems__ */ -{ - struct iomux_softc *sc; - struct pincfg *cfgtuples, *cfg; - phandle_t cfgnode; - int i, ntuples; - uint32_t sion; - -#ifndef __rtems__ - sc = device_get_softc(dev); -#else /* __rtems__ */ - sc = iomux_sc; -#endif /* __rtems__ */ - cfgnode = OF_node_from_xref(cfgxref); - ntuples = OF_getencprop_alloc(cfgnode, "fsl,pins", sizeof(*cfgtuples), - (void **)&cfgtuples); - if (ntuples < 0) - return (ENOENT); - if (ntuples == 0) - return (0); /* Empty property is not an error. */ - for (i = 0, cfg = cfgtuples; i < ntuples; i++, cfg++) { - sion = (cfg->padconf_val & PADCONF_SION) ? PADMUX_SION : 0; - WR4(sc, cfg->mux_reg, cfg->mux_val | sion); - iomux_configure_input(sc, cfg->input_reg, cfg->input_val); - if ((cfg->padconf_val & PADCONF_NONE) == 0) - WR4(sc, cfg->padconf_reg, cfg->padconf_val); -#ifndef __rtems__ - if (bootverbose) { - char name[32]; - OF_getprop(cfgnode, "name", &name, sizeof(name)); - printf("%16s: muxreg 0x%04x muxval 0x%02x " - "inpreg 0x%04x inpval 0x%02x " - "padreg 0x%04x padval 0x%08x\n", - name, cfg->mux_reg, cfg->mux_val | sion, - cfg->input_reg, cfg->input_val, - cfg->padconf_reg, cfg->padconf_val); - } -#endif /* __rtems__ */ - } - OF_prop_free(cfgtuples); - return (0); -} - -#ifndef __rtems__ -static int -iomux_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) - return (ENXIO); - - device_set_desc(dev, "Freescale i.MX pin configuration"); - return (BUS_PROBE_DEFAULT); -} - -static int -iomux_detach(device_t dev) -{ - - /* This device is always present. */ - return (EBUSY); -} - -static int -iomux_attach(device_t dev) -{ - struct iomux_softc * sc; - int rid; - - sc = device_get_softc(dev); - sc->dev = dev; - - switch (imx_soc_type()) { - case IMXSOC_51: - sc->last_gpregaddr = 1 * sizeof(uint32_t); - break; - case IMXSOC_53: - sc->last_gpregaddr = 2 * sizeof(uint32_t); - break; - case IMXSOC_6DL: - case IMXSOC_6S: - case IMXSOC_6SL: - case IMXSOC_6Q: - sc->last_gpregaddr = 13 * sizeof(uint32_t); - break; - case IMXSOC_6UL: - sc->last_gpregaddr = 14 * sizeof(uint32_t); - break; - default: - device_printf(dev, "Unknown SoC type\n"); - return (ENXIO); - } - - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->mem_res == NULL) { - device_printf(dev, "Cannot allocate memory resources\n"); - return (ENXIO); - } - - iomux_sc = sc; - - /* - * Register as a pinctrl device, and call the convenience function that - * walks the entire device tree invoking FDT_PINCTRL_CONFIGURE() on any - * pinctrl-0 property cells whose xref phandle refers to a configuration - * that is a child node of our node in the tree. - * - * The pinctrl bindings documentation specifically mentions that the - * pinctrl device itself may have a pinctrl-0 property which contains - * static configuration to be applied at device init time. The tree - * walk will automatically handle this for us when it passes through our - * node in the tree. - */ - fdt_pinctrl_register(dev, "fsl,pins"); - fdt_pinctrl_configure_tree(dev); - - return (0); -} - -uint32_t -imx_iomux_gpr_get(u_int regaddr) -{ - struct iomux_softc * sc; - - sc = iomux_sc; - KASSERT(sc != NULL, ("%s called before attach", __FUNCTION__)); - KASSERT(regaddr >= 0 && regaddr <= sc->last_gpregaddr, - ("%s bad regaddr %u, max %u", __FUNCTION__, regaddr, - sc->last_gpregaddr)); - - return (RD4(iomux_sc, regaddr)); -} - -void -imx_iomux_gpr_set(u_int regaddr, uint32_t val) -{ - struct iomux_softc * sc; - - sc = iomux_sc; - KASSERT(sc != NULL, ("%s called before attach", __FUNCTION__)); - KASSERT(regaddr >= 0 && regaddr <= sc->last_gpregaddr, - ("%s bad regaddr %u, max %u", __FUNCTION__, regaddr, - sc->last_gpregaddr)); - - WR4(iomux_sc, regaddr, val); -} - -void -imx_iomux_gpr_set_masked(u_int regaddr, uint32_t clrbits, uint32_t setbits) -{ - struct iomux_softc * sc; - uint32_t val; - - sc = iomux_sc; - KASSERT(sc != NULL, ("%s called before attach", __FUNCTION__)); - KASSERT(regaddr >= 0 && regaddr <= sc->last_gpregaddr, - ("%s bad regaddr %u, max %u", __FUNCTION__, regaddr, - sc->last_gpregaddr)); - - val = RD4(iomux_sc, regaddr * 4); - val = (val & ~clrbits) | setbits; - WR4(iomux_sc, regaddr, val); -} - -static device_method_t imx_iomux_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, iomux_probe), - DEVMETHOD(device_attach, iomux_attach), - DEVMETHOD(device_detach, iomux_detach), - - /* fdt_pinctrl interface */ - DEVMETHOD(fdt_pinctrl_configure,iomux_configure_pins), - - DEVMETHOD_END -}; - -static driver_t imx_iomux_driver = { - "imx_iomux", - imx_iomux_methods, - sizeof(struct iomux_softc), -}; - -static devclass_t imx_iomux_devclass; - -EARLY_DRIVER_MODULE(imx_iomux, simplebus, imx_iomux_driver, - imx_iomux_devclass, 0, 0, BUS_PASS_CPU + BUS_PASS_ORDER_LATE); - -#endif /* __rtems__ */ diff --git a/bsps/arm/shared/headers.am b/bsps/arm/shared/headers.am new file mode 100644 index 0000000000..4fd7238f81 --- /dev/null +++ b/bsps/arm/shared/headers.am @@ -0,0 +1,6 @@ +## This file was generated by "./boostrap -H". + +include_arm_freescale_imxdir = $(includedir)/arm/freescale/imx +include_arm_freescale_imx_HEADERS = +include_arm_freescale_imx_HEADERS += ../../../../../../bsps/arm/shared/include/arm/freescale/imx/imx_iomuxreg.h +include_arm_freescale_imx_HEADERS += ../../../../../../bsps/arm/shared/include/arm/freescale/imx/imx_iomuxvar.h diff --git a/bsps/arm/shared/include/arm/freescale/imx/imx_iomuxreg.h b/bsps/arm/shared/include/arm/freescale/imx/imx_iomuxreg.h new file mode 100644 index 0000000000..b84fde26de --- /dev/null +++ b/bsps/arm/shared/include/arm/freescale/imx/imx_iomuxreg.h @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2015 Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/sys/arm/freescale/imx/imx_iomuxreg.h 322015 2017-08-03 14:43:41Z ian $ + */ + +#ifndef IMX_IOMUXREG_H +#define IMX_IOMUXREG_H + +#define IMX_IOMUXREG_LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask)) +#define IMX_IOMUXREG_SHIFTIN(__x, __mask) ((__x) * IMX_IOMUXREG_LOWEST_SET_BIT(__mask)) + +#define IMX_IOMUXREG_BIT(n) (1 << (n)) +#define IMX_IOMUXREG_BITS(__m, __n) \ + ((IMX_IOMUXREG_BIT(MAX((__m), (__n)) + 1) - 1) ^ (IMX_IOMUXREG_BIT(MIN((__m), (__n))) - 1)) + +#define IOMUXC_GPR0 0x00 +#define IOMUXC_GPR1 0x04 +#define IOMUXC_GPR2 0x08 +#define IOMUXC_GPR3 0x0C +#define IOMUXC_GPR3_HDMI_MASK (3 << 2) +#define IOMUXC_GPR3_HDMI_IPU1_DI0 (0 << 2) +#define IOMUXC_GPR3_HDMI_IPU1_DI1 (1 << 2) +#define IOMUXC_GPR3_HDMI_IPU2_DI0 (2 << 2) +#define IOMUXC_GPR3_HDMI_IPU2_DI1 (3 << 2) + +#define IOMUX_GPR13 0x34 +#define IOMUX_GPR13_SATA_PHY_8(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(26, 24)) +#define IOMUX_GPR13_SATA_PHY_7(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(23, 19)) +#define IOMUX_GPR13_SATA_PHY_6(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(18, 16)) +#define IOMUX_GPR13_SATA_SPEED(n) IMX_IOMUXREG_SHIFTIN(n, (1 << 15)) +#define IOMUX_GPR13_SATA_PHY_5(n) IMX_IOMUXREG_SHIFTIN(n, (1 << 14)) +#define IOMUX_GPR13_SATA_PHY_4(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(13, 11)) +#define IOMUX_GPR13_SATA_PHY_3(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(10, 7)) +#define IOMUX_GPR13_SATA_PHY_2(n) IMX_IOMUXREG_SHIFTIN(n, IMX_IOMUXREG_BITS(6, 2)) +#define IOMUX_GPR13_SATA_PHY_1(n) IMX_IOMUXREG_SHIFTIN(n, (1 << 1)) +#define IOMUX_GPR13_SATA_PHY_0(n) IMX_IOMUXREG_SHIFTIN(n, (1 << 0)) + +#endif diff --git a/bsps/arm/shared/include/arm/freescale/imx/imx_iomuxvar.h b/bsps/arm/shared/include/arm/freescale/imx/imx_iomuxvar.h new file mode 100644 index 0000000000..8050b56a84 --- /dev/null +++ b/bsps/arm/shared/include/arm/freescale/imx/imx_iomuxvar.h @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2014 Ian Lepore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/sys/arm/freescale/imx/imx_iomuxvar.h 321938 2017-08-02 18:28:06Z ian $ + */ + +#ifndef IMX_IOMUXVAR_H +#define IMX_IOMUXVAR_H + +/* + * IOMUX interface functions + */ +void iomux_set_function(u_int pin, u_int fn); +void iomux_set_pad(u_int pin, u_int cfg); +u_int iomux_get_pad_config(u_int pin); + +/* + * The IOMUX Controller device has a small set of "general purpose registers" + * which control various aspects of SoC operation that really have nothing to do + * with IO pin assignments or pad control. These functions let other soc level + * code manipulate these values. + */ +uint32_t imx_iomux_gpr_get(u_int regaddr); +void imx_iomux_gpr_set(u_int regaddr, uint32_t val); +void imx_iomux_gpr_set_masked(u_int regaddr, uint32_t clrbits, uint32_t setbits); + +#endif diff --git a/bsps/arm/shared/include/bsp/imx-iomux.h b/bsps/arm/shared/include/bsp/imx-iomux.h new file mode 100644 index 0000000000..60421807c0 --- /dev/null +++ b/bsps/arm/shared/include/bsp/imx-iomux.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsARM + * + * @brief Functions for imx iomux. + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBBSP_ARM_SHARED_IMX_IOMUX_H +#define LIBBSP_ARM_SHARED_IMX_IOMUX_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +int imx_iomux_configure_pins(const void *fdt, uint32_t phandle); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_SHARED_IMX_IOMUX_H */ diff --git a/bsps/arm/shared/pins/imx_iomux.c b/bsps/arm/shared/pins/imx_iomux.c new file mode 100644 index 0000000000..d97e35deef --- /dev/null +++ b/bsps/arm/shared/pins/imx_iomux.c @@ -0,0 +1,472 @@ +/*- + * Copyright (c) 2014 Ian Lepore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/sys/arm/freescale/imx/imx_iomux.c 321938 2017-08-02 18:28:06Z ian $ + */ + +/* + * Pin mux and pad control driver for imx5 and imx6. + * + * This driver implements the fdt_pinctrl interface for configuring the gpio and + * peripheral pins based on fdt configuration data. + * + * When the driver attaches, it walks the entire fdt tree and automatically + * configures the pins for each device which has a pinctrl-0 property and whose + * status is "okay". In addition it implements the fdt_pinctrl_configure() + * method which any other driver can call at any time to reconfigure its pins. + * + * The nature of the fsl,pins property in fdt data makes this driver's job very + * easy. Instead of representing each pin and pad configuration using symbolic + * properties such as pullup-enable="true" and so on, the data simply contains + * the addresses of the registers that control the pins, and the raw values to + * store in those registers. + * + * The imx5 and imx6 SoCs also have a small number of "general purpose + * registers" in the iomuxc device which are used to control an assortment + * of completely unrelated aspects of SoC behavior. This driver provides other + * drivers with direct access to those registers via simple accessor functions. + */ + +#include +#ifndef __rtems__ +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#endif /* __rtems__ */ + +#include +#ifndef __rtems__ +#include +#else /* __rtems__ */ +#include +#include +#include +#include +#include +#include + +typedef size_t bus_size_t; +typedef int phandle_t; +#endif /* __rtems__ */ + +struct iomux_softc { +#ifndef __rtems__ + device_t dev; + struct resource *mem_res; + u_int last_gpregaddr; +#else /* __rtems__ */ + volatile uint32_t *regs; +#endif /* __rtems__ */ +}; + +#ifndef __rtems__ +static struct iomux_softc *iomux_sc; + +static struct ofw_compat_data compat_data[] = { + {"fsl,imx6dl-iomuxc", true}, + {"fsl,imx6q-iomuxc", true}, + {"fsl,imx6sl-iomuxc", true}, + {"fsl,imx6ul-iomuxc", true}, + {"fsl,imx6sx-iomuxc", true}, + {"fsl,imx53-iomuxc", true}, + {"fsl,imx51-iomuxc", true}, + {NULL, false}, +}; +#else /* __rtems__ */ +static struct iomux_softc iomux_sc_instance; + +#define iomux_sc (&iomux_sc_instance); + +/* Return true if there is no status or status is "okay" or "ok". */ +static bool +imx_fdt_node_status_okay(const void *fdt, int node) +{ + const void *status; + int len; + + status = fdt_getprop(fdt, node, "status", &len); + if ((status == NULL) || + (strncmp(status, "okay", MIN(5, len)) == 0) || + (strncmp(status, "ok", MIN(3, len)) == 0)) { + return true; + } + + return false; +} + +/* + * Walk through all subnodes and handle "pinctrl-0" if the node is enabled. This + * does roughly the same as FreeBSDs fdt_pinctrl_configure_tree but without the + * whole open firmware (OF*) functions. + */ +static void +imx_pinctrl_configure_children(const void *fdt, int parent) +{ + int node; + const uint32_t *phandle; + int len; + + fdt_for_each_subnode(node, fdt, parent) { + if (imx_fdt_node_status_okay(fdt, node)) { + imx_pinctrl_configure_children(fdt, node); + phandle = fdt_getprop(fdt, node, "pinctrl-0", &len); + if (phandle != NULL && len == sizeof(*phandle)) { + imx_iomux_configure_pins(fdt, + fdt32_to_cpu(*phandle)); + } + } + } +} + +static void +imx_iomux_init(void) +{ + const void *fdt; + int node; + struct iomux_softc *sc; + + fdt = bsp_fdt_get(); + node = fdt_node_offset_by_compatible(fdt, -1, "fsl,imx7d-iomuxc"); + if (node < 0) { + node = fdt_node_offset_by_compatible(fdt, -1, + "fsl,imx6ul-iomuxc"); + } + sc = iomux_sc; + sc->regs = imx_get_reg_of_node(fdt, node); + + node = fdt_path_offset(fdt, "/"); + imx_pinctrl_configure_children(fdt, node); +} + +RTEMS_SYSINIT_ITEM(imx_iomux_init, RTEMS_SYSINIT_BSP_START, + RTEMS_SYSINIT_ORDER_MIDDLE); + +#define OF_node_from_xref(phandle) fdt_node_offset_by_phandle(fdt, phandle) + +static int +imx_iomux_getencprop_alloc(const char *fdt, int node, const char *name, + size_t elsz, void **buf) +{ + int len; + const uint32_t *val; + int i; + uint32_t *cell; + + val = fdt_getprop(fdt, node, "fsl,pins", &len); + if (val == NULL || len < 0 || len % elsz != 0) { + return (-1); + } + + cell = malloc((size_t)len); + *buf = cell; + if (cell == NULL) { + return (-1); + } + + for (i = 0; i < len / 4; ++i) { + cell[i] = fdt32_to_cpu(val[i]); + } + + return (len / (int)elsz); +} + +#define OF_getencprop_alloc(node, name, elsz, buf) \ + imx_iomux_getencprop_alloc(fdt, node, name, elsz, buf) + +#define OF_prop_free(buf) free(buf) +#endif /* __rtems__ */ + +/* + * Each tuple in an fsl,pins property contains these fields. + */ +struct pincfg { + uint32_t mux_reg; + uint32_t padconf_reg; + uint32_t input_reg; + uint32_t mux_val; + uint32_t input_val; + uint32_t padconf_val; +}; + +#define PADCONF_NONE (1U << 31) /* Do not configure pad. */ +#define PADCONF_SION (1U << 30) /* Force SION bit in mux register. */ +#define PADMUX_SION (1U << 4) /* The SION bit in the mux register. */ + +static inline uint32_t +RD4(struct iomux_softc *sc, bus_size_t off) +{ + +#ifndef __rtems__ + return (bus_read_4(sc->mem_res, off)); +#else /* __rtems__ */ + return (sc->regs[off / 4]); +#endif /* __rtems__ */ +} + +static inline void +WR4(struct iomux_softc *sc, bus_size_t off, uint32_t val) +{ + +#ifndef __rtems__ + bus_write_4(sc->mem_res, off, val); +#else /* __rtems__ */ + sc->regs[off / 4] = val; +#endif /* __rtems__ */ +} + +static void +iomux_configure_input(struct iomux_softc *sc, uint32_t reg, uint32_t val) +{ + u_int select, mask, shift, width; + + /* If register and value are zero, there is nothing to configure. */ + if (reg == 0 && val == 0) + return; + + /* + * If the config value has 0xff in the high byte it is encoded: + * 31 23 15 7 0 + * | 0xff | shift | width | select | + * We need to mask out the old select value and OR in the new, using a + * mask of the given width and shifting the values up by shift. + */ + if ((val & 0xff000000) == 0xff000000) { + select = val & 0x000000ff; + width = (val & 0x0000ff00) >> 8; + shift = (val & 0x00ff0000) >> 16; + mask = ((1u << width) - 1) << shift; + val = (RD4(sc, reg) & ~mask) | (select << shift); + } + WR4(sc, reg, val); +} + +#ifndef __rtems__ +static int +iomux_configure_pins(device_t dev, phandle_t cfgxref) +#else /* __rtems__ */ +int imx_iomux_configure_pins(const void *fdt, uint32_t cfgxref) +#endif /* __rtems__ */ +{ + struct iomux_softc *sc; + struct pincfg *cfgtuples, *cfg; + phandle_t cfgnode; + int i, ntuples; + uint32_t sion; + +#ifndef __rtems__ + sc = device_get_softc(dev); +#else /* __rtems__ */ + sc = iomux_sc; +#endif /* __rtems__ */ + cfgnode = OF_node_from_xref(cfgxref); + ntuples = OF_getencprop_alloc(cfgnode, "fsl,pins", sizeof(*cfgtuples), + (void **)&cfgtuples); + if (ntuples < 0) + return (ENOENT); + if (ntuples == 0) + return (0); /* Empty property is not an error. */ + for (i = 0, cfg = cfgtuples; i < ntuples; i++, cfg++) { + sion = (cfg->padconf_val & PADCONF_SION) ? PADMUX_SION : 0; + WR4(sc, cfg->mux_reg, cfg->mux_val | sion); + iomux_configure_input(sc, cfg->input_reg, cfg->input_val); + if ((cfg->padconf_val & PADCONF_NONE) == 0) + WR4(sc, cfg->padconf_reg, cfg->padconf_val); +#ifndef __rtems__ + if (bootverbose) { + char name[32]; + OF_getprop(cfgnode, "name", &name, sizeof(name)); + printf("%16s: muxreg 0x%04x muxval 0x%02x " + "inpreg 0x%04x inpval 0x%02x " + "padreg 0x%04x padval 0x%08x\n", + name, cfg->mux_reg, cfg->mux_val | sion, + cfg->input_reg, cfg->input_val, + cfg->padconf_reg, cfg->padconf_val); + } +#endif /* __rtems__ */ + } + OF_prop_free(cfgtuples); + return (0); +} + +#ifndef __rtems__ +static int +iomux_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) + return (ENXIO); + + device_set_desc(dev, "Freescale i.MX pin configuration"); + return (BUS_PROBE_DEFAULT); +} + +static int +iomux_detach(device_t dev) +{ + + /* This device is always present. */ + return (EBUSY); +} + +static int +iomux_attach(device_t dev) +{ + struct iomux_softc * sc; + int rid; + + sc = device_get_softc(dev); + sc->dev = dev; + + switch (imx_soc_type()) { + case IMXSOC_51: + sc->last_gpregaddr = 1 * sizeof(uint32_t); + break; + case IMXSOC_53: + sc->last_gpregaddr = 2 * sizeof(uint32_t); + break; + case IMXSOC_6DL: + case IMXSOC_6S: + case IMXSOC_6SL: + case IMXSOC_6Q: + sc->last_gpregaddr = 13 * sizeof(uint32_t); + break; + case IMXSOC_6UL: + sc->last_gpregaddr = 14 * sizeof(uint32_t); + break; + default: + device_printf(dev, "Unknown SoC type\n"); + return (ENXIO); + } + + rid = 0; + sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->mem_res == NULL) { + device_printf(dev, "Cannot allocate memory resources\n"); + return (ENXIO); + } + + iomux_sc = sc; + + /* + * Register as a pinctrl device, and call the convenience function that + * walks the entire device tree invoking FDT_PINCTRL_CONFIGURE() on any + * pinctrl-0 property cells whose xref phandle refers to a configuration + * that is a child node of our node in the tree. + * + * The pinctrl bindings documentation specifically mentions that the + * pinctrl device itself may have a pinctrl-0 property which contains + * static configuration to be applied at device init time. The tree + * walk will automatically handle this for us when it passes through our + * node in the tree. + */ + fdt_pinctrl_register(dev, "fsl,pins"); + fdt_pinctrl_configure_tree(dev); + + return (0); +} + +uint32_t +imx_iomux_gpr_get(u_int regaddr) +{ + struct iomux_softc * sc; + + sc = iomux_sc; + KASSERT(sc != NULL, ("%s called before attach", __FUNCTION__)); + KASSERT(regaddr >= 0 && regaddr <= sc->last_gpregaddr, + ("%s bad regaddr %u, max %u", __FUNCTION__, regaddr, + sc->last_gpregaddr)); + + return (RD4(iomux_sc, regaddr)); +} + +void +imx_iomux_gpr_set(u_int regaddr, uint32_t val) +{ + struct iomux_softc * sc; + + sc = iomux_sc; + KASSERT(sc != NULL, ("%s called before attach", __FUNCTION__)); + KASSERT(regaddr >= 0 && regaddr <= sc->last_gpregaddr, + ("%s bad regaddr %u, max %u", __FUNCTION__, regaddr, + sc->last_gpregaddr)); + + WR4(iomux_sc, regaddr, val); +} + +void +imx_iomux_gpr_set_masked(u_int regaddr, uint32_t clrbits, uint32_t setbits) +{ + struct iomux_softc * sc; + uint32_t val; + + sc = iomux_sc; + KASSERT(sc != NULL, ("%s called before attach", __FUNCTION__)); + KASSERT(regaddr >= 0 && regaddr <= sc->last_gpregaddr, + ("%s bad regaddr %u, max %u", __FUNCTION__, regaddr, + sc->last_gpregaddr)); + + val = RD4(iomux_sc, regaddr * 4); + val = (val & ~clrbits) | setbits; + WR4(iomux_sc, regaddr, val); +} + +static device_method_t imx_iomux_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, iomux_probe), + DEVMETHOD(device_attach, iomux_attach), + DEVMETHOD(device_detach, iomux_detach), + + /* fdt_pinctrl interface */ + DEVMETHOD(fdt_pinctrl_configure,iomux_configure_pins), + + DEVMETHOD_END +}; + +static driver_t imx_iomux_driver = { + "imx_iomux", + imx_iomux_methods, + sizeof(struct iomux_softc), +}; + +static devclass_t imx_iomux_devclass; + +EARLY_DRIVER_MODULE(imx_iomux, simplebus, imx_iomux_driver, + imx_iomux_devclass, 0, 0, BUS_PASS_CPU + BUS_PASS_ORDER_LATE); + +#endif /* __rtems__ */ diff --git a/c/src/lib/libbsp/arm/imx/Makefile.am b/c/src/lib/libbsp/arm/imx/Makefile.am index ad221f7576..80871a286c 100644 --- a/c/src/lib/libbsp/arm/imx/Makefile.am +++ b/c/src/lib/libbsp/arm/imx/Makefile.am @@ -43,7 +43,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/cp15/arm-cp15-set-ttb librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/imx/start/bspreset.c librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/imx/start/bspstart.c librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/imx/start/ccm.c -librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/imx/start/imx_iomux.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/pins/imx_iomux.c if HAS_SMP librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/start/arm-a9mpcore-smp.c librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/imx/start/bspsmp.c diff --git a/spec/build/bsps/arm/imx/bspimx.yml b/spec/build/bsps/arm/imx/bspimx.yml index 48d41890c7..442c631b3a 100644 --- a/spec/build/bsps/arm/imx/bspimx.yml +++ b/spec/build/bsps/arm/imx/bspimx.yml @@ -8,7 +8,8 @@ copyrights: cppflags: [] enabled-by: true family: imx -includes: [] +includes: + - bsps/arm/shared/include install: - destination: ${BSP_INCLUDEDIR} source: @@ -20,8 +21,8 @@ install: - bsps/arm/imx/include/arm/freescale/imx/imx_ecspireg.h - bsps/arm/imx/include/arm/freescale/imx/imx_gpcreg.h - bsps/arm/imx/include/arm/freescale/imx/imx_i2creg.h - - bsps/arm/imx/include/arm/freescale/imx/imx_iomuxreg.h - - bsps/arm/imx/include/arm/freescale/imx/imx_iomuxvar.h + - bsps/arm/shared/include/arm/freescale/imx/imx_iomuxreg.h + - bsps/arm/shared/include/arm/freescale/imx/imx_iomuxvar.h - bsps/arm/imx/include/arm/freescale/imx/imx_srcreg.h - bsps/arm/imx/include/arm/freescale/imx/imx_uartreg.h - bsps/arm/imx/include/arm/freescale/imx/imx_wdogreg.h @@ -29,6 +30,7 @@ install: source: - bsps/arm/imx/include/bsp/imx-gpio.h - bsps/arm/imx/include/bsp/irq.h + - bsps/arm/shared/include/bsp/imx-iomux.h - destination: ${BSP_INCLUDEDIR}/dev/clock source: - bsps/include/dev/clock/arm-generic-timer.h @@ -88,7 +90,7 @@ source: - bsps/arm/imx/start/bspstart.c - bsps/arm/imx/start/bspstarthooks.c - bsps/arm/imx/start/ccm.c -- bsps/arm/imx/start/imx_iomux.c +- bsps/arm/shared/pins/imx_iomux.c - bsps/arm/shared/cache/cache-cp15.c - bsps/arm/shared/cache/cache-v7ar-disable-data.S - bsps/shared/dev/clock/arm-generic-timer.c -- cgit v1.2.3