summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/Kconfig10
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/starfive-pwrseq.c92
3 files changed, 103 insertions, 0 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 87674a2a29..7426dfc463 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -42,4 +42,14 @@ config ACPI_TEST
help
This is a simple Test driver to test the ACPI bus.
+config STARFIVE_PWRSEQ
+ bool "StarFive power sequencing driver"
+ depends on SOC_STARFIVE
+ help
+ This driver sets up a number of StarFive peripherals not matched
+ by more specific barebox drivers by deasserting reset lines, muxing
+ pins and/or enabling clocks. Peripherals set up by this can then
+ be accessed over /dev/mem or used from kernels which still depend
+ on bootloader for initialization.
+
endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 4d92465a1e..36743e6ae6 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_STATE_DRV) += state.o
obj-$(CONFIG_DEV_MEM) += mem.o
obj-$(CONFIG_UBOOTVAR) += ubootvar.o
obj-$(CONFIG_ACPI_TEST) += acpi-test.o
+obj-$(CONFIG_STARFIVE_PWRSEQ) += starfive-pwrseq.o
diff --git a/drivers/misc/starfive-pwrseq.c b/drivers/misc/starfive-pwrseq.c
new file mode 100644
index 0000000000..6236547bc5
--- /dev/null
+++ b/drivers/misc/starfive-pwrseq.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <driver.h>
+#include <init.h>
+#include <linux/reset.h>
+#include <dt-bindings/clock/starfive-jh7100.h>
+#include <linux/clk.h>
+
+struct starfive_pwrseq {
+ const char **names;
+};
+
+static int starfive_pwrseq_probe(struct device_d *dev)
+{
+ int ret;
+
+ ret = device_reset_all(dev);
+ if (ret)
+ return ret;
+
+ return of_platform_populate(dev->device_node, NULL, dev);
+}
+
+static struct of_device_id starfive_pwrseq_dt_ids[] = {
+ { .compatible = "starfive,axi-dma" },
+ { .compatible = "cm,cm521-vpu" },
+ { .compatible = "starfive,vic-sec" },
+ { .compatible = "sfc,tempsensor" },
+ { .compatible = "cm,codaj12-jpu-1" },
+ { .compatible = "cdns,xrp" },
+ { .compatible = "starfive,nne50" },
+ { .compatible = "nvidia,nvdla_os_initial" },
+ { .compatible = "starfive,spi2ahb" },
+ { /* sentinel */ }
+};
+
+static struct driver_d starfive_pwrseq_driver = {
+ .name = "starfive_pwrseq",
+ .probe = starfive_pwrseq_probe,
+ .of_compatible = starfive_pwrseq_dt_ids,
+};
+
+static const int clks[] = {
+ CLK_VDEC_AXI, CLK_VDECBRG_MAIN, CLK_VDEC_BCLK, CLK_VDEC_CCLK, CLK_VDEC_APB,
+ CLK_JPEG_AXI, CLK_JPEG_CCLK, CLK_JPEG_APB,
+ CLK_DLA_AXI, CLK_DLANOC_AXI, CLK_DLA_APB, CLK_NNENOC_AXI, CLK_DLASLV_AXI,
+ CLK_VENC_AXI, CLK_VENCBRG_MAIN, CLK_VENC_BCLK, CLK_VENC_CCLK, CLK_VENC_APB,
+ CLK_SGDMA1P_AXI,
+ CLK_DMA2PNOC_AXI, CLK_SGDMA2P_AXI, CLK_SGDMA2P_AHB,
+ CLK_SDIO0_AHB,
+ CLK_SDIO1_AHB,
+ CLK_SPI2AHB_AHB, CLK_SPI2AHB_CORE,
+ CLK_EZMASTER_AHB,
+ CLK_SEC_AHB, CLK_AES, CLK_SHA, CLK_PKA,
+ CLK_UART0_APB, CLK_UART0_CORE,
+ CLK_UART1_APB, CLK_UART1_CORE,
+ CLK_UART2_APB, CLK_UART2_CORE,
+ CLK_UART3_APB, CLK_UART3_CORE,
+ CLK_SPI0_APB, CLK_SPI0_CORE,
+ CLK_SPI1_APB, CLK_SPI1_CORE,
+ CLK_SPI2_APB, CLK_SPI2_CORE,
+ CLK_SPI3_APB, CLK_SPI3_CORE,
+ CLK_I2C0_APB, CLK_I2C0_CORE,
+ CLK_I2C1_APB, CLK_I2C1_CORE,
+ CLK_I2C2_APB, CLK_I2C2_CORE,
+ CLK_I2C3_APB, CLK_I2C3_CORE,
+ CLK_VP6INTC_APB,
+ CLK_TEMP_APB, CLK_TEMP_SENSE,
+
+ CLK_END
+};
+
+static int __init starfive_pwrseq_driver_register(void)
+{
+ struct of_phandle_args clkspec;
+ int i;
+
+ clkspec.args_count = 1;
+ clkspec.np = of_find_compatible_node(NULL, NULL, "starfive,jh7100-clkgen");
+ if (clkspec.np) {
+ for (i = 0; clks[i] != CLK_END; i++) {
+ clkspec.args[0] = clks[i];
+ clk_enable(of_clk_get_from_provider(&clkspec));
+ }
+ }
+
+ return platform_driver_register(&starfive_pwrseq_driver);
+}
+device_initcall(starfive_pwrseq_driver_register);