diff options
Diffstat (limited to 'roms/u-boot/drivers/pinctrl/nxp')
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/Kconfig | 128 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/Makefile | 11 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx.c | 274 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx.h | 68 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx5.c | 44 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx6.c | 55 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx7.c | 41 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx7ulp.c | 45 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx8.c | 42 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx8m.c | 38 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/pinctrl-imxrt.c | 40 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/pinctrl-mxs.c | 196 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/pinctrl-mxs.h | 61 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/pinctrl-scu.c | 71 | ||||
-rw-r--r-- | roms/u-boot/drivers/pinctrl/nxp/pinctrl-vf610.c | 40 |
15 files changed, 1154 insertions, 0 deletions
diff --git a/roms/u-boot/drivers/pinctrl/nxp/Kconfig b/roms/u-boot/drivers/pinctrl/nxp/Kconfig new file mode 100644 index 000000000..ec55351e6 --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/Kconfig @@ -0,0 +1,128 @@ +config PINCTRL_IMX + bool + +config PINCTRL_IMX_SCU + bool + +config PINCTRL_IMX5 + bool "IMX5 pinctrl driver" + depends on ARCH_MX5 && PINCTRL_FULL + select DEVRES + select PINCTRL_IMX + help + Say Y here to enable the imx5 pinctrl driver + + This provides a simple pinctrl driver for i.MX 53SoC familiy, + i.MX53. This feature depends on device tree + configuration. This driver is different from the linux one, + this is a simple implementation, only parses the 'fsl,pins' + property and configure related registers. + +config PINCTRL_IMX6 + bool "IMX6 pinctrl driver" + depends on ARCH_MX6 && PINCTRL_FULL + select DEVRES + select PINCTRL_IMX + help + Say Y here to enable the imx6 pinctrl driver + + This provides a simple pinctrl driver for i.MX6 SoC familiy, + i.MX6DQ/SL/SX/UL/DQP. This feature depends on device tree + configuration. This driver is different from the linux one, + this is a simple implementation, only parses the 'fsl,pins' + property and configure related registers. + +config PINCTRL_IMX7 + bool "IMX7 pinctrl driver" + depends on ARCH_MX7 && PINCTRL_FULL + select DEVRES + select PINCTRL_IMX + help + Say Y here to enable the imx7 pinctrl driver + + This provides a simple pinctrl driver for i.MX7 SoC familiy, + i.MX7D. This feature depends on device tree + configuration. This driver is different from the linux one, + this is a simple implementation, only parses the 'fsl,pins' + property and configure related registers. + +config PINCTRL_IMX7ULP + bool "IMX7ULP pinctrl driver" + depends on ARCH_MX7ULP && PINCTRL_FULL + select DEVRES + select PINCTRL_IMX + help + Say Y here to enable the imx7ulp pinctrl driver + + This provides a simple pinctrl driver for i.MX7ULP SoC familiy. + This feature depends on device tree configuration. This driver + is different from the linux one, this is a simple implementation, + only parses the 'fsl,pins' property and configure related + registers. + +config PINCTRL_IMX8 + bool "IMX8 pinctrl driver" + depends on ARCH_IMX8 && PINCTRL_FULL + select DEVRES + select PINCTRL_IMX + select PINCTRL_IMX_SCU + help + Say Y here to enable the imx8 pinctrl driver + + This provides a simple pinctrl driver for i.MX8 SoC familiy. + This feature depends on device tree configuration. This driver + is different from the linux one, this is a simple implementation, + only parses the 'fsl,pins' property and configures related + registers. + +config PINCTRL_IMX8M + bool "IMX8M pinctrl driver" + depends on ARCH_IMX8M && PINCTRL_FULL + select DEVRES + select PINCTRL_IMX + help + Say Y here to enable the imx8m pinctrl driver + + This provides a simple pinctrl driver for i.MX8M SoC familiy. + This feature depends on device tree configuration. This driver + is different from the linux one, this is a simple implementation, + only parses the 'fsl,pins' property and configure related + registers. + +config PINCTRL_MXS + bool "NXP MXS pinctrl driver" + depends on ARCH_MX28 && PINCTRL_FULL + help + Say Y here to enable the i.MX mxs pinctrl driver + + This option provides a simple pinctrl driver for i.MX mxs SoC + familiy, e.g. i.MX28. This feature depends on device tree + configuration. + +config PINCTRL_IMXRT + bool "IMXRT pinctrl driver" + depends on ARCH_IMXRT && PINCTRL_FULL + select DEVRES + select PINCTRL_IMX + help + Say Y here to enable the imxrt pinctrl driver + + This provides a simple pinctrl driver for i.MXRT SoC familiy. + This feature depends on device tree configuration. This driver + is different from the linux one, this is a simple implementation, + only parses the 'fsl,pins' property and configure related + registers. + +config PINCTRL_VYBRID + bool "Vybrid (vf610) pinctrl driver" + depends on ARCH_VF610 && PINCTRL_FULL + select DEVRES + select PINCTRL_IMX + help + Say Y here to enable the Vybrid (vf610) pinctrl driver + + This provides a simple pinctrl driver for Vybrid SoC familiy, + vf610. This feature depends on device tree + configuration. This driver is different from the linux one, + this is a simple implementation, only parses the 'fsl,pins' + property and configure related registers. diff --git a/roms/u-boot/drivers/pinctrl/nxp/Makefile b/roms/u-boot/drivers/pinctrl/nxp/Makefile new file mode 100644 index 000000000..066ca75b6 --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/Makefile @@ -0,0 +1,11 @@ +obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o +obj-$(CONFIG_PINCTRL_IMX5) += pinctrl-imx5.o +obj-$(CONFIG_PINCTRL_IMX6) += pinctrl-imx6.o +obj-$(CONFIG_PINCTRL_IMX7) += pinctrl-imx7.o +obj-$(CONFIG_PINCTRL_IMX7ULP) += pinctrl-imx7ulp.o +obj-$(CONFIG_PINCTRL_IMX_SCU) += pinctrl-scu.o +obj-$(CONFIG_PINCTRL_IMX8) += pinctrl-imx8.o +obj-$(CONFIG_PINCTRL_IMX8M) += pinctrl-imx8m.o +obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o +obj-$(CONFIG_PINCTRL_VYBRID) += pinctrl-vf610.o +obj-$(CONFIG_PINCTRL_IMXRT) += pinctrl-imxrt.o diff --git a/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx.c b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx.c new file mode 100644 index 000000000..1596dcc47 --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx.c @@ -0,0 +1,274 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com> + */ + +#include <common.h> +#include <malloc.h> +#include <mapmem.h> +#include <asm/global_data.h> +#include <dm/device_compat.h> +#include <dm/devres.h> +#include <linux/bitops.h> +#include <linux/io.h> +#include <linux/err.h> +#include <dm.h> +#include <dm/pinctrl.h> + +#include "pinctrl-imx.h" + +DECLARE_GLOBAL_DATA_PTR; + +static int imx_pinctrl_set_state(struct udevice *dev, struct udevice *config) +{ + struct imx_pinctrl_priv *priv = dev_get_priv(dev); + struct imx_pinctrl_soc_info *info = priv->info; + int node = dev_of_offset(config); + const struct fdt_property *prop; + u32 *pin_data; + int npins, size, pin_size; + int mux_reg, conf_reg, input_reg; + u32 input_val, mux_mode, config_val; + u32 mux_shift = info->mux_mask ? ffs(info->mux_mask) - 1 : 0; + int i, j = 0; + + dev_dbg(dev, "%s: %s\n", __func__, config->name); + + if (info->flags & IMX8_USE_SCU) + pin_size = SHARE_IMX8_PIN_SIZE; + else if (info->flags & SHARE_MUX_CONF_REG) + pin_size = SHARE_FSL_PIN_SIZE; + else + pin_size = FSL_PIN_SIZE; + + prop = fdt_getprop(gd->fdt_blob, node, "fsl,pins", &size); + if (!prop) { + dev_err(dev, "No fsl,pins property in node %s\n", config->name); + return -EINVAL; + } + + if (!size || size % pin_size) { + dev_err(dev, "Invalid fsl,pins property in node %s\n", + config->name); + return -EINVAL; + } + + pin_data = devm_kzalloc(dev, size, 0); + if (!pin_data) + return -ENOMEM; + + if (fdtdec_get_int_array(gd->fdt_blob, node, "fsl,pins", + pin_data, size >> 2)) { + dev_err(dev, "Error reading pin data.\n"); + devm_kfree(dev, pin_data); + return -EINVAL; + } + + npins = size / pin_size; + + if (info->flags & IMX8_USE_SCU) { + imx_pinctrl_scu_conf_pins(info, pin_data, npins); + } else { + /* + * Refer to linux documentation for details: + * Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt + */ + for (i = 0; i < npins; i++) { + mux_reg = pin_data[j++]; + + if (!(info->flags & ZERO_OFFSET_VALID) && !mux_reg) + mux_reg = -1; + + if (info->flags & SHARE_MUX_CONF_REG) { + conf_reg = mux_reg; + } else { + conf_reg = pin_data[j++]; + if (!(info->flags & ZERO_OFFSET_VALID) && + !conf_reg) + conf_reg = -1; + } + + if ((mux_reg == -1) || (conf_reg == -1)) { + dev_err(dev, "Error mux_reg or conf_reg\n"); + devm_kfree(dev, pin_data); + return -EINVAL; + } + + input_reg = pin_data[j++]; + mux_mode = pin_data[j++]; + input_val = pin_data[j++]; + config_val = pin_data[j++]; + + dev_dbg(dev, "mux_reg 0x%x, conf_reg 0x%x, " + "input_reg 0x%x, mux_mode 0x%x, " + "input_val 0x%x, config_val 0x%x\n", + mux_reg, conf_reg, input_reg, mux_mode, + input_val, config_val); + + if (config_val & IMX_PAD_SION) + mux_mode |= IOMUXC_CONFIG_SION; + + config_val &= ~IMX_PAD_SION; + + /* Set Mux */ + if (info->flags & SHARE_MUX_CONF_REG) { + clrsetbits_le32(info->base + mux_reg, + info->mux_mask, + mux_mode << mux_shift); + } else { + writel(mux_mode, info->base + mux_reg); + } + + dev_dbg(dev, "write mux: offset 0x%x val 0x%x\n", + mux_reg, mux_mode); + + /* + * Set select input + * + * If the select input value begins with 0xff, + * it's a quirky select input and the value should + * be interpreted as below. + * 31 23 15 7 0 + * | 0xff | shift | width | select | + * It's used to work around the problem that the + * select input for some pin is not implemented in + * the select input register but in some general + * purpose register. We encode the select input + * value, width and shift of the bit field into + * input_val cell of pin function ID in device tree, + * and then decode them here for setting up the select + * input bits in general purpose register. + */ + + if (input_val >> 24 == 0xff) { + u32 val = input_val; + u8 select = val & 0xff; + u8 width = (val >> 8) & 0xff; + u8 shift = (val >> 16) & 0xff; + u32 mask = ((1 << width) - 1) << shift; + /* + * The input_reg[i] here is actually some + * IOMUXC general purpose register, not + * regular select input register. + */ + val = readl(info->base + input_reg); + val &= ~mask; + val |= select << shift; + writel(val, info->base + input_reg); + } else if (input_reg) { + /* + * Regular select input register can never be + * at offset 0, and we only print register + * value for regular case. + */ + if (info->input_sel_base) + writel(input_val, + info->input_sel_base + + input_reg); + else + writel(input_val, + info->base + input_reg); + + dev_dbg(dev, "select_input: offset 0x%x val " + "0x%x\n", input_reg, input_val); + } + + /* Set config */ + if (!(config_val & IMX_NO_PAD_CTL)) { + if (info->flags & SHARE_MUX_CONF_REG) { + clrsetbits_le32(info->base + conf_reg, + ~info->mux_mask, + config_val); + } else { + writel(config_val, + info->base + conf_reg); + } + + dev_dbg(dev, "write config: offset 0x%x val " + "0x%x\n", conf_reg, config_val); + } + } + } + + devm_kfree(dev, pin_data); + + return 0; +} + +const struct pinctrl_ops imx_pinctrl_ops = { + .set_state = imx_pinctrl_set_state, +}; + +int imx_pinctrl_probe(struct udevice *dev, + struct imx_pinctrl_soc_info *info) +{ + struct imx_pinctrl_priv *priv = dev_get_priv(dev); + int node = dev_of_offset(dev), ret; + struct fdtdec_phandle_args arg; + fdt_addr_t addr; + fdt_size_t size; + + if (!info) { + dev_err(dev, "wrong pinctrl info\n"); + return -EINVAL; + } + + priv->dev = dev; + priv->info = info; + + if (info->flags & IMX8_USE_SCU) + return 0; + + addr = devfdt_get_addr_size_index(dev, 0, &size); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + info->base = map_sysmem(addr, size); + if (!info->base) + return -ENOMEM; + priv->info = info; + + info->mux_mask = fdtdec_get_int(gd->fdt_blob, node, "fsl,mux_mask", 0); + /* + * Refer to linux documentation for details: + * Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt + */ + if (fdtdec_get_bool(gd->fdt_blob, node, "fsl,input-sel")) { + ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, + node, "fsl,input-sel", + NULL, 0, 0, &arg); + if (ret) { + dev_err(dev, "iomuxc fsl,input-sel property not found\n"); + return -EINVAL; + } + + addr = fdtdec_get_addr_size(gd->fdt_blob, arg.node, "reg", + &size); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + info->input_sel_base = map_sysmem(addr, size); + if (!info->input_sel_base) + return -ENOMEM; + } + + dev_dbg(dev, "initialized IMX pinctrl driver\n"); + + return 0; +} + +int imx_pinctrl_remove(struct udevice *dev) +{ + struct imx_pinctrl_priv *priv = dev_get_priv(dev); + struct imx_pinctrl_soc_info *info = priv->info; + + if (info->flags & IMX8_USE_SCU) + return 0; + + if (info->input_sel_base) + unmap_sysmem(info->input_sel_base); + if (info->base) + unmap_sysmem(info->base); + + return 0; +} diff --git a/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx.h b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx.h new file mode 100644 index 000000000..947975ee7 --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com> + */ + +#ifndef __DRIVERS_PINCTRL_IMX_H +#define __DRIVERS_PINCTRL_IMX_H + +/** + * @base: the address to the controller in virtual memory + * @input_sel_base: the address of the select input in virtual memory. + * @flags: flags specific for each soc + * @mux_mask: Used when SHARE_MUX_CONF_REG flag is added + */ +struct imx_pinctrl_soc_info { + void __iomem *base; + void __iomem *input_sel_base; + unsigned int flags; + unsigned int mux_mask; +}; + +/** + * @dev: a pointer back to containing device + * @info: the soc info + */ +struct imx_pinctrl_priv { + struct udevice *dev; + struct imx_pinctrl_soc_info *info; +}; + +extern const struct pinctrl_ops imx_pinctrl_ops; + +#define IMX_NO_PAD_CTL 0x80000000 /* no pin config need */ +#define IMX_PAD_SION 0x40000000 /* set SION */ + +/* + * Each pin represented in fsl,pins consists of 5 u32 PIN_FUNC_ID and + * 1 u32 CONFIG, so 24 types in total for each pin. + */ +#define FSL_PIN_SIZE 24 +#define SHARE_FSL_PIN_SIZE 20 + +/* Each pin on imx8qm/qxp consists of 2 u32 PIN_FUNC_ID and 1 u32 CONFIG */ +#define SHARE_IMX8_PIN_SIZE 12 + +#define SHARE_MUX_CONF_REG 0x1 +#define ZERO_OFFSET_VALID 0x2 +#define CONFIG_IBE_OBE 0x4 +#define IMX8_USE_SCU 0x8 + +#define IOMUXC_CONFIG_SION (0x1 << 4) + +int imx_pinctrl_probe(struct udevice *dev, struct imx_pinctrl_soc_info *info); + +int imx_pinctrl_remove(struct udevice *dev); + +#ifdef CONFIG_PINCTRL_IMX_SCU +int imx_pinctrl_scu_conf_pins(struct imx_pinctrl_soc_info *info, + u32 *pin_data, int npins); +#else +static inline int imx_pinctrl_scu_conf_pins(struct imx_pinctrl_soc_info *info, + u32 *pin_data, int npins) +{ + return 0; +} +#endif + +#endif /* __DRIVERS_PINCTRL_IMX_H */ diff --git a/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx5.c b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx5.c new file mode 100644 index 000000000..b32b748cf --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx5.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com> + */ + +#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> + +#include "pinctrl-imx.h" + +static struct imx_pinctrl_soc_info imx5_pinctrl_soc_info __section(".data"); + +static int imx5_pinctrl_probe(struct udevice *dev) +{ + struct imx_pinctrl_soc_info *info = + (struct imx_pinctrl_soc_info *)dev_get_driver_data(dev); + + return imx_pinctrl_probe(dev, info); +} + +static const struct udevice_id imx5_pinctrl_match[] = { + { + .compatible = "fsl,imx53-iomuxc", + .data = (ulong)&imx5_pinctrl_soc_info + }, + { + .compatible = "fsl,imx53-iomuxc-gpr", + .data = (ulong)&imx5_pinctrl_soc_info + }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(imx5_pinctrl) = { + .name = "imx5-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(imx5_pinctrl_match), + .probe = imx5_pinctrl_probe, + .remove = imx_pinctrl_remove, + .priv_auto = sizeof(struct imx_pinctrl_priv), + .ops = &imx_pinctrl_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx6.c b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx6.c new file mode 100644 index 000000000..6994dbb61 --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx6.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com> + */ + +#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> + +#include "pinctrl-imx.h" + +static struct imx_pinctrl_soc_info imx6_pinctrl_soc_info __section(".data"); + +/* FIXME Before reloaction, BSS is overlapped with DT area */ +static struct imx_pinctrl_soc_info imx6ul_pinctrl_soc_info = { + .flags = ZERO_OFFSET_VALID, +}; + +static struct imx_pinctrl_soc_info imx6_snvs_pinctrl_soc_info = { + .flags = ZERO_OFFSET_VALID, +}; + +static int imx6_pinctrl_probe(struct udevice *dev) +{ + struct imx_pinctrl_soc_info *info = + (struct imx_pinctrl_soc_info *)dev_get_driver_data(dev); + + return imx_pinctrl_probe(dev, info); +} + +static const struct udevice_id imx6_pinctrl_match[] = { + { .compatible = "fsl,imx6q-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info }, + { .compatible = "fsl,imx6dl-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info }, + { .compatible = "fsl,imx6sl-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info }, + { .compatible = "fsl,imx6sll-iomuxc-snvs", .data = (ulong)&imx6_snvs_pinctrl_soc_info }, + { .compatible = "fsl,imx6sll-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info }, + { .compatible = "fsl,imx6sx-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info }, + { .compatible = "fsl,imx6ul-iomuxc", .data = (ulong)&imx6ul_pinctrl_soc_info }, + { .compatible = "fsl,imx6ull-iomuxc-snvs", .data = (ulong)&imx6_snvs_pinctrl_soc_info }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(fsl_imx6q_iomuxc) = { + .name = "fsl_imx6q_iomuxc", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(imx6_pinctrl_match), + .probe = imx6_pinctrl_probe, + .remove = imx_pinctrl_remove, + .priv_auto = sizeof(struct imx_pinctrl_priv), + .ops = &imx_pinctrl_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +DM_DRIVER_ALIAS(fsl_imx6q_iomuxc, fsl_imx6dl_iomuxc) diff --git a/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx7.c b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx7.c new file mode 100644 index 000000000..77ddb8e0b --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx7.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com> + */ + +#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> + +#include "pinctrl-imx.h" + +static struct imx_pinctrl_soc_info imx7_pinctrl_soc_info __section(".data"); + +static struct imx_pinctrl_soc_info imx7_lpsr_pinctrl_soc_info = { + .flags = ZERO_OFFSET_VALID, +}; + +static int imx7_pinctrl_probe(struct udevice *dev) +{ + struct imx_pinctrl_soc_info *info = + (struct imx_pinctrl_soc_info *)dev_get_driver_data(dev); + + return imx_pinctrl_probe(dev, info); +} + +static const struct udevice_id imx7_pinctrl_match[] = { + { .compatible = "fsl,imx7d-iomuxc", .data = (ulong)&imx7_pinctrl_soc_info }, + { .compatible = "fsl,imx7d-iomuxc-lpsr", .data = (ulong)&imx7_lpsr_pinctrl_soc_info }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(imx7_pinctrl) = { + .name = "imx7-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(imx7_pinctrl_match), + .probe = imx7_pinctrl_probe, + .remove = imx_pinctrl_remove, + .priv_auto = sizeof(struct imx_pinctrl_priv), + .ops = &imx_pinctrl_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx7ulp.c b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx7ulp.c new file mode 100644 index 000000000..da0f6c9ba --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx7ulp.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * + * Peng Fan <peng.fan@nxp.com> + */ + +#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> + +#include "pinctrl-imx.h" + +static struct imx_pinctrl_soc_info imx7ulp_pinctrl_soc_info0 = { + .flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG | CONFIG_IBE_OBE, +}; + +static struct imx_pinctrl_soc_info imx7ulp_pinctrl_soc_info1 = { + .flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG | CONFIG_IBE_OBE, +}; + +static int imx7ulp_pinctrl_probe(struct udevice *dev) +{ + struct imx_pinctrl_soc_info *info = + (struct imx_pinctrl_soc_info *)dev_get_driver_data(dev); + + return imx_pinctrl_probe(dev, info); +} + +static const struct udevice_id imx7ulp_pinctrl_match[] = { + { .compatible = "fsl,imx7ulp-iomuxc-0", .data = (ulong)&imx7ulp_pinctrl_soc_info0 }, + { .compatible = "fsl,imx7ulp-iomuxc-1", .data = (ulong)&imx7ulp_pinctrl_soc_info1 }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(imx7ulp_pinctrl) = { + .name = "imx7ulp-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(imx7ulp_pinctrl_match), + .probe = imx7ulp_pinctrl_probe, + .remove = imx_pinctrl_remove, + .priv_auto = sizeof(struct imx_pinctrl_priv), + .ops = &imx_pinctrl_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx8.c b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx8.c new file mode 100644 index 000000000..46af44ecb --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx8.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include <common.h> +#include <asm/global_data.h> +#include <dm/device.h> +#include <dm/pinctrl.h> + +#include "pinctrl-imx.h" + +DECLARE_GLOBAL_DATA_PTR; + +static struct imx_pinctrl_soc_info imx8_pinctrl_soc_info = { + .flags = IMX8_USE_SCU, +}; + +static int imx8_pinctrl_probe(struct udevice *dev) +{ + struct imx_pinctrl_soc_info *info = + (struct imx_pinctrl_soc_info *)dev_get_driver_data(dev); + + return imx_pinctrl_probe(dev, info); +} + +static const struct udevice_id imx8_pinctrl_match[] = { + { .compatible = "fsl,imx8qxp-iomuxc", .data = (ulong)&imx8_pinctrl_soc_info }, + { .compatible = "fsl,imx8qm-iomuxc", .data = (ulong)&imx8_pinctrl_soc_info }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(imx8_pinctrl) = { + .name = "imx8_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(imx8_pinctrl_match), + .probe = imx8_pinctrl_probe, + .remove = imx_pinctrl_remove, + .priv_auto = sizeof(struct imx_pinctrl_priv), + .ops = &imx_pinctrl_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx8m.c b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx8m.c new file mode 100644 index 000000000..6ea66a080 --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imx8m.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 NXP + */ + +#include <dm/device.h> +#include <dm/pinctrl.h> + +#include "pinctrl-imx.h" + +static struct imx_pinctrl_soc_info imx8mq_pinctrl_soc_info __section(".data"); + +static int imx8mq_pinctrl_probe(struct udevice *dev) +{ + struct imx_pinctrl_soc_info *info = + (struct imx_pinctrl_soc_info *)dev_get_driver_data(dev); + + return imx_pinctrl_probe(dev, info); +} + +static const struct udevice_id imx8m_pinctrl_match[] = { + { .compatible = "fsl,imx8mq-iomuxc", .data = (ulong)&imx8mq_pinctrl_soc_info }, + { .compatible = "fsl,imx8mm-iomuxc", .data = (ulong)&imx8mq_pinctrl_soc_info }, + { .compatible = "fsl,imx8mn-iomuxc", .data = (ulong)&imx8mq_pinctrl_soc_info }, + { .compatible = "fsl,imx8mp-iomuxc", .data = (ulong)&imx8mq_pinctrl_soc_info }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(imx8mq_pinctrl) = { + .name = "imx8mq-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(imx8m_pinctrl_match), + .probe = imx8mq_pinctrl_probe, + .remove = imx_pinctrl_remove, + .priv_auto = sizeof(struct imx_pinctrl_priv), + .ops = &imx_pinctrl_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imxrt.c b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imxrt.c new file mode 100644 index 000000000..53b70da86 --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-imxrt.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 + * Author(s): Giulio Benetti <giulio.benetti@benettiengineering.com> + */ + +#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> + +#include "pinctrl-imx.h" + +static struct imx_pinctrl_soc_info imxrt_pinctrl_soc_info = { + .flags = ZERO_OFFSET_VALID, +}; + +static int imxrt_pinctrl_probe(struct udevice *dev) +{ + struct imx_pinctrl_soc_info *info = + (struct imx_pinctrl_soc_info *)dev_get_driver_data(dev); + + return imx_pinctrl_probe(dev, info); +} + +static const struct udevice_id imxrt_pinctrl_match[] = { + { .compatible = "fsl,imxrt-iomuxc", + .data = (ulong)&imxrt_pinctrl_soc_info }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(imxrt_pinctrl) = { + .name = "imxrt-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(imxrt_pinctrl_match), + .probe = imxrt_pinctrl_probe, + .remove = imx_pinctrl_remove, + .priv_auto = sizeof(struct imx_pinctrl_priv), + .ops = &imx_pinctrl_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/roms/u-boot/drivers/pinctrl/nxp/pinctrl-mxs.c b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-mxs.c new file mode 100644 index 000000000..e6b10a377 --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-mxs.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + */ + +#include <common.h> +#include <log.h> +#include <asm/global_data.h> +#include <dm/device_compat.h> +#include <dm/devres.h> +#include <linux/io.h> +#include <linux/err.h> +#include <dm.h> +#include <dm/pinctrl.h> +#include <dm/read.h> +#include "pinctrl-mxs.h" + +DECLARE_GLOBAL_DATA_PTR; + +struct mxs_pinctrl_priv { + void __iomem *base; + const struct mxs_regs *regs; +}; + +static unsigned long mxs_dt_node_to_map(struct udevice *conf) +{ + unsigned long config = 0; + int ret; + u32 val; + + ret = dev_read_u32(conf, "fsl,drive-strength", &val); + if (!ret) + config = val | MA_PRESENT; + + ret = dev_read_u32(conf, "fsl,voltage", &val); + if (!ret) + config |= val << VOL_SHIFT | VOL_PRESENT; + + ret = dev_read_u32(conf, "fsl,pull-up", &val); + if (!ret) + config |= val << PULL_SHIFT | PULL_PRESENT; + + return config; +} + +static int mxs_pinctrl_set_mux(struct udevice *dev, u32 val, int bank, int pin) +{ + struct mxs_pinctrl_priv *iomux = dev_get_priv(dev); + int muxsel = MUXID_TO_MUXSEL(val), shift; + void __iomem *reg; + + reg = iomux->base + iomux->regs->muxsel; + reg += bank * 0x20 + pin / 16 * 0x10; + shift = pin % 16 * 2; + + mxs_pinctrl_rmwl(muxsel, 0x3, shift, reg); + debug(" mux %d,", muxsel); + + return 0; +} + +static int mxs_pinctrl_set_state(struct udevice *dev, struct udevice *conf) +{ + struct mxs_pinctrl_priv *iomux = dev_get_priv(dev); + u32 *pin_data, val, ma, vol, pull; + int npins, size, i, ret; + unsigned long config; + + debug("\n%s: set state: %s\n", __func__, conf->name); + + size = dev_read_size(conf, "fsl,pinmux-ids"); + if (size < 0) + return size; + + if (!size || size % sizeof(int)) { + dev_err(dev, "Invalid fsl,pinmux-ids property in %s\n", + conf->name); + return -EINVAL; + } + + npins = size / sizeof(int); + + pin_data = devm_kzalloc(dev, size, 0); + if (!pin_data) + return -ENOMEM; + + ret = dev_read_u32_array(conf, "fsl,pinmux-ids", pin_data, npins); + if (ret) { + dev_err(dev, "Error reading pin data.\n"); + devm_kfree(dev, pin_data); + return -EINVAL; + } + + config = mxs_dt_node_to_map(conf); + + ma = CONFIG_TO_MA(config); + vol = CONFIG_TO_VOL(config); + pull = CONFIG_TO_PULL(config); + + for (i = 0; i < npins; i++) { + int pinid, bank, pin, shift; + void __iomem *reg; + + val = pin_data[i]; + + pinid = MUXID_TO_PINID(val); + bank = PINID_TO_BANK(pinid); + pin = PINID_TO_PIN(pinid); + + debug("(val: 0x%x) pin %d,", val, pinid); + /* Setup pinmux */ + mxs_pinctrl_set_mux(dev, val, bank, pin); + + debug(" ma: %d, vol: %d, pull: %d\n", ma, vol, pull); + + /* drive */ + reg = iomux->base + iomux->regs->drive; + reg += bank * 0x40 + pin / 8 * 0x10; + + /* mA */ + if (config & MA_PRESENT) { + shift = pin % 8 * 4; + mxs_pinctrl_rmwl(ma, 0x3, shift, reg); + } + + /* vol */ + if (config & VOL_PRESENT) { + shift = pin % 8 * 4 + 2; + if (vol) + writel(1 << shift, reg + SET); + else + writel(1 << shift, reg + CLR); + } + + /* pull */ + if (config & PULL_PRESENT) { + reg = iomux->base + iomux->regs->pull; + reg += bank * 0x10; + shift = pin; + if (pull) + writel(1 << shift, reg + SET); + else + writel(1 << shift, reg + CLR); + } + } + + devm_kfree(dev, pin_data); + return 0; +} + +static struct pinctrl_ops mxs_pinctrl_ops = { + .set_state = mxs_pinctrl_set_state, +}; + +static int mxs_pinctrl_probe(struct udevice *dev) +{ + struct mxs_pinctrl_priv *iomux = dev_get_priv(dev); + + iomux->base = dev_read_addr_ptr(dev); + iomux->regs = (struct mxs_regs *)dev_get_driver_data(dev); + + return 0; +} + +static const struct mxs_regs imx23_regs = { + .muxsel = 0x100, + .drive = 0x200, + .pull = 0x400, +}; + +static const struct mxs_regs imx28_regs = { + .muxsel = 0x100, + .drive = 0x300, + .pull = 0x600, +}; + +static const struct udevice_id mxs_pinctrl_match[] = { + { .compatible = "fsl,imx23-pinctrl", .data = (ulong)&imx23_regs }, + { .compatible = "fsl,imx28-pinctrl", .data = (ulong)&imx28_regs }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(fsl_imx23_pinctrl) = { + .name = "fsl_imx23_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(mxs_pinctrl_match), + .probe = mxs_pinctrl_probe, +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + .bind = dm_scan_fdt_dev, +#endif + .priv_auto = sizeof(struct mxs_pinctrl_priv), + .ops = &mxs_pinctrl_ops, +}; + +DM_DRIVER_ALIAS(fsl_imx23_pinctrl, fsl_imx28_pinctrl) diff --git a/roms/u-boot/drivers/pinctrl/nxp/pinctrl-mxs.h b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-mxs.h new file mode 100644 index 000000000..a398e43cb --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-mxs.h @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + */ + +#ifndef __PINCTRL_MXS_H +#define __PINCTRL_MXS_H + +#include <dm/pinctrl.h> + +#define SET 0x4 +#define CLR 0x8 +#define TOG 0xc + +#define MXS_PINCTRL_PIN(pin) PINCTRL_PIN(pin, #pin) +#define PINID(bank, pin) ((bank) * 32 + (pin)) + +/* + * pinmux-id bit field definitions + * + * bank: 15..12 (4) + * pin: 11..4 (8) + * muxsel: 3..0 (4) + */ +#define MUXID_TO_PINID(m) PINID((m) >> 12 & 0xf, (m) >> 4 & 0xff) +#define MUXID_TO_MUXSEL(m) ((m) & 0xf) + +#define PINID_TO_BANK(p) ((p) >> 5) +#define PINID_TO_PIN(p) ((p) % 32) + +/* + * pin config bit field definitions + * + * pull-up: 6..5 (2) + * voltage: 4..3 (2) + * mA: 2..0 (3) + * + * MSB of each field is presence bit for the config. + */ +#define PULL_PRESENT (1 << 6) +#define PULL_SHIFT 5 +#define VOL_PRESENT (1 << 4) +#define VOL_SHIFT 3 +#define MA_PRESENT (1 << 2) +#define MA_SHIFT 0 +#define CONFIG_TO_PULL(c) ((c) >> PULL_SHIFT & 0x1) +#define CONFIG_TO_VOL(c) ((c) >> VOL_SHIFT & 0x1) +#define CONFIG_TO_MA(c) ((c) >> MA_SHIFT & 0x3) + +struct mxs_regs { + u16 muxsel; + u16 drive; + u16 pull; +}; + +static inline void mxs_pinctrl_rmwl(u32 value, u32 mask, u8 shift, + void __iomem *reg) +{ + clrsetbits_le32(reg, mask << shift, value << shift); +} +#endif /* __PINCTRL_MXS_H */ diff --git a/roms/u-boot/drivers/pinctrl/nxp/pinctrl-scu.c b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-scu.c new file mode 100644 index 000000000..c032be782 --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-scu.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018-2019 NXP + */ + +#include <common.h> +#include <errno.h> +#include <linux/bitops.h> +#include <asm/io.h> +#include <asm/arch/sci/sci.h> +#include <misc.h> + +#include "pinctrl-imx.h" + +#define PADRING_IFMUX_EN_SHIFT 31 +#define PADRING_IFMUX_EN_MASK BIT(31) +#define PADRING_GP_EN_SHIFT 30 +#define PADRING_GP_EN_MASK BIT(30) +#define PADRING_IFMUX_SHIFT 27 +#define PADRING_IFMUX_MASK GENMASK(29, 27) + +static int imx_pinconf_scu_set(struct imx_pinctrl_soc_info *info, u32 pad, + u32 mux, u32 val) +{ + int ret; + + /* + * Mux should be done in pmx set, but we do not have a good api + * to handle that in scfw, so config it in pad conf func + */ + + if (!sc_rm_is_pad_owned(-1, pad)) { + debug("Pad[%u] is not owned by curr partition\n", pad); + return -EPERM; + } + + val |= PADRING_IFMUX_EN_MASK; + val |= PADRING_GP_EN_MASK; + val |= (mux << PADRING_IFMUX_SHIFT) & PADRING_IFMUX_MASK; + + ret = sc_pad_set(-1, pad, val); + if (ret) + printf("%s %d\n", __func__, ret); + + return 0; +} + +int imx_pinctrl_scu_conf_pins(struct imx_pinctrl_soc_info *info, u32 *pin_data, + int npins) +{ + int pin_id, mux, config_val; + int i, j = 0; + int ret; + + /* + * Refer to linux documentation for details: + * Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt + */ + for (i = 0; i < npins; i++) { + pin_id = pin_data[j++]; + mux = pin_data[j++]; + config_val = pin_data[j++]; + + ret = imx_pinconf_scu_set(info, pin_id, mux, config_val); + if (ret && ret != -EPERM) + printf("Set pin %d, mux %d, val %d, error\n", pin_id, + mux, config_val); + } + + return 0; +} diff --git a/roms/u-boot/drivers/pinctrl/nxp/pinctrl-vf610.c b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-vf610.c new file mode 100644 index 000000000..14e2e9d3e --- /dev/null +++ b/roms/u-boot/drivers/pinctrl/nxp/pinctrl-vf610.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + */ + +#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> + +#include "pinctrl-imx.h" + +static struct imx_pinctrl_soc_info vf610_pinctrl_soc_info = { + .flags = SHARE_MUX_CONF_REG | ZERO_OFFSET_VALID, +}; + +static int vf610_pinctrl_probe(struct udevice *dev) +{ + struct imx_pinctrl_soc_info *info = + (struct imx_pinctrl_soc_info *)dev_get_driver_data(dev); + + return imx_pinctrl_probe(dev, info); +} + +static const struct udevice_id vf610_pinctrl_match[] = { + { .compatible = "fsl,vf610-iomuxc", + .data = (ulong)&vf610_pinctrl_soc_info }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(vf610_pinctrl) = { + .name = "vf610-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(vf610_pinctrl_match), + .probe = vf610_pinctrl_probe, + .remove = imx_pinctrl_remove, + .priv_auto = sizeof(struct imx_pinctrl_priv), + .ops = &imx_pinctrl_ops, + .flags = DM_FLAG_PRE_RELOC, +}; |