[U-Boot] [PATCH 0/2] MSCC: Add sysreset driver for MSCC SoCs

This patch series adds sysreset drivers for MSCC SoCs. There are 3 drivers: sysreset_jr2, sysreset_ocelot and sysreset_luton.
This is based off the u-boot-mips/next repository.
Horatiu Vultur (2): MSCC: Add sysreset drivers for MSCC Socs MSCC: Remove reset.c
MAINTAINERS | 1 + arch/mips/dts/mscc,jr2.dtsi | 7 +- arch/mips/dts/mscc,luton.dtsi | 10 +++ arch/mips/dts/mscc,ocelot.dtsi | 5 ++ arch/mips/mach-mscc/Makefile | 2 +- arch/mips/mach-mscc/include/mach/ddr.h | 18 +++- arch/mips/mach-mscc/reset.c | 47 ---------- 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 +++++++++++++++++++++++++++++++++ 14 files changed, 230 insertions(+), 50 deletions(-) delete mode 100644 arch/mips/mach-mscc/reset.c create mode 100644 drivers/sysreset/sysreset_mscc.c

Add sysreset driver for Luton, Ocelot and Jaguar2 SoCs.
Signed-off-by: Horatiu Vultur horatiu.vultur@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; +} + 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.vultur@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), +};

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.vultur@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.vultur@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),
+};

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.vultur@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.vultur@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

Remove reset.c because it is not used anymore. It is superseed by sysreset driver.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com --- arch/mips/mach-mscc/Makefile | 2 +- arch/mips/mach-mscc/include/mach/ddr.h | 18 ++++++++++++- arch/mips/mach-mscc/reset.c | 47 ---------------------------------- 3 files changed, 18 insertions(+), 49 deletions(-) delete mode 100644 arch/mips/mach-mscc/reset.c
diff --git a/arch/mips/mach-mscc/Makefile b/arch/mips/mach-mscc/Makefile index f5b6968..349e889 100644 --- a/arch/mips/mach-mscc/Makefile +++ b/arch/mips/mach-mscc/Makefile @@ -2,6 +2,6 @@
CFLAGS_cpu.o += -finline-limit=64000
-obj-y += cpu.o dram.o reset.o phy.o lowlevel_init.o +obj-y += cpu.o dram.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/arch/mips/mach-mscc/include/mach/ddr.h b/arch/mips/mach-mscc/include/mach/ddr.h index 7552acb..a2d20db 100644 --- a/arch/mips/mach-mscc/include/mach/ddr.h +++ b/arch/mips/mach-mscc/include/mach/ddr.h @@ -415,6 +415,22 @@ static inline void hal_vcoreiii_ddr_reset_release(void) sleep_100ns(10000); }
+static void ocelot_restart(void) +{ + register 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); +} + /* * DDR memory sanity checking failed, tally and do hard reset * @@ -443,7 +459,7 @@ static inline void hal_vcoreiii_ddr_failed(void) * MIPS CPU (and the cache), and the CPU will start executing * from the reset vector. */ - reset = KSEG0ADDR(_machine_restart); + reset = KSEG0ADDR(ocelot_restart); icache_lock((void *)reset, 128); asm volatile ("jr %0"::"r" (reset));
diff --git a/arch/mips/mach-mscc/reset.c b/arch/mips/mach-mscc/reset.c deleted file mode 100644 index e0e610a..0000000 --- a/arch/mips/mach-mscc/reset.c +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -/* - * Copyright (c) 2018 Microsemi Corporation - */ - -#include <common.h> - -#include <asm/sections.h> -#include <asm/io.h> - -#include <asm/reboot.h> - -void _machine_restart(void) -{ -#if defined(CONFIG_SOC_JR2) - 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); -#else - register 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); -#endif - - while (1) - ; /* NOP */ -}

