diff options
-rw-r--r-- | drivers/misc/Kconfig | 10 | ||||
-rw-r--r-- | drivers/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/starfive-pwrseq.c | 92 |
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); |