Am 15.01.19 um 17:33 schrieb Horatiu Vultur: > Add sysreset driver for Luton, Ocelot and Jaguar2 SoCs. > > Signed-off-by: Horatiu Vultur <horatiu.vul...@microchip.com> > --- > MAINTAINERS | 1 + > arch/mips/dts/mscc,jr2.dtsi | 7 +- > arch/mips/dts/mscc,luton.dtsi | 10 +++ > arch/mips/dts/mscc,ocelot.dtsi | 5 ++ > board/mscc/ocelot/ocelot.c | 20 +++++ > configs/mscc_jr2_defconfig | 2 + > configs/mscc_luton_defconfig | 2 + > configs/mscc_ocelot_defconfig | 2 + > drivers/sysreset/Kconfig | 6 ++ > drivers/sysreset/Makefile | 1 + > drivers/sysreset/sysreset_mscc.c | 157 > +++++++++++++++++++++++++++++++++++++++ > 11 files changed, 212 insertions(+), 1 deletion(-) > create mode 100644 drivers/sysreset/sysreset_mscc.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index 3fa5d3e..fb1b69b 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -527,6 +527,7 @@ F: board/mscc/ > F: configs/mscc* > F: drivers/gpio/mscc_sgpio.c > F: drivers/spi/mscc_bb_spi.c > +F: drivers/sysreset/sysreset_mscc.c > F: include/configs/vcoreiii.h > F: drivers/pinctrl/mscc/ > > diff --git a/arch/mips/dts/mscc,jr2.dtsi b/arch/mips/dts/mscc,jr2.dtsi > index 0900926..86d1378 100644 > --- a/arch/mips/dts/mscc,jr2.dtsi > +++ b/arch/mips/dts/mscc,jr2.dtsi > @@ -52,7 +52,12 @@ > interrupt-parent = <&intc>; > > cpu_ctrl: syscon@0 { > - compatible = "mscc,jr2-cpu-syscon", "syscon"; > + compatible = "mscc,jaguar2-cpu-syscon", "syscon"; > + reg = <0x0 0x2c>; > + }; > + > + sysreset: sysreset@0 { > + compatible = "mscc,jaguar2-chip-reset"; > reg = <0x0 0x2c>; > }; > > diff --git a/arch/mips/dts/mscc,luton.dtsi b/arch/mips/dts/mscc,luton.dtsi > index d11ec48..7cbb53b 100644 > --- a/arch/mips/dts/mscc,luton.dtsi > +++ b/arch/mips/dts/mscc,luton.dtsi > @@ -42,6 +42,16 @@ > #size-cells = <1>; > ranges = <0 0x60000000 0x10200000>; > > + cpu_ctrl: syscon@0 { > + compatible = "mscc,luton-cpu-syscon", "syscon"; > + reg = <0x0 0x2c>; > + }; > + > + sysreset: sysreset@70090 { > + compatible = "mscc,luton-chip-reset"; > + reg = <0x70090 0x2c>; > + }; > + > uart0: serial@10100000 { > pinctrl-0 = <&uart_pins>; > pinctrl-names = "default"; > diff --git a/arch/mips/dts/mscc,ocelot.dtsi b/arch/mips/dts/mscc,ocelot.dtsi > index 2592003..4287117 100644 > --- a/arch/mips/dts/mscc,ocelot.dtsi > +++ b/arch/mips/dts/mscc,ocelot.dtsi > @@ -62,6 +62,11 @@ > reg = <0x0 0x2c>; > }; > > + sysreset: sysreset@1070008 { > + compatible = "mscc,ocelot-chip-reset"; > + reg = <0x1070008 0x4>; > + }; > + > intc: interrupt-controller@70 { > compatible = "mscc,ocelot-icpu-intr"; > reg = <0x70 0x70>; > diff --git a/board/mscc/ocelot/ocelot.c b/board/mscc/ocelot/ocelot.c > index 0f7a532..ae5eb4d 100644 > --- a/board/mscc/ocelot/ocelot.c > +++ b/board/mscc/ocelot/ocelot.c > @@ -10,6 +10,7 @@ > #include <environment.h> > #include <spi.h> > #include <led.h> > +#include <sysreset.h> > > DECLARE_GLOBAL_DATA_PTR; > > @@ -25,6 +26,25 @@ void board_debug_uart_init(void) > mscc_gpio_set_alternate(7, 1); > } > > +__weak int ocelot_sysreset_request(struct udevice *dev, > + enum sysreset_t type) > +{ > + u32 resetbits = PERF_SOFT_RST_SOFT_CHIP_RST; > + (void)readl(BASE_DEVCPU_GCB + PERF_SOFT_RST); > + > + /* Make sure VCore is NOT protected from reset */ > + clrbits_le32(BASE_CFG + ICPU_RESET, ICPU_RESET_CORE_RST_PROTECT); > + > + /* Change to SPI bitbang for SPI reset workaround... */ > + writel(ICPU_SW_MODE_SW_SPI_CS_OE(1) | ICPU_SW_MODE_SW_SPI_CS(1) | > + ICPU_SW_MODE_SW_PIN_CTRL_MODE, BASE_CFG + ICPU_SW_MODE); > + > + /* Do the global reset */ > + writel(resetbits, BASE_DEVCPU_GCB + PERF_SOFT_RST); > + > + return -EINPROGRESS; > +}
is this a difference between Luton and Ocelot or only for one board based on Ocelot platform? I'm asking because you register the same sysreset_request for Luton and Ocelot but for Ocelot you override it again with an Ocelot board-specific function. This looks a little bit strange ;) > + > int board_early_init_r(void) > { > /* Prepare SPI controller to be used in master mode */ > diff --git a/configs/mscc_jr2_defconfig b/configs/mscc_jr2_defconfig > index b215754..0992185 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_MSCC=y > diff --git a/configs/mscc_luton_defconfig b/configs/mscc_luton_defconfig > index 7154e97..7c94a76 100644 > --- a/configs/mscc_luton_defconfig > +++ b/configs/mscc_luton_defconfig > @@ -69,3 +69,5 @@ CONFIG_SPI=y > CONFIG_DM_SPI=y > CONFIG_MSCC_BB_SPI=y > CONFIG_LZMA=y > +CONFIG_SYSRESET=y > +CONFIG_SYSRESET_MSCC=y > diff --git a/configs/mscc_ocelot_defconfig b/configs/mscc_ocelot_defconfig > index fb6a5bd..7d9abb6 100644 > --- a/configs/mscc_ocelot_defconfig > +++ b/configs/mscc_ocelot_defconfig > @@ -69,3 +69,5 @@ CONFIG_SYS_NS16550=y > CONFIG_SPI=y > CONFIG_DM_SPI=y > CONFIG_LZMA=y > +CONFIG_SYSRESET=y > +CONFIG_SYSRESET_MSCC=y > diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig > index 8ce3e2e..e25b3cb 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_MSCC > + bool "Enable support for Ocelot soft reset" > + depends on ARCH_MSCC > + help > + This is soft reset on Ocelot. > + > endif > > config SYSRESET_SYSCON > diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile > index b3728ac..a7f2a73 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_MSCC) += sysreset_mscc.o > diff --git a/drivers/sysreset/sysreset_mscc.c > b/drivers/sysreset/sysreset_mscc.c > new file mode 100644 > index 0000000..ea3757f > --- /dev/null > +++ b/drivers/sysreset/sysreset_mscc.c > @@ -0,0 +1,157 @@ > +// SPDX-License-Identifier: (GPL-2.0 OR MIT) > +/* > + * Microsemi SoCs sysreset driver > + * > + * Author: <horatiu.vul...@microchip.com> > + * 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> > + > +struct mscc_sysreset_priv { > + u32 __iomem *regs; > + u32 cpu; > +}; > + > +enum { > + REG_GCB_SOFT_RST, > + REG_ICPU_RESET, > + REG_ICPU_GENERAL_CTRL, > + MAXREG, > +}; > + > +struct mscc_sysreset_bf { > + u8 beg; > + u8 end; > +}; > + > +struct mscc_sysreset_data { > + u8 regoff[MAXREG]; > + struct mscc_sysreset_bf cpu_ctrl_si_owner; > + int (*request_func)(struct udevice *dev, enum sysreset_t type); > +}; > + > +#define __M(bf) GENMASK((bf).end, (bf).beg) > +#define __F(bf, x) (__M(bf) & ((x) << (bf).beg)) > + > +#define MSCC_F_CPU_CTRL_SI_OWNER(d, x) __F(d->cpu_ctrl_si_owner, x) > + > +__weak int ocelot_sysreset_request(struct udevice *dev, > + enum sysreset_t type) > +{ > + const struct mscc_sysreset_priv *priv = dev_get_priv(dev); > + const struct mscc_sysreset_data *data = > + (const struct mscc_sysreset_data *)dev_get_driver_data(dev); > + void __iomem *cpu = (void __iomem *)priv->cpu; > + > + (void)readl(priv->regs + data->regoff[REG_GCB_SOFT_RST]); > + > + /* Make sure VCore is NOT protected from reset */ > + clrbits_le32(cpu + data->regoff[REG_ICPU_RESET], > + ICPU_RESET_CORE_RST_PROTECT); > + > + /* Do the global reset */ > + writel(PERF_SOFT_RST_SOFT_CHIP_RST, > + priv->regs + data->regoff[REG_GCB_SOFT_RST]); > + > + return -EINPROGRESS; > +} > + > +int jr2_sysreset_request(struct udevice *dev, > + enum sysreset_t type) > +{ > + const struct mscc_sysreset_priv *priv = dev_get_priv(dev); > + const struct mscc_sysreset_data *data = > + (const struct mscc_sysreset_data *)dev_get_driver_data(dev); > + void __iomem *cpu = (void __iomem *)priv->cpu; > + > + u32 reg = readl(cpu + data->regoff[REG_ICPU_GENERAL_CTRL]); > + > + /* Set owner and boot mode */ > + reg |= MSCC_F_CPU_CTRL_SI_OWNER(data, 1) | > + ICPU_GENERAL_CTRL_BOOT_MODE_ENA; > + writel(reg, cpu + data->regoff[REG_ICPU_GENERAL_CTRL]); > + > + /* Read back in order to make BOOT mode setting active */ > + (void)readl(cpu + data->regoff[REG_ICPU_GENERAL_CTRL]); > + > + /* Reset CPU only - still executing _here_. but from cache */ > + writel(readl(cpu + data->regoff[REG_ICPU_RESET]) | > + ICPU_RESET_CORE_RST_CPU_ONLY | > + ICPU_RESET_CORE_RST_FORCE, > + cpu + data->regoff[REG_ICPU_RESET]); > + > + return -EINPROGRESS; > +} > + > +static const struct mscc_sysreset_data ocelot_sysreset_data = { > + .regoff = {0x08, 0x20, 0x24}, > + .cpu_ctrl_si_owner = { 4, 5 }, > + .request_func = ocelot_sysreset_request, > +}; > + > +static const struct mscc_sysreset_data luton_sysreset_data = { > + .regoff = {0x00, 0x20, 0x24}, > + .cpu_ctrl_si_owner = { 0, 0 }, > + .request_func = ocelot_sysreset_request, > +}; > + > +static const struct mscc_sysreset_data jr2_sysreset_data = { > + .regoff = {0x08, 0x20, 0x24}, > + .cpu_ctrl_si_owner = { 6, 7 }, > + .request_func = jr2_sysreset_request, > +}; > + > +static int mscc_sysreset_request(struct udevice *dev, > + enum sysreset_t type) > +{ > + const struct mscc_sysreset_data *data = > + (const struct mscc_sysreset_data *)dev_get_driver_data(dev); > + return data->request_func(dev, type); > +} > + > +static int mscc_probe(struct udevice *dev) > +{ > + struct mscc_sysreset_priv *priv = dev_get_priv(dev); > + int node; > + > + priv->regs = (u32 __iomem *)dev_read_addr(dev); > + node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "syscon"); > + priv->cpu = ofnode_get_addr(offset_to_ofnode(node)); > + > + return 0; > +} > + > +static const struct sysreset_ops mscc_sysreset = { > + .request = mscc_sysreset_request, > +}; > + > +static const struct udevice_id mscc_sysreset_ids[] = { > + { > + .compatible = "mscc,ocelot-chip-reset", > + .data = (ulong)&ocelot_sysreset_data > + }, > + { > + .compatible = "mscc,luton-chip-reset", > + .data = (ulong)&luton_sysreset_data > + }, > + { > + .compatible = "mscc,jaguar2-chip-reset", > + .data = (ulong)&jr2_sysreset_data > + }, > + { } > +}; > + > +U_BOOT_DRIVER(sysreset_ocelot) = { > + .name = "mscc-chip-reset", > + .id = UCLASS_SYSRESET, > + .of_match = mscc_sysreset_ids, > + .ops = &mscc_sysreset, > + .probe = mscc_probe, > + .priv_auto_alloc_size = sizeof(struct mscc_sysreset_priv), > +}; > -- - Daniel _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot