Hi Daniel, The 01/16/2019 15:22, Daniel Schwierzeck wrote: > > > 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 ;) >
There is no difference between the Luton and Ocelot regarding reset, but there is an issue on boards based on Ocelot platform. So that's the reason I marked the function as weak and overwrite it in Ocelot board. > > + > > 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 -- /Horatiu _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot