summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/dts/armada-375.dtsi3
-rw-r--r--arch/arm/dts/armada-38x.dtsi1
-rw-r--r--arch/arm/dts/armada-xp-98dx3236.dtsi1
-rw-r--r--arch/arm/dts/armada-xp.dtsi1
-rw-r--r--arch/arm/mach-mvebu/Makefile1
-rw-r--r--arch/arm/mach-mvebu/system-controller.c105
6 files changed, 111 insertions, 1 deletions
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 = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
};
- 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 <pali@kernel.org>
+
+#include <common.h>
+#include <dm.h>
+#include <reset-uclass.h>
+#include <asm/io.h>
+
+#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,
+};