[U-Boot] [PATCH v2 0/7] MSCC: Add Jaguar2 SOC family

This patch series add support for MSCC Jaguar2 SOC family. In this family there are the following boards: Jagaur2(pcb110), Jaguar2-48(pcb111) and Serval2(pcb112).
This is based off the u-boot-mips/next repository
This version address comments from Daniel Schwierzeck daniel.schwierzeck@gmail.com
v2-changes: - create sysreset driver for Jaguar2 - update pinctrl
Horatiu Vultur (7): pinctrl: mscc: Add gpio and pinctrl for Jaguar2 SOC family MSCC: Add support for Jaguar2 SOC family MSCC: Add device tree for Jaguar2 board MSCC: Add device tree for Jaguar2-48 board MSCC: add device tree for Serval2 board MSCC: Add board support for Jaguar2 SOC family MSCC: Add sysreset driver for Jaguar2 SOC family
MAINTAINERS | 4 + arch/mips/dts/Makefile | 1 + arch/mips/dts/jr2_pcb110.dts | 74 +++++ arch/mips/dts/jr2_pcb111.dts | 74 +++++ arch/mips/dts/mscc,jr2.dtsi | 187 +++++++++++ arch/mips/dts/serval2_pcb112.dts | 60 ++++ arch/mips/mach-mscc/Kconfig | 9 + arch/mips/mach-mscc/Makefile | 5 +- arch/mips/mach-mscc/cpu.c | 7 + arch/mips/mach-mscc/dram.c | 2 +- arch/mips/mach-mscc/include/mach/common.h | 5 + arch/mips/mach-mscc/include/mach/ddr.h | 38 ++- arch/mips/mach-mscc/include/mach/jr2/jr2.h | 24 ++ .../mach-mscc/include/mach/jr2/jr2_devcpu_gcb.h | 20 ++ .../include/mach/jr2/jr2_devcpu_gcb_miim_regs.h | 25 ++ .../mips/mach-mscc/include/mach/jr2/jr2_icpu_cfg.h | 321 +++++++++++++++++++ board/mscc/common/Makefile | 4 + board/mscc/common/spi.c | 31 ++ board/mscc/jr2/Kconfig | 15 + board/mscc/jr2/Makefile | 4 + board/mscc/jr2/jr2.c | 125 ++++++++ board/mscc/ocelot/ocelot.c | 22 -- configs/mscc_jr2_defconfig | 61 ++++ drivers/pinctrl/mscc/Kconfig | 9 + drivers/pinctrl/mscc/Makefile | 1 + drivers/pinctrl/mscc/mscc-common.c | 97 ++++-- drivers/pinctrl/mscc/mscc-common.h | 5 + drivers/pinctrl/mscc/pinctrl-jr2.c | 342 +++++++++++++++++++++ drivers/sysreset/Kconfig | 6 + drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_jr2.c | 46 +++ 31 files changed, 1571 insertions(+), 54 deletions(-) create mode 100644 arch/mips/dts/jr2_pcb110.dts create mode 100644 arch/mips/dts/jr2_pcb111.dts create mode 100644 arch/mips/dts/mscc,jr2.dtsi create mode 100644 arch/mips/dts/serval2_pcb112.dts create mode 100644 arch/mips/mach-mscc/include/mach/jr2/jr2.h create mode 100644 arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb.h create mode 100644 arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb_miim_regs.h create mode 100644 arch/mips/mach-mscc/include/mach/jr2/jr2_icpu_cfg.h create mode 100644 board/mscc/common/Makefile create mode 100644 board/mscc/common/spi.c create mode 100644 board/mscc/jr2/Kconfig create mode 100644 board/mscc/jr2/Makefile create mode 100644 board/mscc/jr2/jr2.c create mode 100644 configs/mscc_jr2_defconfig create mode 100644 drivers/pinctrl/mscc/pinctrl-jr2.c create mode 100644 drivers/sysreset/sysreset_jr2.c

