aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/dts/sama5d2.dtsi74
-rw-r--r--arch/arm/mach-meson/board-info.c10
-rw-r--r--arch/arm/mach-rockchip/rk3288/rk3288.c2
-rw-r--r--arch/arm/mach-socfpga/clock_manager_agilex.c2
-rw-r--r--arch/arm/mach-socfpga/clock_manager_arria10.c7
-rw-r--r--arch/arm/mach-socfpga/clock_manager_n5x.c2
-rw-r--r--arch/arm/mach-zynq/clk.c2
-rw-r--r--arch/mips/mach-pic32/cpu.c7
-rw-r--r--arch/riscv/Kconfig4
-rw-r--r--arch/riscv/config.mk2
-rw-r--r--arch/riscv/dts/Makefile1
-rw-r--r--arch/riscv/dts/cv1800b-milkv-duo.dts38
-rw-r--r--arch/riscv/dts/cv1800b.dtsi18
-rw-r--r--arch/riscv/dts/cv18xx.dtsi192
-rw-r--r--arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi5
-rw-r--r--arch/riscv/dts/jh7110.dtsi6
-rw-r--r--arch/riscv/include/asm/arch-fu740/eeprom.h15
-rw-r--r--arch/riscv/include/asm/sbi.h1
-rw-r--r--arch/sandbox/include/asm/clk.h8
-rw-r--r--board/AndesTech/ae350/ae350.c25
-rw-r--r--board/microchip/pic32mzda/pic32mzda.c2
-rw-r--r--board/sifive/unmatched/spl.c52
-rw-r--r--board/sipeed/maix/maix.c1
-rw-r--r--board/sophgo/milkv_duo/Kconfig28
-rw-r--r--board/sophgo/milkv_duo/MAINTAINERS6
-rw-r--r--board/sophgo/milkv_duo/Makefile5
-rw-r--r--board/sophgo/milkv_duo/board.c9
-rw-r--r--board/starfive/visionfive2/spl.c12
-rw-r--r--board/synopsys/hsdk/clk-lib.c2
-rw-r--r--cmd/riscv/sbi.c1
-rw-r--r--cmd/smbios.c20
-rw-r--r--common/spl/Kconfig2
-rw-r--r--common/spl/spl_opensbi.c15
-rw-r--r--configs/ae350_rv32_defconfig4
-rw-r--r--configs/ae350_rv32_falcon_defconfig1
-rw-r--r--configs/ae350_rv32_falcon_xip_defconfig1
-rw-r--r--configs/ae350_rv32_spl_defconfig4
-rw-r--r--configs/ae350_rv32_spl_xip_defconfig4
-rw-r--r--configs/ae350_rv32_xip_defconfig4
-rw-r--r--configs/ae350_rv64_defconfig4
-rw-r--r--configs/ae350_rv64_falcon_defconfig1
-rw-r--r--configs/ae350_rv64_falcon_xip_defconfig1
-rw-r--r--configs/ae350_rv64_spl_defconfig4
-rw-r--r--configs/ae350_rv64_spl_xip_defconfig4
-rw-r--r--configs/ae350_rv64_xip_defconfig4
-rw-r--r--configs/milkv_duo_defconfig23
-rw-r--r--configs/starfive_visionfive2_defconfig1
-rw-r--r--doc/board/index.rst1
-rw-r--r--doc/board/sophgo/index.rst8
-rw-r--r--doc/board/sophgo/milkv_duo.rst64
-rw-r--r--doc/develop/falcon.rst158
-rw-r--r--drivers/clk/aspeed/clk_ast2600.c2
-rw-r--r--drivers/clk/at91/compat.c14
-rw-r--r--drivers/clk/clk-gpio.c38
-rw-r--r--drivers/clk/clk-uclass.c47
-rw-r--r--drivers/clk/clk-xlnx-clock-wizard.c1
-rw-r--r--drivers/clk/clk_sandbox.c12
-rw-r--r--drivers/clk/clk_sandbox_test.c12
-rw-r--r--drivers/clk/clk_versaclock.c12
-rw-r--r--drivers/clk/clk_zynq.c2
-rw-r--r--drivers/clk/clk_zynqmp.c2
-rw-r--r--drivers/clk/imx/clk-imx8.c2
-rw-r--r--drivers/clk/meson/Kconfig10
-rw-r--r--drivers/clk/meson/Makefile1
-rw-r--r--drivers/clk/meson/clk-measure.c634
-rw-r--r--drivers/clk/mvebu/armada-37xx-periph.c2
-rw-r--r--drivers/cpu/riscv_cpu.c14
-rw-r--r--drivers/dma/bcm6348-iudma.c2
-rw-r--r--drivers/gpio/at91_gpio.c2
-rw-r--r--drivers/gpio/atmel_pio4.c2
-rw-r--r--drivers/gpio/gpio-rcar.c1
-rw-r--r--drivers/hwspinlock/stm32_hwspinlock.c6
-rw-r--r--drivers/i2c/at91_i2c.c2
-rw-r--r--drivers/i2c/designware_i2c.c2
-rw-r--r--drivers/i2c/i2c-microchip.c2
-rw-r--r--drivers/i2c/npcm_i2c.c1
-rw-r--r--drivers/i2c/ocores_i2c.c2
-rw-r--r--drivers/i2c/stm32f7_i2c.c4
-rw-r--r--drivers/mailbox/stm32-ipcc.c7
-rw-r--r--drivers/misc/ls2_sfp.c1
-rw-r--r--drivers/misc/qfw_smbios.c2
-rw-r--r--drivers/mmc/arm_pl180_mmci.c1
-rw-r--r--drivers/mmc/aspeed_sdhci.c4
-rw-r--r--drivers/mmc/atmel_sdhci.c2
-rw-r--r--drivers/mmc/gen_atmel_mci.c19
-rw-r--r--drivers/mmc/msm_sdhci.c1
-rw-r--r--drivers/mmc/pic32_sdhci.c1
-rw-r--r--drivers/mmc/renesas-sdhi.c21
-rw-r--r--drivers/mmc/snps_dw_mmc.c8
-rw-r--r--drivers/mmc/socfpga_dw_mmc.c1
-rw-r--r--drivers/mmc/stm32_sdmmc2.c4
-rw-r--r--drivers/mmc/uniphier-sd.c1
-rw-r--r--drivers/mtd/nand/raw/atmel/nand-controller.c4
-rw-r--r--drivers/mtd/nand/raw/atmel/pmecc.c3
-rw-r--r--drivers/mtd/renesas_rpc_hf.c1
-rw-r--r--drivers/net/bcm6348-eth.c2
-rw-r--r--drivers/net/bcm6368-eth.c2
-rw-r--r--drivers/net/designware.c1
-rw-r--r--drivers/net/dwc_eth_qos.c43
-rw-r--r--drivers/net/dwc_eth_qos_imx.c21
-rw-r--r--drivers/net/dwc_eth_qos_qcom.c1
-rw-r--r--drivers/net/dwc_eth_qos_rockchip.c6
-rw-r--r--drivers/net/phy/motorcomm.c130
-rw-r--r--drivers/net/sni_ave.c5
-rw-r--r--drivers/net/ti/am65-cpsw-nuss.c1
-rw-r--r--drivers/phy/bcm6318-usbh-phy.c2
-rw-r--r--drivers/phy/bcm6348-usbh-phy.c2
-rw-r--r--drivers/phy/bcm6368-usbh-phy.c4
-rw-r--r--drivers/phy/meson-axg-mipi-dphy.c1
-rw-r--r--drivers/phy/meson-g12a-usb3-pcie.c1
-rw-r--r--drivers/phy/meson-gxl-usb2.c1
-rw-r--r--drivers/phy/phy-rcar-gen2.c1
-rw-r--r--drivers/phy/phy-rcar-gen3.c1
-rw-r--r--drivers/pinctrl/pinctrl-k210.c20
-rw-r--r--drivers/power/domain/imx8mp-hsiomix.c4
-rw-r--r--drivers/rtc/stm32_rtc.c16
-rw-r--r--drivers/serial/atmel_usart.c2
-rw-r--r--drivers/serial/serial_bcm6345.c1
-rw-r--r--drivers/serial/serial_msm.c1
-rw-r--r--drivers/serial/serial_pic32.c1
-rw-r--r--drivers/spi/atcspi200_spi.c1
-rw-r--r--drivers/spi/atmel-quadspi.c14
-rw-r--r--drivers/spi/atmel_spi.c2
-rw-r--r--drivers/spi/bcm63xx_hsspi.c4
-rw-r--r--drivers/spi/bcm63xx_spi.c2
-rw-r--r--drivers/spi/bcmbca_hsspi.c4
-rw-r--r--drivers/spi/cadence_qspi.c1
-rw-r--r--drivers/spi/designware_spi.c5
-rw-r--r--drivers/spi/meson_spifc_a1.c10
-rw-r--r--drivers/spi/mvebu_a3700_spi.c10
-rw-r--r--drivers/spi/spi-aspeed-smc.c1
-rw-r--r--drivers/spi/stm32_spi.c19
-rw-r--r--drivers/timer/dw-apb-timer.c2
-rw-r--r--drivers/timer/ostm_timer.c2
-rw-r--r--drivers/usb/dwc3/dwc3-meson-g12a.c4
-rw-r--r--drivers/usb/dwc3/dwc3-meson-gxl.c4
-rw-r--r--drivers/usb/host/ehci-atmel.c8
-rw-r--r--drivers/usb/host/ohci-da8xx.c1
-rw-r--r--drivers/usb/host/xhci-rcar.c5
-rw-r--r--drivers/video/atmel_hlcdfb.c2
-rw-r--r--drivers/video/mali_dp.c11
-rw-r--r--drivers/video/rockchip/rk3288_hdmi.c4
-rw-r--r--drivers/video/rockchip/rk_edp.c8
-rw-r--r--drivers/watchdog/Kconfig6
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/atcwdt200_wdt.c220
-rw-r--r--drivers/watchdog/designware_wdt.c18
-rw-r--r--drivers/watchdog/meson_gxbb_wdt.c4
-rw-r--r--include/clk-uclass.h123
-rw-r--r--include/clk.h31
-rw-r--r--include/configs/milkv_duo.h12
-rw-r--r--include/configs/qemu-riscv.h1
-rw-r--r--include/smbios.h2
-rw-r--r--lib/efi_loader/efi_tcg2.c4
-rw-r--r--lib/efi_loader/smbiosdump.c6
-rw-r--r--lib/smbios-parser.c4
-rw-r--r--lib/smbios.c49
-rw-r--r--test/dm/clk.c9
158 files changed, 2048 insertions, 615 deletions
diff --git a/arch/arm/dts/sama5d2.dtsi b/arch/arm/dts/sama5d2.dtsi
index 819564f..7b62fff 100644
--- a/arch/arm/dts/sama5d2.dtsi
+++ b/arch/arm/dts/sama5d2.dtsi
@@ -34,6 +34,15 @@
#size-cells = <1>;
bootph-all;
+ nfc_sram: sram@100000 {
+ compatible = "mmio-sram";
+ no-memory-wc;
+ reg = <0x00100000 0x2400>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x00100000 0x2400>;
+ };
+
usb1: ohci@400000 {
compatible = "atmel,at91rm9200-ohci", "usb-ohci";
reg = <0x00400000 0x100000>;
@@ -50,6 +59,32 @@
status = "disabled";
};
+ ebi: ebi@10000000 {
+ compatible = "atmel,sama5d3-ebi";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ atmel,smc = <&hsmc>;
+ reg = <0x10000000 0x10000000
+ 0x60000000 0x30000000>;
+ ranges = <0x0 0x0 0x10000000 0x10000000
+ 0x1 0x0 0x60000000 0x10000000
+ 0x2 0x0 0x70000000 0x10000000
+ 0x3 0x0 0x80000000 0x10000000>;
+ clocks = <&h32ck>;
+ status = "disabled";
+
+ nand_controller: nand-controller {
+ compatible = "atmel,sama5d3-nand-controller";
+ atmel,nfc-sram = <&nfc_sram>;
+ atmel,nfc-io = <&nfc_io>;
+ ecc-engine = <&pmecc>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges;
+ status = "disabled";
+ };
+ };
+
sdmmc0: sdio-host@a0000000 {
compatible = "atmel,sama5d2-sdhci";
reg = <0xa0000000 0x300>;
@@ -66,6 +101,11 @@
status = "disabled";
};
+ nfc_io: nfc-io@c0000000 {
+ compatible = "atmel,sama5d3-nfc-io", "syscon";
+ reg = <0xc0000000 0x8000000>;
+ };
+
apb {
compatible = "simple-bus";
#address-cells = <1>;
@@ -79,7 +119,7 @@
status = "disabled";
};
- pmc: pmc@f0014000 {
+ pmc: clock-controller@f0014000 {
compatible = "atmel,sama5d2-pmc", "syscon";
reg = <0xf0014000 0x160>;
#address-cells = <1>;
@@ -657,6 +697,22 @@
};
};
+ hsmc: hsmc@f8014000 {
+ compatible = "atmel,sama5d2-smc", "syscon", "simple-mfd";
+ reg = <0xf8014000 0x1000>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH 6>;
+ clocks = <&hsmc_clk>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pmecc: ecc-engine@f8014070 {
+ compatible = "atmel,sama5d2-pmecc";
+ reg = <0xf8014070 0x490>,
+ <0xf8014500 0x200>;
+ };
+ };
+
uart0: serial@f801c000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xf801c000 0x100>;
@@ -698,13 +754,18 @@
status = "disabled";
};
- rstc@f8048000 {
+ sfr: sfr@f8030000 {
+ compatible = "atmel,sama5d2-sfr", "syscon";
+ reg = <0xf8030000 0x98>;
+ };
+
+ reset_controller: reset-controller@f8048000 {
compatible = "atmel,sama5d3-rstc";
reg = <0xf8048000 0x10>;
clocks = <&clk32k>;
};
- shdwc@f8048010 {
+ shutdown_controller: poweroff@f8048010 {
compatible = "atmel,sama5d2-shdwc";
reg = <0xf8048010 0x10>;
clocks = <&clk32k>;
@@ -719,18 +780,13 @@
clocks = <&h32ck>;
};
- watchdog@f8048040 {
+ watchdog: watchdog@f8048040 {
compatible = "atmel,sama5d4-wdt";
reg = <0xf8048040 0x10>;
clocks = <&clk32k>;
status = "disabled";
};
- sfr: sfr@f8030000 {
- compatible = "atmel,sama5d2-sfr", "syscon";
- reg = <0xf8030000 0x98>;
- };
-
sckc@f8048050 {
compatible = "atmel,at91sam9x5-sckc";
reg = <0xf8048050 0x4>;
diff --git a/arch/arm/mach-meson/board-info.c b/arch/arm/mach-meson/board-info.c
index 95a29da..d51d9b8 100644
--- a/arch/arm/mach-meson/board-info.c
+++ b/arch/arm/mach-meson/board-info.c
@@ -126,13 +126,6 @@ static const char *socinfo_to_soc_id(u32 socinfo)
return "Unknown";
}
-static void print_board_model(void)
-{
- const char *model;
- model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
- printf("Model: %s\n", model ? model : "Unknown");
-}
-
static unsigned int get_socinfo(void)
{
struct regmap *regmap;
@@ -172,9 +165,6 @@ int checkboard(void)
{
unsigned int socinfo;
- /* print board information */
- print_board_model();
-
socinfo = get_socinfo();
if (!socinfo)
return 0;
diff --git a/arch/arm/mach-rockchip/rk3288/rk3288.c b/arch/arm/mach-rockchip/rk3288/rk3288.c
index 26c7e41..d9f782e 100644
--- a/arch/arm/mach-rockchip/rk3288/rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/rk3288.c
@@ -184,8 +184,6 @@ static int do_clock(struct cmd_tbl *cmdtp, int flag, int argc,
rate = clk_get_rate(&clk);
printf("%s: %lu\n", clks[i].name, rate);
-
- clk_free(&clk);
}
return 0;
diff --git a/arch/arm/mach-socfpga/clock_manager_agilex.c b/arch/arm/mach-socfpga/clock_manager_agilex.c
index e035c09..28f593b 100644
--- a/arch/arm/mach-socfpga/clock_manager_agilex.c
+++ b/arch/arm/mach-socfpga/clock_manager_agilex.c
@@ -37,8 +37,6 @@ static ulong cm_get_rate_dm(u32 id)
rate = clk_get_rate(&clk);
- clk_free(&clk);
-
if ((rate == (unsigned long)-ENOSYS) ||
(rate == (unsigned long)-ENXIO) ||
(rate == (unsigned long)-EIO)) {
diff --git a/arch/arm/mach-socfpga/clock_manager_arria10.c b/arch/arm/mach-socfpga/clock_manager_arria10.c
index b48a2b4..8ab18f6 100644
--- a/arch/arm/mach-socfpga/clock_manager_arria10.c
+++ b/arch/arm/mach-socfpga/clock_manager_arria10.c
@@ -962,7 +962,6 @@ static u32 cm_get_rate_dm(char *name)
struct uclass *uc;
struct udevice *dev = NULL;
struct clk clk = { 0 };
- ulong rate;
int ret;
/* Device addresses start at 1 */
@@ -982,11 +981,7 @@ static u32 cm_get_rate_dm(char *name)
if (ret)
return 0;
- rate = clk_get_rate(&clk);
-
- clk_free(&clk);
-
- return rate;
+ return clk_get_rate(&clk);
}
static u32 cm_get_rate_dm_khz(char *name)
diff --git a/arch/arm/mach-socfpga/clock_manager_n5x.c b/arch/arm/mach-socfpga/clock_manager_n5x.c
index 4f09853..0ed480d 100644
--- a/arch/arm/mach-socfpga/clock_manager_n5x.c
+++ b/arch/arm/mach-socfpga/clock_manager_n5x.c
@@ -36,8 +36,6 @@ static ulong cm_get_rate_dm(u32 id)
rate = clk_get_rate(&clk);
- clk_free(&clk);
-
if ((rate == (unsigned long)-ENXIO) ||
(rate == (unsigned long)-EIO)) {
debug("%s id %u: clk_get_rate err: %ld\n",
diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c
index e6a6732..5e1ba8d 100644
--- a/arch/arm/mach-zynq/clk.c
+++ b/arch/arm/mach-zynq/clk.c
@@ -44,8 +44,6 @@ int set_cpu_clk_info(void)
gd->bd->bi_arm_freq = rate;
gd->cpu_clk = clk_get_rate(&clk);
}
-
- clk_free(&clk);
}
gd->bd->bi_dsp_freq = 0;
diff --git a/arch/mips/mach-pic32/cpu.c b/arch/mips/mach-pic32/cpu.c
index 3181a94..668adbb 100644
--- a/arch/mips/mach-pic32/cpu.c
+++ b/arch/mips/mach-pic32/cpu.c
@@ -30,7 +30,6 @@ static ulong rate(int id)
int ret;
struct udevice *dev;
struct clk clk;
- ulong rate;
ret = uclass_get_device(UCLASS_CLK, 0, &dev);
if (ret) {
@@ -43,11 +42,7 @@ static ulong rate(int id)
if (ret < 0)
return ret;
- rate = clk_get_rate(&clk);
-
- clk_free(&clk);
-
- return rate;
+ return clk_get_rate(&clk);
}
static ulong clk_get_cpu_rate(void)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 67126d9..ac52c5e 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -14,6 +14,9 @@ config TARGET_ANDES_AE350
config TARGET_MICROCHIP_ICICLE
bool "Support Microchip PolarFire-SoC Icicle Board"
+config TARGET_MILKV_DUO
+ bool "Support Milk-v Duo Board"
+
config TARGET_OPENPITON_RISCV64
bool "Support RISC-V cores on OpenPiton SoC"
@@ -83,6 +86,7 @@ source "board/openpiton/riscv64/Kconfig"
source "board/sifive/unleashed/Kconfig"
source "board/sifive/unmatched/Kconfig"
source "board/sipeed/maix/Kconfig"
+source "board/sophgo/milkv_duo/Kconfig"
source "board/starfive/visionfive2/Kconfig"
source "board/thead/th1520_lpi4a/Kconfig"
source "board/xilinx/mbv/Kconfig"
diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk
index 9cf2aef..9f16dda 100644
--- a/arch/riscv/config.mk
+++ b/arch/riscv/config.mk
@@ -25,7 +25,7 @@ EFI_LDS := elf_riscv64_efi.lds
PLATFORM_ELFFLAGS += -B riscv -O elf64-littleriscv
endif
-PLATFORM_CPPFLAGS += -ffixed-gp -fpic
+PLATFORM_CPPFLAGS += -ffixed-x3 -fpic
PLATFORM_RELFLAGS += -fno-common -ffunction-sections -fdata-sections
LDFLAGS_u-boot += --gc-sections -static -pie
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
index b05bb56..17cda48 100644
--- a/arch/riscv/dts/Makefile
+++ b/arch/riscv/dts/Makefile
@@ -2,6 +2,7 @@
dtb-$(CONFIG_TARGET_ANDES_AE350) += ae350_32.dtb ae350_64.dtb
dtb-$(CONFIG_TARGET_MICROCHIP_ICICLE) += mpfs-icicle-kit.dtb
+dtb-$(CONFIG_TARGET_MILKV_DUO) += cv1800b-milkv-duo.dtb
dtb-$(CONFIG_TARGET_QEMU_VIRT) += qemu-virt32.dtb qemu-virt64.dtb
dtb-$(CONFIG_TARGET_OPENPITON_RISCV64) += openpiton-riscv64.dtb
dtb-$(CONFIG_TARGET_SIFIVE_UNLEASHED) += hifive-unleashed-a00.dtb
diff --git a/arch/riscv/dts/cv1800b-milkv-duo.dts b/arch/riscv/dts/cv1800b-milkv-duo.dts
new file mode 100644
index 0000000..3af9e34
--- /dev/null
+++ b/arch/riscv/dts/cv1800b-milkv-duo.dts
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ */
+
+/dts-v1/;
+
+#include "cv1800b.dtsi"
+
+/ {
+ model = "Milk-V Duo";
+ compatible = "milkv,duo", "sophgo,cv1800b";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x3f40000>;
+ };
+};
+
+&osc {
+ clock-frequency = <25000000>;
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/riscv/dts/cv1800b.dtsi b/arch/riscv/dts/cv1800b.dtsi
new file mode 100644
index 0000000..165e9e3
--- /dev/null
+++ b/arch/riscv/dts/cv1800b.dtsi
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ */
+
+#include "cv18xx.dtsi"
+
+/ {
+ compatible = "sophgo,cv1800b";
+};
+
+&plic {
+ compatible = "sophgo,cv1800b-plic", "thead,c900-plic";
+};
+
+&clint {
+ compatible = "sophgo,cv1800b-clint", "thead,c900-clint";
+};
diff --git a/arch/riscv/dts/cv18xx.dtsi b/arch/riscv/dts/cv18xx.dtsi
new file mode 100644
index 0000000..2d6f4a4
--- /dev/null
+++ b/arch/riscv/dts/cv18xx.dtsi
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ * Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus: cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <25000000>;
+
+ cpu0: cpu@0 {
+ compatible = "thead,c906", "riscv";
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <512>;
+ d-cache-size = <65536>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <128>;
+ i-cache-size = <32768>;
+ mmu-type = "riscv,sv39";
+ riscv,isa = "rv64imafdc";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu0_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+ };
+
+ osc: oscillator {
+ compatible = "fixed-clock";
+ clock-output-names = "osc_25m";
+ #clock-cells = <0>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&plic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ dma-noncoherent;
+ ranges;
+
+ gpio0: gpio@3020000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x3020000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ porta: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <60 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ gpio1: gpio@3021000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x3021000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portb: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <61 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ gpio2: gpio@3022000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x3022000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portc: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <62 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ gpio3: gpio@3023000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x3023000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portd: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <32>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <63 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ uart0: serial@4140000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x04140000 0x100>;
+ interrupts = <44 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart1: serial@4150000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x04150000 0x100>;
+ interrupts = <45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart2: serial@4160000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x04160000 0x100>;
+ interrupts = <46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart3: serial@4170000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x04170000 0x100>;
+ interrupts = <47 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart4: serial@41c0000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x041c0000 0x100>;
+ interrupts = <48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ plic: interrupt-controller@70000000 {
+ reg = <0x70000000 0x4000000>;
+ interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ riscv,ndev = <101>;
+ };
+
+ clint: timer@74000000 {
+ reg = <0x74000000 0x10000>;
+ interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>;
+ };
+ };
+};
diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
index e94f9fe..f2c6bec 100644
--- a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
@@ -127,6 +127,11 @@
pinctrl-0 = <&i2c5_pins>;
status = "okay";
+ pmic@36 {
+ compatible = "x-powers,axp15060";
+ reg = <0x36>;
+ };
+
eeprom@50 {
compatible = "atmel,24c04";
reg = <0x50>;
diff --git a/arch/riscv/dts/jh7110.dtsi b/arch/riscv/dts/jh7110.dtsi
index 6d2675d..2cdc683 100644
--- a/arch/riscv/dts/jh7110.dtsi
+++ b/arch/riscv/dts/jh7110.dtsi
@@ -473,6 +473,12 @@
status = "disabled";
};
+ power-controller@17030000 {
+ compatible = "starfive,jh7110-pmu";
+ reg = <0x0 0x17030000 0x0 0x10000>;
+ interrupts = <111>;
+ };
+
qspi: spi@13010000 {
compatible = "cdns,qspi-nor";
reg = <0x0 0x13010000 0x0 0x10000
diff --git a/arch/riscv/include/asm/arch-fu740/eeprom.h b/arch/riscv/include/asm/arch-fu740/eeprom.h
new file mode 100644
index 0000000..aaa02c6
--- /dev/null
+++ b/arch/riscv/include/asm/arch-fu740/eeprom.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2024 SiFive, Inc.
+ *
+ * Zong Li <zong.li@sifve.com>
+ */
+
+#ifndef _ASM_RISCV_EEPROM_H
+#define _ASM_RISCV_EEPROM_H
+
+#define PCB_REVISION_REV3 0x3
+
+u8 get_pcb_revision_from_eeprom(void);
+
+#endif /* _ASM_RISCV_EEPROM_H */
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index bf4c9af..d1113f3 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -33,6 +33,7 @@ enum sbi_ext_id {
SBI_EXT_CPPC = 0x43505043,
SBI_EXT_NACL = 0x4E41434C,
SBI_EXT_STA = 0x535441,
+ SBI_EXT_DBTR = 0x44425452,
};
enum sbi_ext_base_fid {
diff --git a/arch/sandbox/include/asm/clk.h b/arch/sandbox/include/asm/clk.h
index d4e04ad..37fe49c 100644
--- a/arch/sandbox/include/asm/clk.h
+++ b/arch/sandbox/include/asm/clk.h
@@ -182,14 +182,6 @@ int sandbox_clk_test_disable(struct udevice *dev, int id);
*/
int sandbox_clk_test_disable_bulk(struct udevice *dev);
/**
- * sandbox_clk_test_free - Ask the sandbox clock test device to free its
- * clocks.
- *
- * @dev: The sandbox clock test (client) device.
- * @return: 0 if OK, or a negative error code.
- */
-int sandbox_clk_test_free(struct udevice *dev);
-/**
* sandbox_clk_test_release_bulk - Ask the sandbox clock test device to release
* all clocks in it's clock bulk struct.
*
diff --git a/board/AndesTech/ae350/ae350.c b/board/AndesTech/ae350/ae350.c
index 4e53fee..62b93b4 100644
--- a/board/AndesTech/ae350/ae350.c
+++ b/board/AndesTech/ae350/ae350.c
@@ -21,8 +21,6 @@
#include <fdtdec.h>
#include <dm.h>
#include <spl.h>
-#include <mapmem.h>
-#include <hang.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -51,29 +49,6 @@ int misc_init_r(void)
}
#endif
-#if CONFIG_IS_ENABLED(LOAD_FIT) || CONFIG_IS_ENABLED(LOAD_FIT_FULL)
-#define ANDES_SPL_FDT_ADDR (CONFIG_TEXT_BASE - 0x100000)
-void spl_perform_fixups(struct spl_image_info *spl_image)
-{
- /*
- * Originally, u-boot-spl will place DTB directly after the kernel,
- * but the size of the kernel did not include the BSS section, which
- * means u-boot-spl will place the DTB in the kernel BSS section
- * causing the DTB to be cleared by kernel BSS initializtion.
- * Moving DTB in front of the kernel can avoid the error.
- */
- if (ANDES_SPL_FDT_ADDR < 0) {
- printf("%s: CONFIG_TEXT_BASE needs to be larger than 0x100000\n",
- __func__);
- hang();
- }
-
- memcpy((void *)ANDES_SPL_FDT_ADDR, spl_image->fdt_addr,
- fdt_totalsize(spl_image->fdt_addr));
- spl_image->fdt_addr = map_sysmem(ANDES_SPL_FDT_ADDR, 0);
-}
-#endif
-
int board_init(void)
{
gd->bd->bi_boot_params = PHYS_SDRAM_0 + 0x400;
diff --git a/board/microchip/pic32mzda/pic32mzda.c b/board/microchip/pic32mzda/pic32mzda.c
index e7337de..3c2203d 100644
--- a/board/microchip/pic32mzda/pic32mzda.c
+++ b/board/microchip/pic32mzda/pic32mzda.c
@@ -36,8 +36,6 @@ int checkboard(void)
rate = clk_get_rate(&clk);
printf("CPU Speed: %lu MHz\n", rate / 1000000);
- clk_free(&clk);
-
return 0;
}
#endif
diff --git a/board/sifive/unmatched/spl.c b/board/sifive/unmatched/spl.c
index 7c0beed..e69bed9 100644
--- a/board/sifive/unmatched/spl.c
+++ b/board/sifive/unmatched/spl.c
@@ -15,6 +15,29 @@
#include <asm/gpio.h>
#include <asm/arch/gpio.h>
#include <asm/arch/spl.h>
+#include <linux/io.h>
+#include <asm/arch/eeprom.h>
+
+struct pwm_sifive_regs {
+ unsigned int cfg; /* PWM configuration register */
+ unsigned int pad0; /* Reserved */
+ unsigned int cnt; /* PWM count register */
+ unsigned int pad1; /* Reserved */
+ unsigned int pwms; /* Scaled PWM count register */
+ unsigned int pad2; /* Reserved */
+ unsigned int pad3; /* Reserved */
+ unsigned int pad4; /* Reserved */
+ unsigned int cmp0; /* PWM 0 compare register */
+ unsigned int cmp1; /* PWM 1 compare register */
+ unsigned int cmp2; /* PWM 2 compare register */
+ unsigned int cmp3; /* PWM 3 compare register */
+};
+
+#define PWM0_BASE 0x10020000
+#define PWM1_BASE 0x10021000
+#define PWM_CFG_INIT 0x1000
+#define PWM_CMP_ENABLE_VAL 0x0
+#define PWM_CMP_DISABLE_VAL 0xffff
#define UBRDG_RESET SIFIVE_GENERIC_GPIO_NR(0, 7)
#define ULPI_RESET SIFIVE_GENERIC_GPIO_NR(0, 9)
@@ -26,6 +49,33 @@
#define MODE_SELECT_SD 0xb
#define MODE_SELECT_MASK GENMASK(3, 0)
+void spl_pwm_device_init(void)
+{
+ struct pwm_sifive_regs *pwm0, *pwm1;
+
+ pwm0 = (struct pwm_sifive_regs *)PWM0_BASE;
+ pwm1 = (struct pwm_sifive_regs *)PWM1_BASE;
+ writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp0);
+
+ /* Set the 3-color PWM LEDs to yellow in SPL */
+ writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp1);
+ writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp2);
+ writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp3);
+ writel(PWM_CFG_INIT, (void *)&pwm0->cfg);
+
+ /* Turn on all the fans, (J21), (J23) and (J24), on the unmatched board */
+ /* The SoC fan(J21) on the rev3 board cannot be controlled by PWM_COMP0,
+ * so here sets the initial value of PWM_COMP0 as DISABLE */
+ if (get_pcb_revision_from_eeprom() == PCB_REVISION_REV3)
+ writel(PWM_CMP_DISABLE_VAL, (void *)&pwm1->cmp1);
+ else
+ writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp1);
+
+ writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp2);
+ writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp3);
+ writel(PWM_CFG_INIT, (void *)&pwm1->cfg);
+}
+
static inline int spl_reset_device_by_gpio(const char *label, int pin, int low_width)
{
int ret;
@@ -90,6 +140,8 @@ int spl_board_init_f(void)
goto end;
}
+ spl_pwm_device_init();
+
ret = spl_gemgxl_init();
if (ret) {
debug("Gigabit ethernet PHY (VSC8541) init failed: %d\n", ret);
diff --git a/board/sipeed/maix/maix.c b/board/sipeed/maix/maix.c
index 79e492f..06653b5 100644
--- a/board/sipeed/maix/maix.c
+++ b/board/sipeed/maix/maix.c
@@ -32,7 +32,6 @@ static int sram_init(void)
continue;
ret = clk_enable(&clk);
- clk_free(&clk);
if (ret)
return ret;
}
diff --git a/board/sophgo/milkv_duo/Kconfig b/board/sophgo/milkv_duo/Kconfig
new file mode 100644
index 0000000..2a458f2
--- /dev/null
+++ b/board/sophgo/milkv_duo/Kconfig
@@ -0,0 +1,28 @@
+if TARGET_MILKV_DUO
+
+config SYS_BOARD
+ default "milkv_duo"
+
+config SYS_VENDOR
+ default "sophgo"
+
+config SYS_CPU
+ default "generic"
+
+config SYS_CONFIG_NAME
+ default "milkv_duo"
+
+config TEXT_BASE
+ default 0x80200000
+
+config ENV_SIZE
+ default 0x20000
+
+config ENV_SECT_SIZE
+ default 0x40000
+
+config BOARD_SPECIFIC_OPTIONS
+ def_bool y
+ select GENERIC_RISCV
+
+endif
diff --git a/board/sophgo/milkv_duo/MAINTAINERS b/board/sophgo/milkv_duo/MAINTAINERS
new file mode 100644
index 0000000..651a059
--- /dev/null
+++ b/board/sophgo/milkv_duo/MAINTAINERS
@@ -0,0 +1,6 @@
+Milk-V Duo
+M: Kongyang Liu <seashell11234455@gmail.com>
+S: Maintained
+F: board/sophgo/milkv_duo/
+F: configs/milkv_duo_defconfig
+F: doc/board/sophgo/milkv_duo.rst
diff --git a/board/sophgo/milkv_duo/Makefile b/board/sophgo/milkv_duo/Makefile
new file mode 100644
index 0000000..a087013
--- /dev/null
+++ b/board/sophgo/milkv_duo/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+
+obj-y := board.o
diff --git a/board/sophgo/milkv_duo/board.c b/board/sophgo/milkv_duo/board.c
new file mode 100644
index 0000000..eaa47be
--- /dev/null
+++ b/board/sophgo/milkv_duo/board.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+ */
+
+int board_init(void)
+{
+ return 0;
+}
diff --git a/board/starfive/visionfive2/spl.c b/board/starfive/visionfive2/spl.c
index 336f0cd..1b49945 100644
--- a/board/starfive/visionfive2/spl.c
+++ b/board/starfive/visionfive2/spl.c
@@ -45,6 +45,10 @@ static const struct starfive_vf2_pro starfive_verb[] = {
{"/soc/ethernet@16030000/mdio/ethernet-phy@0",
"motorcomm,tx-clk-1000-inverted", NULL},
{"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "motorcomm,rx-clk-drv-microamp", "3970"},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "motorcomm,rx-data-drv-microamp", "2910"},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
"rx-internal-delay-ps", "1900"},
{"/soc/ethernet@16030000/mdio/ethernet-phy@0",
"tx-internal-delay-ps", "1500"},
@@ -54,6 +58,10 @@ static const struct starfive_vf2_pro starfive_verb[] = {
{ "/soc/ethernet@16040000/mdio/ethernet-phy@1",
"motorcomm,tx-clk-100-inverted", NULL},
{"/soc/ethernet@16040000/mdio/ethernet-phy@1",
+ "motorcomm,rx-clk-drv-microamp", "3970"},
+ {"/soc/ethernet@16040000/mdio/ethernet-phy@1",
+ "motorcomm,rx-data-drv-microamp", "2910"},
+ {"/soc/ethernet@16040000/mdio/ethernet-phy@1",
"rx-internal-delay-ps", "0"},
{"/soc/ethernet@16040000/mdio/ethernet-phy@1",
"tx-internal-delay-ps", "0"},
@@ -61,11 +69,13 @@ static const struct starfive_vf2_pro starfive_verb[] = {
void spl_fdt_fixup_version_a(void *fdt)
{
+ static const char compat[] = "starfive,visionfive-2-v1.2a\0starfive,jh7110";
u32 phandle;
u8 i;
int offset;
int ret;
+ fdt_setprop(fdt, fdt_path_offset(fdt, "/"), "compatible", compat, sizeof(compat));
fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
"StarFive VisionFive 2 v1.2A");
@@ -106,11 +116,13 @@ void spl_fdt_fixup_version_a(void *fdt)
void spl_fdt_fixup_version_b(void *fdt)
{
+ static const char compat[] = "starfive,visionfive-2-v1.3b\0starfive,jh7110";
u32 phandle;
u8 i;
int offset;
int ret;
+ fdt_setprop(fdt, fdt_path_offset(fdt, "/"), "compatible", compat, sizeof(compat));
fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
"StarFive VisionFive 2 v1.3B");
diff --git a/board/synopsys/hsdk/clk-lib.c b/board/synopsys/hsdk/clk-lib.c
index be76d6c..a9614e9 100644
--- a/board/synopsys/hsdk/clk-lib.c
+++ b/board/synopsys/hsdk/clk-lib.c
@@ -56,8 +56,6 @@ int soc_clk_ctl(const char *name, ulong *rate, enum clk_ctl_ops ctl)
priv_rate = clk_get_rate(&clk);
- clk_free(&clk);
-
mhz_rate = ceil(priv_rate, HZ_IN_MHZ);
if (ctl & CLK_MHZ)
diff --git a/cmd/riscv/sbi.c b/cmd/riscv/sbi.c
index 940d9bc..9daf0e2 100644
--- a/cmd/riscv/sbi.c
+++ b/cmd/riscv/sbi.c
@@ -53,6 +53,7 @@ static struct sbi_ext extensions[] = {
{ SBI_EXT_CPPC, "Collaborative Processor Performance Control Extension" },
{ SBI_EXT_NACL, "Nested Acceleration Extension" },
{ SBI_EXT_STA, "Steal-time Accounting Extension" },
+ { SBI_EXT_DBTR, "Debug Trigger Extension" },
};
static int do_sbi(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/cmd/smbios.c b/cmd/smbios.c
index feebf93..66f6b76 100644
--- a/cmd/smbios.c
+++ b/cmd/smbios.c
@@ -25,6 +25,10 @@ static const char *smbios_get_string(void *table, int index)
{
const char *str = (char *)table +
((struct smbios_header *)table)->length;
+ static const char fallback[] = "Not Specified";
+
+ if (!index)
+ return fallback;
if (!*str)
++str;
@@ -41,7 +45,7 @@ static struct smbios_header *next_table(struct smbios_header *table)
if (table->type == SMBIOS_END_OF_TABLE)
return NULL;
- str = smbios_get_string(table, 0);
+ str = smbios_get_string(table, -1);
return (struct smbios_header *)(++str);
}
@@ -76,7 +80,7 @@ static void smbios_print_type1(struct smbios_type1 *table)
smbios_print_str("Version", table, table->version);
smbios_print_str("Serial Number", table, table->serial_number);
if (table->length >= 0x19) {
- printf("\tUUID %pUl\n", table->uuid);
+ printf("\tUUID: %pUl\n", table->uuid);
smbios_print_str("Wake Up Type", table, table->serial_number);
}
if (table->length >= 0x1b) {
@@ -95,9 +99,9 @@ static void smbios_print_type2(struct smbios_type2 *table)
smbios_print_str("Version", table, table->version);
smbios_print_str("Serial Number", table, table->serial_number);
smbios_print_str("Asset Tag", table, table->asset_tag_number);
- printf("\tFeature Flags: 0x%2x\n", table->feature_flags);
+ printf("\tFeature Flags: 0x%04x\n", table->feature_flags);
smbios_print_str("Chassis Location", table, table->chassis_location);
- printf("\tChassis Handle: 0x%2x\n", table->chassis_handle);
+ printf("\tChassis Handle: 0x%04x\n", table->chassis_handle);
smbios_print_str("Board Type", table, table->board_type);
printf("\tContained Object Handles: ");
handle = (void *)table->eos;
@@ -122,7 +126,7 @@ static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc,
static const char smbios_sig[] = "_SM_";
static const char smbios3_sig[] = "_SM3_";
size_t count = 0;
- u32 max_struct_size;
+ u32 table_maximum_size;
addr = gd_smbios_start();
if (!addr) {
@@ -138,7 +142,7 @@ static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc,
entry3->major_ver, entry3->minor_ver, entry3->doc_rev);
table = (void *)(uintptr_t)entry3->struct_table_address;
size = entry3->length;
- max_struct_size = entry3->max_struct_size;
+ table_maximum_size = entry3->table_maximum_size;
} else if (!memcmp(entry, smbios_sig, sizeof(smbios_sig) - 1)) {
struct smbios_entry *entry2 = entry;
@@ -146,7 +150,7 @@ static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc,
entry2->major_ver, entry2->minor_ver);
table = (void *)(uintptr_t)entry2->struct_table_address;
size = entry2->length;
- max_struct_size = entry2->max_struct_size;
+ table_maximum_size = entry2->struct_table_length;
} else {
log_err("Unknown SMBIOS anchor format\n");
return CMD_RET_FAILURE;
@@ -159,7 +163,7 @@ static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc,
for (struct smbios_header *pos = table; pos; pos = next_table(pos))
++count;
- printf("%zd structures occupying %d bytes\n", count, max_struct_size);
+ printf("%zd structures occupying %d bytes\n", count, table_maximum_size);
printf("Table at 0x%llx\n", (unsigned long long)map_to_sysmem(table));
for (struct smbios_header *pos = table; pos; pos = next_table(pos)) {
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 6a4772e..8805dd3 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -1113,7 +1113,7 @@ config SPL_OS_BOOT
config SPL_PAYLOAD_ARGS_ADDR
hex "Address in memory to load 'args' file for Falcon Mode to"
- depends on SPL_OS_BOOT
+ depends on SPL_OS_BOOT || SPL_LOAD_FIT_OPENSBI_OS_BOOT
default 0x88000000 if ARCH_OMAP2PLUS
help
Address in memory where the 'args' file, typically a device tree
diff --git a/common/spl/spl_opensbi.c b/common/spl/spl_opensbi.c
index 9801d38..8127ebc 100644
--- a/common/spl/spl_opensbi.c
+++ b/common/spl/spl_opensbi.c
@@ -16,6 +16,7 @@
#include <opensbi.h>
#include <linux/libfdt.h>
#include <linux/printk.h>
+#include <mapmem.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -58,6 +59,20 @@ void __noreturn spl_invoke_opensbi(struct spl_image_info *spl_image)
}
/*
+ * Originally, u-boot-spl will place DTB directly after the kernel,
+ * but the size of the kernel did not include the BSS section, which
+ * means u-boot-spl will place the DTB in the kernel BSS section
+ * causing the DTB to be cleared by kernel BSS initializtion.
+ * Moving DTB in front of the kernel can avoid the error.
+ */
+#if CONFIG_IS_ENABLED(LOAD_FIT_OPENSBI_OS_BOOT) && \
+ CONFIG_IS_ENABLED(PAYLOAD_ARGS_ADDR)
+ memcpy((void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR, spl_image->fdt_addr,
+ fdt_totalsize(spl_image->fdt_addr));
+ spl_image->fdt_addr = map_sysmem(CONFIG_SPL_PAYLOAD_ARGS_ADDR, 0);
+#endif
+
+ /*
* Find next os image in /fit-images
* The next os image default is u-boot proper, once enable
* OpenSBI OS boot mode, the OS image should be linux.
diff --git a/configs/ae350_rv32_defconfig b/configs/ae350_rv32_defconfig
index 3bfa3e9..35ad62c 100644
--- a/configs/ae350_rv32_defconfig
+++ b/configs/ae350_rv32_defconfig
@@ -23,6 +23,7 @@ CONFIG_SYS_PROMPT="RISC-V # "
CONFIG_CMD_IMLS=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_WDT=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
CONFIG_CMD_CACHE=y
@@ -49,3 +50,6 @@ CONFIG_BAUDRATE=38400
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_ATCSPI200_SPI=y
+# CONFIG_WATCHDOG_AUTOSTART is not set
+CONFIG_WDT=y
+CONFIG_WDT_ATCWDT200=y
diff --git a/configs/ae350_rv32_falcon_defconfig b/configs/ae350_rv32_falcon_defconfig
index abf7dd4..f814710 100644
--- a/configs/ae350_rv32_falcon_defconfig
+++ b/configs/ae350_rv32_falcon_defconfig
@@ -14,6 +14,7 @@ CONFIG_TARGET_ANDES_AE350=y
CONFIG_RISCV_SMODE=y
# CONFIG_AVAILABLE_HARTS is not set
CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y
+CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000
CONFIG_SYS_MONITOR_BASE=0x88000000
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000
diff --git a/configs/ae350_rv32_falcon_xip_defconfig b/configs/ae350_rv32_falcon_xip_defconfig
index 5166ab7..50e164c 100644
--- a/configs/ae350_rv32_falcon_xip_defconfig
+++ b/configs/ae350_rv32_falcon_xip_defconfig
@@ -15,6 +15,7 @@ CONFIG_TARGET_ANDES_AE350=y
CONFIG_RISCV_SMODE=y
CONFIG_SPL_XIP=y
CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y
+CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000
CONFIG_SYS_MONITOR_BASE=0x88000000
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x80010000
diff --git a/configs/ae350_rv32_spl_defconfig b/configs/ae350_rv32_spl_defconfig
index aeb5020..41cd457 100644
--- a/configs/ae350_rv32_spl_defconfig
+++ b/configs/ae350_rv32_spl_defconfig
@@ -33,6 +33,7 @@ CONFIG_SYS_PROMPT="RISC-V # "
CONFIG_CMD_IMLS=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_WDT=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
CONFIG_CMD_CACHE=y
@@ -58,3 +59,6 @@ CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_ATCSPI200_SPI=y
# CONFIG_BINMAN_FDT is not set
+# CONFIG_WATCHDOG_AUTOSTART is not set
+CONFIG_WDT=y
+CONFIG_WDT_ATCWDT200=y
diff --git a/configs/ae350_rv32_spl_xip_defconfig b/configs/ae350_rv32_spl_xip_defconfig
index f15ec30..954e2f2 100644
--- a/configs/ae350_rv32_spl_xip_defconfig
+++ b/configs/ae350_rv32_spl_xip_defconfig
@@ -34,6 +34,7 @@ CONFIG_SYS_PROMPT="RISC-V # "
CONFIG_CMD_IMLS=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_WDT=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
CONFIG_CMD_CACHE=y
@@ -59,3 +60,6 @@ CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_ATCSPI200_SPI=y
# CONFIG_BINMAN_FDT is not set
+# CONFIG_WATCHDOG_AUTOSTART is not set
+CONFIG_WDT=y
+CONFIG_WDT_ATCWDT200=y
diff --git a/configs/ae350_rv32_xip_defconfig b/configs/ae350_rv32_xip_defconfig
index c40eb04..9586359 100644
--- a/configs/ae350_rv32_xip_defconfig
+++ b/configs/ae350_rv32_xip_defconfig
@@ -24,6 +24,7 @@ CONFIG_SYS_PROMPT="RISC-V # "
CONFIG_CMD_IMLS=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_WDT=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
CONFIG_CMD_CACHE=y
@@ -50,3 +51,6 @@ CONFIG_BAUDRATE=38400
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_ATCSPI200_SPI=y
+# CONFIG_WATCHDOG_AUTOSTART is not set
+CONFIG_WDT=y
+CONFIG_WDT_ATCWDT200=y
diff --git a/configs/ae350_rv64_defconfig b/configs/ae350_rv64_defconfig
index 7ae938a..9882142 100644
--- a/configs/ae350_rv64_defconfig
+++ b/configs/ae350_rv64_defconfig
@@ -23,6 +23,7 @@ CONFIG_SYS_PROMPT="RISC-V # "
CONFIG_CMD_IMLS=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_WDT=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
CONFIG_CMD_CACHE=y
@@ -49,3 +50,6 @@ CONFIG_BAUDRATE=38400
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_ATCSPI200_SPI=y
+# CONFIG_WATCHDOG_AUTOSTART is not set
+CONFIG_WDT=y
+CONFIG_WDT_ATCWDT200=y
diff --git a/configs/ae350_rv64_falcon_defconfig b/configs/ae350_rv64_falcon_defconfig
index 1289238..b0b7ae5 100644
--- a/configs/ae350_rv64_falcon_defconfig
+++ b/configs/ae350_rv64_falcon_defconfig
@@ -14,6 +14,7 @@ CONFIG_ARCH_RV64I=y
CONFIG_RISCV_SMODE=y
# CONFIG_AVAILABLE_HARTS is not set
CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y
+CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000
CONFIG_SYS_MONITOR_BASE=0x88000000
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000
diff --git a/configs/ae350_rv64_falcon_xip_defconfig b/configs/ae350_rv64_falcon_xip_defconfig
index 18e2daf..cac315d 100644
--- a/configs/ae350_rv64_falcon_xip_defconfig
+++ b/configs/ae350_rv64_falcon_xip_defconfig
@@ -15,6 +15,7 @@ CONFIG_ARCH_RV64I=y
CONFIG_RISCV_SMODE=y
CONFIG_SPL_XIP=y
CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y
+CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000
CONFIG_SYS_MONITOR_BASE=0x88000000
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x80010000
diff --git a/configs/ae350_rv64_spl_defconfig b/configs/ae350_rv64_spl_defconfig
index 68ac432..e929320 100644
--- a/configs/ae350_rv64_spl_defconfig
+++ b/configs/ae350_rv64_spl_defconfig
@@ -33,6 +33,7 @@ CONFIG_SYS_PROMPT="RISC-V # "
CONFIG_CMD_IMLS=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_WDT=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
CONFIG_CMD_CACHE=y
@@ -58,3 +59,6 @@ CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_ATCSPI200_SPI=y
# CONFIG_BINMAN_FDT is not set
+# CONFIG_WATCHDOG_AUTOSTART is not set
+CONFIG_WDT=y
+CONFIG_WDT_ATCWDT200=y
diff --git a/configs/ae350_rv64_spl_xip_defconfig b/configs/ae350_rv64_spl_xip_defconfig
index 839ca335..3f92643 100644
--- a/configs/ae350_rv64_spl_xip_defconfig
+++ b/configs/ae350_rv64_spl_xip_defconfig
@@ -34,6 +34,7 @@ CONFIG_SYS_PROMPT="RISC-V # "
CONFIG_CMD_IMLS=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_WDT=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
CONFIG_CMD_CACHE=y
@@ -59,3 +60,6 @@ CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_ATCSPI200_SPI=y
# CONFIG_BINMAN_FDT is not set
+# CONFIG_WATCHDOG_AUTOSTART is not set
+CONFIG_WDT=y
+CONFIG_WDT_ATCWDT200=y
diff --git a/configs/ae350_rv64_xip_defconfig b/configs/ae350_rv64_xip_defconfig
index 5432b6d..835f020 100644
--- a/configs/ae350_rv64_xip_defconfig
+++ b/configs/ae350_rv64_xip_defconfig
@@ -24,6 +24,7 @@ CONFIG_SYS_PROMPT="RISC-V # "
CONFIG_CMD_IMLS=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_WDT=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
CONFIG_CMD_CACHE=y
@@ -50,3 +51,6 @@ CONFIG_BAUDRATE=38400
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_ATCSPI200_SPI=y
+# CONFIG_WATCHDOG_AUTOSTART is not set
+CONFIG_WDT=y
+CONFIG_WDT_ATCWDT200=y
diff --git a/configs/milkv_duo_defconfig b/configs/milkv_duo_defconfig
new file mode 100644
index 0000000..9eca6ab
--- /dev/null
+++ b/configs/milkv_duo_defconfig
@@ -0,0 +1,23 @@
+CONFIG_RISCV=y
+CONFIG_SYS_MALLOC_LEN=0x820000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x82300000
+CONFIG_DEFAULT_DEVICE_TREE="cv1800b-milkv-duo"
+CONFIG_IDENT_STRING="milkv_duo"
+CONFIG_SYS_LOAD_ADDR=0x80080000
+CONFIG_TARGET_MILKV_DUO=y
+CONFIG_ARCH_RV64I=y
+CONFIG_RISCV_SMODE=y
+CONFIG_FIT=y
+CONFIG_SUPPORT_RAW_INITRD=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="milkv_duo# "
+CONFIG_SYS_MAXARGS=64
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=544
+CONFIG_SYS_BOOTM_LEN=0x4000000
+CONFIG_ENV_OVERWRITE=y
+CONFIG_SYS_NS16550=y
+CONFIG_SYS_NS16550_MEM32=y
diff --git a/configs/starfive_visionfive2_defconfig b/configs/starfive_visionfive2_defconfig
index 1b7d57b..c68f3c2 100644
--- a/configs/starfive_visionfive2_defconfig
+++ b/configs/starfive_visionfive2_defconfig
@@ -77,7 +77,6 @@ CONFIG_CMD_TFTPPUT=y
CONFIG_CMD_BOOTSTAGE=y
CONFIG_OF_BOARD=y
CONFIG_ENV_OVERWRITE=y
-CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_ENV_SECT_SIZE_AUTO=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/doc/board/index.rst b/doc/board/index.rst
index c96e5fd..d0f9f35 100644
--- a/doc/board/index.rst
+++ b/doc/board/index.rst
@@ -46,6 +46,7 @@ Board-specific doc
sifive/index
sipeed/index
socionext/index
+ sophgo/index
st/index
starfive/index
ste/index
diff --git a/doc/board/sophgo/index.rst b/doc/board/sophgo/index.rst
new file mode 100644
index 0000000..e097afd
--- /dev/null
+++ b/doc/board/sophgo/index.rst
@@ -0,0 +1,8 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Sophgo
+======
+.. toctree::
+ :maxdepth: 1
+
+ milkv_duo
diff --git a/doc/board/sophgo/milkv_duo.rst b/doc/board/sophgo/milkv_duo.rst
new file mode 100644
index 0000000..cb2ed1a
--- /dev/null
+++ b/doc/board/sophgo/milkv_duo.rst
@@ -0,0 +1,64 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Milk-V Duo
+==========
+
+CV1800B RISC-V SoC
+------------------
+The CV1800B is a high-performance, low-power 1+1 64-bit RISC-V SoC from Sophgo.
+
+Mainline support
+----------------
+The support for following drivers are already enabled:
+1. ns16550 UART Driver.
+
+Building
+~~~~~~~~
+1. Add the RISC-V toolchain to your PATH.
+2. Setup ARCH & cross compilation environment variable:
+
+.. code-block:: console
+
+ export CROSS_COMPILE=<riscv64 toolchain prefix>
+ cd <U-Boot-dir>
+ make milkv_duo_defconfig
+ make
+
+This will generate u-boot-dtb.bin
+
+Booting
+~~~~~~~
+Currently, we rely on vendor FSBL(First Stage Boot Loader) to initialize the
+clock and load the u-boot image, then bootup from it.
+
+Alternatively, to run u-boot-dtb.bin on top of FSBL, follow these steps:
+
+1. Use the vendor-provided tool to create a unified fip.bin file containing
+ FSBL, OpenSBI, and U-Boot.
+
+2. Place the generated fip.bin file into the FAT partition of the SD card.
+
+3. Insert the SD card into the board and power it on.
+
+The board will automatically execute the FSBL from the fip.bin file.
+Subsequently, it will transition to OpenSBI, and finally, OpenSBI will invoke
+U-Boot.
+
+
+Sample boot log from Milk-V Duo board
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. code-block:: none
+
+ U-Boot 2024.01-rc5-00010-g51965baa36 (Dec 28 2023 - 13:15:53 +0800)milkv_duo
+
+ DRAM: 63.3 MiB
+ Core: 10 devices, 8 uclasses, devicetree: separate
+ Loading Environment from nowhere... OK
+ In: serial@4140000
+ Out: serial@4140000
+ Err: serial@4140000
+ Net: No ethernet found.
+ milkv_duo# cpu detail
+ 0: cpu@0 rv64imafdc
+ ID = 0, freq = 0 Hz: L1 cache, MMU
+ milkv_duo#
diff --git a/doc/develop/falcon.rst b/doc/develop/falcon.rst
index 8a46c0e..244b4cc 100644
--- a/doc/develop/falcon.rst
+++ b/doc/develop/falcon.rst
@@ -256,3 +256,161 @@ the following command:
Falcon Mode was presented at the RMLL 2012. Slides are available at:
http://schedule2012.rmll.info/IMG/pdf/LSM2012_UbootFalconMode_Babic.pdf
+
+Falcon Mode Boot on RISC-V
+--------------------------
+
+Introduction
+~~~~~~~~~~~~
+
+In the RISC-V environment, OpenSBI is required to enable a supervisor mode
+binary to execute certain privileged operations. The typical boot sequence on
+RISC-V is SPL -> OpenSBI -> U-Boot -> Linux kernel. SPL will load and start
+the OpenSBI initializations, then OpenSBI will bring up the next image, U-Boot
+proper. The OpenSBI binary must be prepared in advance of the U-Boot build
+process and it will be packed together with U-Boot into a file called
+u-boot.itb.
+
+The Falcon Mode on RISC-V platforms is a distinct boot sequence. Borrowing
+ideas from the U-Boot Falcon Mode on ARM, it skips the U-Boot proper phase
+in the normal boot process and allows OpenSBI to load and start the Linux
+kernel. Its boot sequence is SPL -> OpenSBI -> Linux kernel. The OpenSBI
+binary and Linux kernel binary must be prepared prior to the U-Boot build
+process and they will be packed together as a FIT image named linux.itb in
+this process.
+
+CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT enables the Falcon Mode boot on RISC-V.
+This configuration setting tells OpenSBI that Linux kernel is its next OS
+image and makes it load and start the kernel afterwards.
+
+Note that the Falcon Mode boot bypasses a lot of initializations by U-Boot.
+If the Linux kernel expects hardware initializations by U-Boot, make sure to
+port the relevant code to the SPL build process.
+
+Configuration
+~~~~~~~~~~~~~
+
+CONFIG_SPL_LOAD_FIT_ADDRESS
+ Specifies the address to load u-boot.itb in a normal boot. When the Falcon
+ Mode boot is enabled, it specifies the load address of linux.itb.
+
+CONFIG_SYS_TEXT_BASE
+ Specifies the address of the text section for a u-boot proper in a normal
+ boot. When the Falcon Mode boot is enabled, it specifies the text section
+ address for the Linux kernel image.
+
+CONFIG_SPL_PAYLOAD_ARGS_ADDR
+ The address in the RAM to which the FDT blob is to be moved by the SPL.
+ SPL places the FDT blob right after the kernel. As the kernel does not
+ include the BSS section in its size calculation, SPL ends up placing
+ the FDT blob within the BSS section of the kernel. This may cause the
+ FDT blob to be cleared during kernel BSS initialization. To avoid the
+ issue, be sure to move the FDT blob out of the kernel first.
+
+CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT
+ Activates the Falcon Mode boot on RISC-V.
+
+Example for Andes AE350 Board
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A FDT blob is required to boot the Linux kernel from the SPL. Andes AE350
+platforms generally come with a builtin dtb. To load a custom DTB, follow
+these steps:
+
+1. Load the custom DTB to SDRAM::
+
+ => fatload mmc 0:1 0x20000000 user_custom.dtb
+
+2. Set the SPI speed::
+
+ => sf probe 0:0 50000000 0
+
+3. Erase sectors from the SPI Flash::
+
+ => sf erase 0xf0000 0x10000
+
+4. Write the FDT blob to the erased sectors of the Flash::
+
+ => sf write 0x20000000 0xf0000 0x10000
+
+Console Log of AE350 Falcon Mode Boot
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ U-Boot SPL 2023.01-00031-g777ecdea66 (Oct 31 2023 - 18:41:36 +0800)
+ Trying to boot from RAM
+
+ OpenSBI v1.2-51-g7304e42
+ ____ _____ ____ _____
+ / __ \ / ____| _ \_ _|
+ | | | |_ __ ___ _ __ | (___ | |_) || |
+ | | | | '_ \ / _ \ '_ \ \___ \| _ < | |
+ | |__| | |_) | __/ | | |____) | |_) || |_
+ \____/| .__/ \___|_| |_|_____/|____/_____|
+ | |
+ |_|
+
+ Platform Name : andestech,ax25
+ Platform Features : medeleg
+ Platform HART Count : 1
+ Platform IPI Device : andes_plicsw
+ Platform Timer Device : andes_plmt @ 60000000Hz
+ Platform Console Device : uart8250
+ Platform HSM Device : andes_smu
+ Platform PMU Device : andes_pmu
+ Platform Reboot Device : atcwdt200
+ Platform Shutdown Device : ---
+ Firmware Base : 0x0
+ Firmware Size : 196 KB
+ Runtime SBI Version : 1.0
+
+ Domain0 Name : root
+ Domain0 Boot HART : 0
+ Domain0 HARTs : 0*
+ Domain0 Region00 : 0x0000000000000000-0x000000000003ffff ()
+ Domain0 Region01 : 0x00000000e6000000-0x00000000e60fffff (I,R)
+ Domain0 Region02 : 0x00000000e6400000-0x00000000e67fffff (I)
+ Domain0 Region03 : 0x0000000000000000-0xffffffffffffffff (R,W,X)
+ Domain0 Next Address : 0x0000000001800000
+ Domain0 Next Arg1 : 0x0000000001700000
+ Domain0 Next Mode : S-mode
+ Domain0 SysReset : yes
+
+ Boot HART ID : 0
+ Boot HART Domain : root
+ Boot HART Priv Version : v1.11
+ Boot HART Base ISA : rv64imafdcx
+ Boot HART ISA Extensions : none
+ Boot HART PMP Count : 8
+ Boot HART PMP Granularity : 4
+ Boot HART PMP Address Bits: 31
+ Boot HART MHPM Count : 4
+ Boot HART MHPM Bits : 64
+ Boot HART MIDELEG : 0x0000000000000222
+ Boot HART MEDELEG : 0x000000000000b109
+ [ 0.000000] Linux version 6.1.47-09019-g0584b09ad862-dirty
+ [ 0.000000] OF: fdt: Ignoring memory range 0x0 - 0x1800000
+ [ 0.000000] Machine model: andestech,ax25
+ [ 0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
+ [ 0.000000] printk: bootconsole [sbi0] enabled
+ [ 0.000000] Disabled 4-level and 5-level paging
+ [ 0.000000] efi: UEFI not found.
+ [ 0.000000] Zone ranges:
+ [ 0.000000] DMA32 [mem 0x0000000001800000-0x000000003fffffff]
+ [ 0.000000] Normal empty
+ [ 0.000000] Movable zone start for each node
+ [ 0.000000] Early memory node ranges
+ [ 0.000000] node 0: [mem 0x0000000001800000-0x000000003fffffff]
+ [ 0.000000] Initmem setup node 0 [mem 0x0000000001800000-0x000000003fffffff]
+ [ 0.000000] SBI specification v1.0 detected
+ [ 0.000000] SBI implementation ID=0x1 Version=0x10002
+ [ 0.000000] SBI TIME extension detected
+ [ 0.000000] SBI IPI extension detected
+ [ 0.000000] SBI RFENCE extension detected
+ [ 0.000000] SBI SRST extension detected
+ [ 0.000000] SBI HSM extension detected
+ [ 0.000000] riscv: base ISA extensions acim
+ [ 0.000000] riscv: ELF capabilities acim
+ [ 0.000000] percpu: Embedded 18 pages/cpu s35000 r8192 d30536 u73728
+ [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 252500
diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c
index eecfacd..a159093 100644
--- a/drivers/clk/aspeed/clk_ast2600.c
+++ b/drivers/clk/aspeed/clk_ast2600.c
@@ -1143,8 +1143,6 @@ static void ast2600_clk_dump(struct udevice *dev)
ret = clk_get_rate(&clk);
rate = ret;
- clk_free(&clk);
-
if (ret == -EINVAL) {
printf("clk ID %lu not supported yet\n",
aspeed_clk_names[i].id);
diff --git a/drivers/clk/at91/compat.c b/drivers/clk/at91/compat.c
index 2fdc2fb..ee67093 100644
--- a/drivers/clk/at91/compat.c
+++ b/drivers/clk/at91/compat.c
@@ -516,7 +516,6 @@ static ulong periph_get_rate(struct clk *clk)
{
struct udevice *dev;
struct clk clk_dev;
- ulong clk_rate;
int ret;
dev = dev_get_parent(clk->dev);
@@ -525,11 +524,7 @@ static ulong periph_get_rate(struct clk *clk)
if (ret)
return ret;
- clk_rate = clk_get_rate(&clk_dev);
-
- clk_free(&clk_dev);
-
- return clk_rate;
+ return clk_get_rate(&clk_dev);
}
static struct clk_ops periph_clk_ops = {
@@ -762,7 +757,6 @@ static ulong generic_clk_get_rate(struct clk *clk)
struct pmc_plat *plat = dev_get_plat(clk->dev);
struct at91_pmc *pmc = plat->reg_base;
struct clk parent;
- ulong clk_rate;
u32 tmp, gckdiv;
u8 clock_source, parent_index;
int ret;
@@ -778,11 +772,7 @@ static ulong generic_clk_get_rate(struct clk *clk)
if (ret)
return 0;
- clk_rate = clk_get_rate(&parent) / (gckdiv + 1);
-
- clk_free(&parent);
-
- return clk_rate;
+ return clk_get_rate(&parent) / (gckdiv + 1);
}
static ulong generic_clk_set_rate(struct clk *clk, ulong rate)
diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index 26d795b..4ed1430 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -3,19 +3,23 @@
* Copyright (C) 2023 Marek Vasut <marek.vasut+renesas@mailbox.org>
*/
-#include <asm/gpio.h>
-#include <common.h>
+#include <clk.h>
#include <clk-uclass.h>
#include <dm.h>
+#include <linux/clk-provider.h>
+
+#include <asm/gpio.h>
struct clk_gpio_priv {
- struct gpio_desc enable;
+ struct gpio_desc enable; /* GPIO, controlling the gate */
+ struct clk *clk; /* Gated clock */
};
static int clk_gpio_enable(struct clk *clk)
{
struct clk_gpio_priv *priv = dev_get_priv(clk->dev);
+ clk_enable(priv->clk);
dm_gpio_set_value(&priv->enable, 1);
return 0;
@@ -26,21 +30,45 @@ static int clk_gpio_disable(struct clk *clk)
struct clk_gpio_priv *priv = dev_get_priv(clk->dev);
dm_gpio_set_value(&priv->enable, 0);
+ clk_disable(priv->clk);
return 0;
}
+static ulong clk_gpio_get_rate(struct clk *clk)
+{
+ struct clk_gpio_priv *priv = dev_get_priv(clk->dev);
+
+ return clk_get_rate(priv->clk);
+}
+
const struct clk_ops clk_gpio_ops = {
.enable = clk_gpio_enable,
.disable = clk_gpio_disable,
+ .get_rate = clk_gpio_get_rate,
};
static int clk_gpio_probe(struct udevice *dev)
{
struct clk_gpio_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ log_debug("%s: Could not get gated clock: %ld\n",
+ __func__, PTR_ERR(priv->clk));
+ return PTR_ERR(priv->clk);
+ }
- return gpio_request_by_name(dev, "enable-gpios", 0,
- &priv->enable, GPIOD_IS_OUT);
+ ret = gpio_request_by_name(dev, "enable-gpios", 0,
+ &priv->enable, GPIOD_IS_OUT);
+ if (ret) {
+ log_debug("%s: Could not decode enable-gpios (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ return 0;
}
/*
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 3e9d68f..ed6e60b 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -437,8 +437,6 @@ int clk_release_all(struct clk *clk, unsigned int count)
ret = clk_disable(&clk[i]);
if (ret && ret != -ENOSYS)
return ret;
-
- clk_free(&clk[i]);
}
return 0;
@@ -461,24 +459,9 @@ int clk_request(struct udevice *dev, struct clk *clk)
return ops->request(clk);
}
-void clk_free(struct clk *clk)
-{
- const struct clk_ops *ops;
-
- debug("%s(clk=%p)\n", __func__, clk);
- if (!clk_valid(clk))
- return;
- ops = clk_dev_ops(clk->dev);
-
- if (ops->rfree)
- ops->rfree(clk);
- return;
-}
-
ulong clk_get_rate(struct clk *clk)
{
const struct clk_ops *ops;
- ulong ret;
debug("%s(clk=%p)\n", __func__, clk);
if (!clk_valid(clk))
@@ -488,11 +471,7 @@ ulong clk_get_rate(struct clk *clk)
if (!ops->get_rate)
return -ENOSYS;
- ret = ops->get_rate(clk);
- if (ret)
- return log_ret(ret);
-
- return 0;
+ return ops->get_rate(clk);
}
struct clk *clk_get_parent(struct clk *clk)
@@ -791,22 +770,12 @@ bool clk_is_match(const struct clk *p, const struct clk *q)
return false;
}
-static void devm_clk_release(struct udevice *dev, void *res)
-{
- clk_free(res);
-}
-
-static int devm_clk_match(struct udevice *dev, void *res, void *data)
-{
- return res == data;
-}
-
struct clk *devm_clk_get(struct udevice *dev, const char *id)
{
int rc;
struct clk *clk;
- clk = devres_alloc(devm_clk_release, sizeof(struct clk), __GFP_ZERO);
+ clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
if (unlikely(!clk))
return ERR_PTR(-ENOMEM);
@@ -814,21 +783,9 @@ struct clk *devm_clk_get(struct udevice *dev, const char *id)
if (rc)
return ERR_PTR(rc);
- devres_add(dev, clk);
return clk;
}
-void devm_clk_put(struct udevice *dev, struct clk *clk)
-{
- int rc;
-
- if (!clk)
- return;
-
- rc = devres_release(dev, devm_clk_release, devm_clk_match, clk);
- WARN_ON(rc);
-}
-
int clk_uclass_post_probe(struct udevice *dev)
{
/*
diff --git a/drivers/clk/clk-xlnx-clock-wizard.c b/drivers/clk/clk-xlnx-clock-wizard.c
index 70ee3af..a10a843 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -137,7 +137,6 @@ static int clk_wzrd_probe(struct udevice *dev)
ret = clk_enable(&clk_in1);
if (ret) {
dev_err(dev, "failed to enable clock\n");
- clk_free(&clk_in1);
return ret;
}
diff --git a/drivers/clk/clk_sandbox.c b/drivers/clk/clk_sandbox.c
index 636914d..73d943f 100644
--- a/drivers/clk/clk_sandbox.c
+++ b/drivers/clk/clk_sandbox.c
@@ -101,17 +101,6 @@ static int sandbox_clk_request(struct clk *clk)
return 0;
}
-static void sandbox_clk_free(struct clk *clk)
-{
- struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
-
- if (clk->id >= SANDBOX_CLK_ID_COUNT)
- return;
-
- priv->requested[clk->id] = false;
- return;
-}
-
static struct clk_ops sandbox_clk_ops = {
.round_rate = sandbox_clk_round_rate,
.get_rate = sandbox_clk_get_rate,
@@ -119,7 +108,6 @@ static struct clk_ops sandbox_clk_ops = {
.enable = sandbox_clk_enable,
.disable = sandbox_clk_disable,
.request = sandbox_clk_request,
- .rfree = sandbox_clk_free,
};
static int sandbox_clk_probe(struct udevice *dev)
diff --git a/drivers/clk/clk_sandbox_test.c b/drivers/clk/clk_sandbox_test.c
index c695b69..c224dc1 100644
--- a/drivers/clk/clk_sandbox_test.c
+++ b/drivers/clk/clk_sandbox_test.c
@@ -135,18 +135,6 @@ int sandbox_clk_test_disable_bulk(struct udevice *dev)
return clk_disable_bulk(&sbct->bulk);
}
-int sandbox_clk_test_free(struct udevice *dev)
-{
- struct sandbox_clk_test *sbct = dev_get_priv(dev);
- int i;
-
- devm_clk_put(dev, sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1]);
- for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++)
- clk_free(&sbct->clks[i]);
-
- return 0;
-}
-
int sandbox_clk_test_release_bulk(struct udevice *dev)
{
struct sandbox_clk_test *sbct = dev_get_priv(dev);
diff --git a/drivers/clk/clk_versaclock.c b/drivers/clk/clk_versaclock.c
index 699df3c..bbe7225 100644
--- a/drivers/clk/clk_versaclock.c
+++ b/drivers/clk/clk_versaclock.c
@@ -1000,26 +1000,18 @@ int versaclock_probe(struct udevice *dev)
return 0;
free_out:
- for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) {
- clk_free(&vc5->clk_out[n].hw);
+ for (n = 1; n < vc5->chip_info->clk_out_cnt; n++)
free(out_name[n]);
- }
free_selb:
- clk_free(&vc5->clk_out[0].hw);
free(outsel_name);
free_fod:
- for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) {
- clk_free(&vc5->clk_fod[n].hw);
+ for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++)
free(fod_name[n]);
- }
free_pll:
- clk_free(&vc5->clk_pll.hw);
free(pll_name);
free_pfd:
- clk_free(&vc5->clk_pfd);
free(pfd_name);
free_mux:
- clk_free(&vc5->clk_mux);
free(mux_name);
return ret;
diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c
index 34f964d..e3cefe2 100644
--- a/drivers/clk/clk_zynq.c
+++ b/drivers/clk/clk_zynq.c
@@ -491,8 +491,6 @@ static void zynq_clk_dump(struct udevice *dev)
rate = clk_get_rate(&clk);
- clk_free(&clk);
-
if ((rate == (unsigned long)-ENOSYS) ||
(rate == (unsigned long)-ENXIO))
printf("%10s%20s\n", name, "unknown");
diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c
index 0ffac19..e23f7da 100644
--- a/drivers/clk/clk_zynqmp.c
+++ b/drivers/clk/clk_zynqmp.c
@@ -757,8 +757,6 @@ static void zynqmp_clk_dump(struct udevice *dev)
rate = clk_get_rate(&clk);
- clk_free(&clk);
-
if ((rate == (unsigned long)-ENOSYS) ||
(rate == (unsigned long)-ENXIO) ||
(rate == (unsigned long)-EIO))
diff --git a/drivers/clk/imx/clk-imx8.c b/drivers/clk/imx/clk-imx8.c
index 9600672..d39b87b 100644
--- a/drivers/clk/imx/clk-imx8.c
+++ b/drivers/clk/imx/clk-imx8.c
@@ -62,8 +62,6 @@ static void imx8_clk_dump(struct udevice *dev)
ret = clk_get_rate(&clk);
rate = ret;
- clk_free(&clk);
-
if (ret == -EINVAL) {
printf("clk ID %lu not supported yet\n",
imx8_clk_names[i].id);
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index cdc9d6f..ee33c61 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -29,3 +29,13 @@ config CLK_MESON_A1
help
Enable clock support for the Amlogic A1 SoC family, such as
the A113L
+
+config CLK_MESON_MSR
+ bool "Enable clock measure driver for Amlogic SoCs"
+ depends on CLK && ARCH_MESON
+ depends on CMD_CLK
+ default ARCH_MESON
+ help
+ Enable measuring a set of internal Amlogic SoC clock frequencies
+ using the Hardware Clock Measure registers and print them using
+ the clk dump command.
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index d975f07..c7a446e 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_CLK_MESON_AXG) += axg-ao.o
obj-$(CONFIG_CLK_MESON_G12A) += g12a.o
obj-$(CONFIG_CLK_MESON_G12A) += g12a-ao.o
obj-$(CONFIG_CLK_MESON_A1) += a1.o
+obj-$(CONFIG_CLK_MESON_MSR) += clk-measure.o
diff --git a/drivers/clk/meson/clk-measure.c b/drivers/clk/meson/clk-measure.c
new file mode 100644
index 0000000..f653fc6
--- /dev/null
+++ b/drivers/clk/meson/clk-measure.c
@@ -0,0 +1,634 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Based on Linux driver from:
+ * (C) Copyright 2018 - BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * (C) Copyright 2023 - Neil Armstrong <neil.armstrong@linaro.org>
+ */
+
+#include <log.h>
+#include <clk-uclass.h>
+#include <div64.h>
+#include <dm.h>
+#include <time.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+
+#define MSR_CLK_DUTY 0x0
+#define MSR_CLK_REG0 0x4
+#define MSR_CLK_REG1 0x8
+#define MSR_CLK_REG2 0xc
+
+#define MSR_DURATION GENMASK(15, 0)
+#define MSR_ENABLE BIT(16)
+#define MSR_CONT BIT(17) /* continuous measurement */
+#define MSR_INTR BIT(18) /* interrupts */
+#define MSR_RUN BIT(19)
+#define MSR_CLK_SRC GENMASK(26, 20)
+#define MSR_BUSY BIT(31)
+
+#define MSR_VAL_MASK GENMASK(15, 0)
+
+#define DIV_MIN 32
+#define DIV_STEP 32
+#define DIV_MAX 640
+
+#define CLK_MSR_MAX 128
+
+struct meson_msr_id {
+ unsigned int id;
+ const char *name;
+};
+
+struct meson_msr {
+ struct regmap *regmap;
+ struct meson_msr_id *msr_table;
+};
+
+#define CLK_MSR_ID(__id, __name) \
+ [__id] = {.id = __id, .name = __name,}
+
+static struct meson_msr_id clk_msr_m8[CLK_MSR_MAX] = {
+ CLK_MSR_ID(0, "ring_osc_out_ee0"),
+ CLK_MSR_ID(1, "ring_osc_out_ee1"),
+ CLK_MSR_ID(2, "ring_osc_out_ee2"),
+ CLK_MSR_ID(3, "a9_ring_osck"),
+ CLK_MSR_ID(6, "vid_pll"),
+ CLK_MSR_ID(7, "clk81"),
+ CLK_MSR_ID(8, "encp"),
+ CLK_MSR_ID(9, "encl"),
+ CLK_MSR_ID(11, "eth_rmii"),
+ CLK_MSR_ID(13, "amclk"),
+ CLK_MSR_ID(14, "fec_clk_0"),
+ CLK_MSR_ID(15, "fec_clk_1"),
+ CLK_MSR_ID(16, "fec_clk_2"),
+ CLK_MSR_ID(18, "a9_clk_div16"),
+ CLK_MSR_ID(19, "hdmi_sys"),
+ CLK_MSR_ID(20, "rtc_osc_clk_out"),
+ CLK_MSR_ID(21, "i2s_clk_in_src0"),
+ CLK_MSR_ID(22, "clk_rmii_from_pad"),
+ CLK_MSR_ID(23, "hdmi_ch0_tmds"),
+ CLK_MSR_ID(24, "lvds_fifo"),
+ CLK_MSR_ID(26, "sc_clk_int"),
+ CLK_MSR_ID(28, "sar_adc"),
+ CLK_MSR_ID(30, "mpll_clk_test_out"),
+ CLK_MSR_ID(31, "audac_clkpi"),
+ CLK_MSR_ID(32, "vdac"),
+ CLK_MSR_ID(33, "sdhc_rx"),
+ CLK_MSR_ID(34, "sdhc_sd"),
+ CLK_MSR_ID(35, "mali"),
+ CLK_MSR_ID(36, "hdmi_tx_pixel"),
+ CLK_MSR_ID(38, "vdin_meas"),
+ CLK_MSR_ID(39, "pcm_sclk"),
+ CLK_MSR_ID(40, "pcm_mclk"),
+ CLK_MSR_ID(41, "eth_rx_tx"),
+ CLK_MSR_ID(42, "pwm_d"),
+ CLK_MSR_ID(43, "pwm_c"),
+ CLK_MSR_ID(44, "pwm_b"),
+ CLK_MSR_ID(45, "pwm_a"),
+ CLK_MSR_ID(46, "pcm2_sclk"),
+ CLK_MSR_ID(47, "ddr_dpll_pt"),
+ CLK_MSR_ID(48, "pwm_f"),
+ CLK_MSR_ID(49, "pwm_e"),
+ CLK_MSR_ID(59, "hcodec"),
+ CLK_MSR_ID(60, "usb_32k_alt"),
+ CLK_MSR_ID(61, "gpio"),
+ CLK_MSR_ID(62, "vid2_pll"),
+ CLK_MSR_ID(63, "mipi_csi_cfg"),
+};
+
+static struct meson_msr_id clk_msr_gx[CLK_MSR_MAX] = {
+ CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+ CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+ CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+ CLK_MSR_ID(3, "a53_ring_osc"),
+ CLK_MSR_ID(4, "gp0_pll"),
+ CLK_MSR_ID(6, "enci"),
+ CLK_MSR_ID(7, "clk81"),
+ CLK_MSR_ID(8, "encp"),
+ CLK_MSR_ID(9, "encl"),
+ CLK_MSR_ID(10, "vdac"),
+ CLK_MSR_ID(11, "rgmii_tx"),
+ CLK_MSR_ID(12, "pdm"),
+ CLK_MSR_ID(13, "amclk"),
+ CLK_MSR_ID(14, "fec_0"),
+ CLK_MSR_ID(15, "fec_1"),
+ CLK_MSR_ID(16, "fec_2"),
+ CLK_MSR_ID(17, "sys_pll_div16"),
+ CLK_MSR_ID(18, "sys_cpu_div16"),
+ CLK_MSR_ID(19, "hdmitx_sys"),
+ CLK_MSR_ID(20, "rtc_osc_out"),
+ CLK_MSR_ID(21, "i2s_in_src0"),
+ CLK_MSR_ID(22, "eth_phy_ref"),
+ CLK_MSR_ID(23, "hdmi_todig"),
+ CLK_MSR_ID(26, "sc_int"),
+ CLK_MSR_ID(28, "sar_adc"),
+ CLK_MSR_ID(31, "mpll_test_out"),
+ CLK_MSR_ID(32, "vdec"),
+ CLK_MSR_ID(35, "mali"),
+ CLK_MSR_ID(36, "hdmi_tx_pixel"),
+ CLK_MSR_ID(37, "i958"),
+ CLK_MSR_ID(38, "vdin_meas"),
+ CLK_MSR_ID(39, "pcm_sclk"),
+ CLK_MSR_ID(40, "pcm_mclk"),
+ CLK_MSR_ID(41, "eth_rx_or_rmii"),
+ CLK_MSR_ID(42, "mp0_out"),
+ CLK_MSR_ID(43, "fclk_div5"),
+ CLK_MSR_ID(44, "pwm_b"),
+ CLK_MSR_ID(45, "pwm_a"),
+ CLK_MSR_ID(46, "vpu"),
+ CLK_MSR_ID(47, "ddr_dpll_pt"),
+ CLK_MSR_ID(48, "mp1_out"),
+ CLK_MSR_ID(49, "mp2_out"),
+ CLK_MSR_ID(50, "mp3_out"),
+ CLK_MSR_ID(51, "nand_core"),
+ CLK_MSR_ID(52, "sd_emmc_b"),
+ CLK_MSR_ID(53, "sd_emmc_a"),
+ CLK_MSR_ID(55, "vid_pll_div_out"),
+ CLK_MSR_ID(56, "cci"),
+ CLK_MSR_ID(57, "wave420l_c"),
+ CLK_MSR_ID(58, "wave420l_b"),
+ CLK_MSR_ID(59, "hcodec"),
+ CLK_MSR_ID(60, "alt_32k"),
+ CLK_MSR_ID(61, "gpio_msr"),
+ CLK_MSR_ID(62, "hevc"),
+ CLK_MSR_ID(66, "vid_lock"),
+ CLK_MSR_ID(70, "pwm_f"),
+ CLK_MSR_ID(71, "pwm_e"),
+ CLK_MSR_ID(72, "pwm_d"),
+ CLK_MSR_ID(73, "pwm_c"),
+ CLK_MSR_ID(75, "aoclkx2_int"),
+ CLK_MSR_ID(76, "aoclk_int"),
+ CLK_MSR_ID(77, "rng_ring_osc_0"),
+ CLK_MSR_ID(78, "rng_ring_osc_1"),
+ CLK_MSR_ID(79, "rng_ring_osc_2"),
+ CLK_MSR_ID(80, "rng_ring_osc_3"),
+ CLK_MSR_ID(81, "vapb"),
+ CLK_MSR_ID(82, "ge2d"),
+};
+
+static struct meson_msr_id clk_msr_axg[CLK_MSR_MAX] = {
+ CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+ CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+ CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+ CLK_MSR_ID(3, "a53_ring_osc"),
+ CLK_MSR_ID(4, "gp0_pll"),
+ CLK_MSR_ID(5, "gp1_pll"),
+ CLK_MSR_ID(7, "clk81"),
+ CLK_MSR_ID(9, "encl"),
+ CLK_MSR_ID(17, "sys_pll_div16"),
+ CLK_MSR_ID(18, "sys_cpu_div16"),
+ CLK_MSR_ID(20, "rtc_osc_out"),
+ CLK_MSR_ID(23, "mmc_clk"),
+ CLK_MSR_ID(28, "sar_adc"),
+ CLK_MSR_ID(31, "mpll_test_out"),
+ CLK_MSR_ID(40, "mod_eth_tx_clk"),
+ CLK_MSR_ID(41, "mod_eth_rx_clk_rmii"),
+ CLK_MSR_ID(42, "mp0_out"),
+ CLK_MSR_ID(43, "fclk_div5"),
+ CLK_MSR_ID(44, "pwm_b"),
+ CLK_MSR_ID(45, "pwm_a"),
+ CLK_MSR_ID(46, "vpu"),
+ CLK_MSR_ID(47, "ddr_dpll_pt"),
+ CLK_MSR_ID(48, "mp1_out"),
+ CLK_MSR_ID(49, "mp2_out"),
+ CLK_MSR_ID(50, "mp3_out"),
+ CLK_MSR_ID(51, "sd_emmm_c"),
+ CLK_MSR_ID(52, "sd_emmc_b"),
+ CLK_MSR_ID(61, "gpio_msr"),
+ CLK_MSR_ID(66, "audio_slv_lrclk_c"),
+ CLK_MSR_ID(67, "audio_slv_lrclk_b"),
+ CLK_MSR_ID(68, "audio_slv_lrclk_a"),
+ CLK_MSR_ID(69, "audio_slv_sclk_c"),
+ CLK_MSR_ID(70, "audio_slv_sclk_b"),
+ CLK_MSR_ID(71, "audio_slv_sclk_a"),
+ CLK_MSR_ID(72, "pwm_d"),
+ CLK_MSR_ID(73, "pwm_c"),
+ CLK_MSR_ID(74, "wifi_beacon"),
+ CLK_MSR_ID(75, "tdmin_lb_lrcl"),
+ CLK_MSR_ID(76, "tdmin_lb_sclk"),
+ CLK_MSR_ID(77, "rng_ring_osc_0"),
+ CLK_MSR_ID(78, "rng_ring_osc_1"),
+ CLK_MSR_ID(79, "rng_ring_osc_2"),
+ CLK_MSR_ID(80, "rng_ring_osc_3"),
+ CLK_MSR_ID(81, "vapb"),
+ CLK_MSR_ID(82, "ge2d"),
+ CLK_MSR_ID(84, "audio_resample"),
+ CLK_MSR_ID(85, "audio_pdm_sys"),
+ CLK_MSR_ID(86, "audio_spdifout"),
+ CLK_MSR_ID(87, "audio_spdifin"),
+ CLK_MSR_ID(88, "audio_lrclk_f"),
+ CLK_MSR_ID(89, "audio_lrclk_e"),
+ CLK_MSR_ID(90, "audio_lrclk_d"),
+ CLK_MSR_ID(91, "audio_lrclk_c"),
+ CLK_MSR_ID(92, "audio_lrclk_b"),
+ CLK_MSR_ID(93, "audio_lrclk_a"),
+ CLK_MSR_ID(94, "audio_sclk_f"),
+ CLK_MSR_ID(95, "audio_sclk_e"),
+ CLK_MSR_ID(96, "audio_sclk_d"),
+ CLK_MSR_ID(97, "audio_sclk_c"),
+ CLK_MSR_ID(98, "audio_sclk_b"),
+ CLK_MSR_ID(99, "audio_sclk_a"),
+ CLK_MSR_ID(100, "audio_mclk_f"),
+ CLK_MSR_ID(101, "audio_mclk_e"),
+ CLK_MSR_ID(102, "audio_mclk_d"),
+ CLK_MSR_ID(103, "audio_mclk_c"),
+ CLK_MSR_ID(104, "audio_mclk_b"),
+ CLK_MSR_ID(105, "audio_mclk_a"),
+ CLK_MSR_ID(106, "pcie_refclk_n"),
+ CLK_MSR_ID(107, "pcie_refclk_p"),
+ CLK_MSR_ID(108, "audio_locker_out"),
+ CLK_MSR_ID(109, "audio_locker_in"),
+};
+
+static struct meson_msr_id clk_msr_g12a[CLK_MSR_MAX] = {
+ CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+ CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+ CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+ CLK_MSR_ID(3, "sys_cpu_ring_osc"),
+ CLK_MSR_ID(4, "gp0_pll"),
+ CLK_MSR_ID(6, "enci"),
+ CLK_MSR_ID(7, "clk81"),
+ CLK_MSR_ID(8, "encp"),
+ CLK_MSR_ID(9, "encl"),
+ CLK_MSR_ID(10, "vdac"),
+ CLK_MSR_ID(11, "eth_tx"),
+ CLK_MSR_ID(12, "hifi_pll"),
+ CLK_MSR_ID(13, "mod_tcon"),
+ CLK_MSR_ID(14, "fec_0"),
+ CLK_MSR_ID(15, "fec_1"),
+ CLK_MSR_ID(16, "fec_2"),
+ CLK_MSR_ID(17, "sys_pll_div16"),
+ CLK_MSR_ID(18, "sys_cpu_div16"),
+ CLK_MSR_ID(19, "lcd_an_ph2"),
+ CLK_MSR_ID(20, "rtc_osc_out"),
+ CLK_MSR_ID(21, "lcd_an_ph3"),
+ CLK_MSR_ID(22, "eth_phy_ref"),
+ CLK_MSR_ID(23, "mpll_50m"),
+ CLK_MSR_ID(24, "eth_125m"),
+ CLK_MSR_ID(25, "eth_rmii"),
+ CLK_MSR_ID(26, "sc_int"),
+ CLK_MSR_ID(27, "in_mac"),
+ CLK_MSR_ID(28, "sar_adc"),
+ CLK_MSR_ID(29, "pcie_inp"),
+ CLK_MSR_ID(30, "pcie_inn"),
+ CLK_MSR_ID(31, "mpll_test_out"),
+ CLK_MSR_ID(32, "vdec"),
+ CLK_MSR_ID(33, "sys_cpu_ring_osc_1"),
+ CLK_MSR_ID(34, "eth_mpll_50m"),
+ CLK_MSR_ID(35, "mali"),
+ CLK_MSR_ID(36, "hdmi_tx_pixel"),
+ CLK_MSR_ID(37, "cdac"),
+ CLK_MSR_ID(38, "vdin_meas"),
+ CLK_MSR_ID(39, "bt656"),
+ CLK_MSR_ID(41, "eth_rx_or_rmii"),
+ CLK_MSR_ID(42, "mp0_out"),
+ CLK_MSR_ID(43, "fclk_div5"),
+ CLK_MSR_ID(44, "pwm_b"),
+ CLK_MSR_ID(45, "pwm_a"),
+ CLK_MSR_ID(46, "vpu"),
+ CLK_MSR_ID(47, "ddr_dpll_pt"),
+ CLK_MSR_ID(48, "mp1_out"),
+ CLK_MSR_ID(49, "mp2_out"),
+ CLK_MSR_ID(50, "mp3_out"),
+ CLK_MSR_ID(51, "sd_emmc_c"),
+ CLK_MSR_ID(52, "sd_emmc_b"),
+ CLK_MSR_ID(53, "sd_emmc_a"),
+ CLK_MSR_ID(54, "vpu_clkc"),
+ CLK_MSR_ID(55, "vid_pll_div_out"),
+ CLK_MSR_ID(56, "wave420l_a"),
+ CLK_MSR_ID(57, "wave420l_c"),
+ CLK_MSR_ID(58, "wave420l_b"),
+ CLK_MSR_ID(59, "hcodec"),
+ CLK_MSR_ID(61, "gpio_msr"),
+ CLK_MSR_ID(62, "hevcb"),
+ CLK_MSR_ID(63, "dsi_meas"),
+ CLK_MSR_ID(64, "spicc_1"),
+ CLK_MSR_ID(65, "spicc_0"),
+ CLK_MSR_ID(66, "vid_lock"),
+ CLK_MSR_ID(67, "dsi_phy"),
+ CLK_MSR_ID(68, "hdcp22_esm"),
+ CLK_MSR_ID(69, "hdcp22_skp"),
+ CLK_MSR_ID(70, "pwm_f"),
+ CLK_MSR_ID(71, "pwm_e"),
+ CLK_MSR_ID(72, "pwm_d"),
+ CLK_MSR_ID(73, "pwm_c"),
+ CLK_MSR_ID(75, "hevcf"),
+ CLK_MSR_ID(77, "rng_ring_osc_0"),
+ CLK_MSR_ID(78, "rng_ring_osc_1"),
+ CLK_MSR_ID(79, "rng_ring_osc_2"),
+ CLK_MSR_ID(80, "rng_ring_osc_3"),
+ CLK_MSR_ID(81, "vapb"),
+ CLK_MSR_ID(82, "ge2d"),
+ CLK_MSR_ID(83, "co_rx"),
+ CLK_MSR_ID(84, "co_tx"),
+ CLK_MSR_ID(89, "hdmi_todig"),
+ CLK_MSR_ID(90, "hdmitx_sys"),
+ CLK_MSR_ID(91, "sys_cpub_div16"),
+ CLK_MSR_ID(92, "sys_pll_cpub_div16"),
+ CLK_MSR_ID(94, "eth_phy_rx"),
+ CLK_MSR_ID(95, "eth_phy_pll"),
+ CLK_MSR_ID(96, "vpu_b"),
+ CLK_MSR_ID(97, "cpu_b_tmp"),
+ CLK_MSR_ID(98, "ts"),
+ CLK_MSR_ID(99, "ring_osc_out_ee_3"),
+ CLK_MSR_ID(100, "ring_osc_out_ee_4"),
+ CLK_MSR_ID(101, "ring_osc_out_ee_5"),
+ CLK_MSR_ID(102, "ring_osc_out_ee_6"),
+ CLK_MSR_ID(103, "ring_osc_out_ee_7"),
+ CLK_MSR_ID(104, "ring_osc_out_ee_8"),
+ CLK_MSR_ID(105, "ring_osc_out_ee_9"),
+ CLK_MSR_ID(106, "ephy_test"),
+ CLK_MSR_ID(107, "au_dac_g128x"),
+ CLK_MSR_ID(108, "audio_locker_out"),
+ CLK_MSR_ID(109, "audio_locker_in"),
+ CLK_MSR_ID(110, "audio_tdmout_c_sclk"),
+ CLK_MSR_ID(111, "audio_tdmout_b_sclk"),
+ CLK_MSR_ID(112, "audio_tdmout_a_sclk"),
+ CLK_MSR_ID(113, "audio_tdmin_lb_sclk"),
+ CLK_MSR_ID(114, "audio_tdmin_c_sclk"),
+ CLK_MSR_ID(115, "audio_tdmin_b_sclk"),
+ CLK_MSR_ID(116, "audio_tdmin_a_sclk"),
+ CLK_MSR_ID(117, "audio_resample"),
+ CLK_MSR_ID(118, "audio_pdm_sys"),
+ CLK_MSR_ID(119, "audio_spdifout_b"),
+ CLK_MSR_ID(120, "audio_spdifout"),
+ CLK_MSR_ID(121, "audio_spdifin"),
+ CLK_MSR_ID(122, "audio_pdm_dclk"),
+};
+
+static struct meson_msr_id clk_msr_sm1[CLK_MSR_MAX] = {
+ CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+ CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+ CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+ CLK_MSR_ID(3, "ring_osc_out_ee_3"),
+ CLK_MSR_ID(4, "gp0_pll"),
+ CLK_MSR_ID(5, "gp1_pll"),
+ CLK_MSR_ID(6, "enci"),
+ CLK_MSR_ID(7, "clk81"),
+ CLK_MSR_ID(8, "encp"),
+ CLK_MSR_ID(9, "encl"),
+ CLK_MSR_ID(10, "vdac"),
+ CLK_MSR_ID(11, "eth_tx"),
+ CLK_MSR_ID(12, "hifi_pll"),
+ CLK_MSR_ID(13, "mod_tcon"),
+ CLK_MSR_ID(14, "fec_0"),
+ CLK_MSR_ID(15, "fec_1"),
+ CLK_MSR_ID(16, "fec_2"),
+ CLK_MSR_ID(17, "sys_pll_div16"),
+ CLK_MSR_ID(18, "sys_cpu_div16"),
+ CLK_MSR_ID(19, "lcd_an_ph2"),
+ CLK_MSR_ID(20, "rtc_osc_out"),
+ CLK_MSR_ID(21, "lcd_an_ph3"),
+ CLK_MSR_ID(22, "eth_phy_ref"),
+ CLK_MSR_ID(23, "mpll_50m"),
+ CLK_MSR_ID(24, "eth_125m"),
+ CLK_MSR_ID(25, "eth_rmii"),
+ CLK_MSR_ID(26, "sc_int"),
+ CLK_MSR_ID(27, "in_mac"),
+ CLK_MSR_ID(28, "sar_adc"),
+ CLK_MSR_ID(29, "pcie_inp"),
+ CLK_MSR_ID(30, "pcie_inn"),
+ CLK_MSR_ID(31, "mpll_test_out"),
+ CLK_MSR_ID(32, "vdec"),
+ CLK_MSR_ID(34, "eth_mpll_50m"),
+ CLK_MSR_ID(35, "mali"),
+ CLK_MSR_ID(36, "hdmi_tx_pixel"),
+ CLK_MSR_ID(37, "cdac"),
+ CLK_MSR_ID(38, "vdin_meas"),
+ CLK_MSR_ID(39, "bt656"),
+ CLK_MSR_ID(40, "arm_ring_osc_out_4"),
+ CLK_MSR_ID(41, "eth_rx_or_rmii"),
+ CLK_MSR_ID(42, "mp0_out"),
+ CLK_MSR_ID(43, "fclk_div5"),
+ CLK_MSR_ID(44, "pwm_b"),
+ CLK_MSR_ID(45, "pwm_a"),
+ CLK_MSR_ID(46, "vpu"),
+ CLK_MSR_ID(47, "ddr_dpll_pt"),
+ CLK_MSR_ID(48, "mp1_out"),
+ CLK_MSR_ID(49, "mp2_out"),
+ CLK_MSR_ID(50, "mp3_out"),
+ CLK_MSR_ID(51, "sd_emmc_c"),
+ CLK_MSR_ID(52, "sd_emmc_b"),
+ CLK_MSR_ID(53, "sd_emmc_a"),
+ CLK_MSR_ID(54, "vpu_clkc"),
+ CLK_MSR_ID(55, "vid_pll_div_out"),
+ CLK_MSR_ID(56, "wave420l_a"),
+ CLK_MSR_ID(57, "wave420l_c"),
+ CLK_MSR_ID(58, "wave420l_b"),
+ CLK_MSR_ID(59, "hcodec"),
+ CLK_MSR_ID(60, "arm_ring_osc_out_5"),
+ CLK_MSR_ID(61, "gpio_msr"),
+ CLK_MSR_ID(62, "hevcb"),
+ CLK_MSR_ID(63, "dsi_meas"),
+ CLK_MSR_ID(64, "spicc_1"),
+ CLK_MSR_ID(65, "spicc_0"),
+ CLK_MSR_ID(66, "vid_lock"),
+ CLK_MSR_ID(67, "dsi_phy"),
+ CLK_MSR_ID(68, "hdcp22_esm"),
+ CLK_MSR_ID(69, "hdcp22_skp"),
+ CLK_MSR_ID(70, "pwm_f"),
+ CLK_MSR_ID(71, "pwm_e"),
+ CLK_MSR_ID(72, "pwm_d"),
+ CLK_MSR_ID(73, "pwm_c"),
+ CLK_MSR_ID(74, "arm_ring_osc_out_6"),
+ CLK_MSR_ID(75, "hevcf"),
+ CLK_MSR_ID(76, "arm_ring_osc_out_7"),
+ CLK_MSR_ID(77, "rng_ring_osc_0"),
+ CLK_MSR_ID(78, "rng_ring_osc_1"),
+ CLK_MSR_ID(79, "rng_ring_osc_2"),
+ CLK_MSR_ID(80, "rng_ring_osc_3"),
+ CLK_MSR_ID(81, "vapb"),
+ CLK_MSR_ID(82, "ge2d"),
+ CLK_MSR_ID(83, "co_rx"),
+ CLK_MSR_ID(84, "co_tx"),
+ CLK_MSR_ID(85, "arm_ring_osc_out_8"),
+ CLK_MSR_ID(86, "arm_ring_osc_out_9"),
+ CLK_MSR_ID(87, "mipi_dsi_phy"),
+ CLK_MSR_ID(88, "cis2_adapt"),
+ CLK_MSR_ID(89, "hdmi_todig"),
+ CLK_MSR_ID(90, "hdmitx_sys"),
+ CLK_MSR_ID(91, "nna_core"),
+ CLK_MSR_ID(92, "nna_axi"),
+ CLK_MSR_ID(93, "vad"),
+ CLK_MSR_ID(94, "eth_phy_rx"),
+ CLK_MSR_ID(95, "eth_phy_pll"),
+ CLK_MSR_ID(96, "vpu_b"),
+ CLK_MSR_ID(97, "cpu_b_tmp"),
+ CLK_MSR_ID(98, "ts"),
+ CLK_MSR_ID(99, "arm_ring_osc_out_10"),
+ CLK_MSR_ID(100, "arm_ring_osc_out_11"),
+ CLK_MSR_ID(101, "arm_ring_osc_out_12"),
+ CLK_MSR_ID(102, "arm_ring_osc_out_13"),
+ CLK_MSR_ID(103, "arm_ring_osc_out_14"),
+ CLK_MSR_ID(104, "arm_ring_osc_out_15"),
+ CLK_MSR_ID(105, "arm_ring_osc_out_16"),
+ CLK_MSR_ID(106, "ephy_test"),
+ CLK_MSR_ID(107, "au_dac_g128x"),
+ CLK_MSR_ID(108, "audio_locker_out"),
+ CLK_MSR_ID(109, "audio_locker_in"),
+ CLK_MSR_ID(110, "audio_tdmout_c_sclk"),
+ CLK_MSR_ID(111, "audio_tdmout_b_sclk"),
+ CLK_MSR_ID(112, "audio_tdmout_a_sclk"),
+ CLK_MSR_ID(113, "audio_tdmin_lb_sclk"),
+ CLK_MSR_ID(114, "audio_tdmin_c_sclk"),
+ CLK_MSR_ID(115, "audio_tdmin_b_sclk"),
+ CLK_MSR_ID(116, "audio_tdmin_a_sclk"),
+ CLK_MSR_ID(117, "audio_resample"),
+ CLK_MSR_ID(118, "audio_pdm_sys"),
+ CLK_MSR_ID(119, "audio_spdifout_b"),
+ CLK_MSR_ID(120, "audio_spdifout"),
+ CLK_MSR_ID(121, "audio_spdifin"),
+ CLK_MSR_ID(122, "audio_pdm_dclk"),
+ CLK_MSR_ID(123, "audio_resampled"),
+ CLK_MSR_ID(124, "earcrx_pll"),
+ CLK_MSR_ID(125, "earcrx_pll_test"),
+ CLK_MSR_ID(126, "csi_phy0"),
+ CLK_MSR_ID(127, "csi2_data"),
+};
+
+static int meson_clk_msr_measure_id(struct meson_msr *priv, unsigned int id,
+ unsigned int duration)
+{
+ unsigned int val;
+ int ret;
+
+ regmap_write(priv->regmap, MSR_CLK_REG0, 0);
+
+ /* Set measurement duration */
+ regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_DURATION,
+ FIELD_PREP(MSR_DURATION, duration - 1));
+
+ /* Set ID */
+ regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_CLK_SRC,
+ FIELD_PREP(MSR_CLK_SRC, id));
+
+ /* Enable & Start */
+ regmap_update_bits(priv->regmap, MSR_CLK_REG0,
+ MSR_RUN | MSR_ENABLE,
+ MSR_RUN | MSR_ENABLE);
+
+ ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0,
+ val, !(val & MSR_BUSY), 10, 10000);
+ if (ret)
+ return ret;
+
+ /* Disable */
+ regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0);
+
+ /* Get the value in multiple of gate time counts */
+ regmap_read(priv->regmap, MSR_CLK_REG2, &val);
+
+ if (val >= MSR_VAL_MASK)
+ return -EINVAL;
+
+ return DIV_ROUND_CLOSEST_ULL((val & MSR_VAL_MASK) * 1000000ULL,
+ duration);
+}
+
+static int meson_clk_msr_best_id(struct meson_msr *priv, unsigned int id,
+ unsigned int *precision)
+{
+ unsigned int duration = DIV_MAX;
+ int ret;
+
+ /* Start from max duration and down to min duration */
+ do {
+ ret = meson_clk_msr_measure_id(priv, id, duration);
+ if (ret >= 0)
+ *precision = (2 * 1000000) / duration;
+ else
+ duration -= DIV_STEP;
+ } while (duration >= DIV_MIN && ret == -EINVAL);
+
+ return ret;
+}
+
+static void meson_clk_msr_dump(struct udevice *dev)
+{
+ struct meson_msr *priv = dev_get_priv(dev);
+ unsigned int precision = 0;
+ int val, i;
+
+ printf(" clock rate precision\n");
+ printf("---------------------------------------------\n");
+
+ for (i = 0 ; i < CLK_MSR_MAX ; ++i) {
+ if (!priv->msr_table[i].name)
+ continue;
+
+ val = meson_clk_msr_best_id(priv, i, &precision);
+ if (val < 0)
+ return;
+
+ printf(" %-20s %10d +/-%dHz\n",
+ priv->msr_table[i].name, val, precision);
+ }
+}
+
+static int meson_clk_msr_xlate(struct clk *clk, struct ofnode_phandle_args *args)
+{
+ /* This driver doesn't expose any clocks */
+ return -EINVAL;
+}
+
+static int meson_clk_msr_probe(struct udevice *dev)
+{
+ struct meson_msr *priv = dev_get_priv(dev);
+ int ret;
+
+ priv->msr_table = (struct meson_msr_id *)dev_get_driver_data(dev);
+
+ ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct clk_ops meson_clk_msr_ops = {
+ .of_xlate = meson_clk_msr_xlate,
+ .dump = meson_clk_msr_dump,
+};
+
+static const struct udevice_id meson_clk_msr_ids[] = {
+ {
+ .compatible = "amlogic,meson-gx-clk-measure",
+ .data = (ulong)clk_msr_gx,
+ },
+ {
+ .compatible = "amlogic,meson8-clk-measure",
+ .data = (ulong)clk_msr_m8,
+ },
+ {
+ .compatible = "amlogic,meson8b-clk-measure",
+ .data = (ulong)clk_msr_m8,
+ },
+ {
+ .compatible = "amlogic,meson-axg-clk-measure",
+ .data = (ulong)clk_msr_axg,
+ },
+ {
+ .compatible = "amlogic,meson-g12a-clk-measure",
+ .data = (ulong)clk_msr_g12a,
+ },
+ {
+ .compatible = "amlogic,meson-sm1-clk-measure",
+ .data = (ulong)clk_msr_sm1,
+ },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(meson_clk_msr) = {
+ .name = "meson_clk_msr",
+ .id = UCLASS_CLK,
+ .of_match = meson_clk_msr_ids,
+ .priv_auto = sizeof(struct meson_msr),
+ .ops = &meson_clk_msr_ops,
+ .probe = meson_clk_msr_probe,
+};
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
index 1a70970..f5c9bd7 100644
--- a/drivers/clk/mvebu/armada-37xx-periph.c
+++ b/drivers/clk/mvebu/armada-37xx-periph.c
@@ -454,7 +454,6 @@ static int armada_37xx_periph_clk_set_parent(struct clk *clk,
if (parent->dev != check_parent.dev)
ret = -EINVAL;
- clk_free(&check_parent);
if (ret < 0)
return ret;
@@ -596,7 +595,6 @@ static int armada_37xx_periph_clk_probe(struct udevice *dev)
}
priv->parents[i] = clk_get_rate(&clk);
- clk_free(&clk);
}
return 0;
diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c
index 034b9b4..5d1026b 100644
--- a/drivers/cpu/riscv_cpu.c
+++ b/drivers/cpu/riscv_cpu.c
@@ -11,6 +11,7 @@
#include <errno.h>
#include <log.h>
#include <asm/global_data.h>
+#include <asm/sbi.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <linux/bitops.h>
@@ -45,7 +46,6 @@ static int riscv_cpu_get_info(const struct udevice *dev, struct cpu_info *info)
ret = clk_get_rate(&clk);
if (!IS_ERR_VALUE(ret))
info->cpu_freq = ret;
- clk_free(&clk);
}
if (!info->cpu_freq)
@@ -95,13 +95,24 @@ static int riscv_cpu_bind(struct udevice *dev)
struct cpu_plat *plat = dev_get_parent_plat(dev);
struct driver *drv;
int ret;
+ long mvendorid;
/* save the hart id */
plat->cpu_id = dev_read_addr(dev);
+ /* provide data for SMBIOS */
if (IS_ENABLED(CONFIG_64BIT))
plat->family = 0x201;
else
plat->family = 0x200;
+ if (CONFIG_IS_ENABLED(RISCV_SMODE)) {
+ /*
+ * For RISC-V CPUs the SMBIOS Processor ID field contains
+ * the Machine Vendor ID from CSR mvendorid.
+ */
+ ret = sbi_get_mvendorid(&mvendorid);
+ if (!ret)
+ plat->id[0] = mvendorid;
+ }
/* first examine the property in current cpu node */
ret = dev_read_u32(dev, "timebase-frequency", &plat->timebase_freq);
/* if not found, then look at the parent /cpus node */
@@ -145,7 +156,6 @@ static int riscv_cpu_probe(struct udevice *dev)
return 0;
ret = clk_enable(&clk);
- clk_free(&clk);
if (ret == -ENOSYS || ret == -ENOTSUPP)
return 0;
else
diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c
index d4cfe0c..33c7b98 100644
--- a/drivers/dma/bcm6348-iudma.c
+++ b/drivers/dma/bcm6348-iudma.c
@@ -596,8 +596,6 @@ static int bcm6348_iudma_probe(struct udevice *dev)
pr_err("error enabling clock %d\n", i);
return ret;
}
-
- clk_free(&clk);
}
/* try to perform resets */
diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c
index 1409db5..f80f4af 100644
--- a/drivers/gpio/at91_gpio.c
+++ b/drivers/gpio/at91_gpio.c
@@ -603,8 +603,6 @@ static int at91_gpio_probe(struct udevice *dev)
if (ret)
return ret;
- clk_free(&clk);
-
#if CONFIG_IS_ENABLED(OF_CONTROL)
plat->base_addr = dev_read_addr(dev);
#endif
diff --git a/drivers/gpio/atmel_pio4.c b/drivers/gpio/atmel_pio4.c
index 47ed297..be1dd75 100644
--- a/drivers/gpio/atmel_pio4.c
+++ b/drivers/gpio/atmel_pio4.c
@@ -310,8 +310,6 @@ static int atmel_pio4_probe(struct udevice *dev)
if (ret)
return ret;
- clk_free(&clk);
-
addr_base = dev_read_addr(dev);
if (addr_base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index d6cfbd2..7077850 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -165,7 +165,6 @@ static int rcar_gpio_probe(struct udevice *dev)
}
ret = clk_enable(&clk);
- clk_free(&clk);
if (ret) {
dev_err(dev, "Failed to enable GPIO bank clock\n");
return ret;
diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
index 46ed646..346b138 100644
--- a/drivers/hwspinlock/stm32_hwspinlock.c
+++ b/drivers/hwspinlock/stm32_hwspinlock.c
@@ -69,11 +69,7 @@ static int stm32mp1_hwspinlock_probe(struct udevice *dev)
if (ret)
return ret;
- ret = clk_enable(&clk);
- if (ret)
- clk_free(&clk);
-
- return ret;
+ return clk_enable(&clk);
}
static const struct hwspinlock_ops stm32mp1_hwspinlock_ops = {
diff --git a/drivers/i2c/at91_i2c.c b/drivers/i2c/at91_i2c.c
index e743d2a..b7a2588 100644
--- a/drivers/i2c/at91_i2c.c
+++ b/drivers/i2c/at91_i2c.c
@@ -201,8 +201,6 @@ static int at91_i2c_enable_clk(struct udevice *dev)
bus->bus_clk_rate = clk_rate;
- clk_free(&clk);
-
return 0;
}
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 215ce01..29cf633 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -770,7 +770,6 @@ int designware_i2c_of_to_plat(struct udevice *bus)
ret = clk_enable(&priv->clk);
if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
- clk_free(&priv->clk);
dev_err(bus, "failed to enable clock\n");
return ret;
}
@@ -803,7 +802,6 @@ int designware_i2c_remove(struct udevice *dev)
#if CONFIG_IS_ENABLED(CLK)
clk_disable(&priv->clk);
- clk_free(&priv->clk);
#endif
return reset_release_bulk(&priv->resets);
diff --git a/drivers/i2c/i2c-microchip.c b/drivers/i2c/i2c-microchip.c
index d82b80f..d453e24 100644
--- a/drivers/i2c/i2c-microchip.c
+++ b/drivers/i2c/i2c-microchip.c
@@ -183,8 +183,6 @@ static int mpfs_i2c_init(struct mpfs_i2c_bus *bus, struct udevice *dev)
if (!clk_rate)
return -EINVAL;
- clk_free(&bus->i2c_clk);
-
divisor = clk_rate / bus->clk_rate;
ctrl = readl(bus->base + MPFS_I2C_CTRL);
diff --git a/drivers/i2c/npcm_i2c.c b/drivers/i2c/npcm_i2c.c
index b867b6c..c64752e 100644
--- a/drivers/i2c/npcm_i2c.c
+++ b/drivers/i2c/npcm_i2c.c
@@ -570,7 +570,6 @@ static int npcm_i2c_probe(struct udevice *dev)
printf("%s: fail to get rate\n", __func__);
return -EINVAL;
}
- clk_free(&clk);
bus->num = dev->seq_;
bus->reg = dev_read_addr_ptr(dev);
diff --git a/drivers/i2c/ocores_i2c.c b/drivers/i2c/ocores_i2c.c
index 3b19ba7..fff8511 100644
--- a/drivers/i2c/ocores_i2c.c
+++ b/drivers/i2c/ocores_i2c.c
@@ -396,8 +396,6 @@ static int ocores_i2c_enable_clk(struct udevice *dev)
bus->ip_clk_khz = clk_rate / 1000;
- clk_free(&bus->clk);
-
return 0;
}
diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c
index eaa1d69..f42e08a 100644
--- a/drivers/i2c/stm32f7_i2c.c
+++ b/drivers/i2c/stm32f7_i2c.c
@@ -890,7 +890,7 @@ static int stm32_i2c_probe(struct udevice *dev)
ret = clk_enable(&i2c_priv->clk);
if (ret)
- goto clk_free;
+ return ret;
ret = reset_get_by_index(dev, 0, &reset_ctl);
if (ret)
@@ -904,8 +904,6 @@ static int stm32_i2c_probe(struct udevice *dev)
clk_disable:
clk_disable(&i2c_priv->clk);
-clk_free:
- clk_free(&i2c_priv->clk);
return ret;
}
diff --git a/drivers/mailbox/stm32-ipcc.c b/drivers/mailbox/stm32-ipcc.c
index 69c86e0..046e1a8 100644
--- a/drivers/mailbox/stm32-ipcc.c
+++ b/drivers/mailbox/stm32-ipcc.c
@@ -134,18 +134,13 @@ static int stm32_ipcc_probe(struct udevice *dev)
ret = clk_enable(&clk);
if (ret)
- goto clk_free;
+ return ret;
/* get channel number */
ipcc->n_chans = readl(ipcc->reg_base + IPCC_HWCFGR);
ipcc->n_chans &= IPCFGR_CHAN_MASK;
return 0;
-
-clk_free:
- clk_free(&clk);
-
- return ret;
}
static const struct udevice_id stm32_ipcc_ids[] = {
diff --git a/drivers/misc/ls2_sfp.c b/drivers/misc/ls2_sfp.c
index 2a81bc7..5351c7e 100644
--- a/drivers/misc/ls2_sfp.c
+++ b/drivers/misc/ls2_sfp.c
@@ -249,7 +249,6 @@ static int ls2_sfp_probe(struct udevice *dev)
}
rate = clk_get_rate(&clk);
- clk_free(&clk);
if (!rate || IS_ERR_VALUE(rate)) {
ret = rate ? rate : -ENOENT;
dev_dbg(dev, "could not get clock rate (err %d)\n",
diff --git a/drivers/misc/qfw_smbios.c b/drivers/misc/qfw_smbios.c
index a898cb4..c3e8c31 100644
--- a/drivers/misc/qfw_smbios.c
+++ b/drivers/misc/qfw_smbios.c
@@ -90,7 +90,7 @@ static int qfw_parse_smbios_anchor(struct udevice *dev,
entry->length = sizeof(struct smbios3_entry);
entry->major_ver = entry2->major_ver;
entry->minor_ver = entry2->minor_ver;
- entry->max_struct_size = entry2->struct_table_length;
+ entry->table_maximum_size = entry2->struct_table_length;
} else {
ret = -ENOENT;
goto out;
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c
index 9c5d48e..5cf5502 100644
--- a/drivers/mmc/arm_pl180_mmci.c
+++ b/drivers/mmc/arm_pl180_mmci.c
@@ -447,7 +447,6 @@ static int arm_pl180_mmc_probe(struct udevice *dev)
ret = clk_enable(&clk);
if (ret) {
- clk_free(&clk);
dev_err(dev, "failed to enable clock\n");
return ret;
}
diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c
index 9d79bf5..c9626c6 100644
--- a/drivers/mmc/aspeed_sdhci.c
+++ b/drivers/mmc/aspeed_sdhci.c
@@ -35,7 +35,7 @@ static int aspeed_sdhci_probe(struct udevice *dev)
ret = clk_enable(&clk);
if (ret) {
debug("%s: clock enable failed %d\n", __func__, ret);
- goto free;
+ return ret;
}
host->name = dev->name;
@@ -66,8 +66,6 @@ static int aspeed_sdhci_probe(struct udevice *dev)
err:
clk_disable(&clk);
-free:
- clk_free(&clk);
return ret;
}
diff --git a/drivers/mmc/atmel_sdhci.c b/drivers/mmc/atmel_sdhci.c
index 5347ba9..d92bad9 100644
--- a/drivers/mmc/atmel_sdhci.c
+++ b/drivers/mmc/atmel_sdhci.c
@@ -147,8 +147,6 @@ static int atmel_sdhci_probe(struct udevice *dev)
host->ops = &atmel_sdhci_ops;
upriv->mmc = host->mmc;
- clk_free(&clk);
-
ret = sdhci_probe(dev);
if (ret)
return ret;
diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c
index d91819a..3ee9955 100644
--- a/drivers/mmc/gen_atmel_mci.c
+++ b/drivers/mmc/gen_atmel_mci.c
@@ -559,27 +559,20 @@ static int atmel_mci_enable_clk(struct udevice *dev)
int ret = 0;
ret = clk_get_by_index(dev, 0, &clk);
- if (ret) {
- ret = -EINVAL;
- goto failed;
- }
+ if (ret)
+ return -EINVAL;
ret = clk_enable(&clk);
if (ret)
- goto failed;
+ return ret;
clk_rate = clk_get_rate(&clk);
- if (!clk_rate) {
- ret = -EINVAL;
- goto failed;
- }
+ if (!clk_rate)
+ return -EINVAL;
priv->bus_clk_rate = clk_rate;
-failed:
- clk_free(&clk);
-
- return ret;
+ return 0;
}
static int atmel_mci_probe(struct udevice *dev)
diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c
index 604f9c3..fe1e754 100644
--- a/drivers/mmc/msm_sdhci.c
+++ b/drivers/mmc/msm_sdhci.c
@@ -81,7 +81,6 @@ static int msm_sdc_clk_init(struct udevice *dev)
return ret;
ret = clk_set_rate(&clk, clk_rate);
- clk_free(&clk);
if (ret < 0)
return ret;
diff --git a/drivers/mmc/pic32_sdhci.c b/drivers/mmc/pic32_sdhci.c
index fe55510..7a8e33d 100644
--- a/drivers/mmc/pic32_sdhci.c
+++ b/drivers/mmc/pic32_sdhci.c
@@ -32,7 +32,6 @@ static int pic32_sdhci_probe(struct udevice *dev)
return ret;
clk_rate = clk_get_rate(&clk);
- clk_free(&clk);
if (IS_ERR_VALUE(clk_rate))
return clk_rate;
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index 97aaf1e..a74559c 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -979,19 +979,19 @@ static int rzg2l_sdhi_setup(struct udevice *dev)
ret = clk_get_by_name(dev, "cd", &imclk2);
if (ret < 0) {
dev_err(dev, "failed to get imclk2 (chip detect clk)\n");
- goto err_get_imclk2;
+ return ret;
}
ret = clk_get_by_name(dev, "aclk", &aclk);
if (ret < 0) {
dev_err(dev, "failed to get aclk\n");
- goto err_get_aclk;
+ return ret;
}
ret = clk_enable(&imclk2);
if (ret < 0) {
dev_err(dev, "failed to enable imclk2 (chip detect clk)\n");
- goto err_imclk2;
+ return ret;
}
ret = clk_enable(&aclk);
@@ -1026,11 +1026,6 @@ err_get_reset:
clk_disable(&aclk);
err_aclk:
clk_disable(&imclk2);
-err_imclk2:
- clk_free(&aclk);
-err_get_aclk:
- clk_free(&imclk2);
-err_get_imclk2:
return ret;
}
@@ -1071,7 +1066,7 @@ static int renesas_sdhi_probe(struct udevice *dev)
ret = clk_set_rate(&priv->clkh, 800000000);
if (ret < 0) {
dev_err(dev, "failed to set rate for SDnH clock (%d)\n", ret);
- goto err_clk;
+ return ret;
}
}
@@ -1079,13 +1074,13 @@ static int renesas_sdhi_probe(struct udevice *dev)
ret = clk_set_rate(&priv->clk, 200000000);
if (ret < 0) {
dev_err(dev, "failed to set rate for SDn clock (%d)\n", ret);
- goto err_clkh;
+ return ret;
}
ret = clk_enable(&priv->clk);
if (ret) {
dev_err(dev, "failed to enable SDn clock (%d)\n", ret);
- goto err_clkh;
+ return ret;
}
if (device_is_compatible(dev, "renesas,sdhi-r9a07g044"))
@@ -1107,10 +1102,6 @@ static int renesas_sdhi_probe(struct udevice *dev)
err_tmio_probe:
clk_disable(&priv->clk);
-err_clkh:
- clk_free(&priv->clkh);
-err_clk:
- clk_free(&priv->clk);
return ret;
}
diff --git a/drivers/mmc/snps_dw_mmc.c b/drivers/mmc/snps_dw_mmc.c
index 50a8805..0134399 100644
--- a/drivers/mmc/snps_dw_mmc.c
+++ b/drivers/mmc/snps_dw_mmc.c
@@ -46,7 +46,7 @@ static int snps_dwmmc_clk_setup(struct udevice *dev)
ret = clk_enable(&clk_ciu);
if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
- goto clk_err_ciu;
+ goto clk_err;
host->bus_hz = clk_get_rate(&clk_ciu);
if (host->bus_hz < CLOCK_MIN) {
@@ -60,16 +60,12 @@ static int snps_dwmmc_clk_setup(struct udevice *dev)
ret = clk_enable(&clk_biu);
if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
- goto clk_err_biu;
+ goto clk_err_ciu_dis;
return 0;
-clk_err_biu:
- clk_free(&clk_biu);
clk_err_ciu_dis:
clk_disable(&clk_ciu);
-clk_err_ciu:
- clk_free(&clk_ciu);
clk_err:
dev_err(dev, "failed to setup clocks, ret %d\n", ret);
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index be3d8bf..387cb8b 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -99,7 +99,6 @@ static int socfpga_dwmmc_get_clk_rate(struct udevice *dev)
host->bus_hz = clk_get_rate(&clk);
- clk_free(&clk);
#else
/* Fixed clock divide by 4 which due to the SDMMC wrapper */
host->bus_hz = cm_get_mmc_controller_clk_hz();
diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c
index 5ff5e1a..a2b111a 100644
--- a/drivers/mmc/stm32_sdmmc2.c
+++ b/drivers/mmc/stm32_sdmmc2.c
@@ -766,10 +766,8 @@ static int stm32_sdmmc2_probe(struct udevice *dev)
int ret;
ret = clk_enable(&plat->clk);
- if (ret) {
- clk_free(&plat->clk);
+ if (ret)
return ret;
- }
upriv->mmc = &plat->mmc;
diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c
index 75003a0..8cde430 100644
--- a/drivers/mmc/uniphier-sd.c
+++ b/drivers/mmc/uniphier-sd.c
@@ -64,7 +64,6 @@ static int uniphier_sd_probe(struct udevice *dev)
ret = clk_set_rate(&priv->clk, ULONG_MAX);
if (ret < 0) {
dev_err(dev, "failed to set rate for host clock\n");
- clk_free(&priv->clk);
return ret;
}
diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index a2151f9..0e04414 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -1999,10 +1999,8 @@ atmel_hsmc_nand_controller_remove(struct atmel_nand_controller *nc)
hsmc_nc = container_of(nc, struct atmel_hsmc_nand_controller, base);
- if (hsmc_nc->clk) {
+ if (hsmc_nc->clk)
clk_disable_unprepare(hsmc_nc->clk);
- devm_clk_put(nc->dev, hsmc_nc->clk);
- }
return 0;
}
diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c
index e2e3f1e..51f6bd2 100644
--- a/drivers/mtd/nand/raw/atmel/pmecc.c
+++ b/drivers/mtd/nand/raw/atmel/pmecc.c
@@ -816,9 +816,6 @@ int atmel_pmecc_wait_rdy(struct atmel_pmecc_user *user)
}
EXPORT_SYMBOL_GPL(atmel_pmecc_wait_rdy);
-#define ATMEL_BASE_PMECC 0xffffe000
-#define ATMEL_BASE_PMERRLOC 0xffffe600
-
static struct atmel_pmecc *
atmel_pmecc_create(struct udevice *dev,
const struct atmel_pmecc_caps *caps,
diff --git a/drivers/mtd/renesas_rpc_hf.c b/drivers/mtd/renesas_rpc_hf.c
index aca7a6c..979b64d 100644
--- a/drivers/mtd/renesas_rpc_hf.c
+++ b/drivers/mtd/renesas_rpc_hf.c
@@ -370,7 +370,6 @@ static int rpc_hf_probe(struct udevice *dev)
}
ret = clk_enable(&clk);
- clk_free(&clk);
if (ret) {
dev_err(dev, "Failed to enable RPC clock\n");
return ret;
diff --git a/drivers/net/bcm6348-eth.c b/drivers/net/bcm6348-eth.c
index 72dcd07..15a94f6 100644
--- a/drivers/net/bcm6348-eth.c
+++ b/drivers/net/bcm6348-eth.c
@@ -457,8 +457,6 @@ static int bcm6348_eth_probe(struct udevice *dev)
pr_err("%s: error enabling clock %d\n", __func__, i);
return ret;
}
-
- clk_free(&clk);
}
/* try to perform resets */
diff --git a/drivers/net/bcm6368-eth.c b/drivers/net/bcm6368-eth.c
index fdd938c..9679a45 100644
--- a/drivers/net/bcm6368-eth.c
+++ b/drivers/net/bcm6368-eth.c
@@ -546,8 +546,6 @@ static int bcm6368_eth_probe(struct udevice *dev)
pr_err("%s: error enabling clock %d\n", __func__, i);
return ret;
}
-
- clk_free(&clk);
}
/* try to perform resets */
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index a174344..c869635 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -702,7 +702,6 @@ int designware_eth_probe(struct udevice *dev)
err = clk_enable(&priv->clocks[i]);
if (err && err != -ENOSYS && err != -ENOTSUPP) {
pr_err("failed to enable clock %d\n", i);
- clk_free(&priv->clocks[i]);
goto clk_err;
}
priv->clock_count++;
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index e40e399..9b3bce1 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1382,38 +1382,30 @@ static int eqos_probe_resources_tegra186(struct udevice *dev)
ret = clk_get_by_name(dev, "master_bus", &eqos->clk_master_bus);
if (ret) {
pr_err("clk_get_by_name(master_bus) failed: %d", ret);
- goto err_free_clk_slave_bus;
+ goto err_free_gpio_phy_reset;
}
ret = clk_get_by_name(dev, "rx", &eqos->clk_rx);
if (ret) {
pr_err("clk_get_by_name(rx) failed: %d", ret);
- goto err_free_clk_master_bus;
+ goto err_free_gpio_phy_reset;
}
ret = clk_get_by_name(dev, "ptp_ref", &eqos->clk_ptp_ref);
if (ret) {
pr_err("clk_get_by_name(ptp_ref) failed: %d", ret);
- goto err_free_clk_rx;
+ goto err_free_gpio_phy_reset;
}
ret = clk_get_by_name(dev, "tx", &eqos->clk_tx);
if (ret) {
pr_err("clk_get_by_name(tx) failed: %d", ret);
- goto err_free_clk_ptp_ref;
+ goto err_free_gpio_phy_reset;
}
debug("%s: OK\n", __func__);
return 0;
-err_free_clk_ptp_ref:
- clk_free(&eqos->clk_ptp_ref);
-err_free_clk_rx:
- clk_free(&eqos->clk_rx);
-err_free_clk_master_bus:
- clk_free(&eqos->clk_master_bus);
-err_free_clk_slave_bus:
- clk_free(&eqos->clk_slave_bus);
err_free_gpio_phy_reset:
dm_gpio_free(dev, &eqos->phy_reset_gpio);
err_free_reset_eqos:
@@ -1451,13 +1443,13 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx);
if (ret) {
pr_err("clk_get_by_name(rx) failed: %d", ret);
- goto err_free_clk_master_bus;
+ goto err_probe;
}
ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx);
if (ret) {
pr_err("clk_get_by_name(tx) failed: %d", ret);
- goto err_free_clk_rx;
+ goto err_probe;
}
/* Get ETH_CLK clocks (optional) */
@@ -1468,10 +1460,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
debug("%s: OK\n", __func__);
return 0;
-err_free_clk_rx:
- clk_free(&eqos->clk_rx);
-err_free_clk_master_bus:
- clk_free(&eqos->clk_master_bus);
err_probe:
debug("%s: returns %d\n", __func__, ret);
@@ -1489,13 +1477,6 @@ static int eqos_remove_resources_tegra186(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
-#ifdef CONFIG_CLK
- clk_free(&eqos->clk_tx);
- clk_free(&eqos->clk_ptp_ref);
- clk_free(&eqos->clk_rx);
- clk_free(&eqos->clk_slave_bus);
- clk_free(&eqos->clk_master_bus);
-#endif
dm_gpio_free(dev, &eqos->phy_reset_gpio);
reset_free(&eqos->reset_ctl);
@@ -1505,19 +1486,7 @@ static int eqos_remove_resources_tegra186(struct udevice *dev)
static int eqos_remove_resources_stm32(struct udevice *dev)
{
- struct eqos_priv * __maybe_unused eqos = dev_get_priv(dev);
-
debug("%s(dev=%p):\n", __func__, dev);
-
-#ifdef CONFIG_CLK
- clk_free(&eqos->clk_tx);
- clk_free(&eqos->clk_rx);
- clk_free(&eqos->clk_master_bus);
- if (clk_valid(&eqos->clk_ck))
- clk_free(&eqos->clk_ck);
-#endif
-
- debug("%s: OK\n", __func__);
return 0;
}
diff --git a/drivers/net/dwc_eth_qos_imx.c b/drivers/net/dwc_eth_qos_imx.c
index e3f55dd..9c4e390 100644
--- a/drivers/net/dwc_eth_qos_imx.c
+++ b/drivers/net/dwc_eth_qos_imx.c
@@ -70,30 +70,24 @@ static int eqos_probe_resources_imx(struct udevice *dev)
ret = clk_get_by_name(dev, "ptp_ref", &eqos->clk_ptp_ref);
if (ret) {
dev_dbg(dev, "clk_get_by_name(ptp_ref) failed: %d", ret);
- goto err_free_clk_master_bus;
+ goto err_probe;
}
ret = clk_get_by_name(dev, "tx", &eqos->clk_tx);
if (ret) {
dev_dbg(dev, "clk_get_by_name(tx) failed: %d", ret);
- goto err_free_clk_ptp_ref;
+ goto err_probe;
}
ret = clk_get_by_name(dev, "pclk", &eqos->clk_ck);
if (ret) {
dev_dbg(dev, "clk_get_by_name(pclk) failed: %d", ret);
- goto err_free_clk_tx;
+ goto err_probe;
}
debug("%s: OK\n", __func__);
return 0;
-err_free_clk_tx:
- clk_free(&eqos->clk_tx);
-err_free_clk_ptp_ref:
- clk_free(&eqos->clk_ptp_ref);
-err_free_clk_master_bus:
- clk_free(&eqos->clk_master_bus);
err_probe:
debug("%s: returns %d\n", __func__, ret);
@@ -102,16 +96,7 @@ err_probe:
static int eqos_remove_resources_imx(struct udevice *dev)
{
- struct eqos_priv *eqos = dev_get_priv(dev);
-
debug("%s(dev=%p):\n", __func__, dev);
-
- clk_free(&eqos->clk_ck);
- clk_free(&eqos->clk_tx);
- clk_free(&eqos->clk_ptp_ref);
- clk_free(&eqos->clk_master_bus);
-
- debug("%s: OK\n", __func__);
return 0;
}
diff --git a/drivers/net/dwc_eth_qos_qcom.c b/drivers/net/dwc_eth_qos_qcom.c
index df83f1c..8178138 100644
--- a/drivers/net/dwc_eth_qos_qcom.c
+++ b/drivers/net/dwc_eth_qos_qcom.c
@@ -575,7 +575,6 @@ static int eqos_remove_resources_qcom(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- clk_free(&eqos->clk_tx);
dm_gpio_free(dev, &eqos->phy_reset_gpio);
reset_free(&eqos->reset_ctl);
diff --git a/drivers/net/dwc_eth_qos_rockchip.c b/drivers/net/dwc_eth_qos_rockchip.c
index 834307a..fa9e513 100644
--- a/drivers/net/dwc_eth_qos_rockchip.c
+++ b/drivers/net/dwc_eth_qos_rockchip.c
@@ -372,7 +372,7 @@ static int eqos_probe_resources_rk(struct udevice *dev)
ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
if (ret) {
dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
- goto err_free_clk_master_bus;
+ goto err_release_resets;
}
}
@@ -393,8 +393,6 @@ static int eqos_probe_resources_rk(struct udevice *dev)
return 0;
-err_free_clk_master_bus:
- clk_free(&eqos->clk_master_bus);
err_release_resets:
reset_release_bulk(&data->resets);
err_free:
@@ -412,8 +410,6 @@ static int eqos_remove_resources_rk(struct udevice *dev)
if (dm_gpio_is_valid(&eqos->phy_reset_gpio))
dm_gpio_free(dev, &eqos->phy_reset_gpio);
- clk_free(&eqos->clk_tx);
- clk_free(&eqos->clk_master_bus);
reset_release_bulk(&data->resets);
free(data);
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
index 8635a96..a2c763c 100644
--- a/drivers/net/phy/motorcomm.c
+++ b/drivers/net/phy/motorcomm.c
@@ -23,6 +23,12 @@
#define YTPHY_SYNCE_CFG_REG 0xA012
+#define YT8531_PAD_DRIVE_STRENGTH_CFG_REG 0xA010
+#define YT8531_RGMII_RXC_DS_MASK GENMASK(15, 13)
+#define YT8531_RGMII_RXD_DS_HI_MASK BIT(12) /* Bit 2 of rxd_ds */
+#define YT8531_RGMII_RXD_DS_LOW_MASK GENMASK(5, 4) /* Bit 1/0 of rxd_ds */
+#define YT8531_RGMII_RX_DS_DEFAULT 0x3
+
#define YTPHY_DTS_OUTPUT_CLK_DIS 0
#define YTPHY_DTS_OUTPUT_CLK_25M 25000000
#define YTPHY_DTS_OUTPUT_CLK_125M 125000000
@@ -114,6 +120,10 @@
#define YT8531_CCR_RXC_DLY_EN BIT(8)
#define YT8531_CCR_RXC_DLY_1_900_NS 1900
+#define YT8531_CCR_CFG_LDO_MASK GENMASK(5, 4)
+#define YT8531_CCR_CFG_LDO_3V3 0x0
+#define YT8531_CCR_CFG_LDO_1V8 0x2
+
/* bits in struct ytphy_plat_priv->flag */
#define TX_CLK_ADJ_ENABLED BIT(0)
#define AUTO_SLEEP_DISABLED BIT(1)
@@ -224,6 +234,17 @@ static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask,
return phy_modify(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA, mask, set);
}
+static int ytphy_read_ext(struct phy_device *phydev, u16 regnum)
+{
+ int ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_SELECT, regnum);
+ if (ret < 0)
+ return ret;
+
+ return phy_read(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA);
+}
+
static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
{
struct ytphy_plat_priv *priv = phydev->priv;
@@ -425,6 +446,111 @@ static int yt8511_config(struct phy_device *phydev)
return 0;
}
+/**
+ * struct ytphy_ldo_vol_map - map a current value to a register value
+ * @vol: ldo voltage
+ * @ds: value in the register
+ * @cur: value in device configuration
+ */
+struct ytphy_ldo_vol_map {
+ u32 vol;
+ u32 ds;
+ u32 cur;
+};
+
+static const struct ytphy_ldo_vol_map yt8531_ldo_vol[] = {
+ {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 0, .cur = 1200},
+ {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 1, .cur = 2100},
+ {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 2, .cur = 2700},
+ {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 3, .cur = 2910},
+ {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 4, .cur = 3110},
+ {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 5, .cur = 3600},
+ {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 6, .cur = 3970},
+ {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 7, .cur = 4350},
+ {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 0, .cur = 3070},
+ {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 1, .cur = 4080},
+ {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 2, .cur = 4370},
+ {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 3, .cur = 4680},
+ {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 4, .cur = 5020},
+ {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 5, .cur = 5450},
+ {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 6, .cur = 5740},
+ {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 7, .cur = 6140},
+};
+
+static u32 yt8531_get_ldo_vol(struct phy_device *phydev)
+{
+ u32 val;
+
+ val = ytphy_read_ext(phydev, YT8531_CHIP_CONFIG_REG);
+ val = FIELD_GET(YT8531_CCR_CFG_LDO_MASK, val);
+
+ return val <= YT8531_CCR_CFG_LDO_1V8 ? val : YT8531_CCR_CFG_LDO_1V8;
+}
+
+static int yt8531_get_ds_map(struct phy_device *phydev, u32 cur)
+{
+ u32 vol;
+ int i;
+
+ vol = yt8531_get_ldo_vol(phydev);
+ for (i = 0; i < ARRAY_SIZE(yt8531_ldo_vol); i++) {
+ if (yt8531_ldo_vol[i].vol == vol && yt8531_ldo_vol[i].cur == cur)
+ return yt8531_ldo_vol[i].ds;
+ }
+
+ return -EINVAL;
+}
+
+static int yt8531_set_ds(struct phy_device *phydev)
+{
+ u32 ds_field_low, ds_field_hi, val;
+ int ret, ds;
+
+ /* set rgmii rx clk driver strength */
+ if (!ofnode_read_u32(phydev->node, "motorcomm,rx-clk-drv-microamp", &val)) {
+ ds = yt8531_get_ds_map(phydev, val);
+ if (ds < 0) {
+ pr_warn("No matching current value was found.");
+ return -EINVAL;
+ }
+ } else {
+ ds = YT8531_RGMII_RX_DS_DEFAULT;
+ }
+
+ ret = ytphy_modify_ext(phydev,
+ YT8531_PAD_DRIVE_STRENGTH_CFG_REG,
+ YT8531_RGMII_RXC_DS_MASK,
+ FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds));
+ if (ret < 0)
+ return ret;
+
+ /* set rgmii rx data driver strength */
+ if (!ofnode_read_u32(phydev->node, "motorcomm,rx-data-drv-microamp", &val)) {
+ ds = yt8531_get_ds_map(phydev, val);
+ if (ds < 0) {
+ pr_warn("No matching current value was found.");
+ return -EINVAL;
+ }
+ } else {
+ ds = YT8531_RGMII_RX_DS_DEFAULT;
+ }
+
+ ds_field_hi = FIELD_GET(BIT(2), ds);
+ ds_field_hi = FIELD_PREP(YT8531_RGMII_RXD_DS_HI_MASK, ds_field_hi);
+
+ ds_field_low = FIELD_GET(GENMASK(1, 0), ds);
+ ds_field_low = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW_MASK, ds_field_low);
+
+ ret = ytphy_modify_ext(phydev,
+ YT8531_PAD_DRIVE_STRENGTH_CFG_REG,
+ YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK,
+ ds_field_low | ds_field_hi);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static int yt8531_config(struct phy_device *phydev)
{
struct ytphy_plat_priv *priv = phydev->priv;
@@ -487,6 +613,10 @@ static int yt8531_config(struct phy_device *phydev)
return ret;
}
+ ret = yt8531_set_ds(phydev);
+ if (ret < 0)
+ return ret;
+
return 0;
}
diff --git a/drivers/net/sni_ave.c b/drivers/net/sni_ave.c
index 8eeecbc..a265ce9 100644
--- a/drivers/net/sni_ave.c
+++ b/drivers/net/sni_ave.c
@@ -777,7 +777,7 @@ static int ave_of_to_plat(struct udevice *dev)
if (ret) {
dev_err(dev, "Failed to get clocks property: %d\n",
ret);
- goto out_clk_free;
+ return ret;
}
priv->nclks++;
}
@@ -823,9 +823,6 @@ static int ave_of_to_plat(struct udevice *dev)
out_reset_free:
while (--nr >= 0)
reset_free(&priv->rst[nr]);
-out_clk_free:
- while (--nc >= 0)
- clk_free(&priv->clk[nc]);
return ret;
}
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
index 18a33c4..6da018c 100644
--- a/drivers/net/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ti/am65-cpsw-nuss.c
@@ -948,7 +948,6 @@ static int am65_cpsw_probe_nuss(struct udevice *dev)
cpsw_common->bus_freq);
out:
- clk_free(&cpsw_common->fclk);
power_domain_free(&cpsw_common->pwrdmn);
return ret;
}
diff --git a/drivers/phy/bcm6318-usbh-phy.c b/drivers/phy/bcm6318-usbh-phy.c
index 1c10853..a2fa446 100644
--- a/drivers/phy/bcm6318-usbh-phy.c
+++ b/drivers/phy/bcm6318-usbh-phy.c
@@ -98,8 +98,6 @@ static int bcm6318_usbh_probe(struct udevice *dev)
if (ret < 0)
return ret;
- clk_free(&clk);
-
/* enable power domain */
ret = power_domain_get(dev, &pwr_dom);
if (ret < 0)
diff --git a/drivers/phy/bcm6348-usbh-phy.c b/drivers/phy/bcm6348-usbh-phy.c
index ce6be3d..857fb57 100644
--- a/drivers/phy/bcm6348-usbh-phy.c
+++ b/drivers/phy/bcm6348-usbh-phy.c
@@ -62,8 +62,6 @@ static int bcm6348_usbh_probe(struct udevice *dev)
if (ret < 0)
return ret;
- clk_free(&clk);
-
/* perform reset */
ret = reset_get_by_index(dev, 0, &rst_ctl);
if (ret < 0)
diff --git a/drivers/phy/bcm6368-usbh-phy.c b/drivers/phy/bcm6368-usbh-phy.c
index d057f1f..1a2870d 100644
--- a/drivers/phy/bcm6368-usbh-phy.c
+++ b/drivers/phy/bcm6368-usbh-phy.c
@@ -137,8 +137,6 @@ static int bcm6368_usbh_probe(struct udevice *dev)
if (ret < 0)
return ret;
- clk_free(&clk);
-
#if defined(CONFIG_POWER_DOMAIN)
/* enable power domain */
ret = power_domain_get(dev, &pwr_dom);
@@ -173,8 +171,6 @@ static int bcm6368_usbh_probe(struct udevice *dev)
ret = clk_enable(&clk);
if (ret < 0)
return ret;
-
- clk_free(&clk);
}
mdelay(100);
diff --git a/drivers/phy/meson-axg-mipi-dphy.c b/drivers/phy/meson-axg-mipi-dphy.c
index a69b6c9..faa1d9d 100644
--- a/drivers/phy/meson-axg-mipi-dphy.c
+++ b/drivers/phy/meson-axg-mipi-dphy.c
@@ -369,7 +369,6 @@ int meson_axg_mipi_dphy_probe(struct udevice *dev)
ret = clk_enable(&priv->clk);
if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
pr_err("failed to enable PHY clock\n");
- clk_free(&priv->clk);
return ret;
}
#endif
diff --git a/drivers/phy/meson-g12a-usb3-pcie.c b/drivers/phy/meson-g12a-usb3-pcie.c
index 40a5da9..1eaff41 100644
--- a/drivers/phy/meson-g12a-usb3-pcie.c
+++ b/drivers/phy/meson-g12a-usb3-pcie.c
@@ -398,7 +398,6 @@ int meson_g12a_usb3_pcie_phy_probe(struct udevice *dev)
ret = clk_enable(&priv->clk);
if (ret && ret != -ENOENT && ret != -ENOTSUPP) {
pr_err("failed to enable PHY clock\n");
- clk_free(&priv->clk);
return ret;
}
#endif
diff --git a/drivers/phy/meson-gxl-usb2.c b/drivers/phy/meson-gxl-usb2.c
index 8f5e4a4..d633eff 100644
--- a/drivers/phy/meson-gxl-usb2.c
+++ b/drivers/phy/meson-gxl-usb2.c
@@ -203,7 +203,6 @@ int meson_gxl_usb2_phy_probe(struct udevice *dev)
ret = clk_enable(&priv->clk);
if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
pr_err("failed to enable PHY clock\n");
- clk_free(&priv->clk);
return ret;
}
#endif
diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c
index 1794095..e528c4e 100644
--- a/drivers/phy/phy-rcar-gen2.c
+++ b/drivers/phy/phy-rcar-gen2.c
@@ -172,7 +172,6 @@ static int rcar_gen2_phy_remove(struct udevice *dev)
struct rcar_gen2_phy *priv = dev_get_priv(dev);
clk_disable(&priv->clk);
- clk_free(&priv->clk);
return 0;
}
diff --git a/drivers/phy/phy-rcar-gen3.c b/drivers/phy/phy-rcar-gen3.c
index 7159e7e..03c747b 100644
--- a/drivers/phy/phy-rcar-gen3.c
+++ b/drivers/phy/phy-rcar-gen3.c
@@ -142,7 +142,6 @@ static int rcar_gen3_phy_remove(struct udevice *dev)
struct rcar_gen3_phy *priv = dev_get_priv(dev);
clk_disable(&priv->clk);
- clk_free(&priv->clk);
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c
index 13f0a34..ee35dfe 100644
--- a/drivers/pinctrl/pinctrl-k210.c
+++ b/drivers/pinctrl/pinctrl-k210.c
@@ -691,23 +691,19 @@ static int k210_pc_probe(struct udevice *dev)
ret = clk_enable(&priv->clk);
if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
- goto err;
+ return ret;
ret = dev_read_phandle_with_args(dev, "canaan,k210-sysctl-power",
NULL, 1, 0, &args);
if (ret)
- goto err;
+ return ret;
- if (args.args_count != 1) {
- ret = -EINVAL;
- goto err;
- }
+ if (args.args_count != 1)
+ return -EINVAL;
priv->sysctl = syscon_node_to_regmap(args.node);
- if (IS_ERR(priv->sysctl)) {
- ret = PTR_ERR(priv->sysctl);
- goto err;
- }
+ if (IS_ERR(priv->sysctl))
+ return PTR_ERR(priv->sysctl);
priv->power_offset = args.args[0];
@@ -728,10 +724,6 @@ static int k210_pc_probe(struct udevice *dev)
}
return 0;
-
-err:
- clk_free(&priv->clk);
- return ret;
}
static const struct udevice_id k210_pc_ids[] = {
diff --git a/drivers/power/domain/imx8mp-hsiomix.c b/drivers/power/domain/imx8mp-hsiomix.c
index 6a721a9..e2d772c 100644
--- a/drivers/power/domain/imx8mp-hsiomix.c
+++ b/drivers/power/domain/imx8mp-hsiomix.c
@@ -111,7 +111,7 @@ static int imx8mp_hsiomix_probe(struct udevice *dev)
ret = power_domain_get_by_name(dev, &priv->pd_bus, "bus");
if (ret < 0)
- goto err_pd_bus;
+ return ret;
ret = power_domain_get_by_name(dev, &priv->pd_usb, "usb");
if (ret < 0)
@@ -133,8 +133,6 @@ err_pd_usb_phy1:
power_domain_free(&priv->pd_usb);
err_pd_usb:
power_domain_free(&priv->pd_bus);
-err_pd_bus:
- clk_free(&priv->clk_usb);
return ret;
}
diff --git a/drivers/rtc/stm32_rtc.c b/drivers/rtc/stm32_rtc.c
index 1753283..ec7584c 100644
--- a/drivers/rtc/stm32_rtc.c
+++ b/drivers/rtc/stm32_rtc.c
@@ -223,10 +223,8 @@ static int stm32_rtc_init(struct udevice *dev)
return ret;
ret = clk_enable(&clk);
- if (ret) {
- clk_free(&clk);
+ if (ret)
return ret;
- }
rate = clk_get_rate(&clk);
@@ -275,10 +273,8 @@ static int stm32_rtc_init(struct udevice *dev)
unlock:
stm32_rtc_lock(dev);
- if (ret) {
+ if (ret)
clk_disable(&clk);
- clk_free(&clk);
- }
return ret;
}
@@ -298,17 +294,13 @@ static int stm32_rtc_probe(struct udevice *dev)
return ret;
ret = clk_enable(&clk);
- if (ret) {
- clk_free(&clk);
+ if (ret)
return ret;
- }
ret = stm32_rtc_init(dev);
- if (ret) {
+ if (ret)
clk_disable(&clk);
- clk_free(&clk);
- }
return ret;
}
diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c
index 9853f49..9827c00 100644
--- a/drivers/serial/atmel_usart.c
+++ b/drivers/serial/atmel_usart.c
@@ -253,8 +253,6 @@ static int atmel_serial_enable_clk(struct udevice *dev)
priv->usart_clk_rate = clk_rate;
- clk_free(&clk);
-
return 0;
}
#endif
diff --git a/drivers/serial/serial_bcm6345.c b/drivers/serial/serial_bcm6345.c
index 2359656..13bc517 100644
--- a/drivers/serial/serial_bcm6345.c
+++ b/drivers/serial/serial_bcm6345.c
@@ -239,7 +239,6 @@ static int bcm6345_serial_probe(struct udevice *dev)
if (ret < 0)
return ret;
priv->uartclk = clk_get_rate(&clk);
- clk_free(&clk);
/* initialize serial */
return bcm6345_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE);
diff --git a/drivers/serial/serial_msm.c b/drivers/serial/serial_msm.c
index a22623c..f4d9631 100644
--- a/drivers/serial/serial_msm.c
+++ b/drivers/serial/serial_msm.c
@@ -185,7 +185,6 @@ static int msm_uart_clk_init(struct udevice *dev)
return ret;
ret = clk_set_rate(&clk, clk_rate);
- clk_free(&clk);
if (ret < 0)
return ret;
diff --git a/drivers/serial/serial_pic32.c b/drivers/serial/serial_pic32.c
index 3c5d37c..0a03a9a 100644
--- a/drivers/serial/serial_pic32.c
+++ b/drivers/serial/serial_pic32.c
@@ -155,7 +155,6 @@ static int pic32_uart_probe(struct udevice *dev)
if (ret < 0)
return ret;
priv->uartclk = clk_get_rate(&clk);
- clk_free(&clk);
/* initialize serial */
return pic32_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE);
diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c
index de9c148..70cb242 100644
--- a/drivers/spi/atcspi200_spi.c
+++ b/drivers/spi/atcspi200_spi.c
@@ -362,7 +362,6 @@ static int atcspi200_spi_get_clk(struct udevice *bus)
return -EINVAL;
ns->clock = clk_rate;
- clk_free(&clk);
return 0;
}
diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
index cb64119..bd73e4f 100644
--- a/drivers/spi/atmel-quadspi.c
+++ b/drivers/spi/atmel-quadspi.c
@@ -877,7 +877,6 @@ static int atmel_qspi_set_gclk(struct udevice *bus, uint hz)
ret = clk_enable(&gclk);
if (ret)
dev_err(bus, "Failed to enable QSPI generic clock\n");
- clk_free(&gclk);
return ret;
}
@@ -1000,7 +999,7 @@ static int atmel_qspi_enable_clk(struct udevice *dev)
ret = clk_enable(&pclk);
if (ret) {
dev_err(dev, "Failed to enable QSPI peripheral clock\n");
- goto free_pclk;
+ return ret;
}
if (aq->caps->has_qspick) {
@@ -1008,32 +1007,27 @@ static int atmel_qspi_enable_clk(struct udevice *dev)
ret = clk_get_by_name(dev, "qspick", &qspick);
if (ret) {
dev_err(dev, "Missing QSPI peripheral clock\n");
- goto free_pclk;
+ return ret;
}
ret = clk_enable(&qspick);
if (ret)
dev_err(dev, "Failed to enable QSPI system clock\n");
- clk_free(&qspick);
} else if (aq->caps->has_gclk) {
ret = clk_get_by_name(dev, "gclk", &gclk);
if (ret) {
dev_err(dev, "Missing QSPI generic clock\n");
- goto free_pclk;
+ return ret;
}
ret = clk_enable(&gclk);
if (ret)
dev_err(dev, "Failed to enable QSPI system clock\n");
- clk_free(&gclk);
}
aq->bus_clk_rate = clk_get_rate(&pclk);
if (!aq->bus_clk_rate)
- ret = -EINVAL;
-
-free_pclk:
- clk_free(&pclk);
+ return -EINVAL;
return ret;
}
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index aec6f4e..d4f0c4c 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -338,8 +338,6 @@ static int atmel_spi_enable_clk(struct udevice *bus)
priv->bus_clk_rate = clk_rate;
- clk_free(&clk);
-
return 0;
}
diff --git a/drivers/spi/bcm63xx_hsspi.c b/drivers/spi/bcm63xx_hsspi.c
index 19d9a5a..23ac5bb 100644
--- a/drivers/spi/bcm63xx_hsspi.c
+++ b/drivers/spi/bcm63xx_hsspi.c
@@ -581,8 +581,6 @@ static int bcm63xx_hsspi_probe(struct udevice *dev)
if (ret < 0 && ret != -ENOSYS)
return ret;
- clk_free(&clk);
-
/* get clock rate */
ret = clk_get_by_name(dev, "pll", &clk);
if (ret < 0 && ret != -ENOSYS)
@@ -590,8 +588,6 @@ static int bcm63xx_hsspi_probe(struct udevice *dev)
priv->clk_rate = clk_get_rate(&clk);
- clk_free(&clk);
-
/* perform reset */
ret = reset_get_by_index(dev, 0, &rst_ctl);
if (ret >= 0) {
diff --git a/drivers/spi/bcm63xx_spi.c b/drivers/spi/bcm63xx_spi.c
index 0600d56..889ac1f 100644
--- a/drivers/spi/bcm63xx_spi.c
+++ b/drivers/spi/bcm63xx_spi.c
@@ -391,8 +391,6 @@ static int bcm63xx_spi_probe(struct udevice *dev)
if (ret < 0)
return ret;
- clk_free(&clk);
-
/* perform reset */
ret = reset_get_by_index(dev, 0, &rst_ctl);
if (ret < 0)
diff --git a/drivers/spi/bcmbca_hsspi.c b/drivers/spi/bcmbca_hsspi.c
index fbe315a..af45882 100644
--- a/drivers/spi/bcmbca_hsspi.c
+++ b/drivers/spi/bcmbca_hsspi.c
@@ -375,8 +375,6 @@ static int bcmbca_hsspi_probe(struct udevice *dev)
if (ret < 0 && ret != -ENOSYS)
return ret;
- clk_free(&clk);
-
/* get clock rate */
ret = clk_get_by_name(dev, "pll", &clk);
if (ret < 0 && ret != -ENOSYS)
@@ -384,8 +382,6 @@ static int bcmbca_hsspi_probe(struct udevice *dev)
priv->clk_rate = clk_get_rate(&clk);
- clk_free(&clk);
-
/* initialize hardware */
writel(0, priv->regs + SPI_IR_MASK_REG);
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index dfc74c8..f4593c4 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -236,7 +236,6 @@ static int cadence_spi_probe(struct udevice *bus)
#endif
} else {
priv->ref_clk_hz = clk_get_rate(&clk);
- clk_free(&clk);
if (IS_ERR_VALUE(priv->ref_clk_hz))
return priv->ref_clk_hz;
}
diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c
index 98908c5..22a79da 100644
--- a/drivers/spi/designware_spi.c
+++ b/drivers/spi/designware_spi.c
@@ -319,7 +319,6 @@ __weak int dw_spi_get_clk(struct udevice *bus, ulong *rate)
err_rate:
clk_disable(&priv->clk);
- clk_free(&priv->clk);
return -EINVAL;
}
@@ -743,10 +742,6 @@ static int dw_spi_remove(struct udevice *bus)
ret = clk_disable(&priv->clk);
if (ret)
return ret;
-
- clk_free(&priv->clk);
- if (ret)
- return ret;
#endif
return 0;
}
diff --git a/drivers/spi/meson_spifc_a1.c b/drivers/spi/meson_spifc_a1.c
index cca4deb..943bf69 100644
--- a/drivers/spi/meson_spifc_a1.c
+++ b/drivers/spi/meson_spifc_a1.c
@@ -343,15 +343,6 @@ static int amlogic_spifc_a1_probe(struct udevice *dev)
return 0;
}
-static int amlogic_spifc_a1_remove(struct udevice *dev)
-{
- struct amlogic_spifc_a1 *spifc = dev_get_priv(dev);
-
- clk_free(&spifc->clk);
-
- return 0;
-}
-
static const struct udevice_id meson_spifc_ids[] = {
{ .compatible = "amlogic,a1-spifc", },
{ }
@@ -379,6 +370,5 @@ U_BOOT_DRIVER(meson_spifc_a1) = {
.of_match = meson_spifc_ids,
.ops = &amlogic_spifc_a1_ops,
.probe = amlogic_spifc_a1_probe,
- .remove = amlogic_spifc_a1_remove,
.priv_auto = sizeof(struct amlogic_spifc_a1),
};
diff --git a/drivers/spi/mvebu_a3700_spi.c b/drivers/spi/mvebu_a3700_spi.c
index 52882e8..bba2383 100644
--- a/drivers/spi/mvebu_a3700_spi.c
+++ b/drivers/spi/mvebu_a3700_spi.c
@@ -296,15 +296,6 @@ static int mvebu_spi_of_to_plat(struct udevice *bus)
return 0;
}
-static int mvebu_spi_remove(struct udevice *bus)
-{
- struct mvebu_spi_plat *plat = dev_get_plat(bus);
-
- clk_free(&plat->clk);
-
- return 0;
-}
-
static const struct dm_spi_ops mvebu_spi_ops = {
.xfer = mvebu_spi_xfer,
.set_speed = mvebu_spi_set_speed,
@@ -328,5 +319,4 @@ U_BOOT_DRIVER(mvebu_spi) = {
.of_to_plat = mvebu_spi_of_to_plat,
.plat_auto = sizeof(struct mvebu_spi_plat),
.probe = mvebu_spi_probe,
- .remove = mvebu_spi_remove,
};
diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
index 3962031..7d5f101 100644
--- a/drivers/spi/spi-aspeed-smc.c
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -1148,7 +1148,6 @@ static int apseed_spi_of_to_plat(struct udevice *bus)
}
plat->hclk_rate = clk_get_rate(&hclk);
- clk_free(&hclk);
dev_dbg(bus, "ctrl_base = 0x%x, ahb_base = 0x%p, size = 0x%llx\n",
(u32)priv->regs, plat->ahb_base, (fdt64_t)plat->ahb_sz);
diff --git a/drivers/spi/stm32_spi.c b/drivers/spi/stm32_spi.c
index 82f6ed7..ddb410a 100644
--- a/drivers/spi/stm32_spi.c
+++ b/drivers/spi/stm32_spi.c
@@ -526,22 +526,16 @@ static int stm32_spi_of_to_plat(struct udevice *dev)
ret = reset_get_by_index(dev, 0, &plat->rst_ctl);
if (ret < 0)
- goto clk_err;
+ return ret;
ret = gpio_request_list_by_name(dev, "cs-gpios", plat->cs_gpios,
ARRAY_SIZE(plat->cs_gpios), 0);
if (ret < 0) {
dev_err(dev, "Can't get %s cs gpios: %d", dev->name, ret);
- ret = -ENOENT;
- goto clk_err;
+ return -ENOENT;
}
return 0;
-
-clk_err:
- clk_free(&plat->clk);
-
- return ret;
}
static int stm32_spi_probe(struct udevice *dev)
@@ -610,7 +604,6 @@ static int stm32_spi_probe(struct udevice *dev)
clk_err:
clk_disable(&plat->clk);
- clk_free(&plat->clk);
return ret;
};
@@ -630,13 +623,7 @@ static int stm32_spi_remove(struct udevice *dev)
reset_free(&plat->rst_ctl);
- ret = clk_disable(&plat->clk);
- if (ret < 0)
- return ret;
-
- clk_free(&plat->clk);
-
- return ret;
+ return clk_disable(&plat->clk);
};
static const struct dm_spi_ops stm32_spi_ops = {
diff --git a/drivers/timer/dw-apb-timer.c b/drivers/timer/dw-apb-timer.c
index 6cd2525..0607f75 100644
--- a/drivers/timer/dw-apb-timer.c
+++ b/drivers/timer/dw-apb-timer.c
@@ -74,8 +74,6 @@ static int dw_apb_timer_probe(struct udevice *dev)
return ret;
uc_priv->clock_rate = clk_get_rate(&clk);
-
- clk_free(&clk);
}
/* init timer */
diff --git a/drivers/timer/ostm_timer.c b/drivers/timer/ostm_timer.c
index 3ec729d..3bf0d46 100644
--- a/drivers/timer/ostm_timer.c
+++ b/drivers/timer/ostm_timer.c
@@ -49,8 +49,6 @@ static int ostm_probe(struct udevice *dev)
return ret;
uc_priv->clock_rate = clk_get_rate(&clk);
-
- clk_free(&clk);
#else
uc_priv->clock_rate = get_board_sys_clk() / 2;
#endif
diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c
index 1960352..1a3e935 100644
--- a/drivers/usb/dwc3/dwc3-meson-g12a.c
+++ b/drivers/usb/dwc3/dwc3-meson-g12a.c
@@ -361,10 +361,8 @@ static int dwc3_meson_g12a_clk_init(struct dwc3_meson_g12a *priv)
#if CONFIG_IS_ENABLED(CLK)
ret = clk_enable(&priv->clk);
- if (ret) {
- clk_free(&priv->clk);
+ if (ret)
return ret;
- }
#endif
return 0;
diff --git a/drivers/usb/dwc3/dwc3-meson-gxl.c b/drivers/usb/dwc3/dwc3-meson-gxl.c
index cbe8aaa..2ce9157 100644
--- a/drivers/usb/dwc3/dwc3-meson-gxl.c
+++ b/drivers/usb/dwc3/dwc3-meson-gxl.c
@@ -284,10 +284,8 @@ static int dwc3_meson_gxl_clk_init(struct dwc3_meson_gxl *priv)
#if CONFIG_IS_ENABLED(CLK)
ret = clk_enable(&priv->clk);
- if (ret) {
- clk_free(&priv->clk);
+ if (ret)
return ret;
- }
#endif
return 0;
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index fba3595..c6d50fd 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -70,13 +70,7 @@ static int ehci_atmel_enable_clk(struct udevice *dev)
if (ret)
return -EINVAL;
- ret = clk_enable(&clk);
- if (ret)
- return ret;
-
- clk_free(&clk);
-
- return 0;
+ return clk_enable(&clk);
}
static int ehci_atmel_probe(struct udevice *dev)
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 33c4a91..d3d73d2 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -115,7 +115,6 @@ static int ohci_da8xx_probe(struct udevice *dev)
err = clk_enable(&priv->clocks[i]);
if (err) {
dev_err(dev, "failed to enable clock %d\n", i);
- clk_free(&priv->clocks[i]);
goto clk_err;
}
priv->clock_count++;
diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c
index 5fc7afb..fedcf78 100644
--- a/drivers/usb/host/xhci-rcar.c
+++ b/drivers/usb/host/xhci-rcar.c
@@ -90,7 +90,7 @@ static int xhci_rcar_probe(struct udevice *dev)
ret = clk_enable(&plat->clk);
if (ret) {
dev_err(dev, "Failed to enable USB3 clock\n");
- goto err_clk;
+ return ret;
}
ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
@@ -114,8 +114,6 @@ static int xhci_rcar_probe(struct udevice *dev)
err_fw:
clk_disable(&plat->clk);
-err_clk:
- clk_free(&plat->clk);
return ret;
}
@@ -127,7 +125,6 @@ static int xhci_rcar_deregister(struct udevice *dev)
ret = xhci_deregister(dev);
clk_disable(&plat->clk);
- clk_free(&plat->clk);
return ret;
}
diff --git a/drivers/video/atmel_hlcdfb.c b/drivers/video/atmel_hlcdfb.c
index 2bf19a6..652ba14 100644
--- a/drivers/video/atmel_hlcdfb.c
+++ b/drivers/video/atmel_hlcdfb.c
@@ -62,8 +62,6 @@ static int at91_hlcdc_enable_clk(struct udevice *dev)
priv->clk_rate = clk_rate;
- clk_free(&clk);
-
return 0;
}
diff --git a/drivers/video/mali_dp.c b/drivers/video/mali_dp.c
index cbcdb99..dbb2f53 100644
--- a/drivers/video/mali_dp.c
+++ b/drivers/video/mali_dp.c
@@ -360,25 +360,18 @@ static int malidp_probe(struct udevice *dev)
err = malidp_setup_mode(priv, &timings);
if (err)
- goto fail_timings;
+ return err;
malidp_setup_layer(priv, &timings, MALIDP_LAYER_LV1,
(phys_addr_t)uc_plat->base);
err = malidp_leave_config(priv);
if (err)
- goto fail_timings;
+ return err;
malidp_set_configvalid(priv);
return 0;
-
-fail_timings:
- clk_free(&priv->aclk);
-fail_aclk:
- clk_free(&priv->pxlclk);
-
- return err;
}
static int malidp_bind(struct udevice *dev)
diff --git a/drivers/video/rockchip/rk3288_hdmi.c b/drivers/video/rockchip/rk3288_hdmi.c
index 327ae78..8bedee5 100644
--- a/drivers/video/rockchip/rk3288_hdmi.c
+++ b/drivers/video/rockchip/rk3288_hdmi.c
@@ -67,10 +67,8 @@ static int rk3288_clk_config(struct udevice *dev)
* monitor wants
*/
ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
- if (ret >= 0) {
+ if (ret >= 0)
ret = clk_set_rate(&clk, 384000000);
- clk_free(&clk);
- }
if (ret < 0) {
debug("%s: Failed to set clock in source device '%s': ret=%d\n",
__func__, uc_plat->src_dev->name, ret);
diff --git a/drivers/video/rockchip/rk_edp.c b/drivers/video/rockchip/rk_edp.c
index 3697d58..dbd70ad 100644
--- a/drivers/video/rockchip/rk_edp.c
+++ b/drivers/video/rockchip/rk_edp.c
@@ -1095,20 +1095,16 @@ static int rk_edp_probe(struct udevice *dev)
if (edp_data->chip_type == RK3288_DP) {
ret = clk_get_by_index(dev, 1, &clk);
- if (ret >= 0) {
+ if (ret >= 0)
ret = clk_set_rate(&clk, 0);
- clk_free(&clk);
- }
if (ret) {
debug("%s: Failed to set EDP clock: ret=%d\n", __func__, ret);
return ret;
}
}
ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
- if (ret >= 0) {
+ if (ret >= 0)
ret = clk_set_rate(&clk, 192000000);
- clk_free(&clk);
- }
if (ret < 0) {
debug("%s: Failed to set clock in source device '%s': ret=%d\n",
__func__, uc_plat->src_dev->name, ret);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 5697261..8318fd7 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -130,6 +130,12 @@ config WDT_AT91
Select this to enable Microchip watchdog timer, which can be found on
some AT91 devices.
+config WDT_ATCWDT200
+ bool "Andes watchdog timer support"
+ depends on WDT
+ help
+ Select this to enable Andes ATCWDT200 watchdog timer
+
config WDT_BCM6345
bool "BCM6345 watchdog timer support"
depends on WDT && (ARCH_BMIPS || BCM6856 || \
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 5520d3d..7b39adc 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_WDT_ARM_SMC) += arm_smc_wdt.o
obj-$(CONFIG_WDT_ARMADA_37XX) += armada-37xx-wdt.o
obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o
obj-$(CONFIG_WDT_AST2600) += ast2600_wdt.o
+obj-$(CONFIG_WDT_ATCWDT200) += atcwdt200_wdt.o
obj-$(CONFIG_WDT_BCM2835) += bcm2835_wdt.o
obj-$(CONFIG_WDT_BCM6345) += bcm6345_wdt.o
obj-$(CONFIG_WDT_BOOKE) += booke_wdt.o
diff --git a/drivers/watchdog/atcwdt200_wdt.c b/drivers/watchdog/atcwdt200_wdt.c
new file mode 100644
index 0000000..a29b42d
--- /dev/null
+++ b/drivers/watchdog/atcwdt200_wdt.c
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Andes Technology Corporation.
+ *
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <hang.h>
+#include <linux/bitops.h>
+#include <wdt.h>
+
+#define NODE_NOT_FOUND 0xFFFFFFFF
+
+#define WDT_WP_MAGIC 0x5aa5
+#define WDT_RESTART_MAGIC 0xcafe
+
+/* Control Register */
+#define REG_WDT_ID 0x00
+#define REG_WDT_CFG 0x10
+#define REG_WDT_RS 0x14
+#define REG_WDT_WE 0x18
+#define REG_WDT_STA 0x1C
+
+#define RST_TIME_OFF 8
+#define RST_TIME_MSK (0x7 << RST_TIME_OFF)
+#define RST_CLK_128 (0 << RST_TIME_OFF)
+#define RST_CLK_256 (1 << RST_TIME_OFF)
+#define RST_CLK_512 (2 << RST_TIME_OFF)
+#define RST_CLK_1024 (3 << RST_TIME_OFF)
+#define INT_TIME_OFF 4
+#define INT_TIME_MSK (0xf << INT_TIME_OFF)
+#define INT_CLK_2_6 (0 << INT_TIME_OFF) /* clk period*2^6 */
+#define INT_CLK_2_8 (1 << INT_TIME_OFF) /* clk period*2^8 */
+#define INT_CLK_2_10 (2 << INT_TIME_OFF) /* clk period*2^10 */
+#define INT_CLK_2_11 (3 << INT_TIME_OFF) /* clk period*2^11 */
+#define INT_CLK_2_12 (4 << INT_TIME_OFF) /* clk period*2^12 */
+#define INT_CLK_2_13 (5 << INT_TIME_OFF) /* clk period*2^13 */
+#define INT_CLK_2_14 (6 << INT_TIME_OFF) /* clk period*2^14 */
+#define INT_CLK_2_15 (7 << INT_TIME_OFF) /* clk period*2^15 */
+#define INT_CLK_2_17 (8 << INT_TIME_OFF) /* clk period*2^17 */
+#define INT_CLK_2_19 (9 << INT_TIME_OFF) /* clk period*2^19 */
+#define INT_CLK_2_21 (10 << INT_TIME_OFF) /* clk period*2^21 */
+#define INT_CLK_2_23 (11 << INT_TIME_OFF) /* clk period*2^23 */
+#define INT_CLK_2_25 (12 << INT_TIME_OFF) /* clk period*2^25 */
+#define INT_CLK_2_27 (13 << INT_TIME_OFF) /* clk period*2^27 */
+#define INT_CLK_2_29 (14 << INT_TIME_OFF) /* clk period*2^29 */
+#define INT_CLK_2_31 (15 << INT_TIME_OFF) /* clk period*2^31 */
+#define INT_CLK_MIN 0x0
+#define INT_CLK_MAX_16B 0x7
+#define INT_CLK_MAX_32B 0xF
+#define RST_EN BIT(3)
+#define INT_EN BIT(2)
+#define CLK_PCLK BIT(1)
+#define WDT_EN BIT(0)
+#define INT_EXPIRED BIT(0)
+
+#define INT_TIME_ARRAY 16
+#define RST_TIME_ARRAY 8
+
+struct wdt_priv {
+ void __iomem *base;
+ u32 wdt_clk_src;
+ u32 clk_freq;
+ u8 max_clk;
+};
+
+static inline u8 atcwdt_get_2_power_of_n(u8 index, u8 type)
+{
+ const u8 div_int[INT_TIME_ARRAY] = {6, 8, 10, 11, 12, 13, 14, 15,
+ 17, 19, 21, 23, 25, 27, 29, 31};
+ const u8 div_rst[RST_TIME_ARRAY] = {7, 8, 9, 10, 11, 12, 13, 14};
+ const u8 *pdiv;
+
+ if (type == RST_TIME_ARRAY)
+ pdiv = div_rst;
+ else
+ pdiv = div_int;
+
+ if (index >= type)
+ index = type - 1;
+
+ return pdiv[index];
+}
+
+static u8 atcwdt_search_msb(u64 freq_ms, u8 type)
+{
+ u64 result;
+ u64 freq_sec;
+ u8 index;
+
+ freq_sec = freq_ms / 1000;
+ for (index = 0; index < type; index++) {
+ result = freq_sec >> atcwdt_get_2_power_of_n(index, type);
+
+ if (result <= 1)
+ break;
+ }
+
+ return index;
+}
+
+static int atcwdt_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+ struct wdt_priv *priv = dev_get_priv(dev);
+ u64 rst_max_count;
+ u32 rst_max_time_ms;
+ u64 rst_time_ms;
+ u64 int_time_ms;
+ u8 rst_time;
+ u8 int_time;
+
+ rst_max_count = 1 << atcwdt_get_2_power_of_n(RST_TIME_ARRAY, RST_TIME_ARRAY);
+ rst_max_time_ms = (rst_max_count * 1000) / priv->clk_freq;
+
+ if (timeout > rst_max_time_ms) {
+ int_time_ms = timeout - rst_max_time_ms;
+ rst_time_ms = rst_max_time_ms;
+ } else {
+ int_time_ms = 0;
+ rst_time_ms = timeout;
+ }
+
+ rst_time = atcwdt_search_msb(rst_time_ms * priv->clk_freq, RST_TIME_ARRAY);
+
+ if (int_time_ms) {
+ int_time = atcwdt_search_msb(int_time_ms * priv->clk_freq, INT_TIME_ARRAY);
+ if (int_time > priv->max_clk)
+ int_time = priv->max_clk;
+ } else {
+ int_time = 0;
+ }
+
+ writel(WDT_WP_MAGIC, priv->base + REG_WDT_WE);
+ writel(((rst_time << RST_TIME_OFF) & RST_TIME_MSK) | ((int_time << INT_TIME_OFF) &
+ INT_TIME_MSK) | INT_EN | RST_EN | priv->wdt_clk_src | WDT_EN,
+ priv->base + REG_WDT_CFG);
+
+ return 0;
+}
+
+static int atcwdt_wdt_stop(struct udevice *dev)
+{
+ struct wdt_priv *priv = dev_get_priv(dev);
+
+ writel(WDT_WP_MAGIC, priv->base + REG_WDT_WE);
+ writel(0, priv->base + REG_WDT_CFG);
+
+ return 0;
+}
+
+static int atcwdt_wdt_restart(struct udevice *dev)
+{
+ struct wdt_priv *priv = dev_get_priv(dev);
+
+ writel(WDT_WP_MAGIC, priv->base + REG_WDT_WE);
+ writel(WDT_RESTART_MAGIC, priv->base + REG_WDT_RS);
+ setbits_le32(priv->base + REG_WDT_STA, INT_EXPIRED);
+
+ return 0;
+}
+
+static int atcwdt_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+ atcwdt_wdt_start(dev, 0, 0);
+ hang();
+
+ return 0;
+}
+
+static int atcwdt_wdt_probe(struct udevice *dev)
+{
+ struct wdt_priv *priv = dev_get_priv(dev);
+ int timer_16bit;
+
+ priv->base = dev_remap_addr_index(dev, 0);
+ if (!priv->base)
+ return -EFAULT;
+
+ priv->wdt_clk_src = dev_read_u32_default(dev, "clock-source", NODE_NOT_FOUND);
+ if (priv->wdt_clk_src == NODE_NOT_FOUND || priv->wdt_clk_src > 1)
+ priv->wdt_clk_src = CLK_PCLK;
+
+ timer_16bit = dev_read_u32_default(dev, "16bit_timer", NODE_NOT_FOUND);
+ if (timer_16bit == 1 || timer_16bit == NODE_NOT_FOUND)
+ priv->max_clk = INT_CLK_MAX_16B;
+ else
+ priv->max_clk = INT_CLK_MAX_32B;
+
+ priv->clk_freq = dev_read_u32_default(dev, "clock-frequency", NODE_NOT_FOUND);
+ if (priv->clk_freq == NODE_NOT_FOUND) {
+ printf("atcwdt200: Please provide a valid \"clock-frequency\" in DTB\n");
+ return -EINVAL;
+ }
+
+ atcwdt_wdt_stop(dev);
+
+ return 0;
+}
+
+static const struct wdt_ops atcwdt_wdt_ops = {
+ .start = atcwdt_wdt_start,
+ .reset = atcwdt_wdt_restart,
+ .stop = atcwdt_wdt_stop,
+ .expire_now = atcwdt_wdt_expire_now,
+};
+
+static const struct udevice_id atcwdt_wdt_ids[] = {
+ {.compatible = "andestech,atcwdt200"},
+ {}
+};
+
+U_BOOT_DRIVER(atcwdt) = {
+ .name = "atcwdt200",
+ .id = UCLASS_WDT,
+ .probe = atcwdt_wdt_probe,
+ .of_match = atcwdt_wdt_ids,
+ .ops = &atcwdt_wdt_ops,
+ .priv_auto = sizeof(struct wdt_priv),
+};
diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c
index 447a22d..b22e0ee 100644
--- a/drivers/watchdog/designware_wdt.c
+++ b/drivers/watchdog/designware_wdt.c
@@ -124,13 +124,11 @@ static int designware_wdt_probe(struct udevice *dev)
ret = clk_enable(&clk);
if (ret)
- goto err;
+ return ret;
priv->clk_khz = clk_get_rate(&clk) / 1000;
- if (!priv->clk_khz) {
- ret = -EINVAL;
- goto err;
- }
+ if (!priv->clk_khz)
+ return -EINVAL;
#else
priv->clk_khz = CFG_DW_WDT_CLOCK_KHZ;
#endif
@@ -139,21 +137,15 @@ static int designware_wdt_probe(struct udevice *dev)
ofnode_read_prop(dev_ofnode(dev), "resets", &ret)) {
ret = reset_get_bulk(dev, &priv->resets);
if (ret)
- goto err;
+ return ret;
ret = reset_deassert_bulk(&priv->resets);
if (ret)
- goto err;
+ return ret;
}
/* reset to disable the watchdog */
return designware_wdt_stop(dev);
-
-err:
-#if CONFIG_IS_ENABLED(CLK)
- clk_free(&clk);
-#endif
- return ret;
}
static const struct wdt_ops designware_wdt_ops = {
diff --git a/drivers/watchdog/meson_gxbb_wdt.c b/drivers/watchdog/meson_gxbb_wdt.c
index 6ab0058..01a35b3 100644
--- a/drivers/watchdog/meson_gxbb_wdt.c
+++ b/drivers/watchdog/meson_gxbb_wdt.c
@@ -98,10 +98,8 @@ static int amlogic_wdt_probe(struct udevice *dev)
return ret;
ret = clk_enable(&clk);
- if (ret) {
- clk_free(&clk);
+ if (ret)
return ret;
- }
/* Setup with 1ms timebase */
writel(((clk_get_rate(&clk) / 1000) & GXBB_WDT_CTRL_DIV_MASK) |
diff --git a/include/clk-uclass.h b/include/clk-uclass.h
index cd62848..8c07e72 100644
--- a/include/clk-uclass.h
+++ b/include/clk-uclass.h
@@ -18,7 +18,6 @@ struct ofnode_phandle_args;
* struct clk_ops - The functions that a clock driver must implement.
* @of_xlate: Translate a client's device-tree (OF) clock specifier.
* @request: Request a translated clock.
- * @rfree: Free a previously requested clock.
* @round_rate: Adjust a rate to the exact rate a clock can provide.
* @get_rate: Get current clock rate.
* @set_rate: Set current clock rate.
@@ -33,7 +32,6 @@ struct clk_ops {
int (*of_xlate)(struct clk *clock,
struct ofnode_phandle_args *args);
int (*request)(struct clk *clock);
- void (*rfree)(struct clk *clock);
ulong (*round_rate)(struct clk *clk, ulong rate);
ulong (*get_rate)(struct clk *clk);
ulong (*set_rate)(struct clk *clk, ulong rate);
@@ -58,11 +56,20 @@ struct clk_ops {
* default implementation, which assumes #clock-cells = <1>, and that
* the DT cell contains a simple integer clock ID.
*
+ * This function should be a simple translation of @args into @clock->id and
+ * (optionally) @clock->data. All other processing, allocation, or error
+ * checking should take place in request().
+ *
* At present, the clock API solely supports device-tree. If this
* changes, other xxx_xlate() functions may be added to support those
* other mechanisms.
*
- * Return: 0 if OK, or a negative error code.
+ * Return:
+ * * 0 on success
+ * * -%EINVAL if @args does not have the correct format. For example, it could
+ * have too many/few arguments.
+ * * -%ENOENT if @args has the correct format but cannot be translated. This can
+ * happen if translation involves a table lookup and @args is not present.
*/
int of_xlate(struct clk *clock, struct ofnode_phandle_args *args);
@@ -77,24 +84,36 @@ int of_xlate(struct clk *clock, struct ofnode_phandle_args *args);
* xxx_xlate() call, or as the only step in implementing a client's
* clk_request() call.
*
- * Return: 0 if OK, or a negative error code.
- */
-int request(struct clk *clock);
-
-/**
- * rfree() - Free a previously requested clock.
- * @clock: The clock to free.
+ * This is the right place to do bounds checking (rejecting invalid or
+ * unimplemented clocks), allocate resources, or perform other setup not done
+ * during driver probe(). Most clock drivers should allocate resources in their
+ * probe() function, but it is possible to lazily initialize something here.
*
- * Free any resources allocated in request().
+ * Return:
+ * * 0 on success
+ * * -%ENOENT, if there is no clock corresponding to @clock->id and
+ * @clock->data.
*/
-void rfree(struct clk *clock);
+int request(struct clk *clock);
/**
* round_rate() - Adjust a rate to the exact rate a clock can provide.
- * @clk: The clock to manipulate.
- * @rate: Desidered clock rate in Hz.
+ * @clk: The clock to query.
+ * @rate: Desired clock rate in Hz.
+ *
+ * This function returns a new rate which can be provided to set_rate(). This
+ * new rate should be the closest rate to @rate which can be set without
+ * rounding. The following pseudo-code should hold::
*
- * Return: rounded rate in Hz, or -ve error code.
+ * for all rate in range(ULONG_MAX):
+ * rounded = round_rate(clk, rate)
+ * new_rate = set_rate(clk, rate)
+ * assert(IS_ERR_VALUE(new_rate) || new_rate == rounded)
+ *
+ * Return:
+ * * The rounded rate in Hz on success
+ * * A negative error value from another API (such as clk_get_rate()). This
+ * function must not return an error for any other reason.
*/
ulong round_rate(struct clk *clk, ulong rate);
@@ -102,7 +121,22 @@ ulong round_rate(struct clk *clk, ulong rate);
* get_rate() - Get current clock rate.
* @clk: The clock to query.
*
- * Return: clock rate in Hz, or -ve error code
+ * This returns the current rate of a clock. If the clock is disabled, it
+ * returns the rate at which the clock would run if it was enabled. The
+ * following pseudo-code should hold::
+ *
+ * disable(clk)
+ * rate = get_rate(clk)
+ * enable(clk)
+ * assert(get_rate(clk) == rate)
+ *
+ * Return:
+ * * The rate of @clk
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing
+ * this check in request().
+ * * Another negative error value (such as %EIO or %ECOMM) if the rate could
+ * not be determined due to a bus error.
*/
ulong get_rate(struct clk *clk);
@@ -111,7 +145,27 @@ ulong get_rate(struct clk *clk);
* @clk: The clock to manipulate.
* @rate: New clock rate in Hz.
*
- * Return: new rate, or -ve error code.
+ * Set the rate of @clk to @rate. The actual rate may be rounded. However,
+ * excessive rounding should be avoided. It is left to the driver author's
+ * discretion when this function should attempt to round and when it should
+ * return an error. For example, a dividing clock might use the following
+ * pseudo-logic when implemening this function::
+ *
+ * divisor = parent_rate / rate
+ * if divisor < min || divisor > max:
+ * return -EINVAL
+ *
+ * If there is any concern about rounding, prefer to let consumers make the
+ * decision by calling round_rate().
+ *
+ * Return:
+ * * The new rate on success
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing
+ * this check in request().
+ * * -%EINVAL if @rate is not valid for @clk.
+ * * Another negative error value (such as %EIO or %ECOMM) if the rate could
+ * not be set due to a bus error.
*/
ulong set_rate(struct clk *clk, ulong rate);
@@ -120,7 +174,19 @@ ulong set_rate(struct clk *clk, ulong rate);
* @clk: The clock to manipulate.
* @parent: New clock parent.
*
- * Return: zero on success, or -ve error code.
+ * Set the current parent of @clk to @parent. The rate of the clock may be
+ * modified by this call. If @clk was enabled before this function, it should
+ * remain enabled after this function, although it may be temporarily disabled
+ * if necessary.
+ *
+ * Return:
+ * * 0 on success
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id or @parent->id is invalid. Prefer using an assert
+ * instead, and doing this check in request().
+ * * -%EINVAL if @parent is not a valid parent for @clk.
+ * * Another negative error value (such as %EIO or %ECOMM) if the parent could
+ * not be set due to a bus error.
*/
int set_parent(struct clk *clk, struct clk *parent);
@@ -128,7 +194,16 @@ int set_parent(struct clk *clk, struct clk *parent);
* enable() - Enable a clock.
* @clk: The clock to manipulate.
*
- * Return: zero on success, or -ve error code.
+ * Enable (un-gate) the clock. This function should not modify the rate of the
+ * clock (see get_rate() for details).
+ *
+ * Return:
+ * * 0 on success
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing
+ * this check in request().
+ * * Another negative error value (such as %EIO or %ECOMM) if the clock could
+ * not be enabled due to a bus error.
*/
int enable(struct clk *clk);
@@ -136,7 +211,15 @@ int enable(struct clk *clk);
* disable() - Disable a clock.
* @clk: The clock to manipulate.
*
- * Return: zero on success, or -ve error code.
+ * Disable (gate) the clock. This function should not modify the rate of the
+ * clock (see get_rate() for details).
+ *
+ * * 0 on success
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing
+ * this check in request().
+ * * Another negative error value (such as %EIO or %ECOMM) if the clock could
+ * not be disabled due to a bus error.
*/
int disable(struct clk *clk);
diff --git a/include/clk.h b/include/clk.h
index 3d63944..af23e4f 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -247,19 +247,6 @@ static inline struct clk *devm_clk_get_optional(struct udevice *dev,
*/
int clk_release_all(struct clk *clk, unsigned int count);
-/**
- * devm_clk_put - "free" a managed clock source
- * @dev: device used to acquire the clock
- * @clk: clock source acquired with devm_clk_get()
- *
- * Note: drivers must ensure that all clk_enable calls made on this
- * clock source are balanced by clk_disable calls prior to calling
- * this function.
- *
- * clk_put should not be called from within interrupt context.
- */
-void devm_clk_put(struct udevice *dev, struct clk *clk);
-
#else
static inline int clk_get_by_phandle(struct udevice *dev, const
@@ -313,10 +300,6 @@ static inline int clk_release_all(struct clk *clk, unsigned int count)
{
return -ENOSYS;
}
-
-static inline void devm_clk_put(struct udevice *dev, struct clk *clk)
-{
-}
#endif
/**
@@ -442,15 +425,6 @@ static inline int clk_release_bulk(struct clk_bulk *bulk)
int clk_request(struct udevice *dev, struct clk *clk);
/**
- * clk_free() - Free a previously requested clock.
- * @clk: A clock struct that was previously successfully requested by
- * clk_request/get_by_*().
- *
- * Free resources allocated by clk_request() (or any clk_get_* function).
- */
-void clk_free(struct clk *clk);
-
-/**
* clk_get_rate() - Get current clock rate.
* @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*().
@@ -594,11 +568,6 @@ static inline int clk_request(struct udevice *dev, struct clk *clk)
return -ENOSYS;
}
-static inline void clk_free(struct clk *clk)
-{
- return;
-}
-
static inline ulong clk_get_rate(struct clk *clk)
{
return -ENOSYS;
diff --git a/include/configs/milkv_duo.h b/include/configs/milkv_duo.h
new file mode 100644
index 0000000..0b4109d
--- /dev/null
+++ b/include/configs/milkv_duo.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CFG_SYS_SDRAM_BASE 0x80000000
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h
index 584559c..2f594bf 100644
--- a/include/configs/qemu-riscv.h
+++ b/include/configs/qemu-riscv.h
@@ -23,6 +23,7 @@
#define BOOT_TARGET_DEVICES(func) \
func(VIRTIO, virtio, 0) \
+ func(VIRTIO, virtio, 1) \
func(SCSI, scsi, 0) \
func(DHCP, dhcp, na)
diff --git a/include/smbios.h b/include/smbios.h
index e2b7f69..3df8827 100644
--- a/include/smbios.h
+++ b/include/smbios.h
@@ -75,7 +75,7 @@ struct __packed smbios3_entry {
/** @reserved: reserved */
u8 reserved;
/** maximum size of SMBIOS table */
- u32 max_struct_size;
+ u32 table_maximum_size;
/** @struct_table_address: 64-bit physical starting address */
u64 struct_table_address;
};
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index b5d4aa7..b07e009 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -1098,7 +1098,7 @@ tcg2_measure_smbios(struct udevice *dev,
*/
event_size = sizeof(struct smbios_handoff_table_pointers2) +
FIELD_SIZEOF(struct efi_configuration_table, guid) +
- entry->max_struct_size;
+ entry->table_maximum_size;
event = calloc(1, event_size);
if (!event) {
ret = EFI_OUT_OF_RESOURCES;
@@ -1113,7 +1113,7 @@ tcg2_measure_smbios(struct udevice *dev,
smbios_copy = (struct smbios_header *)((uintptr_t)&event->table_entry[0].table);
memcpy(&event->table_entry[0].table,
(void *)((uintptr_t)entry->struct_table_address),
- entry->max_struct_size);
+ entry->table_maximum_size);
smbios_prepare_measurement(entry, smbios_copy);
diff --git a/lib/efi_loader/smbiosdump.c b/lib/efi_loader/smbiosdump.c
index f0b9018..2f0b91a 100644
--- a/lib/efi_loader/smbiosdump.c
+++ b/lib/efi_loader/smbiosdump.c
@@ -329,7 +329,7 @@ efi_status_t do_check(void)
return EFI_LOAD_ERROR;
}
table = (void *)(uintptr_t)smbios3_anchor->struct_table_address;
- len = smbios3_anchor->max_struct_size;
+ len = smbios3_anchor->table_maximum_size;
} else {
struct smbios_entry *smbios_anchor;
int r;
@@ -469,7 +469,7 @@ static efi_status_t do_save(u16 *filename)
smbios3_anchor = get_config_table(&smbios3_guid);
if (smbios3_anchor) {
- size = 0x20 + smbios3_anchor->max_struct_size;
+ size = 0x20 + smbios3_anchor->table_maximum_size;
ret = bs->allocate_pool(EFI_LOADER_DATA, size, (void **)&buf);
if (ret != EFI_SUCCESS) {
error(u"Out of memory\n");
@@ -480,7 +480,7 @@ static efi_status_t do_save(u16 *filename)
memcpy(buf, smbios3_anchor, smbios3_anchor->length);
memcpy(buf + 0x20,
(void *)(uintptr_t)smbios3_anchor->struct_table_address,
- smbios3_anchor->max_struct_size);
+ smbios3_anchor->table_maximum_size);
smbios3_anchor = (struct smbios3_entry *)buf;
smbios3_anchor->struct_table_address = 0x20;
diff --git a/lib/smbios-parser.c b/lib/smbios-parser.c
index f48d743..9a62b3c 100644
--- a/lib/smbios-parser.c
+++ b/lib/smbios-parser.c
@@ -15,7 +15,7 @@ const struct smbios_entry *smbios_entry(u64 address, u32 size)
{
const struct smbios_entry *entry = (struct smbios_entry *)(uintptr_t)address;
- if (!address | !size)
+ if (!address || !size)
return NULL;
if (memcmp(entry->anchor, "_SM_", 4))
@@ -230,7 +230,7 @@ void smbios_prepare_measurement(const struct smbios3_entry *entry,
void *table_end;
struct smbios_header *header;
- table_end = (void *)((u8 *)smbios_copy + entry->max_struct_size);
+ table_end = (void *)((u8 *)smbios_copy + entry->table_maximum_size);
for (i = 0; i < ARRAY_SIZE(smbios_filter_tables); i++) {
header = smbios_copy;
diff --git a/lib/smbios.c b/lib/smbios.c
index 7bd9805..c83af73 100644
--- a/lib/smbios.c
+++ b/lib/smbios.c
@@ -135,13 +135,16 @@ static const struct map_sysinfo *convert_sysinfo_to_dt(const char *node, const c
*
* @ctx: SMBIOS context
* @str: string to add
- * Return: string number in the string area (1 or more)
+ * Return: string number in the string area. 0 if str is NULL.
*/
static int smbios_add_string(struct smbios_ctx *ctx, const char *str)
{
int i = 1;
char *p = ctx->eos;
+ if (!str)
+ return 0;
+
for (;;) {
if (!*p) {
ctx->last_str = p;
@@ -207,6 +210,7 @@ void get_str_from_dt(const struct map_sysinfo *nprop, char *str, size_t size)
*
* @ctx: context for writing the tables
* @prop: property to write
+ * @sysinfo_id: unique identifier for the string value to be read
* @dval: Default value to use if the string is not found or is empty
* Return: 0 if not found, else SMBIOS string number (1 or more)
*/
@@ -216,7 +220,7 @@ static int smbios_add_prop_si(struct smbios_ctx *ctx, const char *prop,
int ret;
if (!dval || !*dval)
- dval = "Unknown";
+ dval = NULL;
if (!prop)
return smbios_add_string(ctx, dval);
@@ -311,6 +315,10 @@ int smbios_update_version(const char *version)
*/
static int smbios_string_table_len(const struct smbios_ctx *ctx)
{
+ /* In case no string is defined we have to return two \0 */
+ if (ctx->next_ptr == ctx->eos)
+ return 2;
+
/* Allow for the final \0 after all strings */
return (ctx->next_ptr + 1) - ctx->eos;
}
@@ -375,19 +383,19 @@ static int smbios_write_type1(ulong *current, int handle,
memset(t, 0, sizeof(struct smbios_type1));
fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle);
smbios_set_eos(ctx, t->eos);
- t->manufacturer = smbios_add_prop(ctx, "manufacturer", "Unknown");
- t->product_name = smbios_add_prop(ctx, "product", "Unknown");
+ t->manufacturer = smbios_add_prop(ctx, "manufacturer", NULL);
+ t->product_name = smbios_add_prop(ctx, "product", NULL);
t->version = smbios_add_prop_si(ctx, "version",
SYSINFO_ID_SMBIOS_SYSTEM_VERSION,
- "Unknown");
+ NULL);
if (serial_str) {
t->serial_number = smbios_add_prop(ctx, NULL, serial_str);
strncpy((char *)t->uuid, serial_str, sizeof(t->uuid));
} else {
- t->serial_number = smbios_add_prop(ctx, "serial", "Unknown");
+ t->serial_number = smbios_add_prop(ctx, "serial", NULL);
}
- t->sku_number = smbios_add_prop(ctx, "sku", "Unknown");
- t->family = smbios_add_prop(ctx, "family", "Unknown");
+ t->sku_number = smbios_add_prop(ctx, "sku", NULL);
+ t->family = smbios_add_prop(ctx, "family", NULL);
len = t->length + smbios_string_table_len(ctx);
*current += len;
@@ -406,14 +414,15 @@ static int smbios_write_type2(ulong *current, int handle,
memset(t, 0, sizeof(struct smbios_type2));
fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle);
smbios_set_eos(ctx, t->eos);
- t->manufacturer = smbios_add_prop(ctx, "manufacturer", "Unknown");
- t->product_name = smbios_add_prop(ctx, "product", "Unknown");
+ t->manufacturer = smbios_add_prop(ctx, "manufacturer", NULL);
+ t->product_name = smbios_add_prop(ctx, "product", NULL);
t->version = smbios_add_prop_si(ctx, "version",
SYSINFO_ID_SMBIOS_BASEBOARD_VERSION,
- "Unknown");
- t->asset_tag_number = smbios_add_prop(ctx, "asset-tag", "Unknown");
+ NULL);
+ t->asset_tag_number = smbios_add_prop(ctx, "asset-tag", NULL);
t->feature_flags = SMBIOS_BOARD_FEATURE_HOSTING;
t->board_type = SMBIOS_BOARD_MOTHERBOARD;
+ t->chassis_handle = handle + 1;
len = t->length + smbios_string_table_len(ctx);
*current += len;
@@ -432,7 +441,7 @@ static int smbios_write_type3(ulong *current, int handle,
memset(t, 0, sizeof(struct smbios_type3));
fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle);
smbios_set_eos(ctx, t->eos);
- t->manufacturer = smbios_add_prop(ctx, "manufacturer", "Unknown");
+ t->manufacturer = smbios_add_prop(ctx, "manufacturer", NULL);
t->chassis_type = SMBIOS_ENCLOSURE_DESKTOP;
t->bootup_state = SMBIOS_STATE_SAFE;
t->power_supply_state = SMBIOS_STATE_SAFE;
@@ -450,8 +459,8 @@ static void smbios_write_type4_dm(struct smbios_type4 *t,
struct smbios_ctx *ctx)
{
u16 processor_family = SMBIOS_PROCESSOR_FAMILY_UNKNOWN;
- const char *vendor = "Unknown";
- const char *name = "Unknown";
+ const char *vendor = NULL;
+ const char *name = NULL;
#ifdef CONFIG_CPU
char processor_name[49];
@@ -542,6 +551,7 @@ static struct smbios_write_method smbios_write_funcs[] = {
{ smbios_write_type0, "bios", },
{ smbios_write_type1, "system", },
{ smbios_write_type2, "baseboard", },
+ /* Type 3 must immediately follow type 2 due to chassis handle. */
{ smbios_write_type3, "chassis", },
{ smbios_write_type4, },
{ smbios_write_type32, },
@@ -556,7 +566,6 @@ ulong write_smbios_table(ulong addr)
struct smbios_ctx ctx;
ulong tables;
int len = 0;
- int max_struct_size = 0;
int handle = 0;
int i;
@@ -578,7 +587,6 @@ ulong write_smbios_table(ulong addr)
/* populate minimum required tables */
for (i = 0; i < ARRAY_SIZE(smbios_write_funcs); i++) {
const struct smbios_write_method *method;
- int tmp;
method = &smbios_write_funcs[i];
ctx.subnode_name = NULL;
@@ -588,10 +596,7 @@ ulong write_smbios_table(ulong addr)
ctx.node = ofnode_find_subnode(parent_node,
method->subnode_name);
}
- tmp = method->write((ulong *)&addr, handle++, &ctx);
-
- max_struct_size = max(max_struct_size, tmp);
- len += tmp;
+ len += method->write((ulong *)&addr, handle++, &ctx);
}
/*
@@ -610,7 +615,7 @@ ulong write_smbios_table(ulong addr)
se->minor_ver = SMBIOS_MINOR_VER;
se->doc_rev = 0;
se->entry_point_rev = 1;
- se->max_struct_size = len;
+ se->table_maximum_size = len;
se->struct_table_address = table_addr;
se->checksum = table_compute_checksum(se, sizeof(struct smbios3_entry));
unmap_sysmem(se);
diff --git a/test/dm/clk.c b/test/dm/clk.c
index 01417fb..57fabbd 100644
--- a/test/dm/clk.c
+++ b/test/dm/clk.c
@@ -182,19 +182,10 @@ static int dm_test_clk(struct unit_test_state *uts)
SANDBOX_CLK_ID_I2C));
ut_asserteq(1, sandbox_clk_query_requested(dev_clk,
SANDBOX_CLK_ID_UART2));
- ut_assertok(sandbox_clk_test_free(dev_test));
- ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
- SANDBOX_CLK_ID_SPI));
- ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
- SANDBOX_CLK_ID_I2C));
- ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
- SANDBOX_CLK_ID_UART2));
ut_asserteq(1, sandbox_clk_query_requested(dev_clk,
SANDBOX_CLK_ID_UART1));
ut_assertok(device_remove(dev_test, DM_REMOVE_NORMAL));
- ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
- SANDBOX_CLK_ID_UART1));
return 0;
}
DM_TEST(dm_test_clk, UT_TESTF_SCAN_FDT);