From 9f540c3e1d6668d9507f18107dc63113b9a675be Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sun, 21 Oct 2018 22:00:30 +0200 Subject: pinctrl: pinctrl-amd: simplify getting .driver_data We should get 'driver_data' from 'struct device' directly. Going via platform_device is an unneeded step back and forth. Signed-off-by: Wolfram Sang Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-amd.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 67718b0f978d..2a7d638978d8 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -791,8 +791,7 @@ static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin) static int amd_gpio_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct amd_gpio *gpio_dev = platform_get_drvdata(pdev); + struct amd_gpio *gpio_dev = dev_get_drvdata(dev); struct pinctrl_desc *desc = gpio_dev->pctrl->desc; int i; @@ -810,8 +809,7 @@ static int amd_gpio_suspend(struct device *dev) static int amd_gpio_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct amd_gpio *gpio_dev = platform_get_drvdata(pdev); + struct amd_gpio *gpio_dev = dev_get_drvdata(dev); struct pinctrl_desc *desc = gpio_dev->pctrl->desc; int i; -- cgit v1.2.3 From 1ccb0426d7b6a94434a7b4f8d2d7f57de3c1b653 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sun, 21 Oct 2018 22:00:31 +0200 Subject: pinctrl: pinctrl-at91-pio4: simplify getting .driver_data We should get 'driver_data' from 'struct device' directly. Going via platform_device is an unneeded step back and forth. Signed-off-by: Wolfram Sang Reviewed-by: Alexandre Belloni Acked-by: Ludovic Desroches Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91-pio4.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index 5a850491a5cb..4ee135d7b883 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -868,8 +868,7 @@ static struct pinctrl_desc atmel_pinctrl_desc = { static int __maybe_unused atmel_pctrl_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev); + struct atmel_pioctrl *atmel_pioctrl = dev_get_drvdata(dev); int i, j; /* @@ -897,8 +896,7 @@ static int __maybe_unused atmel_pctrl_suspend(struct device *dev) static int __maybe_unused atmel_pctrl_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev); + struct atmel_pioctrl *atmel_pioctrl = dev_get_drvdata(dev); int i, j; for (i = 0; i < atmel_pioctrl->nbanks; i++) { -- cgit v1.2.3 From b96eea718bf697e4a490c2fabfb89995b9193c21 Mon Sep 17 00:00:00 2001 From: "A.s. Dong" Date: Tue, 30 Oct 2018 14:10:51 +0000 Subject: pinctrl: fsl: add scu based pinctrl support Some i.MX SoCs (e.g. MX8QXP and MX8QM) contain a system controller that is responsible for controlling the pad setting of the IPs that are present. Communication between the host processor running an OS and the system controller happens through a SCU protocol. This patch classifies the pad settings into two categories: MMIO and SCU. For the original MMIO method, no functional changes except organize them into a few imx_*_mmio() functions. Besides that, we add the SCU based Pad Mux and Pinconf setting support which are implemented in pinctrl-scu.c. Cc: Linus Walleij Cc: Shawn Guo Cc: Fabio Estevam Cc: Stefan Agner Cc: Pengutronix Kernel Team Signed-off-by: Dong Aisheng Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/Kconfig | 4 + drivers/pinctrl/freescale/Makefile | 1 + drivers/pinctrl/freescale/pinctrl-imx.c | 425 ++++++++++++++++++++------------ drivers/pinctrl/freescale/pinctrl-imx.h | 67 ++++- drivers/pinctrl/freescale/pinctrl-scu.c | 121 +++++++++ 5 files changed, 448 insertions(+), 170 deletions(-) create mode 100644 drivers/pinctrl/freescale/pinctrl-scu.c (limited to 'drivers') diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index dccf64c55498..94dcdb528651 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -5,6 +5,10 @@ config PINCTRL_IMX select GENERIC_PINCONF select REGMAP +config PINCTRL_IMX_SCU + bool + select PINCTRL_IMX + config PINCTRL_IMX1_CORE bool select PINMUX diff --git a/drivers/pinctrl/freescale/Makefile b/drivers/pinctrl/freescale/Makefile index 73175b3e7c9c..7ac8daf11675 100644 --- a/drivers/pinctrl/freescale/Makefile +++ b/drivers/pinctrl/freescale/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 # Freescale pin control drivers obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o +obj-$(CONFIG_PINCTRL_IMX_SCU) += pinctrl-scu.o obj-$(CONFIG_PINCTRL_IMX1_CORE) += pinctrl-imx1-core.o obj-$(CONFIG_PINCTRL_IMX1) += pinctrl-imx1.o obj-$(CONFIG_PINCTRL_IMX21) += pinctrl-imx21.o diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c index 4e8cf0e357c6..78d33dfb4d2d 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx.c @@ -57,9 +57,11 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, struct pinctrl_map **map, unsigned *num_maps) { struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); + const struct imx_pinctrl_soc_info *info = ipctl->info; const struct group_desc *grp; struct pinctrl_map *new_map; struct device_node *parent; + struct imx_pin *pin; int map_num = 1; int i, j; @@ -73,11 +75,14 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, return -EINVAL; } - for (i = 0; i < grp->num_pins; i++) { - struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i]; - - if (!(pin->config & IMX_NO_PAD_CTL)) - map_num++; + if (info->flags & IMX_USE_SCU) { + map_num += grp->num_pins; + } else { + for (i = 0; i < grp->num_pins; i++) { + pin = &((struct imx_pin *)(grp->data))[i]; + if (!(pin->conf.mmio.config & IMX_NO_PAD_CTL)) + map_num++; + } } new_map = kmalloc_array(map_num, sizeof(struct pinctrl_map), @@ -102,16 +107,26 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, /* create config map */ new_map++; for (i = j = 0; i < grp->num_pins; i++) { - struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i]; - - if (!(pin->config & IMX_NO_PAD_CTL)) { - new_map[j].type = PIN_MAP_TYPE_CONFIGS_PIN; - new_map[j].data.configs.group_or_pin = + pin = &((struct imx_pin *)(grp->data))[i]; + new_map[j].type = PIN_MAP_TYPE_CONFIGS_PIN; + new_map[j].data.configs.group_or_pin = pin_get_name(pctldev, pin->pin); - new_map[j].data.configs.configs = &pin->config; + + if (info->flags & IMX_USE_SCU) { + /* + * For SCU case, we set mux and conf together + * in one IPC call + */ + new_map[j].data.configs.configs = + (unsigned long *)&pin->conf.scu; + new_map[j].data.configs.num_configs = 2; + } else if (!(pin->conf.mmio.config & IMX_NO_PAD_CTL)) { + new_map[j].data.configs.configs = + &pin->conf.mmio.config; new_map[j].data.configs.num_configs = 1; - j++; } + + j++; } dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n", @@ -133,19 +148,96 @@ static const struct pinctrl_ops imx_pctrl_ops = { .pin_dbg_show = imx_pin_dbg_show, .dt_node_to_map = imx_dt_node_to_map, .dt_free_map = imx_dt_free_map, - }; +static int imx_pmx_set_one_pin_mmio(struct imx_pinctrl *ipctl, + struct imx_pin *pin) +{ + const struct imx_pinctrl_soc_info *info = ipctl->info; + struct imx_pin_mmio *pin_mmio = &pin->conf.mmio; + const struct imx_pin_reg *pin_reg; + unsigned int pin_id; + + pin_id = pin->pin; + pin_reg = &ipctl->pin_regs[pin_id]; + + if (pin_reg->mux_reg == -1) { + dev_dbg(ipctl->dev, "Pin(%s) does not support mux function\n", + info->pins[pin_id].name); + return 0; + } + + if (info->flags & SHARE_MUX_CONF_REG) { + u32 reg; + + reg = readl(ipctl->base + pin_reg->mux_reg); + reg &= ~info->mux_mask; + reg |= (pin_mmio->mux_mode << info->mux_shift); + writel(reg, ipctl->base + pin_reg->mux_reg); + dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n", + pin_reg->mux_reg, reg); + } else { + writel(pin_mmio->mux_mode, ipctl->base + pin_reg->mux_reg); + dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n", + pin_reg->mux_reg, pin_mmio->mux_mode); + } + + /* + * 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 (pin_mmio->input_val >> 24 == 0xff) { + u32 val = pin_mmio->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(ipctl->base + pin_mmio->input_reg); + val &= ~mask; + val |= select << shift; + writel(val, ipctl->base + pin_mmio->input_reg); + } else if (pin_mmio->input_reg) { + /* + * Regular select input register can never be at offset + * 0, and we only print register value for regular case. + */ + if (ipctl->input_sel_base) + writel(pin_mmio->input_val, ipctl->input_sel_base + + pin_mmio->input_reg); + else + writel(pin_mmio->input_val, ipctl->base + + pin_mmio->input_reg); + dev_dbg(ipctl->dev, + "==>select_input: offset 0x%x val 0x%x\n", + pin_mmio->input_reg, pin_mmio->input_val); + } + + return 0; +} + static int imx_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, unsigned group) { struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); const struct imx_pinctrl_soc_info *info = ipctl->info; - const struct imx_pin_reg *pin_reg; - unsigned int npins, pin_id; - int i; - struct group_desc *grp = NULL; - struct function_desc *func = NULL; + struct function_desc *func; + struct group_desc *grp; + struct imx_pin *pin; + unsigned int npins; + int i, err; /* * Configure the mux mode for each pin in the group for a specific @@ -165,72 +257,16 @@ static int imx_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, func->name, grp->name); for (i = 0; i < npins; i++) { - struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i]; - - pin_id = pin->pin; - pin_reg = &ipctl->pin_regs[pin_id]; - - if (pin_reg->mux_reg == -1) { - dev_dbg(ipctl->dev, "Pin(%s) does not support mux function\n", - info->pins[pin_id].name); - continue; - } - - if (info->flags & SHARE_MUX_CONF_REG) { - u32 reg; - reg = readl(ipctl->base + pin_reg->mux_reg); - reg &= ~info->mux_mask; - reg |= (pin->mux_mode << info->mux_shift); - writel(reg, ipctl->base + pin_reg->mux_reg); - dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n", - pin_reg->mux_reg, reg); - } else { - writel(pin->mux_mode, ipctl->base + pin_reg->mux_reg); - dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n", - pin_reg->mux_reg, pin->mux_mode); - } - /* - * 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. + * For IMX_USE_SCU case, we postpone the mux setting + * until config is set as we can set them together + * in one IPC call */ - if (pin->input_val >> 24 == 0xff) { - u32 val = pin->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(ipctl->base + pin->input_reg); - val &= ~mask; - val |= select << shift; - writel(val, ipctl->base + pin->input_reg); - } else if (pin->input_reg) { - /* - * Regular select input register can never be at offset - * 0, and we only print register value for regular case. - */ - if (ipctl->input_sel_base) - writel(pin->input_val, ipctl->input_sel_base + - pin->input_reg); - else - writel(pin->input_val, ipctl->base + - pin->input_reg); - dev_dbg(ipctl->dev, - "==>select_input: offset 0x%x val 0x%x\n", - pin->input_reg, pin->input_val); + pin = &((struct imx_pin *)(grp->data))[i]; + if (!(info->flags & IMX_USE_SCU)) { + err = imx_pmx_set_one_pin_mmio(ipctl, pin); + if (err) + return err; } } @@ -300,8 +336,8 @@ static u32 imx_pinconf_parse_generic_config(struct device_node *np, return imx_pinconf_decode_generic_config(ipctl, configs, num_configs); } -static int imx_pinconf_get(struct pinctrl_dev *pctldev, - unsigned pin_id, unsigned long *config) +static int imx_pinconf_get_mmio(struct pinctrl_dev *pctldev, unsigned pin_id, + unsigned long *config) { struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); const struct imx_pinctrl_soc_info *info = ipctl->info; @@ -321,9 +357,21 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev, return 0; } -static int imx_pinconf_set(struct pinctrl_dev *pctldev, - unsigned pin_id, unsigned long *configs, - unsigned num_configs) +static int imx_pinconf_get(struct pinctrl_dev *pctldev, + unsigned pin_id, unsigned long *config) +{ + struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); + const struct imx_pinctrl_soc_info *info = ipctl->info; + + if (info->flags & IMX_USE_SCU) + return imx_pinconf_get_scu(pctldev, pin_id, config); + else + return imx_pinconf_get_mmio(pctldev, pin_id, config); +} + +static int imx_pinconf_set_mmio(struct pinctrl_dev *pctldev, + unsigned pin_id, unsigned long *configs, + unsigned num_configs) { struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); const struct imx_pinctrl_soc_info *info = ipctl->info; @@ -358,19 +406,48 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev, return 0; } +static int imx_pinconf_set(struct pinctrl_dev *pctldev, + unsigned pin_id, unsigned long *configs, + unsigned num_configs) +{ + struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); + const struct imx_pinctrl_soc_info *info = ipctl->info; + + if (info->flags & IMX_USE_SCU) + return imx_pinconf_set_scu(pctldev, pin_id, + configs, num_configs); + else + return imx_pinconf_set_mmio(pctldev, pin_id, + configs, num_configs); +} + static void imx_pinconf_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned pin_id) { struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); - const struct imx_pin_reg *pin_reg = &ipctl->pin_regs[pin_id]; + const struct imx_pinctrl_soc_info *info = ipctl->info; + const struct imx_pin_reg *pin_reg; unsigned long config; + int ret; - if (!pin_reg || pin_reg->conf_reg == -1) { - seq_puts(s, "N/A"); - return; + if (info->flags & IMX_USE_SCU) { + ret = imx_pinconf_get_scu(pctldev, pin_id, &config); + if (ret) { + dev_err(ipctl->dev, "failed to get %s pinconf\n", + pin_get_name(pctldev, pin_id)); + seq_puts(s, "N/A"); + return; + } + } else { + pin_reg = &ipctl->pin_regs[pin_id]; + if (!pin_reg || pin_reg->conf_reg == -1) { + seq_puts(s, "N/A"); + return; + } + + config = readl(ipctl->base + pin_reg->conf_reg); } - config = readl(ipctl->base + pin_reg->conf_reg); seq_printf(s, "0x%lx", config); } @@ -418,9 +495,63 @@ static const struct pinconf_ops imx_pinconf_ops = { * * SHARE_MUX_CONF_REG: * + * IMX_USE_SCU: + * */ #define FSL_PIN_SIZE 24 #define FSL_PIN_SHARE_SIZE 20 +#define FSL_SCU_PIN_SIZE 12 + +static void imx_pinctrl_parse_pin_mmio(struct imx_pinctrl *ipctl, + unsigned int *pin_id, struct imx_pin *pin, + const __be32 **list_p, + struct device_node *np) +{ + const struct imx_pinctrl_soc_info *info = ipctl->info; + struct imx_pin_mmio *pin_mmio = &pin->conf.mmio; + struct imx_pin_reg *pin_reg; + const __be32 *list = *list_p; + u32 mux_reg, conf_reg; + u32 config; + + mux_reg = be32_to_cpu(*list++); + + 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 = be32_to_cpu(*list++); + if (!conf_reg) + conf_reg = -1; + } + + *pin_id = (mux_reg != -1) ? mux_reg / 4 : conf_reg / 4; + pin_reg = &ipctl->pin_regs[*pin_id]; + pin->pin = *pin_id; + pin_reg->mux_reg = mux_reg; + pin_reg->conf_reg = conf_reg; + pin_mmio->input_reg = be32_to_cpu(*list++); + pin_mmio->mux_mode = be32_to_cpu(*list++); + pin_mmio->input_val = be32_to_cpu(*list++); + + if (info->generic_pinconf) { + /* generic pin config decoded */ + pin_mmio->config = imx_pinconf_parse_generic_config(np, ipctl); + } else { + /* legacy pin config read from devicetree */ + config = be32_to_cpu(*list++); + + /* SION bit is in mux register */ + if (config & IMX_PAD_SION) + pin_mmio->mux_mode |= IOMUXC_CONFIG_SION; + pin_mmio->config = config & ~IMX_PAD_SION; + } + + dev_dbg(ipctl->dev, "%s: 0x%x 0x%08lx", info->pins[*pin_id].name, + pin_mmio->mux_mode, pin_mmio->config); +} static int imx_pinctrl_parse_groups(struct device_node *np, struct group_desc *grp, @@ -428,14 +559,16 @@ static int imx_pinctrl_parse_groups(struct device_node *np, u32 index) { const struct imx_pinctrl_soc_info *info = ipctl->info; + struct imx_pin *pin; int size, pin_size; const __be32 *list; int i; - u32 config; dev_dbg(ipctl->dev, "group(%d): %pOFn\n", index, np); - if (info->flags & SHARE_MUX_CONF_REG) + if (info->flags & IMX_USE_SCU) + pin_size = FSL_SCU_PIN_SIZE; + else if (info->flags & SHARE_MUX_CONF_REG) pin_size = FSL_PIN_SHARE_SIZE; else pin_size = FSL_PIN_SIZE; @@ -472,9 +605,6 @@ static int imx_pinctrl_parse_groups(struct device_node *np, return -EINVAL; } - /* first try to parse the generic pin config */ - config = imx_pinconf_parse_generic_config(np, ipctl); - grp->num_pins = size / pin_size; grp->data = devm_kcalloc(ipctl->dev, grp->num_pins, sizeof(struct imx_pin), @@ -486,48 +616,13 @@ static int imx_pinctrl_parse_groups(struct device_node *np, return -ENOMEM; for (i = 0; i < grp->num_pins; i++) { - u32 mux_reg = be32_to_cpu(*list++); - u32 conf_reg; - unsigned int pin_id; - struct imx_pin_reg *pin_reg; - struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i]; - - 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 = be32_to_cpu(*list++); - if (!conf_reg) - conf_reg = -1; - } - - pin_id = (mux_reg != -1) ? mux_reg / 4 : conf_reg / 4; - pin_reg = &ipctl->pin_regs[pin_id]; - pin->pin = pin_id; - grp->pins[i] = pin_id; - pin_reg->mux_reg = mux_reg; - pin_reg->conf_reg = conf_reg; - pin->input_reg = be32_to_cpu(*list++); - pin->mux_mode = be32_to_cpu(*list++); - pin->input_val = be32_to_cpu(*list++); - - if (info->generic_pinconf) { - /* generic pin config decoded */ - pin->config = config; - } else { - /* legacy pin config read from devicetree */ - config = be32_to_cpu(*list++); - - /* SION bit is in mux register */ - if (config & IMX_PAD_SION) - pin->mux_mode |= IOMUXC_CONFIG_SION; - pin->config = config & ~IMX_PAD_SION; - } - - dev_dbg(ipctl->dev, "%s: 0x%x 0x%08lx", info->pins[pin_id].name, - pin->mux_mode, pin->config); + pin = &((struct imx_pin *)(grp->data))[i]; + if (info->flags & IMX_USE_SCU) + imx_pinctrl_parse_pin_scu(ipctl, &grp->pins[i], + pin, &list); + else + imx_pinctrl_parse_pin_mmio(ipctl, &grp->pins[i], + pin, &list, np); } return 0; @@ -699,35 +794,37 @@ int imx_pinctrl_probe(struct platform_device *pdev, if (!ipctl) return -ENOMEM; - ipctl->pin_regs = devm_kmalloc_array(&pdev->dev, - info->npins, sizeof(*ipctl->pin_regs), - GFP_KERNEL); - if (!ipctl->pin_regs) - return -ENOMEM; + if (!(info->flags & IMX_USE_SCU)) { + ipctl->pin_regs = devm_kmalloc_array(&pdev->dev, info->npins, + sizeof(*ipctl->pin_regs), + GFP_KERNEL); + if (!ipctl->pin_regs) + return -ENOMEM; - for (i = 0; i < info->npins; i++) { - ipctl->pin_regs[i].mux_reg = -1; - ipctl->pin_regs[i].conf_reg = -1; - } + for (i = 0; i < info->npins; i++) { + ipctl->pin_regs[i].mux_reg = -1; + ipctl->pin_regs[i].conf_reg = -1; + } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ipctl->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(ipctl->base)) - return PTR_ERR(ipctl->base); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ipctl->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(ipctl->base)) + return PTR_ERR(ipctl->base); - if (of_property_read_bool(dev_np, "fsl,input-sel")) { - np = of_parse_phandle(dev_np, "fsl,input-sel", 0); - if (!np) { - dev_err(&pdev->dev, "iomuxc fsl,input-sel property not found\n"); - return -EINVAL; - } + if (of_property_read_bool(dev_np, "fsl,input-sel")) { + np = of_parse_phandle(dev_np, "fsl,input-sel", 0); + if (!np) { + dev_err(&pdev->dev, "iomuxc fsl,input-sel property not found\n"); + return -EINVAL; + } - ipctl->input_sel_base = of_iomap(np, 0); - of_node_put(np); - if (!ipctl->input_sel_base) { - dev_err(&pdev->dev, - "iomuxc input select base address not found\n"); - return -ENOMEM; + ipctl->input_sel_base = of_iomap(np, 0); + of_node_put(np); + if (!ipctl->input_sel_base) { + dev_err(&pdev->dev, + "iomuxc input select base address not found\n"); + return -ENOMEM; + } } } diff --git a/drivers/pinctrl/freescale/pinctrl-imx.h b/drivers/pinctrl/freescale/pinctrl-imx.h index 4b8225ccb03a..98a4889af4ef 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.h +++ b/drivers/pinctrl/freescale/pinctrl-imx.h @@ -19,22 +19,43 @@ struct platform_device; extern struct pinmux_ops imx_pmx_ops; /** - * struct imx_pin - describes a single i.MX pin - * @pin: the pin_id of this pin + * struct imx_pin_mmio - MMIO pin configurations * @mux_mode: the mux mode for this pin. * @input_reg: the select input register offset for this pin if any * 0 if no select input setting needed. * @input_val: the select input value for this pin. * @configs: the config for this pin. */ -struct imx_pin { - unsigned int pin; +struct imx_pin_mmio { unsigned int mux_mode; u16 input_reg; unsigned int input_val; unsigned long config; }; +/** + * struct imx_pin_scu - SCU pin configurations + * @mux: the mux mode for this pin. + * @configs: the config for this pin. + */ +struct imx_pin_scu { + unsigned int mux_mode; + unsigned long config; +}; + +/** + * struct imx_pin - describes a single i.MX pin + * @pin: the pin_id of this pin + * @conf: config type of this pin, either mmio or scu + */ +struct imx_pin { + unsigned int pin; + union { + struct imx_pin_mmio mmio; + struct imx_pin_scu scu; + } conf; +}; + /** * struct imx_pin_reg - describe a pin reg map * @mux_reg: mux register offset @@ -99,8 +120,9 @@ struct imx_pinctrl { #define IMX_CFG_PARAMS_DECODE_INVERT(p, m, o) \ { .param = p, .mask = m, .shift = o, .invert = true, } -#define SHARE_MUX_CONF_REG 0x1 -#define ZERO_OFFSET_VALID 0x2 +#define SHARE_MUX_CONF_REG BIT(0) +#define ZERO_OFFSET_VALID BIT(1) +#define IMX_USE_SCU BIT(2) #define NO_MUX 0x0 #define NO_PAD 0x0 @@ -113,4 +135,37 @@ struct imx_pinctrl { int imx_pinctrl_probe(struct platform_device *pdev, const struct imx_pinctrl_soc_info *info); + +#ifdef CONFIG_PINCTRL_IMX_SCU +#define BM_PAD_CTL_GP_ENABLE BIT(30) +#define BM_PAD_CTL_IFMUX_ENABLE BIT(31) +#define BP_PAD_CTL_IFMUX 27 + +int imx_pinctrl_sc_ipc_init(struct platform_device *pdev); +int imx_pinconf_get_scu(struct pinctrl_dev *pctldev, unsigned pin_id, + unsigned long *config); +int imx_pinconf_set_scu(struct pinctrl_dev *pctldev, unsigned pin_id, + unsigned long *configs, unsigned num_configs); +void imx_pinctrl_parse_pin_scu(struct imx_pinctrl *ipctl, + unsigned int *pin_id, struct imx_pin *pin, + const __be32 **list_p); +#else +static inline int imx_pinconf_get_scu(struct pinctrl_dev *pctldev, + unsigned pin_id, unsigned long *config) +{ + return -EINVAL; +} +static inline int imx_pinconf_set_scu(struct pinctrl_dev *pctldev, + unsigned pin_id, unsigned long *configs, + unsigned num_configs) +{ + return -EINVAL; +} +static inline void imx_pinctrl_parse_pin_scu(struct imx_pinctrl *ipctl, + unsigned int *pin_id, + struct imx_pin *pin, + const __be32 **list_p) +{ +} +#endif #endif /* __DRIVERS_PINCTRL_IMX_H */ diff --git a/drivers/pinctrl/freescale/pinctrl-scu.c b/drivers/pinctrl/freescale/pinctrl-scu.c new file mode 100644 index 000000000000..83e69c0f39e6 --- /dev/null +++ b/drivers/pinctrl/freescale/pinctrl-scu.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP + * Dong Aisheng + */ + +#include +#include +#include +#include +#include + +#include "../core.h" +#include "pinctrl-imx.h" + +enum pad_func_e { + IMX_SC_PAD_FUNC_SET = 15, + IMX_SC_PAD_FUNC_GET = 16, +}; + +struct imx_sc_msg_req_pad_set { + struct imx_sc_rpc_msg hdr; + u32 val; + u16 pad; +} __packed; + +struct imx_sc_msg_req_pad_get { + struct imx_sc_rpc_msg hdr; + u16 pad; +} __packed; + +struct imx_sc_msg_resp_pad_get { + struct imx_sc_rpc_msg hdr; + u32 val; +} __packed; + +struct imx_sc_ipc *pinctrl_ipc_handle; + +int imx_pinctrl_sc_ipc_init(struct platform_device *pdev) +{ + return imx_scu_get_handle(&pinctrl_ipc_handle); +} + +int imx_pinconf_get_scu(struct pinctrl_dev *pctldev, unsigned pin_id, + unsigned long *config) +{ + struct imx_sc_msg_req_pad_get msg; + struct imx_sc_msg_resp_pad_get *resp; + struct imx_sc_rpc_msg *hdr = &msg.hdr; + int ret; + + hdr->ver = IMX_SC_RPC_VERSION; + hdr->svc = IMX_SC_RPC_SVC_PAD; + hdr->func = IMX_SC_PAD_FUNC_GET; + hdr->size = 2; + + msg.pad = pin_id; + + ret = imx_scu_call_rpc(pinctrl_ipc_handle, &msg, true); + if (ret) + return ret; + + resp = (struct imx_sc_msg_resp_pad_get *)&msg; + *config = resp->val; + + return 0; +} + +int imx_pinconf_set_scu(struct pinctrl_dev *pctldev, unsigned pin_id, + unsigned long *configs, unsigned num_configs) +{ + struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); + struct imx_sc_msg_req_pad_set msg; + struct imx_sc_rpc_msg *hdr = &msg.hdr; + unsigned int mux = configs[0]; + unsigned int conf = configs[1]; + unsigned int val; + int ret; + + /* + * Set mux and conf together in one IPC call + */ + WARN_ON(num_configs != 2); + + val = conf | BM_PAD_CTL_IFMUX_ENABLE | BM_PAD_CTL_GP_ENABLE; + val |= mux << BP_PAD_CTL_IFMUX; + + hdr->ver = IMX_SC_RPC_VERSION; + hdr->svc = IMX_SC_RPC_SVC_PAD; + hdr->func = IMX_SC_PAD_FUNC_SET; + hdr->size = 3; + + msg.pad = pin_id; + msg.val = val; + + ret = imx_scu_call_rpc(pinctrl_ipc_handle, &msg, true); + + dev_dbg(ipctl->dev, "write: pin_id %u config 0x%x val 0x%x\n", + pin_id, conf, val); + + return ret; +} + +void imx_pinctrl_parse_pin_scu(struct imx_pinctrl *ipctl, + unsigned int *pin_id, struct imx_pin *pin, + const __be32 **list_p) +{ + const struct imx_pinctrl_soc_info *info = ipctl->info; + struct imx_pin_scu *pin_scu = &pin->conf.scu; + const __be32 *list = *list_p; + + pin->pin = be32_to_cpu(*list++); + *pin_id = pin->pin; + pin_scu->mux_mode = be32_to_cpu(*list++); + pin_scu->config = be32_to_cpu(*list++); + *list_p = list; + + dev_dbg(ipctl->dev, "%s: 0x%x 0x%08lx", info->pins[pin->pin].name, + pin_scu->mux_mode, pin_scu->config); +} -- cgit v1.2.3 From 623f788d0e7c6ef68d1f42595345bc6c78167702 Mon Sep 17 00:00:00 2001 From: "A.s. Dong" Date: Tue, 30 Oct 2018 14:10:56 +0000 Subject: pinctrl: imx: add imx8qxp driver MX8QXP contains a system controller that is responsible for controlling the pad setting of the IPs that are present. Communication between the host processor running an OS and the system controller happens through a SCU protocol. This patch adds the SCU based MX8QXP pinctrl driver. Cc: Linus Walleij Cc: Shawn Guo Cc: Fabio Estevam Cc: Stefan Agner Cc: Pengutronix Kernel Team Signed-off-by: Dong Aisheng Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/Kconfig | 7 + drivers/pinctrl/freescale/Makefile | 1 + drivers/pinctrl/freescale/pinctrl-imx8qxp.c | 232 ++++++++++++++++++++++++++++ 3 files changed, 240 insertions(+) create mode 100644 drivers/pinctrl/freescale/pinctrl-imx8qxp.c (limited to 'drivers') diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index 94dcdb528651..2d6db434f70a 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -128,6 +128,13 @@ config PINCTRL_IMX8MQ help Say Y here to enable the imx8mq pinctrl driver +config PINCTRL_IMX8QXP + bool "IMX8QXP pinctrl driver" + depends on SOC_IMX8QXP + select PINCTRL_IMX_SCU + help + Say Y here to enable the imx8qxp pinctrl driver + config PINCTRL_VF610 bool "Freescale Vybrid VF610 pinctrl driver" depends on SOC_VF610 diff --git a/drivers/pinctrl/freescale/Makefile b/drivers/pinctrl/freescale/Makefile index 7ac8daf11675..6ee398a3e406 100644 --- a/drivers/pinctrl/freescale/Makefile +++ b/drivers/pinctrl/freescale/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_PINCTRL_IMX6UL) += pinctrl-imx6ul.o obj-$(CONFIG_PINCTRL_IMX7D) += pinctrl-imx7d.o obj-$(CONFIG_PINCTRL_IMX7ULP) += pinctrl-imx7ulp.o obj-$(CONFIG_PINCTRL_IMX8MQ) += pinctrl-imx8mq.o +obj-$(CONFIG_PINCTRL_IMX8QXP) += pinctrl-imx8qxp.o obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o diff --git a/drivers/pinctrl/freescale/pinctrl-imx8qxp.c b/drivers/pinctrl/freescale/pinctrl-imx8qxp.c new file mode 100644 index 000000000000..1131dc3c084e --- /dev/null +++ b/drivers/pinctrl/freescale/pinctrl-imx8qxp.c @@ -0,0 +1,232 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP + * Dong Aisheng + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pinctrl-imx.h" + +static const struct pinctrl_pin_desc imx8qxp_pinctrl_pads[] = { + IMX_PINCTRL_PIN(IMX8QXP_PCIE_CTRL0_PERST_B), + IMX_PINCTRL_PIN(IMX8QXP_PCIE_CTRL0_CLKREQ_B), + IMX_PINCTRL_PIN(IMX8QXP_PCIE_CTRL0_WAKE_B), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_PCIESEP), + IMX_PINCTRL_PIN(IMX8QXP_USB_SS3_TC0), + IMX_PINCTRL_PIN(IMX8QXP_USB_SS3_TC1), + IMX_PINCTRL_PIN(IMX8QXP_USB_SS3_TC2), + IMX_PINCTRL_PIN(IMX8QXP_USB_SS3_TC3), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_3V3_USB3IO), + IMX_PINCTRL_PIN(IMX8QXP_EMMC0_CLK), + IMX_PINCTRL_PIN(IMX8QXP_EMMC0_CMD), + IMX_PINCTRL_PIN(IMX8QXP_EMMC0_DATA0), + IMX_PINCTRL_PIN(IMX8QXP_EMMC0_DATA1), + IMX_PINCTRL_PIN(IMX8QXP_EMMC0_DATA2), + IMX_PINCTRL_PIN(IMX8QXP_EMMC0_DATA3), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_SD1FIX0), + IMX_PINCTRL_PIN(IMX8QXP_EMMC0_DATA4), + IMX_PINCTRL_PIN(IMX8QXP_EMMC0_DATA5), + IMX_PINCTRL_PIN(IMX8QXP_EMMC0_DATA6), + IMX_PINCTRL_PIN(IMX8QXP_EMMC0_DATA7), + IMX_PINCTRL_PIN(IMX8QXP_EMMC0_STROBE), + IMX_PINCTRL_PIN(IMX8QXP_EMMC0_RESET_B), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_SD1FIX1), + IMX_PINCTRL_PIN(IMX8QXP_USDHC1_RESET_B), + IMX_PINCTRL_PIN(IMX8QXP_USDHC1_VSELECT), + IMX_PINCTRL_PIN(IMX8QXP_CTL_NAND_RE_P_N), + IMX_PINCTRL_PIN(IMX8QXP_USDHC1_WP), + IMX_PINCTRL_PIN(IMX8QXP_USDHC1_CD_B), + IMX_PINCTRL_PIN(IMX8QXP_CTL_NAND_DQS_P_N), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_VSELSEP), + IMX_PINCTRL_PIN(IMX8QXP_USDHC1_CLK), + IMX_PINCTRL_PIN(IMX8QXP_USDHC1_CMD), + IMX_PINCTRL_PIN(IMX8QXP_USDHC1_DATA0), + IMX_PINCTRL_PIN(IMX8QXP_USDHC1_DATA1), + IMX_PINCTRL_PIN(IMX8QXP_USDHC1_DATA2), + IMX_PINCTRL_PIN(IMX8QXP_USDHC1_DATA3), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_VSEL3), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_RGMII_TXC), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_RGMII_TX_CTL), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_RGMII_TXD0), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_RGMII_TXD1), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_RGMII_TXD2), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_RGMII_TXD3), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_RGMII_RXC), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_RGMII_RX_CTL), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_RGMII_RXD0), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_RGMII_RXD1), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_RGMII_RXD2), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_RGMII_RXD3), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_REFCLK_125M_25M), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_MDIO), + IMX_PINCTRL_PIN(IMX8QXP_ENET0_MDC), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_GPIOCT), + IMX_PINCTRL_PIN(IMX8QXP_ESAI0_FSR), + IMX_PINCTRL_PIN(IMX8QXP_ESAI0_FST), + IMX_PINCTRL_PIN(IMX8QXP_ESAI0_SCKR), + IMX_PINCTRL_PIN(IMX8QXP_ESAI0_SCKT), + IMX_PINCTRL_PIN(IMX8QXP_ESAI0_TX0), + IMX_PINCTRL_PIN(IMX8QXP_ESAI0_TX1), + IMX_PINCTRL_PIN(IMX8QXP_ESAI0_TX2_RX3), + IMX_PINCTRL_PIN(IMX8QXP_ESAI0_TX3_RX2), + IMX_PINCTRL_PIN(IMX8QXP_ESAI0_TX4_RX1), + IMX_PINCTRL_PIN(IMX8QXP_ESAI0_TX5_RX0), + IMX_PINCTRL_PIN(IMX8QXP_SPDIF0_RX), + IMX_PINCTRL_PIN(IMX8QXP_SPDIF0_TX), + IMX_PINCTRL_PIN(IMX8QXP_SPDIF0_EXT_CLK), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_GPIORHB), + IMX_PINCTRL_PIN(IMX8QXP_SPI3_SCK), + IMX_PINCTRL_PIN(IMX8QXP_SPI3_SDO), + IMX_PINCTRL_PIN(IMX8QXP_SPI3_SDI), + IMX_PINCTRL_PIN(IMX8QXP_SPI3_CS0), + IMX_PINCTRL_PIN(IMX8QXP_SPI3_CS1), + IMX_PINCTRL_PIN(IMX8QXP_MCLK_IN1), + IMX_PINCTRL_PIN(IMX8QXP_MCLK_IN0), + IMX_PINCTRL_PIN(IMX8QXP_MCLK_OUT0), + IMX_PINCTRL_PIN(IMX8QXP_UART1_TX), + IMX_PINCTRL_PIN(IMX8QXP_UART1_RX), + IMX_PINCTRL_PIN(IMX8QXP_UART1_RTS_B), + IMX_PINCTRL_PIN(IMX8QXP_UART1_CTS_B), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_GPIORHK), + IMX_PINCTRL_PIN(IMX8QXP_SAI0_TXD), + IMX_PINCTRL_PIN(IMX8QXP_SAI0_TXC), + IMX_PINCTRL_PIN(IMX8QXP_SAI0_RXD), + IMX_PINCTRL_PIN(IMX8QXP_SAI0_TXFS), + IMX_PINCTRL_PIN(IMX8QXP_SAI1_RXD), + IMX_PINCTRL_PIN(IMX8QXP_SAI1_RXC), + IMX_PINCTRL_PIN(IMX8QXP_SAI1_RXFS), + IMX_PINCTRL_PIN(IMX8QXP_SPI2_CS0), + IMX_PINCTRL_PIN(IMX8QXP_SPI2_SDO), + IMX_PINCTRL_PIN(IMX8QXP_SPI2_SDI), + IMX_PINCTRL_PIN(IMX8QXP_SPI2_SCK), + IMX_PINCTRL_PIN(IMX8QXP_SPI0_SCK), + IMX_PINCTRL_PIN(IMX8QXP_SPI0_SDI), + IMX_PINCTRL_PIN(IMX8QXP_SPI0_SDO), + IMX_PINCTRL_PIN(IMX8QXP_SPI0_CS1), + IMX_PINCTRL_PIN(IMX8QXP_SPI0_CS0), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_GPIORHT), + IMX_PINCTRL_PIN(IMX8QXP_ADC_IN1), + IMX_PINCTRL_PIN(IMX8QXP_ADC_IN0), + IMX_PINCTRL_PIN(IMX8QXP_ADC_IN3), + IMX_PINCTRL_PIN(IMX8QXP_ADC_IN2), + IMX_PINCTRL_PIN(IMX8QXP_ADC_IN5), + IMX_PINCTRL_PIN(IMX8QXP_ADC_IN4), + IMX_PINCTRL_PIN(IMX8QXP_FLEXCAN0_RX), + IMX_PINCTRL_PIN(IMX8QXP_FLEXCAN0_TX), + IMX_PINCTRL_PIN(IMX8QXP_FLEXCAN1_RX), + IMX_PINCTRL_PIN(IMX8QXP_FLEXCAN1_TX), + IMX_PINCTRL_PIN(IMX8QXP_FLEXCAN2_RX), + IMX_PINCTRL_PIN(IMX8QXP_FLEXCAN2_TX), + IMX_PINCTRL_PIN(IMX8QXP_UART0_RX), + IMX_PINCTRL_PIN(IMX8QXP_UART0_TX), + IMX_PINCTRL_PIN(IMX8QXP_UART2_TX), + IMX_PINCTRL_PIN(IMX8QXP_UART2_RX), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_GPIOLH), + IMX_PINCTRL_PIN(IMX8QXP_MIPI_DSI0_I2C0_SCL), + IMX_PINCTRL_PIN(IMX8QXP_MIPI_DSI0_I2C0_SDA), + IMX_PINCTRL_PIN(IMX8QXP_MIPI_DSI0_GPIO0_00), + IMX_PINCTRL_PIN(IMX8QXP_MIPI_DSI0_GPIO0_01), + IMX_PINCTRL_PIN(IMX8QXP_MIPI_DSI1_I2C0_SCL), + IMX_PINCTRL_PIN(IMX8QXP_MIPI_DSI1_I2C0_SDA), + IMX_PINCTRL_PIN(IMX8QXP_MIPI_DSI1_GPIO0_00), + IMX_PINCTRL_PIN(IMX8QXP_MIPI_DSI1_GPIO0_01), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_MIPIDSIGPIO), + IMX_PINCTRL_PIN(IMX8QXP_JTAG_TRST_B), + IMX_PINCTRL_PIN(IMX8QXP_PMIC_I2C_SCL), + IMX_PINCTRL_PIN(IMX8QXP_PMIC_I2C_SDA), + IMX_PINCTRL_PIN(IMX8QXP_PMIC_INT_B), + IMX_PINCTRL_PIN(IMX8QXP_SCU_GPIO0_00), + IMX_PINCTRL_PIN(IMX8QXP_SCU_GPIO0_01), + IMX_PINCTRL_PIN(IMX8QXP_SCU_PMIC_STANDBY), + IMX_PINCTRL_PIN(IMX8QXP_SCU_BOOT_MODE0), + IMX_PINCTRL_PIN(IMX8QXP_SCU_BOOT_MODE1), + IMX_PINCTRL_PIN(IMX8QXP_SCU_BOOT_MODE2), + IMX_PINCTRL_PIN(IMX8QXP_SCU_BOOT_MODE3), + IMX_PINCTRL_PIN(IMX8QXP_CSI_D00), + IMX_PINCTRL_PIN(IMX8QXP_CSI_D01), + IMX_PINCTRL_PIN(IMX8QXP_CSI_D02), + IMX_PINCTRL_PIN(IMX8QXP_CSI_D03), + IMX_PINCTRL_PIN(IMX8QXP_CSI_D04), + IMX_PINCTRL_PIN(IMX8QXP_CSI_D05), + IMX_PINCTRL_PIN(IMX8QXP_CSI_D06), + IMX_PINCTRL_PIN(IMX8QXP_CSI_D07), + IMX_PINCTRL_PIN(IMX8QXP_CSI_HSYNC), + IMX_PINCTRL_PIN(IMX8QXP_CSI_VSYNC), + IMX_PINCTRL_PIN(IMX8QXP_CSI_PCLK), + IMX_PINCTRL_PIN(IMX8QXP_CSI_MCLK), + IMX_PINCTRL_PIN(IMX8QXP_CSI_EN), + IMX_PINCTRL_PIN(IMX8QXP_CSI_RESET), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_GPIORHD), + IMX_PINCTRL_PIN(IMX8QXP_MIPI_CSI0_MCLK_OUT), + IMX_PINCTRL_PIN(IMX8QXP_MIPI_CSI0_I2C0_SCL), + IMX_PINCTRL_PIN(IMX8QXP_MIPI_CSI0_I2C0_SDA), + IMX_PINCTRL_PIN(IMX8QXP_MIPI_CSI0_GPIO0_01), + IMX_PINCTRL_PIN(IMX8QXP_MIPI_CSI0_GPIO0_00), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0A_DATA0), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0A_DATA1), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0A_DATA2), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0A_DATA3), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0A_DQS), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0A_SS0_B), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0A_SS1_B), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0A_SCLK), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_QSPI0A), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0B_SCLK), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0B_DATA0), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0B_DATA1), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0B_DATA2), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0B_DATA3), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0B_DQS), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0B_SS0_B), + IMX_PINCTRL_PIN(IMX8QXP_QSPI0B_SS1_B), + IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_QSPI0B), +}; + +static struct imx_pinctrl_soc_info imx8qxp_pinctrl_info = { + .pins = imx8qxp_pinctrl_pads, + .npins = ARRAY_SIZE(imx8qxp_pinctrl_pads), + .flags = IMX_USE_SCU, +}; + +static const struct of_device_id imx8qxp_pinctrl_of_match[] = { + { .compatible = "fsl,imx8qxp-iomuxc", }, + { /* sentinel */ } +}; + +static int imx8qxp_pinctrl_probe(struct platform_device *pdev) +{ + int ret; + + ret = imx_pinctrl_sc_ipc_init(pdev); + if (ret) + return ret; + + return imx_pinctrl_probe(pdev, &imx8qxp_pinctrl_info); +} + +static struct platform_driver imx8qxp_pinctrl_driver = { + .driver = { + .name = "imx8qxp-pinctrl", + .of_match_table = of_match_ptr(imx8qxp_pinctrl_of_match), + .suppress_bind_attrs = true, + }, + .probe = imx8qxp_pinctrl_probe, +}; + +static int __init imx8qxp_pinctrl_init(void) +{ + return platform_driver_register(&imx8qxp_pinctrl_driver); +} +arch_initcall(imx8qxp_pinctrl_init); -- cgit v1.2.3 From 3c7b30f704b6f5e53eed6bf89cf2c8d1b38b02c0 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sat, 27 Oct 2018 10:15:33 +0200 Subject: pinctrl: bcm2835: Use raw spinlock for RT compatibility The BCM2835 pinctrl driver acquires a spinlock in its ->irq_enable, ->irq_disable and ->irq_set_type callbacks. Spinlocks become sleeping locks with CONFIG_PREEMPT_RT_FULL=y, therefore invocation of one of the callbacks in atomic context may cause a hard lockup if at least two GPIO pins in the same bank are used as interrupts. The issue doesn't occur with just a single interrupt pin per bank because the lock is never contended. I'm experiencing such lockups with GPIO 8 and 28 used as level-triggered interrupts, i.e. with ->irq_disable being invoked on reception of every IRQ. The critical section protected by the spinlock is very small (one bitop and one RMW of an MMIO register), hence converting to a raw spinlock seems a better trade-off than converting the driver to threaded IRQ handling (which would increase latency to handle an interrupt). Cc: Mathias Duckeck Signed-off-by: Lukas Wunner Acked-by: Julia Cartwright Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index fa530913a2c8..08925d24180b 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -90,7 +90,7 @@ struct bcm2835_pinctrl { struct gpio_chip gpio_chip; struct pinctrl_gpio_range gpio_range; - spinlock_t irq_lock[BCM2835_NUM_BANKS]; + raw_spinlock_t irq_lock[BCM2835_NUM_BANKS]; }; /* pins are just named GPIO0..GPIO53 */ @@ -461,10 +461,10 @@ static void bcm2835_gpio_irq_enable(struct irq_data *data) unsigned bank = GPIO_REG_OFFSET(gpio); unsigned long flags; - spin_lock_irqsave(&pc->irq_lock[bank], flags); + raw_spin_lock_irqsave(&pc->irq_lock[bank], flags); set_bit(offset, &pc->enabled_irq_map[bank]); bcm2835_gpio_irq_config(pc, gpio, true); - spin_unlock_irqrestore(&pc->irq_lock[bank], flags); + raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags); } static void bcm2835_gpio_irq_disable(struct irq_data *data) @@ -476,12 +476,12 @@ static void bcm2835_gpio_irq_disable(struct irq_data *data) unsigned bank = GPIO_REG_OFFSET(gpio); unsigned long flags; - spin_lock_irqsave(&pc->irq_lock[bank], flags); + raw_spin_lock_irqsave(&pc->irq_lock[bank], flags); bcm2835_gpio_irq_config(pc, gpio, false); /* Clear events that were latched prior to clearing event sources */ bcm2835_gpio_set_bit(pc, GPEDS0, gpio); clear_bit(offset, &pc->enabled_irq_map[bank]); - spin_unlock_irqrestore(&pc->irq_lock[bank], flags); + raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags); } static int __bcm2835_gpio_irq_set_type_disabled(struct bcm2835_pinctrl *pc, @@ -584,7 +584,7 @@ static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type) unsigned long flags; int ret; - spin_lock_irqsave(&pc->irq_lock[bank], flags); + raw_spin_lock_irqsave(&pc->irq_lock[bank], flags); if (test_bit(offset, &pc->enabled_irq_map[bank])) ret = __bcm2835_gpio_irq_set_type_enabled(pc, gpio, type); @@ -596,7 +596,7 @@ static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type) else irq_set_handler_locked(data, handle_level_irq); - spin_unlock_irqrestore(&pc->irq_lock[bank], flags); + raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags); return ret; } @@ -1047,7 +1047,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) for_each_set_bit(offset, &events, 32) bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset)); - spin_lock_init(&pc->irq_lock[i]); + raw_spin_lock_init(&pc->irq_lock[i]); } err = gpiochip_add_data(&pc->gpio_chip, pc); -- cgit v1.2.3 From 80ef7d09104424120c5a9e531f6c41ecb14b023c Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 8 Oct 2018 10:30:16 +0100 Subject: pinctrl: sh-pfc: r8a77470: Add remaining I2C pin groups This patch adds I2C[0123] groups and functions to the RZ/G1C (a.k.a. R8A77470) pinctrl driver. Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/sh-pfc/pfc-r8a77470.c | 191 ++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77470.c b/drivers/pinctrl/sh-pfc/pfc-r8a77470.c index 3d36e5f4ca7b..9b67ea71801a 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a77470.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a77470.c @@ -1284,6 +1284,143 @@ static const unsigned int du0_disp_pins[] = { static const unsigned int du0_disp_mux[] = { DU0_DISP_MARK }; +/* - I2C0 ------------------------------------------------------------------- */ +static const unsigned int i2c0_a_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(4, 0), RCAR_GP_PIN(4, 1), +}; +static const unsigned int i2c0_a_mux[] = { + SCL0_A_MARK, SDA0_A_MARK, +}; +static const unsigned int i2c0_b_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(5, 28), RCAR_GP_PIN(5, 29), +}; +static const unsigned int i2c0_b_mux[] = { + SCL0_B_MARK, SDA0_B_MARK, +}; +static const unsigned int i2c0_c_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(3, 11), RCAR_GP_PIN(3, 12), +}; +static const unsigned int i2c0_c_mux[] = { + SCL0_C_MARK, SDA0_C_MARK, +}; +static const unsigned int i2c0_d_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(1, 2), RCAR_GP_PIN(1, 3), +}; +static const unsigned int i2c0_d_mux[] = { + SCL0_D_MARK, SDA0_D_MARK, +}; +static const unsigned int i2c0_e_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(2, 2), RCAR_GP_PIN(2, 3), +}; +static const unsigned int i2c0_e_mux[] = { + SCL0_E_MARK, SDA0_E_MARK, +}; +/* - I2C1 ------------------------------------------------------------------- */ +static const unsigned int i2c1_a_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(4, 2), RCAR_GP_PIN(4, 3), +}; +static const unsigned int i2c1_a_mux[] = { + SCL1_A_MARK, SDA1_A_MARK, +}; +static const unsigned int i2c1_b_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6), +}; +static const unsigned int i2c1_b_mux[] = { + SCL1_B_MARK, SDA1_B_MARK, +}; +static const unsigned int i2c1_c_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(4, 22), RCAR_GP_PIN(4, 23), +}; +static const unsigned int i2c1_c_mux[] = { + SCL1_C_MARK, SDA1_C_MARK, +}; +static const unsigned int i2c1_d_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(1, 8), RCAR_GP_PIN(1, 9), +}; +static const unsigned int i2c1_d_mux[] = { + SCL1_D_MARK, SDA1_D_MARK, +}; +static const unsigned int i2c1_e_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(4, 16), RCAR_GP_PIN(4, 17), +}; +static const unsigned int i2c1_e_mux[] = { + SCL1_E_MARK, SDA1_E_MARK, +}; +/* - I2C2 ------------------------------------------------------------------- */ +static const unsigned int i2c2_a_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(4, 24), RCAR_GP_PIN(4, 25), +}; +static const unsigned int i2c2_a_mux[] = { + SCL2_A_MARK, SDA2_A_MARK, +}; +static const unsigned int i2c2_b_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 14), +}; +static const unsigned int i2c2_b_mux[] = { + SCL2_B_MARK, SDA2_B_MARK, +}; +static const unsigned int i2c2_c_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(4, 4), RCAR_GP_PIN(4, 5), +}; +static const unsigned int i2c2_c_mux[] = { + SCL2_C_MARK, SDA2_C_MARK, +}; +static const unsigned int i2c2_d_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1), +}; +static const unsigned int i2c2_d_mux[] = { + SCL2_D_MARK, SDA2_D_MARK, +}; +/* - I2C3 ------------------------------------------------------------------- */ +static const unsigned int i2c3_a_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(3, 9), RCAR_GP_PIN(3, 10), +}; +static const unsigned int i2c3_a_mux[] = { + SCL3_A_MARK, SDA3_A_MARK, +}; +static const unsigned int i2c3_b_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(1, 0), RCAR_GP_PIN(1, 1), +}; +static const unsigned int i2c3_b_mux[] = { + SCL3_B_MARK, SDA3_B_MARK, +}; +static const unsigned int i2c3_c_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 2), +}; +static const unsigned int i2c3_c_mux[] = { + SCL3_C_MARK, SDA3_C_MARK, +}; +static const unsigned int i2c3_d_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), +}; +static const unsigned int i2c3_d_mux[] = { + SCL3_D_MARK, SDA3_D_MARK, +}; +static const unsigned int i2c3_e_pins[] = { + /* SCL, SDA */ + RCAR_GP_PIN(5, 25), RCAR_GP_PIN(5, 26), +}; +static const unsigned int i2c3_e_mux[] = { + SCL3_E_MARK, SDA3_E_MARK, +}; /* - I2C4 ------------------------------------------------------------------- */ static const unsigned int i2c4_a_pins[] = { /* SCL, SDA */ @@ -1698,6 +1835,25 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(du0_oddf), SH_PFC_PIN_GROUP(du0_cde), SH_PFC_PIN_GROUP(du0_disp), + SH_PFC_PIN_GROUP(i2c0_a), + SH_PFC_PIN_GROUP(i2c0_b), + SH_PFC_PIN_GROUP(i2c0_c), + SH_PFC_PIN_GROUP(i2c0_d), + SH_PFC_PIN_GROUP(i2c0_e), + SH_PFC_PIN_GROUP(i2c1_a), + SH_PFC_PIN_GROUP(i2c1_b), + SH_PFC_PIN_GROUP(i2c1_c), + SH_PFC_PIN_GROUP(i2c1_d), + SH_PFC_PIN_GROUP(i2c1_e), + SH_PFC_PIN_GROUP(i2c2_a), + SH_PFC_PIN_GROUP(i2c2_b), + SH_PFC_PIN_GROUP(i2c2_c), + SH_PFC_PIN_GROUP(i2c2_d), + SH_PFC_PIN_GROUP(i2c3_a), + SH_PFC_PIN_GROUP(i2c3_b), + SH_PFC_PIN_GROUP(i2c3_c), + SH_PFC_PIN_GROUP(i2c3_d), + SH_PFC_PIN_GROUP(i2c3_e), SH_PFC_PIN_GROUP(i2c4_a), SH_PFC_PIN_GROUP(i2c4_b), SH_PFC_PIN_GROUP(i2c4_c), @@ -1780,6 +1936,37 @@ static const char * const du0_groups[] = { "du0_disp", }; +static const char * const i2c0_groups[] = { + "i2c0_a", + "i2c0_b", + "i2c0_c", + "i2c0_d", + "i2c0_e", +}; + +static const char * const i2c1_groups[] = { + "i2c1_a", + "i2c1_b", + "i2c1_c", + "i2c1_d", + "i2c1_e", +}; + +static const char * const i2c2_groups[] = { + "i2c2_a", + "i2c2_b", + "i2c2_c", + "i2c2_d", +}; + +static const char * const i2c3_groups[] = { + "i2c3_a", + "i2c3_b", + "i2c3_c", + "i2c3_d", + "i2c3_e", +}; + static const char * const i2c4_groups[] = { "i2c4_a", "i2c4_b", @@ -1874,6 +2061,10 @@ static const char * const usb1_groups[] = { static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(avb), SH_PFC_FUNCTION(du0), + SH_PFC_FUNCTION(i2c0), + SH_PFC_FUNCTION(i2c1), + SH_PFC_FUNCTION(i2c2), + SH_PFC_FUNCTION(i2c3), SH_PFC_FUNCTION(i2c4), SH_PFC_FUNCTION(mmc), SH_PFC_FUNCTION(qspi0), -- cgit v1.2.3 From 5c9258bca9ace0a25614b635fc1c2836ee4d8c96 Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 8 Oct 2018 10:30:17 +0100 Subject: pinctrl: sh-pfc: r8a77470: Add DU1 pin groups Add DU1 pin groups and function to the RZ/G1C (a.k.a. R8A77470) pinctrl driver. Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/sh-pfc/pfc-r8a77470.c | 108 ++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77470.c b/drivers/pinctrl/sh-pfc/pfc-r8a77470.c index 9b67ea71801a..f22a931824e1 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a77470.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a77470.c @@ -1284,6 +1284,92 @@ static const unsigned int du0_disp_pins[] = { static const unsigned int du0_disp_mux[] = { DU0_DISP_MARK }; +static const unsigned int du1_rgb666_pins[] = { + /* R[7:2], G[7:2], B[7:2] */ + RCAR_GP_PIN(4, 9), RCAR_GP_PIN(4, 8), RCAR_GP_PIN(4, 7), + RCAR_GP_PIN(4, 6), RCAR_GP_PIN(4, 5), RCAR_GP_PIN(4, 4), + RCAR_GP_PIN(4, 17), RCAR_GP_PIN(4, 16), RCAR_GP_PIN(4, 15), + RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 13), RCAR_GP_PIN(4, 12), + RCAR_GP_PIN(4, 25), RCAR_GP_PIN(4, 24), RCAR_GP_PIN(4, 23), + RCAR_GP_PIN(4, 22), RCAR_GP_PIN(4, 21), RCAR_GP_PIN(4, 20), +}; +static const unsigned int du1_rgb666_mux[] = { + DU1_DR7_MARK, DU1_DR6_MARK, DU1_DR5_MARK, DU1_DR4_MARK, + DU1_DR3_MARK, DU1_DR2_MARK, + DU1_DG7_MARK, DU1_DG6_MARK, DU1_DG5_MARK, DU1_DG4_MARK, + DU1_DG3_MARK, DU1_DG2_MARK, + DU1_DB7_MARK, DU1_DB6_MARK, DU1_DB5_MARK, DU1_DB4_MARK, + DU1_DB3_MARK, DU1_DB2_MARK, +}; +static const unsigned int du1_rgb888_pins[] = { + /* R[7:0], G[7:0], B[7:0] */ + RCAR_GP_PIN(4, 9), RCAR_GP_PIN(4, 8), RCAR_GP_PIN(4, 7), + RCAR_GP_PIN(4, 6), RCAR_GP_PIN(4, 5), RCAR_GP_PIN(4, 4), + RCAR_GP_PIN(4, 3), RCAR_GP_PIN(4, 2), + RCAR_GP_PIN(4, 17), RCAR_GP_PIN(4, 16), RCAR_GP_PIN(4, 15), + RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 13), RCAR_GP_PIN(4, 12), + RCAR_GP_PIN(4, 11), RCAR_GP_PIN(4, 10), + RCAR_GP_PIN(4, 25), RCAR_GP_PIN(4, 24), RCAR_GP_PIN(4, 23), + RCAR_GP_PIN(4, 22), RCAR_GP_PIN(4, 21), RCAR_GP_PIN(4, 20), + RCAR_GP_PIN(4, 19), RCAR_GP_PIN(4, 18), +}; +static const unsigned int du1_rgb888_mux[] = { + DU1_DR7_MARK, DU1_DR6_MARK, DU1_DR5_MARK, DU1_DR4_MARK, + DU1_DR3_MARK, DU1_DR2_MARK, DU1_DR1_MARK, DU1_DR0_MARK, + DU1_DG7_MARK, DU1_DG6_MARK, DU1_DG5_MARK, DU1_DG4_MARK, + DU1_DG3_MARK, DU1_DG2_MARK, DU1_DG1_MARK, DU1_DG0_MARK, + DU1_DB7_MARK, DU1_DB6_MARK, DU1_DB5_MARK, DU1_DB4_MARK, + DU1_DB3_MARK, DU1_DB2_MARK, DU1_DB1_MARK, DU1_DB0_MARK, +}; +static const unsigned int du1_clk0_out_pins[] = { + /* DOTCLKOUT0 */ + RCAR_GP_PIN(5, 2), +}; +static const unsigned int du1_clk0_out_mux[] = { + DU1_DOTCLKOUT0_MARK +}; +static const unsigned int du1_clk1_out_pins[] = { + /* DOTCLKOUT1 */ + RCAR_GP_PIN(5, 0), +}; +static const unsigned int du1_clk1_out_mux[] = { + DU1_DOTCLKOUT1_MARK +}; +static const unsigned int du1_clk_in_pins[] = { + /* DOTCLKIN */ + RCAR_GP_PIN(5, 1), +}; +static const unsigned int du1_clk_in_mux[] = { + DU1_DOTCLKIN_MARK +}; +static const unsigned int du1_sync_pins[] = { + /* EXVSYNC/VSYNC, EXHSYNC/HSYNC */ + RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 4), +}; +static const unsigned int du1_sync_mux[] = { + DU1_EXVSYNC_DU1_VSYNC_MARK, DU1_EXHSYNC_DU1_HSYNC_MARK +}; +static const unsigned int du1_oddf_pins[] = { + /* EXODDF/ODDF/DISP/CDE */ + RCAR_GP_PIN(5, 3), +}; +static const unsigned int du1_oddf_mux[] = { + DU1_EXODDF_DU1_ODDF_DISP_CDE_MARK, +}; +static const unsigned int du1_cde_pins[] = { + /* CDE */ + RCAR_GP_PIN(5, 7), +}; +static const unsigned int du1_cde_mux[] = { + DU1_CDE_MARK +}; +static const unsigned int du1_disp_pins[] = { + /* DISP */ + RCAR_GP_PIN(5, 6), +}; +static const unsigned int du1_disp_mux[] = { + DU1_DISP_MARK +}; /* - I2C0 ------------------------------------------------------------------- */ static const unsigned int i2c0_a_pins[] = { /* SCL, SDA */ @@ -1835,6 +1921,15 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(du0_oddf), SH_PFC_PIN_GROUP(du0_cde), SH_PFC_PIN_GROUP(du0_disp), + SH_PFC_PIN_GROUP(du1_rgb666), + SH_PFC_PIN_GROUP(du1_rgb888), + SH_PFC_PIN_GROUP(du1_clk0_out), + SH_PFC_PIN_GROUP(du1_clk1_out), + SH_PFC_PIN_GROUP(du1_clk_in), + SH_PFC_PIN_GROUP(du1_sync), + SH_PFC_PIN_GROUP(du1_oddf), + SH_PFC_PIN_GROUP(du1_cde), + SH_PFC_PIN_GROUP(du1_disp), SH_PFC_PIN_GROUP(i2c0_a), SH_PFC_PIN_GROUP(i2c0_b), SH_PFC_PIN_GROUP(i2c0_c), @@ -1936,6 +2031,18 @@ static const char * const du0_groups[] = { "du0_disp", }; +static const char * const du1_groups[] = { + "du1_rgb666", + "du1_rgb888", + "du1_clk0_out", + "du1_clk1_out", + "du1_clk_in", + "du1_sync", + "du1_oddf", + "du1_cde", + "du1_disp", +}; + static const char * const i2c0_groups[] = { "i2c0_a", "i2c0_b", @@ -2061,6 +2168,7 @@ static const char * const usb1_groups[] = { static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(avb), SH_PFC_FUNCTION(du0), + SH_PFC_FUNCTION(du1), SH_PFC_FUNCTION(i2c0), SH_PFC_FUNCTION(i2c1), SH_PFC_FUNCTION(i2c2), -- cgit v1.2.3 From 610d662ac3d38ef0acad2c1128e6a9a547fd8c0f Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 8 Oct 2018 10:30:18 +0100 Subject: pinctrl: sh-pfc: r8a77470: Add VIN pin groups Add VIN[01] pin groups and functions to the RZ/G1C (a.k.a. R8A77470) pinctrl driver. Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/sh-pfc/pfc-r8a77470.c | 184 ++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77470.c b/drivers/pinctrl/sh-pfc/pfc-r8a77470.c index f22a931824e1..3e9015588c6c 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a77470.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a77470.c @@ -1897,6 +1897,146 @@ static const unsigned int usb1_mux[] = { USB1_PWEN_MARK, USB1_OVC_MARK, }; +/* - VIN0 ------------------------------------------------------------------- */ +static const union vin_data vin0_data_pins = { + .data24 = { + /* B */ + RCAR_GP_PIN(5, 20), RCAR_GP_PIN(5, 21), + RCAR_GP_PIN(5, 22), RCAR_GP_PIN(5, 23), + RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 25), + RCAR_GP_PIN(5, 26), RCAR_GP_PIN(5, 27), + /* G */ + RCAR_GP_PIN(4, 2), RCAR_GP_PIN(4, 3), + RCAR_GP_PIN(4, 4), RCAR_GP_PIN(4, 5), + RCAR_GP_PIN(4, 6), RCAR_GP_PIN(5, 8), + RCAR_GP_PIN(5, 9), RCAR_GP_PIN(5, 10), + /* R */ + RCAR_GP_PIN(5, 11), RCAR_GP_PIN(5, 12), + RCAR_GP_PIN(5, 13), RCAR_GP_PIN(5, 14), + RCAR_GP_PIN(5, 15), RCAR_GP_PIN(5, 16), + RCAR_GP_PIN(5, 17), RCAR_GP_PIN(5, 19), + }, +}; +static const union vin_data vin0_data_mux = { + .data24 = { + /* B */ + VI0_DATA0_VI0_B0_MARK, VI0_DATA1_VI0_B1_MARK, + VI0_DATA2_VI0_B2_MARK, VI0_DATA3_VI0_B3_MARK, + VI0_DATA4_VI0_B4_MARK, VI0_DATA5_VI0_B5_MARK, + VI0_DATA6_VI0_B6_MARK, VI0_DATA7_VI0_B7_MARK, + /* G */ + VI0_G0_MARK, VI0_G1_MARK, + VI0_G2_MARK, VI0_G3_MARK, + VI0_G4_MARK, VI0_G5_MARK, + VI0_G6_MARK, VI0_G7_MARK, + /* R */ + VI0_R0_MARK, VI0_R1_MARK, + VI0_R2_MARK, VI0_R3_MARK, + VI0_R4_MARK, VI0_R5_MARK, + VI0_R6_MARK, VI0_R7_MARK, + }, +}; +static const unsigned int vin0_data18_pins[] = { + /* B */ + RCAR_GP_PIN(5, 22), RCAR_GP_PIN(5, 23), + RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 25), + RCAR_GP_PIN(5, 26), RCAR_GP_PIN(5, 27), + /* G */ + RCAR_GP_PIN(4, 4), RCAR_GP_PIN(4, 5), + RCAR_GP_PIN(4, 6), RCAR_GP_PIN(5, 8), + RCAR_GP_PIN(5, 9), RCAR_GP_PIN(5, 10), + /* R */ + RCAR_GP_PIN(5, 13), RCAR_GP_PIN(5, 14), + RCAR_GP_PIN(5, 15), RCAR_GP_PIN(5, 16), + RCAR_GP_PIN(5, 17), RCAR_GP_PIN(5, 19), +}; +static const unsigned int vin0_data18_mux[] = { + /* B */ + VI0_DATA2_VI0_B2_MARK, VI0_DATA3_VI0_B3_MARK, + VI0_DATA4_VI0_B4_MARK, VI0_DATA5_VI0_B5_MARK, + VI0_DATA6_VI0_B6_MARK, VI0_DATA7_VI0_B7_MARK, + /* G */ + VI0_G2_MARK, VI0_G3_MARK, + VI0_G4_MARK, VI0_G5_MARK, + VI0_G6_MARK, VI0_G7_MARK, + /* R */ + VI0_R2_MARK, VI0_R3_MARK, + VI0_R4_MARK, VI0_R5_MARK, + VI0_R6_MARK, VI0_R7_MARK, +}; +static const unsigned int vin0_sync_pins[] = { + RCAR_GP_PIN(5, 30), /* HSYNC */ + RCAR_GP_PIN(5, 31), /* VSYNC */ +}; +static const unsigned int vin0_sync_mux[] = { + VI0_HSYNC_N_MARK, + VI0_VSYNC_N_MARK, +}; +static const unsigned int vin0_field_pins[] = { + RCAR_GP_PIN(5, 29), +}; +static const unsigned int vin0_field_mux[] = { + VI0_FIELD_MARK, +}; +static const unsigned int vin0_clkenb_pins[] = { + RCAR_GP_PIN(5, 28), +}; +static const unsigned int vin0_clkenb_mux[] = { + VI0_CLKENB_MARK, +}; +static const unsigned int vin0_clk_pins[] = { + RCAR_GP_PIN(5, 18), +}; +static const unsigned int vin0_clk_mux[] = { + VI0_CLK_MARK, +}; +/* - VIN1 ------------------------------------------------------------------- */ +static const union vin_data vin1_data_pins = { + .data12 = { + RCAR_GP_PIN(3, 1), RCAR_GP_PIN(3, 2), + RCAR_GP_PIN(3, 3), RCAR_GP_PIN(3, 4), + RCAR_GP_PIN(3, 5), RCAR_GP_PIN(3, 6), + RCAR_GP_PIN(3, 7), RCAR_GP_PIN(3, 8), + RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 14), + RCAR_GP_PIN(3, 15), RCAR_GP_PIN(3, 16), + }, +}; +static const union vin_data vin1_data_mux = { + .data12 = { + VI1_DATA0_MARK, VI1_DATA1_MARK, + VI1_DATA2_MARK, VI1_DATA3_MARK, + VI1_DATA4_MARK, VI1_DATA5_MARK, + VI1_DATA6_MARK, VI1_DATA7_MARK, + VI1_DATA8_MARK, VI1_DATA9_MARK, + VI1_DATA10_MARK, VI1_DATA11_MARK, + }, +}; +static const unsigned int vin1_sync_pins[] = { + RCAR_GP_PIN(3, 11), /* HSYNC */ + RCAR_GP_PIN(3, 12), /* VSYNC */ +}; +static const unsigned int vin1_sync_mux[] = { + VI1_HSYNC_N_MARK, + VI1_VSYNC_N_MARK, +}; +static const unsigned int vin1_field_pins[] = { + RCAR_GP_PIN(3, 10), +}; +static const unsigned int vin1_field_mux[] = { + VI1_FIELD_MARK, +}; +static const unsigned int vin1_clkenb_pins[] = { + RCAR_GP_PIN(3, 9), +}; +static const unsigned int vin1_clkenb_mux[] = { + VI1_CLKENB_MARK, +}; +static const unsigned int vin1_clk_pins[] = { + RCAR_GP_PIN(3, 0), +}; +static const unsigned int vin1_clk_mux[] = { + VI1_CLK_MARK, +}; static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(avb_col), @@ -2001,6 +2141,24 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(sdhi2_wp), SH_PFC_PIN_GROUP(usb0), SH_PFC_PIN_GROUP(usb1), + VIN_DATA_PIN_GROUP(vin0_data, 24), + VIN_DATA_PIN_GROUP(vin0_data, 20), + SH_PFC_PIN_GROUP(vin0_data18), + VIN_DATA_PIN_GROUP(vin0_data, 16), + VIN_DATA_PIN_GROUP(vin0_data, 12), + VIN_DATA_PIN_GROUP(vin0_data, 10), + VIN_DATA_PIN_GROUP(vin0_data, 8), + SH_PFC_PIN_GROUP(vin0_sync), + SH_PFC_PIN_GROUP(vin0_field), + SH_PFC_PIN_GROUP(vin0_clkenb), + SH_PFC_PIN_GROUP(vin0_clk), + VIN_DATA_PIN_GROUP(vin1_data, 12), + VIN_DATA_PIN_GROUP(vin1_data, 10), + VIN_DATA_PIN_GROUP(vin1_data, 8), + SH_PFC_PIN_GROUP(vin1_sync), + SH_PFC_PIN_GROUP(vin1_field), + SH_PFC_PIN_GROUP(vin1_clkenb), + SH_PFC_PIN_GROUP(vin1_clk), }; static const char * const avb_groups[] = { @@ -2165,6 +2323,30 @@ static const char * const usb1_groups[] = { "usb1", }; +static const char * const vin0_groups[] = { + "vin0_data24", + "vin0_data20", + "vin0_data18", + "vin0_data16", + "vin0_data12", + "vin0_data10", + "vin0_data8", + "vin0_sync", + "vin0_field", + "vin0_clkenb", + "vin0_clk", +}; + +static const char * const vin1_groups[] = { + "vin1_data12", + "vin1_data10", + "vin1_data8", + "vin1_sync", + "vin1_field", + "vin1_clkenb", + "vin1_clk", +}; + static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(avb), SH_PFC_FUNCTION(du0), @@ -2186,6 +2368,8 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(sdhi2), SH_PFC_FUNCTION(usb0), SH_PFC_FUNCTION(usb1), + SH_PFC_FUNCTION(vin0), + SH_PFC_FUNCTION(vin1), }; static const struct pinmux_cfg_reg pinmux_config_regs[] = { -- cgit v1.2.3 From f743f017b739e27601fec7d3eab29840c5e95b37 Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Mon, 8 Oct 2018 10:30:19 +0100 Subject: pinctrl: sh-pfc: r8a77470: Add QSPI1 pin groups Add QSPI1 pin groups and function to the RZ/G1C (a.k.a. R8A77470) pinctrl driver. Signed-off-by: Fabrizio Castro Reviewed-by: Fabrizio Castro Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/sh-pfc/pfc-r8a77470.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77470.c b/drivers/pinctrl/sh-pfc/pfc-r8a77470.c index 3e9015588c6c..5e29b957bab9 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a77470.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a77470.c @@ -1604,6 +1604,29 @@ static const unsigned int qspi0_data4_mux[] = { QSPI0_MOSI_QSPI0_IO0_MARK, QSPI0_MISO_QSPI0_IO1_MARK, QSPI0_IO2_MARK, QSPI0_IO3_MARK, }; +static const unsigned int qspi1_ctrl_pins[] = { + /* SPCLK, SSL */ + RCAR_GP_PIN(4, 6), RCAR_GP_PIN(4, 9), +}; +static const unsigned int qspi1_ctrl_mux[] = { + QSPI1_SPCLK_MARK, QSPI1_SSL_MARK, +}; +static const unsigned int qspi1_data2_pins[] = { + /* MOSI_IO0, MISO_IO1 */ + RCAR_GP_PIN(4, 4), RCAR_GP_PIN(4, 5), +}; +static const unsigned int qspi1_data2_mux[] = {