The Jaguar2 SOC family has 63 gpio pins therefore I extended mscc-common to support new numbe of pins.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com --- MAINTAINERS | 1 + drivers/pinctrl/mscc/Kconfig | 9 + drivers/pinctrl/mscc/Makefile | 1 + drivers/pinctrl/mscc/mscc-common.c | 97 ++++++++--- drivers/pinctrl/mscc/mscc-common.h | 5 + drivers/pinctrl/mscc/pinctrl-jr2.c | 342 +++++++++++++++++++++++++++++++++++++ 6 files changed, 433 insertions(+), 22 deletions(-) create mode 100644 drivers/pinctrl/mscc/pinctrl-jr2.c
diff --git a/MAINTAINERS b/MAINTAINERS index 494962e..495d3e5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -525,6 +525,7 @@ F: board/mscc/ F: configs/mscc* F: drivers/gpio/mscc_sgpio.c F: include/configs/vcoreiii.h +F: drivers/pinctrl/mscc/
MIPS JZ4780 M: Ezequiel Garcia ezequiel@collabora.com diff --git a/drivers/pinctrl/mscc/Kconfig b/drivers/pinctrl/mscc/Kconfig index cfc6c06..d07ea1b 100644 --- a/drivers/pinctrl/mscc/Kconfig +++ b/drivers/pinctrl/mscc/Kconfig @@ -20,3 +20,12 @@ config PINCTRL_MSCC_LUTON help Support pin multiplexing and pin configuration control on Microsemi luton SoCs. + +config PINCTRL_MSCC_JR2 + depends on SOC_JR2 && PINCTRL_FULL && OF_CONTROL + select PINCTRL_MSCC + default y + bool "Microsemi jr2 family pin control driver" + help + Support pin multiplexing and pin configuration control on + Microsemi jr2 SoCs. diff --git a/drivers/pinctrl/mscc/Makefile b/drivers/pinctrl/mscc/Makefile index 6910671..8038d54 100644 --- a/drivers/pinctrl/mscc/Makefile +++ b/drivers/pinctrl/mscc/Makefile @@ -3,3 +3,4 @@ obj-y += mscc-common.o obj-$(CONFIG_PINCTRL_MSCC_OCELOT) += pinctrl-ocelot.o obj-$(CONFIG_PINCTRL_MSCC_LUTON) += pinctrl-luton.o +obj-$(CONFIG_PINCTRL_MSCC_JR2) += pinctrl-jr2.o diff --git a/drivers/pinctrl/mscc/mscc-common.c b/drivers/pinctrl/mscc/mscc-common.c index d74b8a6..7743565 100644 --- a/drivers/pinctrl/mscc/mscc-common.c +++ b/drivers/pinctrl/mscc/mscc-common.c @@ -22,6 +22,18 @@ #include <linux/io.h> #include "mscc-common.h"
+#if defined(CONFIG_SOC_JR2) +#define MSCC_GPIO_OUT_SET 0x00 +#define MSCC_GPIO_OUT_CLR 0x08 +#define MSCC_GPIO_OUT 0x10 +#define MSCC_GPIO_IN 0x18 +#define MSCC_GPIO_OE 0x20 +#define MSCC_GPIO_INTR 0x28 +#define MSCC_GPIO_INTR_ENA 0x30 +#define MSCC_GPIO_INTR_IDENT 0x38 +#define MSCC_GPIO_ALT0 0x40 +#define MSCC_GPIO_ALT1 0x48 +#else #define MSCC_GPIO_OUT_SET 0x0 #define MSCC_GPIO_OUT_CLR 0x4 #define MSCC_GPIO_OUT 0x8 @@ -32,6 +44,39 @@ #define MSCC_GPIO_INTR_IDENT 0x1c #define MSCC_GPIO_ALT0 0x20 #define MSCC_GPIO_ALT1 0x24 +#endif + +static void mscc_writel(unsigned int offset, void *addr) +{ + if (offset < 32) + writel(BIT(offset), addr); + else + writel(BIT(offset % 32), addr + 4); +} + +static unsigned int mscc_readl(unsigned int offset, void *addr) +{ + if (offset < 32) + return readl(addr); + else + return readl(addr + 4); +} + +void mscc_setbits(unsigned int offset, void *addr) +{ + if (offset < 32) + writel(readl(addr) | BIT(offset), addr); + else + writel(readl(addr + 4) | BIT(offset % 32), addr + 4); +} + +void mscc_clrbits(unsigned int offset, void *addr) +{ + if (offset < 32) + writel(readl(addr) & ~BIT(offset), addr); + else + writel(readl(addr + 4) & ~BIT(offset % 32), addr + 4); +}
static int mscc_get_functions_count(struct udevice *dev) { @@ -48,8 +93,8 @@ static const char *mscc_get_function_name(struct udevice *dev, return info->function_names[function]; }
-static int mscc_pin_function_idx(unsigned int pin, unsigned int function, - const struct mscc_pin_data *mscc_pins) +int mscc_pin_function_idx(unsigned int pin, unsigned int function, + const struct mscc_pin_data *mscc_pins) { struct mscc_pin_caps *p = mscc_pins[pin].drv_data; int i; @@ -62,7 +107,7 @@ static int mscc_pin_function_idx(unsigned int pin, unsigned int function, return -1; }
-static int mscc_pinmux_set_mux(struct udevice *dev, +__weak int mscc_pinmux_set_mux(struct udevice *dev, unsigned int pin_selector, unsigned int selector) { struct mscc_pinctrl *info = dev_get_priv(dev); @@ -79,15 +124,16 @@ static int mscc_pinmux_set_mux(struct udevice *dev, * This is racy because both registers can't be updated at the same time * but it doesn't matter much for now. */ + if (f & BIT(0)) - setbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin)); + mscc_setbits(pin->pin, info->regs + MSCC_GPIO_ALT0); else - clrbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin)); + mscc_clrbits(pin->pin, info->regs + MSCC_GPIO_ALT0);
if (f & BIT(1)) - setbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1)); + mscc_setbits(pin->pin, info->regs + MSCC_GPIO_ALT1 + 4); else - clrbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1)); + mscc_clrbits(pin->pin, info->regs + MSCC_GPIO_ALT1 + 4);
return 0; } @@ -120,8 +166,8 @@ static int mscc_create_group_func_map(struct udevice *dev, }
info->func[f].ngroups = npins; - info->func[f].groups = devm_kzalloc(dev, npins * - sizeof(char *), GFP_KERNEL); + info->func[f].groups = devm_kzalloc(dev, npins * sizeof(char *), + GFP_KERNEL); if (!info->func[f].groups) return -ENOMEM;
@@ -132,7 +178,8 @@ static int mscc_create_group_func_map(struct udevice *dev, return 0; }
-static int mscc_pinctrl_register(struct udevice *dev, struct mscc_pinctrl *info) +static int mscc_pinctrl_register(struct udevice *dev, + struct mscc_pinctrl *info) { int ret;
@@ -150,38 +197,44 @@ static int mscc_gpio_get(struct udevice *dev, unsigned int offset) struct mscc_pinctrl *info = dev_get_priv(dev->parent); unsigned int val;
- val = readl(info->regs + MSCC_GPIO_IN); + if (mscc_readl(offset, info->regs + MSCC_GPIO_OE) & BIT(offset % 32)) + val = mscc_readl(offset, info->regs + MSCC_GPIO_OUT); + else + val = mscc_readl(offset, info->regs + MSCC_GPIO_IN);
- return !!(val & BIT(offset)); + return !!(val & BIT(offset % 32)); }
-static int mscc_gpio_set(struct udevice *dev, unsigned int offset, int value) +static int mscc_gpio_set(struct udevice *dev, unsigned int offset, + int value) { struct mscc_pinctrl *info = dev_get_priv(dev->parent);
if (value) - writel(BIT(offset), info->regs + MSCC_GPIO_OUT_SET); + mscc_writel(offset, info->regs + MSCC_GPIO_OUT_SET); else - writel(BIT(offset), info->regs + MSCC_GPIO_OUT_CLR); + mscc_writel(offset, info->regs + MSCC_GPIO_OUT_CLR);
return 0; }
-static int mscc_gpio_get_direction(struct udevice *dev, unsigned int offset) +static int mscc_gpio_get_direction(struct udevice *dev, + unsigned int offset) { struct mscc_pinctrl *info = dev_get_priv(dev->parent); unsigned int val;
- val = readl(info->regs + MSCC_GPIO_OE); + val = mscc_readl(offset, info->regs + MSCC_GPIO_OE);
- return (val & BIT(offset)) ? GPIOF_OUTPUT : GPIOF_INPUT; + return (val & BIT(offset % 32)) ? GPIOF_OUTPUT : GPIOF_INPUT; }
-static int mscc_gpio_direction_input(struct udevice *dev, unsigned int offset) +static int mscc_gpio_direction_input(struct udevice *dev, + unsigned int offset) { struct mscc_pinctrl *info = dev_get_priv(dev->parent);
- clrbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset)); + mscc_clrbits(offset, info->regs + MSCC_GPIO_OE);
return 0; } @@ -191,7 +244,7 @@ static int mscc_gpio_direction_output(struct udevice *dev, { struct mscc_pinctrl *info = dev_get_priv(dev->parent);
- setbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset)); + mscc_setbits(offset, info->regs + MSCC_GPIO_OE);
return mscc_gpio_set(dev, offset, value); } @@ -215,7 +268,7 @@ const struct pinctrl_ops mscc_pinctrl_ops = {
int mscc_pinctrl_probe(struct udevice *dev, int num_func, const struct mscc_pin_data *mscc_pins, int num_pins, - char *const *function_names) + char * const*function_names) { struct mscc_pinctrl *priv = dev_get_priv(dev); int ret; diff --git a/drivers/pinctrl/mscc/mscc-common.h b/drivers/pinctrl/mscc/mscc-common.h index b0001db..1b986a9 100644 --- a/drivers/pinctrl/mscc/mscc-common.h +++ b/drivers/pinctrl/mscc/mscc-common.h @@ -43,6 +43,11 @@ struct mscc_pinctrl { char * const *function_names; };
+void mscc_setbits(unsigned int offset, void *addr); +void mscc_clrbits(unsigned int offset, void *addr); +int mscc_pin_function_idx(unsigned int pin, unsigned int function, + const struct mscc_pin_data *mscc_pins); + int mscc_pinctrl_probe(struct udevice *dev, int num_func, const struct mscc_pin_data *mscc_pins, int num_pins, char * const *function_names); diff --git a/drivers/pinctrl/mscc/pinctrl-jr2.c b/drivers/pinctrl/mscc/pinctrl-jr2.c new file mode 100644 index 0000000..5c28693 --- /dev/null +++ b/drivers/pinctrl/mscc/pinctrl-jr2.c @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Microsemi SoCs pinctrl driver + * + * Author: horatiu.vultur@microchip.com + * License: Dual MIT/GPL + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <config.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dm/pinctrl.h> +#include <dm/root.h> +#include <errno.h> +#include <fdtdec.h> +#include <linux/io.h> +#include <asm/gpio.h> +#include <asm/system.h> +#include "mscc-common.h" + +#define MSCC_GPIO_ALT0 0x40 +#define MSCC_GPIO_ALT1 0x48 + +enum { + FUNC_NONE, + FUNC_GPIO, + FUNC_IRQ0_IN, + FUNC_IRQ0_OUT, + FUNC_IRQ1_IN, + FUNC_IRQ1_OUT, + FUNC_MIIM1, + FUNC_MIIM2, + FUNC_PCI_WAKE, + FUNC_PTP0, + FUNC_PTP1, + FUNC_PTP2, + FUNC_PTP3, + FUNC_PWM, + FUNC_RECO_CLK0, + FUNC_RECO_CLK1, + FUNC_SFP0, + FUNC_SFP1, + FUNC_SFP2, + FUNC_SFP3, + FUNC_SFP4, + FUNC_SFP5, + FUNC_SFP6, + FUNC_SFP7, + FUNC_SFP8, + FUNC_SFP9, + FUNC_SFP10, + FUNC_SFP11, + FUNC_SFP12, + FUNC_SFP13, + FUNC_SFP14, + FUNC_SFP15, + FUNC_SIO, + FUNC_SIO1, + FUNC_SIO2, + FUNC_SI, + FUNC_TACHO, + FUNC_TWI, + FUNC_TWI2, + FUNC_TWI_SCL_M, + FUNC_UART, + FUNC_UART2, + FUNC_MAX +}; + +char *jr2_function_names[] = { + [FUNC_NONE] = "none", + [FUNC_GPIO] = "gpio", + [FUNC_IRQ0_IN] = "irq0_in", + [FUNC_IRQ0_OUT] = "irq0_out", + [FUNC_IRQ1_IN] = "irq1_in", + [FUNC_IRQ1_OUT] = "irq1_out", + [FUNC_MIIM1] = "miim1", + [FUNC_MIIM2] = "miim2", + [FUNC_PCI_WAKE] = "pci_wake", + [FUNC_PTP0] = "ptp0", + [FUNC_PTP1] = "ptp1", + [FUNC_PTP2] = "ptp2", + [FUNC_PTP3] = "ptp3", + [FUNC_PWM] = "pwm", + [FUNC_RECO_CLK0] = "reco_clk0", + [FUNC_RECO_CLK1] = "reco_clk1", + [FUNC_SFP0] = "sfp0", + [FUNC_SFP1] = "sfp1", + [FUNC_SFP2] = "sfp2", + [FUNC_SFP3] = "sfp3", + [FUNC_SFP4] = "sfp4", + [FUNC_SFP5] = "sfp5", + [FUNC_SFP6] = "sfp6", + [FUNC_SFP7] = "sfp7", + [FUNC_SFP8] = "sfp8", + [FUNC_SFP9] = "sfp9", + [FUNC_SFP10] = "sfp10", + [FUNC_SFP11] = "sfp11", + [FUNC_SFP12] = "sfp12", + [FUNC_SFP13] = "sfp13", + [FUNC_SFP14] = "sfp14", + [FUNC_SFP15] = "sfp15", + [FUNC_SIO] = "sio", + [FUNC_SIO1] = "sio1", + [FUNC_SIO2] = "sio2", + [FUNC_SI] = "si", + [FUNC_TACHO] = "tacho", + [FUNC_TWI] = "twi", + [FUNC_TWI2] = "twi2", + [FUNC_TWI_SCL_M] = "twi_scl_m", + [FUNC_UART] = "uart", + [FUNC_UART2] = "uart2", +}; + +MSCC_P(0, SIO, NONE, NONE); +MSCC_P(1, SIO, NONE, NONE); +MSCC_P(2, SIO, NONE, NONE); +MSCC_P(3, SIO, NONE, NONE); +MSCC_P(4, SIO1, NONE, NONE); +MSCC_P(5, SIO1, NONE, NONE); +MSCC_P(6, IRQ0_IN, IRQ0_OUT, NONE); +MSCC_P(7, IRQ1_IN, IRQ1_OUT, NONE); +MSCC_P(8, PTP0, NONE, NONE); +MSCC_P(9, PTP1, NONE, NONE); +MSCC_P(10, UART, NONE, NONE); +MSCC_P(11, UART, NONE, NONE); +MSCC_P(12, SIO1, NONE, NONE); +MSCC_P(13, SIO1, NONE, NONE); +MSCC_P(14, TWI, TWI_SCL_M, NONE); +MSCC_P(15, TWI, NONE, NONE); +MSCC_P(16, SI, TWI_SCL_M, NONE); +MSCC_P(17, SI, TWI_SCL_M, NONE); +MSCC_P(18, SI, TWI_SCL_M, NONE); +MSCC_P(19, PCI_WAKE, NONE, NONE); +MSCC_P(20, IRQ0_OUT, TWI_SCL_M, NONE); +MSCC_P(21, IRQ1_OUT, TWI_SCL_M, NONE); +MSCC_P(22, TACHO, NONE, NONE); +MSCC_P(23, PWM, NONE, NONE); +MSCC_P(24, UART2, NONE, NONE); +MSCC_P(25, UART2, SI, NONE); +MSCC_P(26, PTP2, SI, NONE); +MSCC_P(27, PTP3, SI, NONE); +MSCC_P(28, TWI2, SI, NONE); +MSCC_P(29, TWI, SI, NONE); +MSCC_P(30, SIO2, SI, NONE); +MSCC_P(31, SIO2, SI, NONE); +MSCC_P(32, SIO2, SI, NONE); +MSCC_P(33, SIO2, SI, NONE); +MSCC_P(34, NONE, TWI_SCL_M, NONE); +MSCC_P(35, NONE, TWI_SCL_M, NONE); +MSCC_P(36, NONE, TWI_SCL_M, NONE); +MSCC_P(37, NONE, TWI_SCL_M, NONE); +MSCC_P(38, NONE, TWI_SCL_M, NONE); +MSCC_P(39, NONE, TWI_SCL_M, NONE); +MSCC_P(40, NONE, TWI_SCL_M, NONE); +MSCC_P(41, NONE, TWI_SCL_M, NONE); +MSCC_P(42, NONE, TWI_SCL_M, NONE); +MSCC_P(43, NONE, TWI_SCL_M, NONE); +MSCC_P(44, NONE, SFP8, NONE); +MSCC_P(45, NONE, SFP9, NONE); +MSCC_P(46, NONE, SFP10, NONE); +MSCC_P(47, NONE, SFP11, NONE); +MSCC_P(48, SFP0, NONE, NONE); +MSCC_P(49, SFP1, SI, NONE); +MSCC_P(50, SFP2, SI, NONE); +MSCC_P(51, SFP3, SI, NONE); +MSCC_P(52, SFP4, NONE, NONE); +MSCC_P(53, SFP5, NONE, NONE); +MSCC_P(54, SFP6, NONE, NONE); +MSCC_P(55, SFP7, NONE, NONE); +MSCC_P(56, MIIM1, SFP12, NONE); +MSCC_P(57, MIIM1, SFP13, NONE); +MSCC_P(58, MIIM2, SFP14, NONE); +MSCC_P(59, MIIM2, SFP15, NONE); +MSCC_P(60, NONE, NONE, NONE); +MSCC_P(61, NONE, NONE, NONE); +MSCC_P(62, NONE, NONE, NONE); +MSCC_P(63, NONE, NONE, NONE); + +#define JR2_PIN(n) { \ + .name = "GPIO_"#n, \ + .drv_data = &mscc_pin_##n \ +} + +const struct mscc_pin_data jr2_pins[] = { + JR2_PIN(0), + JR2_PIN(1), + JR2_PIN(2), + JR2_PIN(3), + JR2_PIN(4), + JR2_PIN(5), + JR2_PIN(6), + JR2_PIN(7), + JR2_PIN(8), + JR2_PIN(9), + JR2_PIN(10), + JR2_PIN(11), + JR2_PIN(12), + JR2_PIN(13), + JR2_PIN(14), + JR2_PIN(15), + JR2_PIN(16), + JR2_PIN(17), + JR2_PIN(18), + JR2_PIN(19), + JR2_PIN(20), + JR2_PIN(21), + JR2_PIN(22), + JR2_PIN(23), + JR2_PIN(24), + JR2_PIN(25), + JR2_PIN(26), + JR2_PIN(27), + JR2_PIN(28), + JR2_PIN(29), + JR2_PIN(30), + JR2_PIN(31), + JR2_PIN(32), + JR2_PIN(33), + JR2_PIN(34), + JR2_PIN(35), + JR2_PIN(36), + JR2_PIN(37), + JR2_PIN(38), + JR2_PIN(39), + JR2_PIN(40), + JR2_PIN(41), + JR2_PIN(42), + JR2_PIN(43), + JR2_PIN(44), + JR2_PIN(45), + JR2_PIN(46), + JR2_PIN(47), + JR2_PIN(48), + JR2_PIN(49), + JR2_PIN(50), + JR2_PIN(51), + JR2_PIN(52), + JR2_PIN(53), + JR2_PIN(54), + JR2_PIN(55), + JR2_PIN(56), + JR2_PIN(57), + JR2_PIN(58), + JR2_PIN(59), + JR2_PIN(60), + JR2_PIN(61), + JR2_PIN(62), + JR2_PIN(63), +}; + +int mscc_pinmux_set_mux(struct udevice *dev, + unsigned int pin_selector, unsigned int selector) +{ + struct mscc_pinctrl *info = dev_get_priv(dev); + struct mscc_pin_caps *pin = info->mscc_pins[pin_selector].drv_data; + int f, offset, regoff; + + f = mscc_pin_function_idx(pin_selector, selector, info->mscc_pins); + if (f < 0) + return -EINVAL; + /* + * f is encoded on two bits. + * bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of + * ALT1 + * This is racy because both registers can't be updated at the same time + * but it doesn't matter much for now. + */ + offset = pin->pin; + regoff = MSCC_GPIO_ALT0; + if (offset >= 32) { + offset = offset % 32; + regoff = MSCC_GPIO_ALT1; + } + + if (f & BIT(0)) + mscc_setbits(offset, info->regs + regoff); + else + mscc_clrbits(offset, info->regs + regoff); + + if (f & BIT(1)) + mscc_setbits(offset, info->regs + regoff + 4); + else + mscc_clrbits(offset, info->regs + regoff + 4); + + return 0; +} + +static int jr2_gpio_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv; + + uc_priv = dev_get_uclass_priv(dev); + uc_priv->bank_name = "jr2-gpio"; + uc_priv->gpio_count = ARRAY_SIZE(jr2_pins); + + return 0; +} + +static struct driver jr2_gpio_driver = { + .name = "jr2-gpio", + .id = UCLASS_GPIO, + .probe = jr2_gpio_probe, + .ops = &mscc_gpio_ops, +}; + +int jr2_pinctrl_probe(struct udevice *dev) +{ + int ret; + + ret = mscc_pinctrl_probe(dev, FUNC_MAX, jr2_pins, + ARRAY_SIZE(jr2_pins), + jr2_function_names); + + if (ret) + return ret; + + ret = device_bind(dev, &jr2_gpio_driver, "jr2-gpio", NULL, + dev_of_offset(dev), NULL); + + if (ret) + return ret; + + return 0; +} + +static const struct udevice_id jr2_pinctrl_of_match[] = { + { .compatible = "mscc,jr2-pinctrl" }, + {}, +}; + +U_BOOT_DRIVER(jr2_pinctrl) = { + .name = "jr2-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(jr2_pinctrl_of_match), + .probe = jr2_pinctrl_probe, + .priv_auto_alloc_size = sizeof(struct mscc_pinctrl), + .ops = &mscc_pinctrl_ops, +};

Am 07.01.19 um 14:02 schrieb Horatiu Vultur:
The Jaguar2 SOC family has 63 gpio pins therefore I extended mscc-common to support new numbe of pins.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com
MAINTAINERS | 1 + drivers/pinctrl/mscc/Kconfig | 9 + drivers/pinctrl/mscc/Makefile | 1 + drivers/pinctrl/mscc/mscc-common.c | 97 ++++++++--- drivers/pinctrl/mscc/mscc-common.h | 5 + drivers/pinctrl/mscc/pinctrl-jr2.c | 342 +++++++++++++++++++++++++++++++++++++ 6 files changed, 433 insertions(+), 22 deletions(-) create mode 100644 drivers/pinctrl/mscc/pinctrl-jr2.c
diff --git a/MAINTAINERS b/MAINTAINERS index 494962e..495d3e5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -525,6 +525,7 @@ F: board/mscc/ F: configs/mscc* F: drivers/gpio/mscc_sgpio.c F: include/configs/vcoreiii.h +F: drivers/pinctrl/mscc/
MIPS JZ4780 M: Ezequiel Garcia ezequiel@collabora.com diff --git a/drivers/pinctrl/mscc/Kconfig b/drivers/pinctrl/mscc/Kconfig index cfc6c06..d07ea1b 100644 --- a/drivers/pinctrl/mscc/Kconfig +++ b/drivers/pinctrl/mscc/Kconfig @@ -20,3 +20,12 @@ config PINCTRL_MSCC_LUTON help Support pin multiplexing and pin configuration control on Microsemi luton SoCs.
+config PINCTRL_MSCC_JR2
- depends on SOC_JR2 && PINCTRL_FULL && OF_CONTROL
- select PINCTRL_MSCC
- default y
- bool "Microsemi jr2 family pin control driver"
- help
Support pin multiplexing and pin configuration control on
Microsemi jr2 SoCs.
diff --git a/drivers/pinctrl/mscc/Makefile b/drivers/pinctrl/mscc/Makefile index 6910671..8038d54 100644 --- a/drivers/pinctrl/mscc/Makefile +++ b/drivers/pinctrl/mscc/Makefile @@ -3,3 +3,4 @@ obj-y += mscc-common.o obj-$(CONFIG_PINCTRL_MSCC_OCELOT) += pinctrl-ocelot.o obj-$(CONFIG_PINCTRL_MSCC_LUTON) += pinctrl-luton.o +obj-$(CONFIG_PINCTRL_MSCC_JR2) += pinctrl-jr2.o diff --git a/drivers/pinctrl/mscc/mscc-common.c b/drivers/pinctrl/mscc/mscc-common.c index d74b8a6..7743565 100644 --- a/drivers/pinctrl/mscc/mscc-common.c +++ b/drivers/pinctrl/mscc/mscc-common.c @@ -22,6 +22,18 @@ #include <linux/io.h> #include "mscc-common.h"
+#if defined(CONFIG_SOC_JR2) +#define MSCC_GPIO_OUT_SET 0x00 +#define MSCC_GPIO_OUT_CLR 0x08 +#define MSCC_GPIO_OUT 0x10 +#define MSCC_GPIO_IN 0x18 +#define MSCC_GPIO_OE 0x20 +#define MSCC_GPIO_INTR 0x28 +#define MSCC_GPIO_INTR_ENA 0x30 +#define MSCC_GPIO_INTR_IDENT 0x38 +#define MSCC_GPIO_ALT0 0x40 +#define MSCC_GPIO_ALT1 0x48 +#else
you should also move this to pinctrl-jr2.c
#define MSCC_GPIO_OUT_SET 0x0 #define MSCC_GPIO_OUT_CLR 0x4 #define MSCC_GPIO_OUT 0x8 @@ -32,6 +44,39 @@ #define MSCC_GPIO_INTR_IDENT 0x1c #define MSCC_GPIO_ALT0 0x20 #define MSCC_GPIO_ALT1 0x24 +#endif
+static void mscc_writel(unsigned int offset, void *addr) +{
- if (offset < 32)
writel(BIT(offset), addr);
- else
writel(BIT(offset % 32), addr + 4);
+}
+static unsigned int mscc_readl(unsigned int offset, void *addr) +{
- if (offset < 32)
return readl(addr);
- else
return readl(addr + 4);
+}
+void mscc_setbits(unsigned int offset, void *addr) +{
- if (offset < 32)
writel(readl(addr) | BIT(offset), addr);
- else
writel(readl(addr + 4) | BIT(offset % 32), addr + 4);
+}
+void mscc_clrbits(unsigned int offset, void *addr) +{
- if (offset < 32)
writel(readl(addr) & ~BIT(offset), addr);
- else
writel(readl(addr + 4) & ~BIT(offset % 32), addr + 4);
+}
static int mscc_get_functions_count(struct udevice *dev) { @@ -48,8 +93,8 @@ static const char *mscc_get_function_name(struct udevice *dev, return info->function_names[function]; }
-static int mscc_pin_function_idx(unsigned int pin, unsigned int function,
const struct mscc_pin_data *mscc_pins)
+int mscc_pin_function_idx(unsigned int pin, unsigned int function,
const struct mscc_pin_data *mscc_pins)
{ struct mscc_pin_caps *p = mscc_pins[pin].drv_data; int i; @@ -62,7 +107,7 @@ static int mscc_pin_function_idx(unsigned int pin, unsigned int function, return -1; }
-static int mscc_pinmux_set_mux(struct udevice *dev, +__weak int mscc_pinmux_set_mux(struct udevice *dev, unsigned int pin_selector, unsigned int selector) { struct mscc_pinctrl *info = dev_get_priv(dev); @@ -79,15 +124,16 @@ static int mscc_pinmux_set_mux(struct udevice *dev, * This is racy because both registers can't be updated at the same time * but it doesn't matter much for now. */
- if (f & BIT(0))
setbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin));
elsemscc_setbits(pin->pin, info->regs + MSCC_GPIO_ALT0);
clrbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin));
mscc_clrbits(pin->pin, info->regs + MSCC_GPIO_ALT0);
if (f & BIT(1))
setbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1));
elsemscc_setbits(pin->pin, info->regs + MSCC_GPIO_ALT1 + 4);
clrbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1));
mscc_clrbits(pin->pin, info->regs + MSCC_GPIO_ALT1 + 4);
return 0;
} @@ -120,8 +166,8 @@ static int mscc_create_group_func_map(struct udevice *dev, }
info->func[f].ngroups = npins;
info->func[f].groups = devm_kzalloc(dev, npins *
sizeof(char *), GFP_KERNEL);
info->func[f].groups = devm_kzalloc(dev, npins * sizeof(char *),
if (!info->func[f].groups) return -ENOMEM;GFP_KERNEL);
@@ -132,7 +178,8 @@ static int mscc_create_group_func_map(struct udevice *dev, return 0; }
-static int mscc_pinctrl_register(struct udevice *dev, struct mscc_pinctrl *info) +static int mscc_pinctrl_register(struct udevice *dev,
struct mscc_pinctrl *info)
{ int ret;
@@ -150,38 +197,44 @@ static int mscc_gpio_get(struct udevice *dev, unsigned int offset) struct mscc_pinctrl *info = dev_get_priv(dev->parent); unsigned int val;
- val = readl(info->regs + MSCC_GPIO_IN);
- if (mscc_readl(offset, info->regs + MSCC_GPIO_OE) & BIT(offset % 32))
val = mscc_readl(offset, info->regs + MSCC_GPIO_OUT);
- else
val = mscc_readl(offset, info->regs + MSCC_GPIO_IN);
- return !!(val & BIT(offset));
- return !!(val & BIT(offset % 32));
}
-static int mscc_gpio_set(struct udevice *dev, unsigned int offset, int value) +static int mscc_gpio_set(struct udevice *dev, unsigned int offset,
int value)
{ struct mscc_pinctrl *info = dev_get_priv(dev->parent);
if (value)
writel(BIT(offset), info->regs + MSCC_GPIO_OUT_SET);
elsemscc_writel(offset, info->regs + MSCC_GPIO_OUT_SET);
writel(BIT(offset), info->regs + MSCC_GPIO_OUT_CLR);
mscc_writel(offset, info->regs + MSCC_GPIO_OUT_CLR);
return 0;
}
-static int mscc_gpio_get_direction(struct udevice *dev, unsigned int offset) +static int mscc_gpio_get_direction(struct udevice *dev,
unsigned int offset)
{ struct mscc_pinctrl *info = dev_get_priv(dev->parent); unsigned int val;
- val = readl(info->regs + MSCC_GPIO_OE);
- val = mscc_readl(offset, info->regs + MSCC_GPIO_OE);
- return (val & BIT(offset)) ? GPIOF_OUTPUT : GPIOF_INPUT;
- return (val & BIT(offset % 32)) ? GPIOF_OUTPUT : GPIOF_INPUT;
}
-static int mscc_gpio_direction_input(struct udevice *dev, unsigned int offset) +static int mscc_gpio_direction_input(struct udevice *dev,
unsigned int offset)
{ struct mscc_pinctrl *info = dev_get_priv(dev->parent);
- clrbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset));
mscc_clrbits(offset, info->regs + MSCC_GPIO_OE);
return 0;
} @@ -191,7 +244,7 @@ static int mscc_gpio_direction_output(struct udevice *dev, { struct mscc_pinctrl *info = dev_get_priv(dev->parent);
- setbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset));
mscc_setbits(offset, info->regs + MSCC_GPIO_OE);
return mscc_gpio_set(dev, offset, value);
} @@ -215,7 +268,7 @@ const struct pinctrl_ops mscc_pinctrl_ops = {
int mscc_pinctrl_probe(struct udevice *dev, int num_func, const struct mscc_pin_data *mscc_pins, int num_pins,
char *const *function_names)
char * const*function_names)
missing space: char * const *function_names
{ struct mscc_pinctrl *priv = dev_get_priv(dev); int ret; diff --git a/drivers/pinctrl/mscc/mscc-common.h b/drivers/pinctrl/mscc/mscc-common.h index b0001db..1b986a9 100644 --- a/drivers/pinctrl/mscc/mscc-common.h +++ b/drivers/pinctrl/mscc/mscc-common.h @@ -43,6 +43,11 @@ struct mscc_pinctrl { char * const *function_names; };
+void mscc_setbits(unsigned int offset, void *addr); +void mscc_clrbits(unsigned int offset, void *addr); +int mscc_pin_function_idx(unsigned int pin, unsigned int function,
const struct mscc_pin_data *mscc_pins);
int mscc_pinctrl_probe(struct udevice *dev, int num_func, const struct mscc_pin_data *mscc_pins, int num_pins, char * const *function_names); diff --git a/drivers/pinctrl/mscc/pinctrl-jr2.c b/drivers/pinctrl/mscc/pinctrl-jr2.c new file mode 100644 index 0000000..5c28693 --- /dev/null +++ b/drivers/pinctrl/mscc/pinctrl-jr2.c @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/*
- Microsemi SoCs pinctrl driver
- Author: horatiu.vultur@microchip.com
- License: Dual MIT/GPL
license is redundant due to SPDX
- Copyright (c) 2018 Microsemi Corporation
- */
+#include <common.h> +#include <config.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dm/pinctrl.h> +#include <dm/root.h> +#include <errno.h> +#include <fdtdec.h> +#include <linux/io.h> +#include <asm/gpio.h> +#include <asm/system.h> +#include "mscc-common.h"
+#define MSCC_GPIO_ALT0 0x40 +#define MSCC_GPIO_ALT1 0x48
+enum {
- FUNC_NONE,
- FUNC_GPIO,
- FUNC_IRQ0_IN,
- FUNC_IRQ0_OUT,
- FUNC_IRQ1_IN,
- FUNC_IRQ1_OUT,
- FUNC_MIIM1,
- FUNC_MIIM2,
- FUNC_PCI_WAKE,
- FUNC_PTP0,
- FUNC_PTP1,
- FUNC_PTP2,
- FUNC_PTP3,
- FUNC_PWM,
- FUNC_RECO_CLK0,
- FUNC_RECO_CLK1,
- FUNC_SFP0,
- FUNC_SFP1,
- FUNC_SFP2,
- FUNC_SFP3,
- FUNC_SFP4,
- FUNC_SFP5,
- FUNC_SFP6,
- FUNC_SFP7,
- FUNC_SFP8,
- FUNC_SFP9,
- FUNC_SFP10,
- FUNC_SFP11,
- FUNC_SFP12,
- FUNC_SFP13,
- FUNC_SFP14,
- FUNC_SFP15,
- FUNC_SIO,
- FUNC_SIO1,
- FUNC_SIO2,
- FUNC_SI,
- FUNC_TACHO,
- FUNC_TWI,
- FUNC_TWI2,
- FUNC_TWI_SCL_M,
- FUNC_UART,
- FUNC_UART2,
- FUNC_MAX
+};
+char *jr2_function_names[] = {
- [FUNC_NONE] = "none",
- [FUNC_GPIO] = "gpio",
- [FUNC_IRQ0_IN] = "irq0_in",
- [FUNC_IRQ0_OUT] = "irq0_out",
- [FUNC_IRQ1_IN] = "irq1_in",
- [FUNC_IRQ1_OUT] = "irq1_out",
- [FUNC_MIIM1] = "miim1",
- [FUNC_MIIM2] = "miim2",
- [FUNC_PCI_WAKE] = "pci_wake",
- [FUNC_PTP0] = "ptp0",
- [FUNC_PTP1] = "ptp1",
- [FUNC_PTP2] = "ptp2",
- [FUNC_PTP3] = "ptp3",
- [FUNC_PWM] = "pwm",
- [FUNC_RECO_CLK0] = "reco_clk0",
- [FUNC_RECO_CLK1] = "reco_clk1",
- [FUNC_SFP0] = "sfp0",
- [FUNC_SFP1] = "sfp1",
- [FUNC_SFP2] = "sfp2",
- [FUNC_SFP3] = "sfp3",
- [FUNC_SFP4] = "sfp4",
- [FUNC_SFP5] = "sfp5",
- [FUNC_SFP6] = "sfp6",
- [FUNC_SFP7] = "sfp7",
- [FUNC_SFP8] = "sfp8",
- [FUNC_SFP9] = "sfp9",
- [FUNC_SFP10] = "sfp10",
- [FUNC_SFP11] = "sfp11",
- [FUNC_SFP12] = "sfp12",
- [FUNC_SFP13] = "sfp13",
- [FUNC_SFP14] = "sfp14",
- [FUNC_SFP15] = "sfp15",
- [FUNC_SIO] = "sio",
- [FUNC_SIO1] = "sio1",
- [FUNC_SIO2] = "sio2",
- [FUNC_SI] = "si",
- [FUNC_TACHO] = "tacho",
- [FUNC_TWI] = "twi",
- [FUNC_TWI2] = "twi2",
- [FUNC_TWI_SCL_M] = "twi_scl_m",
- [FUNC_UART] = "uart",
- [FUNC_UART2] = "uart2",
+};
+MSCC_P(0, SIO, NONE, NONE); +MSCC_P(1, SIO, NONE, NONE); +MSCC_P(2, SIO, NONE, NONE); +MSCC_P(3, SIO, NONE, NONE); +MSCC_P(4, SIO1, NONE, NONE); +MSCC_P(5, SIO1, NONE, NONE); +MSCC_P(6, IRQ0_IN, IRQ0_OUT, NONE); +MSCC_P(7, IRQ1_IN, IRQ1_OUT, NONE); +MSCC_P(8, PTP0, NONE, NONE); +MSCC_P(9, PTP1, NONE, NONE); +MSCC_P(10, UART, NONE, NONE); +MSCC_P(11, UART, NONE, NONE); +MSCC_P(12, SIO1, NONE, NONE); +MSCC_P(13, SIO1, NONE, NONE); +MSCC_P(14, TWI, TWI_SCL_M, NONE); +MSCC_P(15, TWI, NONE, NONE); +MSCC_P(16, SI, TWI_SCL_M, NONE); +MSCC_P(17, SI, TWI_SCL_M, NONE); +MSCC_P(18, SI, TWI_SCL_M, NONE); +MSCC_P(19, PCI_WAKE, NONE, NONE); +MSCC_P(20, IRQ0_OUT, TWI_SCL_M, NONE); +MSCC_P(21, IRQ1_OUT, TWI_SCL_M, NONE); +MSCC_P(22, TACHO, NONE, NONE); +MSCC_P(23, PWM, NONE, NONE); +MSCC_P(24, UART2, NONE, NONE); +MSCC_P(25, UART2, SI, NONE); +MSCC_P(26, PTP2, SI, NONE); +MSCC_P(27, PTP3, SI, NONE); +MSCC_P(28, TWI2, SI, NONE); +MSCC_P(29, TWI, SI, NONE); +MSCC_P(30, SIO2, SI, NONE); +MSCC_P(31, SIO2, SI, NONE); +MSCC_P(32, SIO2, SI, NONE); +MSCC_P(33, SIO2, SI, NONE); +MSCC_P(34, NONE, TWI_SCL_M, NONE); +MSCC_P(35, NONE, TWI_SCL_M, NONE); +MSCC_P(36, NONE, TWI_SCL_M, NONE); +MSCC_P(37, NONE, TWI_SCL_M, NONE); +MSCC_P(38, NONE, TWI_SCL_M, NONE); +MSCC_P(39, NONE, TWI_SCL_M, NONE); +MSCC_P(40, NONE, TWI_SCL_M, NONE); +MSCC_P(41, NONE, TWI_SCL_M, NONE); +MSCC_P(42, NONE, TWI_SCL_M, NONE); +MSCC_P(43, NONE, TWI_SCL_M, NONE); +MSCC_P(44, NONE, SFP8, NONE); +MSCC_P(45, NONE, SFP9, NONE); +MSCC_P(46, NONE, SFP10, NONE); +MSCC_P(47, NONE, SFP11, NONE); +MSCC_P(48, SFP0, NONE, NONE); +MSCC_P(49, SFP1, SI, NONE); +MSCC_P(50, SFP2, SI, NONE); +MSCC_P(51, SFP3, SI, NONE); +MSCC_P(52, SFP4, NONE, NONE); +MSCC_P(53, SFP5, NONE, NONE); +MSCC_P(54, SFP6, NONE, NONE); +MSCC_P(55, SFP7, NONE, NONE); +MSCC_P(56, MIIM1, SFP12, NONE); +MSCC_P(57, MIIM1, SFP13, NONE); +MSCC_P(58, MIIM2, SFP14, NONE); +MSCC_P(59, MIIM2, SFP15, NONE); +MSCC_P(60, NONE, NONE, NONE); +MSCC_P(61, NONE, NONE, NONE); +MSCC_P(62, NONE, NONE, NONE); +MSCC_P(63, NONE, NONE, NONE);
+#define JR2_PIN(n) { \
- .name = "GPIO_"#n, \
- .drv_data = &mscc_pin_##n \
+}
+const struct mscc_pin_data jr2_pins[] = {
- JR2_PIN(0),
- JR2_PIN(1),
- JR2_PIN(2),
- JR2_PIN(3),
- JR2_PIN(4),
- JR2_PIN(5),
- JR2_PIN(6),
- JR2_PIN(7),
- JR2_PIN(8),
- JR2_PIN(9),
- JR2_PIN(10),
- JR2_PIN(11),
- JR2_PIN(12),
- JR2_PIN(13),
- JR2_PIN(14),
- JR2_PIN(15),
- JR2_PIN(16),
- JR2_PIN(17),
- JR2_PIN(18),
- JR2_PIN(19),
- JR2_PIN(20),
- JR2_PIN(21),
- JR2_PIN(22),
- JR2_PIN(23),
- JR2_PIN(24),
- JR2_PIN(25),
- JR2_PIN(26),
- JR2_PIN(27),
- JR2_PIN(28),
- JR2_PIN(29),
- JR2_PIN(30),
- JR2_PIN(31),
- JR2_PIN(32),
- JR2_PIN(33),
- JR2_PIN(34),
- JR2_PIN(35),
- JR2_PIN(36),
- JR2_PIN(37),
- JR2_PIN(38),
- JR2_PIN(39),
- JR2_PIN(40),
- JR2_PIN(41),
- JR2_PIN(42),
- JR2_PIN(43),
- JR2_PIN(44),
- JR2_PIN(45),
- JR2_PIN(46),
- JR2_PIN(47),
- JR2_PIN(48),
- JR2_PIN(49),
- JR2_PIN(50),
- JR2_PIN(51),
- JR2_PIN(52),
- JR2_PIN(53),
- JR2_PIN(54),
- JR2_PIN(55),
- JR2_PIN(56),
- JR2_PIN(57),
- JR2_PIN(58),
- JR2_PIN(59),
- JR2_PIN(60),
- JR2_PIN(61),
- JR2_PIN(62),
- JR2_PIN(63),
+};
+int mscc_pinmux_set_mux(struct udevice *dev,
unsigned int pin_selector, unsigned int selector)
+{
- struct mscc_pinctrl *info = dev_get_priv(dev);
- struct mscc_pin_caps *pin = info->mscc_pins[pin_selector].drv_data;
- int f, offset, regoff;
- f = mscc_pin_function_idx(pin_selector, selector, info->mscc_pins);
- if (f < 0)
return -EINVAL;
- /*
* f is encoded on two bits.
* bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of
* ALT1
* This is racy because both registers can't be updated at the same time
* but it doesn't matter much for now.
*/
- offset = pin->pin;
- regoff = MSCC_GPIO_ALT0;
- if (offset >= 32) {
offset = offset % 32;
regoff = MSCC_GPIO_ALT1;
- }
- if (f & BIT(0))
mscc_setbits(offset, info->regs + regoff);
- else
mscc_clrbits(offset, info->regs + regoff);
- if (f & BIT(1))
mscc_setbits(offset, info->regs + regoff + 4);
- else
mscc_clrbits(offset, info->regs + regoff + 4);
- return 0;
+}
+static int jr2_gpio_probe(struct udevice *dev) +{
- struct gpio_dev_priv *uc_priv;
- uc_priv = dev_get_uclass_priv(dev);
- uc_priv->bank_name = "jr2-gpio";
- uc_priv->gpio_count = ARRAY_SIZE(jr2_pins);
- return 0;
+}
+static struct driver jr2_gpio_driver = {
- .name = "jr2-gpio",
- .id = UCLASS_GPIO,
- .probe = jr2_gpio_probe,
- .ops = &mscc_gpio_ops,
+};
+int jr2_pinctrl_probe(struct udevice *dev) +{
- int ret;
- ret = mscc_pinctrl_probe(dev, FUNC_MAX, jr2_pins,
ARRAY_SIZE(jr2_pins),
jr2_function_names);
- if (ret)
return ret;
- ret = device_bind(dev, &jr2_gpio_driver, "jr2-gpio", NULL,
dev_of_offset(dev), NULL);
- if (ret)
return ret;
- return 0;
+}
+static const struct udevice_id jr2_pinctrl_of_match[] = {
- { .compatible = "mscc,jr2-pinctrl" },
- {},
+};
+U_BOOT_DRIVER(jr2_pinctrl) = {
- .name = "jr2-pinctrl",
- .id = UCLASS_PINCTRL,
- .of_match = of_match_ptr(jr2_pinctrl_of_match),
- .probe = jr2_pinctrl_probe,
- .priv_auto_alloc_size = sizeof(struct mscc_pinctrl),
- .ops = &mscc_pinctrl_ops,
+};

Hi Daniel,
The 01/07/2019 20:38, Daniel Schwierzeck wrote:
Am 07.01.19 um 14:02 schrieb Horatiu Vultur:
The Jaguar2 SOC family has 63 gpio pins therefore I extended mscc-common to support new numbe of pins.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com
MAINTAINERS | 1 + drivers/pinctrl/mscc/Kconfig | 9 + drivers/pinctrl/mscc/Makefile | 1 + drivers/pinctrl/mscc/mscc-common.c | 97 ++++++++--- drivers/pinctrl/mscc/mscc-common.h | 5 + drivers/pinctrl/mscc/pinctrl-jr2.c | 342 +++++++++++++++++++++++++++++++++++++ 6 files changed, 433 insertions(+), 22 deletions(-) create mode 100644 drivers/pinctrl/mscc/pinctrl-jr2.c
diff --git a/MAINTAINERS b/MAINTAINERS index 494962e..495d3e5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -525,6 +525,7 @@ F: board/mscc/ F: configs/mscc* F: drivers/gpio/mscc_sgpio.c F: include/configs/vcoreiii.h +F: drivers/pinctrl/mscc/
MIPS JZ4780 M: Ezequiel Garcia ezequiel@collabora.com diff --git a/drivers/pinctrl/mscc/Kconfig b/drivers/pinctrl/mscc/Kconfig index cfc6c06..d07ea1b 100644 --- a/drivers/pinctrl/mscc/Kconfig +++ b/drivers/pinctrl/mscc/Kconfig @@ -20,3 +20,12 @@ config PINCTRL_MSCC_LUTON help Support pin multiplexing and pin configuration control on Microsemi luton SoCs.
+config PINCTRL_MSCC_JR2
- depends on SOC_JR2 && PINCTRL_FULL && OF_CONTROL
- select PINCTRL_MSCC
- default y
- bool "Microsemi jr2 family pin control driver"
- help
Support pin multiplexing and pin configuration control on
Microsemi jr2 SoCs.
diff --git a/drivers/pinctrl/mscc/Makefile b/drivers/pinctrl/mscc/Makefile index 6910671..8038d54 100644 --- a/drivers/pinctrl/mscc/Makefile +++ b/drivers/pinctrl/mscc/Makefile @@ -3,3 +3,4 @@ obj-y += mscc-common.o obj-$(CONFIG_PINCTRL_MSCC_OCELOT) += pinctrl-ocelot.o obj-$(CONFIG_PINCTRL_MSCC_LUTON) += pinctrl-luton.o +obj-$(CONFIG_PINCTRL_MSCC_JR2) += pinctrl-jr2.o diff --git a/drivers/pinctrl/mscc/mscc-common.c b/drivers/pinctrl/mscc/mscc-common.c index d74b8a6..7743565 100644 --- a/drivers/pinctrl/mscc/mscc-common.c +++ b/drivers/pinctrl/mscc/mscc-common.c @@ -22,6 +22,18 @@ #include <linux/io.h> #include "mscc-common.h"
+#if defined(CONFIG_SOC_JR2) +#define MSCC_GPIO_OUT_SET 0x00 +#define MSCC_GPIO_OUT_CLR 0x08 +#define MSCC_GPIO_OUT 0x10 +#define MSCC_GPIO_IN 0x18 +#define MSCC_GPIO_OE 0x20 +#define MSCC_GPIO_INTR 0x28 +#define MSCC_GPIO_INTR_ENA 0x30 +#define MSCC_GPIO_INTR_IDENT 0x38 +#define MSCC_GPIO_ALT0 0x40 +#define MSCC_GPIO_ALT1 0x48 +#else
you should also move this to pinctrl-jr2.c
If I will move also this in pinctrl-jr2 then I will need to mark many functions as weak and implement them in pinctrl-jr2. And thier implementation will be the same. Another reason why not to move them in pinctr-jr2 is that soon we want to add support for another target which has same features as JR2.
Maybe another solution is to extend the function mscc_pinctrl_probe to receive also an array with the offset of MSCC_GPIO_*. And then each specific pinctrl will need to pass this array, similar with mscc_pins. In this way the mscc-common will not contain any specific code to any of the targets.
#define MSCC_GPIO_OUT_SET 0x0 #define MSCC_GPIO_OUT_CLR 0x4 #define MSCC_GPIO_OUT 0x8 @@ -32,6 +44,39 @@ #define MSCC_GPIO_INTR_IDENT 0x1c #define MSCC_GPIO_ALT0 0x20 #define MSCC_GPIO_ALT1 0x24 +#endif
+static void mscc_writel(unsigned int offset, void *addr) +{
- if (offset < 32)
writel(BIT(offset), addr);
- else
writel(BIT(offset % 32), addr + 4);
+}
+static unsigned int mscc_readl(unsigned int offset, void *addr) +{
- if (offset < 32)
return readl(addr);
- else
return readl(addr + 4);
+}
+void mscc_setbits(unsigned int offset, void *addr) +{
- if (offset < 32)
writel(readl(addr) | BIT(offset), addr);
- else
writel(readl(addr + 4) | BIT(offset % 32), addr + 4);
+}
+void mscc_clrbits(unsigned int offset, void *addr) +{
- if (offset < 32)
writel(readl(addr) & ~BIT(offset), addr);
- else
writel(readl(addr + 4) & ~BIT(offset % 32), addr + 4);
+}
static int mscc_get_functions_count(struct udevice *dev) { @@ -48,8 +93,8 @@ static const char *mscc_get_function_name(struct udevice *dev, return info->function_names[function]; }
-static int mscc_pin_function_idx(unsigned int pin, unsigned int function,
const struct mscc_pin_data *mscc_pins)
+int mscc_pin_function_idx(unsigned int pin, unsigned int function,
const struct mscc_pin_data *mscc_pins)
{ struct mscc_pin_caps *p = mscc_pins[pin].drv_data; int i; @@ -62,7 +107,7 @@ static int mscc_pin_function_idx(unsigned int pin, unsigned int function, return -1; }
-static int mscc_pinmux_set_mux(struct udevice *dev, +__weak int mscc_pinmux_set_mux(struct udevice *dev, unsigned int pin_selector, unsigned int selector) { struct mscc_pinctrl *info = dev_get_priv(dev); @@ -79,15 +124,16 @@ static int mscc_pinmux_set_mux(struct udevice *dev, * This is racy because both registers can't be updated at the same time * but it doesn't matter much for now. */
- if (f & BIT(0))
setbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin));
elsemscc_setbits(pin->pin, info->regs + MSCC_GPIO_ALT0);
clrbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin));
mscc_clrbits(pin->pin, info->regs + MSCC_GPIO_ALT0);
if (f & BIT(1))
setbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1));
elsemscc_setbits(pin->pin, info->regs + MSCC_GPIO_ALT1 + 4);
clrbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1));
mscc_clrbits(pin->pin, info->regs + MSCC_GPIO_ALT1 + 4);
return 0;
} @@ -120,8 +166,8 @@ static int mscc_create_group_func_map(struct udevice *dev, }
info->func[f].ngroups = npins;
info->func[f].groups = devm_kzalloc(dev, npins *
sizeof(char *), GFP_KERNEL);
info->func[f].groups = devm_kzalloc(dev, npins * sizeof(char *),
if (!info->func[f].groups) return -ENOMEM;GFP_KERNEL);
@@ -132,7 +178,8 @@ static int mscc_create_group_func_map(struct udevice *dev, return 0; }
-static int mscc_pinctrl_register(struct udevice *dev, struct mscc_pinctrl *info) +static int mscc_pinctrl_register(struct udevice *dev,
struct mscc_pinctrl *info)
{ int ret;
@@ -150,38 +197,44 @@ static int mscc_gpio_get(struct udevice *dev, unsigned int offset) struct mscc_pinctrl *info = dev_get_priv(dev->parent); unsigned int val;
- val = readl(info->regs + MSCC_GPIO_IN);
- if (mscc_readl(offset, info->regs + MSCC_GPIO_OE) & BIT(offset % 32))
val = mscc_readl(offset, info->regs + MSCC_GPIO_OUT);
- else
val = mscc_readl(offset, info->regs + MSCC_GPIO_IN);
- return !!(val & BIT(offset));
- return !!(val & BIT(offset % 32));
}
-static int mscc_gpio_set(struct udevice *dev, unsigned int offset, int value) +static int mscc_gpio_set(struct udevice *dev, unsigned int offset,
int value)
{ struct mscc_pinctrl *info = dev_get_priv(dev->parent);
if (value)
writel(BIT(offset), info->regs + MSCC_GPIO_OUT_SET);
elsemscc_writel(offset, info->regs + MSCC_GPIO_OUT_SET);
writel(BIT(offset), info->regs + MSCC_GPIO_OUT_CLR);
mscc_writel(offset, info->regs + MSCC_GPIO_OUT_CLR);
return 0;
}
-static int mscc_gpio_get_direction(struct udevice *dev, unsigned int offset) +static int mscc_gpio_get_direction(struct udevice *dev,
unsigned int offset)
{ struct mscc_pinctrl *info = dev_get_priv(dev->parent); unsigned int val;
- val = readl(info->regs + MSCC_GPIO_OE);
- val = mscc_readl(offset, info->regs + MSCC_GPIO_OE);
- return (val & BIT(offset)) ? GPIOF_OUTPUT : GPIOF_INPUT;
- return (val & BIT(offset % 32)) ? GPIOF_OUTPUT : GPIOF_INPUT;
}
-static int mscc_gpio_direction_input(struct udevice *dev, unsigned int offset) +static int mscc_gpio_direction_input(struct udevice *dev,
unsigned int offset)
{ struct mscc_pinctrl *info = dev_get_priv(dev->parent);
- clrbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset));
mscc_clrbits(offset, info->regs + MSCC_GPIO_OE);
return 0;
} @@ -191,7 +244,7 @@ static int mscc_gpio_direction_output(struct udevice *dev, { struct mscc_pinctrl *info = dev_get_priv(dev->parent);
- setbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset));
mscc_setbits(offset, info->regs + MSCC_GPIO_OE);
return mscc_gpio_set(dev, offset, value);
} @@ -215,7 +268,7 @@ const struct pinctrl_ops mscc_pinctrl_ops = {
int mscc_pinctrl_probe(struct udevice *dev, int num_func, const struct mscc_pin_data *mscc_pins, int num_pins,
char *const *function_names)
char * const*function_names)
missing space: char * const *function_names
{ struct mscc_pinctrl *priv = dev_get_priv(dev); int ret; diff --git a/drivers/pinctrl/mscc/mscc-common.h b/drivers/pinctrl/mscc/mscc-common.h index b0001db..1b986a9 100644 --- a/drivers/pinctrl/mscc/mscc-common.h +++ b/drivers/pinctrl/mscc/mscc-common.h @@ -43,6 +43,11 @@ struct mscc_pinctrl { char * const *function_names; };
+void mscc_setbits(unsigned int offset, void *addr); +void mscc_clrbits(unsigned int offset, void *addr); +int mscc_pin_function_idx(unsigned int pin, unsigned int function,
const struct mscc_pin_data *mscc_pins);
int mscc_pinctrl_probe(struct udevice *dev, int num_func, const struct mscc_pin_data *mscc_pins, int num_pins, char * const *function_names); diff --git a/drivers/pinctrl/mscc/pinctrl-jr2.c b/drivers/pinctrl/mscc/pinctrl-jr2.c new file mode 100644 index 0000000..5c28693 --- /dev/null +++ b/drivers/pinctrl/mscc/pinctrl-jr2.c @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/*
- Microsemi SoCs pinctrl driver
- Author: horatiu.vultur@microchip.com
- License: Dual MIT/GPL
license is redundant due to SPDX
- Copyright (c) 2018 Microsemi Corporation
- */
+#include <common.h> +#include <config.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dm/pinctrl.h> +#include <dm/root.h> +#include <errno.h> +#include <fdtdec.h> +#include <linux/io.h> +#include <asm/gpio.h> +#include <asm/system.h> +#include "mscc-common.h"
+#define MSCC_GPIO_ALT0 0x40 +#define MSCC_GPIO_ALT1 0x48
+enum {
- FUNC_NONE,
- FUNC_GPIO,
- FUNC_IRQ0_IN,
- FUNC_IRQ0_OUT,
- FUNC_IRQ1_IN,
- FUNC_IRQ1_OUT,
- FUNC_MIIM1,
- FUNC_MIIM2,
- FUNC_PCI_WAKE,
- FUNC_PTP0,
- FUNC_PTP1,
- FUNC_PTP2,
- FUNC_PTP3,
- FUNC_PWM,
- FUNC_RECO_CLK0,
- FUNC_RECO_CLK1,
- FUNC_SFP0,
- FUNC_SFP1,
- FUNC_SFP2,
- FUNC_SFP3,
- FUNC_SFP4,
- FUNC_SFP5,
- FUNC_SFP6,
- FUNC_SFP7,
- FUNC_SFP8,
- FUNC_SFP9,
- FUNC_SFP10,
- FUNC_SFP11,
- FUNC_SFP12,
- FUNC_SFP13,
- FUNC_SFP14,
- FUNC_SFP15,
- FUNC_SIO,
- FUNC_SIO1,
- FUNC_SIO2,
- FUNC_SI,
- FUNC_TACHO,
- FUNC_TWI,
- FUNC_TWI2,
- FUNC_TWI_SCL_M,
- FUNC_UART,
- FUNC_UART2,
- FUNC_MAX
+};
+char *jr2_function_names[] = {
- [FUNC_NONE] = "none",
- [FUNC_GPIO] = "gpio",
- [FUNC_IRQ0_IN] = "irq0_in",
- [FUNC_IRQ0_OUT] = "irq0_out",
- [FUNC_IRQ1_IN] = "irq1_in",
- [FUNC_IRQ1_OUT] = "irq1_out",
- [FUNC_MIIM1] = "miim1",
- [FUNC_MIIM2] = "miim2",
- [FUNC_PCI_WAKE] = "pci_wake",
- [FUNC_PTP0] = "ptp0",
- [FUNC_PTP1] = "ptp1",
- [FUNC_PTP2] = "ptp2",
- [FUNC_PTP3] = "ptp3",
- [FUNC_PWM] = "pwm",
- [FUNC_RECO_CLK0] = "reco_clk0",
- [FUNC_RECO_CLK1] = "reco_clk1",
- [FUNC_SFP0] = "sfp0",
- [FUNC_SFP1] = "sfp1",
- [FUNC_SFP2] = "sfp2",
- [FUNC_SFP3] = "sfp3",
- [FUNC_SFP4] = "sfp4",
- [FUNC_SFP5] = "sfp5",
- [FUNC_SFP6] = "sfp6",
- [FUNC_SFP7] = "sfp7",
- [FUNC_SFP8] = "sfp8",
- [FUNC_SFP9] = "sfp9",
- [FUNC_SFP10] = "sfp10",
- [FUNC_SFP11] = "sfp11",
- [FUNC_SFP12] = "sfp12",
- [FUNC_SFP13] = "sfp13",
- [FUNC_SFP14] = "sfp14",
- [FUNC_SFP15] = "sfp15",
- [FUNC_SIO] = "sio",
- [FUNC_SIO1] = "sio1",
- [FUNC_SIO2] = "sio2",
- [FUNC_SI] = "si",
- [FUNC_TACHO] = "tacho",
- [FUNC_TWI] = "twi",
- [FUNC_TWI2] = "twi2",
- [FUNC_TWI_SCL_M] = "twi_scl_m",
- [FUNC_UART] = "uart",
- [FUNC_UART2] = "uart2",
+};
+MSCC_P(0, SIO, NONE, NONE); +MSCC_P(1, SIO, NONE, NONE); +MSCC_P(2, SIO, NONE, NONE); +MSCC_P(3, SIO, NONE, NONE); +MSCC_P(4, SIO1, NONE, NONE); +MSCC_P(5, SIO1, NONE, NONE); +MSCC_P(6, IRQ0_IN, IRQ0_OUT, NONE); +MSCC_P(7, IRQ1_IN, IRQ1_OUT, NONE); +MSCC_P(8, PTP0, NONE, NONE); +MSCC_P(9, PTP1, NONE, NONE); +MSCC_P(10, UART, NONE, NONE); +MSCC_P(11, UART, NONE, NONE); +MSCC_P(12, SIO1, NONE, NONE); +MSCC_P(13, SIO1, NONE, NONE); +MSCC_P(14, TWI, TWI_SCL_M, NONE); +MSCC_P(15, TWI, NONE, NONE); +MSCC_P(16, SI, TWI_SCL_M, NONE); +MSCC_P(17, SI, TWI_SCL_M, NONE); +MSCC_P(18, SI, TWI_SCL_M, NONE); +MSCC_P(19, PCI_WAKE, NONE, NONE); +MSCC_P(20, IRQ0_OUT, TWI_SCL_M, NONE); +MSCC_P(21, IRQ1_OUT, TWI_SCL_M, NONE); +MSCC_P(22, TACHO, NONE, NONE); +MSCC_P(23, PWM, NONE, NONE); +MSCC_P(24, UART2, NONE, NONE); +MSCC_P(25, UART2, SI, NONE); +MSCC_P(26, PTP2, SI, NONE); +MSCC_P(27, PTP3, SI, NONE); +MSCC_P(28, TWI2, SI, NONE); +MSCC_P(29, TWI, SI, NONE); +MSCC_P(30, SIO2, SI, NONE); +MSCC_P(31, SIO2, SI, NONE); +MSCC_P(32, SIO2, SI, NONE); +MSCC_P(33, SIO2, SI, NONE); +MSCC_P(34, NONE, TWI_SCL_M, NONE); +MSCC_P(35, NONE, TWI_SCL_M, NONE); +MSCC_P(36, NONE, TWI_SCL_M, NONE); +MSCC_P(37, NONE, TWI_SCL_M, NONE); +MSCC_P(38, NONE, TWI_SCL_M, NONE); +MSCC_P(39, NONE, TWI_SCL_M, NONE); +MSCC_P(40, NONE, TWI_SCL_M, NONE); +MSCC_P(41, NONE, TWI_SCL_M, NONE); +MSCC_P(42, NONE, TWI_SCL_M, NONE); +MSCC_P(43, NONE, TWI_SCL_M, NONE); +MSCC_P(44, NONE, SFP8, NONE); +MSCC_P(45, NONE, SFP9, NONE); +MSCC_P(46, NONE, SFP10, NONE); +MSCC_P(47, NONE, SFP11, NONE); +MSCC_P(48, SFP0, NONE, NONE); +MSCC_P(49, SFP1, SI, NONE); +MSCC_P(50, SFP2, SI, NONE); +MSCC_P(51, SFP3, SI, NONE); +MSCC_P(52, SFP4, NONE, NONE); +MSCC_P(53, SFP5, NONE, NONE); +MSCC_P(54, SFP6, NONE, NONE); +MSCC_P(55, SFP7, NONE, NONE); +MSCC_P(56, MIIM1, SFP12, NONE); +MSCC_P(57, MIIM1, SFP13, NONE); +MSCC_P(58, MIIM2, SFP14, NONE); +MSCC_P(59, MIIM2, SFP15, NONE); +MSCC_P(60, NONE, NONE, NONE); +MSCC_P(61, NONE, NONE, NONE); +MSCC_P(62, NONE, NONE, NONE); +MSCC_P(63, NONE, NONE, NONE);
+#define JR2_PIN(n) { \
- .name = "GPIO_"#n, \
- .drv_data = &mscc_pin_##n \
+}
+const struct mscc_pin_data jr2_pins[] = {
- JR2_PIN(0),
- JR2_PIN(1),
- JR2_PIN(2),
- JR2_PIN(3),
- JR2_PIN(4),
- JR2_PIN(5),
- JR2_PIN(6),
- JR2_PIN(7),
- JR2_PIN(8),
- JR2_PIN(9),
- JR2_PIN(10),
- JR2_PIN(11),
- JR2_PIN(12),
- JR2_PIN(13),
- JR2_PIN(14),
- JR2_PIN(15),
- JR2_PIN(16),
- JR2_PIN(17),
- JR2_PIN(18),
- JR2_PIN(19),
- JR2_PIN(20),
- JR2_PIN(21),
- JR2_PIN(22),
- JR2_PIN(23),
- JR2_PIN(24),
- JR2_PIN(25),
- JR2_PIN(26),
- JR2_PIN(27),
- JR2_PIN(28),
- JR2_PIN(29),
- JR2_PIN(30),
- JR2_PIN(31),
- JR2_PIN(32),
- JR2_PIN(33),
- JR2_PIN(34),
- JR2_PIN(35),
- JR2_PIN(36),
- JR2_PIN(37),
- JR2_PIN(38),
- JR2_PIN(39),
- JR2_PIN(40),
- JR2_PIN(41),
- JR2_PIN(42),
- JR2_PIN(43),
- JR2_PIN(44),
- JR2_PIN(45),
- JR2_PIN(46),
- JR2_PIN(47),
- JR2_PIN(48),
- JR2_PIN(49),
- JR2_PIN(50),
- JR2_PIN(51),
- JR2_PIN(52),
- JR2_PIN(53),
- JR2_PIN(54),
- JR2_PIN(55),
- JR2_PIN(56),
- JR2_PIN(57),
- JR2_PIN(58),
- JR2_PIN(59),
- JR2_PIN(60),
- JR2_PIN(61),
- JR2_PIN(62),
- JR2_PIN(63),
+};
+int mscc_pinmux_set_mux(struct udevice *dev,
unsigned int pin_selector, unsigned int selector)
+{
- struct mscc_pinctrl *info = dev_get_priv(dev);
- struct mscc_pin_caps *pin = info->mscc_pins[pin_selector].drv_data;
- int f, offset, regoff;
- f = mscc_pin_function_idx(pin_selector, selector, info->mscc_pins);
- if (f < 0)
return -EINVAL;
- /*
* f is encoded on two bits.
* bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of
* ALT1
* This is racy because both registers can't be updated at the same time
* but it doesn't matter much for now.
*/
- offset = pin->pin;
- regoff = MSCC_GPIO_ALT0;
- if (offset >= 32) {
offset = offset % 32;
regoff = MSCC_GPIO_ALT1;
- }
- if (f & BIT(0))
mscc_setbits(offset, info->regs + regoff);
- else
mscc_clrbits(offset, info->regs + regoff);
- if (f & BIT(1))
mscc_setbits(offset, info->regs + regoff + 4);
- else
mscc_clrbits(offset, info->regs + regoff + 4);
- return 0;
+}
+static int jr2_gpio_probe(struct udevice *dev) +{
- struct gpio_dev_priv *uc_priv;
- uc_priv = dev_get_uclass_priv(dev);
- uc_priv->bank_name = "jr2-gpio";
- uc_priv->gpio_count = ARRAY_SIZE(jr2_pins);
- return 0;
+}
+static struct driver jr2_gpio_driver = {
- .name = "jr2-gpio",
- .id = UCLASS_GPIO,
- .probe = jr2_gpio_probe,
- .ops = &mscc_gpio_ops,
+};
+int jr2_pinctrl_probe(struct udevice *dev) +{
- int ret;
- ret = mscc_pinctrl_probe(dev, FUNC_MAX, jr2_pins,
ARRAY_SIZE(jr2_pins),
jr2_function_names);
- if (ret)
return ret;
- ret = device_bind(dev, &jr2_gpio_driver, "jr2-gpio", NULL,
dev_of_offset(dev), NULL);
- if (ret)
return ret;
- return 0;
+}
+static const struct udevice_id jr2_pinctrl_of_match[] = {
- { .compatible = "mscc,jr2-pinctrl" },
- {},
+};
+U_BOOT_DRIVER(jr2_pinctrl) = {
- .name = "jr2-pinctrl",
- .id = UCLASS_PINCTRL,
- .of_match = of_match_ptr(jr2_pinctrl_of_match),
- .probe = jr2_pinctrl_probe,
- .priv_auto_alloc_size = sizeof(struct mscc_pinctrl),
- .ops = &mscc_pinctrl_ops,
+};
--
- Daniel