Am 15.01.19 um 17:33 schrieb Horatiu Vultur:
Remove reset.c because it is not used anymore. It is superseed by sysreset driver.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com
arch/mips/mach-mscc/Makefile | 2 +- arch/mips/mach-mscc/include/mach/ddr.h | 18 ++++++++++++- arch/mips/mach-mscc/reset.c | 47 ---------------------------------- 3 files changed, 18 insertions(+), 49 deletions(-) delete mode 100644 arch/mips/mach-mscc/reset.c
diff --git a/arch/mips/mach-mscc/Makefile b/arch/mips/mach-mscc/Makefile index f5b6968..349e889 100644 --- a/arch/mips/mach-mscc/Makefile +++ b/arch/mips/mach-mscc/Makefile @@ -2,6 +2,6 @@
CFLAGS_cpu.o += -finline-limit=64000
-obj-y += cpu.o dram.o reset.o phy.o lowlevel_init.o +obj-y += cpu.o dram.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/arch/mips/mach-mscc/include/mach/ddr.h b/arch/mips/mach-mscc/include/mach/ddr.h index 7552acb..a2d20db 100644 --- a/arch/mips/mach-mscc/include/mach/ddr.h +++ b/arch/mips/mach-mscc/include/mach/ddr.h @@ -415,6 +415,22 @@ static inline void hal_vcoreiii_ddr_reset_release(void) sleep_100ns(10000); }
+static void ocelot_restart(void) +{
- register 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);
+}
/*
- DDR memory sanity checking failed, tally and do hard reset
@@ -443,7 +459,7 @@ static inline void hal_vcoreiii_ddr_failed(void) * MIPS CPU (and the cache), and the CPU will start executing * from the reset vector. */
- reset = KSEG0ADDR(_machine_restart);
- reset = KSEG0ADDR(ocelot_restart);
ah I didn't thought about that when suggesting a sysreset driver.Then it's maybe not a good idea at all. Or you export a function declaration like mscc_cpu_reset(void) and implement it for each MSCC SoC. You could call this still in hal_vcoreiii_ddr_failed() context. The sysreset driver then simply wraps this function. But then it's not really worth the overhead. Sorry for the troubles ;)
icache_lock((void *)reset, 128); asm volatile ("jr %0"::"r" (reset));
diff --git a/arch/mips/mach-mscc/reset.c b/arch/mips/mach-mscc/reset.c deleted file mode 100644 index e0e610a..0000000 --- a/arch/mips/mach-mscc/reset.c +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -/*
- Copyright (c) 2018 Microsemi Corporation
- */
-#include <common.h>
-#include <asm/sections.h> -#include <asm/io.h>
-#include <asm/reboot.h>
-void _machine_restart(void) -{ -#if defined(CONFIG_SOC_JR2)
- 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);
-#else
- register 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);
-#endif
- while (1)
; /* NOP */
-}

Hi Daniel,
The 01/16/2019 15:35, Daniel Schwierzeck wrote:
Am 15.01.19 um 17:33 schrieb Horatiu Vultur:
Remove reset.c because it is not used anymore. It is superseed by sysreset driver.
Signed-off-by: Horatiu Vultur horatiu.vultur@microchip.com
arch/mips/mach-mscc/Makefile | 2 +- arch/mips/mach-mscc/include/mach/ddr.h | 18 ++++++++++++- arch/mips/mach-mscc/reset.c | 47 ---------------------------------- 3 files changed, 18 insertions(+), 49 deletions(-) delete mode 100644 arch/mips/mach-mscc/reset.c
diff --git a/arch/mips/mach-mscc/Makefile b/arch/mips/mach-mscc/Makefile index f5b6968..349e889 100644 --- a/arch/mips/mach-mscc/Makefile +++ b/arch/mips/mach-mscc/Makefile @@ -2,6 +2,6 @@
CFLAGS_cpu.o += -finline-limit=64000
-obj-y += cpu.o dram.o reset.o phy.o lowlevel_init.o +obj-y += cpu.o dram.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/arch/mips/mach-mscc/include/mach/ddr.h b/arch/mips/mach-mscc/include/mach/ddr.h index 7552acb..a2d20db 100644 --- a/arch/mips/mach-mscc/include/mach/ddr.h +++ b/arch/mips/mach-mscc/include/mach/ddr.h @@ -415,6 +415,22 @@ static inline void hal_vcoreiii_ddr_reset_release(void) sleep_100ns(10000); }
+static void ocelot_restart(void) +{
- register 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);
+}
/*
- DDR memory sanity checking failed, tally and do hard reset
@@ -443,7 +459,7 @@ static inline void hal_vcoreiii_ddr_failed(void) * MIPS CPU (and the cache), and the CPU will start executing * from the reset vector. */
- reset = KSEG0ADDR(_machine_restart);
- reset = KSEG0ADDR(ocelot_restart);
ah I didn't thought about that when suggesting a sysreset driver.Then it's maybe not a good idea at all. Or you export a function declaration like mscc_cpu_reset(void) and implement it for each MSCC SoC. You could call this still in hal_vcoreiii_ddr_failed() context. The sysreset driver then simply wraps this function. But then it's not really worth the overhead. Sorry for the troubles ;)
No problem, thanks for all the feedback :) One thingy is that after the patch[1] is accepted, I would like to send a new patch series for a new SoC. And this new SoC has a different reset mechanism which means that I need to put another #ifdef inside _machine_restart.
For me it is perfectly fine not to accept this patch series and after I send the new patch series for new SoC to have another look at the function _machine_restart.
[1] https://lists.denx.de/pipermail/u-boot/2019-January/354812.html
icache_lock((void *)reset, 128); asm volatile ("jr %0"::"r" (reset));
diff --git a/arch/mips/mach-mscc/reset.c b/arch/mips/mach-mscc/reset.c deleted file mode 100644 index e0e610a..0000000 --- a/arch/mips/mach-mscc/reset.c +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -/*
- Copyright (c) 2018 Microsemi Corporation
- */
-#include <common.h>
-#include <asm/sections.h> -#include <asm/io.h>
-#include <asm/reboot.h>
-void _machine_restart(void) -{ -#if defined(CONFIG_SOC_JR2)
- 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);
-#else
- register 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);
-#endif
- while (1)
; /* NOP */
-}
--
- Daniel
participants (2)
-
Daniel Schwierzeck
-
Horatiu Vultur