summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/dts/ipq9574-rdp433-u-boot.dtsi25
-rw-r--r--arch/arm/dts/r8a779g0-u-boot.dtsi4
-rw-r--r--arch/arm/lib/crt0_aarch64_efi.S1
-rw-r--r--arch/arm/lib/crt0_arm_efi.S1
-rw-r--r--arch/arm/mach-snapdragon/board.c123
-rw-r--r--arch/riscv/cpu/k1/Kconfig1
-rw-r--r--arch/riscv/dts/binman.dtsi10
-rw-r--r--arch/riscv/dts/cv18xx.dtsi14
-rw-r--r--arch/riscv/dts/k1.dtsi35
-rw-r--r--arch/riscv/dts/starfive-visionfive2-binman.dtsi76
-rw-r--r--arch/riscv/lib/crt0_riscv_efi.S1
-rw-r--r--board/emulation/qemu-riscv/Kconfig1
-rw-r--r--board/renesas/common/Makefile2
-rw-r--r--board/renesas/common/gen4-common.c126
-rw-r--r--board/renesas/common/gen4-spl.c2
-rw-r--r--board/starfive/visionfive2/spl.c4
-rw-r--r--board/toradex/verdin-am62/verdin-am62.c7
-rw-r--r--cmd/version.c1
-rw-r--r--configs/bananapi-f3_defconfig1
-rw-r--r--configs/qcom_defconfig2
-rw-r--r--configs/qcom_ipq9574_mmc_defconfig83
-rw-r--r--configs/r8a779g0_whitehawk_defconfig2
-rw-r--r--configs/renesas_rzg2l_smarc_defconfig8
-rw-r--r--configs/sifive_unmatched_defconfig2
-rw-r--r--doc/README.bitbangMII39
-rw-r--r--doc/board/qualcomm/index.rst1
-rw-r--r--doc/board/qualcomm/rdp.rst55
-rw-r--r--doc/develop/bitbangmii.rst75
-rw-r--r--doc/develop/index.rst1
-rw-r--r--doc/develop/release_cycle.rst2
-rw-r--r--drivers/clk/clk-stub.c1
-rw-r--r--drivers/clk/qcom/Kconfig8
-rw-r--r--drivers/clk/qcom/Makefile1
-rw-r--r--drivers/clk/qcom/clock-apq8016.c12
-rw-r--r--drivers/clk/qcom/clock-ipq9574.c94
-rw-r--r--drivers/clk/qcom/clock-qcm2290.c4
-rw-r--r--drivers/clk/qcom/clock-qcom.h13
-rw-r--r--drivers/clk/qcom/clock-sa8775p.c4
-rw-r--r--drivers/clk/qcom/clock-sc7280.c124
-rw-r--r--drivers/clk/qcom/clock-sdm845.c4
-rw-r--r--drivers/clk/qcom/clock-sm6115.c4
-rw-r--r--drivers/clk/qcom/clock-sm8150.c4
-rw-r--r--drivers/clk/qcom/clock-sm8250.c4
-rw-r--r--drivers/clk/qcom/clock-sm8550.c4
-rw-r--r--drivers/clk/qcom/clock-sm8650.c4
-rw-r--r--drivers/clk/qcom/clock-x1e80100.c4
-rw-r--r--drivers/mmc/msm_sdhci.c10
-rw-r--r--drivers/net/phy/micrel_ksz90x1.c169
-rw-r--r--drivers/net/ravb.c14
-rw-r--r--drivers/phy/Kconfig4
-rw-r--r--drivers/phy/phy-rcar-gen3.c79
-rw-r--r--drivers/pinctrl/qcom/Kconfig38
-rw-r--r--drivers/pinctrl/qcom/Makefile2
-rw-r--r--drivers/pinctrl/qcom/pinctrl-apq8016.c4
-rw-r--r--drivers/pinctrl/qcom/pinctrl-apq8096.c4
-rw-r--r--drivers/pinctrl/qcom/pinctrl-ipq4019.c3
-rw-r--r--drivers/pinctrl/qcom/pinctrl-ipq9574.c226
-rw-r--r--drivers/pinctrl/qcom/pinctrl-qcm2290.c2
-rw-r--r--drivers/pinctrl/qcom/pinctrl-qcom.c5
-rw-r--r--drivers/pinctrl/qcom/pinctrl-qcom.h3
-rw-r--r--drivers/pinctrl/qcom/pinctrl-qcs404.c4
-rw-r--r--drivers/pinctrl/qcom/pinctrl-sc7280.c106
-rw-r--r--drivers/pinctrl/qcom/pinctrl-sdm845.c4
-rw-r--r--drivers/pinctrl/qcom/pinctrl-sm6115.c2
-rw-r--r--drivers/pinctrl/qcom/pinctrl-sm8150.c4
-rw-r--r--drivers/pinctrl/qcom/pinctrl-sm8250.c2
-rw-r--r--drivers/pinctrl/qcom/pinctrl-sm8550.c4
-rw-r--r--drivers/pinctrl/qcom/pinctrl-sm8650.c4
-rw-r--r--drivers/pinctrl/qcom/pinctrl-x1e80100.c4
-rw-r--r--drivers/power/regulator/Kconfig8
-rw-r--r--drivers/power/regulator/Makefile1
-rw-r--r--drivers/power/regulator/rzg2l-usbphy-regulator.c42
-rw-r--r--drivers/ram/renesas/dbsc5/dbsc5.c3
-rw-r--r--drivers/ram/renesas/dbsc5/dbsc5.h1
-rw-r--r--drivers/ram/renesas/dbsc5/dram.c167
-rw-r--r--drivers/reset/Kconfig16
-rw-r--r--drivers/reset/Makefile2
-rw-r--r--drivers/reset/reset-rzg2l-usbphy-ctrl.c142
-rw-r--r--drivers/reset/reset-spacemit-k1.c548
-rw-r--r--drivers/rng/msm_rng.c13
-rw-r--r--drivers/sysreset/Kconfig1
-rw-r--r--drivers/usb/dwc3/gadget.c19
-rw-r--r--fs/fs.c2
-rw-r--r--include/configs/sifive-unleashed.h1
-rw-r--r--include/configs/sifive-unmatched.h1
-rw-r--r--include/dbsc5.h56
-rw-r--r--include/dt-bindings/reset/spacemit-k1-reset.h118
-rw-r--r--include/lmb.h6
-rw-r--r--include/phy.h24
-rw-r--r--include/renesas/rzg2l-usbphy.h17
-rw-r--r--lib/efi_loader/efi_memory.c3
-rw-r--r--lib/efi_loader/elf_efi.ldsi6
-rw-r--r--lib/lmb.c6
-rw-r--r--scripts/Makefile.lib4
-rwxr-xr-xscripts/checkpatch.pl6
-rwxr-xr-xscripts/event_dump.py2
-rw-r--r--test/lib/lmb.c53
-rwxr-xr-xtools/qconfig.py4
-rw-r--r--tools/sfspl.c5
101 files changed, 2511 insertions, 461 deletions
diff --git a/Makefile b/Makefile
index ea6ca427496..620996862e6 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
VERSION = 2025
PATCHLEVEL = 04
SUBLEVEL =
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc5
NAME =
# *DOCUMENTATION*
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index cf08fe63f1e..32b80da9869 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1117,6 +1117,8 @@ config ARCH_SNAPDRAGON
select OF_BOARD
select SAVE_PREV_BL_FDT_ADDR
select LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK
+ select SYSRESET
+ select SYSRESET_PSCI
imply OF_UPSTREAM
imply CMD_DM
diff --git a/arch/arm/dts/ipq9574-rdp433-u-boot.dtsi b/arch/arm/dts/ipq9574-rdp433-u-boot.dtsi
new file mode 100644
index 00000000000..390e2338d65
--- /dev/null
+++ b/arch/arm/dts/ipq9574-rdp433-u-boot.dtsi
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/ {
+ /* Will be removed when SMEM parsing is updated */
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x0 0x40000000 0x0 0x40000000>,
+ <0x0 0x4a500000 0x0 0x00100000>;
+ };
+};
+
+&sdhc_1 {
+ sdhci-caps-mask = <0x0 0x04000000>;
+ sdhci-caps = <0x0 0x04000000>; /* SDHCI_CAN_VDD_180 */
+
+ /*
+ * This reset is needed to clear out the settings done by
+ * previous boot loader. Without this the SDHCI_RESET_ALL
+ * reset done sdhci_init() times out.
+ */
+ resets = <&gcc GCC_SDCC_BCR>;
+};
diff --git a/arch/arm/dts/r8a779g0-u-boot.dtsi b/arch/arm/dts/r8a779g0-u-boot.dtsi
index 10051c9dbfe..cc9d99b0f34 100644
--- a/arch/arm/dts/r8a779g0-u-boot.dtsi
+++ b/arch/arm/dts/r8a779g0-u-boot.dtsi
@@ -147,6 +147,10 @@
bootph-all;
};
+&otp {
+ bootph-all;
+};
+
&pfc {
bootph-all;
};
diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S
index e21b54fdbcb..003d5f83041 100644
--- a/arch/arm/lib/crt0_aarch64_efi.S
+++ b/arch/arm/lib/crt0_aarch64_efi.S
@@ -144,6 +144,7 @@ section_table:
IMAGE_SCN_CNT_INITIALIZED_DATA)
.align 12
+ .globl _start
_start:
stp x29, x30, [sp, #-32]!
mov x29, sp
diff --git a/arch/arm/lib/crt0_arm_efi.S b/arch/arm/lib/crt0_arm_efi.S
index 91b0fe12c51..1e7de5c3343 100644
--- a/arch/arm/lib/crt0_arm_efi.S
+++ b/arch/arm/lib/crt0_arm_efi.S
@@ -143,6 +143,7 @@ section_table:
IMAGE_SCN_CNT_INITIALIZED_DATA)
.align 12
+ .globl _start
_start:
stmfd sp!, {r0-r2, lr}
diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index 2ef936aab75..deae4d32378 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -88,7 +88,29 @@ int dram_init_banksize(void)
return 0;
}
-static void qcom_parse_memory(const void *fdt)
+/**
+ * The generic memory parsing code in U-Boot lacks a few things that we
+ * need on Qualcomm:
+ *
+ * 1. It sets gd->ram_size and gd->ram_base to represent a single memory block
+ * 2. setup_dest_addr() later relocates U-Boot to ram_base + ram_size, the end
+ * of that first memory block.
+ *
+ * This results in all memory beyond U-Boot being unusable in Linux when booting
+ * with EFI.
+ *
+ * Since the ranges in the memory node may be out of order, the only way for us
+ * to correctly determine the relocation address for U-Boot is to parse all
+ * memory regions and find the highest valid address.
+ *
+ * We can't use fdtdec_setup_memory_banksize() since it stores the result in
+ * gd->bd, which is not yet allocated.
+ *
+ * @fdt: FDT blob to parse /memory node from
+ *
+ * Return: 0 on success or -ENODATA if /memory node is missing or incomplete
+ */
+static int qcom_parse_memory(const void *fdt)
{
int offset;
const fdt64_t *memory;
@@ -97,16 +119,12 @@ static void qcom_parse_memory(const void *fdt)
int i, j, banks;
offset = fdt_path_offset(fdt, "/memory");
- if (offset < 0) {
- log_err("No memory node found in device tree!\n");
- return;
- }
+ if (offset < 0)
+ return -ENODATA;
memory = fdt_getprop(fdt, offset, "reg", &memsize);
- if (!memory) {
- log_err("No memory configuration was provided by the previous bootloader!\n");
- return;
- }
+ if (!memory)
+ return -ENODATA;
banks = min(memsize / (2 * sizeof(u64)), (ulong)CONFIG_NR_DRAM_BANKS);
@@ -119,7 +137,6 @@ static void qcom_parse_memory(const void *fdt)
for (i = 0, j = 0; i < banks * 2; i += 2, j++) {
prevbl_ddr_banks[j].start = get_unaligned_be64(&memory[i]);
prevbl_ddr_banks[j].size = get_unaligned_be64(&memory[i + 1]);
- /* SM8650 boards sometimes have empty regions! */
if (!prevbl_ddr_banks[j].size) {
j--;
continue;
@@ -127,13 +144,16 @@ static void qcom_parse_memory(const void *fdt)
ram_end = max(ram_end, prevbl_ddr_banks[j].start + prevbl_ddr_banks[j].size);
}
+ if (!banks || !prevbl_ddr_banks[0].size)
+ return -ENODATA;
+
/* Sort our RAM banks -_- */
qsort(prevbl_ddr_banks, banks, sizeof(prevbl_ddr_banks[0]), ddr_bank_cmp);
gd->ram_base = prevbl_ddr_banks[0].start;
gd->ram_size = ram_end - gd->ram_base;
- debug("ram_base = %#011lx, ram_size = %#011llx, ram_end = %#011llx\n",
- gd->ram_base, gd->ram_size, ram_end);
+
+ return 0;
}
static void show_psci_version(void)
@@ -142,24 +162,56 @@ static void show_psci_version(void)
arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
+ /* Some older SoCs like MSM8916 don't always support PSCI */
+ if ((int)res.a0 == PSCI_RET_NOT_SUPPORTED)
+ return;
+
debug("PSCI: v%ld.%ld\n",
PSCI_VERSION_MAJOR(res.a0),
PSCI_VERSION_MINOR(res.a0));
}
+/**
+ * Most MSM8916 devices in the wild shipped without PSCI support, but the
+ * upstream DTs pretend that PSCI exists. If that situation is detected here,
+ * the /psci node is deleted. This is done very early to ensure the PSCI
+ * firmware driver doesn't bind (which then binds a sysreset driver that won't
+ * work).
+ */
+static void qcom_psci_fixup(void *fdt)
+{
+ int offset, ret;
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
+
+ if ((int)res.a0 != PSCI_RET_NOT_SUPPORTED)
+ return;
+
+ offset = fdt_path_offset(fdt, "/psci");
+ if (offset < 0)
+ return;
+
+ debug("Found /psci DT node on device with no PSCI. Deleting.\n");
+ ret = fdt_del_node(fdt, offset);
+ if (ret)
+ log_err("Failed to delete /psci node: %d\n", ret);
+}
+
/* We support booting U-Boot with an internal DT when running as a first-stage bootloader
* or for supporting quirky devices where it's easier to leave the downstream DT in place
* to improve ABL compatibility. Otherwise, we use the DT provided by ABL.
*/
int board_fdt_blob_setup(void **fdtp)
{
- struct fdt_header *fdt;
+ struct fdt_header *external_fdt, *internal_fdt;
bool internal_valid, external_valid;
- int ret = 0;
+ int ret = -ENODATA;
- fdt = (struct fdt_header *)get_prev_bl_fdt_addr();
- external_valid = fdt && !fdt_check_header(fdt);
- internal_valid = !fdt_check_header(*fdtp);
+ internal_fdt = (struct fdt_header *)*fdtp;
+ external_fdt = (struct fdt_header *)get_prev_bl_fdt_addr();
+ external_valid = external_fdt && !fdt_check_header(external_fdt);
+ internal_valid = !fdt_check_header(internal_fdt);
/*
* There is no point returning an error here, U-Boot can't do anything useful in this situation.
@@ -167,31 +219,42 @@ int board_fdt_blob_setup(void **fdtp)
*/
if (!internal_valid && !external_valid)
panic("Internal FDT is invalid and no external FDT was provided! (fdt=%#llx)\n",
- (phys_addr_t)fdt);
+ (phys_addr_t)external_fdt);
+
+ /* Prefer memory information from internal DT if it's present */
+ if (internal_valid)
+ ret = qcom_parse_memory(internal_fdt);
+
+ if (ret < 0 && external_valid) {
+ /* No internal FDT or it lacks a proper /memory node.
+ * The previous bootloader handed us something, let's try that.
+ */
+ if (internal_valid)
+ debug("No memory info in internal FDT, falling back to external\n");
+
+ ret = qcom_parse_memory(external_fdt);
+ }
+
+ if (ret < 0)
+ panic("No valid memory ranges found!\n");
+
+ debug("ram_base = %#011lx, ram_size = %#011llx\n",
+ gd->ram_base, gd->ram_size);
if (internal_valid) {
debug("Using built in FDT\n");
ret = -EEXIST;
} else {
debug("Using external FDT\n");
- /* So we can use it before returning */
- *fdtp = fdt;
+ *fdtp = external_fdt;
+ ret = 0;
}
- /*
- * Parse the /memory node while we're here,
- * this makes it easy to do other things early.
- */
- qcom_parse_memory(*fdtp);
+ qcom_psci_fixup(*fdtp);
return ret;
}
-void reset_cpu(void)
-{
- psci_system_reset();
-}
-
/*
* Some Qualcomm boards require GPIO configuration when switching USB modes.
* Support setting this configuration via pinctrl state.
diff --git a/arch/riscv/cpu/k1/Kconfig b/arch/riscv/cpu/k1/Kconfig
index d9cd8dce964..14201df80f2 100644
--- a/arch/riscv/cpu/k1/Kconfig
+++ b/arch/riscv/cpu/k1/Kconfig
@@ -13,6 +13,7 @@ config SPACEMIT_K1
imply RISCV_ACLINT if RISCV_MMODE
imply SPL_RISCV_ACLINT if SPL_RISCV_MMODE
imply CMD_CPU
+ imply DM_RESET
imply SPL_CPU
imply SPL_OPENSBI
imply SPL_LOAD_FIT
diff --git a/arch/riscv/dts/binman.dtsi b/arch/riscv/dts/binman.dtsi
index 0405faca574..ceb916b74a7 100644
--- a/arch/riscv/dts/binman.dtsi
+++ b/arch/riscv/dts/binman.dtsi
@@ -82,8 +82,9 @@
};
};
-#ifndef CONFIG_OF_BOARD
+#if !defined(CONFIG_OF_BOARD) || defined(CONFIG_MULTI_DTB_FIT)
@fdt-SEQ {
+ fit,operation = "gen-fdt-nodes";
description = "NAME";
type = "flat_dt";
compression = "none";
@@ -92,9 +93,12 @@
};
configurations {
+
+#ifndef CONFIG_MULTI_DTB_FIT
default = "conf-1";
+#endif
-#ifndef CONFIG_OF_BOARD
+#if !defined(CONFIG_OF_BOARD) || defined(CONFIG_MULTI_DTB_FIT)
@conf-SEQ {
#else
conf-1 {
@@ -115,7 +119,7 @@
#endif
#endif /* CONFIG_OPTEE */
-#ifndef CONFIG_OF_BOARD
+#if !defined(CONFIG_OF_BOARD) || defined(CONFIG_MULTI_DTB_FIT)
fdt = "fdt-SEQ";
#endif
};
diff --git a/arch/riscv/dts/cv18xx.dtsi b/arch/riscv/dts/cv18xx.dtsi
index 8a7386b76e6..6fac247e7ac 100644
--- a/arch/riscv/dts/cv18xx.dtsi
+++ b/arch/riscv/dts/cv18xx.dtsi
@@ -46,20 +46,6 @@
#clock-cells = <0>;
};
- eth_csrclk: eth-csrclk {
- compatible = "fixed-clock";
- clock-frequency = <250000000>;
- clock-output-names = "eth_csrclk";
- #clock-cells = <0x0>;
- };
-
- eth_ptpclk: eth-ptpclk {
- compatible = "fixed-clock";
- clock-frequency = <50000000>;
- clock-output-names = "eth_ptpclk";
- #clock-cells = <0x0>;
- };
-
soc {
compatible = "simple-bus";
interrupt-parent = <&plic>;
diff --git a/arch/riscv/dts/k1.dtsi b/arch/riscv/dts/k1.dtsi
index 514be453dba..7c0f1b928e2 100644
--- a/arch/riscv/dts/k1.dtsi
+++ b/arch/riscv/dts/k1.dtsi
@@ -327,7 +327,7 @@
ranges;
uart0: serial@d4017000 {
- compatible = "spacemit,k1-uart", "snps,dw-apb-uart";
+ compatible = "spacemit,k1-uart", "intel,xscale-uart";
reg = <0x0 0xd4017000 0x0 0x100>;
interrupts = <42>;
clock-frequency = <14857000>;
@@ -337,7 +337,7 @@
};
uart2: serial@d4017100 {
- compatible = "spacemit,k1-uart", "snps,dw-apb-uart";
+ compatible = "spacemit,k1-uart", "intel,xscale-uart";
reg = <0x0 0xd4017100 0x0 0x100>;
interrupts = <44>;
clock-frequency = <14857000>;
@@ -347,7 +347,7 @@
};
uart3: serial@d4017200 {
- compatible = "spacemit,k1-uart", "snps,dw-apb-uart";
+ compatible = "spacemit,k1-uart", "intel,xscale-uart";
reg = <0x0 0xd4017200 0x0 0x100>;
interrupts = <45>;
clock-frequency = <14857000>;
@@ -357,7 +357,7 @@
};
uart4: serial@d4017300 {
- compatible = "spacemit,k1-uart", "snps,dw-apb-uart";
+ compatible = "spacemit,k1-uart", "intel,xscale-uart";
reg = <0x0 0xd4017300 0x0 0x100>;
interrupts = <46>;
clock-frequency = <14857000>;
@@ -367,7 +367,7 @@
};
uart5: serial@d4017400 {
- compatible = "spacemit,k1-uart", "snps,dw-apb-uart";
+ compatible = "spacemit,k1-uart", "intel,xscale-uart";
reg = <0x0 0xd4017400 0x0 0x100>;
interrupts = <47>;
clock-frequency = <14857000>;
@@ -377,7 +377,7 @@
};
uart6: serial@d4017500 {
- compatible = "spacemit,k1-uart", "snps,dw-apb-uart";
+ compatible = "spacemit,k1-uart", "intel,xscale-uart";
reg = <0x0 0xd4017500 0x0 0x100>;
interrupts = <48>;
clock-frequency = <14857000>;
@@ -387,7 +387,7 @@
};
uart7: serial@d4017600 {
- compatible = "spacemit,k1-uart", "snps,dw-apb-uart";
+ compatible = "spacemit,k1-uart", "intel,xscale-uart";
reg = <0x0 0xd4017600 0x0 0x100>;
interrupts = <49>;
clock-frequency = <14857000>;
@@ -397,7 +397,7 @@
};
uart8: serial@d4017700 {
- compatible = "spacemit,k1-uart", "snps,dw-apb-uart";
+ compatible = "spacemit,k1-uart", "intel,xscale-uart";
reg = <0x0 0xd4017700 0x0 0x100>;
interrupts = <50>;
clock-frequency = <14857000>;
@@ -407,7 +407,7 @@
};
uart9: serial@d4017800 {
- compatible = "spacemit,k1-uart", "snps,dw-apb-uart";
+ compatible = "spacemit,k1-uart", "intel,xscale-uart";
reg = <0x0 0xd4017800 0x0 0x100>;
interrupts = <51>;
clock-frequency = <14857000>;
@@ -447,7 +447,7 @@
};
sec_uart1: serial@f0612000 {
- compatible = "spacemit,k1-uart", "snps,dw-apb-uart";
+ compatible = "spacemit,k1-uart", "intel,xscale-uart";
reg = <0x0 0xf0612000 0x0 0x100>;
interrupts = <43>;
clock-frequency = <14857000>;
@@ -455,5 +455,20 @@
reg-io-width = <4>;
status = "reserved"; /* for TEE usage */
};
+
+ reset: reset-controller@d4050000 {
+ compatible = "spacemit,k1-reset";
+ reg = <0x0 0xd4050000 0x0 0x209c>,
+ <0x0 0xd4282800 0x0 0x400>,
+ <0x0 0xd4015000 0x0 0x1000>,
+ <0x0 0xd4090000 0x0 0x1000>,
+ <0x0 0xd4282c00 0x0 0x400>,
+ <0x0 0xd8440000 0x0 0x98>,
+ <0x0 0xc0000000 0x0 0x4280>,
+ <0x0 0xf0610000 0x0 0x20>;
+ reg-names = "mpmu", "apmu", "apbc", "apbs", "ciu", "dciu", "ddrc", "apbc2";
+ #reset-cells = <1>;
+ status = "disabled";
+ };
};
}; \ No newline at end of file
diff --git a/arch/riscv/dts/starfive-visionfive2-binman.dtsi b/arch/riscv/dts/starfive-visionfive2-binman.dtsi
index 4cce001e80d..05787bdb92d 100644
--- a/arch/riscv/dts/starfive-visionfive2-binman.dtsi
+++ b/arch/riscv/dts/starfive-visionfive2-binman.dtsi
@@ -13,82 +13,6 @@
};
&binman {
- itb {
- fit {
- images {
- fdt-jh7110-milkv-mars {
- description = "jh7110-milkv-mars";
- load = <0x40400000>;
- compression = "none";
-
- blob-ext {
- filename = "dts/upstream/src/riscv/starfive/jh7110-milkv-mars.dtb";
- };
- };
-
- fdt-jh7110-pine64-star64 {
- description = "jh7110-pine64-star64";
- load = <0x40400000>;
- compression = "none";
-
- blob-ext {
- filename = "dts/upstream/src/riscv/starfive/jh7110-pine64-star64.dtb";
- };
- };
-
- fdt-jh7110-starfive-visionfive-2-v1.2a {
- description = "jh7110-starfive-visionfive-2-v1.2a";
- load = <0x40400000>;
- compression = "none";
-
- blob-ext {
- filename = "dts/upstream/src/riscv/starfive/jh7110-starfive-visionfive-2-v1.2a.dtb";
- };
- };
-
- fdt-jh7110-starfive-visionfive-2-v1.3b {
- description = "jh7110-starfive-visionfive-2-v1.3b";
- load = <0x40400000>;
- compression = "none";
-
- blob-ext {
- filename = "dts/upstream/src/riscv/starfive/jh7110-starfive-visionfive-2-v1.3b.dtb";
- };
- };
- };
-
- configurations {
- conf-jh7110-milkv-mars {
- description = "jh7110-milkv-mars";
- firmware = "opensbi";
- loadables = "uboot";
- fdt = "fdt-jh7110-milkv-mars";
- };
-
- conf-jh7110-pine64-star64 {
- description = "jh7110-pine64-star64";
- firmware = "opensbi";
- loadables = "uboot";
- fdt = "fdt-jh7110-pine64-star64";
- };
-
- conf-jh7110-starfive-visionfive-2-v1.2a {
- description = "jh7110-starfive-visionfive-2-v1.2a";
- firmware = "opensbi";
- loadables = "uboot";
- fdt = "fdt-jh7110-starfive-visionfive-2-v1.2a";
- };
-
- conf-jh7110-starfive-visionfive-2-v1.3b {
- description = "jh7110-starfive-visionfive-2-v1.3b";
- firmware = "opensbi";
- loadables = "uboot";
- fdt = "fdt-jh7110-starfive-visionfive-2-v1.3b";
- };
- };
- };
- };
-
spl-img {
filename = "spl/u-boot-spl.bin.normal.out";
diff --git a/arch/riscv/lib/crt0_riscv_efi.S b/arch/riscv/lib/crt0_riscv_efi.S
index 9eacbe4a859..f170e4b26d6 100644
--- a/arch/riscv/lib/crt0_riscv_efi.S
+++ b/arch/riscv/lib/crt0_riscv_efi.S
@@ -179,6 +179,7 @@ section_table:
IMAGE_SCN_CNT_INITIALIZED_DATA)
.align 12
+ .globl _start
_start:
addi sp, sp, -(SIZE_LONG * 3)
SAVE_LONG(a0, 0)
diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig
index 012ac14a123..134dbfd7151 100644
--- a/board/emulation/qemu-riscv/Kconfig
+++ b/board/emulation/qemu-riscv/Kconfig
@@ -62,6 +62,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
imply VIDEO_SIMPLE
imply PCIE_ECAM_GENERIC
imply DM_RNG
+ imply RNG_RISCV_ZKR
imply DM_RTC
imply RTC_GOLDFISH
imply SCSI
diff --git a/board/renesas/common/Makefile b/board/renesas/common/Makefile
index 347be5cc93c..5e51b691178 100644
--- a/board/renesas/common/Makefile
+++ b/board/renesas/common/Makefile
@@ -1,6 +1,4 @@
#
-# board/renesas/whitehawk/Makefile
-#
# Copyright (C) 2024 Marek Vasut <marek.vasut+renesas@mailbox.org>
#
# SPDX-License-Identifier: GPL-2.0+
diff --git a/board/renesas/common/gen4-common.c b/board/renesas/common/gen4-common.c
index 52a0639073b..f7d129be4c8 100644
--- a/board/renesas/common/gen4-common.c
+++ b/board/renesas/common/gen4-common.c
@@ -7,11 +7,13 @@
#include <asm/arch/renesas.h>
#include <asm/arch/sys_proto.h>
+#include <asm/armv8/mmu.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/processor.h>
#include <asm/system.h>
+#include <image.h>
#include <linux/errno.h>
#define RST_BASE 0xE6160000 /* Domain0 */
@@ -88,3 +90,127 @@ int ft_board_setup(void *blob, struct bd_info *bd)
{
return 0;
}
+
+/* R-Car Gen4 TFA BL31 handoff structure and handling. */
+struct param_header {
+ u8 type;
+ u8 version;
+ u16 size;
+ u32 attr;
+};
+
+struct tfa_image_info {
+ struct param_header h;
+ uintptr_t image_base;
+ u32 image_size;
+ u32 image_max_size;
+};
+
+struct aapcs64_params {
+ u64 arg0;
+ u64 arg1;
+ u64 arg2;
+ u64 arg3;
+ u64 arg4;
+ u64 arg5;
+ u64 arg6;
+ u64 arg7;
+};
+
+struct entry_point_info {
+ struct param_header h;
+ uintptr_t pc;
+ u32 spsr;
+ struct aapcs64_params args;
+};
+
+struct bl2_to_bl31_params_mem {
+ struct tfa_image_info bl32_image_info;
+ struct tfa_image_info bl33_image_info;
+ struct entry_point_info bl33_ep_info;
+ struct entry_point_info bl32_ep_info;
+};
+
+/* Default jump address, return to U-Boot */
+#define BL33_BASE 0x44100000
+/* Custom parameters address passed to TFA by ICUMXA loader */
+#define PARAMS_BASE 0x46422200
+
+/* Usually such a structure is produced by ICUMXA and passed in at 0x46422200 */
+static const struct bl2_to_bl31_params_mem blinfo_template = {
+ .bl33_ep_info.h.type = 1, /* PARAM_EP */
+ .bl33_ep_info.h.version = 2, /* Version 2 */
+ .bl33_ep_info.h.size = sizeof(struct entry_point_info),
+ .bl33_ep_info.h.attr = 0x81, /* Executable | Non-Secure */
+ .bl33_ep_info.spsr = 0x2c9, /* Mode=EL2, SP=ELX, Exceptions=OFF */
+ .bl33_ep_info.pc = BL33_BASE,
+
+ .bl33_image_info.h.type = 1, /* PARAM_EP */
+ .bl33_image_info.h.version = 2, /* Version 2 */
+ .bl33_image_info.h.size = sizeof(struct image_info),
+ .bl33_image_info.h.attr = 0,
+ .bl33_image_info.image_base = BL33_BASE,
+};
+
+static bool tfa_bl31_image_loaded;
+static ulong tfa_bl31_image_addr;
+
+static void tfa_bl31_image_process(ulong image, size_t size)
+{
+ /* Custom parameters address passed to TFA by ICUMXA loader */
+ struct bl2_to_bl31_params_mem *blinfo = (struct bl2_to_bl31_params_mem *)PARAMS_BASE;
+
+ /* Not in EL3, do nothing. */
+ if (current_el() != 3)
+ return;
+
+ /* Clear a page and copy template */
+ memset((void *)PARAMS_BASE, 0, PAGE_SIZE);
+ memcpy(blinfo, &blinfo_template, sizeof(*blinfo));
+ tfa_bl31_image_addr = image;
+ tfa_bl31_image_loaded = true;
+}
+
+U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_TFA_BL31, tfa_bl31_image_process);
+
+void armv8_switch_to_el2_prep(u64 args, u64 mach_nr, u64 fdt_addr,
+ u64 arg4, u64 entry_point, u64 es_flag)
+{
+ typedef void __noreturn (*image_entry_noargs_t)(void);
+ image_entry_noargs_t image_entry =
+ (image_entry_noargs_t)(void *)tfa_bl31_image_addr;
+ struct bl2_to_bl31_params_mem *blinfo =
+ (struct bl2_to_bl31_params_mem *)PARAMS_BASE;
+
+ /* Not in EL3, do nothing. */
+ if (current_el() != 3)
+ return;
+
+ /*
+ * Destination address in arch/arm/cpu/armv8/transition.S
+ * right past the first bl in armv8_switch_to_el2() to let
+ * the rest of U-Boot pre-Linux code run. The code does run
+ * without stack pointer!
+ */
+ const u64 ep = ((u64)(uintptr_t)&armv8_switch_to_el2) + 4;
+
+ /* If TFA BL31 was not part of the fitImage, do regular boot. */
+ if (!tfa_bl31_image_loaded)
+ return;
+
+ /*
+ * Set up kernel entry point and parameters:
+ * x0 is FDT address, x1..x3 must be 0
+ */
+ blinfo->bl33_ep_info.pc = ep;
+ blinfo->bl33_ep_info.args.arg0 = args;
+ blinfo->bl33_ep_info.args.arg1 = mach_nr;
+ blinfo->bl33_ep_info.args.arg2 = fdt_addr;
+ blinfo->bl33_ep_info.args.arg3 = arg4;
+ blinfo->bl33_ep_info.args.arg4 = entry_point;
+ blinfo->bl33_ep_info.args.arg5 = es_flag;
+ blinfo->bl33_image_info.image_base = ep;
+
+ /* Jump to TFA BL31 */
+ image_entry();
+}
diff --git a/board/renesas/common/gen4-spl.c b/board/renesas/common/gen4-spl.c
index e46ef0a3075..ebfefab7253 100644
--- a/board/renesas/common/gen4-spl.c
+++ b/board/renesas/common/gen4-spl.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * R-Car Gen4 Cortex-R52 SPL
+ * R-Car Gen4 SPL
*
* Copyright (C) 2024 Marek Vasut <marek.vasut+renesas@mailbox.org>
*/
diff --git a/board/starfive/visionfive2/spl.c b/board/starfive/visionfive2/spl.c
index 1538d6aec73..13a48939c8f 100644
--- a/board/starfive/visionfive2/spl.c
+++ b/board/starfive/visionfive2/spl.c
@@ -121,6 +121,10 @@ int board_fit_config_name_match(const char *name)
product_id = get_product_id_from_eeprom();
+ /* Strip off prefix */
+ if (strncmp(name, "starfive/", 9))
+ return -EINVAL;
+ name += 9;
if (!strncmp(product_id, "VF7110", 6)) {
version = get_pcb_revision_from_eeprom();
if ((version == 'b' || version == 'B') &&
diff --git a/board/toradex/verdin-am62/verdin-am62.c b/board/toradex/verdin-am62/verdin-am62.c
index a1c471111a0..7b2eecbf659 100644
--- a/board/toradex/verdin-am62/verdin-am62.c
+++ b/board/toradex/verdin-am62/verdin-am62.c
@@ -112,13 +112,6 @@ int board_late_init(void)
#define CORE_VOLTAGE 0x80000000
#define MCU_CTRL_LFXOSC_32K_BYPASS_VAL BIT(4)
-#if IS_ENABLED(CONFIG_XPL_BUILD)
-void spl_perform_fixups(struct spl_image_info *spl_image)
-{
- fixup_memory_node(spl_image);
-}
-#endif
-
#ifdef CONFIG_SPL_BOARD_INIT
void spl_board_init(void)
{
diff --git a/cmd/version.c b/cmd/version.c
index 53db1a0b6bd..62406608eb0 100644
--- a/cmd/version.c
+++ b/cmd/version.c
@@ -6,6 +6,7 @@
#include <command.h>
#include <display_options.h>
+#include <version.h>
#include <version_string.h>
#include <linux/compiler.h>
#ifdef CONFIG_SYS_COREBOOT
diff --git a/configs/bananapi-f3_defconfig b/configs/bananapi-f3_defconfig
index 0f12db3db84..7483f128bae 100644
--- a/configs/bananapi-f3_defconfig
+++ b/configs/bananapi-f3_defconfig
@@ -18,3 +18,4 @@ CONFIG_HUSH_PARSER=y
CONFIG_ENV_OVERWRITE=y
CONFIG_SYS_NS16550=y
CONFIG_SYS_NS16550_MEM32=y
+CONFIG_RESET_SPACEMIT_K1=y
diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig
index 661a484f7bf..ba4d38d100e 100644
--- a/configs/qcom_defconfig
+++ b/configs/qcom_defconfig
@@ -97,6 +97,7 @@ CONFIG_PINCTRL_QCOM_APQ8016=y
CONFIG_PINCTRL_QCOM_APQ8096=y
CONFIG_PINCTRL_QCOM_QCM2290=y
CONFIG_PINCTRL_QCOM_QCS404=y
+CONFIG_PINCTRL_QCOM_SC7280=y
CONFIG_PINCTRL_QCOM_SDM845=y
CONFIG_PINCTRL_QCOM_SM6115=y
CONFIG_PINCTRL_QCOM_SM8150=y
@@ -120,6 +121,7 @@ CONFIG_QCOM_RPMH=y
CONFIG_SPMI_MSM=y
CONFIG_SYSINFO=y
CONFIG_SYSINFO_SMBIOS=y
+CONFIG_SYSRESET_QCOM_PSHOLD=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
diff --git a/configs/qcom_ipq9574_mmc_defconfig b/configs/qcom_ipq9574_mmc_defconfig
new file mode 100644
index 00000000000..9bc1e1c70b7
--- /dev/null
+++ b/configs/qcom_ipq9574_mmc_defconfig
@@ -0,0 +1,83 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_SYS_INIT_SP_BSS_OFFSET=1572864
+CONFIG_ARCH_SNAPDRAGON=y
+CONFIG_NR_DRAM_BANKS=24
+CONFIG_DEFAULT_DEVICE_TREE="qcom/ipq9574-rdp433"
+CONFIG_SYS_LOAD_ADDR=0x50000000
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+# CONFIG_EFI_LOADER is not set
+# CONFIG_EFI_BINARY_EXEC is not set
+# CONFIG_EFI_VARIABLE_FILE_STORE is not set
+# CONFIG_PXE_UTILS is not set
+# CONFIG_BOOTSTD is not set
+# CONFIG_BOOTMETH_VBE is not set
+CONFIG_BOOTDELAY=2
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_USE_PREBOOT=y
+CONFIG_SYS_CBSIZE=512
+CONFIG_LOG_MAX_LEVEL=9
+CONFIG_LOG_DEFAULT_LEVEL=4
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_PART=y
+CONFIG_OF_LIVE=y
+CONFIG_USE_DEFAULT_ENV_FILE=y
+CONFIG_DEFAULT_ENV_FILE="board/qualcomm/default.env"
+CONFIG_CLK=y
+CONFIG_CLK_QCOM_IPQ9574=y
+CONFIG_DFU_MMC=y
+CONFIG_DFU_SCSI=y
+CONFIG_SYS_DFU_DATA_BUF_SIZE=0x200000
+CONFIG_MSM_GPIO=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_QCOM_IPQ9574=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ADMA=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_ETH_PHY=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_QCOM=y
+CONFIG_RGMII=y
+CONFIG_PHY=y
+CONFIG_PHY_QCOM_QMP_UFS=y
+CONFIG_PHY_QCOM_QUSB2=y
+CONFIG_SCSI=y
+CONFIG_MSM_SERIAL=y
+CONFIG_MSM_GENI_SERIAL=y
+CONFIG_SOC_QCOM=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_BASE=0x78b1000
+CONFIG_DEBUG_UART_MSM=y
+CONFIG_DEBUG_UART_CLOCK=1843200
+CONFIG_TEXT_BASE=0x4A240000
+CONFIG_REMAKE_ELF=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_BOOTSTD_FULL=y
+CONFIG_SYS_CBSIZE=1024
+CONFIG_SYS_PBSIZE=1024
+CONFIG_OF_LIVE=y
+CONFIG_MSM_SERIAL=y
+CONFIG_DM_EVENT=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_SIZE=0x40000
+CONFIG_ENV_OFFSET=0
+CONFIG_PARTITIONS=y
+CONFIG_PARTITION_UUIDS=y
+CONFIG_MTD=y
+CONFIG_MTD_PARTS=y
+CONFIG_HUSH_PARSER=y
+CONFIG_PARTITIONS=y
+CONFIG_EFI_PARTITION=y
+# CONFIG_I2C is not set
+# CONFIG_INPUT is not set
+# CONFIG_SCSI is not set
+# CONFIG_SPMI is not set
diff --git a/configs/r8a779g0_whitehawk_defconfig b/configs/r8a779g0_whitehawk_defconfig
index b49a81dcd49..8dcf8e35ee0 100644
--- a/configs/r8a779g0_whitehawk_defconfig
+++ b/configs/r8a779g0_whitehawk_defconfig
@@ -3,6 +3,8 @@
CONFIG_ARM=y
CONFIG_ARCH_RENESAS=y
CONFIG_RCAR_GEN4=y
+CONFIG_ARM_SMCCC=y
+CONFIG_ARMV8_PSCI=y
CONFIG_ENV_SIZE=0x20000
CONFIG_ENV_OFFSET=0xFFFE0000
CONFIG_DEFAULT_DEVICE_TREE="renesas/r8a779g0-white-hawk"
diff --git a/configs/renesas_rzg2l_smarc_defconfig b/configs/renesas_rzg2l_smarc_defconfig
index 7a1224b3f07..b1d970b6b7e 100644
--- a/configs/renesas_rzg2l_smarc_defconfig
+++ b/configs/renesas_rzg2l_smarc_defconfig
@@ -26,6 +26,7 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_PART=y
+CONFIG_CMD_USB=y
CONFIG_CMD_PMIC=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_EXT4=y
@@ -54,5 +55,12 @@ CONFIG_PMIC_RAA215300=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_RESET_RZG2L_USBPHY_CTRL=y
CONFIG_SYSRESET=y
CONFIG_SYSRESET_RAA215300=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_GENERIC=y
+CONFIG_USB_STORAGE=y
diff --git a/configs/sifive_unmatched_defconfig b/configs/sifive_unmatched_defconfig
index 88a75c03259..f70e3db4441 100644
--- a/configs/sifive_unmatched_defconfig
+++ b/configs/sifive_unmatched_defconfig
@@ -27,7 +27,7 @@ CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x84000000
CONFIG_BOOTSTD_DEFAULTS=y
CONFIG_USE_PREBOOT=y
-CONFIG_PREBOOT="setenv fdt_addr ${fdtcontroladdr};fdt addr ${fdtcontroladdr};"
+CONFIG_PREBOOT="setenv fdt_addr ${fdtcontroladdr};fdt addr ${fdtcontroladdr};nvme scan"
CONFIG_DEFAULT_FDT_FILE="sifive/hifive-unmatched-a00.dtb"
CONFIG_SYS_CBSIZE=256
CONFIG_SYS_PBSIZE=276
diff --git a/doc/README.bitbangMII b/doc/README.bitbangMII
deleted file mode 100644
index 05ab20376f3..00000000000
--- a/doc/README.bitbangMII
+++ /dev/null
@@ -1,39 +0,0 @@
-This patch rewrites the miiphybb ( Bit-banged MII bus driver ) in order to
-support an arbitrary number of mii buses. This feature is useful when your
-board uses different mii buses for different phys and all (or a part) of these
-buses are implemented via bit-banging mode.
-
-The driver requires that the following macros should be defined into the board
-configuration file:
-
-CONFIG_BITBANGMII - Enable the miiphybb driver
-
-The board code needs to fill the bb_miiphy_buses[] array with a record for
-each required bus and declare the bb_miiphy_buses_num variable with the
-number of mii buses. The record (struct bb_miiphy_bus) has the following
-fields/callbacks (see miiphy.h for details):
-
-char name[] - The symbolic name that must be equal to the MII bus
- registered name
-int (*init)() - Initialization function called at startup time (just
- before the Ethernet initialization)
-int (*mdio_active)() - Activate the MDIO pin as output
-int (*mdio_tristate)() - Activate the MDIO pin as input/tristate pin
-int (*set_mdio)() - Write the MDIO pin
-int (*get_mdio)() - Read the MDIO pin
-int (*set_mdc)() - Write the MDC pin
-int (*delay)() - Delay function
-void *priv - Private data used by board specific code
-
-The board code will look like:
-
-struct bb_miiphy_bus bb_miiphy_buses[] = {
- { .name = "miibus#1", .init = b1_init, .mdio_active = b1_mdio_active, ... },
- { .name = "miibus#2", .init = b2_init, .mdio_active = b2_mdio_active, ... },
- ...
-};
-int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
- sizeof(bb_miiphy_buses[0]);
-
-2009 Industrie Dial Face S.p.A.
- Luigi 'Comio' Mantellini <luigi.mantellini@idf-hit.com>
diff --git a/doc/board/qualcomm/index.rst b/doc/board/qualcomm/index.rst
index 8c7969987a9..66bc922033a 100644
--- a/doc/board/qualcomm/index.rst
+++ b/doc/board/qualcomm/index.rst
@@ -10,3 +10,4 @@ Qualcomm
rb3gen2
board
debugging
+ rdp
diff --git a/doc/board/qualcomm/rdp.rst b/doc/board/qualcomm/rdp.rst
new file mode 100644
index 00000000000..fd14f1d9829
--- /dev/null
+++ b/doc/board/qualcomm/rdp.rst
@@ -0,0 +1,55 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. sectionauthor:: Varadarajan Narayanan <quic_varada@quicinc.com>
+
+Qualcomm Reference Design Platform (RDP)
+========================================
+
+Qualcomm RDPs are development boards based on the Qualcomm IPQ series of
+SoCs. These SoCs are used as the application processors in WiFi router
+platforms. RDPs come in multiple variants with differences in storage
+medium (NOR, NAND, MMC), no. of USB and PCIe ports, n/w ports etc.
+
+.. _Qualcomm's product page: https://www.qualcomm.com/products/internet-of-things/networking/wi-fi-networks/networking-pro-series/qualcomm-networking-pro-820-platform
+
+Installation
+------------
+First, setup ``CROSS_COMPILE`` for aarch64. Then, build U-Boot for ``IPQ9574``::
+
+ $ export CROSS_COMPILE=<aarch64 toolchain prefix>
+ $ make qcom_ipq9574_mmc_defconfig
+ $ make -j8
+
+This will build ``u-boot.elf`` in the configured output directory.
+
+Although the RDPs do not have secure boot set up by default, the firmware still
+expects firmware ELF images to be "signed". The signature does not provide any
+security in this case, but it provides the firmware with some required metadata.
+
+To "sign" ``u-boot.elf`` you can use e.g. `qtestsign`_::
+
+ $ qtestsign -v6 aboot -o u-boot.mbn u-boot.elf
+
+Then install the resulting ``u-boot.mbn`` to the ``0:APPSBL`` partition
+on your device with::
+
+ IPQ9574# tftpboot path/to/u-boot.mbn
+ IPQ9574# mmc part (note down the start & end block no.s of '0:APPSBL' partition)
+ IPQ9574# mmc erase <start blk no> <count>
+ IPQ9574# mmc write $fileaddr <blk no> <count>
+
+U-Boot should be running after a reboot (``reset``).
+
+.. WARNING
+ Boards with newer software versions would automatically go the emergency
+ download (EDL) mode if U-Boot is not functioning as expected. If its a
+ runtime failure at Uboot, the system will get reset (due to watchdog)
+ and XBL will try to boot from next bank and if Bank B also doesn't have
+ a functional image and is not booting fine, then the system will enter
+ EDL. A tool like bkerler's `edl`_ can be used for flashing with the
+ firehose loader binary appropriate for the board.
+
+ Note that the support added is very basic. Restoring the original U-Boot
+ on boards with older version of the software requires a debugger.
+
+.. _qtestsign: https://github.com/msm8916-mainline/qtestsign
+.. _edl: https://github.com/bkerler/edl
diff --git a/doc/develop/bitbangmii.rst b/doc/develop/bitbangmii.rst
new file mode 100644
index 00000000000..35a4a0cb7f9
--- /dev/null
+++ b/doc/develop/bitbangmii.rst
@@ -0,0 +1,75 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+.. Luigi 'Comio' Mantellini <luigi.mantellini@idf-hit.com>, Industrie Dial Face S.p.A., 2009
+
+Bit-banged MII bus support
+==========================
+
+The miiphybb ( Bit-banged MII bus driver ) supports an arbitrary number of
+MII buses. This feature is useful when a driver uses different MII buses for
+different PHYs and all (or a part) of these buses are implemented via
+bit-banging mode.
+
+The driver requires that the following macro is defined in the board
+configuration file:
+
+* CONFIG_BITBANGMII - Enable the miiphybb driver
+
+The driver code needs to allocate a regular MDIO device using mdio_alloc()
+and assign .read and .write accessors which wrap bb_miiphy_read() and
+bb_miiphy_write() functions respectively. The bb_miiphy_read() and
+bb_miiphy_write() functions take a pointer to a callback structure,
+struct bb_miiphy_bus_ops. The struct bb_miiphy_bus_ops has the following
+fields/callbacks (see miiphy.h for details):
+
+.. code-block:: c
+
+ int (*mdio_active)() // Activate the MDIO pin as output
+ int (*mdio_tristate)() // Activate the MDIO pin as input/tristate pin
+ int (*set_mdio)() // Write the MDIO pin
+ int (*get_mdio)() // Read the MDIO pin
+ int (*set_mdc)() // Write the MDC pin
+ int (*delay)() // Delay function
+
+The driver code will look like:
+
+.. code-block:: c
+
+ static const struct bb_miiphy_bus_ops ravb_bb_miiphy_bus_ops = {
+ .mdio_active = ravb_bb_mdio_active,
+ .mdio_tristate = ravb_bb_mdio_tristate,
+ .set_mdio = ravb_bb_set_mdio,
+ .get_mdio = ravb_bb_get_mdio,
+ .set_mdc = ravb_bb_set_mdc,
+ .delay = ravb_bb_delay,
+ };
+
+ static int ravb_bb_miiphy_read(struct mii_dev *miidev, int addr,
+ int devad, int reg)
+ {
+ return bb_miiphy_read(miidev, &ravb_bb_miiphy_bus_ops,
+ addr, devad, reg);
+ }
+
+ static int ravb_bb_miiphy_write(struct mii_dev *miidev, int addr,
+ int devad, int reg, u16 value)
+ {
+ return bb_miiphy_write(miidev, &ravb_bb_miiphy_bus_ops,
+ addr, devad, reg, value);
+ }
+
+ static int ravb_probe(struct udevice *dev)
+ {
+ struct mii_dev *mdiodev;
+ ...
+ mdiodev = mdio_alloc();
+ if (!mdiodev)
+ return -ENOMEM;
+
+ mdiodev->read = ravb_bb_miiphy_read;
+ mdiodev->write = ravb_bb_miiphy_write;
+ mdiodev->priv = eth;
+ snprintf(mdiodev->name, sizeof(mdiodev->name), dev->name);
+
+ ret = mdio_register(mdiodev);
+ ...
+ }
diff --git a/doc/develop/index.rst b/doc/develop/index.rst
index d9f2a838207..c907f8c9c2c 100644
--- a/doc/develop/index.rst
+++ b/doc/develop/index.rst
@@ -9,6 +9,7 @@ General
.. toctree::
:maxdepth: 1
+ bitbangmii
board_best_practices
codingstyle
designprinciples
diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst
index dc5bb340ff2..e736dc0616e 100644
--- a/doc/develop/release_cycle.rst
+++ b/doc/develop/release_cycle.rst
@@ -76,7 +76,7 @@ For the next scheduled release, release candidates were made on::
* U-Boot v2025.04-rc4 was released on Mon 10 March 2025.
-.. * U-Boot v2025.04-rc5 was released on Mon 24 March 2025.
+* U-Boot v2025.04-rc5 was released on Mon 24 March 2025.
Please note that the following dates are planned only and may be deviated from
as needed.
diff --git a/drivers/clk/clk-stub.c b/drivers/clk/clk-stub.c
index 5fbbb07b7f7..343fa5cd3fe 100644
--- a/drivers/clk/clk-stub.c
+++ b/drivers/clk/clk-stub.c
@@ -50,6 +50,7 @@ static struct clk_ops stub_clk_ops = {
static const struct udevice_id stub_clk_ids[] = {
{ .compatible = "qcom,rpmcc" },
+ { .compatible = "qcom,sc7280-rpmh-clk" },
{ .compatible = "qcom,sm8150-rpmh-clk" },
{ .compatible = "qcom,sm8250-rpmh-clk" },
{ .compatible = "qcom,sm8550-rpmh-clk" },
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index cb867acc48c..3ea01f3c969 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -31,6 +31,14 @@ config CLK_QCOM_IPQ4019
on the Snapdragon IPQ4019 SoC. This driver supports the clocks
and resets exposed by the GCC hardware block.
+config CLK_QCOM_IPQ9574
+ bool "Qualcomm IPQ9574 GCC"
+ select CLK_QCOM
+ help
+ Say Y here to enable support for the Global Clock Controller
+ on the Snapdragon IPQ9574 SoC. This driver supports the clocks
+ and resets exposed by the GCC hardware block.
+
config CLK_QCOM_QCM2290
bool "Qualcomm QCM2290 GCC"
select CLK_QCOM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 1bc0f15005b..e13fc8c1071 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_CLK_QCOM_SDM845) += clock-sdm845.o
obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o
obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o
obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipq4019.o
+obj-$(CONFIG_CLK_QCOM_IPQ9574) += clock-ipq9574.o
obj-$(CONFIG_CLK_QCOM_QCM2290) += clock-qcm2290.o
obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o
obj-$(CONFIG_CLK_QCOM_SA8775P) += clock-sa8775p.o
diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c
index b5def55dbc2..6a53f900a9e 100644
--- a/drivers/clk/qcom/clock-apq8016.c
+++ b/drivers/clk/qcom/clock-apq8016.c
@@ -54,8 +54,9 @@ static struct vote_clk gcc_blsp1_ahb_clk = {
};
static const struct gate_clk apq8016_clks[] = {
- GATE_CLK(GCC_USB_HS_AHB_CLK, 0x41008, 0x00000001),
- GATE_CLK(GCC_USB_HS_SYSTEM_CLK, 0x41004, 0x00000001),
+ GATE_CLK(GCC_PRNG_AHB_CLK, 0x45004, BIT(8)),
+ GATE_CLK(GCC_USB_HS_AHB_CLK, 0x41008, BIT(0)),
+ GATE_CLK(GCC_USB_HS_SYSTEM_CLK, 0x41004, BIT(0)),
};
/* SDHCI */
@@ -139,15 +140,14 @@ static int apq8016_clk_enable(struct clk *clk)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
- if (priv->data->num_clks < clk->id) {
+ if (priv->data->num_clks < clk->id || !apq8016_clks[clk->id].reg) {
log_warning("%s: unknown clk id %lu\n", __func__, clk->id);
return 0;
}
- debug("%s: clk %s\n", __func__, apq8016_clks[clk->id].name);
- qcom_gate_clk_en(priv, clk->id);
+ debug("%s: enabling clock %s\n", __func__, apq8016_clks[clk->id].name);
- return 0;
+ return qcom_gate_clk_en(priv, clk->id);
}
static struct msm_clk_data apq8016_clk_data = {
diff --git a/drivers/clk/qcom/clock-ipq9574.c b/drivers/clk/qcom/clock-ipq9574.c
new file mode 100644
index 00000000000..b0af4036059
--- /dev/null
+++ b/drivers/clk/qcom/clock-ipq9574.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock drivers for Qualcomm ipq9574
+ *
+ * (C) Copyright 2025 Linaro Ltd.
+ */
+
+#include <linux/types.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <linux/bug.h>
+#include <linux/bitops.h>
+#include <dt-bindings/clock/qcom,ipq9574-gcc.h>
+#include <dt-bindings/reset/qcom,ipq9574-gcc.h>
+
+#include "clock-qcom.h"
+
+#define GCC_BLSP1_AHB_CBCR 0x1004
+#define GCC_BLSP1_UART3_APPS_CMD_RCGR 0x402C
+#define GCC_BLSP1_UART3_APPS_CBCR 0x4054
+
+#define GCC_SDCC1_APPS_CBCR 0x3302C
+#define GCC_SDCC1_AHB_CBCR 0x33034
+#define GCC_SDCC1_APPS_CMD_RCGR 0x33004
+#define GCC_SDCC1_ICE_CORE_CBCR 0x33030
+
+static ulong ipq9574_set_rate(struct clk *clk, ulong rate)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ switch (clk->id) {
+ case GCC_BLSP1_UART3_APPS_CLK:
+ clk_rcg_set_rate_mnd(priv->base, GCC_BLSP1_UART3_APPS_CMD_RCGR,
+ 0, 144, 15625, CFG_CLK_SRC_GPLL0, 16);
+ return rate;
+ case GCC_SDCC1_APPS_CLK:
+ clk_rcg_set_rate_mnd(priv->base, GCC_SDCC1_APPS_CMD_RCGR,
+ 11, 0, 0, CFG_CLK_SRC_GPLL2, 16);
+ return rate;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct gate_clk ipq9574_clks[] = {
+ GATE_CLK(GCC_BLSP1_UART3_APPS_CLK, 0x4054, 0x00000001),
+ GATE_CLK(GCC_BLSP1_AHB_CLK, 0x1004, 0x00000001),
+ GATE_CLK(GCC_SDCC1_AHB_CLK, 0x33034, 0x00000001),
+ GATE_CLK(GCC_SDCC1_APPS_CLK, 0x3302C, 0x00000001),
+ GATE_CLK(GCC_SDCC1_ICE_CORE_CLK, 0x33030, 0x00000001),
+};
+
+static int ipq9574_enable(struct clk *clk)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ debug("%s: clk %s\n", __func__, ipq9574_clks[clk->id].name);
+
+ if (!ipq9574_clks[clk->id].reg)
+ return -EINVAL;
+
+ qcom_gate_clk_en(priv, clk->id);
+
+ return 0;
+}
+
+static const struct qcom_reset_map ipq9574_gcc_resets[] = {
+ [GCC_SDCC_BCR] = { 0x33000 },
+};
+
+static struct msm_clk_data ipq9574_gcc_data = {
+ .resets = ipq9574_gcc_resets,
+ .num_resets = ARRAY_SIZE(ipq9574_gcc_resets),
+ .enable = ipq9574_enable,
+ .set_rate = ipq9574_set_rate,
+};
+
+static const struct udevice_id gcc_ipq9574_of_match[] = {
+ {
+ .compatible = "qcom,ipq9574-gcc",
+ .data = (ulong)&ipq9574_gcc_data,
+ },
+ { }
+};
+
+U_BOOT_DRIVER(gcc_ipq9574) = {
+ .name = "gcc_ipq9574",
+ .id = UCLASS_NOP,
+ .of_match = gcc_ipq9574_of_match,
+ .bind = qcom_cc_bind,
+ .flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
+};
diff --git a/drivers/clk/qcom/clock-qcm2290.c b/drivers/clk/qcom/clock-qcm2290.c
index c78705cb8cf..1326b770c3e 100644
--- a/drivers/clk/qcom/clock-qcm2290.c
+++ b/drivers/clk/qcom/clock-qcm2290.c
@@ -134,9 +134,7 @@ static int qcm2290_enable(struct clk *clk)
break;
}
- qcom_gate_clk_en(priv, clk->id);
-
- return 0;
+ return qcom_gate_clk_en(priv, clk->id);
}
static const struct qcom_reset_map qcm2290_gcc_resets[] = {
diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
index ff336dea39c..f43edea2525 100644
--- a/drivers/clk/qcom/clock-qcom.h
+++ b/drivers/clk/qcom/clock-qcom.h
@@ -7,10 +7,12 @@
#include <asm/io.h>
#include <linux/bitfield.h>
+#include <errno.h>
#define CFG_CLK_SRC_CXO (0 << 8)
#define CFG_CLK_SRC_GPLL0 (1 << 8)
#define CFG_CLK_SRC_GPLL0_AUX2 (2 << 8)
+#define CFG_CLK_SRC_GPLL2 (2 << 8)
#define CFG_CLK_SRC_GPLL9 (2 << 8)
#define CFG_CLK_SRC_GPLL0_ODD (3 << 8)
#define CFG_CLK_SRC_GPLL6 (4 << 8)
@@ -105,14 +107,19 @@ void clk_rcg_set_rate(phys_addr_t base, uint32_t cmd_rcgr, int div,
int source);
void clk_phy_mux_enable(phys_addr_t base, uint32_t cmd_rcgr, bool enabled);
-static inline void qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id)
+static inline int qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id)
{
u32 val;
- if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0)
- return;
+ if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0) {
+ log_err("gcc@%#08llx: unknown clock ID %lu!\n",
+ priv->base, id);
+ return -ENOENT;
+ }
val = readl(priv->base + priv->data->clks[id].reg);
writel(val | priv->data->clks[id].en_val, priv->base + priv->data->clks[id].reg);
+
+ return 0;
}
#endif
diff --git a/drivers/clk/qcom/clock-sa8775p.c b/drivers/clk/qcom/clock-sa8775p.c
index e31f24ed4f0..527cecf5c82 100644
--- a/drivers/clk/qcom/clock-sa8775p.c
+++ b/drivers/clk/qcom/clock-sa8775p.c
@@ -73,9 +73,7 @@ static int sa8775p_enable(struct clk *clk)
break;
}
- qcom_gate_clk_en(priv, clk->id);
-
- return 0;
+ return qcom_gate_clk_en(priv, clk->id);
}
static const struct qcom_reset_map sa8775p_gcc_resets[] = {
diff --git a/drivers/clk/qcom/clock-sc7280.c b/drivers/clk/qcom/clock-sc7280.c
index 5d343f12051..8691f08109b 100644
--- a/drivers/clk/qcom/clock-sc7280.c
+++ b/drivers/clk/qcom/clock-sc7280.c
@@ -16,29 +16,64 @@
#include "clock-qcom.h"
-#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf038
#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf020
+#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf038
+#define USB30_SEC_MASTER_CLK_CMD_RCGR 0x9e020
+#define USB30_SEC_MOCK_UTMI_CLK_CMD_RCGR 0x9e038
+#define PCIE_1_AUX_CLK_CMD_RCGR 0x8d058
+#define PCIE1_PHY_RCHNG_CMD_RCGR 0x8d03c
+#define PCIE_1_PIPE_CLK_PHY_MUX 0x8d054
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
+ F(66666667, CFG_CLK_SRC_GPLL0_EVEN, 4.5, 0, 0),
+ F(133333333, CFG_CLK_SRC_GPLL0, 4.5, 0, 0),
+ F(200000000, CFG_CLK_SRC_GPLL0_ODD, 1, 0, 0),
+ F(240000000, CFG_CLK_SRC_GPLL0, 2.5, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_sec_master_clk_src[] = {
+ F(60000000, CFG_CLK_SRC_GPLL0_EVEN, 5, 0, 0),
+ F(120000000, CFG_CLK_SRC_GPLL0_EVEN, 2.5, 0, 0),
+ { }
+};
static ulong sc7280_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct freq_tbl *freq;
if (clk->id < priv->data->num_clks)
debug("%s: %s, requested rate=%ld\n", __func__, priv->data->clks[clk->id].name, rate);
switch (clk->id) {
- case GCC_USB30_PRIM_MOCK_UTMI_CLK:
- WARN(rate != 19200000, "Unexpected rate for USB30_PRIM_MOCK_UTMI_CLK: %lu\n", rate);
- clk_rcg_set_rate(priv->base, USB30_PRIM_MASTER_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO);
- return rate;
case GCC_USB30_PRIM_MASTER_CLK:
- WARN(rate != 200000000, "Unexpected rate for USB30_PRIM_MASTER_CLK: %lu\n", rate);
+ freq = qcom_find_freq(ftbl_gcc_usb30_prim_master_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_MASTER_CLK_CMD_RCGR,
- 1, 0, 0, CFG_CLK_SRC_GPLL0_ODD, 8);
- clk_rcg_set_rate(priv->base, 0xf064, 0, 0);
- return rate;
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_USB30_PRIM_MOCK_UTMI_CLK:
+ clk_rcg_set_rate(priv->base, USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR, 1, 0);
+ return 19200000;
+ case GCC_USB3_PRIM_PHY_AUX_CLK_SRC:
+ clk_rcg_set_rate(priv->base, USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR, 1, 0);
+ return 19200000;
+ case GCC_USB30_SEC_MASTER_CLK:
+ freq = qcom_find_freq(ftbl_gcc_usb30_sec_master_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, USB30_SEC_MASTER_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_USB30_SEC_MOCK_UTMI_CLK:
+ clk_rcg_set_rate(priv->base, USB30_SEC_MOCK_UTMI_CLK_CMD_RCGR, 1, 0);
+ return 19200000;
+ case GCC_USB3_SEC_PHY_AUX_CLK_SRC:
+ clk_rcg_set_rate(priv->base, USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR, 1, 0);
+ return 19200000;
+ case GCC_PCIE1_PHY_RCHNG_CLK:
+ clk_rcg_set_rate(priv->base, PCIE1_PHY_RCHNG_CMD_RCGR, 5, CFG_CLK_SRC_GPLL0_EVEN);
+ return 100000000;
default:
- return 0;
+ return rate;
}
}
@@ -50,13 +85,35 @@ static const struct gate_clk sc7280_clks[] = {
GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0xf01c, 1),
GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0xf054, 1),
GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0xf058, 1),
+ GATE_CLK(GCC_CFG_NOC_USB3_SEC_AXI_CLK, 0x9e07c, 1),
+ GATE_CLK(GCC_USB30_SEC_MASTER_CLK, 0x9e010, 1),
+ GATE_CLK(GCC_AGGRE_USB3_SEC_AXI_CLK, 0x9e080, 1),
+ GATE_CLK(GCC_USB30_SEC_SLEEP_CLK, 0x9e018, 1),
+ GATE_CLK(GCC_USB30_SEC_MOCK_UTMI_CLK, 0x9e01c, 1),
+ GATE_CLK(GCC_USB3_SEC_PHY_AUX_CLK, 0x9e054, 1),
+ GATE_CLK(GCC_USB3_SEC_PHY_COM_AUX_CLK, 0x9e058, 1),
+ GATE_CLK(GCC_PCIE_CLKREF_EN, 0x8c004, 1),
+ GATE_CLK(GCC_PCIE_1_PIPE_CLK, 0x52000, BIT(30)),
+ GATE_CLK(GCC_PCIE_1_AUX_CLK, 0x52000, BIT(29)),
+ GATE_CLK(GCC_PCIE_1_CFG_AHB_CLK, 0x52000, BIT(28)),
+ GATE_CLK(GCC_PCIE_1_MSTR_AXI_CLK, 0x52000, BIT(27)),
+ GATE_CLK(GCC_PCIE_1_SLV_AXI_CLK, 0x52000, BIT(26)),
+ GATE_CLK(GCC_PCIE_1_SLV_Q2A_AXI_CLK, 0x52000, BIT(25)),
+ GATE_CLK(GCC_PCIE1_PHY_RCHNG_CLK, 0x52000, BIT(23)),
+ GATE_CLK(GCC_DDRSS_PCIE_SF_CLK, 0x52000, BIT(19)),
+ GATE_CLK(GCC_AGGRE_NOC_PCIE_TBU_CLK, 0x52000, BIT(18)),
+ GATE_CLK(GCC_AGGRE_NOC_PCIE_1_AXI_CLK, 0x52000, BIT(11)),
+ GATE_CLK(GCC_AGGRE_NOC_PCIE_CENTER_SF_AXI_CLK, 0x52008, BIT(28)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x52008, BIT(10)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x52008, BIT(11)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x52008, BIT(13)),
};
static int sc7280_enable(struct clk *clk)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
- if (priv->data->num_clks < clk->id) {
+ if (priv->data->num_clks <= clk->id) {
debug("%s: unknown clk id %lu\n", __func__, clk->id);
return 0;
}
@@ -71,11 +128,32 @@ static int sc7280_enable(struct clk *clk)
qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_AUX_CLK);
qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK);
break;
+ case GCC_AGGRE_USB3_SEC_AXI_CLK:
+ qcom_gate_clk_en(priv, GCC_USB30_SEC_MASTER_CLK);
+ fallthrough;
+ case GCC_USB30_SEC_MASTER_CLK:
+ qcom_gate_clk_en(priv, GCC_USB3_SEC_PHY_AUX_CLK);
+ qcom_gate_clk_en(priv, GCC_USB3_SEC_PHY_COM_AUX_CLK);
+ break;
+ case GCC_PCIE_1_PIPE_CLK:
+ clk_phy_mux_enable(priv->base, PCIE_1_PIPE_CLK_PHY_MUX, true);
+ break;
+ case GCC_PCIE_1_AUX_CLK:
+ clk_rcg_set_rate_mnd(priv->base, PCIE_1_AUX_CLK_CMD_RCGR, 1, 0, 0,
+ CFG_CLK_SRC_CXO, 16);
+ break;
+ case GCC_QUPV3_WRAP0_S0_CLK:
+ clk_rcg_set_rate_mnd(priv->base, 0x17010, 1, 0, 0, CFG_CLK_SRC_CXO, 16);
+ break;
+ case GCC_QUPV3_WRAP0_S1_CLK:
+ clk_rcg_set_rate_mnd(priv->base, 0x17140, 1, 0, 0, CFG_CLK_SRC_CXO, 16);
+ break;
+ case GCC_QUPV3_WRAP0_S3_CLK:
+ clk_rcg_set_rate_mnd(priv->base, 0x173a0, 1, 0, 0, CFG_CLK_SRC_CXO, 16);
+ break;
}
- qcom_gate_clk_en(priv, clk->id);
-
- return 0;
+ return qcom_gate_clk_en(priv, clk->id);
}
static const struct qcom_reset_map sc7280_gcc_resets[] = {
@@ -100,6 +178,20 @@ static const struct qcom_reset_map sc7280_gcc_resets[] = {
static const struct qcom_power_map sc7280_gdscs[] = {
[GCC_UFS_PHY_GDSC] = { 0x77004 },
[GCC_USB30_PRIM_GDSC] = { 0xf004 },
+ [GCC_USB30_SEC_GDSC] = { 0x9e004 },
+ [GCC_PCIE_1_GDSC] = { 0x8d004 },
+};
+
+static const phys_addr_t sc7280_rcg_addrs[] = {
+ 0x10f020, // USB30_PRIM_MASTER_CLK_CMD_RCGR
+ 0x10f038, // USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR
+ 0x18d058, // PCIE_1_AUX_CLK_CMD_RCGR
+};
+
+static const char *const sc7280_rcg_names[] = {
+ "USB30_PRIM_MASTER_CLK_SRC",
+ "USB30_PRIM_MOCK_UTMI_CLK_SRC",
+ "GCC_PCIE_1_AUX_CLK_SRC",
};
static struct msm_clk_data qcs404_gcc_data = {
@@ -113,6 +205,10 @@ static struct msm_clk_data qcs404_gcc_data = {
.enable = sc7280_enable,
.set_rate = sc7280_set_rate,
+
+ .dbg_rcg_addrs = sc7280_rcg_addrs,
+ .num_rcgs = ARRAY_SIZE(sc7280_rcg_addrs),
+ .dbg_rcg_names = sc7280_rcg_names,
};
static const struct udevice_id gcc_sc7280_of_match[] = {
diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
index adffb0cb240..6a0bf16ba2d 100644
--- a/drivers/clk/qcom/clock-sdm845.c
+++ b/drivers/clk/qcom/clock-sdm845.c
@@ -162,9 +162,7 @@ static int sdm845_clk_enable(struct clk *clk)
break;
}
- qcom_gate_clk_en(priv, clk->id);
-
- return 0;
+ return qcom_gate_clk_en(priv, clk->id);
}
static const struct qcom_reset_map sdm845_gcc_resets[] = {
diff --git a/drivers/clk/qcom/clock-sm6115.c b/drivers/clk/qcom/clock-sm6115.c
index 9057dfe0bb1..17c2e561758 100644
--- a/drivers/clk/qcom/clock-sm6115.c
+++ b/drivers/clk/qcom/clock-sm6115.c
@@ -146,9 +146,7 @@ static int sm6115_enable(struct clk *clk)
break;
}
- qcom_gate_clk_en(priv, clk->id);
-
- return 0;
+ return qcom_gate_clk_en(priv, clk->id);
}
static const struct qcom_reset_map sm6115_gcc_resets[] = {
diff --git a/drivers/clk/qcom/clock-sm8150.c b/drivers/clk/qcom/clock-sm8150.c
index 88f2e678f43..7dd0d56eb43 100644
--- a/drivers/clk/qcom/clock-sm8150.c
+++ b/drivers/clk/qcom/clock-sm8150.c
@@ -243,9 +243,7 @@ static int sm8150_clk_enable(struct clk *clk)
break;
};
- qcom_gate_clk_en(priv, clk->id);
-
- return 0;
+ return qcom_gate_clk_en(priv, clk->id);
}
static const struct qcom_reset_map sm8150_gcc_resets[] = {
diff --git a/drivers/clk/qcom/clock-sm8250.c b/drivers/clk/qcom/clock-sm8250.c
index e322a923a5c..26396847d85 100644
--- a/drivers/clk/qcom/clock-sm8250.c
+++ b/drivers/clk/qcom/clock-sm8250.c
@@ -195,9 +195,7 @@ static int sm8250_enable(struct clk *clk)
break;
}
- qcom_gate_clk_en(priv, clk->id);
-
- return 0;
+ return qcom_gate_clk_en(priv, clk->id);
}
static const struct qcom_reset_map sm8250_gcc_resets[] = {
diff --git a/drivers/clk/qcom/clock-sm8550.c b/drivers/clk/qcom/clock-sm8550.c
index 62b5a409e8e..7c06489b9c4 100644
--- a/drivers/clk/qcom/clock-sm8550.c
+++ b/drivers/clk/qcom/clock-sm8550.c
@@ -220,9 +220,7 @@ static int sm8550_enable(struct clk *clk)
break;
}
- qcom_gate_clk_en(priv, clk->id);
-
- return 0;
+ return qcom_gate_clk_en(priv, clk->id);
}
static const struct qcom_reset_map sm8550_gcc_resets[] = {
diff --git a/drivers/clk/qcom/clock-sm8650.c b/drivers/clk/qcom/clock-sm8650.c
index 9baaecb571f..364454644a6 100644
--- a/drivers/clk/qcom/clock-sm8650.c
+++ b/drivers/clk/qcom/clock-sm8650.c
@@ -217,9 +217,7 @@ static int sm8650_enable(struct clk *clk)
break;
}
- qcom_gate_clk_en(priv, clk->id);
-
- return 0;
+ return qcom_gate_clk_en(priv, clk->id);
}
static const struct qcom_reset_map sm8650_gcc_resets[] = {
diff --git a/drivers/clk/qcom/clock-x1e80100.c b/drivers/clk/qcom/clock-x1e80100.c
index bd9c6ed1c8a..542d6248d65 100644
--- a/drivers/clk/qcom/clock-x1e80100.c
+++ b/drivers/clk/qcom/clock-x1e80100.c
@@ -174,9 +174,7 @@ static int x1e80100_enable(struct clk *clk)
break;
}
- qcom_gate_clk_en(priv, clk->id);
-
- return 0;
+ return qcom_gate_clk_en(priv, clk->id);
}
static const struct qcom_reset_map x1e80100_gcc_resets[] = {
diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c
index 27bb7052fca..ac77fb06bf7 100644
--- a/drivers/mmc/msm_sdhci.c
+++ b/drivers/mmc/msm_sdhci.c
@@ -10,6 +10,7 @@
#include <clk.h>
#include <dm.h>
#include <malloc.h>
+#include <reset.h>
#include <sdhci.h>
#include <wait_bit.h>
#include <asm/global_data.h>
@@ -153,9 +154,18 @@ static int msm_sdc_probe(struct udevice *dev)
const struct msm_sdhc_variant_info *var_info;
struct sdhci_host *host = &prv->host;
u32 core_version, core_minor, core_major;
+ struct reset_ctl bcr_rst;
u32 caps;
int ret;
+ ret = reset_get_by_index(dev, 0, &bcr_rst);
+ if (!ret) {
+ reset_assert(&bcr_rst);
+ udelay(200);
+ reset_deassert(&bcr_rst);
+ udelay(200);
+ }
+
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_BROKEN_R1B;
host->max_clk = 0;
diff --git a/drivers/net/phy/micrel_ksz90x1.c b/drivers/net/phy/micrel_ksz90x1.c
index c48ae6e88f3..ee8eae1efd9 100644
--- a/drivers/net/phy/micrel_ksz90x1.c
+++ b/drivers/net/phy/micrel_ksz90x1.c
@@ -389,10 +389,126 @@ U_BOOT_PHY_DRIVER(ksz9031) = {
#define KSZ9131RN_DLL_ENABLE_DELAY 0
#define KSZ9131RN_DLL_DISABLE_DELAY BIT(12)
+#define KSZ9131RN_COMMON_CTRL 0
+#define KSZ9131RN_COMMON_CTRL_INDIVIDUAL_LED_MODE BIT(4)
+
+#define KSZ9131RN_LED_ERRATA_REG 0x1e
+#define KSZ9131RN_LED_ERRATA_BIT BIT(9)
+
+#define KSZ9131RN_CONTROL_PAD_SKEW 4
+#define KSZ9131RN_RX_DATA_PAD_SKEW 5
+#define KSZ9131RN_TX_DATA_PAD_SKEW 6
+#define KSZ9131RN_CLK_PAD_SKEW 8
+
+#define KSZ9131RN_SKEW_5BIT_MAX 2400
+#define KSZ9131RN_SKEW_4BIT_MAX 800
+#define KSZ9131RN_OFFSET 700
+#define KSZ9131RN_STEP 100
+
+static int ksz9131_of_load_skew_values(struct phy_device *phydev,
+ ofnode of_node,
+ u16 reg, size_t field_sz,
+ const char *field[], u8 numfields)
+{
+ int val[4] = {-(1 + KSZ9131RN_OFFSET), -(2 + KSZ9131RN_OFFSET),
+ -(3 + KSZ9131RN_OFFSET), -(4 + KSZ9131RN_OFFSET)};
+ int skewval, skewmax = 0;
+ int matches = 0;
+ u16 maxval;
+ u16 newval;
+ u16 mask;
+ int i;
+
+ /* psec properties in dts should mean x pico seconds */
+ if (field_sz == 5)
+ skewmax = KSZ9131RN_SKEW_5BIT_MAX;
+ else
+ skewmax = KSZ9131RN_SKEW_4BIT_MAX;
+
+ for (i = 0; i < numfields; i++)
+ if (!ofnode_read_s32(of_node, field[i], &skewval)) {
+ if (skewval < -KSZ9131RN_OFFSET)
+ skewval = -KSZ9131RN_OFFSET;
+ else if (skewval > skewmax)
+ skewval = skewmax;
+
+ val[i] = skewval + KSZ9131RN_OFFSET;
+ matches++;
+ }
+
+ if (!matches)
+ return 0;
+
+ if (matches < numfields)
+ newval = phy_read_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG, reg);
+ else
+ newval = 0;
+
+ maxval = (field_sz == 4) ? 0xf : 0x1f;
+ for (i = 0; i < numfields; i++)
+ if (val[i] != -(i + 1 + KSZ9131RN_OFFSET)) {
+ mask = 0xffff;
+ mask ^= maxval << (field_sz * i);
+ newval = (newval & mask) |
+ (((val[i] / KSZ9131RN_STEP) & maxval)
+ << (field_sz * i));
+ }
+
+ return phy_write_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG, reg, newval);
+}
+
+static int ksz9131_of_load_all_skew_values(struct phy_device *phydev)
+{
+ const char *control_skews[2] = { "txen-skew-psec", "rxdv-skew-psec" };
+ const char *clk_skews[2] = { "rxc-skew-psec", "txc-skew-psec" };
+ const char *rx_data_skews[4] = {
+ "rxd0-skew-psec", "rxd1-skew-psec",
+ "rxd2-skew-psec", "rxd3-skew-psec"
+ };
+ const char *tx_data_skews[4] = {
+ "txd0-skew-psec", "txd1-skew-psec",
+ "txd2-skew-psec", "txd3-skew-psec"
+ };
+ struct ofnode_phandle_args phandle_args;
+ int ret;
+
+ /*
+ * Silently ignore failure here as the device tree is not required to
+ * contain a phy node.
+ */
+ if (dev_read_phandle_with_args(phydev->dev, "phy-handle", NULL, 0, 0,
+ &phandle_args))
+ return 0;
+
+ if (!ofnode_valid(phandle_args.node))
+ return 0;
+
+ ret = ksz9131_of_load_skew_values(phydev, phandle_args.node,
+ KSZ9131RN_CLK_PAD_SKEW, 5,
+ clk_skews, 2);
+ if (ret < 0)
+ return ret;
+
+ ret = ksz9131_of_load_skew_values(phydev, phandle_args.node,
+ KSZ9131RN_CONTROL_PAD_SKEW, 4,
+ control_skews, 2);
+ if (ret < 0)
+ return ret;
+
+ ret = ksz9131_of_load_skew_values(phydev, phandle_args.node,
+ KSZ9131RN_RX_DATA_PAD_SKEW, 4,
+ rx_data_skews, 4);
+ if (ret < 0)
+ return ret;
+
+ return ksz9131_of_load_skew_values(phydev, phandle_args.node,
+ KSZ9131RN_TX_DATA_PAD_SKEW, 4,
+ tx_data_skews, 4);
+}
+
static int ksz9131_config_rgmii_delay(struct phy_device *phydev)
{
- struct phy_driver *drv = phydev->drv;
- u16 rxcdll_val, txcdll_val, val;
+ u16 rxcdll_val, txcdll_val;
int ret;
switch (phydev->interface) {
@@ -416,24 +532,37 @@ static int ksz9131_config_rgmii_delay(struct phy_device *phydev)
return 0;
}
- val = drv->readext(phydev, 0, KSZ9131RN_MMD_COMMON_CTRL_REG,
- KSZ9131RN_RXC_DLL_CTRL);
- val &= ~KSZ9131RN_DLL_CTRL_BYPASS;
- val |= rxcdll_val;
- ret = drv->writeext(phydev, 0, KSZ9131RN_MMD_COMMON_CTRL_REG,
- KSZ9131RN_RXC_DLL_CTRL, val);
- if (ret)
+ ret = phy_modify_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG,
+ KSZ9131RN_RXC_DLL_CTRL, KSZ9131RN_DLL_CTRL_BYPASS,
+ rxcdll_val);
+ if (ret < 0)
return ret;
- val = drv->readext(phydev, 0, KSZ9131RN_MMD_COMMON_CTRL_REG,
- KSZ9131RN_TXC_DLL_CTRL);
+ return phy_modify_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG,
+ KSZ9131RN_TXC_DLL_CTRL, KSZ9131RN_DLL_CTRL_BYPASS,
+ txcdll_val);
+}
+
+/* Silicon Errata DS80000693B
+ *
+ * When LEDs are configured in Individual Mode, LED1 is ON in a no-link
+ * condition. Workaround is to set register 0x1e, bit 9, this way LED1 behaves
+ * according to the datasheet (off if there is no link).
+ */
+static int ksz9131_led_errata(struct phy_device *phydev)
+{
+ int reg;
- val &= ~KSZ9131RN_DLL_CTRL_BYPASS;
- val |= txcdll_val;
- ret = drv->writeext(phydev, 0, KSZ9131RN_MMD_COMMON_CTRL_REG,
- KSZ9131RN_TXC_DLL_CTRL, val);
+ reg = phy_read_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG,
+ KSZ9131RN_COMMON_CTRL);
+ if (reg < 0)
+ return reg;
- return ret;
+ if (!(reg & KSZ9131RN_COMMON_CTRL_INDIVIDUAL_LED_MODE))
+ return 0;
+
+ return phy_set_bits(phydev, MDIO_DEVAD_NONE, KSZ9131RN_LED_ERRATA_REG,
+ KSZ9131RN_LED_ERRATA_BIT);
}
static int ksz9131_config(struct phy_device *phydev)
@@ -446,6 +575,14 @@ static int ksz9131_config(struct phy_device *phydev)
return ret;
}
+ ret = ksz9131_of_load_all_skew_values(phydev);
+ if (ret < 0)
+ return ret;
+
+ ret = ksz9131_led_errata(phydev);
+ if (ret < 0)
+ return ret;
+
/* add an option to disable the gigabit feature of this PHY */
if (env_get("disable_giga")) {
unsigned features;
diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
index c39bef17b79..539fd37ee59 100644
--- a/drivers/net/ravb.c
+++ b/drivers/net/ravb.c
@@ -592,7 +592,7 @@ static int ravb_probe(struct udevice *dev)
ret = clk_get_bulk(dev, &eth->clks);
if (ret < 0)
- goto err_mdio_alloc;
+ goto err_clk_get;
mdiodev = mdio_alloc();
if (!mdiodev) {
@@ -614,23 +614,25 @@ static int ravb_probe(struct udevice *dev)
/* Bring up PHY */
ret = clk_enable_bulk(&eth->clks);
if (ret)
- goto err_mdio_register;
+ goto err_clk_enable;
ret = ravb_reset(dev);
if (ret)
- goto err_mdio_reset;
+ goto err_clk_enable;
ret = ravb_phy_config(dev);
if (ret)
- goto err_mdio_reset;
+ goto err_clk_enable;
return 0;
-err_mdio_reset:
- clk_release_bulk(&eth->clks);
+err_clk_enable:
+ mdio_unregister(mdiodev);
err_mdio_register:
mdio_free(mdiodev);
err_mdio_alloc:
+ clk_release_bulk(&eth->clks);
+err_clk_get:
unmap_physmem(eth->iobase, MAP_NOCACHE);
return ret;
}
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index f940648fe58..d3fe90d939e 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -163,8 +163,8 @@ config PHY_RCAR_GEN2
config PHY_RCAR_GEN3
tristate "Renesas R-Car Gen3 USB PHY"
- depends on PHY && RCAR_GEN3 && CLK && DM_REGULATOR
- default y if RCAR_GEN3
+ depends on PHY && CLK && DM_REGULATOR && (RCAR_GEN3 || RZG2L)
+ default y if (RCAR_GEN3 || RZG2L)
help
Support for the Renesas R-Car Gen3 USB PHY. This driver operates the
PHY connected to EHCI USB module and controls USB OTG operation.
diff --git a/drivers/phy/phy-rcar-gen3.c b/drivers/phy/phy-rcar-gen3.c
index 8c004eaf4c6..d06861c4f79 100644
--- a/drivers/phy/phy-rcar-gen3.c
+++ b/drivers/phy/phy-rcar-gen3.c
@@ -55,6 +55,7 @@
/* VBCTRL */
#define USB2_VBCTRL_DRVVBUSSEL BIT(8)
+#define USB2_VBCTRL_VBOUT BIT(0)
/* LINECTRL1 */
#define USB2_LINECTRL1_DPRPD_EN BIT(19)
@@ -68,6 +69,13 @@
#define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is enabled */
#define USB2_ADPCTRL_DRVVBUS BIT(4)
+/* RZ/G2L specific */
+#define USB2_OBINT_IDCHG_EN BIT(0)
+#define USB2_LINECTRL1_USB2_IDMON BIT(0)
+
+/* Device flags */
+#define RCAR_GEN3_PHY_NO_ADPCTRL BIT(0)
+
struct rcar_gen3_phy {
fdt_addr_t regs;
struct clk clk;
@@ -122,15 +130,50 @@ static int rcar_gen3_phy_phy_power_off(struct phy *phy)
return regulator_set_enable(priv->vbus_supply, false);
}
+static bool rcar_gen3_phy_check_id(struct phy *phy)
+{
+ const u32 adpdevmask = USB2_ADPCTRL_IDDIG | USB2_ADPCTRL_OTGSESSVLD;
+ struct rcar_gen3_phy *priv = dev_get_priv(phy->dev);
+ ulong flags = dev_get_driver_data(phy->dev);
+ u32 val;
+
+ if (flags & RCAR_GEN3_PHY_NO_ADPCTRL) {
+ val = readl(priv->regs + USB2_LINECTRL1);
+ return !!(val & USB2_LINECTRL1_USB2_IDMON);
+ }
+
+ val = readl(priv->regs + USB2_ADPCTRL);
+ return (val & adpdevmask) == adpdevmask;
+}
+
+static void rcar_gen3_phy_set_vbus(struct phy *phy, bool enable)
+{
+ struct rcar_gen3_phy *priv = dev_get_priv(phy->dev);
+ ulong flags = dev_get_driver_data(phy->dev);
+ u32 bits = USB2_ADPCTRL_DRVVBUS;
+ u64 reg = USB2_ADPCTRL;
+
+ if (flags & RCAR_GEN3_PHY_NO_ADPCTRL) {
+ bits = USB2_VBCTRL_VBOUT;
+ reg = USB2_VBCTRL;
+ }
+
+ if (enable)
+ setbits_le32(priv->regs + reg, bits);
+ else
+ clrbits_le32(priv->regs + reg, bits);
+}
+
static int rcar_gen3_phy_phy_set_mode(struct phy *phy, enum phy_mode mode,
int submode)
{
- const u32 adpdevmask = USB2_ADPCTRL_IDDIG | USB2_ADPCTRL_OTGSESSVLD;
struct rcar_gen3_phy *priv = dev_get_priv(phy->dev);
- u32 adpctrl;
+ ulong flags = dev_get_driver_data(phy->dev);
if (mode == PHY_MODE_USB_OTG) {
if (submode) {
+ u32 obint_enable_bits;
+
/* OTG submode is used as initialization indicator */
writel(USB2_INT_ENABLE_UCOM_INTEN |
USB2_INT_ENABLE_USBH_INTB_EN |
@@ -138,13 +181,16 @@ static int rcar_gen3_phy_phy_set_mode(struct phy *phy, enum phy_mode mode,
priv->regs + USB2_INT_ENABLE);
setbits_le32(priv->regs + USB2_VBCTRL,
USB2_VBCTRL_DRVVBUSSEL);
- writel(USB2_OBINT_SESSVLDCHG | USB2_OBINT_IDDIGCHG,
- priv->regs + USB2_OBINTSTA);
- setbits_le32(priv->regs + USB2_OBINTEN,
- USB2_OBINT_SESSVLDCHG |
- USB2_OBINT_IDDIGCHG);
- setbits_le32(priv->regs + USB2_ADPCTRL,
- USB2_ADPCTRL_IDPULLUP);
+ if (flags & RCAR_GEN3_PHY_NO_ADPCTRL) {
+ obint_enable_bits = USB2_OBINT_IDCHG_EN;
+ } else {
+ obint_enable_bits = USB2_OBINT_SESSVLDCHG |
+ USB2_OBINT_IDDIGCHG;
+ setbits_le32(priv->regs + USB2_ADPCTRL,
+ USB2_ADPCTRL_IDPULLUP);
+ }
+ writel(obint_enable_bits, priv->regs + USB2_OBINTSTA);
+ setbits_le32(priv->regs + USB2_OBINTEN, obint_enable_bits);
clrsetbits_le32(priv->regs + USB2_LINECTRL1,
USB2_LINECTRL1_DP_RPD |
USB2_LINECTRL1_DM_RPD |
@@ -154,8 +200,7 @@ static int rcar_gen3_phy_phy_set_mode(struct phy *phy, enum phy_mode mode,
USB2_LINECTRL1_DMRPD_EN);
}
- adpctrl = readl(priv->regs + USB2_ADPCTRL);
- if ((adpctrl & adpdevmask) == adpdevmask)
+ if (rcar_gen3_phy_check_id(phy))
mode = PHY_MODE_USB_DEVICE;
else
mode = PHY_MODE_USB_HOST;
@@ -165,13 +210,13 @@ static int rcar_gen3_phy_phy_set_mode(struct phy *phy, enum phy_mode mode,
clrbits_le32(priv->regs + USB2_COMMCTRL, USB2_COMMCTRL_OTG_PERI);
setbits_le32(priv->regs + USB2_LINECTRL1,
USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD);
- setbits_le32(priv->regs + USB2_ADPCTRL, USB2_ADPCTRL_DRVVBUS);
+ rcar_gen3_phy_set_vbus(phy, true);
} else if (mode == PHY_MODE_USB_DEVICE) {
setbits_le32(priv->regs + USB2_COMMCTRL, USB2_COMMCTRL_OTG_PERI);
clrsetbits_le32(priv->regs + USB2_LINECTRL1,
USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD,
USB2_LINECTRL1_DM_RPD);
- clrbits_le32(priv->regs + USB2_ADPCTRL, USB2_ADPCTRL_DRVVBUS);
+ rcar_gen3_phy_set_vbus(phy, false);
} else {
dev_err(phy->dev, "Unknown mode %d\n", mode);
return -EINVAL;
@@ -226,7 +271,13 @@ static int rcar_gen3_phy_remove(struct udevice *dev)
}
static const struct udevice_id rcar_gen3_phy_of_match[] = {
- { .compatible = "renesas,rcar-gen3-usb2-phy", },
+ {
+ .compatible = "renesas,rcar-gen3-usb2-phy",
+ },
+ {
+ .compatible = "renesas,rzg2l-usb2-phy",
+ .data = RCAR_GEN3_PHY_NO_ADPCTRL,
+ },
{ },
};
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index d3eb6998551..f4a3942ee2f 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -7,84 +7,98 @@ config PINCTRL_QCOM
menu "Qualcomm pinctrl drivers"
config PINCTRL_QCOM_APQ8016
- bool "Qualcomm APQ8016 GCC"
+ bool "Qualcomm APQ8016 Pinctrl"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the MSM8916 / APQ8016
Snapdragon 410 SoC, as well as the associated GPIO driver.
config PINCTRL_QCOM_APQ8096
- bool "Qualcomm APQ8096 GCC"
+ bool "Qualcomm APQ8096 Pinctrl"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the MSM8996 / APQ8096
Snapdragon 820 SoC, as well as the associated GPIO driver.
config PINCTRL_QCOM_IPQ4019
- bool "Qualcomm IPQ4019 GCC"
+ bool "Qualcomm IPQ4019 Pinctrl"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the IPQ4019 SoC,
as well as the associated GPIO driver.
+config PINCTRL_QCOM_IPQ9574
+ bool "Qualcomm IPQ9574 Pinctrl"
+ select PINCTRL_QCOM
+ help
+ Say Y here to enable support for pinctrl on the IPQ9574 SoC,
+ as well as the associated GPIO driver.
+
config PINCTRL_QCOM_QCM2290
- bool "Qualcomm QCM2290 GCC"
+ bool "Qualcomm QCM2290 Pinctrl"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon QCM2290 SoC,
as well as the associated GPIO driver.
config PINCTRL_QCOM_QCS404
- bool "Qualcomm QCS404 GCC"
+ bool "Qualcomm QCS404 Pinctrl"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon QCS404 SoC,
as well as the associated GPIO driver.
+config PINCTRL_QCOM_SC7280
+ bool "Qualcomm SC7280/QCM6490 Pinctrl"
+ select PINCTRL_QCOM
+ help
+ Say Y here to enable support for pinctrl on the Snapdragon SC7280 SoC,
+ as well as the associated GPIO driver.
+
config PINCTRL_QCOM_SDM845
- bool "Qualcomm SDM845 GCC"
+ bool "Qualcomm SDM845 Pinctrl"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon 845 SoC,
as well as the associated GPIO driver.
config PINCTRL_QCOM_SM6115
- bool "Qualcomm SM6115 GCC"
+ bool "Qualcomm SM6115 Pinctrl"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM6115 SoC,
as well as the associated GPIO driver.
config PINCTRL_QCOM_SM8150
- bool "Qualcomm SM8150 GCC"
+ bool "Qualcomm SM8150 Pinctrl"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM8150 SoC,
as well as the associated GPIO driver.
config PINCTRL_QCOM_SM8250
- bool "Qualcomm SM8250 GCC"
+ bool "Qualcomm SM8250 Pinctrl"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM8250 SoC,
as well as the associated GPIO driver.
config PINCTRL_QCOM_SM8550
- bool "Qualcomm SM8550 GCC"
+ bool "Qualcomm SM8550 Pinctrl"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM8550 SoC,
as well as the associated GPIO driver.
config PINCTRL_QCOM_SM8650
- bool "Qualcomm SM8650 GCC"
+ bool "Qualcomm SM8650 Pinctrl"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM8650 SoC,
as well as the associated GPIO driver.
config PINCTRL_QCOM_X1E80100
- bool "Qualcomm X1E80100 GCC"
+ bool "Qualcomm X1E80100 Pinctrl"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon X1E80100 SoC,
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 06d3c95f93a..94cdc6e4a62 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -5,9 +5,11 @@
obj-$(CONFIG_PINCTRL_QCOM) += pinctrl-qcom.o
obj-$(CONFIG_PINCTRL_QCOM_APQ8016) += pinctrl-apq8016.o
obj-$(CONFIG_PINCTRL_QCOM_IPQ4019) += pinctrl-ipq4019.o
+obj-$(CONFIG_PINCTRL_QCOM_IPQ9574) += pinctrl-ipq9574.o
obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o
obj-$(CONFIG_PINCTRL_QCOM_QCM2290) += pinctrl-qcm2290.o
obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.o
+obj-$(CONFIG_PINCTRL_QCOM_SC7280) += pinctrl-sc7280.o
obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o
obj-$(CONFIG_PINCTRL_QCOM_SM6115) += pinctrl-sm6115.o
obj-$(CONFIG_PINCTRL_QCOM_SM8150) += pinctrl-sm8150.o
diff --git a/drivers/pinctrl/qcom/pinctrl-apq8016.c b/drivers/pinctrl/qcom/pinctrl-apq8016.c
index 0c7437822ff..9ae07d43d93 100644
--- a/drivers/pinctrl/qcom/pinctrl-apq8016.c
+++ b/drivers/pinctrl/qcom/pinctrl-apq8016.c
@@ -50,8 +50,8 @@ static const char *apq8016_get_pin_name(struct udevice *dev,
}
}
-static unsigned int apq8016_get_function_mux(__maybe_unused unsigned int pin,
- unsigned int selector)
+static int apq8016_get_function_mux(__maybe_unused unsigned int pin,
+ unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
diff --git a/drivers/pinctrl/qcom/pinctrl-apq8096.c b/drivers/pinctrl/qcom/pinctrl-apq8096.c
index 132ece868bf..eaa927c6e22 100644
--- a/drivers/pinctrl/qcom/pinctrl-apq8096.c
+++ b/drivers/pinctrl/qcom/pinctrl-apq8096.c
@@ -43,8 +43,8 @@ static const char *apq8096_get_pin_name(struct udevice *dev,
}
}
-static unsigned int apq8096_get_function_mux(__maybe_unused unsigned int pin,
- unsigned int selector)
+static int apq8096_get_function_mux(__maybe_unused unsigned int pin,
+ unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
diff --git a/drivers/pinctrl/qcom/pinctrl-ipq4019.c b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
index 3215c677b26..dafcd494df4 100644
--- a/drivers/pinctrl/qcom/pinctrl-ipq4019.c
+++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
@@ -311,8 +311,7 @@ static const char *ipq4019_get_pin_name(struct udevice *dev,
return pin_name;
}
-static unsigned int ipq4019_get_function_mux(unsigned int pin,
- unsigned int selector)
+static int ipq4019_get_function_mux(unsigned int pin, unsigned int selector)
{
unsigned int i;
const msm_pin_function *func = ipq4019_pin_functions + pin;
diff --git a/drivers/pinctrl/qcom/pinctrl-ipq9574.c b/drivers/pinctrl/qcom/pinctrl-ipq9574.c
new file mode 100644
index 00000000000..ce09072ae3c
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-ipq9574.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pinctrl driver for Qualcomm ipq9574
+ *
+ * (C) Copyright 2025 Linaro Ltd.
+ */
+
+#include <dm.h>
+
+#include "pinctrl-qcom.h"
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
+
+enum ipq9574_functions {
+ msm_mux_blsp0_spi,
+ msm_mux_blsp0_uart,
+ msm_mux_blsp1_i2c,
+ msm_mux_blsp1_spi,
+ msm_mux_blsp1_uart,
+ msm_mux_blsp2_i2c,
+ msm_mux_blsp2_spi,
+ msm_mux_blsp2_uart,
+ msm_mux_blsp3_i2c,
+ msm_mux_blsp3_spi,
+ msm_mux_blsp3_uart,
+ msm_mux_blsp4_i2c,
+ msm_mux_blsp4_spi,
+ msm_mux_blsp4_uart,
+ msm_mux_blsp5_i2c,
+ msm_mux_blsp5_uart,
+ msm_mux_gpio,
+ msm_mux_mdc,
+ msm_mux_mdio,
+ msm_mux_pcie0_clk,
+ msm_mux_pcie0_wake,
+ msm_mux_pcie1_clk,
+ msm_mux_pcie1_wake,
+ msm_mux_pcie2_clk,
+ msm_mux_pcie2_wake,
+ msm_mux_pcie3_clk,
+ msm_mux_pcie3_wake,
+ msm_mux_qspi_data,
+ msm_mux_qspi_clk,
+ msm_mux_qspi_cs,
+ msm_mux_sdc_data,
+ msm_mux_sdc_clk,
+ msm_mux_sdc_cmd,
+ msm_mux_sdc_rclk,
+ msm_mux_NA,
+};
+
+#define MSM_PIN_FUNCTION(fname) \
+ [msm_mux_##fname] = {#fname, msm_mux_##fname}
+
+static const struct pinctrl_function msm_pinctrl_functions[] = {
+ MSM_PIN_FUNCTION(blsp0_spi),
+ MSM_PIN_FUNCTION(blsp0_uart),
+ MSM_PIN_FUNCTION(blsp1_i2c),
+ MSM_PIN_FUNCTION(blsp1_spi),
+ MSM_PIN_FUNCTION(blsp1_uart),
+ MSM_PIN_FUNCTION(blsp2_i2c),
+ MSM_PIN_FUNCTION(blsp2_spi),
+ MSM_PIN_FUNCTION(blsp2_uart),
+ MSM_PIN_FUNCTION(blsp3_i2c),
+ MSM_PIN_FUNCTION(blsp3_spi),
+ MSM_PIN_FUNCTION(blsp3_uart),
+ MSM_PIN_FUNCTION(blsp4_i2c),
+ MSM_PIN_FUNCTION(blsp4_spi),
+ MSM_PIN_FUNCTION(blsp4_uart),
+ MSM_PIN_FUNCTION(blsp5_i2c),
+ MSM_PIN_FUNCTION(blsp5_uart),
+ MSM_PIN_FUNCTION(gpio),
+ MSM_PIN_FUNCTION(mdc),
+ MSM_PIN_FUNCTION(mdio),
+ MSM_PIN_FUNCTION(pcie0_clk),
+ MSM_PIN_FUNCTION(pcie0_wake),
+ MSM_PIN_FUNCTION(pcie1_clk),
+ MSM_PIN_FUNCTION(pcie1_wake),
+ MSM_PIN_FUNCTION(pcie2_clk),
+ MSM_PIN_FUNCTION(pcie2_wake),
+ MSM_PIN_FUNCTION(pcie3_clk),
+ MSM_PIN_FUNCTION(pcie3_wake),
+ MSM_PIN_FUNCTION(qspi_data),
+ MSM_PIN_FUNCTION(qspi_clk),
+ MSM_PIN_FUNCTION(qspi_cs),
+ MSM_PIN_FUNCTION(sdc_data),
+ MSM_PIN_FUNCTION(sdc_clk),
+ MSM_PIN_FUNCTION(sdc_cmd),
+ MSM_PIN_FUNCTION(sdc_rclk),
+};
+
+typedef unsigned int msm_pin_function[10];
+
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9) \
+ [id] = { msm_mux_gpio, /* gpio mode */ \
+ msm_mux_##f1, \
+ msm_mux_##f2, \
+ msm_mux_##f3, \
+ msm_mux_##f4, \
+ msm_mux_##f5, \
+ msm_mux_##f6, \
+ msm_mux_##f7, \
+ msm_mux_##f8, \
+ msm_mux_##f9, \
+ }
+
+static const msm_pin_function ipq9574_pin_functions[] = {
+ PINGROUP(0, sdc_data, qspi_data, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(1, sdc_data, qspi_data, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(2, sdc_data, qspi_data, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(3, sdc_data, qspi_data, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(4, sdc_cmd, qspi_cs, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(5, sdc_clk, qspi_clk, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(6, sdc_data, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(7, sdc_data, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(8, sdc_data, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(9, sdc_data, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(10, sdc_rclk, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(11, blsp0_spi, blsp0_uart, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(12, blsp0_spi, blsp0_uart, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(13, blsp0_spi, blsp0_uart, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(14, blsp0_spi, blsp0_uart, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(15, blsp3_spi, blsp3_i2c, blsp3_uart, NA, NA, NA, NA, NA, NA),
+ PINGROUP(16, blsp3_spi, blsp3_i2c, blsp3_uart, NA, NA, NA, NA, NA, NA),
+ PINGROUP(17, blsp3_spi, blsp3_uart, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(18, blsp3_spi, blsp3_uart, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(19, blsp3_spi, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(20, blsp3_spi, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(21, blsp3_spi, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(22, pcie0_clk, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(23, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(24, pcie0_wake, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(25, pcie1_clk, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(26, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(27, pcie1_wake, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(28, pcie2_clk, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(29, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(30, pcie2_wake, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(31, pcie3_clk, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(32, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(33, pcie3_wake, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(34, blsp2_uart, blsp2_i2c, blsp2_spi, blsp1_uart, NA, NA, NA, NA, NA),
+ PINGROUP(35, blsp2_uart, blsp2_i2c, blsp2_spi, blsp1_uart, NA, NA, NA, NA, NA),
+ PINGROUP(36, blsp1_uart, blsp1_i2c, blsp2_spi, NA, NA, NA, NA, NA, NA),
+ PINGROUP(37, blsp1_uart, blsp1_i2c, blsp2_spi, NA, NA, NA, NA, NA, NA),
+ PINGROUP(38, mdc, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(39, mdio, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(40, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(41, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(42, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(43, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(44, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(45, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(47, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(48, blsp5_i2c, blsp5_uart, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(49, blsp5_i2c, blsp5_uart, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(50, blsp4_uart, blsp4_i2c, blsp4_spi, NA, NA, NA, NA, NA, NA),
+ PINGROUP(51, blsp4_uart, blsp4_i2c, blsp4_spi, NA, NA, NA, NA, NA, NA),
+ PINGROUP(52, blsp4_uart, blsp4_spi, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(53, blsp4_uart, blsp4_spi, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(54, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(55, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(56, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(57, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(58, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(59, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(60, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(61, blsp1_spi, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(62, blsp1_spi, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(63, blsp1_spi, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(64, blsp1_spi, NA, NA, NA, NA, NA, NA, NA, NA),
+};
+
+static const char *ipq9574_get_function_name(struct udevice *dev,
+ unsigned int selector)
+{
+ return msm_pinctrl_functions[selector].name;
+}
+
+static const char *ipq9574_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
+ return pin_name;
+}
+
+static int ipq9574_get_function_mux(unsigned int pin, unsigned int selector)
+{
+ unsigned int i;
+ const msm_pin_function *func = ipq9574_pin_functions + pin;
+
+ for (i = 0; i < 10; i++)
+ if ((*func)[i] == selector)
+ return i;
+
+ debug("Can't find requested function for pin:selector %u:%u\n",
+ pin, selector);
+
+ return -EINVAL;
+}
+
+static const struct msm_pinctrl_data ipq9574_data = {
+ .pin_data = {
+ .pin_count = 65,
+ },
+ .functions_count = ARRAY_SIZE(msm_pinctrl_functions),
+ .get_function_name = ipq9574_get_function_name,
+ .get_function_mux = ipq9574_get_function_mux,
+ .get_pin_name = ipq9574_get_pin_name,
+};
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+ { .compatible = "qcom,ipq9574-tlmm", .data = (ulong)&ipq9574_data },
+ { /* Sentinal */ }
+};
+
+U_BOOT_DRIVER(pinctrl_ipq9574) = {
+ .name = "pinctrl_ipq9574",
+ .id = UCLASS_NOP,
+ .of_match = msm_pinctrl_ids,
+ .ops = &msm_pinctrl_ops,
+ .bind = msm_pinctrl_bind,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/pinctrl/qcom/pinctrl-qcm2290.c b/drivers/pinctrl/qcom/pinctrl-qcm2290.c
index af969e177d7..0c2222ce663 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcm2290.c
+++ b/drivers/pinctrl/qcom/pinctrl-qcm2290.c
@@ -38,7 +38,7 @@ static const char *qcm2290_get_pin_name(struct udevice *dev, unsigned int select
return pin_name;
}
-static unsigned int qcm2290_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
+static int qcm2290_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
diff --git a/drivers/pinctrl/qcom/pinctrl-qcom.c b/drivers/pinctrl/qcom/pinctrl-qcom.c
index 26a3fba194a..24d031947a3 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcom.c
+++ b/drivers/pinctrl/qcom/pinctrl-qcom.c
@@ -92,7 +92,10 @@ static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector,
unsigned int func_selector)
{
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
- u32 func = priv->data->get_function_mux(pin_selector, func_selector);
+ int func = priv->data->get_function_mux(pin_selector, func_selector);
+
+ if (func < 0)
+ return func;
/* Always NOP for special pins, assume they're in the correct state */
if (qcom_is_special_pin(&priv->data->pin_data, pin_selector))
diff --git a/drivers/pinctrl/qcom/pinctrl-qcom.h b/drivers/pinctrl/qcom/pinctrl-qcom.h
index 49b7bfbc001..cd167e63868 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcom.h
+++ b/drivers/pinctrl/qcom/pinctrl-qcom.h
@@ -18,8 +18,7 @@ struct msm_pinctrl_data {
int functions_count;
const char *(*get_function_name)(struct udevice *dev,
unsigned int selector);
- unsigned int (*get_function_mux)(unsigned int pin,
- unsigned int selector);
+ int (*get_function_mux)(unsigned int pin, unsigned int selector);
const char *(*get_pin_name)(struct udevice *dev,
unsigned int selector);
};
diff --git a/drivers/pinctrl/qcom/pinctrl-qcs404.c b/drivers/pinctrl/qcom/pinctrl-qcs404.c
index fb6defaeddf..c272595aa2a 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcs404.c
+++ b/drivers/pinctrl/qcom/pinctrl-qcs404.c
@@ -93,8 +93,8 @@ static const char *qcs404_get_pin_name(struct udevice *dev,
}
}
-static unsigned int qcs404_get_function_mux(__maybe_unused unsigned int pin,
- unsigned int selector)
+static int qcs404_get_function_mux(__maybe_unused unsigned int pin,
+ unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
diff --git a/drivers/pinctrl/qcom/pinctrl-sc7280.c b/drivers/pinctrl/qcom/pinctrl-sc7280.c
new file mode 100644
index 00000000000..fe87947fbbf
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-sc7280.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Qualcomm sc7280 pinctrl
+ *
+ * (C) Copyright 2024 Linaro Ltd.
+ *
+ */
+
+#include <dm.h>
+
+#include "pinctrl-qcom.h"
+
+#define WEST 0x00000000
+#define SOUTH 0x00400000
+#define NORTH 0x00800000
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
+
+static const struct pinctrl_function msm_pinctrl_functions[] = {
+ { "qup05", 1 },
+ { "gpio", 0 },
+ { "pcie1_clkreqn", 3},
+};
+#define SDC_PINGROUP(pg_name, ctl, pull, drv) \
+ { \
+ .name = pg_name, \
+ .ctl_reg = ctl, \
+ .io_reg = 0, \
+ .pull_bit = pull, \
+ .drv_bit = drv, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = -1, \
+ }
+
+#define UFS_RESET(pg_name, offset) \
+ { \
+ .name = pg_name, \
+ .ctl_reg = offset, \
+ .io_reg = offset + 0x4, \
+ .pull_bit = 3, \
+ .drv_bit = 0, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = 0, \
+ }
+
+static const struct msm_special_pin_data sc7280_special_pins_data[] = {
+ [0] = UFS_RESET("ufs_reset", SOUTH + 0xbe000),
+ [1] = SDC_PINGROUP("sdc1_rclk", 0xb3004, 0, 6),
+ [2] = SDC_PINGROUP("sdc1_clk", 0xb3000, 13, 6),
+ [3] = SDC_PINGROUP("sdc1_cmd", 0xb3000, 11, 3),
+ [4] = SDC_PINGROUP("sdc1_data", 0xb3000, 9, 0),
+ [5] = SDC_PINGROUP("sdc2_clk", 0xb4000, 14, 6),
+ [6] = SDC_PINGROUP("sdc2_cmd", 0xb4000, 11, 3),
+ [7] = SDC_PINGROUP("sdc2_data", 0xb4000, 9, 0),
+};
+
+static const char *sc7280_get_function_name(struct udevice *dev, unsigned int selector)
+{
+ return msm_pinctrl_functions[selector].name;
+}
+
+static const char *sc7280_get_pin_name(struct udevice *dev, unsigned int selector)
+{
+ if (selector >= 175 && selector <= 182)
+ snprintf(pin_name, MAX_PIN_NAME_LEN,
+ sc7280_special_pins_data[selector - 175].name);
+ else
+ snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
+
+ return pin_name;
+}
+
+static int sc7280_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
+{
+ return msm_pinctrl_functions[selector].val;
+}
+
+static struct msm_pinctrl_data sc7280_data = {
+ .pin_data = {
+ .pin_count = 183,
+ .special_pins_start = 175,
+ .special_pins_data = sc7280_special_pins_data,
+ },
+ .functions_count = ARRAY_SIZE(msm_pinctrl_functions),
+ .get_function_name = sc7280_get_function_name,
+ .get_function_mux = sc7280_get_function_mux,
+ .get_pin_name = sc7280_get_pin_name,
+};
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+ {
+ .compatible = "qcom,sc7280-pinctrl",
+ .data = (ulong)&sc7280_data
+ },
+ { /* Sentinel */ } };
+
+U_BOOT_DRIVER(pinctrl_sc7280) = {
+ .name = "pinctrl_sc7280",
+ .id = UCLASS_NOP,
+ .of_match = msm_pinctrl_ids,
+ .ops = &msm_pinctrl_ops,
+ .bind = msm_pinctrl_bind,
+};
diff --git a/drivers/pinctrl/qcom/pinctrl-sdm845.c b/drivers/pinctrl/qcom/pinctrl-sdm845.c
index f1a23f51099..3f55fc81c8e 100644
--- a/drivers/pinctrl/qcom/pinctrl-sdm845.c
+++ b/drivers/pinctrl/qcom/pinctrl-sdm845.c
@@ -80,8 +80,8 @@ static const char *sdm845_get_pin_name(struct udevice *dev,
return pin_name;
}
-static unsigned int sdm845_get_function_mux(__maybe_unused unsigned int pin,
- unsigned int selector)
+static int sdm845_get_function_mux(__maybe_unused unsigned int pin,
+ unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
diff --git a/drivers/pinctrl/qcom/pinctrl-sm6115.c b/drivers/pinctrl/qcom/pinctrl-sm6115.c
index f07f39f4ac3..7e80ea39a12 100644
--- a/drivers/pinctrl/qcom/pinctrl-sm6115.c
+++ b/drivers/pinctrl/qcom/pinctrl-sm6115.c
@@ -167,7 +167,7 @@ static const char *sm6115_get_pin_name(struct udevice *dev, unsigned int selecto
return pin_name;
}
-static unsigned int sm6115_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
+static int sm6115_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
diff --git a/drivers/pinctrl/qcom/pinctrl-sm8150.c b/drivers/pinctrl/qcom/pinctrl-sm8150.c
index 1fb2ffb9597..fe789e8639b 100644
--- a/drivers/pinctrl/qcom/pinctrl-sm8150.c
+++ b/drivers/pinctrl/qcom/pinctrl-sm8150.c
@@ -123,8 +123,8 @@ static const char *sm8150_get_pin_name(struct udevice *dev,
return pin_name;
}
-static unsigned int sm8150_get_function_mux(__maybe_unused unsigned int pin,
- unsigned int selector)
+static int sm8150_get_function_mux(__maybe_unused unsigned int pin,
+ unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
diff --git a/drivers/pinctrl/qcom/pinctrl-sm8250.c b/drivers/pinctrl/qcom/pinctrl-sm8250.c
index b21cdc4d24b..d5447651695 100644
--- a/drivers/pinctrl/qcom/pinctrl-sm8250.c
+++ b/drivers/pinctrl/qcom/pinctrl-sm8250.c
@@ -99,7 +99,7 @@ static const char *sm8250_get_pin_name(struct udevice *dev, unsigned int selecto
return pin_name;
}
-static unsigned int sm8250_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
+static int sm8250_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
diff --git a/drivers/pinctrl/qcom/pinctrl-sm8550.c b/drivers/pinctrl/qcom/pinctrl-sm8550.c
index 25b972a6d82..f7fcad0e4aa 100644
--- a/drivers/pinctrl/qcom/pinctrl-sm8550.c
+++ b/drivers/pinctrl/qcom/pinctrl-sm8550.c
@@ -68,8 +68,8 @@ static const char *sm8550_get_pin_name(struct udevice *dev,
return pin_name;
}
-static unsigned int sm8550_get_function_mux(__maybe_unused unsigned int pin,
- unsigned int selector)
+static int sm8550_get_function_mux(__maybe_unused unsigned int pin,
+ unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
diff --git a/drivers/pinctrl/qcom/pinctrl-sm8650.c b/drivers/pinctrl/qcom/pinctrl-sm8650.c
index 9146d6abd9a..6b9d56b1058 100644
--- a/drivers/pinctrl/qcom/pinctrl-sm8650.c
+++ b/drivers/pinctrl/qcom/pinctrl-sm8650.c
@@ -69,8 +69,8 @@ static const char *sm8650_get_pin_name(struct udevice *dev,
return pin_name;
}
-static unsigned int sm8650_get_function_mux(__maybe_unused unsigned int pin,
- unsigned int selector)
+static int sm8650_get_function_mux(__maybe_unused unsigned int pin,
+ unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
diff --git a/drivers/pinctrl/qcom/pinctrl-x1e80100.c b/drivers/pinctrl/qcom/pinctrl-x1e80100.c
index f39dc426d68..319667bfc16 100644
--- a/drivers/pinctrl/qcom/pinctrl-x1e80100.c
+++ b/drivers/pinctrl/qcom/pinctrl-x1e80100.c
@@ -72,8 +72,8 @@ static const char *x1e80100_get_pin_name(struct udevice *dev,
return pin_name;
}
-static unsigned int x1e80100_get_function_mux(__maybe_unused unsigned int pin,
- unsigned int selector)
+static int x1e80100_get_function_mux(__maybe_unused unsigned int pin,
+ unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index 958f337c7e7..8f102a92c23 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -478,3 +478,11 @@ config DM_REGULATOR_TPS65219
features for REGULATOR TPS65219 and the family of TPS65219 PMICs.
TPS65219 series of PMICs have 3 single phase BUCKs & 4 LDOs.
The driver implements get/set api for value and enable.
+
+config REGULATOR_RZG2L_USBPHY
+ bool "Enable driver for RZ/G2L USB PHY VBUS supply"
+ depends on DM_REGULATOR
+ help
+ Enable this option to support controlling the VBUS supply in
+ the USB PHY peripheral of the Renesas RZ/G2L SoC. This option
+ is required in order to use the USB OTG port.
diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile
index ca6c89d13b5..4382d4b3ab9 100644
--- a/drivers/power/regulator/Makefile
+++ b/drivers/power/regulator/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_DM_REGULATOR_TPS65941) += tps65941_regulator.o
obj-$(CONFIG_DM_REGULATOR_SCMI) += scmi_regulator.o
obj-$(CONFIG_$(XPL_)DM_REGULATOR_ANATOP) += anatop_regulator.o
obj-$(CONFIG_DM_REGULATOR_TPS65219) += tps65219_regulator.o
+obj-$(CONFIG_REGULATOR_RZG2L_USBPHY) += rzg2l-usbphy-regulator.o
diff --git a/drivers/power/regulator/rzg2l-usbphy-regulator.c b/drivers/power/regulator/rzg2l-usbphy-regulator.c
new file mode 100644
index 00000000000..451f04c140e
--- /dev/null
+++ b/drivers/power/regulator/rzg2l-usbphy-regulator.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Renesas Electronics Corporation
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <power/regulator.h>
+#include <renesas/rzg2l-usbphy.h>
+
+#define VBENCTL 0x03c
+#define VBENCTL_VBUS_SEL BIT(0)
+
+static int rzg2l_usbphy_regulator_set_enable(struct udevice *dev, bool enable)
+{
+ struct rzg2l_usbphy_ctrl_priv *priv = dev_get_priv(dev->parent);
+
+ if (enable)
+ clrbits_le32(priv->regs + VBENCTL, VBENCTL_VBUS_SEL);
+ else
+ setbits_le32(priv->regs + VBENCTL, VBENCTL_VBUS_SEL);
+
+ return 0;
+}
+
+static int rzg2l_usbphy_regulator_get_enable(struct udevice *dev)
+{
+ struct rzg2l_usbphy_ctrl_priv *priv = dev_get_priv(dev->parent);
+
+ return !!readl(priv->regs + VBENCTL) & VBENCTL_VBUS_SEL;
+}
+
+static const struct dm_regulator_ops rzg2l_usbphy_regulator_ops = {
+ .get_enable = rzg2l_usbphy_regulator_get_enable,
+ .set_enable = rzg2l_usbphy_regulator_set_enable,
+};
+
+U_BOOT_DRIVER(rzg2l_usbphy_regulator) = {
+ .name = "rzg2l_usbphy_regulator",
+ .id = UCLASS_REGULATOR,
+ .ops = &rzg2l_usbphy_regulator_ops,
+};
diff --git a/drivers/ram/renesas/dbsc5/dbsc5.c b/drivers/ram/renesas/dbsc5/dbsc5.c
index d24b7c5c30a..4cbc6aeda43 100644
--- a/drivers/ram/renesas/dbsc5/dbsc5.c
+++ b/drivers/ram/renesas/dbsc5/dbsc5.c
@@ -59,7 +59,8 @@ int renesas_dbsc5_bind(struct udevice *dev)
struct renesas_dbsc5_data r8a779g0_dbsc5_data = {
.clock_node = "renesas,r8a779g0-cpg-mssr",
- .reset_node = "renesas,r8a779g0-rst"
+ .reset_node = "renesas,r8a779g0-rst",
+ .otp_node = "renesas,r8a779g0-otp",
};
static const struct udevice_id renesas_dbsc5_ids[] = {
diff --git a/drivers/ram/renesas/dbsc5/dbsc5.h b/drivers/ram/renesas/dbsc5/dbsc5.h
index c410eb0c5ed..bf22fcb8c11 100644
--- a/drivers/ram/renesas/dbsc5/dbsc5.h
+++ b/drivers/ram/renesas/dbsc5/dbsc5.h
@@ -23,6 +23,7 @@
struct renesas_dbsc5_data {
const char *clock_node;
const char *reset_node;
+ const char *otp_node;
};
#endif /* __DRIVERS_RAM_RENESAS_DBSC5_DBSC5_H__ */
diff --git a/drivers/ram/renesas/dbsc5/dram.c b/drivers/ram/renesas/dbsc5/dram.c
index 210a68f6496..6f78afb0ab5 100644
--- a/drivers/ram/renesas/dbsc5/dram.c
+++ b/drivers/ram/renesas/dbsc5/dram.c
@@ -4,6 +4,7 @@
*/
#include <asm/io.h>
+#include <dbsc5.h>
#include <dm.h>
#include <errno.h>
#include <hang.h>
@@ -12,13 +13,6 @@
#include <linux/sizes.h>
#include "dbsc5.h"
-/* The number of channels V4H has */
-#define DRAM_CH_CNT 4
-/* The number of slices V4H has */
-#define SLICE_CNT 2
-/* The number of chip select V4H has */
-#define CS_CNT 2
-
/* Number of array elements in Data Slice */
#define DDR_PHY_SLICE_REGSET_SIZE_V4H 0x100
/* Number of array elements in Data Slice */
@@ -220,6 +214,7 @@ static const u16 jedec_spec2_tRFC_ab[] = {
#define PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS DDR_REGDEF(0x00, 0x09, 0x103F)
#define PHY_WDQLVL_STATUS_OBS DDR_REGDEF(0x00, 0x20, 0x1043)
#define PHY_DATA_DC_CAL_START DDR_REGDEF(0x18, 0x01, 0x104D)
+#define PHY_SLV_DLY_CTRL_GATE_DISABLE DDR_REGDEF(0x10, 0x01, 0x104E)
#define PHY_REGULATOR_EN_CNT DDR_REGDEF(0x18, 0x06, 0x1050)
#define PHY_VREF_INITIAL_START_POINT DDR_REGDEF(0x00, 0x09, 0x1055)
#define PHY_VREF_INITIAL_STOP_POINT DDR_REGDEF(0x10, 0x09, 0x1055)
@@ -469,7 +464,7 @@ static const u32 DDR_PHY_SLICE_REGSET_V4H[DDR_PHY_SLICE_REGSET_NUM_V4H] = {
0x00000000, 0x00500050, 0x00500050, 0x00500050,
0x00500050, 0x0D000050, 0x10100004, 0x06102010,
0x61619041, 0x07097000, 0x00644180, 0x00803280,
- 0x00808001, 0x13010100, 0x02000016, 0x10001003,
+ 0x00808001, 0x13010101, 0x02000016, 0x10001003,
0x06093E42, 0x0F063D01, 0x011700C8, 0x04100140,
0x00000100, 0x000001D1, 0x05000068, 0x00030402,
0x01400000, 0x80800300, 0x00160010, 0x76543210,
@@ -512,8 +507,8 @@ static const u32 DDR_PHY_ADR_G_REGSET_V4H[DDR_PHY_ADR_G_REGSET_NUM_V4H] = {
0x00040101, 0x00000000, 0x00000000, 0x00000064,
0x00000000, 0x00000000, 0x39421B42, 0x00010124,
0x00520052, 0x00000052, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x07030102,
+ 0x00010001, 0x00000000, 0x00000000, 0x00010001,
+ 0x00000000, 0x00000000, 0x00010001, 0x07030102,
0x01030307, 0x00000054, 0x00004096, 0x08200820,
0x08200820, 0x08200820, 0x08200820, 0x00000820,
0x004103B8, 0x0000003F, 0x000C0006, 0x00000000,
@@ -1294,7 +1289,7 @@ static const struct dbsc5_table_patch dbsc5_table_patch_slice_mbpsdiv_572 = {
};
static const struct dbsc5_table_patch dbsc5_table_patch_adr_g_mbpsdiv_572 = {
- PHY_PAD_ACS_RX_PCLK_CLK_SEL, 0x03
+ PHY_PAD_ACS_RX_PCLK_CLK_SEL, 0x02
};
static const struct dbsc5_table_patch dbsc5_table_patch_adr_g_mbpsdiv_400[] = {
@@ -1374,46 +1369,6 @@ static const u32 PI_DARRAY3_1_CSx_Fx[CS_CNT][3] = {
#define CLK_DIV(a, diva, b, divb) (((a) * (divb)) / ((b) * (diva)))
-struct renesas_dbsc5_board_config {
- /* Channels in use */
- u8 bdcfg_phyvalid;
- /* Read vref (SoC) training range */
- u32 bdcfg_vref_r;
- /* Write vref (MR14, MR15) training range */
- u16 bdcfg_vref_w;
- /* CA vref (MR12) training range */
- u16 bdcfg_vref_ca;
- /* RFM required check */
- bool bdcfg_rfm_chk;
-
- /* Board parameter about channels */
- struct {
- /*
- * 0x00: 4Gb dual channel die / 2Gb single channel die
- * 0x01: 6Gb dual channel die / 3Gb single channel die
- * 0x02: 8Gb dual channel die / 4Gb single channel die
- * 0x03: 12Gb dual channel die / 6Gb single channel die
- * 0x04: 16Gb dual channel die / 8Gb single channel die
- * 0x05: 24Gb dual channel die / 12Gb single channel die
- * 0x06: 32Gb dual channel die / 16Gb single channel die
- * 0x07: 24Gb single channel die
- * 0x08: 32Gb single channel die
- * 0xFF: NO_MEMORY
- */
- u8 bdcfg_ddr_density[CS_CNT];
- /* SoC caX([6][5][4][3][2][1][0]) -> MEM caY: */
- u32 bdcfg_ca_swap;
- /* SoC dqsX([1][0]) -> MEM dqsY: */
- u8 bdcfg_dqs_swap;
- /* SoC dq([7][6][5][4][3][2][1][0]) -> MEM dqY/dm: (8 means DM) */
- u32 bdcfg_dq_swap[SLICE_CNT];
- /* SoC dm -> MEM dqY/dm: (8 means DM) */
- u8 bdcfg_dm_swap[SLICE_CNT];
- /* SoC ckeX([1][0]) -> MEM csY */
- u8 bdcfg_cs_swap;
- } ch[4];
-};
-
struct renesas_dbsc5_dram_priv {
void __iomem *regs;
void __iomem *cpg_regs;
@@ -1713,14 +1668,17 @@ static void dbsc5_clk_wait_dbpdstat1(struct udevice *dev, u32 status)
{
struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
- u32 i, ch, reg;
+ u32 i, ch, chk, reg;
for (i = 0; i < 2; i++) {
do {
reg = status;
- r_foreach_vch(dev, ch)
+ chk = 0;
+ r_foreach_vch(dev, ch) {
reg &= readl(regs_dbsc_d + DBSC_DBPDSTAT1(ch));
- } while (reg != status);
+ chk |= readl(regs_dbsc_d + DBSC_DBPDSTAT0(ch));
+ }
+ } while (reg != status && !(chk & BIT(0)));
}
}
@@ -2192,7 +2150,7 @@ static void dbsc5_ddrtbl_calc(struct renesas_dbsc5_dram_priv *priv)
if (js1[i].fx3 * 2 * priv->ddr_mbpsdiv >= priv->ddr_mbps * 3)
break;
- priv->js1_ind = max(i, JS1_USABLEC_SPEC_HI);
+ priv->js1_ind = clamp(i, 0, JS1_USABLEC_SPEC_HI);
priv->RL = js1[priv->js1_ind].RLset1;
priv->WL = js1[priv->js1_ind].WLsetA;
@@ -2635,7 +2593,7 @@ static void dbsc5_dbsc_regset(struct udevice *dev)
*/
dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(11),
priv->RL + 4 + priv->js2[JS2_tWCK2DQO_HF] -
- js1[priv->js1_ind].ODTLon - priv->js2[JS2_tODTon_min]);
+ js1[priv->js1_ind].ODTLon - priv->js2[JS2_tODTon_min] + 2);
/* DBTR12.TWRRD_S : WL + BL/2 + tWTR_S, TWRRD_L : WL + BL + tWTR_L */
dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(12),
@@ -3491,13 +3449,10 @@ static void dbsc5_manual_write_dca(struct udevice *dev)
{
struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
const u32 rank = priv->ch_have_this_cs[1] ? 0x2 : 0x1;
- u32 slv_dly_center[DRAM_CH_CNT][CS_CNT][SLICE_CNT];
- u32 slv_dly_center_cyc;
- u32 slv_dly_center_dly;
+ u32 phy_slv_dly[DRAM_CH_CNT][CS_CNT][SLICE_CNT];
+ u32 phy_slv_dly_avg[DRAM_CH_CNT][SLICE_CNT];
u32 slv_dly_min[DRAM_CH_CNT][SLICE_CNT];
u32 slv_dly_max[DRAM_CH_CNT][SLICE_CNT];
- u32 slv_dly_min_tmp[DRAM_CH_CNT][CS_CNT][SLICE_CNT];
- u32 slv_dly_max_tmp[DRAM_CH_CNT][CS_CNT][SLICE_CNT];
u32 phy_dcc_code_min[DRAM_CH_CNT][SLICE_CNT];
u32 phy_dcc_code_max[DRAM_CH_CNT][SLICE_CNT];
u32 phy_dcc_code_mid;
@@ -3521,18 +3476,9 @@ static void dbsc5_manual_write_dca(struct udevice *dev)
dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_INDEX, cs);
r_foreach_vch(dev, ch) {
for (slice = 0; slice < SLICE_CNT; slice++) {
- slv_dly_center[ch][cs][slice] =
- dbsc5_ddr_getval_slice(dev, ch, slice, PHY_CLK_WRDQS_SLAVE_DELAY);
- slv_dly_center_cyc = slv_dly_center[ch][cs][slice] & 0x180;
- slv_dly_center_dly = slv_dly_center[ch][cs][slice] & 0x7F;
- slv_dly_min_tmp[ch][cs][slice] =
- slv_dly_center_cyc |
- (slv_dly_center_dly * ratio_min / ratio_min_div);
- slv_dly_max_tmp[ch][cs][slice] = slv_dly_center_cyc;
- if ((slv_dly_center_dly * ratio_max) > (0x7F * ratio_max_div))
- slv_dly_max_tmp[ch][cs][slice] |= 0x7F;
- else
- slv_dly_max_tmp[ch][cs][slice] |= slv_dly_center_dly * ratio_max / ratio_max_div;
+ phy_slv_dly[ch][cs][slice] =
+ dbsc5_ddr_getval_slice(dev, ch, slice,
+ PHY_CLK_WRDQS_SLAVE_DELAY);
}
}
}
@@ -3540,22 +3486,22 @@ static void dbsc5_manual_write_dca(struct udevice *dev)
r_foreach_vch(dev, ch) {
for (slice = 0; slice < SLICE_CNT; slice++) {
if (rank == 0x2) {
- if (slv_dly_max_tmp[ch][0][slice] < slv_dly_max_tmp[ch][1][slice])
- slv_dly_max[ch][slice] = slv_dly_max_tmp[ch][1][slice];
- else
- slv_dly_max[ch][slice] = slv_dly_max_tmp[ch][0][slice];
-
- if (slv_dly_min_tmp[ch][0][slice] < slv_dly_min_tmp[ch][1][slice])
- slv_dly_min[ch][slice] = slv_dly_min_tmp[ch][0][slice];
- else
- slv_dly_min[ch][slice] = slv_dly_min_tmp[ch][1][slice];
+ /* Calculate average between ranks */
+ phy_slv_dly_avg[ch][slice] = (phy_slv_dly[ch][0][slice] +
+ phy_slv_dly[ch][1][slice]) / 2;
} else {
- slv_dly_max[ch][slice] = slv_dly_max_tmp[ch][0][slice];
- slv_dly_min[ch][slice] = slv_dly_min_tmp[ch][0][slice];
+ phy_slv_dly_avg[ch][slice] = phy_slv_dly[ch][0][slice];
}
+ /* Determine the search range */
+ slv_dly_min[ch][slice] = (phy_slv_dly_avg[ch][slice] & 0x07F) * ratio_min / ratio_min_div;
+ slv_dly_max[ch][slice] = (phy_slv_dly_avg[ch][slice] & 0x07F) * ratio_max / ratio_max_div;
+ if (slv_dly_max[ch][slice] > 0x7F)
+ slv_dly_max[ch][slice] = 0x7F;
}
}
+ dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_SLV_DLY_CTRL_GATE_DISABLE, 0x1);
+
for (i = 0; i <= 0x7F; i++) {
r_foreach_vch(dev, ch) {
for (slice = 0; slice < SLICE_CNT; slice++) {
@@ -3621,13 +3567,16 @@ static void dbsc5_manual_write_dca(struct udevice *dev)
for (slice = 0; slice < SLICE_CNT; slice++) {
dbsc5_ddr_setval_slice(dev, ch, slice,
PHY_CLK_WRDQS_SLAVE_DELAY,
- slv_dly_center[ch][cs][slice]);
+ phy_slv_dly[ch][cs][slice]);
dbsc5_ddr_setval_slice(dev, ch, slice,
SC_PHY_WCK_CALC, 0x1);
dbsc5_ddr_setval(dev, ch, SC_PHY_MANUAL_UPDATE, 0x1);
}
}
}
+
+ dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_SLV_DLY_CTRL_GATE_DISABLE, 0x0);
+
dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_MULTICAST_EN, 0x1);
r_foreach_vch(dev, ch) {
@@ -4369,16 +4318,20 @@ static int renesas_dbsc5_dram_probe(struct udevice *dev)
{
#define RST_MODEMR0 0x0
#define RST_MODEMR1 0x4
+#define OTP_MONITOR17 0x1144
struct renesas_dbsc5_data *data = (struct renesas_dbsc5_data *)dev_get_driver_data(dev);
ofnode cnode = ofnode_by_compatible(ofnode_null(), data->clock_node);
ofnode rnode = ofnode_by_compatible(ofnode_null(), data->reset_node);
+ ofnode onode = ofnode_by_compatible(ofnode_null(), data->otp_node);
struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
phys_addr_t rregs = ofnode_get_addr(rnode);
const u32 modemr0 = readl(rregs + RST_MODEMR0);
const u32 modemr1 = readl(rregs + RST_MODEMR1);
- u32 breg, reg, md, sscg;
+ phys_addr_t oregs = ofnode_get_addr(onode);
+ const u32 otpmon17 = readl(oregs + OTP_MONITOR17);
+ u32 breg, reg, md, sscg, product;
u32 ch, cs;
/* Get board data */
@@ -4433,29 +4386,41 @@ static int renesas_dbsc5_dram_probe(struct udevice *dev)
/* Decode DDR operating frequency from MD[37:36,19,17] pins */
md = ((modemr0 & BIT(19)) >> 18) | ((modemr0 & BIT(17)) >> 17);
+ product = otpmon17 & 0xff;
sscg = (modemr1 >> 4) & 0x03;
if (sscg == 2) {
printf("MD[37:36] setting 0x%x not supported!", sscg);
hang();
}
- if (md == 0) {
- if (sscg == 0) {
- priv->ddr_mbps = 6400;
- priv->ddr_mbpsdiv = 1;
- } else {
- priv->ddr_mbps = 19000;
- priv->ddr_mbpsdiv = 3;
- }
- } else if (md == 1) {
- priv->ddr_mbps = 6000;
- priv->ddr_mbpsdiv = 1;
- } else if (md == 1) {
- priv->ddr_mbps = 5500;
- priv->ddr_mbpsdiv = 1;
- } else if (md == 1) {
+ if (product == 0x2) { /* V4H-3 */
priv->ddr_mbps = 4800;
priv->ddr_mbpsdiv = 1;
+ } else if (product == 0x1) { /* V4H-5 */
+ if (md == 3)
+ priv->ddr_mbps = 4800;
+ else
+ priv->ddr_mbps = 5000;
+ priv->ddr_mbpsdiv = 1;
+ } else { /* V4H-7 */
+ if (md == 0) {
+ if (sscg == 0) {
+ priv->ddr_mbps = 6400;
+ priv->ddr_mbpsdiv = 1;
+ } else {
+ priv->ddr_mbps = 19000;
+ priv->ddr_mbpsdiv = 3;
+ }
+ } else if (md == 1) {
+ priv->ddr_mbps = 6000;
+ priv->ddr_mbpsdiv = 1;
+ } else if (md == 2) {
+ priv->ddr_mbps = 5500;
+ priv->ddr_mbpsdiv = 1;
+ } else if (md == 3) {
+ priv->ddr_mbps = 4800;
+ priv->ddr_mbpsdiv = 1;
+ }
}
priv->ddr_mul = CLK_DIV(priv->ddr_mbps, priv->ddr_mbpsdiv * 2,
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index fe5c1214f57..b408f19a20b 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -235,4 +235,20 @@ config RESET_AT91
This enables the Reset Controller driver support for Microchip/Atmel
SoCs. Mainly used to expose assert/deassert methods to other drivers
that require it.
+
+config RESET_RZG2L_USBPHY_CTRL
+ bool "Enable support for Renesas RZ/G2L USB 2.0 PHY control"
+ depends on DM_RESET
+ select REGULATOR_RZG2L_USBPHY
+ help
+ Enable support for controlling USB 2.0 PHY resets on the Renesas
+ RZ/G2L SoC. This is required for USB 2.0 functionality to work on this
+ SoC.
+
+config RESET_SPACEMIT_K1
+ bool "Support for SPACEMIT's K1 Reset driver"
+ depends on DM_RESET
+ help
+ Support for SPACEMIT's K1 Reset system. Basic Assert/Deassert
+ is supported.
endmenu
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index d99a78c9828..8cab734bdab 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -33,3 +33,5 @@ obj-$(CONFIG_RESET_ZYNQMP) += reset-zynqmp.o
obj-$(CONFIG_RESET_DRA7) += reset-dra7.o
obj-$(CONFIG_RESET_AT91) += reset-at91.o
obj-$(CONFIG_$(PHASE_)RESET_JH7110) += reset-jh7110.o
+obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
+obj-$(CONFIG_RESET_SPACEMIT_K1) += reset-spacemit-k1.o
diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
new file mode 100644
index 00000000000..622d7b9cf4f
--- /dev/null
+++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Renesas Electronics Corporation
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/device_compat.h>
+#include <dm/lists.h>
+#include <renesas/rzg2l-usbphy.h>
+#include <reset-uclass.h>
+#include <reset.h>
+
+#define RESET 0x000
+
+#define RESET_SEL_PLLRESET BIT(12)
+#define RESET_PLLRESET BIT(8)
+
+#define RESET_SEL_P2RESET BIT(5)
+#define RESET_SEL_P1RESET BIT(4)
+#define RESET_PHYRST_2 BIT(1)
+#define RESET_PHYRST_1 BIT(0)
+
+#define PHY_RESET_MASK (RESET_PHYRST_1 | RESET_PHYRST_2)
+
+#define NUM_PORTS 2
+
+static int rzg2l_usbphy_ctrl_assert(struct reset_ctl *reset_ctl)
+{
+ struct rzg2l_usbphy_ctrl_priv *priv = dev_get_priv(reset_ctl->dev);
+ u32 val;
+
+ val = readl(priv->regs + RESET);
+ val |= reset_ctl->id ? RESET_PHYRST_2 : RESET_PHYRST_1;
+
+ /* If both ports are in reset, we can also place the PLL into reset. */
+ if ((val & PHY_RESET_MASK) == PHY_RESET_MASK)
+ val |= RESET_PLLRESET;
+
+ writel(val, priv->regs + RESET);
+ return 0;
+}
+
+static int rzg2l_usbphy_ctrl_deassert(struct reset_ctl *reset_ctl)
+{
+ struct rzg2l_usbphy_ctrl_priv *priv = dev_get_priv(reset_ctl->dev);
+ u32 val = reset_ctl->id ? RESET_PHYRST_2 : RESET_PHYRST_1;
+
+ /* If either port is out of reset, the PLL must also be out of reset. */
+ val |= RESET_PLLRESET;
+
+ clrbits_le32(priv->regs + RESET, val);
+ return 0;
+}
+
+static int rzg2l_usbphy_ctrl_of_xlate(struct reset_ctl *reset_ctl,
+ struct ofnode_phandle_args *args)
+{
+ if (args->args[0] >= NUM_PORTS)
+ return -EINVAL;
+
+ reset_ctl->id = args->args[0];
+ return 0;
+}
+
+struct reset_ops rzg2l_usbphy_ctrl_ops = {
+ .rst_assert = rzg2l_usbphy_ctrl_assert,
+ .rst_deassert = rzg2l_usbphy_ctrl_deassert,
+ .of_xlate = rzg2l_usbphy_ctrl_of_xlate,
+};
+
+static int rzg2l_usbphy_ctrl_probe(struct udevice *dev)
+{
+ struct rzg2l_usbphy_ctrl_priv *priv = dev_get_priv(dev);
+ struct reset_ctl rst;
+ int ret;
+
+ priv->regs = dev_read_addr(dev);
+
+ ret = reset_get_by_index(dev, 0, &rst);
+ if (ret < 0) {
+ dev_err(dev, "failed to get reset line: %d\n", ret);
+ return ret;
+ }
+
+ ret = reset_deassert(&rst);
+ if (ret < 0) {
+ dev_err(dev, "failed to de-assert reset line: %d\n", ret);
+ return ret;
+ }
+
+ /* put pll and phy into reset state */
+ setbits_le32(priv->regs + RESET,
+ RESET_SEL_PLLRESET | RESET_PLLRESET |
+ RESET_SEL_P1RESET | RESET_PHYRST_1 |
+ RESET_SEL_P2RESET | RESET_PHYRST_2);
+
+ return 0;
+}
+
+static const struct udevice_id rzg2l_usbphy_ctrl_ids[] = {
+ { .compatible = "renesas,rzg2l-usbphy-ctrl", },
+ { /* sentinel */ }
+};
+
+static int rzg2l_usbphy_ctrl_bind(struct udevice *dev)
+{
+ struct driver *drv;
+ ofnode node;
+ int ret;
+
+ node = ofnode_find_subnode(dev_ofnode(dev), "regulator-vbus");
+ if (!ofnode_valid(node)) {
+ dev_err(dev, "Failed to find vbus regulator devicetree node\n");
+ return -ENOENT;
+ }
+
+ drv = lists_driver_lookup_name("rzg2l_usbphy_regulator");
+ if (!drv) {
+ dev_err(dev, "Failed to find vbus regulator driver\n");
+ return -ENOENT;
+ }
+
+ ret = device_bind(dev, drv, dev->name, NULL, node, NULL);
+ if (ret) {
+ dev_err(dev, "Failed to bind vbus regulator: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+U_BOOT_DRIVER(rzg2l_usbphy_ctrl) = {
+ .name = "rzg2l_usbphy_ctrl",
+ .id = UCLASS_RESET,
+ .of_match = rzg2l_usbphy_ctrl_ids,
+ .bind = rzg2l_usbphy_ctrl_bind,
+ .probe = rzg2l_usbphy_ctrl_probe,
+ .ops = &rzg2l_usbphy_ctrl_ops,
+ .priv_auto = sizeof(struct rzg2l_usbphy_ctrl_priv),
+};
diff --git a/drivers/reset/reset-spacemit-k1.c b/drivers/reset/reset-spacemit-k1.c
new file mode 100644
index 00000000000..613e002fc4f
--- /dev/null
+++ b/drivers/reset/reset-spacemit-k1.c
@@ -0,0 +1,548 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 Spacemit Inc.
+ * Copyright (C) 2025 Huan Zhou <pericycle.cc@gmail.com>
+ */
+
+#include <asm/io.h>
+#include <config.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dt-bindings/reset/spacemit-k1-reset.h>
+#include <linux/bitops.h>
+#include <reset-uclass.h>
+
+/* APBC register offset */
+#define APBC_UART1_CLK_RST 0x0
+#define APBC_UART2_CLK_RST 0x4
+#define APBC_GPIO_CLK_RST 0x8
+#define APBC_PWM0_CLK_RST 0xc
+#define APBC_PWM1_CLK_RST 0x10
+#define APBC_PWM2_CLK_RST 0x14
+#define APBC_PWM3_CLK_RST 0x18
+#define APBC_TWSI8_CLK_RST 0x20
+#define APBC_UART3_CLK_RST 0x24
+#define APBC_RTC_CLK_RST 0x28
+#define APBC_TWSI0_CLK_RST 0x2c
+#define APBC_TWSI1_CLK_RST 0x30
+#define APBC_TIMERS1_CLK_RST 0x34
+#define APBC_TWSI2_CLK_RST 0x38
+#define APBC_AIB_CLK_RST 0x3c
+#define APBC_TWSI4_CLK_RST 0x40
+#define APBC_TIMERS2_CLK_RST 0x44
+#define APBC_ONEWIRE_CLK_RST 0x48
+#define APBC_TWSI5_CLK_RST 0x4c
+#define APBC_DRO_CLK_RST 0x58
+#define APBC_IR_CLK_RST 0x5c
+#define APBC_TWSI6_CLK_RST 0x60
+#define APBC_TWSI7_CLK_RST 0x68
+#define APBC_TSEN_CLK_RST 0x6c
+
+#define APBC_UART4_CLK_RST 0x70
+#define APBC_UART5_CLK_RST 0x74
+#define APBC_UART6_CLK_RST 0x78
+#define APBC_SSP3_CLK_RST 0x7c
+
+#define APBC_SSPA0_CLK_RST 0x80
+#define APBC_SSPA1_CLK_RST 0x84
+
+#define APBC_IPC_AP2AUD_CLK_RST 0x90
+#define APBC_UART7_CLK_RST 0x94
+#define APBC_UART8_CLK_RST 0x98
+#define APBC_UART9_CLK_RST 0x9c
+
+#define APBC_CAN0_CLK_RST 0xa0
+#define APBC_PWM4_CLK_RST 0xa8
+#define APBC_PWM5_CLK_RST 0xac
+#define APBC_PWM6_CLK_RST 0xb0
+#define APBC_PWM7_CLK_RST 0xb4
+#define APBC_PWM8_CLK_RST 0xb8
+#define APBC_PWM9_CLK_RST 0xbc
+#define APBC_PWM10_CLK_RST 0xc0
+#define APBC_PWM11_CLK_RST 0xc4
+#define APBC_PWM12_CLK_RST 0xc8
+#define APBC_PWM13_CLK_RST 0xcc
+#define APBC_PWM14_CLK_RST 0xd0
+#define APBC_PWM15_CLK_RST 0xd4
+#define APBC_PWM16_CLK_RST 0xd8
+#define APBC_PWM17_CLK_RST 0xdc
+#define APBC_PWM18_CLK_RST 0xe0
+#define APBC_PWM19_CLK_RST 0xe4
+/* end of APBC register offset */
+
+/* MPMU register offset */
+#define MPMU_WDTPCR 0x200
+/* end of MPMU register offset */
+
+/* APMU register offset */
+#define APMU_JPG_CLK_RES_CTRL 0x20
+#define APMU_CSI_CCIC2_CLK_RES_CTRL 0x24
+#define APMU_ISP_CLK_RES_CTRL 0x38
+#define APMU_LCD_CLK_RES_CTRL1 0x44
+#define APMU_LCD_SPI_CLK_RES_CTRL 0x48
+#define APMU_LCD_CLK_RES_CTRL2 0x4c
+#define APMU_CCIC_CLK_RES_CTRL 0x50
+#define APMU_SDH0_CLK_RES_CTRL 0x54
+#define APMU_SDH1_CLK_RES_CTRL 0x58
+#define APMU_USB_CLK_RES_CTRL 0x5c
+#define APMU_QSPI_CLK_RES_CTRL 0x60
+#define APMU_USB_CLK_RES_CTRL 0x5c
+#define APMU_DMA_CLK_RES_CTRL 0x64
+#define APMU_AES_CLK_RES_CTRL 0x68
+#define APMU_VPU_CLK_RES_CTRL 0xa4
+#define APMU_GPU_CLK_RES_CTRL 0xcc
+#define APMU_SDH2_CLK_RES_CTRL 0xe0
+#define APMU_PMUA_MC_CTRL 0xe8
+#define APMU_PMU_CC2_AP 0x100
+#define APMU_PMUA_EM_CLK_RES_CTRL 0x104
+
+#define APMU_AUDIO_CLK_RES_CTRL 0x14c
+#define APMU_HDMI_CLK_RES_CTRL 0x1B8
+
+#define APMU_PCIE_CLK_RES_CTRL_0 0x3cc
+#define APMU_PCIE_CLK_RES_CTRL_1 0x3d4
+#define APMU_PCIE_CLK_RES_CTRL_2 0x3dc
+
+#define APMU_EMAC0_CLK_RES_CTRL 0x3e4
+#define APMU_EMAC1_CLK_RES_CTRL 0x3ec
+/* end of APMU register offset */
+
+/* APBC2 register offset */
+#define APBC2_UART1_CLK_RST 0x00
+#define APBC2_SSP2_CLK_RST 0x04
+#define APBC2_TWSI3_CLK_RST 0x08
+#define APBC2_RTC_CLK_RST 0x0c
+#define APBC2_TIMERS0_CLK_RST 0x10
+#define APBC2_KPC_CLK_RST 0x14
+#define APBC2_GPIO_CLK_RST 0x1c
+/* end of APBC2 register offset */
+
+enum spacemit_reset_base_type {
+ RST_BASE_TYPE_MPMU = 0,
+ RST_BASE_TYPE_APMU = 1,
+ RST_BASE_TYPE_APBC = 2,
+ RST_BASE_TYPE_APBS = 3,
+ RST_BASE_TYPE_CIU = 4,
+ RST_BASE_TYPE_DCIU = 5,
+ RST_BASE_TYPE_DDRC = 6,
+ RST_BASE_TYPE_AUDC = 7,
+ RST_BASE_TYPE_APBC2 = 8,
+};
+
+struct spacemit_reset_signal {
+ u32 offset;
+ u32 mask;
+ u32 deassert_val;
+ u32 assert_val;
+ enum spacemit_reset_base_type type;
+};
+
+struct spacemit_reset_base {
+ void __iomem *mpmu_base;
+ void __iomem *apmu_base;
+ void __iomem *apbc_base;
+ void __iomem *apbs_base;
+ void __iomem *ciu_base;
+ void __iomem *dciu_base;
+ void __iomem *ddrc_base;
+ void __iomem *audio_ctrl_base;
+ void __iomem *apbc2_base;
+};
+
+struct spacemit_reset {
+ struct spacemit_reset_base io_base;
+ const struct spacemit_reset_signal *signals;
+};
+
+enum {
+ RESET_TWSI6_SPL = 0,
+ RESET_TWSI8_SPL,
+ RESET_SDH_AXI_SPL,
+ RESET_SDH0_SPL,
+ RESET_USB_AXI_SPL,
+ RESET_USBP1_AXI_SPL,
+ RESET_USB3_0_SPL,
+ RESET_QSPI_SPL,
+ RESET_QSPI_BUS_SPL,
+ RESET_AES_SPL,
+ RESET_SDH2_SPL,
+ RESET_NUMBER_SPL
+};
+
+static const struct spacemit_reset_signal
+ k1_reset_signals[RESET_NUMBER] = {
+ [RESET_UART1] = { APBC_UART1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_UART2] = { APBC_UART2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_GPIO] = { APBC_GPIO_CLK_RST, BIT(2), 0,
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM0] = { APBC_PWM0_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM1] = { APBC_PWM1_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM2] = { APBC_PWM2_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM3] = { APBC_PWM3_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM4] = { APBC_PWM4_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM5] = { APBC_PWM5_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM6] = { APBC_PWM6_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM7] = { APBC_PWM7_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM8] = { APBC_PWM8_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM9] = { APBC_PWM9_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM10] = { APBC_PWM10_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM11] = { APBC_PWM11_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM12] = { APBC_PWM12_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM13] = { APBC_PWM13_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM14] = { APBC_PWM14_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM15] = { APBC_PWM15_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM16] = { APBC_PWM16_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM17] = { APBC_PWM17_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM18] = { APBC_PWM18_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_PWM19] = { APBC_PWM19_CLK_RST,
+ BIT(2) | BIT(0),
+ BIT(0),
+ BIT(2),
+ RST_BASE_TYPE_APBC },
+ [RESET_SSP3] = { APBC_SSP3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_UART3] = { APBC_UART3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_RTC] = { APBC_RTC_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_TWSI0] = { APBC_TWSI0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_TIMERS1] = { APBC_TIMERS1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_AIB] = { APBC_AIB_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_TIMERS2] = { APBC_TIMERS2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_ONEWIRE] = { APBC_ONEWIRE_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_SSPA0] = { APBC_SSPA0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_SSPA1] = { APBC_SSPA1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_DRO] = { APBC_DRO_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_IR] = { APBC_IR_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_TWSI1] = { APBC_TWSI1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_TSEN] = { APBC_TSEN_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_TWSI2] = { APBC_TWSI2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_TWSI4] = { APBC_TWSI4_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_TWSI5] = { APBC_TWSI5_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_TWSI6] = { APBC_TWSI6_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_TWSI7] = { APBC_TWSI7_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_TWSI8] = { APBC_TWSI8_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_IPC_AP2AUD] = { APBC_IPC_AP2AUD_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_UART4] = { APBC_UART4_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_UART5] = { APBC_UART5_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_UART6] = { APBC_UART6_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_UART7] = { APBC_UART7_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_UART8] = { APBC_UART8_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_UART9] = { APBC_UART9_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ [RESET_CAN0] = { APBC_CAN0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
+ /* MPMU */
+ [RESET_WDT] = { MPMU_WDTPCR, BIT(2), 0, BIT(2), RST_BASE_TYPE_MPMU },
+ /* APMU */
+ [RESET_JPG] = { APMU_JPG_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
+ [RESET_CSI] = { APMU_CSI_CCIC2_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
+ [RESET_CCIC2_PHY] = { APMU_CSI_CCIC2_CLK_RES_CTRL,
+ BIT(2),
+ BIT(2),
+ 0,
+ RST_BASE_TYPE_APMU },
+ [RESET_CCIC3_PHY] = { APMU_CSI_CCIC2_CLK_RES_CTRL,
+ BIT(29),
+ BIT(29),
+ 0,
+ RST_BASE_TYPE_APMU },
+ [RESET_ISP] = { APMU_ISP_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
+ [RESET_ISP_AHB] = { APMU_ISP_CLK_RES_CTRL, BIT(3), BIT(3), 0, RST_BASE_TYPE_APMU },
+ [RESET_ISP_CI] = { APMU_ISP_CLK_RES_CTRL, BIT(16), BIT(16), 0, RST_BASE_TYPE_APMU },
+ [RESET_ISP_CPP] = { APMU_ISP_CLK_RES_CTRL, BIT(27), BIT(27), 0, RST_BASE_TYPE_APMU },
+ [RESET_LCD] = { APMU_LCD_CLK_RES_CTRL1, BIT(4), BIT(4), 0, RST_BASE_TYPE_APMU },
+ [RESET_DSI_ESC] = { APMU_LCD_CLK_RES_CTRL1, BIT(3), BIT(3), 0, RST_BASE_TYPE_APMU },
+ [RESET_V2D] = { APMU_LCD_CLK_RES_CTRL1, BIT(27), BIT(27), 0, RST_BASE_TYPE_APMU },
+ [RESET_MIPI] = { APMU_LCD_CLK_RES_CTRL1, BIT(15), BIT(15), 0, RST_BASE_TYPE_APMU },
+ [RESET_LCD_SPI] = { APMU_LCD_SPI_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
+ [RESET_LCD_SPI_BUS] = { APMU_LCD_SPI_CLK_RES_CTRL,
+ BIT(4),
+ BIT(4),
+ 0,
+ RST_BASE_TYPE_APMU },
+ [RESET_LCD_SPI_HBUS] = { APMU_LCD_SPI_CLK_RES_CTRL,
+ BIT(2),
+ BIT(2),
+ 0,
+ RST_BASE_TYPE_APMU },
+ [RESET_LCD_MCLK] = { APMU_LCD_CLK_RES_CTRL2, BIT(9), BIT(9), 0, RST_BASE_TYPE_APMU },
+ [RESET_CCIC_4X] = { APMU_CCIC_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
+ [RESET_CCIC1_PHY] = { APMU_CCIC_CLK_RES_CTRL, BIT(2), BIT(2), 0, RST_BASE_TYPE_APMU },
+ [RESET_SDH_AXI] = { APMU_SDH0_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
+ [RESET_SDH0] = { APMU_SDH0_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
+ [RESET_SDH1] = { APMU_SDH1_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
+ [RESET_USB_AXI] = { APMU_USB_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
+ [RESET_USBP1_AXI] = { APMU_USB_CLK_RES_CTRL, BIT(4), BIT(4), 0, RST_BASE_TYPE_APMU },
+ [RESET_USB3_0] = { APMU_USB_CLK_RES_CTRL,
+ BIT(9) | BIT(10) | BIT(11),
+ BIT(9) | BIT(10) | BIT(11),
+ 0,
+ RST_BASE_TYPE_APMU },
+ [RESET_QSPI] = { APMU_QSPI_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
+ [RESET_QSPI_BUS] = { APMU_QSPI_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
+ [RESET_DMA] = { APMU_DMA_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
+ [RESET_AES] = { APMU_AES_CLK_RES_CTRL, BIT(4), BIT(4), 0, RST_BASE_TYPE_APMU },
+ [RESET_VPU] = { APMU_VPU_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
+ [RESET_GPU] = { APMU_GPU_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
+ [RESET_SDH2] = { APMU_SDH2_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
+ [RESET_MC] = { APMU_PMUA_MC_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
+ [RESET_EM_AXI] = { APMU_PMUA_EM_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
+ [RESET_EM] = { APMU_PMUA_EM_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
+ [RESET_AUDIO_SYS] = { APMU_AUDIO_CLK_RES_CTRL,
+ BIT(0) | BIT(2) | BIT(3),
+ BIT(0) | BIT(2) | BIT(3),
+ 0,
+ RST_BASE_TYPE_APMU },
+ [RESET_HDMI] = { APMU_HDMI_CLK_RES_CTRL, BIT(9), BIT(9), 0, RST_BASE_TYPE_APMU },
+ [RESET_PCIE0] = { APMU_PCIE_CLK_RES_CTRL_0,
+ BIT(3) | BIT(4) | BIT(5) | BIT(8),
+ BIT(3) | BIT(4) | BIT(5),
+ BIT(8),
+ RST_BASE_TYPE_APMU },
+ [RESET_PCIE1] = { APMU_PCIE_CLK_RES_CTRL_1,
+ BIT(3) | BIT(4) | BIT(5) | BIT(8),
+ BIT(3) | BIT(4) | BIT(5),
+ BIT(8),
+ RST_BASE_TYPE_APMU },
+ [RESET_PCIE2] = { APMU_PCIE_CLK_RES_CTRL_2, 0x138, 0x38, 0x100, RST_BASE_TYPE_APMU },
+ [RESET_EMAC0] = { APMU_EMAC0_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
+ [RESET_EMAC1] = { APMU_EMAC1_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
+ [RESET_SEC_UART1] = { APBC2_UART1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
+ [RESET_SEC_SSP2] = { APBC2_SSP2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
+ [RESET_SEC_TWSI3] = { APBC2_TWSI3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
+ [RESET_SEC_RTC] = { APBC2_RTC_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
+ [RESET_SEC_TIMERS0] = { APBC2_TIMERS0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
+ [RESET_SEC_KPC] = { APBC2_KPC_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
+ [RESET_SEC_GPIO] = { APBC2_GPIO_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
+ };
+
+static u32 spacemit_reset_read(struct spacemit_reset *reset, u32 id)
+{
+ void __iomem *base;
+
+ switch (reset->signals[id].type) {
+ case RST_BASE_TYPE_APMU:
+ base = reset->io_base.apmu_base;
+ break;
+ case RST_BASE_TYPE_APBC:
+ base = reset->io_base.apbc_base;
+ break;
+ default:
+ base = reset->io_base.apbc_base;
+ break;
+ }
+
+ return readl(base + reset->signals[id].offset);
+}
+
+static void spacemit_reset_write(struct spacemit_reset *reset, u32 value, u32 id)
+{
+ void __iomem *base;
+
+ switch (reset->signals[id].type) {
+ case RST_BASE_TYPE_APMU:
+ base = reset->io_base.apmu_base;
+ break;
+ case RST_BASE_TYPE_APBC:
+ base = reset->io_base.apbc_base;
+ break;
+ default:
+ base = reset->io_base.apbc_base;
+ break;
+ }
+
+ writel(value, base + reset->signals[id].offset);
+}
+
+static void spacemit_reset_set(struct reset_ctl *rst, u32 id, bool assert)
+{
+ u32 value;
+ struct spacemit_reset *reset = dev_get_priv(rst->dev);
+
+ value = spacemit_reset_read(reset, id);
+
+ if (assert) {
+ value &= ~reset->signals[id].mask;
+ value |= reset->signals[id].assert_val;
+ } else {
+ value &= ~reset->signals[id].mask;
+ value |= reset->signals[id].deassert_val;
+ }
+
+ spacemit_reset_write(reset, value, id);
+}
+
+static int spacemit_reset_update(struct reset_ctl *rst, bool assert)
+{
+ if (rst->id < RESET_UART1 || rst->id >= RESET_NUMBER)
+ return 0;
+
+ /* can not write to twsi8 */
+ if (rst->id == RESET_TWSI8)
+ return 0;
+
+ spacemit_reset_set(rst, rst->id, assert);
+ return 0;
+}
+
+static int spacemit_reset_assert(struct reset_ctl *rst)
+{
+ return spacemit_reset_update(rst, true);
+}
+
+static int spacemit_reset_deassert(struct reset_ctl *rst)
+{
+ return spacemit_reset_update(rst, false);
+}
+
+static int spacemit_k1_reset_probe(struct udevice *dev)
+{
+ struct spacemit_reset *reset = dev_get_priv(dev);
+
+ reset->io_base.mpmu_base = (void *)dev_remap_addr_index(dev, 0);
+ if (!reset->io_base.mpmu_base) {
+ pr_err("failed to map mpmu registers\n");
+ goto out;
+ }
+
+ reset->io_base.apmu_base = (void *)dev_remap_addr_index(dev, 1);
+ if (!reset->io_base.apmu_base) {
+ pr_err("failed to map apmu registers\n");
+ goto out;
+ }
+
+ reset->io_base.apbc_base = (void *)dev_remap_addr_index(dev, 2);
+ if (!reset->io_base.apbc_base) {
+ pr_err("failed to map apbc registers\n");
+ goto out;
+ }
+
+ reset->io_base.apbs_base = (void *)dev_remap_addr_index(dev, 3);
+ if (!reset->io_base.apbs_base) {
+ pr_err("failed to map apbs registers\n");
+ goto out;
+ }
+
+ reset->io_base.ciu_base = (void *)dev_remap_addr_index(dev, 4);
+ if (!reset->io_base.ciu_base) {
+ pr_err("failed to map ciu registers\n");
+ goto out;
+ }
+
+ reset->io_base.dciu_base = (void *)dev_remap_addr_index(dev, 5);
+ if (!reset->io_base.dciu_base) {
+ pr_err("failed to map dragon ciu registers\n");
+ goto out;
+ }
+
+ reset->io_base.ddrc_base = (void *)dev_remap_addr_index(dev, 6);
+ if (!reset->io_base.ddrc_base) {
+ pr_err("failed to map ddrc registers\n");
+ goto out;
+ }
+
+ reset->io_base.apbc2_base = (void *)dev_remap_addr_index(dev, 7);
+ if (!reset->io_base.apbc2_base) {
+ pr_err("failed to map apbc2 registers\n");
+ goto out;
+ }
+
+ reset->signals = k1_reset_signals;
+
+out:
+ return 0;
+}
+
+const struct reset_ops k1_reset_ops = {
+ .rst_assert = spacemit_reset_assert,
+ .rst_deassert = spacemit_reset_deassert,
+};
+
+static const struct udevice_id k1_reset_ids[] = {
+ { .compatible = "spacemit,k1-reset", },
+ {},
+};
+
+U_BOOT_DRIVER(k1_reset) = {
+ .name = "spacemit,k1-reset",
+ .id = UCLASS_RESET,
+ .ops = &k1_reset_ops,
+ .of_match = k1_reset_ids,
+ .probe = spacemit_k1_reset_probe,
+ .priv_auto = sizeof(struct spacemit_reset),
+};
diff --git a/drivers/rng/msm_rng.c b/drivers/rng/msm_rng.c
index f790d3b60f9..aab602c5ed0 100644
--- a/drivers/rng/msm_rng.c
+++ b/drivers/rng/msm_rng.c
@@ -44,6 +44,11 @@ static int msm_rng_read(struct udevice *dev, void *data, size_t len)
u32 *retdata = data;
size_t maxsize;
u32 val;
+ int ret;
+
+ ret = clk_enable(&priv->clk);
+ if (ret < 0)
+ return ret;
/* calculate max size bytes to transfer back to caller */
maxsize = min_t(size_t, MAX_HW_FIFO_SIZE, len);
@@ -66,6 +71,8 @@ static int msm_rng_read(struct udevice *dev, void *data, size_t len)
break;
} while (currsize < maxsize);
+ clk_disable(&priv->clk);
+
return 0;
}
@@ -76,7 +83,7 @@ static int msm_rng_enable(struct msm_rng_priv *priv, int enable)
if (enable) {
/* Enable PRNG only if it is not already enabled */
val = readl_relaxed(priv->base + PRNG_CONFIG);
- if (val & PRNG_CONFIG_HW_ENABLE) {
+ if (!(val & PRNG_CONFIG_HW_ENABLE)) {
val = readl_relaxed(priv->base + PRNG_LFSR_CFG);
val &= ~PRNG_LFSR_CFG_MASK;
val |= PRNG_LFSR_CFG_CLOCKS;
@@ -118,7 +125,9 @@ static int msm_rng_probe(struct udevice *dev)
if (ret < 0)
return ret;
- return msm_rng_enable(priv, 1);
+ ret = msm_rng_enable(priv, 1);
+ clk_disable(&priv->clk);
+ return ret;
}
static int msm_rng_remove(struct udevice *dev)
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index 121194e4418..475540ffac7 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -242,7 +242,6 @@ config SYSRESET_RAA215300
config SYSRESET_QCOM_PSHOLD
bool "Support sysreset for Qualcomm SoCs via PSHOLD"
- depends on ARCH_IPQ40XX
help
Add support for the system reboot on Qualcomm SoCs via PSHOLD.
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index e5a383407a2..477ecd02098 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1631,8 +1631,25 @@ usb_ep *dwc3_gadget_match_ep(struct usb_gadget *gadget,
return dwc3_find_ep(gadget, "ep1in");
if (usb_endpoint_is_bulk_out(desc))
return dwc3_find_ep(gadget, "ep2out");
- if (usb_endpoint_is_int_in(desc))
+ if (usb_endpoint_is_int_in(desc)) {
+ /*
+ * Special workaround for NXP UUU tool in SPL.
+ *
+ * The tool excepts the interrupt-in endpoint to be ep1in,
+ * otherwise it crashes. This is a result of the previous
+ * hard-coded EP setup in drivers/usb/gadget/epautoconf.c
+ * which did special-case EP allocation for SPL builds,
+ * and which was since converted to this callback, but
+ * without the special-case EP allocation in SPL part.
+ *
+ * This reinstates the SPL part in an isolated manner,
+ * only for NXP iMX SoCs, only for SPL builds, and only
+ * for the ep1in interrupt-in endpoint.
+ */
+ if (IS_ENABLED(CONFIG_MACH_IMX) && IS_ENABLED(CONFIG_XPL_BUILD))
+ return dwc3_find_ep(gadget, "ep1in");
return dwc3_find_ep(gadget, "ep3in");
+ }
return NULL;
}
diff --git a/fs/fs.c b/fs/fs.c
index 30a8e5010f2..cda85a20188 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -574,7 +574,7 @@ static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset,
lmb_dump_all();
- if (lmb_alloc_addr(addr, read_len, LMB_NONE) == addr)
+ if (!lmb_alloc_addr(addr, read_len, LMB_NONE))
return 0;
log_err("** Reading file would overwrite reserved memory **\n");
diff --git a/include/configs/sifive-unleashed.h b/include/configs/sifive-unleashed.h
index 2996b375723..cd8d0438ba6 100644
--- a/include/configs/sifive-unleashed.h
+++ b/include/configs/sifive-unleashed.h
@@ -11,7 +11,6 @@
#include <linux/sizes.h>
-#define CFG_SYS_SDRAM_BASE 0x80000000
#define RISCV_MMODE_TIMERBASE 0x2000000
#define RISCV_MMODE_TIMEROFF 0xbff8
diff --git a/include/configs/sifive-unmatched.h b/include/configs/sifive-unmatched.h
index 27e0912665b..e0064edc5c9 100644
--- a/include/configs/sifive-unmatched.h
+++ b/include/configs/sifive-unmatched.h
@@ -11,6 +11,5 @@
#include <linux/sizes.h>
-#define CFG_SYS_SDRAM_BASE 0x80000000
#endif /* __SIFIVE_UNMATCHED_H */
diff --git a/include/dbsc5.h b/include/dbsc5.h
new file mode 100644
index 00000000000..cec937d89e7
--- /dev/null
+++ b/include/dbsc5.h
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024-2025 Renesas Electronics Corp.
+ */
+
+#ifndef __INCLUDE_DBSC5_H__
+#define __INCLUDE_DBSC5_H__
+
+/* The number of channels V4H has */
+#define DRAM_CH_CNT 4
+/* The number of slices V4H has */
+#define SLICE_CNT 2
+/* The number of chip select V4H has */
+#define CS_CNT 2
+
+struct renesas_dbsc5_board_config {
+ /* Channels in use */
+ u8 bdcfg_phyvalid;
+ /* Read vref (SoC) training range */
+ u32 bdcfg_vref_r;
+ /* Write vref (MR14, MR15) training range */
+ u16 bdcfg_vref_w;
+ /* CA vref (MR12) training range */
+ u16 bdcfg_vref_ca;
+ /* RFM required check */
+ bool bdcfg_rfm_chk;
+
+ /* Board parameter about channels */
+ struct {
+ /*
+ * 0x00: 4Gb dual channel die / 2Gb single channel die
+ * 0x01: 6Gb dual channel die / 3Gb single channel die
+ * 0x02: 8Gb dual channel die / 4Gb single channel die
+ * 0x03: 12Gb dual channel die / 6Gb single channel die
+ * 0x04: 16Gb dual channel die / 8Gb single channel die
+ * 0x05: 24Gb dual channel die / 12Gb single channel die
+ * 0x06: 32Gb dual channel die / 16Gb single channel die
+ * 0x07: 24Gb single channel die
+ * 0x08: 32Gb single channel die
+ * 0xFF: NO_MEMORY
+ */
+ u8 bdcfg_ddr_density[CS_CNT];
+ /* SoC caX([6][5][4][3][2][1][0]) -> MEM caY: */
+ u32 bdcfg_ca_swap;
+ /* SoC dqsX([1][0]) -> MEM dqsY: */
+ u8 bdcfg_dqs_swap;
+ /* SoC dq([7][6][5][4][3][2][1][0]) -> MEM dqY/dm: (8 means DM) */
+ u32 bdcfg_dq_swap[SLICE_CNT];
+ /* SoC dm -> MEM dqY/dm: (8 means DM) */
+ u8 bdcfg_dm_swap[SLICE_CNT];
+ /* SoC ckeX([1][0]) -> MEM csY */
+ u8 bdcfg_cs_swap;
+ } ch[4];
+};
+
+#endif /* __INCLUDE_DBSC5_H__ */
diff --git a/include/dt-bindings/reset/spacemit-k1-reset.h b/include/dt-bindings/reset/spacemit-k1-reset.h
new file mode 100644
index 00000000000..74db58b27ef
--- /dev/null
+++ b/include/dt-bindings/reset/spacemit-k1-reset.h
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2022 Spacemit Inc.
+ * Copyright (C) 2025 Huan Zhou <pericycle.cc@gmail.com>
+ */
+
+#ifndef __DT_BINDINGS_RESET_SAPCEMIT_K1_H__
+#define __DT_BINDINGS_RESET_SAPCEMIT_K1_H__
+/* APBC */
+#define RESET_UART1 1
+#define RESET_UART2 2
+#define RESET_GPIO 3
+#define RESET_PWM0 4
+#define RESET_PWM1 5
+#define RESET_PWM2 6
+#define RESET_PWM3 7
+#define RESET_PWM4 8
+#define RESET_PWM5 9
+#define RESET_PWM6 10
+#define RESET_PWM7 11
+#define RESET_PWM8 12
+#define RESET_PWM9 13
+#define RESET_PWM10 14
+#define RESET_PWM11 15
+#define RESET_PWM12 16
+#define RESET_PWM13 17
+#define RESET_PWM14 18
+#define RESET_PWM15 19
+#define RESET_PWM16 20
+#define RESET_PWM17 21
+#define RESET_PWM18 22
+#define RESET_PWM19 23
+#define RESET_SSP3 24
+#define RESET_UART3 25
+#define RESET_RTC 26
+#define RESET_TWSI0 27
+#define RESET_TIMERS1 28
+#define RESET_AIB 29
+#define RESET_TIMERS2 30
+#define RESET_ONEWIRE 31
+#define RESET_SSPA0 32
+#define RESET_SSPA1 33
+#define RESET_DRO 34
+#define RESET_IR 35
+#define RESET_TWSI1 36
+#define RESET_TSEN 37
+#define RESET_TWSI2 38
+#define RESET_TWSI4 39
+#define RESET_TWSI5 40
+#define RESET_TWSI6 41
+#define RESET_TWSI7 42
+#define RESET_TWSI8 43
+#define RESET_IPC_AP2AUD 44
+#define RESET_UART4 45
+#define RESET_UART5 46
+#define RESET_UART6 47
+#define RESET_UART7 48
+#define RESET_UART8 49
+#define RESET_UART9 50
+#define RESET_CAN0 51
+
+/* MPMU */
+#define RESET_WDT 52
+
+/* APMU */
+#define RESET_JPG 53
+#define RESET_CSI 54
+#define RESET_CCIC2_PHY 55
+#define RESET_CCIC3_PHY 56
+#define RESET_ISP 57
+#define RESET_ISP_AHB 58
+#define RESET_ISP_CI 59
+#define RESET_ISP_CPP 60
+#define RESET_LCD 61
+#define RESET_DSI_ESC 62
+#define RESET_V2D 63
+#define RESET_MIPI 64
+#define RESET_LCD_SPI 65
+#define RESET_LCD_SPI_BUS 66
+#define RESET_LCD_SPI_HBUS 67
+#define RESET_LCD_MCLK 68
+#define RESET_CCIC_4X 69
+#define RESET_CCIC1_PHY 70
+#define RESET_SDH_AXI 71
+#define RESET_SDH0 72
+#define RESET_SDH1 73
+#define RESET_USB_AXI 74
+#define RESET_USBP1_AXI 75
+#define RESET_USB3_0 76
+#define RESET_QSPI 77
+#define RESET_QSPI_BUS 78
+#define RESET_DMA 79
+#define RESET_AES 80
+#define RESET_VPU 81
+#define RESET_GPU 82
+#define RESET_SDH2 83
+#define RESET_MC 84
+#define RESET_EM_AXI 85
+#define RESET_EM 86
+#define RESET_AUDIO_SYS 87
+#define RESET_HDMI 88
+#define RESET_PCIE0 89
+#define RESET_PCIE1 90
+#define RESET_PCIE2 91
+#define RESET_EMAC0 92
+#define RESET_EMAC1 93
+
+/* APBC2 */
+#define RESET_SEC_UART1 94
+#define RESET_SEC_SSP2 95
+#define RESET_SEC_TWSI3 96
+#define RESET_SEC_RTC 97
+#define RESET_SEC_TIMERS0 98
+#define RESET_SEC_KPC 99
+#define RESET_SEC_GPIO 100
+#define RESET_NUMBER 101
+
+#endif
diff --git a/include/lmb.h b/include/lmb.h
index 09297a4f530..0d316c64c0a 100644
--- a/include/lmb.h
+++ b/include/lmb.h
@@ -135,9 +135,9 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr,
* parameter. The base parameter is used to specify the base address
* of the requested region.
*
- * Return: Base address on success, 0 on error.
+ * Return: 0 on success -1 on error
*/
-phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags);
+int lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags);
/**
* lmb_is_reserved_flags() - Test if address is in reserved region with flag
@@ -175,7 +175,7 @@ void lmb_pop(struct lmb *store);
static inline int lmb_read_check(phys_addr_t addr, phys_size_t len)
{
- return lmb_alloc_addr(addr, len, LMB_NONE) == addr ? 0 : -1;
+ return lmb_alloc_addr(addr, len, LMB_NONE);
}
/**
diff --git a/include/phy.h b/include/phy.h
index 36785031eeb..36354aaf774 100644
--- a/include/phy.h
+++ b/include/phy.h
@@ -334,6 +334,30 @@ int gen10g_shutdown(struct phy_device *phydev);
int gen10g_discover_mmds(struct phy_device *phydev);
/**
+ * phy_set_bits - Convenience function for setting bits in a PHY register
+ * @phydev: the phy_device struct
+ * @devad: The MMD to read from
+ * @regnum: register number to write
+ * @val: bits to set
+ */
+static inline int phy_set_bits(struct phy_device *phydev, int devad, u32 regnum, u16 val)
+{
+ return phy_modify(phydev, devad, regnum, 0, val);
+}
+
+/**
+ * phy_clear_bits - Convenience function for clearing bits in a PHY register
+ * @phydev: the phy_device struct
+ * @devad: The MMD to write to
+ * @regnum: register number to write
+ * @val: bits to clear
+ */
+static inline int phy_clear_bits(struct phy_device *phydev, int devad, u32 regnum, u16 val)
+{
+ return phy_modify(phydev, devad, regnum, val, 0);
+}
+
+/**
* U_BOOT_PHY_DRIVER() - Declare a new U-Boot driver
* @__name: name of the driver
*/
diff --git a/include/renesas/rzg2l-usbphy.h b/include/renesas/rzg2l-usbphy.h
new file mode 100644
index 00000000000..1a46b585f17
--- /dev/null
+++ b/include/renesas/rzg2l-usbphy.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * RZ/G2L USB PHY common definitions
+ *
+ * Copyright (C) 2021-2023 Renesas Electronics Corp.
+ */
+
+#ifndef RENESAS_RZG2L_USBPHY_H
+#define RENESAS_RZG2L_USBPHY_H
+
+#include <fdtdec.h>
+
+struct rzg2l_usbphy_ctrl_priv {
+ fdt_addr_t regs;
+};
+
+#endif /* RENESAS_RZG2L_USBPHY_H */
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 6d00b186250..c39b53922bb 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -491,8 +491,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
return EFI_NOT_FOUND;
addr = map_to_sysmem((void *)(uintptr_t)*memory);
- addr = (u64)lmb_alloc_addr(addr, len, flags);
- if (!addr)
+ if (lmb_alloc_addr(addr, len, flags))
return EFI_NOT_FOUND;
break;
default:
diff --git a/lib/efi_loader/elf_efi.ldsi b/lib/efi_loader/elf_efi.ldsi
index 190a88fb69e..4fa5ca43872 100644
--- a/lib/efi_loader/elf_efi.ldsi
+++ b/lib/efi_loader/elf_efi.ldsi
@@ -21,10 +21,10 @@ SECTIONS
*(.gnu.linkonce.t.*)
*(.srodata)
*(.rodata*)
- . = ALIGN(16);
- *(.dynamic);
- . = ALIGN(512);
}
+ . = ALIGN(16);
+ .dynamic : { *(.dynamic) }
+ . = ALIGN(512);
.rela.dyn : { *(.rela.dyn) }
.rela.plt : { *(.rela.plt) }
.rela.got : { *(.rela.got) }
diff --git a/lib/lmb.c b/lib/lmb.c
index 981ea1b2ca0..bb6f232f6bc 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -742,7 +742,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr,
return _lmb_alloc_base(size, align, max_addr, flags);
}
-phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags)
+int lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags)
{
long rgn;
struct lmb_region *lmb_memory = lmb.available_mem.data;
@@ -759,11 +759,11 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags)
base + size - 1, 1)) {
/* ok, reserve the memory */
if (!lmb_reserve(base, size, flags))
- return base;
+ return 0;
}
}
- return 0;
+ return -1;
}
/* Return number of bytes from a given address that are free */
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 18993435eae..275c308154b 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -513,8 +513,8 @@ $(obj)/%_efi.S: $(obj)/%.efi
$(call cmd,S_efi)
quiet_cmd_efi_objcopy = OBJCOPY $@
-cmd_efi_objcopy = $(OBJCOPY) -j .header -j .text -j .sdata -j .data -j \
- .dynamic -j .dynsym -j .rel* -j .rela* -j .reloc \
+cmd_efi_objcopy = $(OBJCOPY) -j .header -j .text -j .sdata -j .data \
+ -j .dynamic -j .dynstr -j .dynsym -j .rel* -j .reloc \
$(if $(EFI_TARGET),$(EFI_TARGET),-O binary) $^ $@
$(obj)/%.efi: $(obj)/%_efi.so
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index f9f8891c0c4..414019c5b89 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2692,6 +2692,12 @@ sub u_boot_line {
ERROR("PRE_SCHEMA",
"Driver model schema uses 'bootph-...' tags now\n" . $herecurr);
}
+
+ # Do not allow CONFIG_xPL_BUILD in device trees
+ if ($realfile =~ /\.dtsi?$/ && $line =~ /^\+.*CONFIG_(X|S|T|V)PL_BUILD.*/) {
+ ERROR("CONFIG_xPL_BUILD",
+ "Do not use CONFIG_xPL_BUILD in device trees\n" . $herecurr);
+ }
}
sub exclude_global_initialisers {
diff --git a/scripts/event_dump.py b/scripts/event_dump.py
index 24dfe2bda91..61bb3a8eb92 100755
--- a/scripts/event_dump.py
+++ b/scripts/event_dump.py
@@ -107,7 +107,7 @@ def main(argv):
Args:
argv (list of str): List of program arguments, excluding arvg[0]
"""
- epilog = 'Show a list of even spies in a U-Boot EFL file'
+ epilog = 'Show a list of event spies in a U-Boot ELF file'
parser = ArgumentParser(epilog=epilog)
parser.add_argument('elf', type=str, help='ELF file to decode')
parser.add_argument('-e', '--endian', type=str, default='auto',
diff --git a/test/lib/lmb.c b/test/lib/lmb.c
index 24416e83491..ad916740d90 100644
--- a/test/lib/lmb.c
+++ b/test/lib/lmb.c
@@ -566,21 +566,21 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
/* Try to allocate a page twice */
b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE);
- ut_asserteq(b, alloc_addr_a);
- b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE);
ut_asserteq(b, 0);
+ b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE);
+ ut_asserteq(b, -1);
b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE);
- ut_asserteq(b, alloc_addr_a);
+ ut_asserteq(b, 0);
b = lmb_alloc_addr(alloc_addr_a, 0x2000, LMB_NONE);
- ut_asserteq(b, alloc_addr_a);
+ ut_asserteq(b, 0);
ret = lmb_free(alloc_addr_a, 0x2000);
ut_asserteq(ret, 0);
b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE);
- ut_asserteq(b, alloc_addr_a);
- b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE);
ut_asserteq(b, 0);
+ b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE);
+ ut_asserteq(b, -1);
b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE);
- ut_asserteq(b, 0);
+ ut_asserteq(b, -1);
ret = lmb_free(alloc_addr_a, 0x1000);
ut_asserteq(ret, 0);
@@ -667,22 +667,22 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
/* allocate blocks */
a = lmb_alloc_addr(ram, alloc_addr_a - ram, LMB_NONE);
- ut_asserteq(a, ram);
+ ut_asserteq(a, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 3, ram, 0x8010000,
alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
b = lmb_alloc_addr(alloc_addr_a + 0x10000,
alloc_addr_b - alloc_addr_a - 0x10000, LMB_NONE);
- ut_asserteq(b, alloc_addr_a + 0x10000);
+ ut_asserteq(b, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 0x10010000,
alloc_addr_c, 0x10000, 0, 0);
c = lmb_alloc_addr(alloc_addr_b + 0x10000,
alloc_addr_c - alloc_addr_b - 0x10000, LMB_NONE);
- ut_asserteq(c, alloc_addr_b + 0x10000);
+ ut_asserteq(c, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000,
0, 0, 0, 0);
d = lmb_alloc_addr(alloc_addr_c + 0x10000,
ram_end - alloc_addr_c - 0x10000, LMB_NONE);
- ut_asserteq(d, alloc_addr_c + 0x10000);
+ ut_asserteq(d, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, ram_size,
0, 0, 0, 0);
@@ -692,57 +692,58 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, ram_size,
0, 0, 0, 0);
- ret = lmb_free(d, ram_end - alloc_addr_c - 0x10000);
+ /* free thge allocation from d */
+ ret = lmb_free(alloc_addr_c + 0x10000, ram_end - alloc_addr_c - 0x10000);
ut_asserteq(ret, 0);
/* allocate at 3 points in free range */
d = lmb_alloc_addr(ram_end - 4, 4, LMB_NONE);
- ut_asserteq(d, ram_end - 4);
+ ut_asserteq(d, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 0x18010000,
- d, 4, 0, 0);
- ret = lmb_free(d, 4);
+ ram_end - 4, 4, 0, 0);
+ ret = lmb_free(ram_end - 4, 4);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000,
0, 0, 0, 0);
d = lmb_alloc_addr(ram_end - 128, 4, LMB_NONE);
- ut_asserteq(d, ram_end - 128);
+ ut_asserteq(d, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 0x18010000,
- d, 4, 0, 0);
- ret = lmb_free(d, 4);
+ ram_end - 128, 4, 0, 0);
+ ret = lmb_free(ram_end - 128, 4);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000,
0, 0, 0, 0);
d = lmb_alloc_addr(alloc_addr_c + 0x10000, 4, LMB_NONE);
- ut_asserteq(d, alloc_addr_c + 0x10000);
+ ut_asserteq(d, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010004,
0, 0, 0, 0);
- ret = lmb_free(d, 4);
+ ret = lmb_free(alloc_addr_c + 0x10000, 4);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000,
0, 0, 0, 0);
- /* allocate at the bottom */
- ret = lmb_free(a, alloc_addr_a - ram);
+ /* allocate at the bottom a was assigned to ram at the top */
+ ret = lmb_free(ram, alloc_addr_a - ram);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram + 0x8000000,
0x10010000, 0, 0, 0, 0);
d = lmb_alloc_addr(ram, 4, LMB_NONE);
- ut_asserteq(d, ram);
- ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, d, 4,
+ ut_asserteq(d, 0);
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 4,
ram + 0x8000000, 0x10010000, 0, 0);
/* check that allocating outside memory fails */
if (ram_end != 0) {
ret = lmb_alloc_addr(ram_end, 1, LMB_NONE);
- ut_asserteq(ret, 0);
+ ut_asserteq(ret, -1);
}
if (ram != 0) {
ret = lmb_alloc_addr(ram - 1, 1, LMB_NONE);
- ut_asserteq(ret, 0);
+ ut_asserteq(ret, -1);
}
lmb_pop(&store);
diff --git a/tools/qconfig.py b/tools/qconfig.py
index 259adbe1bc9..c96a305a48f 100755
--- a/tools/qconfig.py
+++ b/tools/qconfig.py
@@ -1453,7 +1453,7 @@ def do_scan_source(path, do_update):
print('\nCONFIG options used as Proper in Makefiles but without a non-xPL_ variant:')
not_found = check_not_found(all_uses, MODE_PROPER)
show_uses(not_found)
- proper_not_found |= {not_found.keys()}
+ proper_not_found |= not_found.keys()
# Scan the source code
all_uses, _ = scan_src_files(src_list)
@@ -1471,7 +1471,7 @@ def do_scan_source(path, do_update):
print('\nCONFIG options used as Proper in source but without a non-xPL_ variant:')
not_found = check_not_found(all_uses, MODE_PROPER)
show_uses(not_found)
- proper_not_found |= {not_found.keys()}
+ proper_not_found |= not_found.keys()
print('\nCONFIG options used as SPL but without an xPL_ variant:')
for item in sorted(spl_not_found):
diff --git a/tools/sfspl.c b/tools/sfspl.c
index c76420ce21b..516e96e8dd9 100644
--- a/tools/sfspl.c
+++ b/tools/sfspl.c
@@ -70,11 +70,14 @@ static int sfspl_verify_header(unsigned char *buf, int size,
printf("Truncated file\n");
return EXIT_FAILURE;
}
+ if ((size_t)size > hdr_size + file_size)
+ printf("File too long, expected %u bytes\n",
+ hdr_size + file_size);
if (hdr->version != DEFAULT_VERSION) {
printf("Unknown file format version\n");
return EXIT_FAILURE;
}
- crc_check = crc32(0, &buf[hdr_size], size - hdr_size);
+ crc_check = crc32(0, &buf[hdr_size], file_size);
if (crc_check != crc) {
printf("Incorrect CRC32\n");
return EXIT_FAILURE;