Am 08.01.19 um 09:00 schrieb Horatiu Vultur:
Hi Daniel,
The 01/07/2019 20:38, Daniel Schwierzeck wrote:
Am 07.01.19 um 14:02 schrieb Horatiu Vultur:
The Jaguar2 SOC family has 63 gpio pins therefore I extended mscc-common to support new numbe of pins.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com
MAINTAINERS | 1 + drivers/pinctrl/mscc/Kconfig | 9 + drivers/pinctrl/mscc/Makefile | 1 + drivers/pinctrl/mscc/mscc-common.c | 97 ++++++++--- drivers/pinctrl/mscc/mscc-common.h | 5 + drivers/pinctrl/mscc/pinctrl-jr2.c | 342 +++++++++++++++++++++++++++++++++++++ 6 files changed, 433 insertions(+), 22 deletions(-) create mode 100644 drivers/pinctrl/mscc/pinctrl-jr2.c
diff --git a/MAINTAINERS b/MAINTAINERS index 494962e..495d3e5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -525,6 +525,7 @@ F: board/mscc/ F: configs/mscc* F: drivers/gpio/mscc_sgpio.c F: include/configs/vcoreiii.h +F: drivers/pinctrl/mscc/
MIPS JZ4780 M: Ezequiel Garcia ezequiel@collabora.com diff --git a/drivers/pinctrl/mscc/Kconfig b/drivers/pinctrl/mscc/Kconfig index cfc6c06..d07ea1b 100644 --- a/drivers/pinctrl/mscc/Kconfig +++ b/drivers/pinctrl/mscc/Kconfig @@ -20,3 +20,12 @@ config PINCTRL_MSCC_LUTON help Support pin multiplexing and pin configuration control on Microsemi luton SoCs.
+config PINCTRL_MSCC_JR2
- depends on SOC_JR2 && PINCTRL_FULL && OF_CONTROL
- select PINCTRL_MSCC
- default y
- bool "Microsemi jr2 family pin control driver"
- help
Support pin multiplexing and pin configuration control on
Microsemi jr2 SoCs.
diff --git a/drivers/pinctrl/mscc/Makefile b/drivers/pinctrl/mscc/Makefile index 6910671..8038d54 100644 --- a/drivers/pinctrl/mscc/Makefile +++ b/drivers/pinctrl/mscc/Makefile @@ -3,3 +3,4 @@ obj-y += mscc-common.o obj-$(CONFIG_PINCTRL_MSCC_OCELOT) += pinctrl-ocelot.o obj-$(CONFIG_PINCTRL_MSCC_LUTON) += pinctrl-luton.o +obj-$(CONFIG_PINCTRL_MSCC_JR2) += pinctrl-jr2.o diff --git a/drivers/pinctrl/mscc/mscc-common.c b/drivers/pinctrl/mscc/mscc-common.c index d74b8a6..7743565 100644 --- a/drivers/pinctrl/mscc/mscc-common.c +++ b/drivers/pinctrl/mscc/mscc-common.c @@ -22,6 +22,18 @@ #include <linux/io.h> #include "mscc-common.h"
+#if defined(CONFIG_SOC_JR2) +#define MSCC_GPIO_OUT_SET 0x00 +#define MSCC_GPIO_OUT_CLR 0x08 +#define MSCC_GPIO_OUT 0x10 +#define MSCC_GPIO_IN 0x18 +#define MSCC_GPIO_OE 0x20 +#define MSCC_GPIO_INTR 0x28 +#define MSCC_GPIO_INTR_ENA 0x30 +#define MSCC_GPIO_INTR_IDENT 0x38 +#define MSCC_GPIO_ALT0 0x40 +#define MSCC_GPIO_ALT1 0x48 +#else
you should also move this to pinctrl-jr2.c
If I will move also this in pinctrl-jr2 then I will need to mark many functions as weak and implement them in pinctrl-jr2. And thier implementation will be the same. Another reason why not to move them in pinctr-jr2 is that soon we want to add support for another target which has same features as JR2.
Maybe another solution is to extend the function mscc_pinctrl_probe to receive also an array with the offset of MSCC_GPIO_*. And then each specific pinctrl will need to pass this array, similar with mscc_pins. In this way the mscc-common will not contain any specific code to any of the targets.
yes, that's even better than __weak. This technique is also used in other drivers where register offset mappings are selected via DT compatible string. One example I know of is drivers/spi/bcm63xx_spi.c.
#define MSCC_GPIO_OUT_SET 0x0 #define MSCC_GPIO_OUT_CLR 0x4 #define MSCC_GPIO_OUT 0x8 @@ -32,6 +44,39 @@ #define MSCC_GPIO_INTR_IDENT 0x1c #define MSCC_GPIO_ALT0 0x20 #define MSCC_GPIO_ALT1 0x24 +#endif
+static void mscc_writel(unsigned int offset, void *addr) +{
- if (offset < 32)
writel(BIT(offset), addr);
- else
writel(BIT(offset % 32), addr + 4);
+}
+static unsigned int mscc_readl(unsigned int offset, void *addr) +{
- if (offset < 32)
return readl(addr);
- else
return readl(addr + 4);
+}
+void mscc_setbits(unsigned int offset, void *addr) +{
- if (offset < 32)
writel(readl(addr) | BIT(offset), addr);
- else
writel(readl(addr + 4) | BIT(offset % 32), addr + 4);
+}
+void mscc_clrbits(unsigned int offset, void *addr) +{
- if (offset < 32)
writel(readl(addr) & ~BIT(offset), addr);
- else
writel(readl(addr + 4) & ~BIT(offset % 32), addr + 4);
+}
static int mscc_get_functions_count(struct udevice *dev) { @@ -48,8 +93,8 @@ static const char *mscc_get_function_name(struct udevice *dev, return info->function_names[function]; }
-static int mscc_pin_function_idx(unsigned int pin, unsigned int function,
const struct mscc_pin_data *mscc_pins)
+int mscc_pin_function_idx(unsigned int pin, unsigned int function,
const struct mscc_pin_data *mscc_pins)
{ struct mscc_pin_caps *p = mscc_pins[pin].drv_data; int i; @@ -62,7 +107,7 @@ static int mscc_pin_function_idx(unsigned int pin, unsigned int function, return -1; }
-static int mscc_pinmux_set_mux(struct udevice *dev, +__weak int mscc_pinmux_set_mux(struct udevice *dev, unsigned int pin_selector, unsigned int selector) { struct mscc_pinctrl *info = dev_get_priv(dev); @@ -79,15 +124,16 @@ static int mscc_pinmux_set_mux(struct udevice *dev, * This is racy because both registers can't be updated at the same time * but it doesn't matter much for now. */
- if (f & BIT(0))
setbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin));
elsemscc_setbits(pin->pin, info->regs + MSCC_GPIO_ALT0);
clrbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin));
mscc_clrbits(pin->pin, info->regs + MSCC_GPIO_ALT0);
if (f & BIT(1))
setbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1));
elsemscc_setbits(pin->pin, info->regs + MSCC_GPIO_ALT1 + 4);
clrbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1));
mscc_clrbits(pin->pin, info->regs + MSCC_GPIO_ALT1 + 4);
return 0;
} @@ -120,8 +166,8 @@ static int mscc_create_group_func_map(struct udevice *dev, }
info->func[f].ngroups = npins;
info->func[f].groups = devm_kzalloc(dev, npins *
sizeof(char *), GFP_KERNEL);
info->func[f].groups = devm_kzalloc(dev, npins * sizeof(char *),
if (!info->func[f].groups) return -ENOMEM;GFP_KERNEL);
@@ -132,7 +178,8 @@ static int mscc_create_group_func_map(struct udevice *dev, return 0; }
-static int mscc_pinctrl_register(struct udevice *dev, struct mscc_pinctrl *info) +static int mscc_pinctrl_register(struct udevice *dev,
struct mscc_pinctrl *info)
{ int ret;
@@ -150,38 +197,44 @@ static int mscc_gpio_get(struct udevice *dev, unsigned int offset) struct mscc_pinctrl *info = dev_get_priv(dev->parent); unsigned int val;
- val = readl(info->regs + MSCC_GPIO_IN);
- if (mscc_readl(offset, info->regs + MSCC_GPIO_OE) & BIT(offset % 32))
val = mscc_readl(offset, info->regs + MSCC_GPIO_OUT);
- else
val = mscc_readl(offset, info->regs + MSCC_GPIO_IN);
- return !!(val & BIT(offset));
- return !!(val & BIT(offset % 32));
}
-static int mscc_gpio_set(struct udevice *dev, unsigned int offset, int value) +static int mscc_gpio_set(struct udevice *dev, unsigned int offset,
int value)
{ struct mscc_pinctrl *info = dev_get_priv(dev->parent);
if (value)
writel(BIT(offset), info->regs + MSCC_GPIO_OUT_SET);
elsemscc_writel(offset, info->regs + MSCC_GPIO_OUT_SET);
writel(BIT(offset), info->regs + MSCC_GPIO_OUT_CLR);
mscc_writel(offset, info->regs + MSCC_GPIO_OUT_CLR);
return 0;
}
-static int mscc_gpio_get_direction(struct udevice *dev, unsigned int offset) +static int mscc_gpio_get_direction(struct udevice *dev,
unsigned int offset)
{ struct mscc_pinctrl *info = dev_get_priv(dev->parent); unsigned int val;
- val = readl(info->regs + MSCC_GPIO_OE);
- val = mscc_readl(offset, info->regs + MSCC_GPIO_OE);
- return (val & BIT(offset)) ? GPIOF_OUTPUT : GPIOF_INPUT;
- return (val & BIT(offset % 32)) ? GPIOF_OUTPUT : GPIOF_INPUT;
}
-static int mscc_gpio_direction_input(struct udevice *dev, unsigned int offset) +static int mscc_gpio_direction_input(struct udevice *dev,
unsigned int offset)
{ struct mscc_pinctrl *info = dev_get_priv(dev->parent);
- clrbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset));
mscc_clrbits(offset, info->regs + MSCC_GPIO_OE);
return 0;
} @@ -191,7 +244,7 @@ static int mscc_gpio_direction_output(struct udevice *dev, { struct mscc_pinctrl *info = dev_get_priv(dev->parent);
- setbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset));
mscc_setbits(offset, info->regs + MSCC_GPIO_OE);
return mscc_gpio_set(dev, offset, value);
} @@ -215,7 +268,7 @@ const struct pinctrl_ops mscc_pinctrl_ops = {
int mscc_pinctrl_probe(struct udevice *dev, int num_func, const struct mscc_pin_data *mscc_pins, int num_pins,
char *const *function_names)
char * const*function_names)
missing space: char * const *function_names
{ struct mscc_pinctrl *priv = dev_get_priv(dev); int ret; diff --git a/drivers/pinctrl/mscc/mscc-common.h b/drivers/pinctrl/mscc/mscc-common.h index b0001db..1b986a9 100644 --- a/drivers/pinctrl/mscc/mscc-common.h +++ b/drivers/pinctrl/mscc/mscc-common.h @@ -43,6 +43,11 @@ struct mscc_pinctrl { char * const *function_names; };
+void mscc_setbits(unsigned int offset, void *addr); +void mscc_clrbits(unsigned int offset, void *addr); +int mscc_pin_function_idx(unsigned int pin, unsigned int function,
const struct mscc_pin_data *mscc_pins);
int mscc_pinctrl_probe(struct udevice *dev, int num_func, const struct mscc_pin_data *mscc_pins, int num_pins, char * const *function_names); diff --git a/drivers/pinctrl/mscc/pinctrl-jr2.c b/drivers/pinctrl/mscc/pinctrl-jr2.c new file mode 100644 index 0000000..5c28693 --- /dev/null +++ b/drivers/pinctrl/mscc/pinctrl-jr2.c @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/*
- Microsemi SoCs pinctrl driver
- Author: horatiu.vultur@microchip.com
- License: Dual MIT/GPL
license is redundant due to SPDX
- Copyright (c) 2018 Microsemi Corporation
- */
+#include <common.h> +#include <config.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dm/pinctrl.h> +#include <dm/root.h> +#include <errno.h> +#include <fdtdec.h> +#include <linux/io.h> +#include <asm/gpio.h> +#include <asm/system.h> +#include "mscc-common.h"
+#define MSCC_GPIO_ALT0 0x40 +#define MSCC_GPIO_ALT1 0x48
+enum {
- FUNC_NONE,
- FUNC_GPIO,
- FUNC_IRQ0_IN,
- FUNC_IRQ0_OUT,
- FUNC_IRQ1_IN,
- FUNC_IRQ1_OUT,
- FUNC_MIIM1,
- FUNC_MIIM2,
- FUNC_PCI_WAKE,
- FUNC_PTP0,
- FUNC_PTP1,
- FUNC_PTP2,
- FUNC_PTP3,
- FUNC_PWM,
- FUNC_RECO_CLK0,
- FUNC_RECO_CLK1,
- FUNC_SFP0,
- FUNC_SFP1,
- FUNC_SFP2,
- FUNC_SFP3,
- FUNC_SFP4,
- FUNC_SFP5,
- FUNC_SFP6,
- FUNC_SFP7,
- FUNC_SFP8,
- FUNC_SFP9,
- FUNC_SFP10,
- FUNC_SFP11,
- FUNC_SFP12,
- FUNC_SFP13,
- FUNC_SFP14,
- FUNC_SFP15,
- FUNC_SIO,
- FUNC_SIO1,
- FUNC_SIO2,
- FUNC_SI,
- FUNC_TACHO,
- FUNC_TWI,
- FUNC_TWI2,
- FUNC_TWI_SCL_M,
- FUNC_UART,
- FUNC_UART2,
- FUNC_MAX
+};
+char *jr2_function_names[] = {
- [FUNC_NONE] = "none",
- [FUNC_GPIO] = "gpio",
- [FUNC_IRQ0_IN] = "irq0_in",
- [FUNC_IRQ0_OUT] = "irq0_out",
- [FUNC_IRQ1_IN] = "irq1_in",
- [FUNC_IRQ1_OUT] = "irq1_out",
- [FUNC_MIIM1] = "miim1",
- [FUNC_MIIM2] = "miim2",
- [FUNC_PCI_WAKE] = "pci_wake",
- [FUNC_PTP0] = "ptp0",
- [FUNC_PTP1] = "ptp1",
- [FUNC_PTP2] = "ptp2",
- [FUNC_PTP3] = "ptp3",
- [FUNC_PWM] = "pwm",
- [FUNC_RECO_CLK0] = "reco_clk0",
- [FUNC_RECO_CLK1] = "reco_clk1",
- [FUNC_SFP0] = "sfp0",
- [FUNC_SFP1] = "sfp1",
- [FUNC_SFP2] = "sfp2",
- [FUNC_SFP3] = "sfp3",
- [FUNC_SFP4] = "sfp4",
- [FUNC_SFP5] = "sfp5",
- [FUNC_SFP6] = "sfp6",
- [FUNC_SFP7] = "sfp7",
- [FUNC_SFP8] = "sfp8",
- [FUNC_SFP9] = "sfp9",
- [FUNC_SFP10] = "sfp10",
- [FUNC_SFP11] = "sfp11",
- [FUNC_SFP12] = "sfp12",
- [FUNC_SFP13] = "sfp13",
- [FUNC_SFP14] = "sfp14",
- [FUNC_SFP15] = "sfp15",
- [FUNC_SIO] = "sio",
- [FUNC_SIO1] = "sio1",
- [FUNC_SIO2] = "sio2",
- [FUNC_SI] = "si",
- [FUNC_TACHO] = "tacho",
- [FUNC_TWI] = "twi",
- [FUNC_TWI2] = "twi2",
- [FUNC_TWI_SCL_M] = "twi_scl_m",
- [FUNC_UART] = "uart",
- [FUNC_UART2] = "uart2",
+};
+MSCC_P(0, SIO, NONE, NONE); +MSCC_P(1, SIO, NONE, NONE); +MSCC_P(2, SIO, NONE, NONE); +MSCC_P(3, SIO, NONE, NONE); +MSCC_P(4, SIO1, NONE, NONE); +MSCC_P(5, SIO1, NONE, NONE); +MSCC_P(6, IRQ0_IN, IRQ0_OUT, NONE); +MSCC_P(7, IRQ1_IN, IRQ1_OUT, NONE); +MSCC_P(8, PTP0, NONE, NONE); +MSCC_P(9, PTP1, NONE, NONE); +MSCC_P(10, UART, NONE, NONE); +MSCC_P(11, UART, NONE, NONE); +MSCC_P(12, SIO1, NONE, NONE); +MSCC_P(13, SIO1, NONE, NONE); +MSCC_P(14, TWI, TWI_SCL_M, NONE); +MSCC_P(15, TWI, NONE, NONE); +MSCC_P(16, SI, TWI_SCL_M, NONE); +MSCC_P(17, SI, TWI_SCL_M, NONE); +MSCC_P(18, SI, TWI_SCL_M, NONE); +MSCC_P(19, PCI_WAKE, NONE, NONE); +MSCC_P(20, IRQ0_OUT, TWI_SCL_M, NONE); +MSCC_P(21, IRQ1_OUT, TWI_SCL_M, NONE); +MSCC_P(22, TACHO, NONE, NONE); +MSCC_P(23, PWM, NONE, NONE); +MSCC_P(24, UART2, NONE, NONE); +MSCC_P(25, UART2, SI, NONE); +MSCC_P(26, PTP2, SI, NONE); +MSCC_P(27, PTP3, SI, NONE); +MSCC_P(28, TWI2, SI, NONE); +MSCC_P(29, TWI, SI, NONE); +MSCC_P(30, SIO2, SI, NONE); +MSCC_P(31, SIO2, SI, NONE); +MSCC_P(32, SIO2, SI, NONE); +MSCC_P(33, SIO2, SI, NONE); +MSCC_P(34, NONE, TWI_SCL_M, NONE); +MSCC_P(35, NONE, TWI_SCL_M, NONE); +MSCC_P(36, NONE, TWI_SCL_M, NONE); +MSCC_P(37, NONE, TWI_SCL_M, NONE); +MSCC_P(38, NONE, TWI_SCL_M, NONE); +MSCC_P(39, NONE, TWI_SCL_M, NONE); +MSCC_P(40, NONE, TWI_SCL_M, NONE); +MSCC_P(41, NONE, TWI_SCL_M, NONE); +MSCC_P(42, NONE, TWI_SCL_M, NONE); +MSCC_P(43, NONE, TWI_SCL_M, NONE); +MSCC_P(44, NONE, SFP8, NONE); +MSCC_P(45, NONE, SFP9, NONE); +MSCC_P(46, NONE, SFP10, NONE); +MSCC_P(47, NONE, SFP11, NONE); +MSCC_P(48, SFP0, NONE, NONE); +MSCC_P(49, SFP1, SI, NONE); +MSCC_P(50, SFP2, SI, NONE); +MSCC_P(51, SFP3, SI, NONE); +MSCC_P(52, SFP4, NONE, NONE); +MSCC_P(53, SFP5, NONE, NONE); +MSCC_P(54, SFP6, NONE, NONE); +MSCC_P(55, SFP7, NONE, NONE); +MSCC_P(56, MIIM1, SFP12, NONE); +MSCC_P(57, MIIM1, SFP13, NONE); +MSCC_P(58, MIIM2, SFP14, NONE); +MSCC_P(59, MIIM2, SFP15, NONE); +MSCC_P(60, NONE, NONE, NONE); +MSCC_P(61, NONE, NONE, NONE); +MSCC_P(62, NONE, NONE, NONE); +MSCC_P(63, NONE, NONE, NONE);
+#define JR2_PIN(n) { \
- .name = "GPIO_"#n, \
- .drv_data = &mscc_pin_##n \
+}
+const struct mscc_pin_data jr2_pins[] = {
- JR2_PIN(0),
- JR2_PIN(1),
- JR2_PIN(2),
- JR2_PIN(3),
- JR2_PIN(4),
- JR2_PIN(5),
- JR2_PIN(6),
- JR2_PIN(7),
- JR2_PIN(8),
- JR2_PIN(9),
- JR2_PIN(10),
- JR2_PIN(11),
- JR2_PIN(12),
- JR2_PIN(13),
- JR2_PIN(14),
- JR2_PIN(15),
- JR2_PIN(16),
- JR2_PIN(17),
- JR2_PIN(18),
- JR2_PIN(19),
- JR2_PIN(20),
- JR2_PIN(21),
- JR2_PIN(22),
- JR2_PIN(23),
- JR2_PIN(24),
- JR2_PIN(25),
- JR2_PIN(26),
- JR2_PIN(27),
- JR2_PIN(28),
- JR2_PIN(29),
- JR2_PIN(30),
- JR2_PIN(31),
- JR2_PIN(32),
- JR2_PIN(33),
- JR2_PIN(34),
- JR2_PIN(35),
- JR2_PIN(36),
- JR2_PIN(37),
- JR2_PIN(38),
- JR2_PIN(39),
- JR2_PIN(40),
- JR2_PIN(41),
- JR2_PIN(42),
- JR2_PIN(43),
- JR2_PIN(44),
- JR2_PIN(45),
- JR2_PIN(46),
- JR2_PIN(47),
- JR2_PIN(48),
- JR2_PIN(49),
- JR2_PIN(50),
- JR2_PIN(51),
- JR2_PIN(52),
- JR2_PIN(53),
- JR2_PIN(54),
- JR2_PIN(55),
- JR2_PIN(56),
- JR2_PIN(57),
- JR2_PIN(58),
- JR2_PIN(59),
- JR2_PIN(60),
- JR2_PIN(61),
- JR2_PIN(62),
- JR2_PIN(63),
+};
+int mscc_pinmux_set_mux(struct udevice *dev,
unsigned int pin_selector, unsigned int selector)
+{
- struct mscc_pinctrl *info = dev_get_priv(dev);
- struct mscc_pin_caps *pin = info->mscc_pins[pin_selector].drv_data;
- int f, offset, regoff;
- f = mscc_pin_function_idx(pin_selector, selector, info->mscc_pins);
- if (f < 0)
return -EINVAL;
- /*
* f is encoded on two bits.
* bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of
* ALT1
* This is racy because both registers can't be updated at the same time
* but it doesn't matter much for now.
*/
- offset = pin->pin;
- regoff = MSCC_GPIO_ALT0;
- if (offset >= 32) {
offset = offset % 32;
regoff = MSCC_GPIO_ALT1;
- }
- if (f & BIT(0))
mscc_setbits(offset, info->regs + regoff);
- else
mscc_clrbits(offset, info->regs + regoff);
- if (f & BIT(1))
mscc_setbits(offset, info->regs + regoff + 4);
- else
mscc_clrbits(offset, info->regs + regoff + 4);
- return 0;
+}
+static int jr2_gpio_probe(struct udevice *dev) +{
- struct gpio_dev_priv *uc_priv;
- uc_priv = dev_get_uclass_priv(dev);
- uc_priv->bank_name = "jr2-gpio";
- uc_priv->gpio_count = ARRAY_SIZE(jr2_pins);
- return 0;
+}
+static struct driver jr2_gpio_driver = {
- .name = "jr2-gpio",
- .id = UCLASS_GPIO,
- .probe = jr2_gpio_probe,
- .ops = &mscc_gpio_ops,
+};
+int jr2_pinctrl_probe(struct udevice *dev) +{
- int ret;
- ret = mscc_pinctrl_probe(dev, FUNC_MAX, jr2_pins,
ARRAY_SIZE(jr2_pins),
jr2_function_names);
- if (ret)
return ret;
- ret = device_bind(dev, &jr2_gpio_driver, "jr2-gpio", NULL,
dev_of_offset(dev), NULL);
- if (ret)
return ret;
- return 0;
+}
+static const struct udevice_id jr2_pinctrl_of_match[] = {
- { .compatible = "mscc,jr2-pinctrl" },
- {},
+};
+U_BOOT_DRIVER(jr2_pinctrl) = {
- .name = "jr2-pinctrl",
- .id = UCLASS_PINCTRL,
- .of_match = of_match_ptr(jr2_pinctrl_of_match),
- .probe = jr2_pinctrl_probe,
- .priv_auto_alloc_size = sizeof(struct mscc_pinctrl),
- .ops = &mscc_pinctrl_ops,
+};
--
- Daniel

