diff --git a/arch/arm/dts/armada-375.dtsi b/arch/arm/dts/armada-375.dtsi index 62a548a55f3..fdf2d6dbdc8 100644 --- a/arch/arm/dts/armada-375.dtsi +++ b/arch/arm/dts/armada-375.dtsi @@ -384,9 +384,10 @@ interrupts = ; }; - system-controller@18200 { + systemc: system-controller@18200 { compatible = "marvell,armada-375-system-controller"; reg = <0x18200 0x100>; + #reset-cells = <2>; }; gateclk: clock-gating-control@18220 { diff --git a/arch/arm/dts/armada-38x.dtsi b/arch/arm/dts/armada-38x.dtsi index 72c49beb71a..061bd785208 100644 --- a/arch/arm/dts/armada-38x.dtsi +++ b/arch/arm/dts/armada-38x.dtsi @@ -328,6 +328,7 @@ compatible = "marvell,armada-380-system-controller", "marvell,armada-370-xp-system-controller"; reg = <0x18200 0x100>; + #reset-cells = <2>; }; gateclk: clock-gating-control@18220 { diff --git a/arch/arm/dts/armada-xp-98dx3236.dtsi b/arch/arm/dts/armada-xp-98dx3236.dtsi index 5df1d1848db..8369de79afa 100644 --- a/arch/arm/dts/armada-xp-98dx3236.dtsi +++ b/arch/arm/dts/armada-xp-98dx3236.dtsi @@ -136,6 +136,7 @@ systemc: system-controller@18200 { compatible = "marvell,armada-370-xp-system-controller"; reg = <0x18200 0x500>; + #reset-cells = <2>; }; gateclk: clock-gating-control@18220 { diff --git a/arch/arm/dts/armada-xp.dtsi b/arch/arm/dts/armada-xp.dtsi index d856d960227..fb5640bbd93 100644 --- a/arch/arm/dts/armada-xp.dtsi +++ b/arch/arm/dts/armada-xp.dtsi @@ -78,6 +78,7 @@ systemc: system-controller@18200 { compatible = "marvell,armada-370-xp-system-controller"; reg = <0x18200 0x500>; + #reset-cells = <2>; }; gateclk: clock-gating-control@18220 { diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index 7e9c206ed6b..0b2c57e5736 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -21,6 +21,7 @@ else # CONFIG_ARCH_KIRKWOOD obj-y = cpu.o obj-y += dram.o +obj-$(CONFIG_DM_RESET) += system-controller.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_ARMADA_375) += ../../../drivers/ddr/marvell/axp/xor.o obj-$(CONFIG_ARMADA_38X) += ../../../drivers/ddr/marvell/a38x/xor.o diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c new file mode 100644 index 00000000000..ea858b269e8 --- /dev/null +++ b/arch/arm/mach-mvebu/system-controller.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0+ +// (C) 2021 Pali Rohár + +#include +#include +#include +#include + +#define MVEBU_SOC_CONTROL_1_REG 0x4 + +#define MVEBU_PCIE_ID 0 + +struct mvebu_reset_data { + void *base; +}; + +static int mvebu_reset_of_xlate(struct reset_ctl *rst, + struct ofnode_phandle_args *args) +{ + if (args->args_count < 2) + return -EINVAL; + + rst->id = args->args[0]; + rst->data = args->args[1]; + + /* Currently only PCIe is implemented */ + if (rst->id != MVEBU_PCIE_ID) + return -EINVAL; + + /* Four PCIe enable bits are shared across more PCIe links */ + if (!(rst->data >= 0 && rst->data <= 3)) + return -EINVAL; + + return 0; +} + +static int mvebu_reset_request(struct reset_ctl *rst) +{ + return 0; +} + +static int mvebu_reset_free(struct reset_ctl *rst) +{ + return 0; +} + +static int mvebu_reset_assert(struct reset_ctl *rst) +{ + struct mvebu_reset_data *data = dev_get_priv(rst->dev); + + clrbits_32(data->base + MVEBU_SOC_CONTROL_1_REG, BIT(rst->data)); + return 0; +} + +static int mvebu_reset_deassert(struct reset_ctl *rst) +{ + struct mvebu_reset_data *data = dev_get_priv(rst->dev); + + setbits_32(data->base + MVEBU_SOC_CONTROL_1_REG, BIT(rst->data)); + return 0; +} + +static int mvebu_reset_status(struct reset_ctl *rst) +{ + struct mvebu_reset_data *data = dev_get_priv(rst->dev); + + return !(readl(data->base + MVEBU_SOC_CONTROL_1_REG) & BIT(rst->data)); +} + +static int mvebu_reset_of_to_plat(struct udevice *dev) +{ + struct mvebu_reset_data *data = dev_get_priv(dev); + + data->base = (void *)dev_read_addr(dev); + if ((fdt_addr_t)data->base == FDT_ADDR_T_NONE) + return -EINVAL; + + return 0; +} + +static const struct udevice_id mvebu_reset_of_match[] = { + { .compatible = "marvell,armada-370-xp-system-controller" }, + { .compatible = "marvell,armada-375-system-controller" }, + { .compatible = "marvell,armada-380-system-controller" }, + { .compatible = "marvell,armada-390-system-controller" }, + { }, +}; + +static struct reset_ops mvebu_reset_ops = { + .of_xlate = mvebu_reset_of_xlate, + .request = mvebu_reset_request, + .rfree = mvebu_reset_free, + .rst_assert = mvebu_reset_assert, + .rst_deassert = mvebu_reset_deassert, + .rst_status = mvebu_reset_status, +}; + +U_BOOT_DRIVER(mvebu_reset) = { + .name = "mvebu-reset", + .id = UCLASS_RESET, + .of_match = mvebu_reset_of_match, + .of_to_plat = mvebu_reset_of_to_plat, + .priv_auto = sizeof(struct mvebu_reset_data), + .ops = &mvebu_reset_ops, +};