Hi Daniel,
First, thank you for all the feedback.
I have created a new patch series that will fix the issue that you addressed bellow but the fix it would not use compatible string, because that presume that I need to change the other pinctrl-drivers(ocelot, luton). I was thinking if it is OK the way I have done in v3 and then create a new patch series specific for fixing pinctrl. Similar with the issue that I have for sysreset driver.
The 01/08/2019 17:12, Daniel Schwierzeck wrote:
Am 08.01.19 um 09:00 schrieb Horatiu Vultur:
Hi Daniel,
The 01/07/2019 20:38, Daniel Schwierzeck wrote:
Am 07.01.19 um 14:02 schrieb Horatiu Vultur:
The Jaguar2 SOC family has 63 gpio pins therefore I extended mscc-common to support new numbe of pins.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com
MAINTAINERS | 1 + drivers/pinctrl/mscc/Kconfig | 9 + drivers/pinctrl/mscc/Makefile | 1 + drivers/pinctrl/mscc/mscc-common.c | 97 ++++++++--- drivers/pinctrl/mscc/mscc-common.h | 5 + drivers/pinctrl/mscc/pinctrl-jr2.c | 342 +++++++++++++++++++++++++++++++++++++ 6 files changed, 433 insertions(+), 22 deletions(-) create mode 100644 drivers/pinctrl/mscc/pinctrl-jr2.c
diff --git a/MAINTAINERS b/MAINTAINERS index 494962e..495d3e5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -525,6 +525,7 @@ F: board/mscc/ F: configs/mscc* F: drivers/gpio/mscc_sgpio.c F: include/configs/vcoreiii.h +F: drivers/pinctrl/mscc/
MIPS JZ4780 M: Ezequiel Garcia ezequiel@collabora.com diff --git a/drivers/pinctrl/mscc/Kconfig b/drivers/pinctrl/mscc/Kconfig index cfc6c06..d07ea1b 100644 --- a/drivers/pinctrl/mscc/Kconfig +++ b/drivers/pinctrl/mscc/Kconfig @@ -20,3 +20,12 @@ config PINCTRL_MSCC_LUTON help Support pin multiplexing and pin configuration control on Microsemi luton SoCs.
+config PINCTRL_MSCC_JR2
- depends on SOC_JR2 && PINCTRL_FULL && OF_CONTROL
- select PINCTRL_MSCC
- default y
- bool "Microsemi jr2 family pin control driver"
- help
Support pin multiplexing and pin configuration control on
Microsemi jr2 SoCs.
diff --git a/drivers/pinctrl/mscc/Makefile b/drivers/pinctrl/mscc/Makefile index 6910671..8038d54 100644 --- a/drivers/pinctrl/mscc/Makefile +++ b/drivers/pinctrl/mscc/Makefile @@ -3,3 +3,4 @@ obj-y += mscc-common.o obj-$(CONFIG_PINCTRL_MSCC_OCELOT) += pinctrl-ocelot.o obj-$(CONFIG_PINCTRL_MSCC_LUTON) += pinctrl-luton.o +obj-$(CONFIG_PINCTRL_MSCC_JR2) += pinctrl-jr2.o diff --git a/drivers/pinctrl/mscc/mscc-common.c b/drivers/pinctrl/mscc/mscc-common.c index d74b8a6..7743565 100644 --- a/drivers/pinctrl/mscc/mscc-common.c +++ b/drivers/pinctrl/mscc/mscc-common.c @@ -22,6 +22,18 @@ #include <linux/io.h> #include "mscc-common.h"
+#if defined(CONFIG_SOC_JR2) +#define MSCC_GPIO_OUT_SET 0x00 +#define MSCC_GPIO_OUT_CLR 0x08 +#define MSCC_GPIO_OUT 0x10 +#define MSCC_GPIO_IN 0x18 +#define MSCC_GPIO_OE 0x20 +#define MSCC_GPIO_INTR 0x28 +#define MSCC_GPIO_INTR_ENA 0x30 +#define MSCC_GPIO_INTR_IDENT 0x38 +#define MSCC_GPIO_ALT0 0x40 +#define MSCC_GPIO_ALT1 0x48 +#else
you should also move this to pinctrl-jr2.c
If I will move also this in pinctrl-jr2 then I will need to mark many functions as weak and implement them in pinctrl-jr2. And thier implementation will be the same. Another reason why not to move them in pinctr-jr2 is that soon we want to add support for another target which has same features as JR2.
Maybe another solution is to extend the function mscc_pinctrl_probe to receive also an array with the offset of MSCC_GPIO_*. And then each specific pinctrl will need to pass this array, similar with mscc_pins. In this way the mscc-common will not contain any specific code to any of the targets.
yes, that's even better than __weak. This technique is also used in other drivers where register offset mappings are selected via DT compatible string. One example I know of is drivers/spi/bcm63xx_spi.c.
#define MSCC_GPIO_OUT_SET 0x0 #define MSCC_GPIO_OUT_CLR 0x4 #define MSCC_GPIO_OUT 0x8 @@ -32,6 +44,39 @@ #define MSCC_GPIO_INTR_IDENT 0x1c #define MSCC_GPIO_ALT0 0x20 #define MSCC_GPIO_ALT1 0x24 +#endif
+static void mscc_writel(unsigned int offset, void *addr) +{
- if (offset < 32)
writel(BIT(offset), addr);
- else
writel(BIT(offset % 32), addr + 4);
+}
+static unsigned int mscc_readl(unsigned int offset, void *addr) +{
- if (offset < 32)
return readl(addr);
- else
return readl(addr + 4);
+}
+void mscc_setbits(unsigned int offset, void *addr) +{
- if (offset < 32)
writel(readl(addr) | BIT(offset), addr);
- else
writel(readl(addr + 4) | BIT(offset % 32), addr + 4);
+}
+void mscc_clrbits(unsigned int offset, void *addr) +{
- if (offset < 32)
writel(readl(addr) & ~BIT(offset), addr);
- else
writel(readl(addr + 4) & ~BIT(offset % 32), addr + 4);
+}
static int mscc_get_functions_count(struct udevice *dev) { @@ -48,8 +93,8 @@ static const char *mscc_get_function_name(struct udevice *dev, return info->function_names[function]; }
-static int mscc_pin_function_idx(unsigned int pin, unsigned int function,
const struct mscc_pin_data *mscc_pins)
+int mscc_pin_function_idx(unsigned int pin, unsigned int function,
const struct mscc_pin_data *mscc_pins)
{ struct mscc_pin_caps *p = mscc_pins[pin].drv_data; int i; @@ -62,7 +107,7 @@ static int mscc_pin_function_idx(unsigned int pin, unsigned int function, return -1; }
-static int mscc_pinmux_set_mux(struct udevice *dev, +__weak int mscc_pinmux_set_mux(struct udevice *dev, unsigned int pin_selector, unsigned int selector) { struct mscc_pinctrl *info = dev_get_priv(dev); @@ -79,15 +124,16 @@ static int mscc_pinmux_set_mux(struct udevice *dev, * This is racy because both registers can't be updated at the same time * but it doesn't matter much for now. */
- if (f & BIT(0))
setbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin));
elsemscc_setbits(pin->pin, info->regs + MSCC_GPIO_ALT0);
clrbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin));
mscc_clrbits(pin->pin, info->regs + MSCC_GPIO_ALT0);
if (f & BIT(1))
setbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1));
elsemscc_setbits(pin->pin, info->regs + MSCC_GPIO_ALT1 + 4);
clrbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1));
mscc_clrbits(pin->pin, info->regs + MSCC_GPIO_ALT1 + 4);
return 0;
} @@ -120,8 +166,8 @@ static int mscc_create_group_func_map(struct udevice *dev, }
info->func[f].ngroups = npins;
info->func[f].groups = devm_kzalloc(dev, npins *
sizeof(char *), GFP_KERNEL);
info->func[f].groups = devm_kzalloc(dev, npins * sizeof(char *),
if (!info->func[f].groups) return -ENOMEM;GFP_KERNEL);
@@ -132,7 +178,8 @@ static int mscc_create_group_func_map(struct udevice *dev, return 0; }
-static int mscc_pinctrl_register(struct udevice *dev, struct mscc_pinctrl *info) +static int mscc_pinctrl_register(struct udevice *dev,
struct mscc_pinctrl *info)
{ int ret;
@@ -150,38 +197,44 @@ static int mscc_gpio_get(struct udevice *dev, unsigned int offset) struct mscc_pinctrl *info = dev_get_priv(dev->parent); unsigned int val;
- val = readl(info->regs + MSCC_GPIO_IN);
- if (mscc_readl(offset, info->regs + MSCC_GPIO_OE) & BIT(offset % 32))
val = mscc_readl(offset, info->regs + MSCC_GPIO_OUT);
- else
val = mscc_readl(offset, info->regs + MSCC_GPIO_IN);
- return !!(val & BIT(offset));
- return !!(val & BIT(offset % 32));
}
-static int mscc_gpio_set(struct udevice *dev, unsigned int offset, int value) +static int mscc_gpio_set(struct udevice *dev, unsigned int offset,
int value)
{ struct mscc_pinctrl *info = dev_get_priv(dev->parent);
if (value)
writel(BIT(offset), info->regs + MSCC_GPIO_OUT_SET);
elsemscc_writel(offset, info->regs + MSCC_GPIO_OUT_SET);
writel(BIT(offset), info->regs + MSCC_GPIO_OUT_CLR);
mscc_writel(offset, info->regs + MSCC_GPIO_OUT_CLR);
return 0;
}
-static int mscc_gpio_get_direction(struct udevice *dev, unsigned int offset) +static int mscc_gpio_get_direction(struct udevice *dev,
unsigned int offset)
{ struct mscc_pinctrl *info = dev_get_priv(dev->parent); unsigned int val;
- val = readl(info->regs + MSCC_GPIO_OE);
- val = mscc_readl(offset, info->regs + MSCC_GPIO_OE);
- return (val & BIT(offset)) ? GPIOF_OUTPUT : GPIOF_INPUT;
- return (val & BIT(offset % 32)) ? GPIOF_OUTPUT : GPIOF_INPUT;
}
-static int mscc_gpio_direction_input(struct udevice *dev, unsigned int offset) +static int mscc_gpio_direction_input(struct udevice *dev,
unsigned int offset)
{ struct mscc_pinctrl *info = dev_get_priv(dev->parent);
- clrbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset));
mscc_clrbits(offset, info->regs + MSCC_GPIO_OE);
return 0;
} @@ -191,7 +244,7 @@ static int mscc_gpio_direction_output(struct udevice *dev, { struct mscc_pinctrl *info = dev_get_priv(dev->parent);
- setbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset));
mscc_setbits(offset, info->regs + MSCC_GPIO_OE);
return mscc_gpio_set(dev, offset, value);
} @@ -215,7 +268,7 @@ const struct pinctrl_ops mscc_pinctrl_ops = {
int mscc_pinctrl_probe(struct udevice *dev, int num_func, const struct mscc_pin_data *mscc_pins, int num_pins,
char *const *function_names)
char * const*function_names)
missing space: char * const *function_names
{ struct mscc_pinctrl *priv = dev_get_priv(dev); int ret; diff --git a/drivers/pinctrl/mscc/mscc-common.h b/drivers/pinctrl/mscc/mscc-common.h index b0001db..1b986a9 100644 --- a/drivers/pinctrl/mscc/mscc-common.h +++ b/drivers/pinctrl/mscc/mscc-common.h @@ -43,6 +43,11 @@ struct mscc_pinctrl { char * const *function_names; };
+void mscc_setbits(unsigned int offset, void *addr); +void mscc_clrbits(unsigned int offset, void *addr); +int mscc_pin_function_idx(unsigned int pin, unsigned int function,
const struct mscc_pin_data *mscc_pins);
int mscc_pinctrl_probe(struct udevice *dev, int num_func, const struct mscc_pin_data *mscc_pins, int num_pins, char * const *function_names); diff --git a/drivers/pinctrl/mscc/pinctrl-jr2.c b/drivers/pinctrl/mscc/pinctrl-jr2.c new file mode 100644 index 0000000..5c28693 --- /dev/null +++ b/drivers/pinctrl/mscc/pinctrl-jr2.c @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/*
- Microsemi SoCs pinctrl driver
- Author: horatiu.vultur@microchip.com
- License: Dual MIT/GPL
license is redundant due to SPDX
- Copyright (c) 2018 Microsemi Corporation
- */
+#include <common.h> +#include <config.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dm/pinctrl.h> +#include <dm/root.h> +#include <errno.h> +#include <fdtdec.h> +#include <linux/io.h> +#include <asm/gpio.h> +#include <asm/system.h> +#include "mscc-common.h"
+#define MSCC_GPIO_ALT0 0x40 +#define MSCC_GPIO_ALT1 0x48
+enum {
- FUNC_NONE,
- FUNC_GPIO,
- FUNC_IRQ0_IN,
- FUNC_IRQ0_OUT,
- FUNC_IRQ1_IN,
- FUNC_IRQ1_OUT,
- FUNC_MIIM1,
- FUNC_MIIM2,
- FUNC_PCI_WAKE,
- FUNC_PTP0,
- FUNC_PTP1,
- FUNC_PTP2,
- FUNC_PTP3,
- FUNC_PWM,
- FUNC_RECO_CLK0,
- FUNC_RECO_CLK1,
- FUNC_SFP0,
- FUNC_SFP1,
- FUNC_SFP2,
- FUNC_SFP3,
- FUNC_SFP4,
- FUNC_SFP5,
- FUNC_SFP6,
- FUNC_SFP7,
- FUNC_SFP8,
- FUNC_SFP9,
- FUNC_SFP10,
- FUNC_SFP11,
- FUNC_SFP12,
- FUNC_SFP13,
- FUNC_SFP14,
- FUNC_SFP15,
- FUNC_SIO,
- FUNC_SIO1,
- FUNC_SIO2,
- FUNC_SI,
- FUNC_TACHO,
- FUNC_TWI,
- FUNC_TWI2,
- FUNC_TWI_SCL_M,
- FUNC_UART,
- FUNC_UART2,
- FUNC_MAX
+};
+char *jr2_function_names[] = {
- [FUNC_NONE] = "none",
- [FUNC_GPIO] = "gpio",
- [FUNC_IRQ0_IN] = "irq0_in",
- [FUNC_IRQ0_OUT] = "irq0_out",
- [FUNC_IRQ1_IN] = "irq1_in",
- [FUNC_IRQ1_OUT] = "irq1_out",
- [FUNC_MIIM1] = "miim1",
- [FUNC_MIIM2] = "miim2",
- [FUNC_PCI_WAKE] = "pci_wake",
- [FUNC_PTP0] = "ptp0",
- [FUNC_PTP1] = "ptp1",
- [FUNC_PTP2] = "ptp2",
- [FUNC_PTP3] = "ptp3",
- [FUNC_PWM] = "pwm",
- [FUNC_RECO_CLK0] = "reco_clk0",
- [FUNC_RECO_CLK1] = "reco_clk1",
- [FUNC_SFP0] = "sfp0",
- [FUNC_SFP1] = "sfp1",
- [FUNC_SFP2] = "sfp2",
- [FUNC_SFP3] = "sfp3",
- [FUNC_SFP4] = "sfp4",
- [FUNC_SFP5] = "sfp5",
- [FUNC_SFP6] = "sfp6",
- [FUNC_SFP7] = "sfp7",
- [FUNC_SFP8] = "sfp8",
- [FUNC_SFP9] = "sfp9",
- [FUNC_SFP10] = "sfp10",
- [FUNC_SFP11] = "sfp11",
- [FUNC_SFP12] = "sfp12",
- [FUNC_SFP13] = "sfp13",
- [FUNC_SFP14] = "sfp14",
- [FUNC_SFP15] = "sfp15",
- [FUNC_SIO] = "sio",
- [FUNC_SIO1] = "sio1",
- [FUNC_SIO2] = "sio2",
- [FUNC_SI] = "si",
- [FUNC_TACHO] = "tacho",
- [FUNC_TWI] = "twi",
- [FUNC_TWI2] = "twi2",
- [FUNC_TWI_SCL_M] = "twi_scl_m",
- [FUNC_UART] = "uart",
- [FUNC_UART2] = "uart2",
+};
+MSCC_P(0, SIO, NONE, NONE); +MSCC_P(1, SIO, NONE, NONE); +MSCC_P(2, SIO, NONE, NONE); +MSCC_P(3, SIO, NONE, NONE); +MSCC_P(4, SIO1, NONE, NONE); +MSCC_P(5, SIO1, NONE, NONE); +MSCC_P(6, IRQ0_IN, IRQ0_OUT, NONE); +MSCC_P(7, IRQ1_IN, IRQ1_OUT, NONE); +MSCC_P(8, PTP0, NONE, NONE); +MSCC_P(9, PTP1, NONE, NONE); +MSCC_P(10, UART, NONE, NONE); +MSCC_P(11, UART, NONE, NONE); +MSCC_P(12, SIO1, NONE, NONE); +MSCC_P(13, SIO1, NONE, NONE); +MSCC_P(14, TWI, TWI_SCL_M, NONE); +MSCC_P(15, TWI, NONE, NONE); +MSCC_P(16, SI, TWI_SCL_M, NONE); +MSCC_P(17, SI, TWI_SCL_M, NONE); +MSCC_P(18, SI, TWI_SCL_M, NONE); +MSCC_P(19, PCI_WAKE, NONE, NONE); +MSCC_P(20, IRQ0_OUT, TWI_SCL_M, NONE); +MSCC_P(21, IRQ1_OUT, TWI_SCL_M, NONE); +MSCC_P(22, TACHO, NONE, NONE); +MSCC_P(23, PWM, NONE, NONE); +MSCC_P(24, UART2, NONE, NONE); +MSCC_P(25, UART2, SI, NONE); +MSCC_P(26, PTP2, SI, NONE); +MSCC_P(27, PTP3, SI, NONE); +MSCC_P(28, TWI2, SI, NONE); +MSCC_P(29, TWI, SI, NONE); +MSCC_P(30, SIO2, SI, NONE); +MSCC_P(31, SIO2, SI, NONE); +MSCC_P(32, SIO2, SI, NONE); +MSCC_P(33, SIO2, SI, NONE); +MSCC_P(34, NONE, TWI_SCL_M, NONE); +MSCC_P(35, NONE, TWI_SCL_M, NONE); +MSCC_P(36, NONE, TWI_SCL_M, NONE); +MSCC_P(37, NONE, TWI_SCL_M, NONE); +MSCC_P(38, NONE, TWI_SCL_M, NONE); +MSCC_P(39, NONE, TWI_SCL_M, NONE); +MSCC_P(40, NONE, TWI_SCL_M, NONE); +MSCC_P(41, NONE, TWI_SCL_M, NONE); +MSCC_P(42, NONE, TWI_SCL_M, NONE); +MSCC_P(43, NONE, TWI_SCL_M, NONE); +MSCC_P(44, NONE, SFP8, NONE); +MSCC_P(45, NONE, SFP9, NONE); +MSCC_P(46, NONE, SFP10, NONE); +MSCC_P(47, NONE, SFP11, NONE); +MSCC_P(48, SFP0, NONE, NONE); +MSCC_P(49, SFP1, SI, NONE); +MSCC_P(50, SFP2, SI, NONE); +MSCC_P(51, SFP3, SI, NONE); +MSCC_P(52, SFP4, NONE, NONE); +MSCC_P(53, SFP5, NONE, NONE); +MSCC_P(54, SFP6, NONE, NONE); +MSCC_P(55, SFP7, NONE, NONE); +MSCC_P(56, MIIM1, SFP12, NONE); +MSCC_P(57, MIIM1, SFP13, NONE); +MSCC_P(58, MIIM2, SFP14, NONE); +MSCC_P(59, MIIM2, SFP15, NONE); +MSCC_P(60, NONE, NONE, NONE); +MSCC_P(61, NONE, NONE, NONE); +MSCC_P(62, NONE, NONE, NONE); +MSCC_P(63, NONE, NONE, NONE);
+#define JR2_PIN(n) { \
- .name = "GPIO_"#n, \
- .drv_data = &mscc_pin_##n \
+}
+const struct mscc_pin_data jr2_pins[] = {
- JR2_PIN(0),
- JR2_PIN(1),
- JR2_PIN(2),
- JR2_PIN(3),
- JR2_PIN(4),
- JR2_PIN(5),
- JR2_PIN(6),
- JR2_PIN(7),
- JR2_PIN(8),
- JR2_PIN(9),
- JR2_PIN(10),
- JR2_PIN(11),
- JR2_PIN(12),
- JR2_PIN(13),
- JR2_PIN(14),
- JR2_PIN(15),
- JR2_PIN(16),
- JR2_PIN(17),
- JR2_PIN(18),
- JR2_PIN(19),
- JR2_PIN(20),
- JR2_PIN(21),
- JR2_PIN(22),
- JR2_PIN(23),
- JR2_PIN(24),
- JR2_PIN(25),
- JR2_PIN(26),
- JR2_PIN(27),
- JR2_PIN(28),
- JR2_PIN(29),
- JR2_PIN(30),
- JR2_PIN(31),
- JR2_PIN(32),
- JR2_PIN(33),
- JR2_PIN(34),
- JR2_PIN(35),
- JR2_PIN(36),
- JR2_PIN(37),
- JR2_PIN(38),
- JR2_PIN(39),
- JR2_PIN(40),
- JR2_PIN(41),
- JR2_PIN(42),
- JR2_PIN(43),
- JR2_PIN(44),
- JR2_PIN(45),
- JR2_PIN(46),
- JR2_PIN(47),
- JR2_PIN(48),
- JR2_PIN(49),
- JR2_PIN(50),
- JR2_PIN(51),
- JR2_PIN(52),
- JR2_PIN(53),
- JR2_PIN(54),
- JR2_PIN(55),
- JR2_PIN(56),
- JR2_PIN(57),
- JR2_PIN(58),
- JR2_PIN(59),
- JR2_PIN(60),
- JR2_PIN(61),
- JR2_PIN(62),
- JR2_PIN(63),
+};
+int mscc_pinmux_set_mux(struct udevice *dev,
unsigned int pin_selector, unsigned int selector)
+{
- struct mscc_pinctrl *info = dev_get_priv(dev);
- struct mscc_pin_caps *pin = info->mscc_pins[pin_selector].drv_data;
- int f, offset, regoff;
- f = mscc_pin_function_idx(pin_selector, selector, info->mscc_pins);
- if (f < 0)
return -EINVAL;
- /*
* f is encoded on two bits.
* bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of
* ALT1
* This is racy because both registers can't be updated at the same time
* but it doesn't matter much for now.
*/
- offset = pin->pin;
- regoff = MSCC_GPIO_ALT0;
- if (offset >= 32) {
offset = offset % 32;
regoff = MSCC_GPIO_ALT1;
- }
- if (f & BIT(0))
mscc_setbits(offset, info->regs + regoff);
- else
mscc_clrbits(offset, info->regs + regoff);
- if (f & BIT(1))
mscc_setbits(offset, info->regs + regoff + 4);
- else
mscc_clrbits(offset, info->regs + regoff + 4);
- return 0;
+}
+static int jr2_gpio_probe(struct udevice *dev) +{
- struct gpio_dev_priv *uc_priv;
- uc_priv = dev_get_uclass_priv(dev);
- uc_priv->bank_name = "jr2-gpio";
- uc_priv->gpio_count = ARRAY_SIZE(jr2_pins);
- return 0;
+}
+static struct driver jr2_gpio_driver = {
- .name = "jr2-gpio",
- .id = UCLASS_GPIO,
- .probe = jr2_gpio_probe,
- .ops = &mscc_gpio_ops,
+};
+int jr2_pinctrl_probe(struct udevice *dev) +{
- int ret;
- ret = mscc_pinctrl_probe(dev, FUNC_MAX, jr2_pins,
ARRAY_SIZE(jr2_pins),
jr2_function_names);
- if (ret)
return ret;
- ret = device_bind(dev, &jr2_gpio_driver, "jr2-gpio", NULL,
dev_of_offset(dev), NULL);
- if (ret)
return ret;
- return 0;
+}
+static const struct udevice_id jr2_pinctrl_of_match[] = {
- { .compatible = "mscc,jr2-pinctrl" },
- {},
+};
+U_BOOT_DRIVER(jr2_pinctrl) = {
- .name = "jr2-pinctrl",
- .id = UCLASS_PINCTRL,
- .of_match = of_match_ptr(jr2_pinctrl_of_match),
- .probe = jr2_pinctrl_probe,
- .priv_auto_alloc_size = sizeof(struct mscc_pinctrl),
- .ops = &mscc_pinctrl_ops,
+};
--
- Daniel
--
- Daniel

Am 09.01.19 um 09:21 schrieb Horatiu Vultur:
Hi Daniel,
First, thank you for all the feedback.
I have created a new patch series that will fix the issue that you addressed bellow but the fix it would not use compatible string, because that presume that I need to change the other pinctrl-drivers(ocelot, luton). I was thinking if it is OK the way I have done in v3 and then create a new patch series specific for fixing pinctrl. Similar with the issue that I have for sysreset driver.
I didn't expect that you select the registers via compatible strings in the pinctrl driver because you effectively have three drivers and a common driver core. Your v3 variant is perfect. The compatible string method makes sense for drivers that support more than one SoC. The sysreset driver could be an example.

As the Ocelot and Luton SoCs, this family of SoCs are found in Microsemi Switches solution.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com --- arch/mips/mach-mscc/Kconfig | 9 + arch/mips/mach-mscc/cpu.c | 7 + arch/mips/mach-mscc/dram.c | 2 +- arch/mips/mach-mscc/include/mach/common.h | 5 + arch/mips/mach-mscc/include/mach/ddr.h | 38 ++- arch/mips/mach-mscc/include/mach/jr2/jr2.h | 24 ++ .../mach-mscc/include/mach/jr2/jr2_devcpu_gcb.h | 20 ++ .../include/mach/jr2/jr2_devcpu_gcb_miim_regs.h | 25 ++ .../mips/mach-mscc/include/mach/jr2/jr2_icpu_cfg.h | 321 +++++++++++++++++++++ 9 files changed, 443 insertions(+), 8 deletions(-) create mode 100644 arch/mips/mach-mscc/include/mach/jr2/jr2.h create mode 100644 arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb.h create mode 100644 arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb_miim_regs.h create mode 100644 arch/mips/mach-mscc/include/mach/jr2/jr2_icpu_cfg.h
diff --git a/arch/mips/mach-mscc/Kconfig b/arch/mips/mach-mscc/Kconfig index 37ef432..fc6aa03 100644 --- a/arch/mips/mach-mscc/Kconfig +++ b/arch/mips/mach-mscc/Kconfig @@ -33,6 +33,13 @@ config SOC_LUTON help This supports MSCC Luton family of SOCs.
+config SOC_JR2 + bool "Jaguar2 SOC Family" + select SOC_VCOREIII + select DESIGNWARE_SPI + help + This supports MSCC Jaguar2 family of SOCs. + endchoice
config SYS_CONFIG_NAME @@ -65,4 +72,6 @@ source "board/mscc/ocelot/Kconfig"
source "board/mscc/luton/Kconfig"
+source "board/mscc/jr2/Kconfig" + endmenu diff --git a/arch/mips/mach-mscc/cpu.c b/arch/mips/mach-mscc/cpu.c index 5be8ff6..4729b7a 100644 --- a/arch/mips/mach-mscc/cpu.c +++ b/arch/mips/mach-mscc/cpu.c @@ -87,8 +87,15 @@ int mach_cpu_init(void) ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) + ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG); #else +#ifdef CONFIG_SOC_OCELOT writel(ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) + ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG); +#endif +#ifdef CONFIG_SOC_JR2 + writel(ICPU_SPI_MST_CFG_FAST_READ_ENA + + ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) + + ICPU_SPI_MST_CFG_CLK_DIV(14), BASE_CFG + ICPU_SPI_MST_CFG); +#endif /* * Legacy and mainline linux kernel expect that the * interruption map was set as it was done by redboot. diff --git a/arch/mips/mach-mscc/dram.c b/arch/mips/mach-mscc/dram.c index 309007c..8002e07 100644 --- a/arch/mips/mach-mscc/dram.c +++ b/arch/mips/mach-mscc/dram.c @@ -19,7 +19,7 @@ static inline int vcoreiii_train_bytelane(void)
ret = hal_vcoreiii_train_bytelane(0);
-#ifdef CONFIG_SOC_OCELOT +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) if (ret) return ret; ret = hal_vcoreiii_train_bytelane(1); diff --git a/arch/mips/mach-mscc/include/mach/common.h b/arch/mips/mach-mscc/include/mach/common.h index d18ae78..9cb2fbb 100644 --- a/arch/mips/mach-mscc/include/mach/common.h +++ b/arch/mips/mach-mscc/include/mach/common.h @@ -16,6 +16,11 @@ #include <mach/luton/luton_devcpu_gcb.h> #include <mach/luton/luton_devcpu_gcb_miim_regs.h> #include <mach/luton/luton_icpu_cfg.h> +#elif defined(CONFIG_SOC_JR2) +#include <mach/jr2/jr2.h> +#include <mach/jr2/jr2_devcpu_gcb.h> +#include <mach/jr2/jr2_devcpu_gcb_miim_regs.h> +#include <mach/jr2/jr2_icpu_cfg.h> #else #error Unsupported platform #endif diff --git a/arch/mips/mach-mscc/include/mach/ddr.h b/arch/mips/mach-mscc/include/mach/ddr.h index f445e63..7552acb 100644 --- a/arch/mips/mach-mscc/include/mach/ddr.h +++ b/arch/mips/mach-mscc/include/mach/ddr.h @@ -161,7 +161,7 @@
#endif
-#ifdef CONFIG_SOC_OCELOT +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) #define MIPS_VCOREIII_MEMORY_16BIT 1 #endif
@@ -239,7 +239,7 @@ ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(VC3_MPAR_row_addr_cnt - 1) | \ ICPU_MEMCTRL_CFG_MSB_COL_ADDR(VC3_MPAR_col_addr_cnt - 1)
-#ifdef CONFIG_SOC_OCELOT +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) #define MSCC_MEMPARM_PERIOD \ ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(8) | \ ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(VC3_MPAR_tREFI) @@ -378,7 +378,7 @@ static inline void memphy_soft_reset(void) PAUSE(); }
-#ifdef CONFIG_SOC_OCELOT +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) static u8 training_data[] = { 0xfe, 0x11, 0x33, 0x55, 0x77, 0x99, 0xbb, 0xdd };
static inline void sleep_100ns(u32 val) @@ -398,6 +398,7 @@ static inline void sleep_100ns(u32 val) ; }
+#if defined(CONFIG_SOC_OCELOT) static inline void hal_vcoreiii_ddr_reset_assert(void) { /* DDR has reset pin on GPIO 19 toggle Low-High to release */ @@ -448,6 +449,26 @@ static inline void hal_vcoreiii_ddr_failed(void)
panic("DDR init failed\n"); } +#else /* JR2 */ +static inline void hal_vcoreiii_ddr_reset_assert(void) +{ + /* Ensure the memory controller physical iface is forced reset */ + writel(readl(BASE_CFG + ICPU_MEMPHY_CFG) | + ICPU_MEMPHY_CFG_PHY_RST, BASE_CFG + ICPU_MEMPHY_CFG); + + /* Ensure the memory controller is forced reset */ + writel(readl(BASE_CFG + ICPU_RESET) | + ICPU_RESET_MEM_RST_FORCE, BASE_CFG + ICPU_RESET); +} + +static inline void hal_vcoreiii_ddr_failed(void) +{ + writel(0, BASE_CFG + ICPU_RESET); + writel(PERF_SOFT_RST_SOFT_CHIP_RST, BASE_CFG + PERF_SOFT_RST); + + panic("DDR init failed\n"); +} +#endif
/* * DDR memory sanity checking done, possibly enable ECC. @@ -738,7 +759,7 @@ static inline void hal_vcoreiii_init_memctl(void) /* Wait for ZCAL to clear */ while (readl(BASE_CFG + ICPU_MEMPHY_ZCAL) & ICPU_MEMPHY_ZCAL_ZCAL_ENA) ; -#ifdef CONFIG_SOC_OCELOT +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) /* Check no ZCAL_ERR */ if (readl(BASE_CFG + ICPU_MEMPHY_ZCAL_STAT) & ICPU_MEMPHY_ZCAL_STAT_ZCAL_ERR) @@ -752,7 +773,7 @@ static inline void hal_vcoreiii_init_memctl(void) writel(MSCC_MEMPARM_MEMCFG, BASE_CFG + ICPU_MEMCTRL_CFG); writel(MSCC_MEMPARM_PERIOD, BASE_CFG + ICPU_MEMCTRL_REF_PERIOD);
-#ifdef CONFIG_SOC_OCELOT +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) writel(MSCC_MEMPARM_TIMING0, BASE_CFG + ICPU_MEMCTRL_TIMING0); #else /* Luton */ clrbits_le32(BASE_CFG + ICPU_MEMCTRL_TIMING0, ((1 << 20) - 1)); @@ -767,7 +788,7 @@ static inline void hal_vcoreiii_init_memctl(void) writel(MSCC_MEMPARM_MR2, BASE_CFG + ICPU_MEMCTRL_MR2_VAL); writel(MSCC_MEMPARM_MR3, BASE_CFG + ICPU_MEMCTRL_MR3_VAL);
-#ifdef CONFIG_SOC_OCELOT +#if defined(CONFIG_SOC_OCELOT) /* Termination setup - enable ODT */ writel(ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA | /* Assert ODT0 for any write */ @@ -778,6 +799,9 @@ static inline void hal_vcoreiii_init_memctl(void) hal_vcoreiii_ddr_reset_release();
writel(readl(BASE_CFG + ICPU_GPR(7)) + 1, BASE_CFG + ICPU_GPR(7)); +#elif defined(CONFIG_SOC_JR2) + writel(ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(3), + BASE_CFG + ICPU_MEMCTRL_TERMRES_CTRL); #else /* Luton */ /* Termination setup - disable ODT */ writel(0, BASE_CFG + ICPU_MEMCTRL_TERMRES_CTRL); @@ -796,7 +820,7 @@ static inline void hal_vcoreiii_wait_memctl(void)
/* Settle...? */ sleep_100ns(10000); -#ifdef CONFIG_SOC_OCELOT +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) /* Establish data contents in DDR RAM for training */
__raw_writel(0xcacafefe, ((void __iomem *)MSCC_DDR_TO)); diff --git a/arch/mips/mach-mscc/include/mach/jr2/jr2.h b/arch/mips/mach-mscc/include/mach/jr2/jr2.h new file mode 100644 index 0000000..67244f6 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/jr2/jr2.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Microsemi Jaguar2 Switch driver + * + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_JR2_H_ +#define _MSCC_JR2_H_ + +#include <linux/bitops.h> +#include <dm.h> + +/* + * Target offset base(s) + */ +#define MSCC_IO_ORIGIN1_OFFSET 0x70000000 +#define MSCC_IO_ORIGIN1_SIZE 0x00200000 +#define MSCC_IO_ORIGIN2_OFFSET 0x71000000 +#define MSCC_IO_ORIGIN2_SIZE 0x01000000 +#define BASE_CFG ((void __iomem *)0x70000000) +#define BASE_DEVCPU_GCB ((void __iomem *)0x71010000) + +#endif diff --git a/arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb.h b/arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb.h new file mode 100644 index 0000000..4a1228d --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb.h @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_JR2_DEVCPU_GCB_H_ +#define _MSCC_JR2_DEVCPU_GCB_H_ + +#define PERF_GPR 0x4 + +#define PERF_SOFT_RST 0x8 + +#define PERF_SOFT_RST_SOFT_NON_CFG_RST BIT(2) +#define PERF_SOFT_RST_SOFT_SWC_RST BIT(1) +#define PERF_SOFT_RST_SOFT_CHIP_RST BIT(0) + +#define GPIO_GPIO_ALT(x) (0x78 + 4 * (x)) +#define GPIO_GPIO_ALT1(x) (0x80 + 4 * (x)) + +#endif diff --git a/arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb_miim_regs.h b/arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb_miim_regs.h new file mode 100644 index 0000000..3c84edc --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb_miim_regs.h @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_JR2_DEVCPU_GCB_MIIM_REGS_H_ +#define _MSCC_JR2_DEVCPU_GCB_MIIM_REGS_H_ + +#define MIIM_MII_STATUS(gi) (0xc8 + (gi * 36)) +#define MIIM_MII_CMD(gi) (0xd0 + (gi * 36)) +#define MIIM_MII_DATA(gi) (0xd4 + (gi * 36)) + +#define MSCC_F_MII_STATUS_MIIM_STAT_BUSY(x) ((x) ? BIT(3) : 0) + +#define MSCC_F_MII_CMD_MIIM_CMD_VLD(x) ((x) ? BIT(31) : 0) +#define MSCC_F_MII_CMD_MIIM_CMD_PHYAD(x) (GENMASK(29, 25) & ((x) << 25)) +#define MSCC_F_MII_CMD_MIIM_CMD_REGAD(x) (GENMASK(24, 20) & ((x) << 20)) +#define MSCC_F_MII_CMD_MIIM_CMD_WRDATA(x) (GENMASK(19, 4) & ((x) << 4)) +#define MSCC_F_MII_CMD_MIIM_CMD_OPR_FIELD(x) (GENMASK(2, 1) & ((x) << 1)) +#define MSCC_F_MII_CMD_MIIM_CMD_SCAN(x) ((x) ? BIT(0) : 0) + +#define MSCC_M_MII_DATA_MIIM_DATA_SUCCESS GENMASK(17, 16) +#define MSCC_X_MII_DATA_MIIM_DATA_RDDATA(x) (((x) >> 0) & GENMASK(15, 0)) + +#endif diff --git a/arch/mips/mach-mscc/include/mach/jr2/jr2_icpu_cfg.h b/arch/mips/mach-mscc/include/mach/jr2/jr2_icpu_cfg.h new file mode 100644 index 0000000..6e0bbe2 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/jr2/jr2_icpu_cfg.h @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_JR2_ICPU_CFG_H_ +#define _MSCC_JR2_ICPU_CFG_H_ + +#define ICPU_GPR(x) (0x4 * (x)) +#define ICPU_GPR_RSZ 0x4 + +#define ICPU_RESET 0x20 + +#define ICPU_RESET_CORE_RST_CPU_ONLY BIT(3) +#define ICPU_RESET_CORE_RST_PROTECT BIT(2) +#define ICPU_RESET_CORE_RST_FORCE BIT(1) +#define ICPU_RESET_MEM_RST_FORCE BIT(0) + +#define ICPU_GENERAL_CTRL 0x24 + +#define ICPU_GENERAL_CTRL_CPU_BUSIF_SLEEP_DIS BIT(15) +#define ICPU_GENERAL_CTRL_CPU_BUSIF_WERR_ENA BIT(14) +#define ICPU_GENERAL_CTRL_CPU_8051_IROM_ENA BIT(13) +#define ICPU_GENERAL_CTRL_CPU_MIPS_DIS BIT(12) +#define ICPU_GENERAL_CTRL_IF_MIIM_SLV_ENA BIT(11) +#define ICPU_GENERAL_CTRL_IF_PI_SLV_DONEPOL BIT(10) +#define ICPU_GENERAL_CTRL_IF_PI_MST_ENA BIT(9) +#define ICPU_GENERAL_CTRL_IF_PI_SLV_ENA BIT(8) +#define ICPU_GENERAL_CTRL_IF_SI_OWNER(x) (((x) << 6) & GENMASK(7, 6)) +#define ICPU_GENERAL_CTRL_IF_SI_OWNER_M GENMASK(7, 6) +#define ICPU_GENERAL_CTRL_IF_SI_OWNER_X(x) (((x) & GENMASK(7, 6)) >> 4) +#define ICPU_GENERAL_CTRL_IF_SI1_OWNER(x) (((x) << 4) & GENMASK(5, 4)) +#define ICPU_GENERAL_CTRL_IF_SI1_OWNER_M GENMASK(5, 4) +#define ICPU_GENERAL_CTRL_IF_SI1_OWNER_X(x) (((x) & GENMASK(5, 4)) >> 4) +#define ICPU_GENERAL_CTRL_SSI_MST_CONTENTION BIT(3) +#define ICPU_GENERAL_CTRL_CPU_BE_ENA BIT(2) +#define ICPU_GENERAL_CTRL_CPU_DIS BIT(1) +#define ICPU_GENERAL_CTRL_BOOT_MODE_ENA BIT(0) + +#define ICPU_SPI_MST_CFG 0x3c + +#define ICPU_SPI_MST_CFG_A32B_ENA BIT(11) +#define ICPU_SPI_MST_CFG_FAST_READ_ENA BIT(10) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME(x) (((x) << 5) & GENMASK(9, 5)) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_M GENMASK(9, 5) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_X(x) (((x) & GENMASK(9, 5)) >> 5) +#define ICPU_SPI_MST_CFG_CLK_DIV(x) ((x) & GENMASK(4, 0)) +#define ICPU_SPI_MST_CFG_CLK_DIV_M GENMASK(4, 0) + +#define ICPU_SW_MODE 0x50 + +#define ICPU_SW_MODE_SW_PIN_CTRL_MODE BIT(13) +#define ICPU_SW_MODE_SW_SPI_SCK BIT(12) +#define ICPU_SW_MODE_SW_SPI_SCK_OE BIT(11) +#define ICPU_SW_MODE_SW_SPI_SDO BIT(10) +#define ICPU_SW_MODE_SW_SPI_SDO_OE BIT(9) +#define ICPU_SW_MODE_SW_SPI_CS(x) (((x) << 5) & GENMASK(8, 5)) +#define ICPU_SW_MODE_SW_SPI_CS_M GENMASK(8, 5) +#define ICPU_SW_MODE_SW_SPI_CS_X(x) (((x) & GENMASK(8, 5)) >> 5) +#define ICPU_SW_MODE_SW_SPI_CS_OE(x) (((x) << 1) & GENMASK(4, 1)) +#define ICPU_SW_MODE_SW_SPI_CS_OE_M GENMASK(4, 1) +#define ICPU_SW_MODE_SW_SPI_CS_OE_X(x) (((x) & GENMASK(4, 1)) >> 1) +#define ICPU_SW_MODE_SW_SPI_SDI BIT(0) + +#define ICPU_INTR_ENA 0x88 + +#define ICPU_DST_INTR_MAP(x) (0x98 + 0x4 * (x)) +#define ICPU_DST_INTR_MAP_RSZ 0x4 + +#define ICPU_TIMER_TICK_DIV 0x108 + +#define ICPU_TIMER_VALUE(x) (0x10c + 0x4 * (x)) +#define ICPU_TIMER_VALUE_RSZ 0x4 + +#define ICPU_TIMER_CTRL(x) (0x124 + 0x4 * (x)) +#define ICPU_TIMER_CTRL_RSZ 0x4 + +#define ICPU_TIMER_CTRL_MAX_FREQ_ENA BIT(3) +#define ICPU_TIMER_CTRL_ONE_SHOT_ENA BIT(2) +#define ICPU_TIMER_CTRL_TIMER_ENA BIT(1) +#define ICPU_TIMER_CTRL_FORCE_RELOAD BIT(0) + +#define ICPU_MEMCTRL_CTRL 0x130 + +#define ICPU_MEMCTRL_CTRL_PWR_DOWN BIT(3) +#define ICPU_MEMCTRL_CTRL_MDSET BIT(2) +#define ICPU_MEMCTRL_CTRL_STALL_REF_ENA BIT(1) +#define ICPU_MEMCTRL_CTRL_INITIALIZE BIT(0) + +#define ICPU_MEMCTRL_CFG 0x134 + +#define ICPU_MEMCTRL_CFG_DDR_512MBYTE_PLUS BIT(16) +#define ICPU_MEMCTRL_CFG_DDR_ECC_ERR_ENA BIT(15) +#define ICPU_MEMCTRL_CFG_DDR_ECC_COR_ENA BIT(14) +#define ICPU_MEMCTRL_CFG_DDR_ECC_ENA BIT(13) +#define ICPU_MEMCTRL_CFG_DDR_WIDTH BIT(12) +#define ICPU_MEMCTRL_CFG_DDR_MODE BIT(11) +#define ICPU_MEMCTRL_CFG_BURST_SIZE BIT(10) +#define ICPU_MEMCTRL_CFG_BURST_LEN BIT(9) +#define ICPU_MEMCTRL_CFG_BANK_CNT BIT(8) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_M GENMASK(7, 4) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_STAT 0x138 + +#define ICPU_MEMCTRL_STAT_RDATA_MASKED BIT(5) +#define ICPU_MEMCTRL_STAT_RDATA_DUMMY BIT(4) +#define ICPU_MEMCTRL_STAT_RDATA_ECC_ERR BIT(3) +#define ICPU_MEMCTRL_STAT_RDATA_ECC_COR BIT(2) +#define ICPU_MEMCTRL_STAT_PWR_DOWN_ACK BIT(1) +#define ICPU_MEMCTRL_STAT_INIT_DONE BIT(0) + +#define ICPU_MEMCTRL_REF_PERIOD 0x13c + +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_M GENMASK(19, 16) +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(x) ((x) & GENMASK(15, 0)) +#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD_M GENMASK(15, 0) + +#define ICPU_MEMCTRL_ZQCAL 0x140 + +#define ICPU_MEMCTRL_ZQCAL_ZQCAL_LONG BIT(1) +#define ICPU_MEMCTRL_ZQCAL_ZQCAL_SHORT BIT(0) + +#define ICPU_MEMCTRL_TIMING0 0x144 + +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY(x) (((x) << 28) & GENMASK(31, 28)) +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_M GENMASK(31, 28) +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_X(x) (((x) & GENMASK(31, 28)) >> 28) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY(x) (((x) << 24) & GENMASK(27, 24)) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_M GENMASK(27, 24) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_X(x) (((x) & GENMASK(27, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY(x) (((x) << 20) & GENMASK(23, 20)) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_M GENMASK(23, 20) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_X(x) (((x) & GENMASK(23, 20)) >> 20) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_M GENMASK(19, 16) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_TIMING1 0x148 + +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(x) (((x) << 24) & GENMASK(31, 24)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_M GENMASK(31, 24) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_X(x) (((x) & GENMASK(31, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(x) (((x) << 16) & GENMASK(23, 16)) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_M GENMASK(23, 16) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_X(x) (((x) & GENMASK(23, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_TIMING2 0x14c + +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(x) (((x) << 28) & GENMASK(31, 28)) +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_M GENMASK(31, 28) +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_X(x) (((x) & GENMASK(31, 28)) >> 28) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY(x) (((x) << 24) & GENMASK(27, 24)) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_M GENMASK(27, 24) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_X(x) (((x) & GENMASK(27, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING2_REF_DLY(x) (((x) << 16) & GENMASK(23, 16)) +#define ICPU_MEMCTRL_TIMING2_REF_DLY_M GENMASK(23, 16) +#define ICPU_MEMCTRL_TIMING2_REF_DLY_X(x) (((x) & GENMASK(23, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING2_INIT_DLY(x) ((x) & GENMASK(15, 0)) +#define ICPU_MEMCTRL_TIMING2_INIT_DLY_M GENMASK(15, 0) + +#define ICPU_MEMCTRL_TIMING3 0x150 + +#define ICPU_MEMCTRL_TIMING3_RMW_DLY(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_TIMING3_RMW_DLY_M GENMASK(19, 16) +#define ICPU_MEMCTRL_TIMING3_RMW_DLY_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_TIMING4 0x154 + +#define ICPU_MEMCTRL_TIMING4_ZQCAL_INIT_DLY(x) (((x) << 20) & GENMASK(31, 20)) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_INIT_DLY_M GENMASK(31, 20) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_INIT_DLY_X(x) (((x) & GENMASK(31, 20)) >> 20) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_LONG_DLY(x) (((x) << 8) & GENMASK(19, 8)) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_LONG_DLY_M GENMASK(19, 8) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_LONG_DLY_X(x) (((x) & GENMASK(19, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_SHORT_DLY(x) ((x) & GENMASK(7, 0)) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_SHORT_DLY_M GENMASK(7, 0) + +#define ICPU_MEMCTRL_MR0_VAL 0x158 + +#define ICPU_MEMCTRL_MR1_VAL 0x15c + +#define ICPU_MEMCTRL_MR2_VAL 0x160 + +#define ICPU_MEMCTRL_MR3_VAL 0x164 + +#define ICPU_MEMCTRL_TERMRES_CTRL 0x168 + +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_EXT BIT(11) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA(x) (((x) << 7) & GENMASK(10, 7)) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_M GENMASK(10, 7) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_X(x) (((x) & GENMASK(10, 7)) >> 7) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_EXT BIT(6) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(x) (((x) << 2) & GENMASK(5, 2)) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_M GENMASK(5, 2) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_X(x) (((x) & GENMASK(5, 2)) >> 2) +#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_EXT BIT(1) +#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA BIT(0) + +#define ICPU_MEMCTRL_DFT 0x16c + +#define ICPU_MEMCTRL_DFT_DDRDFT_LBW BIT(7) +#define ICPU_MEMCTRL_DFT_DDRDFT_GATE_ENA BIT(6) +#define ICPU_MEMCTRL_DFT_DDRDFT_TERM_ENA BIT(5) +#define ICPU_MEMCTRL_DFT_DDRDFT_A10 BIT(4) +#define ICPU_MEMCTRL_DFT_DDRDFT_STAT BIT(3) +#define ICPU_MEMCTRL_DFT_DDRDFT_MODE(x) (((x) << 1) & GENMASK(2, 1)) +#define ICPU_MEMCTRL_DFT_DDRDFT_MODE_M GENMASK(2, 1) +#define ICPU_MEMCTRL_DFT_DDRDFT_MODE_X(x) (((x) & GENMASK(2, 1)) >> 1) +#define ICPU_MEMCTRL_DFT_DDRDFT_ENA BIT(0) + +#define ICPU_MEMCTRL_DQS_DLY(x) (0x170 + 0x4 * (x)) +#define ICPU_MEMCTRL_DQS_DLY_RSZ 0x4 + +#define ICPU_MEMCTRL_DQS_DLY_TRAIN_DQ_ENA BIT(11) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1(x) (((x) << 8) & GENMASK(10, 8)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_M GENMASK(10, 8) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_X(x) (((x) & GENMASK(10, 8)) >> 8) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0(x) (((x) << 5) & GENMASK(7, 5)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_M GENMASK(7, 5) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_X(x) (((x) & GENMASK(7, 5)) >> 5) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY(x) ((x) & GENMASK(4, 0)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_M GENMASK(4, 0) + +#define ICPU_MEMCTRL_DQS_AUTO (0x178 + 0x4 * (x)) +#define ICPU_MEMCTRL_DQS_AUTO_RSZ 0x4 + +#define ICPU_MEMCTRL_DQS_AUTO_DQS_DRIFT(x) (((x) << 6) & GENMASK(7, 6)) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_DRIFT_M GENMASK(7, 6) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_DRIFT_X(x) (((x) & GENMASK(7, 6)) >> 6) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_OVERFLOW BIT(5) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_UNDERFLOW BIT(4) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_AUTO_SRC BIT(3) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_AUTO_UP BIT(2) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_AUTO_DOWN BIT(1) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_AUTO_ENA BIT(0) + +#define ICPU_MEMPHY_CFG 0x180 + +#define ICPU_MEMPHY_CFG_PHY_FLUSH_DIS BIT(10) +#define ICPU_MEMPHY_CFG_PHY_RD_ADJ_DIS BIT(9) +#define ICPU_MEMPHY_CFG_PHY_DQS_EXT BIT(8) +#define ICPU_MEMPHY_CFG_PHY_FIFO_RST BIT(7) +#define ICPU_MEMPHY_CFG_PHY_DLL_BL_RST BIT(6) +#define ICPU_MEMPHY_CFG_PHY_DLL_CL_RST BIT(5) +#define ICPU_MEMPHY_CFG_PHY_ODT_OE BIT(4) +#define ICPU_MEMPHY_CFG_PHY_CK_OE BIT(3) +#define ICPU_MEMPHY_CFG_PHY_CL_OE BIT(2) +#define ICPU_MEMPHY_CFG_PHY_SSTL_ENA BIT(1) +#define ICPU_MEMPHY_CFG_PHY_RST BIT(0) + +#define ICPU_MEMPHY_ZCAL 0x1a8 + +#define ICPU_MEMPHY_ZCAL_ZCAL_CLK_SEL BIT(9) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT(x) (((x) << 5) & GENMASK(8, 5)) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_M GENMASK(8, 5) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_X(x) (((x) & GENMASK(8, 5)) >> 5) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG(x) (((x) << 1) & GENMASK(4, 1)) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_M GENMASK(4, 1) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_X(x) (((x) & GENMASK(4, 1)) >> 1) +#define ICPU_MEMPHY_ZCAL_ZCAL_ENA BIT(0) +// +#define ICPU_MEMPHY_ZCAL_STAT 0x1ac + +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL(x) (((x) << 12) & GENMASK(31, 12)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL_M GENMASK(31, 12) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL_X(x) (((x) & GENMASK(31, 12)) >> 12) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU(x) (((x) << 8) & GENMASK(9, 8)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU_M GENMASK(9, 8) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU_X(x) (((x) & GENMASK(9, 8)) >> 8) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD(x) (((x) << 6) & GENMASK(7, 6)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD_M GENMASK(7, 6) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD_X(x) (((x) & GENMASK(7, 6)) >> 6) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU(x) (((x) << 4) & GENMASK(5, 4)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU_M GENMASK(5, 4) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU_X(x) (((x) & GENMASK(5, 4)) >> 4) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD(x) (((x) << 2) & GENMASK(3, 2)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD_M GENMASK(3, 2) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD_X(x) (((x) & GENMASK(3, 2)) >> 2) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ERR BIT(1) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_DONE BIT(0) + +#endif

Am 07.01.19 um 14:02 schrieb Horatiu Vultur:
As the Ocelot and Luton SoCs, this family of SoCs are found in Microsemi Switches solution.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com
arch/mips/mach-mscc/Kconfig | 9 + arch/mips/mach-mscc/cpu.c | 7 + arch/mips/mach-mscc/dram.c | 2 +- arch/mips/mach-mscc/include/mach/common.h | 5 + arch/mips/mach-mscc/include/mach/ddr.h | 38 ++- arch/mips/mach-mscc/include/mach/jr2/jr2.h | 24 ++ .../mach-mscc/include/mach/jr2/jr2_devcpu_gcb.h | 20 ++ .../include/mach/jr2/jr2_devcpu_gcb_miim_regs.h | 25 ++ .../mips/mach-mscc/include/mach/jr2/jr2_icpu_cfg.h | 321 +++++++++++++++++++++ 9 files changed, 443 insertions(+), 8 deletions(-) create mode 100644 arch/mips/mach-mscc/include/mach/jr2/jr2.h create mode 100644 arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb.h create mode 100644 arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb_miim_regs.h create mode 100644 arch/mips/mach-mscc/include/mach/jr2/jr2_icpu_cfg.h
Reviewed-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com

Add device tree based on evaluation board pcb110.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com --- MAINTAINERS | 1 + arch/mips/dts/jr2_pcb110.dts | 74 +++++++++++++++++ arch/mips/dts/mscc,jr2.dtsi | 187 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 262 insertions(+) create mode 100644 arch/mips/dts/jr2_pcb110.dts create mode 100644 arch/mips/dts/mscc,jr2.dtsi
diff --git a/MAINTAINERS b/MAINTAINERS index 495d3e5..f05c36b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -521,6 +521,7 @@ F: arch/mips/mach-mscc/ F: arch/mips/dts/luton* F: arch/mips/dts/mscc* F: arch/mips/dts/ocelot* +F: arch/mips/dts/jr2* F: board/mscc/ F: configs/mscc* F: drivers/gpio/mscc_sgpio.c diff --git a/arch/mips/dts/jr2_pcb110.dts b/arch/mips/dts/jr2_pcb110.dts new file mode 100644 index 0000000..54b8988 --- /dev/null +++ b/arch/mips/dts/jr2_pcb110.dts @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,jr2.dtsi" + +/ { + model = "Jaguar2 Cu8-Sfp16 PCB110 Reference Board"; + compatible = "mscc,jr2-pcb110", "mscc,jr2"; + + aliases { + spi0 = &spi0; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-leds { + compatible = "gpio-leds"; + + status_green { + label = "pcb110:green:status"; + gpios = <&gpio 12 0>; + default-state = "on"; + }; + + status_red { + label = "pcb110:red:status"; + gpios = <&gpio 13 0>; + default-state = "off"; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + spi-flash@0 { + compatible = "spi-flash"; + spi-max-frequency = <18000000>; /* input clock */ + reg = <0>; /* CS0 */ + }; +}; + +&gpio { + /* SPIO only use DO, CLK, no inputs */ + sgpio1_pins: sgpio1-pins { + pins = "GPIO_4", "GPIO_5"; + function = "sio1"; + }; +}; + +&sgpio { + status = "okay"; + sgpio-ports = <0x00ffffff>; +}; + +&sgpio1 { + status = "okay"; + sgpio-ports = <0x00ff0000>; +}; + +&sgpio2 { + status = "okay"; + sgpio-ports = <0x3f00ffff>; + gpio-ranges = <&sgpio2 0 0 96>; +}; diff --git a/arch/mips/dts/mscc,jr2.dtsi b/arch/mips/dts/mscc,jr2.dtsi new file mode 100644 index 0000000..1ae7873 --- /dev/null +++ b/arch/mips/dts/mscc,jr2.dtsi @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mscc,jr2"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "mips,mips24KEc"; + device_type = "cpu"; + clocks = <&cpu_clk>; + reg = <0>; + }; + }; + + aliases { + serial0 = &uart0; + }; + + cpuintc: interrupt-controller@0 { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + cpu_clk: cpu-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <500000000>; + }; + + ahb_clk: ahb-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + }; + + ahb { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x70000000 0x2000000>; + + interrupt-parent = <&intc>; + + cpu_ctrl: syscon@0 { + compatible = "mscc,jr2-cpu-syscon", "syscon"; + reg = <0x0 0x2c>; + }; + + intc: interrupt-controller@70 { + compatible = "mscc,jr2-icpu-intr"; + reg = <0x70 0x94>; + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&cpuintc>; + interrupts = <2>; + }; + + uart0: serial@100000 { + pinctrl-0 = <&uart_pins>; + pinctrl-names = "default"; + compatible = "ns16550a"; + reg = <0x100000 0x20>; + interrupts = <6>; + clocks = <&ahb_clk>; + reg-io-width = <4>; + reg-shift = <2>; + + status = "disabled"; + }; + + uart2: serial@100800 { + pinctrl-0 = <&uart2_pins>; + pinctrl-names = "default"; + compatible = "ns16550a"; + reg = <0x100800 0x20>; + interrupts = <7>; + clocks = <&ahb_clk>; + reg-io-width = <4>; + reg-shift = <2>; + + status = "disabled"; + }; + + spi0: spi-master@101000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dw-apb-ssi"; + reg = <0x101000 0x40>; + num-chipselect = <4>; + bus-num = <0>; + reg-io-width = <4>; + reg-shift = <2>; + spi-max-frequency = <18000000>; /* input clock */ + clocks = <&ahb_clk>; + + status = "disabled"; + }; + + reset@1010008 { + compatible = "mscc,jr2-chip-reset"; + reg = <0x1010008 0x4>; + }; + + gpio: pinctrl@1070034 { + compatible = "mscc,jr2-pinctrl"; + reg = <0x1010038 0x90>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&gpio 0 0 64>; + + sgpio_pins: sgpio-pins { + pins = "GPIO_0", "GPIO_1", "GPIO_2", "GPIO_3"; + function = "sio"; + }; + + sgpio1_pins: sgpio1-pins { + pins = "GPIO_4", "GPIO_5", "GPIO_12", "GPIO_13"; + function = "sio1"; + }; + + sgpio2_pins: sgpio2-pins { + pins = "GPIO_30", "GPIO_31", + "GPIO_32", "GPIO_33"; + function = "sio2"; + }; + + uart_pins: uart-pins { + pins = "GPIO_10", "GPIO_11"; + function = "uart"; + }; + + uart2_pins: uart2-pins { + pins = "GPIO_24", "GPIO_25"; + function = "uart2"; + }; + }; + + sgpio: gpio@1010150 { + compatible = "mscc,ocelot-sgpio"; + status = "disabled"; + pinctrl-0 = <&sgpio_pins>; + pinctrl-names = "default"; + reg = <0x1010150 0x100>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&sgpio 0 0 64>; + gpio-bank-name = "sgpio0_"; + sgpio-clock = <0x14>; + }; + + sgpio1: gpio@101025c { + compatible = "mscc,ocelot-sgpio"; + status = "disabled"; + pinctrl-0 = <&sgpio1_pins>; + pinctrl-names = "default"; + reg = <0x101025c 0x100>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&sgpio1 0 0 64>; + gpio-bank-name = "sgpio1_"; + sgpio-clock = <0x14>; + }; + + sgpio2: gpio@1010368 { + compatible = "mscc,ocelot-sgpio"; + status = "disabled"; + pinctrl-0 = <&sgpio2_pins>; + pinctrl-names = "default"; + reg = <0x1010368 0x100>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&sgpio2 0 0 64>; + gpio-bank-name = "sgpio2_"; + sgpio-clock = <0x14>; + }; + }; +};

Add device tree based on evaluation board pcb111.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com --- arch/mips/dts/jr2_pcb111.dts | 74 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 arch/mips/dts/jr2_pcb111.dts
diff --git a/arch/mips/dts/jr2_pcb111.dts b/arch/mips/dts/jr2_pcb111.dts new file mode 100644 index 0000000..f1af66f --- /dev/null +++ b/arch/mips/dts/jr2_pcb111.dts @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,jr2.dtsi" + +/ { + model = "Jaguar2 Cu48 PCB111 Reference Board"; + compatible = "mscc,jr2-pcb111", "mscc,jr2"; + + aliases { + spi0 = &spi0; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-leds { + compatible = "gpio-leds"; + + status_green { + label = "pcb111:green:status"; + gpios = <&gpio 12 0>; + default-state = "on"; + }; + + status_red { + label = "pcb111:red:status"; + gpios = <&gpio 13 0>; + default-state = "off"; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + spi-flash@0 { + compatible = "spi-flash"; + spi-max-frequency = <18000000>; /* input clock */ + reg = <0>; /* CS0 */ + }; +}; + +&gpio { + /* SPIO only use DO, CLK, no inputs */ + sgpio1_pins: sgpio1-pins { + pins = "GPIO_4", "GPIO_5"; + function = "sio1"; + }; +}; + +&sgpio { + status = "okay"; + sgpio-ports = <0xffffffff>; +}; + +&sgpio1 { + status = "okay"; + sgpio-ports = <0x001effff>; +}; + +&sgpio2 { + status = "okay"; + sgpio-ports = <0xff000000>; + gpio-ranges = <&sgpio2 0 0 96>; +};

Add device tree based on evaluation board pcb112.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com --- MAINTAINERS | 1 + arch/mips/dts/serval2_pcb112.dts | 60 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 arch/mips/dts/serval2_pcb112.dts
diff --git a/MAINTAINERS b/MAINTAINERS index f05c36b..d42736b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -522,6 +522,7 @@ F: arch/mips/dts/luton* F: arch/mips/dts/mscc* F: arch/mips/dts/ocelot* F: arch/mips/dts/jr2* +F: arch/mips/dts/serval* F: board/mscc/ F: configs/mscc* F: drivers/gpio/mscc_sgpio.c diff --git a/arch/mips/dts/serval2_pcb112.dts b/arch/mips/dts/serval2_pcb112.dts new file mode 100644 index 0000000..fe025f4 --- /dev/null +++ b/arch/mips/dts/serval2_pcb112.dts @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,jr2.dtsi" + +/ { + model = "Serval2 NID PCB112 Reference Board"; + compatible = "mscc,serval2-pcb110", "mscc,jr2"; + + aliases { + spi0 = &spi0; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-leds { + compatible = "gpio-leds"; + + status_green { + label = "pcb110:green:status"; + gpios = <&gpio 12 0>; + default-state = "on"; + }; + + status_red { + label = "pcb110:red:status"; + gpios = <&gpio 13 0>; + default-state = "off"; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + spi-flash@0 { + compatible = "spi-flash"; + spi-max-frequency = <18000000>; /* input clock */ + reg = <0>; /* CS0 */ + }; +}; + +&sgpio { + status = "okay"; + sgpio-ports = <0x0000ffff>; +}; + +&sgpio2 { + status = "okay"; + sgpio-ports = <0x3fe0ffff>; +};

Add board support and configuration for Jaguar2 SOC family. The detection of the board type in this family is based on the phy ids.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com --- arch/mips/dts/Makefile | 1 + arch/mips/mach-mscc/Makefile | 5 +- board/mscc/common/Makefile | 4 ++ board/mscc/common/spi.c | 31 ++++++++++++ board/mscc/jr2/Kconfig | 15 ++++++ board/mscc/jr2/Makefile | 4 ++ board/mscc/jr2/jr2.c | 117 +++++++++++++++++++++++++++++++++++++++++++ board/mscc/ocelot/ocelot.c | 22 -------- configs/mscc_jr2_defconfig | 59 ++++++++++++++++++++++ 9 files changed, 234 insertions(+), 24 deletions(-) create mode 100644 board/mscc/common/Makefile create mode 100644 board/mscc/common/spi.c create mode 100644 board/mscc/jr2/Kconfig create mode 100644 board/mscc/jr2/Makefile create mode 100644 board/mscc/jr2/jr2.c create mode 100644 configs/mscc_jr2_defconfig
diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile index b61afe6..1484db9 100644 --- a/arch/mips/dts/Makefile +++ b/arch/mips/dts/Makefile @@ -19,6 +19,7 @@ dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb dtb-$(CONFIG_TARGET_JZ4780_CI20) += ci20.dtb dtb-$(CONFIG_SOC_LUTON) += luton_pcb090.dtb luton_pcb091.dtb dtb-$(CONFIG_SOC_OCELOT) += ocelot_pcb120.dtb ocelot_pcb123.dtb +dtb-$(CONFIG_SOC_JR2) += jr2_pcb110.dtb jr2_pcb111.dtb serval2_pcb112.dtb
targets += $(dtb-y)
diff --git a/arch/mips/mach-mscc/Makefile b/arch/mips/mach-mscc/Makefile index 44538b7..f5b6968 100644 --- a/arch/mips/mach-mscc/Makefile +++ b/arch/mips/mach-mscc/Makefile @@ -2,5 +2,6 @@
CFLAGS_cpu.o += -finline-limit=64000
-obj-y += cpu.o dram.o reset.o phy.o gpio.o lowlevel_init.o -obj-$(CONFIG_SOC_LUTON) += lowlevel_init_luton.o +obj-y += cpu.o dram.o reset.o phy.o lowlevel_init.o +obj-$(CONFIG_SOC_LUTON) += lowlevel_init_luton.o gpio.o +obj-$(CONFIG_SOC_OCELOT) += gpio.o diff --git a/board/mscc/common/Makefile b/board/mscc/common/Makefile new file mode 100644 index 0000000..4f0eded --- /dev/null +++ b/board/mscc/common/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +obj-$(CONFIG_SOC_JR2) := spi.o +obj-$(CONFIG_SOC_OCELOT) := spi.o diff --git a/board/mscc/common/spi.c b/board/mscc/common/spi.c new file mode 100644 index 0000000..0566fcb --- /dev/null +++ b/board/mscc/common/spi.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Coprporation + */ + +#include <common.h> +#include <asm/io.h> +#include <spi.h> + +void external_cs_manage(struct udevice *dev, bool enable) +{ + u32 cs = spi_chip_select(dev); + /* IF_SI0_OWNER, select the owner of the SI interface + * Encoding: 0: SI Slave + * 1: SI Boot Master + * 2: SI Master Controller + */ + if (!enable) { + writel(ICPU_SW_MODE_SW_PIN_CTRL_MODE | + ICPU_SW_MODE_SW_SPI_CS(BIT(cs)), + BASE_CFG + ICPU_SW_MODE); + clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, + ICPU_GENERAL_CTRL_IF_SI_OWNER_M, + ICPU_GENERAL_CTRL_IF_SI_OWNER(2)); + } else { + writel(0, BASE_CFG + ICPU_SW_MODE); + clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, + ICPU_GENERAL_CTRL_IF_SI_OWNER_M, + ICPU_GENERAL_CTRL_IF_SI_OWNER(1)); + } +} diff --git a/board/mscc/jr2/Kconfig b/board/mscc/jr2/Kconfig new file mode 100644 index 0000000..68a2de8 --- /dev/null +++ b/board/mscc/jr2/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +config SYS_VENDOR + default "mscc" + +if SOC_JR2 + +config SYS_BOARD + default "jr2" + +config SYS_CONFIG_NAME + default "jr2" + +endif + diff --git a/board/mscc/jr2/Makefile b/board/mscc/jr2/Makefile new file mode 100644 index 0000000..c1db2a9 --- /dev/null +++ b/board/mscc/jr2/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +obj-$(CONFIG_SOC_JR2) := jr2.o + diff --git a/board/mscc/jr2/jr2.c b/board/mscc/jr2/jr2.c new file mode 100644 index 0000000..36f9896 --- /dev/null +++ b/board/mscc/jr2/jr2.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <asm/io.h> +#include <led.h> + +DECLARE_GLOBAL_DATA_PTR; + +enum { + BOARD_TYPE_PCB110 = 0xAABBCE00, + BOARD_TYPE_PCB111, + BOARD_TYPE_PCB112, +}; + +int board_early_init_r(void) +{ + /* Prepare SPI controller to be used in master mode */ + writel(0, BASE_CFG + ICPU_SW_MODE); + clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, + ICPU_GENERAL_CTRL_IF_SI_OWNER_M, + ICPU_GENERAL_CTRL_IF_SI_OWNER(2)); + + /* Address of boot parameters */ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE; + + /* LED setup */ + if (IS_ENABLED(CONFIG_LED)) + led_default_state(); + + return 0; +} + +static void vcoreiii_gpio_set_alternate(int gpio, int mode) +{ + u32 mask; + u32 val0, val1; + void __iomem *reg0, *reg1; + + if (gpio < 32) { + mask = BIT(gpio); + reg0 = BASE_CFG + GPIO_GPIO_ALT(0); + reg1 = BASE_CFG + GPIO_GPIO_ALT(1); + } else { + gpio -= 32; + mask = BIT(gpio); + reg0 = BASE_CFG + GPIO_GPIO_ALT1(0); + reg1 = BASE_CFG + GPIO_GPIO_ALT1(1); + } + val0 = readl(reg0); + val1 = readl(reg1); + if (mode == 1) { + writel(val0 | mask, reg0); + writel(val1 & ~mask, reg1); + } else if (mode == 2) { + writel(val0 & ~mask, reg0); + writel(val1 | mask, reg1); + } else if (mode == 3) { + writel(val0 | mask, reg0); + writel(val1 | mask, reg1); + } else { + writel(val0 & ~mask, reg0); + writel(val1 & ~mask, reg1); + } +} + +static void do_board_detect(void) +{ + int i; + u16 pval; + + /* MIIM 1 + 2 MDC/MDIO */ + for (i = 56; i < 60; i++) + vcoreiii_gpio_set_alternate(i, 1); + + if (mscc_phy_rd(0, 0x10, 0x3, &pval) == 0 && + ((pval >> 4) & 0x3F) == 0x3c) { + gd->board_type = BOARD_TYPE_PCB112; /* Serval2-NID */ + } else if (mscc_phy_rd(1, 0x0, 0x3, &pval) == 0 && + ((pval >> 4) & 0x3F) == 0x3c) { + gd->board_type = BOARD_TYPE_PCB110; /* Jr2-24 */ + } else { + /* Fall-back */ + gd->board_type = BOARD_TYPE_PCB111; /* Jr2-48 */ + } +} + +#if defined(CONFIG_MULTI_DTB_FIT) +int board_fit_config_name_match(const char *name) +{ + if (gd->board_type == BOARD_TYPE_PCB110 && + strcmp(name, "jr2_pcb110") == 0) + return 0; + + if (gd->board_type == BOARD_TYPE_PCB111 && + strcmp(name, "jr2_pcb111") == 0) + return 0; + + if (gd->board_type == BOARD_TYPE_PCB112 && + strcmp(name, "serval2_pcb112") == 0) + return 0; + + return -1; +} +#endif + +#if defined(CONFIG_DTB_RESELECT) +int embedded_dtb_select(void) +{ + do_board_detect(); + fdtdec_setup(); + + return 0; +} +#endif diff --git a/board/mscc/ocelot/ocelot.c b/board/mscc/ocelot/ocelot.c index a05c308..0f7a532 100644 --- a/board/mscc/ocelot/ocelot.c +++ b/board/mscc/ocelot/ocelot.c @@ -18,28 +18,6 @@ enum { BOARD_TYPE_PCB123, };
-void external_cs_manage(struct udevice *dev, bool enable) -{ - u32 cs = spi_chip_select(dev); - /* IF_SI0_OWNER, select the owner of the SI interface - * Encoding: 0: SI Slave - * 1: SI Boot Master - * 2: SI Master Controller - */ - if (!enable) { - writel(ICPU_SW_MODE_SW_PIN_CTRL_MODE | - ICPU_SW_MODE_SW_SPI_CS(BIT(cs)), BASE_CFG + ICPU_SW_MODE); - clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, - ICPU_GENERAL_CTRL_IF_SI_OWNER_M, - ICPU_GENERAL_CTRL_IF_SI_OWNER(2)); - } else { - writel(0, BASE_CFG + ICPU_SW_MODE); - clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, - ICPU_GENERAL_CTRL_IF_SI_OWNER_M, - ICPU_GENERAL_CTRL_IF_SI_OWNER(1)); - } -} - void board_debug_uart_init(void) { /* too early for the pinctrl driver, so configure the UART pins here */ diff --git a/configs/mscc_jr2_defconfig b/configs/mscc_jr2_defconfig new file mode 100644 index 0000000..b215754 --- /dev/null +++ b/configs/mscc_jr2_defconfig @@ -0,0 +1,59 @@ +CONFIG_MIPS=y +CONFIG_SYS_TEXT_BASE=0x40000000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_ARCH_MSCC=y +CONFIG_SOC_JR2=y +CONFIG_SYS_LITTLE_ENDIAN=y +CONFIG_FIT=y +CONFIG_BOOTDELAY=3 +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="console=ttyS0,115200" +CONFIG_LOGLEVEL=7 +CONFIG_DISPLAY_CPUINFO=y +CONFIG_SYS_PROMPT="jr2 # " +# CONFIG_CMD_BDI is not set +# CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +# CONFIG_CMD_CRC32 is not set +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MEMTEST=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +# CONFIG_CMD_NET is not set +CONFIG_CMD_MTDPARTS=y +CONFIG_MTDIDS_DEFAULT="nor0=spi_flash" +CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:1m(UBoot),256k(Env),256k(Env.bk)" +# CONFIG_ISO_PARTITION is not set +CONFIG_DEFAULT_DEVICE_TREE="jr2_pcb110" +CONFIG_OF_LIST="jr2_pcb110 jr2_pcb111 serval2_pcb112" +CONFIG_DTB_RESELECT=y +CONFIG_MULTI_DTB_FIT=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_CLK=y +CONFIG_DM_GPIO=y +CONFIG_MSCC_SGPIO=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_MTD=y +CONFIG_DM_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_DM_SERIAL=y +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_LZMA=y +CONFIG_XZ=y

Am 07.01.19 um 14:02 schrieb Horatiu Vultur:
Add board support and configuration for Jaguar2 SOC family. The detection of the board type in this family is based on the phy ids.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com
arch/mips/dts/Makefile | 1 + arch/mips/mach-mscc/Makefile | 5 +- board/mscc/common/Makefile | 4 ++ board/mscc/common/spi.c | 31 ++++++++++++ board/mscc/jr2/Kconfig | 15 ++++++ board/mscc/jr2/Makefile | 4 ++ board/mscc/jr2/jr2.c | 117 +++++++++++++++++++++++++++++++++++++++++++ board/mscc/ocelot/ocelot.c | 22 -------- configs/mscc_jr2_defconfig | 59 ++++++++++++++++++++++ 9 files changed, 234 insertions(+), 24 deletions(-) create mode 100644 board/mscc/common/Makefile create mode 100644 board/mscc/common/spi.c create mode 100644 board/mscc/jr2/Kconfig create mode 100644 board/mscc/jr2/Makefile create mode 100644 board/mscc/jr2/jr2.c create mode 100644 configs/mscc_jr2_defconfig
Reviewed-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com

Create sysreset driver for Jaguar2 SOC family and update defconfig to use it.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com --- MAINTAINERS | 1 + board/mscc/jr2/jr2.c | 8 +++++++ configs/mscc_jr2_defconfig | 2 ++ drivers/sysreset/Kconfig | 6 ++++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_jr2.c | 46 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 64 insertions(+) create mode 100644 drivers/sysreset/sysreset_jr2.c
diff --git a/MAINTAINERS b/MAINTAINERS index d42736b..8b8cc9d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -526,6 +526,7 @@ F: arch/mips/dts/serval* F: board/mscc/ F: configs/mscc* F: drivers/gpio/mscc_sgpio.c +F: drivers/sysreset/sysreset_jr2.c F: include/configs/vcoreiii.h F: drivers/pinctrl/mscc/
diff --git a/board/mscc/jr2/jr2.c b/board/mscc/jr2/jr2.c index 36f9896..2935ad0 100644 --- a/board/mscc/jr2/jr2.c +++ b/board/mscc/jr2/jr2.c @@ -6,6 +6,7 @@ #include <common.h> #include <asm/io.h> #include <led.h> +#include <dm/lists.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -17,6 +18,8 @@ enum {
int board_early_init_r(void) { + int ret; + /* Prepare SPI controller to be used in master mode */ writel(0, BASE_CFG + ICPU_SW_MODE); clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, @@ -30,6 +33,11 @@ int board_early_init_r(void) if (IS_ENABLED(CONFIG_LED)) led_default_state();
+ ret = device_bind_driver(gd->dm_root, "jr2_soft_reset", + "reset_soft", NULL); + if (ret) + printf("Warning: No reset driver: ret=%d\n", ret); + return 0; }
diff --git a/configs/mscc_jr2_defconfig b/configs/mscc_jr2_defconfig index b215754..e80dde6 100644 --- a/configs/mscc_jr2_defconfig +++ b/configs/mscc_jr2_defconfig @@ -57,3 +57,5 @@ CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_LZMA=y CONFIG_XZ=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_JR2=y diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index 8ce3e2e..7c6db0f 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -43,6 +43,12 @@ config SYSRESET_TI_SCI This enables the system reset driver support over TI System Control Interface available on some new TI's SoCs.
+config SYSRESET_JR2 + bool "Enable support for Jaguar2 soft reset" + depends on SOC_JR2 + help + This is soft reset on Jaguar2. + endif
config SYSRESET_SYSCON diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index b3728ac..24c488b 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o obj-$(CONFIG_SYSRESET_X86) += sysreset_x86.o obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o +obj-$(CONFIG_SYSRESET_JR2) += sysreset_jr2.o diff --git a/drivers/sysreset/sysreset_jr2.c b/drivers/sysreset/sysreset_jr2.c new file mode 100644 index 0000000..76a5bac --- /dev/null +++ b/drivers/sysreset/sysreset_jr2.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Microsemi SoCs pinctrl driver + * + * Author: horatiu.vultur@microchip.com + * License: Dual MIT/GPL + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <sysreset.h> +#include <linux/err.h> +#include <asm/io.h> + +static int jr2_sysreset_request(struct udevice *dev, + enum sysreset_t type) +{ + register u32 reg = readl(BASE_CFG + ICPU_GENERAL_CTRL); + /* Set owner */ + reg &= ~ICPU_GENERAL_CTRL_IF_SI_OWNER_M; + reg |= ICPU_GENERAL_CTRL_IF_SI_OWNER(1); + /* Set boot mode */ + reg |= ICPU_GENERAL_CTRL_BOOT_MODE_ENA; + writel(reg, BASE_CFG + ICPU_GENERAL_CTRL); + /* Read back in order to make BOOT mode setting active */ + reg = readl(BASE_CFG + ICPU_GENERAL_CTRL); + /* Reset CPU only - still executing _here_. but from cache */ + writel(readl(BASE_CFG + ICPU_RESET) | + ICPU_RESET_CORE_RST_CPU_ONLY | + ICPU_RESET_CORE_RST_FORCE, + BASE_CFG + ICPU_RESET); + + return -EINPROGRESS; +} + +static struct sysreset_ops jr2_sysreset = { + .request = jr2_sysreset_request, +}; + +U_BOOT_DRIVER(sysreset_jr2) = { + .id = UCLASS_SYSRESET, + .name = "jr2_soft_reset", + .ops = &jr2_sysreset, +};

Am 07.01.19 um 14:02 schrieb Horatiu Vultur:
Create sysreset driver for Jaguar2 SOC family and update defconfig to use it.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com
MAINTAINERS | 1 + board/mscc/jr2/jr2.c | 8 +++++++ configs/mscc_jr2_defconfig | 2 ++ drivers/sysreset/Kconfig | 6 ++++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_jr2.c | 46 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 64 insertions(+) create mode 100644 drivers/sysreset/sysreset_jr2.c
diff --git a/MAINTAINERS b/MAINTAINERS index d42736b..8b8cc9d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -526,6 +526,7 @@ F: arch/mips/dts/serval* F: board/mscc/ F: configs/mscc* F: drivers/gpio/mscc_sgpio.c +F: drivers/sysreset/sysreset_jr2.c F: include/configs/vcoreiii.h F: drivers/pinctrl/mscc/
diff --git a/board/mscc/jr2/jr2.c b/board/mscc/jr2/jr2.c index 36f9896..2935ad0 100644 --- a/board/mscc/jr2/jr2.c +++ b/board/mscc/jr2/jr2.c @@ -6,6 +6,7 @@ #include <common.h> #include <asm/io.h> #include <led.h> +#include <dm/lists.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -17,6 +18,8 @@ enum {
int board_early_init_r(void) {
- int ret;
- /* Prepare SPI controller to be used in master mode */ writel(0, BASE_CFG + ICPU_SW_MODE); clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
@@ -30,6 +33,11 @@ int board_early_init_r(void) if (IS_ENABLED(CONFIG_LED)) led_default_state();
- ret = device_bind_driver(gd->dm_root, "jr2_soft_reset",
"reset_soft", NULL);
- if (ret)
printf("Warning: No reset driver: ret=%d\n", ret);
that shouldn't be necessary if you put a device node to device tree.
Actually my intention in last review was that you create a driver which fits all MSCC SoCs and control the differences via the device tree compatible string. This way you could entirely get rid of the legacy _machine_restart() hook in the MSCC platform. But you don't have to do this in this series.
return 0; }
diff --git a/configs/mscc_jr2_defconfig b/configs/mscc_jr2_defconfig index b215754..e80dde6 100644 --- a/configs/mscc_jr2_defconfig +++ b/configs/mscc_jr2_defconfig @@ -57,3 +57,5 @@ CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_LZMA=y CONFIG_XZ=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_JR2=y diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index 8ce3e2e..7c6db0f 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -43,6 +43,12 @@ config SYSRESET_TI_SCI This enables the system reset driver support over TI System Control Interface available on some new TI's SoCs.
+config SYSRESET_JR2
- bool "Enable support for Jaguar2 soft reset"
- depends on SOC_JR2
- help
This is soft reset on Jaguar2.
endif
config SYSRESET_SYSCON diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index b3728ac..24c488b 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o obj-$(CONFIG_SYSRESET_X86) += sysreset_x86.o obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o +obj-$(CONFIG_SYSRESET_JR2) += sysreset_jr2.o diff --git a/drivers/sysreset/sysreset_jr2.c b/drivers/sysreset/sysreset_jr2.c new file mode 100644 index 0000000..76a5bac --- /dev/null +++ b/drivers/sysreset/sysreset_jr2.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/*
- Microsemi SoCs pinctrl driver
- Author: horatiu.vultur@microchip.com
- License: Dual MIT/GPL
redundant due to SPDX identifier
- Copyright (c) 2018 Microsemi Corporation
- */
+#include <common.h> +#include <dm.h> +#include <errno.h> +#include <sysreset.h> +#include <linux/err.h> +#include <asm/io.h>
+static int jr2_sysreset_request(struct udevice *dev,
enum sysreset_t type)
+{
- register u32 reg = readl(BASE_CFG + ICPU_GENERAL_CTRL);
register is not required in this context
- /* Set owner */
- reg &= ~ICPU_GENERAL_CTRL_IF_SI_OWNER_M;
- reg |= ICPU_GENERAL_CTRL_IF_SI_OWNER(1);
- /* Set boot mode */
- reg |= ICPU_GENERAL_CTRL_BOOT_MODE_ENA;
- writel(reg, BASE_CFG + ICPU_GENERAL_CTRL);
- /* Read back in order to make BOOT mode setting active */
- reg = readl(BASE_CFG + ICPU_GENERAL_CTRL);
- /* Reset CPU only - still executing _here_. but from cache */
- writel(readl(BASE_CFG + ICPU_RESET) |
ICPU_RESET_CORE_RST_CPU_ONLY |
ICPU_RESET_CORE_RST_FORCE,
BASE_CFG + ICPU_RESET);
- return -EINPROGRESS;
+}
+static struct sysreset_ops jr2_sysreset = {
- .request = jr2_sysreset_request,
+};
+U_BOOT_DRIVER(sysreset_jr2) = {
- .id = UCLASS_SYSRESET,
- .name = "jr2_soft_reset",
- .ops = &jr2_sysreset,
+};

Hi Daniel,
The 01/07/2019 21:11, Daniel Schwierzeck wrote:
Am 07.01.19 um 14:02 schrieb Horatiu Vultur:
Create sysreset driver for Jaguar2 SOC family and update defconfig to use it.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com
MAINTAINERS | 1 + board/mscc/jr2/jr2.c | 8 +++++++ configs/mscc_jr2_defconfig | 2 ++ drivers/sysreset/Kconfig | 6 ++++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_jr2.c | 46 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 64 insertions(+) create mode 100644 drivers/sysreset/sysreset_jr2.c
diff --git a/MAINTAINERS b/MAINTAINERS index d42736b..8b8cc9d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -526,6 +526,7 @@ F: arch/mips/dts/serval* F: board/mscc/ F: configs/mscc* F: drivers/gpio/mscc_sgpio.c +F: drivers/sysreset/sysreset_jr2.c F: include/configs/vcoreiii.h F: drivers/pinctrl/mscc/
diff --git a/board/mscc/jr2/jr2.c b/board/mscc/jr2/jr2.c index 36f9896..2935ad0 100644 --- a/board/mscc/jr2/jr2.c +++ b/board/mscc/jr2/jr2.c @@ -6,6 +6,7 @@ #include <common.h> #include <asm/io.h> #include <led.h> +#include <dm/lists.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -17,6 +18,8 @@ enum {
int board_early_init_r(void) {
- int ret;
- /* Prepare SPI controller to be used in master mode */ writel(0, BASE_CFG + ICPU_SW_MODE); clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
@@ -30,6 +33,11 @@ int board_early_init_r(void) if (IS_ENABLED(CONFIG_LED)) led_default_state();
- ret = device_bind_driver(gd->dm_root, "jr2_soft_reset",
"reset_soft", NULL);
- if (ret)
printf("Warning: No reset driver: ret=%d\n", ret);
that shouldn't be necessary if you put a device node to device tree.
Actually my intention in last review was that you create a driver which fits all MSCC SoCs and control the differences via the device tree compatible string. This way you could entirely get rid of the legacy _machine_restart() hook in the MSCC platform. But you don't have to do this in this series.
Ah, now it is more clear. I will create a different patch for this and fix it for all MSCC SoCs.
return 0; }
diff --git a/configs/mscc_jr2_defconfig b/configs/mscc_jr2_defconfig index b215754..e80dde6 100644 --- a/configs/mscc_jr2_defconfig +++ b/configs/mscc_jr2_defconfig @@ -57,3 +57,5 @@ CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_LZMA=y CONFIG_XZ=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_JR2=y diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index 8ce3e2e..7c6db0f 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -43,6 +43,12 @@ config SYSRESET_TI_SCI This enables the system reset driver support over TI System Control Interface available on some new TI's SoCs.
+config SYSRESET_JR2
- bool "Enable support for Jaguar2 soft reset"
- depends on SOC_JR2
- help
This is soft reset on Jaguar2.
endif
config SYSRESET_SYSCON diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index b3728ac..24c488b 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o obj-$(CONFIG_SYSRESET_X86) += sysreset_x86.o obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o +obj-$(CONFIG_SYSRESET_JR2) += sysreset_jr2.o diff --git a/drivers/sysreset/sysreset_jr2.c b/drivers/sysreset/sysreset_jr2.c new file mode 100644 index 0000000..76a5bac --- /dev/null +++ b/drivers/sysreset/sysreset_jr2.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/*
- Microsemi SoCs pinctrl driver
- Author: horatiu.vultur@microchip.com
- License: Dual MIT/GPL
redundant due to SPDX identifier
- Copyright (c) 2018 Microsemi Corporation
- */
+#include <common.h> +#include <dm.h> +#include <errno.h> +#include <sysreset.h> +#include <linux/err.h> +#include <asm/io.h>
+static int jr2_sysreset_request(struct udevice *dev,
enum sysreset_t type)
+{
- register u32 reg = readl(BASE_CFG + ICPU_GENERAL_CTRL);
register is not required in this context
- /* Set owner */
- reg &= ~ICPU_GENERAL_CTRL_IF_SI_OWNER_M;
- reg |= ICPU_GENERAL_CTRL_IF_SI_OWNER(1);
- /* Set boot mode */
- reg |= ICPU_GENERAL_CTRL_BOOT_MODE_ENA;
- writel(reg, BASE_CFG + ICPU_GENERAL_CTRL);
- /* Read back in order to make BOOT mode setting active */
- reg = readl(BASE_CFG + ICPU_GENERAL_CTRL);
- /* Reset CPU only - still executing _here_. but from cache */
- writel(readl(BASE_CFG + ICPU_RESET) |
ICPU_RESET_CORE_RST_CPU_ONLY |
ICPU_RESET_CORE_RST_FORCE,
BASE_CFG + ICPU_RESET);
- return -EINPROGRESS;
+}
+static struct sysreset_ops jr2_sysreset = {
- .request = jr2_sysreset_request,
+};
+U_BOOT_DRIVER(sysreset_jr2) = {
- .id = UCLASS_SYSRESET,
- .name = "jr2_soft_reset",
- .ops = &jr2_sysreset,
+};
--
- Daniel
participants (2)
-
Daniel Schwierzeck
-
Horatiu Vultur