From 41d7f6744894a464785fa4589a648f1151685978 Mon Sep 17 00:00:00 2001 From: Ayan Kumar Halder Date: Wed, 22 Jun 2022 10:26:57 +0200 Subject: [PATCH 01/48] xilinx: Remove the legacy property "#stream-id-cells" "#stream-id-cells" was being used with "mmu-masters" for Xen specific device trees. With Xen commit 2278d2cbb0b7c1b48b298c6c4c6a7de2271ac928 (Link below) Xen is able to support smmu bindings in both formats ie : 1. Using iommus (linux format) 2. Using mmu-masters (legacy format). Thus, "#stream-id-cells" which was used for the legacy format, can be removed as Xen can use smmu bindings in linux format. Link: https://www.mail-archive.com/xen-devel@lists.xenproject.org/msg101649.html Signed-off-by: Ayan Kumar Halder Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/1e062acb233dee47cd7dd2429cb482132617cbc8.1655886415.git.michal.simek@amd.com --- arch/arm/dts/versal-mini-emmc0.dts | 1 - arch/arm/dts/versal-mini-emmc1.dts | 1 - arch/arm/dts/zynqmp.dtsi | 28 ---------------------------- 3 files changed, 30 deletions(-) diff --git a/arch/arm/dts/versal-mini-emmc0.dts b/arch/arm/dts/versal-mini-emmc0.dts index 6a6e7467a23..7c81a82fb92 100644 --- a/arch/arm/dts/versal-mini-emmc0.dts +++ b/arch/arm/dts/versal-mini-emmc0.dts @@ -47,7 +47,6 @@ xlnx,device_id = <0>; no-1-8-v; xlnx,mio-bank = <0>; - #stream-id-cells = <1>; }; }; diff --git a/arch/arm/dts/versal-mini-emmc1.dts b/arch/arm/dts/versal-mini-emmc1.dts index c342e6bdf7a..bf7569d4cca 100644 --- a/arch/arm/dts/versal-mini-emmc1.dts +++ b/arch/arm/dts/versal-mini-emmc1.dts @@ -47,7 +47,6 @@ xlnx,device_id = <1>; no-1-8-v; xlnx,mio-bank = <0>; - #stream-id-cells = <1>; }; }; diff --git a/arch/arm/dts/zynqmp.dtsi b/arch/arm/dts/zynqmp.dtsi index dae8f0669df..fbc6e752da9 100644 --- a/arch/arm/dts/zynqmp.dtsi +++ b/arch/arm/dts/zynqmp.dtsi @@ -281,7 +281,6 @@ interrupts = <0 124 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <128>; - #stream-id-cells = <1>; iommus = <&smmu 0x14e8>; power-domains = <&zynqmp_firmware PD_GDMA>; #dma-cells = <1>; @@ -295,7 +294,6 @@ interrupts = <0 125 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <128>; - #stream-id-cells = <1>; iommus = <&smmu 0x14e9>; power-domains = <&zynqmp_firmware PD_GDMA>; #dma-cells = <1>; @@ -309,7 +307,6 @@ interrupts = <0 126 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <128>; - #stream-id-cells = <1>; iommus = <&smmu 0x14ea>; power-domains = <&zynqmp_firmware PD_GDMA>; #dma-cells = <1>; @@ -323,7 +320,6 @@ interrupts = <0 127 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <128>; - #stream-id-cells = <1>; iommus = <&smmu 0x14eb>; power-domains = <&zynqmp_firmware PD_GDMA>; #dma-cells = <1>; @@ -337,7 +333,6 @@ interrupts = <0 128 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <128>; - #stream-id-cells = <1>; iommus = <&smmu 0x14ec>; power-domains = <&zynqmp_firmware PD_GDMA>; #dma-cells = <1>; @@ -351,7 +346,6 @@ interrupts = <0 129 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <128>; - #stream-id-cells = <1>; iommus = <&smmu 0x14ed>; power-domains = <&zynqmp_firmware PD_GDMA>; #dma-cells = <1>; @@ -365,7 +359,6 @@ interrupts = <0 130 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <128>; - #stream-id-cells = <1>; iommus = <&smmu 0x14ee>; power-domains = <&zynqmp_firmware PD_GDMA>; #dma-cells = <1>; @@ -379,7 +372,6 @@ interrupts = <0 131 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <128>; - #stream-id-cells = <1>; iommus = <&smmu 0x14ef>; power-domains = <&zynqmp_firmware PD_GDMA>; #dma-cells = <1>; @@ -420,7 +412,6 @@ interrupts = <0 77 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <64>; - #stream-id-cells = <1>; iommus = <&smmu 0x868>; power-domains = <&zynqmp_firmware PD_ADMA>; #dma-cells = <1>; @@ -434,7 +425,6 @@ interrupts = <0 78 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <64>; - #stream-id-cells = <1>; iommus = <&smmu 0x869>; power-domains = <&zynqmp_firmware PD_ADMA>; #dma-cells = <1>; @@ -448,7 +438,6 @@ interrupts = <0 79 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <64>; - #stream-id-cells = <1>; iommus = <&smmu 0x86a>; power-domains = <&zynqmp_firmware PD_ADMA>; #dma-cells = <1>; @@ -462,7 +451,6 @@ interrupts = <0 80 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <64>; - #stream-id-cells = <1>; iommus = <&smmu 0x86b>; power-domains = <&zynqmp_firmware PD_ADMA>; #dma-cells = <1>; @@ -476,7 +464,6 @@ interrupts = <0 81 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <64>; - #stream-id-cells = <1>; iommus = <&smmu 0x86c>; power-domains = <&zynqmp_firmware PD_ADMA>; #dma-cells = <1>; @@ -490,7 +477,6 @@ interrupts = <0 82 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <64>; - #stream-id-cells = <1>; iommus = <&smmu 0x86d>; power-domains = <&zynqmp_firmware PD_ADMA>; #dma-cells = <1>; @@ -504,7 +490,6 @@ interrupts = <0 83 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <64>; - #stream-id-cells = <1>; iommus = <&smmu 0x86e>; power-domains = <&zynqmp_firmware PD_ADMA>; #dma-cells = <1>; @@ -518,7 +503,6 @@ interrupts = <0 84 4>; clock-names = "clk_main", "clk_apb"; xlnx,bus-width = <64>; - #stream-id-cells = <1>; iommus = <&smmu 0x86f>; power-domains = <&zynqmp_firmware PD_ADMA>; #dma-cells = <1>; @@ -540,7 +524,6 @@ interrupts = <0 14 4>; #address-cells = <1>; #size-cells = <0>; - #stream-id-cells = <1>; iommus = <&smmu 0x872>; power-domains = <&zynqmp_firmware PD_NAND>; }; @@ -554,7 +537,6 @@ clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk"; #address-cells = <1>; #size-cells = <0>; - #stream-id-cells = <1>; iommus = <&smmu 0x874>; power-domains = <&zynqmp_firmware PD_ETH_0>; resets = <&zynqmp_reset ZYNQMP_RESET_GEM0>; @@ -569,7 +551,6 @@ clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk"; #address-cells = <1>; #size-cells = <0>; - #stream-id-cells = <1>; iommus = <&smmu 0x875>; power-domains = <&zynqmp_firmware PD_ETH_1>; resets = <&zynqmp_reset ZYNQMP_RESET_GEM1>; @@ -584,7 +565,6 @@ clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk"; #address-cells = <1>; #size-cells = <0>; - #stream-id-cells = <1>; iommus = <&smmu 0x876>; power-domains = <&zynqmp_firmware PD_ETH_2>; resets = <&zynqmp_reset ZYNQMP_RESET_GEM2>; @@ -599,7 +579,6 @@ clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk"; #address-cells = <1>; #size-cells = <0>; - #stream-id-cells = <1>; iommus = <&smmu 0x877>; power-domains = <&zynqmp_firmware PD_ETH_3>; resets = <&zynqmp_reset ZYNQMP_RESET_GEM3>; @@ -676,7 +655,6 @@ <0x0 0x0 0x0 0x2 &pcie_intc 0x2>, <0x0 0x0 0x0 0x3 &pcie_intc 0x3>, <0x0 0x0 0x0 0x4 &pcie_intc 0x4>; - #stream-id-cells = <1>; iommus = <&smmu 0x4d0>; power-domains = <&zynqmp_firmware PD_PCIE>; pcie_intc: legacy-interrupt-controller { @@ -698,7 +676,6 @@ <0x0 0xc0000000 0x0 0x8000000>; #address-cells = <1>; #size-cells = <0>; - #stream-id-cells = <1>; iommus = <&smmu 0x873>; power-domains = <&zynqmp_firmware PD_QSPI>; }; @@ -730,7 +707,6 @@ interrupts = <0 133 4>; power-domains = <&zynqmp_firmware PD_SATA>; resets = <&zynqmp_reset ZYNQMP_RESET_SATA>; - #stream-id-cells = <4>; iommus = <&smmu 0x4c0>, <&smmu 0x4c1>, <&smmu 0x4c2>, <&smmu 0x4c3>; /* dma-coherent; */ @@ -745,7 +721,6 @@ reg = <0x0 0xff160000 0x0 0x1000>; clock-names = "clk_xin", "clk_ahb"; xlnx,device_id = <0>; - #stream-id-cells = <1>; iommus = <&smmu 0x870>; #clock-cells = <1>; clock-output-names = "clk_out_sd0", "clk_in_sd0"; @@ -762,7 +737,6 @@ reg = <0x0 0xff170000 0x0 0x1000>; clock-names = "clk_xin", "clk_ahb"; xlnx,device_id = <1>; - #stream-id-cells = <1>; iommus = <&smmu 0x871>; #clock-cells = <1>; clock-output-names = "clk_out_sd1", "clk_in_sd1"; @@ -892,7 +866,6 @@ interrupt-parent = <&gic>; interrupt-names = "dwc_usb3", "otg", "hiber"; interrupts = <0 65 4>, <0 69 4>, <0 75 4>; - #stream-id-cells = <1>; iommus = <&smmu 0x860>; snps,quirk-frame-length-adjustment = <0x20>; snps,refclk_fladj; @@ -924,7 +897,6 @@ interrupt-parent = <&gic>; interrupt-names = "dwc_usb3", "otg", "hiber"; interrupts = <0 70 4>, <0 74 4>, <0 76 4>; - #stream-id-cells = <1>; iommus = <&smmu 0x861>; snps,quirk-frame-length-adjustment = <0x20>; snps,refclk_fladj; From 156cb2af92c244fae15c8fbdab293d88d451edcf Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 29 Jun 2022 11:13:14 +0200 Subject: [PATCH 02/48] arm64: zynqmp: Used fixed-partitions for QSPI in k26 Using fixed partitions is recommended way how to describe QSPI. Also add label for qspi flash memory to be able to reference it in future. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/a84f7ce8d6472fce66539ba29d31fbaae511d94b.1655732762.git.michal.simek@amd.com --- arch/arm/dts/zynqmp-sm-k26-revA.dts | 163 +++++++++++++++------------- 1 file changed, 85 insertions(+), 78 deletions(-) diff --git a/arch/arm/dts/zynqmp-sm-k26-revA.dts b/arch/arm/dts/zynqmp-sm-k26-revA.dts index 7c2bfa395da..ac349a9dcc5 100644 --- a/arch/arm/dts/zynqmp-sm-k26-revA.dts +++ b/arch/arm/dts/zynqmp-sm-k26-revA.dts @@ -130,7 +130,7 @@ &qspi { /* MIO 0-5 - U143 */ status = "okay"; - flash@0 { /* MT25QU512A */ + spi_flash: flash@0 { /* MT25QU512A */ compatible = "mt25qu512a", "jedec,spi-nor"; /* 64MB */ #address-cells = <1>; #size-cells = <1>; @@ -138,83 +138,90 @@ spi-tx-bus-width = <4>; spi-rx-bus-width = <4>; spi-max-frequency = <40000000>; /* 40MHz */ - partition@0 { - label = "Image Selector"; - reg = <0x0 0x80000>; /* 512KB */ - read-only; - lock; - }; - partition@80000 { - label = "Image Selector Golden"; - reg = <0x80000 0x80000>; /* 512KB */ - read-only; - lock; - }; - partition@100000 { - label = "Persistent Register"; - reg = <0x100000 0x20000>; /* 128KB */ - }; - partition@120000 { - label = "Persistent Register Backup"; - reg = <0x120000 0x20000>; /* 128KB */ - }; - partition@140000 { - label = "Open_1"; - reg = <0x140000 0xC0000>; /* 768KB */ - }; - partition@200000 { - label = "Image A (FSBL, PMU, ATF, U-Boot)"; - reg = <0x200000 0xD00000>; /* 13MB */ - }; - partition@f00000 { - label = "ImgSel Image A Catch"; - reg = <0xF00000 0x80000>; /* 512KB */ - read-only; - lock; - }; - partition@f80000 { - label = "Image B (FSBL, PMU, ATF, U-Boot)"; - reg = <0xF80000 0xD00000>; /* 13MB */ - }; - partition@1c80000 { - label = "ImgSel Image B Catch"; - reg = <0x1C80000 0x80000>; /* 512KB */ - read-only; - lock; - }; - partition@1d00000 { - label = "Open_2"; - reg = <0x1D00000 0x100000>; /* 1MB */ - }; - partition@1e00000 { - label = "Recovery Image"; - reg = <0x1E00000 0x200000>; /* 2MB */ - read-only; - lock; - }; - partition@2000000 { - label = "Recovery Image Backup"; - reg = <0x2000000 0x200000>; /* 2MB */ - read-only; - lock; - }; - partition@2200000 { - label = "U-Boot storage variables"; - reg = <0x2200000 0x20000>; /* 128KB */ - }; - partition@2220000 { - label = "U-Boot storage variables backup"; - reg = <0x2220000 0x20000>; /* 128KB */ - }; - partition@2240000 { - label = "SHA256"; - reg = <0x2240000 0x10000>; /* 256B but 64KB sector */ - read-only; - lock; - }; - partition@2250000 { - label = "User"; - reg = <0x2250000 0x1db0000>; /* 29.5 MB */ + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Image Selector"; + reg = <0x0 0x80000>; /* 512KB */ + read-only; + lock; + }; + partition@80000 { + label = "Image Selector Golden"; + reg = <0x80000 0x80000>; /* 512KB */ + read-only; + lock; + }; + partition@100000 { + label = "Persistent Register"; + reg = <0x100000 0x20000>; /* 128KB */ + }; + partition@120000 { + label = "Persistent Register Backup"; + reg = <0x120000 0x20000>; /* 128KB */ + }; + partition@140000 { + label = "Open_1"; + reg = <0x140000 0xC0000>; /* 768KB */ + }; + partition@200000 { + label = "Image A (FSBL, PMU, ATF, U-Boot)"; + reg = <0x200000 0xD00000>; /* 13MB */ + }; + partition@f00000 { + label = "ImgSel Image A Catch"; + reg = <0xF00000 0x80000>; /* 512KB */ + read-only; + lock; + }; + partition@f80000 { + label = "Image B (FSBL, PMU, ATF, U-Boot)"; + reg = <0xF80000 0xD00000>; /* 13MB */ + }; + partition@1c80000 { + label = "ImgSel Image B Catch"; + reg = <0x1C80000 0x80000>; /* 512KB */ + read-only; + lock; + }; + partition@1d00000 { + label = "Open_2"; + reg = <0x1D00000 0x100000>; /* 1MB */ + }; + partition@1e00000 { + label = "Recovery Image"; + reg = <0x1E00000 0x200000>; /* 2MB */ + read-only; + lock; + }; + partition@2000000 { + label = "Recovery Image Backup"; + reg = <0x2000000 0x200000>; /* 2MB */ + read-only; + lock; + }; + partition@2200000 { + label = "U-Boot storage variables"; + reg = <0x2200000 0x20000>; /* 128KB */ + }; + partition@2220000 { + label = "U-Boot storage variables backup"; + reg = <0x2220000 0x20000>; /* 128KB */ + }; + partition@2240000 { + label = "SHA256"; + reg = <0x2240000 0x10000>; /* 256B but 64KB sector */ + read-only; + lock; + }; + partition@2250000 { + label = "User"; + reg = <0x2250000 0x1db0000>; /* 29.5 MB */ + }; }; }; }; From 71f07731488e9ade674ee396208317ab2db3cce1 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Mon, 27 Jun 2022 14:22:45 +0530 Subject: [PATCH 03/48] mmc: zynq_sdhci: Fix timing macros for MMC High speed Timing macro's are wrong for MMC_HS_52 and MMC_DDR_52. Fix it with correct values of MMC_TIMING_MMC_HS and MMC_TIMING_MMC_DDR52 respectively. Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/1656319965-12124-1-git-send-email-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- drivers/mmc/zynq_sdhci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index e978b679885..8f4071c8c28 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -101,8 +101,8 @@ static const u8 mode2timing[] = { [MMC_LEGACY] = MMC_TIMING_LEGACY, [MMC_HS] = MMC_TIMING_MMC_HS, [SD_HS] = MMC_TIMING_SD_HS, - [MMC_HS_52] = MMC_TIMING_UHS_SDR50, - [MMC_DDR_52] = MMC_TIMING_UHS_DDR50, + [MMC_HS_52] = MMC_TIMING_MMC_HS, + [MMC_DDR_52] = MMC_TIMING_MMC_DDR52, [UHS_SDR12] = MMC_TIMING_UHS_SDR12, [UHS_SDR25] = MMC_TIMING_UHS_SDR25, [UHS_SDR50] = MMC_TIMING_UHS_SDR50, From 5e0e1a86d327d0e3330aee737559dd15a3b27bd7 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Fri, 15 Jul 2022 01:40:25 -0500 Subject: [PATCH 04/48] tools: relocate-rela: Fix ELF decoding on big-endian hosts The new ELF decoding logic assumed that the target binary has the same endianness as the host, which broke building ARM64 firmware binaries on big-endian machines. This commit fixes the ELF64 decoding to be host-endianness-neutral, and applies the same changes to the ELF32 decoding. It does not fix the microblaze-specific dynamic symbol decoding. It also corrects the functions used for byte swapping in rela_elf64() and rela_elf32(). The result is the same, but semantically the code is converting bytes read from a foreign-endianness file to host byte order. Fixes: 4c9e2d643460 ("tools: relocate-rela: Read rela start/end directly from ELF") Fixes: a1405d9cfedb ("tools: relocate-rela: Check that relocation works only for EM_AARCH64") Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20220715064026.54551-1-samuel@sholland.org Signed-off-by: Michal Simek --- tools/relocate-rela.c | 125 +++++++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 57 deletions(-) diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index 090fb1acb20..fcf3fb201f0 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -60,7 +60,9 @@ static int decode_elf64(FILE *felf, char **argv) { size_t size; Elf64_Ehdr header; - uint64_t section_header_base, section_header_size, sh_offset, sh_size; + uint64_t section_header_base, section_header_size; + uint64_t sh_addr, sh_offset, sh_size; + Elf64_Half sh_index, sh_num; Elf64_Shdr *sh_table; /* Elf symbol table */ int ret, i, machine; char *sh_str; @@ -76,7 +78,7 @@ static int decode_elf64(FILE *felf, char **argv) return 25; } - machine = header.e_machine; + machine = le16_to_cpu(header.e_machine); debug("Machine\t%d\n", machine); if (machine != EM_AARCH64) { @@ -84,9 +86,10 @@ static int decode_elf64(FILE *felf, char **argv) return 30; } - text_base = header.e_entry; - section_header_base = header.e_shoff; - section_header_size = header.e_shentsize * header.e_shnum; + text_base = le64_to_cpu(header.e_entry); + section_header_base = le64_to_cpu(header.e_shoff); + section_header_size = le16_to_cpu(header.e_shentsize) * + le16_to_cpu(header.e_shnum); sh_table = malloc(section_header_size); if (!sh_table) { @@ -114,9 +117,9 @@ static int decode_elf64(FILE *felf, char **argv) return 27; } - sh_size = sh_table[header.e_shstrndx].sh_size; - debug("e_shstrndx\t0x%08x\n", header.e_shstrndx); - debug("sh_size\t\t0x%08lx\n", sh_size); + sh_index = le16_to_cpu(header.e_shstrndx); + sh_size = le64_to_cpu(sh_table[sh_index].sh_size); + debug("e_shstrndx %x, sh_size %lx\n", sh_index, sh_size); sh_str = malloc(sh_size); if (!sh_str) { @@ -130,9 +133,8 @@ static int decode_elf64(FILE *felf, char **argv) * Specifies the byte offset from the beginning of the file * to the first byte in the section. */ - sh_offset = sh_table[header.e_shstrndx].sh_offset; - - debug("sh_offset\t0x%08x\n", header.e_shnum); + sh_offset = le64_to_cpu(sh_table[sh_index].sh_offset); + sh_num = le16_to_cpu(header.e_shnum); ret = fseek(felf, sh_offset, SEEK_SET); if (ret) { @@ -153,18 +155,22 @@ static int decode_elf64(FILE *felf, char **argv) return 30; } - for (i = 0; i < header.e_shnum; i++) { - /* fprintf(stderr, "%s\n", sh_str + sh_table[i].sh_name); Debug only */ - if (!strcmp(".rela.dyn", (sh_str + sh_table[i].sh_name))) { + for (i = 0; i < sh_num; i++) { + char *sh_name = sh_str + le32_to_cpu(sh_table[i].sh_name); + + debug("%s\n", sh_name); + + sh_addr = le64_to_cpu(sh_table[i].sh_addr); + sh_offset = le64_to_cpu(sh_table[i].sh_offset); + sh_size = le64_to_cpu(sh_table[i].sh_size); + + if (!strcmp(".rela.dyn", sh_name)) { debug("Found section\t\".rela_dyn\"\n"); - debug(" at addr\t0x%08x\n", - (unsigned int)sh_table[i].sh_addr); - debug(" at offset\t0x%08x\n", - (unsigned int)sh_table[i].sh_offset); - debug(" of size\t0x%08x\n", - (unsigned int)sh_table[i].sh_size); - rela_start = sh_table[i].sh_addr; - rela_end = rela_start + sh_table[i].sh_size; + debug(" at addr\t0x%08x\n", sh_addr); + debug(" at offset\t0x%08x\n", sh_offset); + debug(" of size\t0x%08x\n", sh_size); + rela_start = sh_addr; + rela_end = rela_start + sh_size; break; } } @@ -188,7 +194,9 @@ static int decode_elf32(FILE *felf, char **argv) { size_t size; Elf32_Ehdr header; - uint64_t section_header_base, section_header_size, sh_offset, sh_size; + uint64_t section_header_base, section_header_size; + uint32_t sh_addr, sh_offset, sh_size; + Elf32_Half sh_index, sh_num; Elf32_Shdr *sh_table; /* Elf symbol table */ int ret, i, machine; char *sh_str; @@ -204,7 +212,7 @@ static int decode_elf32(FILE *felf, char **argv) return 25; } - machine = header.e_machine; + machine = le16_to_cpu(header.e_machine); debug("Machine %d\n", machine); if (machine != EM_MICROBLAZE) { @@ -212,14 +220,10 @@ static int decode_elf32(FILE *felf, char **argv) return 30; } - text_base = header.e_entry; - section_header_base = header.e_shoff; - - debug("Section header base %x\n", section_header_base); - - section_header_size = header.e_shentsize * header.e_shnum; - - debug("Section header size %d\n", section_header_size); + text_base = le32_to_cpu(header.e_entry); + section_header_base = le32_to_cpu(header.e_shoff); + section_header_size = le16_to_cpu(header.e_shentsize) * + le16_to_cpu(header.e_shnum); sh_table = malloc(section_header_size); if (!sh_table) { @@ -247,8 +251,9 @@ static int decode_elf32(FILE *felf, char **argv) return 27; } - sh_size = sh_table[header.e_shstrndx].sh_size; - debug("e_shstrndx %x, sh_size %lx\n", header.e_shstrndx, sh_size); + sh_index = le16_to_cpu(header.e_shstrndx); + sh_size = le32_to_cpu(sh_table[sh_index].sh_size); + debug("e_shstrndx %x, sh_size %lx\n", sh_index, sh_size); sh_str = malloc(sh_size); if (!sh_str) { @@ -262,9 +267,8 @@ static int decode_elf32(FILE *felf, char **argv) * Specifies the byte offset from the beginning of the file * to the first byte in the section. */ - sh_offset = sh_table[header.e_shstrndx].sh_offset; - - debug("sh_offset %x\n", header.e_shnum); + sh_offset = le32_to_cpu(sh_table[sh_index].sh_offset); + sh_num = le16_to_cpu(header.e_shnum); ret = fseek(felf, sh_offset, SEEK_SET); if (ret) { @@ -277,7 +281,7 @@ static int decode_elf32(FILE *felf, char **argv) size = fread(sh_str, 1, sh_size, felf); if (size != sh_size) { - fprintf(stderr, "%s: Can't read section: %lx/%lx\n", + fprintf(stderr, "%s: Can't read section: %lx/%x\n", argv[0], size, sh_size); free(sh_str); free(sh_table); @@ -285,22 +289,29 @@ static int decode_elf32(FILE *felf, char **argv) return 30; } - for (i = 0; i < header.e_shnum; i++) { - debug("%s\n", sh_str + sh_table[i].sh_name); - if (!strcmp(".rela.dyn", (sh_str + sh_table[i].sh_name))) { + for (i = 0; i < sh_num; i++) { + char *sh_name = sh_str + le32_to_cpu(sh_table[i].sh_name); + + debug("%s\n", sh_name); + + sh_addr = le64_to_cpu(sh_table[i].sh_addr); + sh_offset = le64_to_cpu(sh_table[i].sh_offset); + sh_size = le64_to_cpu(sh_table[i].sh_size); + + if (!strcmp(".rela.dyn", sh_name)) { debug("Found section\t\".rela_dyn\"\n"); - debug(" at addr\t0x%08x\n", (unsigned int)sh_table[i].sh_addr); - debug(" at offset\t0x%08x\n", (unsigned int)sh_table[i].sh_offset); - debug(" of size\t0x%08x\n", (unsigned int)sh_table[i].sh_size); - rela_start = sh_table[i].sh_addr; - rela_end = rela_start + sh_table[i].sh_size; + debug(" at addr\t0x%08x\n", sh_addr); + debug(" at offset\t0x%08x\n", sh_offset); + debug(" of size\t0x%08x\n", sh_size); + rela_start = sh_addr; + rela_end = rela_start + sh_size; } - if (!strcmp(".dynsym", (sh_str + sh_table[i].sh_name))) { + if (!strcmp(".dynsym", sh_name)) { debug("Found section\t\".dynsym\"\n"); - debug(" at addr\t0x%08x\n", (unsigned int)sh_table[i].sh_addr); - debug(" at offset\t0x%08x\n", (unsigned int)sh_table[i].sh_offset); - debug(" of size\t0x%08x\n", (unsigned int)sh_table[i].sh_size); - dyn_start = sh_table[i].sh_addr; + debug(" at addr\t0x%08x\n", sh_addr); + debug(" at offset\t0x%08x\n", sh_offset); + debug(" of size\t0x%08x\n", sh_size); + dyn_start = sh_addr; } } @@ -386,9 +397,9 @@ static int rela_elf64(char **argv, FILE *f) return 4; } - swrela.r_offset = cpu_to_le64(rela.r_offset); - swrela.r_info = cpu_to_le64(rela.r_info); - swrela.r_addend = cpu_to_le64(rela.r_addend); + swrela.r_offset = le64_to_cpu(rela.r_offset); + swrela.r_info = le64_to_cpu(rela.r_info); + swrela.r_addend = le64_to_cpu(rela.r_addend); if (!supported_rela(&swrela)) continue; @@ -487,9 +498,9 @@ static int rela_elf32(char **argv, FILE *f) PRIu32 " r_addend:\t%" PRIx32 "\n", rela.r_offset, rela.r_info, rela.r_addend); - swrela.r_offset = cpu_to_le32(rela.r_offset); - swrela.r_info = cpu_to_le32(rela.r_info); - swrela.r_addend = cpu_to_le32(rela.r_addend); + swrela.r_offset = le32_to_cpu(rela.r_offset); + swrela.r_info = le32_to_cpu(rela.r_info); + swrela.r_addend = le32_to_cpu(rela.r_addend); debug("SWRela:\toffset:\t%" PRIx32 " r_info:\t%" PRIu32 " r_addend:\t%" PRIx32 "\n", From fcbc43bd508afbb5b7ffa9682dc22e1f5e0912d4 Mon Sep 17 00:00:00 2001 From: Stefan Herbrechtsmeier Date: Thu, 14 Jul 2022 15:47:33 +0200 Subject: [PATCH 05/48] xilinx: zynqmp: Do not use 0 as spl bss start address Do not use 0 as address for memory because of the special meaning for pointers (null pointer). Change the spl bss start address to the second page. Signed-off-by: Stefan Herbrechtsmeier Link: https://lore.kernel.org/r/20220714134733.7487-1-stefan.herbrechtsmeier-oss@weidmueller.com Signed-off-by: Michal Simek --- common/spl/Kconfig | 3 ++- configs/avnet_ultrazedev_cc_v1_0_ultrazedev_som_v1_0_defconfig | 2 -- configs/xilinx_zynqmp_mini_emmc0_defconfig | 2 -- configs/xilinx_zynqmp_mini_emmc1_defconfig | 2 -- configs/xilinx_zynqmp_mini_qspi_defconfig | 2 -- configs/xilinx_zynqmp_virt_defconfig | 2 -- 6 files changed, 2 insertions(+), 11 deletions(-) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 2352fc9d6d2..cb85ee415cb 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -107,7 +107,7 @@ config SPL_PAD_TO config SPL_HAS_BSS_LINKER_SECTION depends on SPL_FRAMEWORK bool "Use a specific address for the BSS via the linker script" - default y if ARCH_SUNXI || ARCH_MX6 || ARCH_OMAP2PLUS || MIPS || RISCV + default y if ARCH_SUNXI || ARCH_MX6 || ARCH_OMAP2PLUS || MIPS || RISCV || ARCH_ZYNQMP config SPL_BSS_START_ADDR hex "Link address for the BSS within the SPL binary" @@ -118,6 +118,7 @@ config SPL_BSS_START_ADDR default 0x81f80000 if ARCH_SUNXI && MACH_SUNIV default 0x4ff80000 if ARCH_SUNXI && !(MACH_SUN9I || MACH_SUNIV) default 0x2ff80000 if ARCH_SUNXI && MACH_SUN9I + default 0x1000 if ARCH_ZYNQMP choice prompt "Enforce SPL BSS limit" diff --git a/configs/avnet_ultrazedev_cc_v1_0_ultrazedev_som_v1_0_defconfig b/configs/avnet_ultrazedev_cc_v1_0_ultrazedev_som_v1_0_defconfig index 0574ee95e42..f04fa64450c 100644 --- a/configs/avnet_ultrazedev_cc_v1_0_ultrazedev_som_v1_0_defconfig +++ b/configs/avnet_ultrazedev_cc_v1_0_ultrazedev_som_v1_0_defconfig @@ -27,8 +27,6 @@ CONFIG_BOOTDELAY=0 # CONFIG_DISPLAY_CPUINFO is not set CONFIG_CLOCKS=y CONFIG_SPL_MAX_SIZE=0x40000 -CONFIG_SPL_HAS_BSS_LINKER_SECTION=y -CONFIG_SPL_BSS_START_ADDR=0x0 CONFIG_SPL_BSS_MAX_SIZE=0x80000 # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_STACK=0xfffffffc diff --git a/configs/xilinx_zynqmp_mini_emmc0_defconfig b/configs/xilinx_zynqmp_mini_emmc0_defconfig index a248cbf3a37..c481a6917ff 100644 --- a/configs/xilinx_zynqmp_mini_emmc0_defconfig +++ b/configs/xilinx_zynqmp_mini_emmc0_defconfig @@ -25,8 +25,6 @@ CONFIG_BOARD_EARLY_INIT_R=y # CONFIG_BOARD_LATE_INIT is not set CONFIG_CLOCKS=y CONFIG_SPL_MAX_SIZE=0x40000 -CONFIG_SPL_HAS_BSS_LINKER_SECTION=y -CONFIG_SPL_BSS_START_ADDR=0x0 CONFIG_SPL_BSS_MAX_SIZE=0x80000 # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_STACK=0xfffffffc diff --git a/configs/xilinx_zynqmp_mini_emmc1_defconfig b/configs/xilinx_zynqmp_mini_emmc1_defconfig index df0365ba77f..b02fec64d19 100644 --- a/configs/xilinx_zynqmp_mini_emmc1_defconfig +++ b/configs/xilinx_zynqmp_mini_emmc1_defconfig @@ -25,8 +25,6 @@ CONFIG_BOARD_EARLY_INIT_R=y # CONFIG_BOARD_LATE_INIT is not set CONFIG_CLOCKS=y CONFIG_SPL_MAX_SIZE=0x40000 -CONFIG_SPL_HAS_BSS_LINKER_SECTION=y -CONFIG_SPL_BSS_START_ADDR=0x0 CONFIG_SPL_BSS_MAX_SIZE=0x80000 # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_STACK=0xfffffffc diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig index 82510f19047..49e2758d647 100644 --- a/configs/xilinx_zynqmp_mini_qspi_defconfig +++ b/configs/xilinx_zynqmp_mini_qspi_defconfig @@ -24,8 +24,6 @@ CONFIG_REMAKE_ELF=y # CONFIG_BOARD_LATE_INIT is not set CONFIG_CLOCKS=y CONFIG_SPL_MAX_SIZE=0x40000 -CONFIG_SPL_HAS_BSS_LINKER_SECTION=y -CONFIG_SPL_BSS_START_ADDR=0x0 CONFIG_SPL_BSS_MAX_SIZE=0x80000 # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_STACK=0xfffffffc diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index 89622d18f8e..6776bd9d5d0 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -32,8 +32,6 @@ CONFIG_PREBOOT="run scsi_init;usb start" CONFIG_BOARD_EARLY_INIT_R=y CONFIG_CLOCKS=y CONFIG_SPL_MAX_SIZE=0x40000 -CONFIG_SPL_HAS_BSS_LINKER_SECTION=y -CONFIG_SPL_BSS_START_ADDR=0x0 CONFIG_SPL_BSS_MAX_SIZE=0x80000 # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_STACK=0xfffffffc From e3521e9c69af1818fac28d980bf956fc8a7ceabe Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 4 Jul 2022 16:09:00 +0200 Subject: [PATCH 06/48] arm64: zynqmp: Enable SLG gpo driver by default This device is used on SOM CCs that's why enable it by default. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/ebbfc0c883ca7d4f70c75d8d3655aaa6a81d77be.1656943737.git.michal.simek@amd.com --- configs/xilinx_zynqmp_virt_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index 6776bd9d5d0..bee48162e75 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -137,6 +137,7 @@ CONFIG_FPGA_ZYNQMPPL=y CONFIG_GPIO_HOG=y CONFIG_XILINX_GPIO=y CONFIG_DM_PCA953X=y +CONFIG_SLG7XL45106_I2C_GPO=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_CADENCE=y CONFIG_I2C_MUX=y From b09e462482b4b84f5d99986514db5fe8d10f4c2f Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Jul 2022 10:47:16 +0200 Subject: [PATCH 07/48] arm: riscv: Remove additional ifdef from code guarded by CONFIG_IS_ENABLED CONFIG_OF_LIBFDT is used twice for guarding the same code. It is enough to do it once that's why remove additional ifdefs from arm and risc-v code. Fixes: 0c303f9a6628 ("image: Drop IMAGE_ENABLE_OF_LIBFDT") Signed-off-by: Michal Simek Reviewed-by: Tom Rini Link: https://lore.kernel.org/r/f8e3ff9124195cbd957874de9a65ef79760ef5e7.1657183634.git.michal.simek@amd.com --- arch/arm/lib/bootm.c | 2 -- arch/riscv/lib/bootm.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index a59a5e6c0ea..fc22befeac1 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -200,12 +200,10 @@ static void boot_prep_linux(bootm_headers_t *images) char *commandline = env_get("bootargs"); if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) { -#ifdef CONFIG_OF_LIBFDT debug("using: FDT\n"); if (image_setup_linux(images)) { panic("FDT creation failed!"); } -#endif } else if (BOOTM_ENABLE_TAGS) { debug("using: ATAGS\n"); setup_start_tag(gd->bd); diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index 2e1e286c8ef..c1ac339283a 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -65,13 +65,11 @@ static void announce_and_cleanup(int fake) static void boot_prep_linux(bootm_headers_t *images) { if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) { -#ifdef CONFIG_OF_LIBFDT debug("using: FDT\n"); if (image_setup_linux(images)) { printf("FDT creation failed! hanging..."); hang(); } -#endif } else { printf("Device tree not found or missing FDT support\n"); hang(); From 7c1860fce4e369bdcabc1f574feb6b9af19999a3 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Thu, 7 Jul 2022 10:45:36 +0200 Subject: [PATCH 08/48] lmb: Fix lmb property's defination under struct lmb Under struct lmb {} the lmb property's should be defined only if CONFIG_LMB_MEMORY_REGIONS is defined. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/c24a2b1d6f5db4eb65393f6a77fae129b30b6233.1657183534.git.michal.simek@amd.com --- include/lmb.h | 2 +- lib/lmb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/lmb.h b/include/lmb.h index ab277ca8000..1476d78c282 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -68,7 +68,7 @@ struct lmb_region { struct lmb { struct lmb_region memory; struct lmb_region reserved; -#if !IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) +#if IS_ENABLED(CONFIG_LMB_MEMORY_REGIONS) struct lmb_property memory_regions[CONFIG_LMB_MEMORY_REGIONS]; struct lmb_property reserved_regions[CONFIG_LMB_RESERVED_REGIONS]; #endif diff --git a/lib/lmb.c b/lib/lmb.c index f72996a4248..f21fe672ae9 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -108,7 +108,7 @@ void lmb_init(struct lmb *lmb) #if IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) lmb->memory.max = CONFIG_LMB_MAX_REGIONS; lmb->reserved.max = CONFIG_LMB_MAX_REGIONS; -#else +#elif IS_ENABLED(CONFIG_LMB_MEMORY_REGIONS) lmb->memory.max = CONFIG_LMB_MEMORY_REGIONS; lmb->reserved.max = CONFIG_LMB_RESERVED_REGIONS; lmb->memory.region = lmb->memory_regions; From 65168910adaae3a4ac91fd5acf30941a28facc0e Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Thu, 7 Jul 2022 10:45:37 +0200 Subject: [PATCH 09/48] zynqmp: Run board_get_usable_ram_top() only on main U-Boot With commit ce39ee28ec31 ("zynqmp: Do not place u-boot to reserved memory location"), the function board_get_usable_ram_top() is allocating MMU_SECTION_SIZE of about 2MB using lmb_alloc(). But we dont have this much memory in case of mini U-Boot. Keep these functions which use lmb under CONFIG_LMB so that they are compiled and used only when LMB is enabled. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/75e52def75f573e554a6b177a78504c128cb0c4a.1657183534.git.michal.simek@amd.com --- arch/arc/lib/bootm.c | 8 +++++--- arch/arm/lib/bootm.c | 2 +- arch/m68k/lib/bootm.c | 8 +++++--- arch/microblaze/lib/bootm.c | 2 +- arch/powerpc/lib/bootm.c | 8 +++++--- arch/riscv/lib/bootm.c | 2 +- arch/x86/lib/bootm.c | 5 ++--- board/xilinx/zynqmp/zynqmp.c | 3 +++ boot/image-board.c | 4 ++++ 9 files changed, 27 insertions(+), 15 deletions(-) diff --git a/arch/arc/lib/bootm.c b/arch/arc/lib/bootm.c index ed6c5dfa584..628addd87ed 100644 --- a/arch/arc/lib/bootm.c +++ b/arch/arc/lib/bootm.c @@ -29,9 +29,11 @@ static int boot_prep_linux(bootm_headers_t *images) { int ret; - ret = image_setup_linux(images); - if (ret) - return ret; + if (CONFIG_IS_ENABLED(LMB)) { + ret = image_setup_linux(images); + if (ret) + return ret; + } return board_prep_linux(images); } diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index fc22befeac1..9f086f3b904 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -199,7 +199,7 @@ static void boot_prep_linux(bootm_headers_t *images) { char *commandline = env_get("bootargs"); - if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) { + if (CONFIG_IS_ENABLED(OF_LIBFDT) && CONFIG_IS_ENABLED(LMB) && images->ft_len) { debug("using: FDT\n"); if (image_setup_linux(images)) { panic("FDT creation failed!"); diff --git a/arch/m68k/lib/bootm.c b/arch/m68k/lib/bootm.c index 27729db67e2..9cade929541 100644 --- a/arch/m68k/lib/bootm.c +++ b/arch/m68k/lib/bootm.c @@ -60,9 +60,11 @@ int do_bootm_linux(int flag, int argc, char *const argv[], } set_clocks_in_mhz(kbd); - ret = image_setup_linux(images); - if (ret) - goto error; + if (CONFIG_IS_ENABLED(LMB)) { + ret = image_setup_linux(images); + if (ret) + goto error; + } kernel = (void (*)(struct bd_info *, ulong, ulong, ulong, ulong))images->ep; diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index af946b86428..31b6659cdf7 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -73,7 +73,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) static void boot_prep_linux(bootm_headers_t *images) { - if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) { + if (CONFIG_IS_ENABLED(OF_LIBFDT) && CONFIG_IS_ENABLED(LMB) && images->ft_len) { debug("using: FDT\n"); if (image_setup_linux(images)) { printf("FDT creation failed! hanging..."); diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index d365705856d..e52aa75703f 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -214,9 +214,11 @@ static int boot_body_linux(bootm_headers_t *images) if (ret) return ret; - ret = image_setup_linux(images); - if (ret) - return ret; + if (CONFIG_IS_ENABLED(LMB)) { + ret = image_setup_linux(images); + if (ret) + return ret; + } return 0; } diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index c1ac339283a..670d9c9ebcf 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -64,7 +64,7 @@ static void announce_and_cleanup(int fake) static void boot_prep_linux(bootm_headers_t *images) { - if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) { + if (CONFIG_IS_ENABLED(OF_LIBFDT) && CONFIG_IS_ENABLED(LMB) && images->ft_len) { debug("using: FDT\n"); if (image_setup_linux(images)) { printf("FDT creation failed! hanging..."); diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index 57cba5c65d3..1bcdb3e30d2 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -78,15 +78,14 @@ static int boot_prep_linux(bootm_headers_t *images) size_t len; int ret; -#ifdef CONFIG_OF_LIBFDT - if (images->ft_len) { + if (CONFIG_IS_ENABLED(OF_LIBFDT) && CONFIG_IS_ENABLED(LMB) && images->ft_len) { debug("using: FDT\n"); if (image_setup_linux(images)) { puts("FDT creation failed! hanging..."); hang(); } } -#endif + if (images->legacy_hdr_valid) { hdr = images->legacy_hdr_os; if (image_check_type(hdr, IH_TYPE_MULTI)) { diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 106c3953e1f..f7c6e3ed4e3 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -253,6 +253,7 @@ int dram_init(void) return 0; } +#if defined(CONFIG_LMB) ulong board_get_usable_ram_top(ulong total_size) { phys_size_t size; @@ -277,6 +278,8 @@ ulong board_get_usable_ram_top(ulong total_size) return reg + size; } +#endif + #else int dram_init_banksize(void) { diff --git a/boot/image-board.c b/boot/image-board.c index cfc1c658e3a..03c866b5fa8 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -537,6 +537,7 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, return 0; } +#if defined(CONFIG_LMB) /** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -630,6 +631,7 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, error: return -1; } +#endif int boot_get_setup(bootm_headers_t *images, u8 arch, ulong *setup_start, ulong *setup_len) @@ -823,6 +825,7 @@ int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, return 0; } +#if defined(CONFIG_LMB) #ifdef CONFIG_SYS_BOOT_GET_CMDLINE /** * boot_get_cmdline - allocate and initialize kernel cmdline @@ -932,6 +935,7 @@ int image_setup_linux(bootm_headers_t *images) return 0; } +#endif void genimg_print_size(uint32_t size) { From a5bd1fe863907f27c68e30d8ef030649f4bf7d5f Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Jul 2022 10:45:38 +0200 Subject: [PATCH 10/48] arm64: zynqmp: Disable LMB for mini configurations There is no need to have LMB enabled that's why save some space by disabling it. aarch64: (for 8/8 boards) all -1168.5 rodata -105.5 text -1063.0 xilinx_zynqmp_mini: all -2013 rodata -185 text -1828 xilinx_zynqmp_mini_qspi: all -2013 rodata -185 text -1828 xilinx_zynqmp_mini_emmc0: all -2661 rodata -237 text -2424 xilinx_zynqmp_mini_emmc1: all -2661 rodata -237 text -2424 Signed-off-by: Michal Simek Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/f735d7691f4e7a7958d985b22c40aeb26e37a404.1657183534.git.michal.simek@amd.com --- configs/xilinx_zynqmp_mini_defconfig | 1 + configs/xilinx_zynqmp_mini_emmc0_defconfig | 1 + configs/xilinx_zynqmp_mini_emmc1_defconfig | 1 + configs/xilinx_zynqmp_mini_qspi_defconfig | 1 + 4 files changed, 4 insertions(+) diff --git a/configs/xilinx_zynqmp_mini_defconfig b/configs/xilinx_zynqmp_mini_defconfig index 5963dd90f72..1474434fb8d 100644 --- a/configs/xilinx_zynqmp_mini_defconfig +++ b/configs/xilinx_zynqmp_mini_defconfig @@ -63,3 +63,4 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ARM_DCC=y CONFIG_PANIC_HANG=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set diff --git a/configs/xilinx_zynqmp_mini_emmc0_defconfig b/configs/xilinx_zynqmp_mini_emmc0_defconfig index c481a6917ff..16f1d490953 100644 --- a/configs/xilinx_zynqmp_mini_emmc0_defconfig +++ b/configs/xilinx_zynqmp_mini_emmc0_defconfig @@ -78,3 +78,4 @@ CONFIG_ARM_DCC=y CONFIG_PANIC_HANG=y # CONFIG_GZIP is not set # CONFIG_EFI_LOADER is not set +# CONFIG_LMB is not set diff --git a/configs/xilinx_zynqmp_mini_emmc1_defconfig b/configs/xilinx_zynqmp_mini_emmc1_defconfig index b02fec64d19..cfaffa147aa 100644 --- a/configs/xilinx_zynqmp_mini_emmc1_defconfig +++ b/configs/xilinx_zynqmp_mini_emmc1_defconfig @@ -78,3 +78,4 @@ CONFIG_ARM_DCC=y CONFIG_PANIC_HANG=y # CONFIG_GZIP is not set # CONFIG_EFI_LOADER is not set +# CONFIG_LMB is not set diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig index 49e2758d647..e6d43083475 100644 --- a/configs/xilinx_zynqmp_mini_qspi_defconfig +++ b/configs/xilinx_zynqmp_mini_qspi_defconfig @@ -82,3 +82,4 @@ CONFIG_SPI=y CONFIG_ZYNQMP_GQSPI=y CONFIG_PANIC_HANG=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set From 2075215dd968b5488f87a59c4d3494a8b8c1460d Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Jul 2022 12:52:26 +0200 Subject: [PATCH 11/48] py: tests: Bind should run only on sandbox Disable test to run on any other platform than sandbox. Signed-off-by: Michal Simek Signed-off-by: Michal Simek Reviewed-by: Simon Glass Link: https://lore.kernel.org/r/786bfdfda7dee4494e39c3fff699970ecd623116.1657191142.git.michal.simek@amd.com --- test/py/tests/test_bind.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/py/tests/test_bind.py b/test/py/tests/test_bind.py index d7e6626d45f..c90c54d266f 100644 --- a/test/py/tests/test_bind.py +++ b/test/py/tests/test_bind.py @@ -25,7 +25,7 @@ def in_tree(response, name, uclass, drv, depth, last_child): return True return False - +@pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_bind') def test_bind_unbind_with_node(u_boot_console): @@ -117,6 +117,7 @@ def get_next_line(tree, name): break return child_line +@pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_bind') def test_bind_unbind_with_uclass(u_boot_console): #bind /bind-test From 34b01c22ccd2cf55a85a05c8d542bab0523f76c0 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Jul 2022 12:59:42 +0200 Subject: [PATCH 12/48] test/py: Run simple dm commands without checking Just to make sure that dm commands can operate. This was the problem on Microblaze in past without fixing manual relocation. Signed-off-by: Michal Simek Signed-off-by: Michal Simek Reviewed-by: Simon Glass Link: https://lore.kernel.org/r/e6c4b8b44445c16cee84436627642ccc9886f507.1657191580.git.michal.simek@amd.com --- test/py/tests/test_dm.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/py/tests/test_dm.py b/test/py/tests/test_dm.py index 97203b536e1..ea93061fdfa 100644 --- a/test/py/tests/test_dm.py +++ b/test/py/tests/test_dm.py @@ -33,3 +33,11 @@ def test_dm_static(u_boot_console): response = u_boot_console.run_command('dm drivers') for driver in drivers: assert driver in response + +@pytest.mark.buildconfigspec("cmd_dm") +def test_dm_uclass(u_boot_console): + response = u_boot_console.run_command("dm uclass") + +@pytest.mark.buildconfigspec("cmd_dm") +def test_dm_devres(u_boot_console): + response = u_boot_console.run_command("dm devres") From 7e9c2cd4e46cb93c22ea513c24c83b07873deac6 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Jul 2022 13:06:16 +0200 Subject: [PATCH 13/48] xilinx: Remove duplicate PMIO_NODE_ID_BASE macro PMIO_NODE_ID_BASE is defined twice that's why remove one instance. Fixes: 248fe9f302df ("spi: cadence_qspi: Enable apb linear mode for apb read & write operations") Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/ce9a601bb99418aa20272d046c74678829d942cc.1657191974.git.michal.simek@amd.com --- include/zynqmp_firmware.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h index 6c4fd9a6c5f..86c14d560e1 100644 --- a/include/zynqmp_firmware.h +++ b/include/zynqmp_firmware.h @@ -435,8 +435,6 @@ enum pm_gem_config_type { #define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0) #define PMIO_NODE_ID_BASE 0x1410801B -#define PMIO_NODE_ID_BASE 0x1410801B - /* * Return payload size * Not every firmware call expects the same amount of return bytes, however the From 165694b1254909953eea9768ea3d914555c17cc5 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Jul 2022 13:10:53 +0200 Subject: [PATCH 14/48] dt-bindings: versal: Add versal reset IDs The same file is already the part of Linux kernel that's why add it also to u-boot to be able to use it in source code and DT files. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/1c3bc464536a9bf64a2e8bfe18a938c9cb490620.1657192249.git.michal.simek@amd.com --- .../dt-bindings/reset/xlnx-versal-resets.h | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 include/dt-bindings/reset/xlnx-versal-resets.h diff --git a/include/dt-bindings/reset/xlnx-versal-resets.h b/include/dt-bindings/reset/xlnx-versal-resets.h new file mode 100644 index 00000000000..895424e9b0e --- /dev/null +++ b/include/dt-bindings/reset/xlnx-versal-resets.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Xilinx, Inc. + */ + +#ifndef _DT_BINDINGS_VERSAL_RESETS_H +#define _DT_BINDINGS_VERSAL_RESETS_H + +#define VERSAL_RST_PMC_POR (0xc30c001U) +#define VERSAL_RST_PMC (0xc410002U) +#define VERSAL_RST_PS_POR (0xc30c003U) +#define VERSAL_RST_PL_POR (0xc30c004U) +#define VERSAL_RST_NOC_POR (0xc30c005U) +#define VERSAL_RST_FPD_POR (0xc30c006U) +#define VERSAL_RST_ACPU_0_POR (0xc30c007U) +#define VERSAL_RST_ACPU_1_POR (0xc30c008U) +#define VERSAL_RST_OCM2_POR (0xc30c009U) +#define VERSAL_RST_PS_SRST (0xc41000aU) +#define VERSAL_RST_PL_SRST (0xc41000bU) +#define VERSAL_RST_NOC (0xc41000cU) +#define VERSAL_RST_NPI (0xc41000dU) +#define VERSAL_RST_SYS_RST_1 (0xc41000eU) +#define VERSAL_RST_SYS_RST_2 (0xc41000fU) +#define VERSAL_RST_SYS_RST_3 (0xc410010U) +#define VERSAL_RST_FPD (0xc410011U) +#define VERSAL_RST_PL0 (0xc410012U) +#define VERSAL_RST_PL1 (0xc410013U) +#define VERSAL_RST_PL2 (0xc410014U) +#define VERSAL_RST_PL3 (0xc410015U) +#define VERSAL_RST_APU (0xc410016U) +#define VERSAL_RST_ACPU_0 (0xc410017U) +#define VERSAL_RST_ACPU_1 (0xc410018U) +#define VERSAL_RST_ACPU_L2 (0xc410019U) +#define VERSAL_RST_ACPU_GIC (0xc41001aU) +#define VERSAL_RST_RPU_ISLAND (0xc41001bU) +#define VERSAL_RST_RPU_AMBA (0xc41001cU) +#define VERSAL_RST_R5_0 (0xc41001dU) +#define VERSAL_RST_R5_1 (0xc41001eU) +#define VERSAL_RST_SYSMON_PMC_SEQ_RST (0xc41001fU) +#define VERSAL_RST_SYSMON_PMC_CFG_RST (0xc410020U) +#define VERSAL_RST_SYSMON_FPD_CFG_RST (0xc410021U) +#define VERSAL_RST_SYSMON_FPD_SEQ_RST (0xc410022U) +#define VERSAL_RST_SYSMON_LPD (0xc410023U) +#define VERSAL_RST_PDMA_RST1 (0xc410024U) +#define VERSAL_RST_PDMA_RST0 (0xc410025U) +#define VERSAL_RST_ADMA (0xc410026U) +#define VERSAL_RST_TIMESTAMP (0xc410027U) +#define VERSAL_RST_OCM (0xc410028U) +#define VERSAL_RST_OCM2_RST (0xc410029U) +#define VERSAL_RST_IPI (0xc41002aU) +#define VERSAL_RST_SBI (0xc41002bU) +#define VERSAL_RST_LPD (0xc41002cU) +#define VERSAL_RST_QSPI (0xc10402dU) +#define VERSAL_RST_OSPI (0xc10402eU) +#define VERSAL_RST_SDIO_0 (0xc10402fU) +#define VERSAL_RST_SDIO_1 (0xc104030U) +#define VERSAL_RST_I2C_PMC (0xc104031U) +#define VERSAL_RST_GPIO_PMC (0xc104032U) +#define VERSAL_RST_GEM_0 (0xc104033U) +#define VERSAL_RST_GEM_1 (0xc104034U) +#define VERSAL_RST_SPARE (0xc104035U) +#define VERSAL_RST_USB_0 (0xc104036U) +#define VERSAL_RST_UART_0 (0xc104037U) +#define VERSAL_RST_UART_1 (0xc104038U) +#define VERSAL_RST_SPI_0 (0xc104039U) +#define VERSAL_RST_SPI_1 (0xc10403aU) +#define VERSAL_RST_CAN_FD_0 (0xc10403bU) +#define VERSAL_RST_CAN_FD_1 (0xc10403cU) +#define VERSAL_RST_I2C_0 (0xc10403dU) +#define VERSAL_RST_I2C_1 (0xc10403eU) +#define VERSAL_RST_GPIO_LPD (0xc10403fU) +#define VERSAL_RST_TTC_0 (0xc104040U) +#define VERSAL_RST_TTC_1 (0xc104041U) +#define VERSAL_RST_TTC_2 (0xc104042U) +#define VERSAL_RST_TTC_3 (0xc104043U) +#define VERSAL_RST_SWDT_FPD (0xc104044U) +#define VERSAL_RST_SWDT_LPD (0xc104045U) +#define VERSAL_RST_USB (0xc104046U) +#define VERSAL_RST_DPC (0xc208047U) +#define VERSAL_RST_PMCDBG (0xc208048U) +#define VERSAL_RST_DBG_TRACE (0xc208049U) +#define VERSAL_RST_DBG_FPD (0xc20804aU) +#define VERSAL_RST_DBG_TSTMP (0xc20804bU) +#define VERSAL_RST_RPU0_DBG (0xc20804cU) +#define VERSAL_RST_RPU1_DBG (0xc20804dU) +#define VERSAL_RST_HSDP (0xc20804eU) +#define VERSAL_RST_DBG_LPD (0xc20804fU) +#define VERSAL_RST_CPM_POR (0xc30c050U) +#define VERSAL_RST_CPM (0xc410051U) +#define VERSAL_RST_CPMDBG (0xc208052U) +#define VERSAL_RST_PCIE_CFG (0xc410053U) +#define VERSAL_RST_PCIE_CORE0 (0xc410054U) +#define VERSAL_RST_PCIE_CORE1 (0xc410055U) +#define VERSAL_RST_PCIE_DMA (0xc410056U) +#define VERSAL_RST_CMN (0xc410057U) +#define VERSAL_RST_L2_0 (0xc410058U) +#define VERSAL_RST_L2_1 (0xc410059U) +#define VERSAL_RST_ADDR_REMAP (0xc41005aU) +#define VERSAL_RST_CPI0 (0xc41005bU) +#define VERSAL_RST_CPI1 (0xc41005cU) +#define VERSAL_RST_XRAM (0xc30c05dU) +#define VERSAL_RST_AIE_ARRAY (0xc10405eU) +#define VERSAL_RST_AIE_SHIM (0xc10405fU) + +#endif From bb7468b4c9d7ce0f7cdd5bc5eae11e8fe87250cf Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 8 Jul 2022 08:15:05 +0200 Subject: [PATCH 15/48] tools: relocate-rela: Remove guard around R_AARCH64_RELATIVE In code you can find out this fragment: 19 #ifndef R_AARCH64_RELATIVE 20 #define R_AARCH64_RELATIVE 1027 21 #endif which means that R_AARCH64_RELATIVE is defined all the time that's why ifdef is not needed. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/0d40a09ab6edcd88ba3059f7a0b63a819b71256a.1657260903.git.michal.simek@amd.com --- tools/relocate-rela.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index fcf3fb201f0..5f31d8a746d 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -43,10 +43,8 @@ static bool supported_rela(Elf64_Rela *rela) uint32_t type = rela->r_info & mask; switch (type) { -#ifdef R_AARCH64_RELATIVE case R_AARCH64_RELATIVE: return true; -#endif default: fprintf(stderr, "warning: unsupported relocation type %" PRIu32 " at %" PRIx64 "\n", From 65fc1697dbfbf61680e6a9cdad0a2d7dd2f9bed9 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 8 Jul 2022 08:15:06 +0200 Subject: [PATCH 16/48] tools: relocate-rela: Define all macros for e_machine and reloc types With some old toolchain not all values should be available that's why better to define all of them to avoid compilation issues. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/e2a66854c5506100eb82b5b33cec7f0b5fca1008.1657260903.git.michal.simek@amd.com --- tools/relocate-rela.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index 5f31d8a746d..2d2a2ed2772 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -16,10 +16,34 @@ #include #include "compiler.h" +#ifndef EM_AARCH64 +#define EM_AARCH64 183 +#endif + #ifndef R_AARCH64_RELATIVE #define R_AARCH64_RELATIVE 1027 #endif +#ifndef EM_MICROBLAZE +#define EM_MICROBLAZE 189 +#endif + +#ifndef R_MICROBLAZE_NONE +#define R_MICROBLAZE_NONE 0 +#endif + +#ifndef R_MICROBLAZE_32 +#define R_MICROBLAZE_32 1 +#endif + +#ifndef R_MICROBLAZE_REL +#define R_MICROBLAZE_REL 16 +#endif + +#ifndef R_MICROBLAZE_GLOB_DAT +#define R_MICROBLAZE_GLOB_DAT 18 +#endif + static int ei_class; static uint64_t rela_start, rela_end, text_base, dyn_start; From c6bceb4e360d704fb9746541c18a1a08f49353fc Mon Sep 17 00:00:00 2001 From: Kunihiko Hayashi Date: Wed, 13 Jul 2022 10:38:59 +0900 Subject: [PATCH 17/48] serial: zynq: Use DIV_ROUND_CLOSEST() to calcurate divider value Since the calulation of "bgen" is rounded down, using a higher baudrate will result in a larger difference from the actual baudrate. Should use DIV_ROUND_CLOSEST() like the Linux driver. Signed-off-by: Kunihiko Hayashi Link: https://lore.kernel.org/r/1657676339-6055-1-git-send-email-hayashi.kunihiko@socionext.com Signed-off-by: Michal Simek --- drivers/serial/serial_zynq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c index 83adfb5fb98..295337a8176 100644 --- a/drivers/serial/serial_zynq.c +++ b/drivers/serial/serial_zynq.c @@ -75,7 +75,7 @@ static void _uart_zynq_serial_setbrg(struct uart_zynq *regs, * Find acceptable values for baud generation. */ for (bdiv = 4; bdiv < 255; bdiv++) { - bgen = clock / (baud * (bdiv + 1)); + bgen = DIV_ROUND_CLOSEST(clock, baud * (bdiv + 1)); if (bgen < 2 || bgen > 65535) continue; From ee5a4b87a1a57607db28fafa2692dabf92c64570 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 21 Jul 2022 16:19:17 +0200 Subject: [PATCH 18/48] xilinx: Wire uuid reading from FRU UUID is already recorded when FRU is parsed but it is not copied to local structures and exported to variable that's why simply add it. Data is saved in binary format but there must be conversion to string for exporting it to variable and string should be in uuid format too. One way how to use it directly is to setup pxeuuid based on it. For example via preboot with "setenv pxeuuid ${board_uuid}" Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/1dfa4b4220a508abc05351da2119880811b77612.1658413156.git.michal.simek@amd.com --- board/xilinx/common/board.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 5f2afb9def4..b0c11aaa425 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "fru.h" @@ -86,6 +87,7 @@ int zynq_board_read_rom_ethaddr(unsigned char *ethaddr) #define EEPROM_HDR_SERIAL_LEN 20 #define EEPROM_HDR_NO_OF_MAC_ADDR 4 #define EEPROM_HDR_ETH_ALEN ETH_ALEN +#define EEPROM_HDR_UUID_LEN 16 struct xilinx_board_description { u32 header; @@ -94,6 +96,7 @@ struct xilinx_board_description { char revision[EEPROM_HDR_REV_LEN + 1]; char serial[EEPROM_HDR_SERIAL_LEN + 1]; u8 mac_addr[EEPROM_HDR_NO_OF_MAC_ADDR][EEPROM_HDR_ETH_ALEN + 1]; + char uuid[EEPROM_HDR_UUID_LEN + 1]; }; static int highest_id = -1; @@ -237,6 +240,8 @@ static int xilinx_read_eeprom_fru(struct udevice *dev, char *name, /* It is clear that FRU was captured and structures were filled */ strncpy(desc->manufacturer, (char *)fru_data.brd.manufacturer_name, sizeof(desc->manufacturer)); + strncpy(desc->uuid, (char *)fru_data.brd.uuid, + sizeof(desc->uuid)); strncpy(desc->name, (char *)fru_data.brd.product_name, sizeof(desc->name)); for (i = 0; i < sizeof(desc->name); i++) { @@ -452,6 +457,19 @@ int board_late_init_xilinx(void) ret |= env_set_by_index("serial", id, desc->serial); + if (desc->uuid[0]) { + char uuid[UUID_STR_LEN + 1]; + char *t = desc->uuid; + + memset(uuid, 0, UUID_STR_LEN + 1); + + sprintf(uuid, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + t[0], t[1], t[2], t[3], t[4], t[5], + t[6], t[7], t[8], t[9], t[10], t[11], + t[12], t[13], t[14], t[15]); + ret |= env_set_by_index("uuid", id, uuid); + } + if (!CONFIG_IS_ENABLED(NET)) continue; From 4a1bfcd7aa6f2138a8431a916d4202a66ab65a6c Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 21 Jul 2022 16:19:18 +0200 Subject: [PATCH 19/48] xilinx: common: Use strlcpy instead of strncpy It is recommendation done by checkpatch to all the time have \0 terminated strings. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/c7bfab50c40f6213f1b347b5e4674e382e83cb94.1658413156.git.michal.simek@amd.com --- board/xilinx/common/board.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index b0c11aaa425..9b4aded466a 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -238,23 +238,23 @@ static int xilinx_read_eeprom_fru(struct udevice *dev, char *name, } /* It is clear that FRU was captured and structures were filled */ - strncpy(desc->manufacturer, (char *)fru_data.brd.manufacturer_name, + strlcpy(desc->manufacturer, (char *)fru_data.brd.manufacturer_name, sizeof(desc->manufacturer)); - strncpy(desc->uuid, (char *)fru_data.brd.uuid, + strlcpy(desc->uuid, (char *)fru_data.brd.uuid, sizeof(desc->uuid)); - strncpy(desc->name, (char *)fru_data.brd.product_name, + strlcpy(desc->name, (char *)fru_data.brd.product_name, sizeof(desc->name)); for (i = 0; i < sizeof(desc->name); i++) { if (desc->name[i] == ' ') desc->name[i] = '\0'; } - strncpy(desc->revision, (char *)fru_data.brd.rev, + strlcpy(desc->revision, (char *)fru_data.brd.rev, sizeof(desc->revision)); for (i = 0; i < sizeof(desc->revision); i++) { if (desc->revision[i] == ' ') desc->revision[i] = '\0'; } - strncpy(desc->serial, (char *)fru_data.brd.serial_number, + strlcpy(desc->serial, (char *)fru_data.brd.serial_number, sizeof(desc->serial)); while (id < EEPROM_HDR_NO_OF_MAC_ADDR) { From 9df50817405b358c5dd8c669030de7b1f8b15cb8 Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Wed, 20 Jul 2022 03:59:57 -0600 Subject: [PATCH 20/48] reset: zynqmp: Add reset driver support for versal Add support for versal platform by adding "xlnx,versal-reset" compatible string in zynqmp-reset driver. Reset numbering schema for versal is not same as zynqmp, so nr_reset and reset_id are set to zero. In case of assert/dessert, required device reset id is sent from respective driver through struct reset_ctl. Signed-off-by: T Karthik Reddy Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220720095959.29610-2-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- drivers/reset/Kconfig | 6 +++--- drivers/reset/reset-zynqmp.c | 10 +++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index b57714111b5..69a7b4ccbad 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -199,11 +199,11 @@ config RESET_SCMI protocol communication with a SCMI server. config RESET_ZYNQMP - bool "Reset Driver for Xilinx ZynqMP SoC's" + bool "Reset Driver for Xilinx ZynqMP & Versal SoC's" depends on DM_RESET && ZYNQMP_FIRMWARE help - Support for reset controller on Xilinx ZynqMP SoC. Driver is only - passing request via Xilinx firmware interface to TF-A and PMU + Support for reset controller on Xilinx ZynqMP & Versal SoC's. Driver + is only passing request via Xilinx firmware interface to TF-A and PMU firmware. config RESET_DRA7 diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c index 4e3f907980f..52c08c4722d 100644 --- a/drivers/reset/reset-zynqmp.c +++ b/drivers/reset/reset-zynqmp.c @@ -53,7 +53,7 @@ static int zynqmp_reset_request(struct reset_ctl *rst) dev_dbg(rst->dev, "%s(rst=%p) (id=%lu) (nr_reset=%d)\n", __func__, rst, rst->id, priv->nr_reset); - if (rst->id > priv->nr_reset) + if (priv->nr_reset && rst->id > priv->nr_reset) return -EINVAL; return 0; @@ -63,8 +63,11 @@ static int zynqmp_reset_probe(struct udevice *dev) { struct zynqmp_reset_priv *priv = dev_get_priv(dev); - priv->reset_id = ZYNQMP_RESET_ID; - priv->nr_reset = ZYNQMP_NR_RESETS; + if (device_is_compatible(dev, "xlnx,zynqmp-reset")) { + priv->reset_id = ZYNQMP_RESET_ID; + priv->nr_reset = ZYNQMP_NR_RESETS; + } + return 0; } @@ -76,6 +79,7 @@ const struct reset_ops zynqmp_reset_ops = { static const struct udevice_id zynqmp_reset_ids[] = { { .compatible = "xlnx,zynqmp-reset" }, + { .compatible = "xlnx,versal-reset" }, { } }; From c0ce59aaacfd139f75f57181f0e15a3efbd7b3fc Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 20 Jul 2022 03:59:58 -0600 Subject: [PATCH 21/48] arm64: versal: Enable reset driver for versal Add CONFIG_DM_RESET and CONFIG_RESET_ZYNQMP configs in versal default configuration to enable support for reset driver for versal platform. Signed-off-by: Michal Simek Signed-off-by: T Karthik Reddy Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220720095959.29610-3-ashok.reddy.soma@xilinx.com --- configs/xilinx_versal_virt_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index 7f0bcb2eaa9..d2490fe7c50 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -100,6 +100,8 @@ CONFIG_PHY_GIGE=y CONFIG_XILINX_AXIEMAC=y CONFIG_XILINX_AXIMRMAC=y CONFIG_ZYNQ_GEM=y +CONFIG_DM_RESET=y +CONFIG_RESET_ZYNQMP=y CONFIG_ARM_DCC=y CONFIG_PL01X_SERIAL=y CONFIG_XILINX_UARTLITE=y From 9dac63b6f4df17398345d4ea4f771fcf9e5e4547 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Wed, 20 Jul 2022 03:59:59 -0600 Subject: [PATCH 22/48] arm64: zynqmp: Enable reset driver Enable reset driver for ZynqMP platforms. This will enable us to reset the IP's using generic reset_assert and reset_deassert calls. Signed-off-by: T Karthik Reddy Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220720095959.29610-4-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- configs/xilinx_zynqmp_virt_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index bee48162e75..22ddbf31db4 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -183,6 +183,8 @@ CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_PWM=y CONFIG_PWM_CADENCE_TTC=y +CONFIG_DM_RESET=y +CONFIG_RESET_ZYNQMP=y CONFIG_DM_RTC=y CONFIG_RTC_EMULATION=y CONFIG_RTC_ZYNQMP=y From c9f12ed9bcb973297a33f50e1fa28506118bcb91 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 22 Jul 2022 02:46:54 -0600 Subject: [PATCH 23/48] firmware: zynqmp: Change prototype of zynqmp_pmufw_load_config_object() zynqmp_pmufw_load_config_object() has some error cases and it is better to return those errors. Change prototype of this function to return errors. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/20220722084658.30995-2-ashok.reddy.soma@xilinx.com --- drivers/firmware/firmware-zynqmp.c | 8 +++++--- include/zynqmp_firmware.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index b0cd647aa51..325e4ddea6d 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -227,7 +227,7 @@ int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id) * @cfg_obj: Pointer to the configuration object * @size: Size of @cfg_obj in bytes */ -void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size) +int zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size) { int err; u32 ret_payload[PAYLOAD_ARG_CNT]; @@ -241,12 +241,12 @@ void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size) 0, ret_payload); if (err == XST_PM_NO_ACCESS) { printf("PMUFW no permission to change config object\n"); - return; + return -EACCES; } if (err == XST_PM_ALREADY_CONFIGURED) { debug("PMUFW Node is already configured\n"); - return; + return -ENODEV; } if (err) @@ -257,6 +257,8 @@ void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size) if ((err || ret_payload[0]) && IS_ENABLED(CONFIG_SPL_BUILD)) panic("PMUFW config object loading failed in EL3\n"); + + return 0; } static int zynqmp_power_probe(struct udevice *dev) diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h index 86c14d560e1..52bc20f195e 100644 --- a/include/zynqmp_firmware.h +++ b/include/zynqmp_firmware.h @@ -447,7 +447,7 @@ enum pm_gem_config_type { unsigned int zynqmp_firmware_version(void); int zynqmp_pmufw_node(u32 id); int zynqmp_pmufw_config_close(void); -void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size); +int zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size); int xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 *ret_payload); int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value); From 2e40ab1f215641c53d2c60baa347892d159cafc9 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 22 Jul 2022 02:46:55 -0600 Subject: [PATCH 24/48] firmware: zynqmp: Load config overlay for core0 to pmufw Try loading pmufw config overlay for core0, if it doesn't return any error it means pmufw is accepting nodes for other IP's. Otherwise dont try to load config object for any other IP, just return from zynqmp_pmufw_node function. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/20220722084658.30995-3-ashok.reddy.soma@xilinx.com --- drivers/firmware/firmware-zynqmp.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 325e4ddea6d..76ddc6b4f40 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -70,11 +70,20 @@ int zynqmp_pmufw_config_close(void) int zynqmp_pmufw_node(u32 id) { + static bool skip_config; + int ret; + + if (skip_config) + return 0; + /* Record power domain id */ xpm_configobject[NODE_ID_LOCATION] = id; - zynqmp_pmufw_load_config_object(xpm_configobject, - sizeof(xpm_configobject)); + ret = zynqmp_pmufw_load_config_object(xpm_configobject, + sizeof(xpm_configobject)); + + if (ret && id == NODE_APU_0) + skip_config = true; return 0; } @@ -284,6 +293,9 @@ static int zynqmp_power_probe(struct udevice *dev) ret >> ZYNQMP_PM_VERSION_MAJOR_SHIFT, ret & ZYNQMP_PM_VERSION_MINOR_MASK); + if (IS_ENABLED(CONFIG_ARCH_ZYNQMP)) + zynqmp_pmufw_node(NODE_APU_0); + return 0; }; From 7b4e365e49c76df88917883bd59dc9799131bac2 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 22 Jul 2022 02:46:56 -0600 Subject: [PATCH 25/48] arm64: zynqmp: Enable power domain driver Enable power domain driver to configure pmufw config object and request node for all the IP's that are enabled in DT. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/20220722084658.30995-4-ashok.reddy.soma@xilinx.com --- configs/xilinx_zynqmp_virt_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index 22ddbf31db4..e5ac26e0381 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -179,6 +179,8 @@ CONFIG_PHY_FIXED=y CONFIG_DM_ETH_PHY=y CONFIG_XILINX_AXIEMAC=y CONFIG_ZYNQ_GEM=y +CONFIG_POWER_DOMAIN=y +CONFIG_ZYNQMP_POWER_DOMAIN=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_PWM=y From cce33515010287a5bd7f4b6f9ebce0f56268a7f1 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 22 Jul 2022 02:46:57 -0600 Subject: [PATCH 26/48] mailbox: zynqmp: Move struct zynqmp_ipi_msg from sys_proto.h Mailbox driver might be need for Versal and other future platforms. To remove the dependency, move struct zynqmp_ipi_msg to zynqmp_firmware.h so that mailbox driver compiles for other platforms easily. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/20220722084658.30995-5-ashok.reddy.soma@xilinx.com --- arch/arm/mach-zynqmp/include/mach/sys_proto.h | 5 ----- drivers/mailbox/zynqmp-ipi.c | 2 +- include/zynqmp_firmware.h | 5 +++++ 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h index 1c12eac715e..9fffb4e541c 100644 --- a/arch/arm/mach-zynqmp/include/mach/sys_proto.h +++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h @@ -46,11 +46,6 @@ enum { TCM_SPLIT, }; -struct zynqmp_ipi_msg { - size_t len; - u32 *buf; -}; - int zynq_board_read_rom_ethaddr(unsigned char *ethaddr); unsigned int zynqmp_get_silicon_version(void); diff --git a/drivers/mailbox/zynqmp-ipi.c b/drivers/mailbox/zynqmp-ipi.c index 959cce923c5..3e4ec47389f 100644 --- a/drivers/mailbox/zynqmp-ipi.c +++ b/drivers/mailbox/zynqmp-ipi.c @@ -11,10 +11,10 @@ #include #include #include -#include #include #include #include +#include /* IPI bitmasks, register base */ /* TODO: move reg base to DT */ diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h index 52bc20f195e..f7a4a39d350 100644 --- a/include/zynqmp_firmware.h +++ b/include/zynqmp_firmware.h @@ -490,4 +490,9 @@ enum zynqmp_pm_request_ack { /* PM API versions */ #define PM_API_VERSION_2 2 +struct zynqmp_ipi_msg { + size_t len; + u32 *buf; +}; + #endif /* _ZYNQMP_FIRMWARE_H_ */ From 5f53e534ac15ad63ee530a43536b8da6c30cd36d Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 22 Jul 2022 02:46:58 -0600 Subject: [PATCH 27/48] arm64: versal: Enable power domain driver and its dependencies Enable power domain driver to configure pmufw config object and request node for all the IP's that are enabled in DT. This driver depends on mailbox and IPI driver, hence enable them as well. Add ARCH_VERSAL in the depends on of mailbox Kconfig to compile for Versal platforms. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/20220722084658.30995-6-ashok.reddy.soma@xilinx.com --- configs/xilinx_versal_virt_defconfig | 2 ++ drivers/mailbox/Kconfig | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index d2490fe7c50..7b5853143ef 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -69,6 +69,8 @@ CONFIG_FPGA_XILINX=y CONFIG_FPGA_VERSALPL=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_CADENCE=y +CONFIG_DM_MAILBOX=y +CONFIG_ZYNQMP_IPI=y CONFIG_MISC=y CONFIG_I2C_EEPROM=y CONFIG_SUPPORT_EMMC_BOOT=y diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index 73db2af0b81..acbdce11b7c 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -54,7 +54,7 @@ config K3_SEC_PROXY config ZYNQMP_IPI bool "Xilinx ZynqMP IPI controller support" - depends on DM_MAILBOX && ARCH_ZYNQMP + depends on DM_MAILBOX && (ARCH_ZYNQMP || ARCH_VERSAL) help This enables support for the Xilinx ZynqMP Inter Processor Interrupt communication controller. From e8ffc1dfcb1b4a7465ae7ec2b45569f0f27ff501 Mon Sep 17 00:00:00 2001 From: Alexander Dahl Date: Thu, 21 Jul 2022 15:31:21 +0200 Subject: [PATCH 28/48] fpga: Convert SYS_FPGA_CHECK_CTRLC to Kconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit 8cca60a2cbf2 ("Kconfig: Remove some symbols from the whitelist") downstream builds failed for boards setting this in include/configs/… Signed-off-by: Alexander Dahl Link: https://lore.kernel.org/r/20220721133122.32428-2-ada@thorsis.com Signed-off-by: Michal Simek --- README | 3 --- drivers/fpga/Kconfig | 6 ++++++ drivers/fpga/virtex2.c | 7 ------- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/README b/README index ff0df3797d2..8c31e5c0e39 100644 --- a/README +++ b/README @@ -1346,9 +1346,6 @@ The following options need to be configured: If defined, a function that provides delays in the FPGA configuration driver. - CONFIG_SYS_FPGA_CHECK_CTRLC - Allow Control-C to interrupt FPGA configuration - CONFIG_SYS_FPGA_CHECK_ERROR Check for configuration errors during FPGA bitfile diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 76719517f54..78d9588e4b7 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -91,4 +91,10 @@ config FPGA_ZYNQPL Enable FPGA driver for loading bitstream in BIT and BIN format on Xilinx Zynq devices. +config SYS_FPGA_CHECK_CTRLC + bool "Allow Control-C to interrupt FPGA configuration" + depends on FPGA + help + User can interrupt FPGA configuration by pressing CTRL+C. + endmenu diff --git a/drivers/fpga/virtex2.c b/drivers/fpga/virtex2.c index b3e0537bab0..0fd2290e3d3 100644 --- a/drivers/fpga/virtex2.c +++ b/drivers/fpga/virtex2.c @@ -45,13 +45,6 @@ #define CONFIG_SYS_FPGA_PROG_FEEDBACK #endif -/* - * Don't allow config cycle to be interrupted - */ -#ifndef CONFIG_SYS_FPGA_CHECK_CTRLC -#undef CONFIG_SYS_FPGA_CHECK_CTRLC -#endif - /* * Check for errors during configuration by default */ From 8c09cb6f4dc5eda57d2e9e76ee8b0f4e2e340071 Mon Sep 17 00:00:00 2001 From: Alexander Dahl Date: Thu, 21 Jul 2022 15:31:22 +0200 Subject: [PATCH 29/48] fpga: Convert SYS_FPGA_PROG_FEEDBACK to Kconfig This converts the following to Kconfig: SYS_FPGA_PROG_FEEDBACK Signed-off-by: Alexander Dahl Link: https://lore.kernel.org/r/20220721133122.32428-3-ada@thorsis.com Signed-off-by: Michal Simek --- README | 4 ---- configs/astro_mcf5373l_defconfig | 1 + drivers/fpga/Kconfig | 7 +++++++ drivers/fpga/spartan2.c | 1 - drivers/fpga/virtex2.c | 4 ---- include/configs/astro_mcf5373l.h | 1 - scripts/config_whitelist.txt | 1 - 7 files changed, 8 insertions(+), 11 deletions(-) diff --git a/README b/README index 8c31e5c0e39..2c4bde0b329 100644 --- a/README +++ b/README @@ -1330,10 +1330,6 @@ The following options need to be configured: Enables support for FPGA family. (SPARTAN2, SPARTAN3, VIRTEX2, CYCLONE2, ACEX1K, ACEX) - CONFIG_SYS_FPGA_PROG_FEEDBACK - - Enable printing of hash marks during FPGA configuration. - CONFIG_SYS_FPGA_CHECK_BUSY Enable checks on FPGA configuration interface busy diff --git a/configs/astro_mcf5373l_defconfig b/configs/astro_mcf5373l_defconfig index 3a44c7e8ec9..9f5cb8702c6 100644 --- a/configs/astro_mcf5373l_defconfig +++ b/configs/astro_mcf5373l_defconfig @@ -33,6 +33,7 @@ CONFIG_FPGA_ALTERA=y CONFIG_FPGA_CYCLON2=y CONFIG_FPGA_XILINX=y CONFIG_FPGA_SPARTAN3=y +CONFIG_SYS_FPGA_PROG_FEEDBACK=y CONFIG_SYS_I2C_LEGACY=y CONFIG_SYS_I2C_FSL=y CONFIG_SYS_FSL_I2C_OFFSET=0x58000 diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 78d9588e4b7..696ea92c6e9 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -97,4 +97,11 @@ config SYS_FPGA_CHECK_CTRLC help User can interrupt FPGA configuration by pressing CTRL+C. +config SYS_FPGA_PROG_FEEDBACK + bool "Progress output during FPGA configuration" + depends on FPGA + default y if FPGA_VIRTEX2 + help + Enable printing of hash marks during FPGA configuration. + endmenu diff --git a/drivers/fpga/spartan2.c b/drivers/fpga/spartan2.c index 3435400e58b..fe37752210b 100644 --- a/drivers/fpga/spartan2.c +++ b/drivers/fpga/spartan2.c @@ -15,7 +15,6 @@ #endif #undef CONFIG_SYS_FPGA_CHECK_BUSY -#undef CONFIG_SYS_FPGA_PROG_FEEDBACK /* Note: The assumption is that we cannot possibly run fast enough to * overrun the device (the Slave Parallel mode can free run at 50MHz). diff --git a/drivers/fpga/virtex2.c b/drivers/fpga/virtex2.c index 0fd2290e3d3..2e764bdcd52 100644 --- a/drivers/fpga/virtex2.c +++ b/drivers/fpga/virtex2.c @@ -41,10 +41,6 @@ #define CONFIG_FPGA_DELAY() #endif -#ifndef CONFIG_SYS_FPGA_PROG_FEEDBACK -#define CONFIG_SYS_FPGA_PROG_FEEDBACK -#endif - /* * Check for errors during configuration by default */ diff --git a/include/configs/astro_mcf5373l.h b/include/configs/astro_mcf5373l.h index a8265e961a2..da4d49741d2 100644 --- a/include/configs/astro_mcf5373l.h +++ b/include/configs/astro_mcf5373l.h @@ -131,7 +131,6 @@ * it needs non-blocking CFI routines. */ -#define CONFIG_SYS_FPGA_PROG_FEEDBACK #define CONFIG_SYS_FPGA_WAIT 1000 /* End of user parameters to be customized */ diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index efc2f3bcf71..fc07c5d2579 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -743,7 +743,6 @@ CONFIG_SYS_FPGA_FTIM0 CONFIG_SYS_FPGA_FTIM1 CONFIG_SYS_FPGA_FTIM2 CONFIG_SYS_FPGA_FTIM3 -CONFIG_SYS_FPGA_PROG_FEEDBACK CONFIG_SYS_FPGA_SIZE CONFIG_SYS_FPGA_WAIT CONFIG_SYS_FSL_BMAN_ADDR From fb2b88567d3b06095b089e70f75160a107710ea8 Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:02 +0300 Subject: [PATCH 30/48] fpga: add option for loading FPGA secure bitstreams It allows using this feature without enabling the "fpga loads" command. Signed-off-by: Oleksandr Suvorov Co-developed-by: Adrian Fiergolski Signed-off-by: Adrian Fiergolski Tested-by: Ricardo Salveti Tested-by: Adrian Fiergolski Link: https://lore.kernel.org/r/20220722141614.297383-2-oleksandr.suvorov@foundries.io Signed-off-by: Michal Simek --- cmd/Kconfig | 3 ++- drivers/fpga/Kconfig | 14 ++++++++++++++ drivers/fpga/fpga.c | 2 +- drivers/fpga/xilinx.c | 2 +- drivers/fpga/zynqmppl.c | 4 ++-- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index b3820f1e043..a8260aa170d 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1038,8 +1038,9 @@ config CMD_FPGA_LOADP a partial bitstream. config CMD_FPGA_LOAD_SECURE - bool "fpga loads - loads secure bitstreams (Xilinx only)" + bool "fpga loads - loads secure bitstreams" depends on CMD_FPGA + select FPGA_LOAD_SECURE help Enables the fpga loads command which is used to load secure (authenticated or encrypted or both) bitstreams on to FPGA. diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 696ea92c6e9..e07a9cf80ea 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -104,4 +104,18 @@ config SYS_FPGA_PROG_FEEDBACK help Enable printing of hash marks during FPGA configuration. +config FPGA_LOAD_SECURE + bool "Enable loading secure bitstreams" + depends on FPGA + help + Enables the fpga loads() functions that are used to load secure + (authenticated or encrypted or both) bitstreams on to FPGA. + +config SPL_FPGA_LOAD_SECURE + bool "Enable loading secure bitstreams for SPL" + depends on SPL_FPGA + help + Enables the fpga loads() functions that are used to load secure + (authenticated or encrypted or both) bitstreams on to FPGA. + endmenu diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c index fe3dfa12335..3b0a44b2420 100644 --- a/drivers/fpga/fpga.c +++ b/drivers/fpga/fpga.c @@ -220,7 +220,7 @@ int fpga_fsload(int devnum, const void *buf, size_t size, } #endif -#if defined(CONFIG_CMD_FPGA_LOAD_SECURE) +#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) int fpga_loads(int devnum, const void *buf, size_t size, struct fpga_secure_info *fpga_sec_info) { diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c index cbebefb55fe..6bc1bc491fb 100644 --- a/drivers/fpga/xilinx.c +++ b/drivers/fpga/xilinx.c @@ -172,7 +172,7 @@ int xilinx_loadfs(xilinx_desc *desc, const void *buf, size_t bsize, } #endif -#if defined(CONFIG_CMD_FPGA_LOAD_SECURE) +#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) int xilinx_loads(xilinx_desc *desc, const void *buf, size_t bsize, struct fpga_secure_info *fpga_sec_info) { diff --git a/drivers/fpga/zynqmppl.c b/drivers/fpga/zynqmppl.c index 6b394869dbf..8ff12bf50a0 100644 --- a/drivers/fpga/zynqmppl.c +++ b/drivers/fpga/zynqmppl.c @@ -245,7 +245,7 @@ static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize, return ret; } -#if defined(CONFIG_CMD_FPGA_LOAD_SECURE) && !defined(CONFIG_SPL_BUILD) +#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) static int zynqmp_loads(xilinx_desc *desc, const void *buf, size_t bsize, struct fpga_secure_info *fpga_sec_info) { @@ -306,7 +306,7 @@ static int zynqmp_pcap_info(xilinx_desc *desc) struct xilinx_fpga_op zynqmp_op = { .load = zynqmp_load, -#if defined(CONFIG_CMD_FPGA_LOAD_SECURE) && !defined(CONFIG_SPL_BUILD) +#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) .loads = zynqmp_loads, #endif .info = zynqmp_pcap_info, From f18adf106576f298ead743a02800c6fdc90d884c Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:03 +0300 Subject: [PATCH 31/48] fpga: xilinx: add missed identifier names Function definition arguments should also have identifier names. Add missed ones to struct xilinx_fpga_op callbacks, unifying code. Signed-off-by: Oleksandr Suvorov Tested-by: Ricardo Salveti Tested-by: Adrian Fiergolski Link: https://lore.kernel.org/r/20220722141614.297383-3-oleksandr.suvorov@foundries.io Signed-off-by: Michal Simek --- include/xilinx.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/xilinx.h b/include/xilinx.h index ab4537becfa..362943bc717 100644 --- a/include/xilinx.h +++ b/include/xilinx.h @@ -48,12 +48,14 @@ typedef struct { /* typedef xilinx_desc */ } xilinx_desc; /* end, typedef xilinx_desc */ struct xilinx_fpga_op { - int (*load)(xilinx_desc *, const void *, size_t, bitstream_type); - int (*loadfs)(xilinx_desc *, const void *, size_t, fpga_fs_info *); + int (*load)(xilinx_desc *desc, const void *buf, size_t bsize, + bitstream_type bstype); + int (*loadfs)(xilinx_desc *desc, const void *buf, size_t bsize, + fpga_fs_info *fpga_fsinfo); int (*loads)(xilinx_desc *desc, const void *buf, size_t bsize, struct fpga_secure_info *fpga_sec_info); - int (*dump)(xilinx_desc *, const void *, size_t); - int (*info)(xilinx_desc *); + int (*dump)(xilinx_desc *desc, const void *buf, size_t bsize); + int (*info)(xilinx_desc *desc); }; /* Generic Xilinx Functions From d7fcbfc19b4e83930a90c834046d4bf7dc3adefe Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:04 +0300 Subject: [PATCH 32/48] fpga: xilinx: add bitstream flags to driver desc Store a set of supported bitstream types in xilinx_desc structure. It will be used to determine whether an FPGA image is able to be loaded with a given driver. Signed-off-by: Oleksandr Suvorov Tested-by: Ricardo Salveti Tested-by: Adrian Fiergolski Link: https://lore.kernel.org/r/20220722141614.297383-4-oleksandr.suvorov@foundries.io Signed-off-by: Michal Simek --- arch/arm/mach-zynq/cpu.c | 1 + board/xilinx/versal/board.c | 5 ++++- board/xilinx/zynqmp/zynqmp.c | 5 ++++- include/versalpl.h | 3 --- include/xilinx.h | 4 ++++ include/zynqmppl.h | 3 +-- 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-zynq/cpu.c b/arch/arm/mach-zynq/cpu.c index 69b818f24b8..ac595ee0a27 100644 --- a/arch/arm/mach-zynq/cpu.c +++ b/arch/arm/mach-zynq/cpu.c @@ -22,6 +22,7 @@ xilinx_desc fpga = { .family = xilinx_zynq, .iface = devcfg, .operations = &zynq_op, + .flags = FPGA_LEGACY, }; #endif diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c index 81663e0cd0e..d8f39be56c8 100644 --- a/board/xilinx/versal/board.c +++ b/board/xilinx/versal/board.c @@ -27,7 +27,10 @@ DECLARE_GLOBAL_DATA_PTR; #if defined(CONFIG_FPGA_VERSALPL) -static xilinx_desc versalpl = XILINX_VERSAL_DESC; +static xilinx_desc versalpl = { + xilinx_versal, csu_dma, 1, &versal_op, 0, &versal_op, NULL, + FPGA_LEGACY +}; #endif int board_init(void) diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index f7c6e3ed4e3..57259b60a02 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -48,7 +48,10 @@ DECLARE_GLOBAL_DATA_PTR; #if CONFIG_IS_ENABLED(FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) -static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC; +static xilinx_desc zynqmppl = { + xilinx_zynqmp, csu_dma, 1, &zynqmp_op, 0, &zynqmp_op, NULL, + ZYNQMP_FPGA_FLAGS +}; #endif int __maybe_unused psu_uboot_init(void) diff --git a/include/versalpl.h b/include/versalpl.h index b94c82e6e66..0cc101be2f8 100644 --- a/include/versalpl.h +++ b/include/versalpl.h @@ -14,7 +14,4 @@ extern struct xilinx_fpga_op versal_op; -#define XILINX_VERSAL_DESC \ -{ xilinx_versal, csu_dma, 1, &versal_op, 0, &versal_op } - #endif /* _VERSALPL_H_ */ diff --git a/include/xilinx.h b/include/xilinx.h index 362943bc717..d9e4b8da968 100644 --- a/include/xilinx.h +++ b/include/xilinx.h @@ -37,6 +37,9 @@ typedef enum { /* typedef xilinx_family */ max_xilinx_type /* insert all new types before this */ } xilinx_family; /* end, typedef xilinx_family */ +/* FPGA bitstream supported types */ +#define FPGA_LEGACY BIT(0) + typedef struct { /* typedef xilinx_desc */ xilinx_family family; /* part type */ xilinx_iface iface; /* interface type */ @@ -45,6 +48,7 @@ typedef struct { /* typedef xilinx_desc */ int cookie; /* implementation specific cookie */ struct xilinx_fpga_op *operations; /* operations */ char *name; /* device name in bitstream */ + int flags; /* compatible flags */ } xilinx_desc; /* end, typedef xilinx_desc */ struct xilinx_fpga_op { diff --git a/include/zynqmppl.h b/include/zynqmppl.h index 35cfe17d444..8401a850afb 100644 --- a/include/zynqmppl.h +++ b/include/zynqmppl.h @@ -25,7 +25,6 @@ extern struct xilinx_fpga_op zynqmp_op; -#define XILINX_ZYNQMP_DESC \ -{ xilinx_zynqmp, csu_dma, 1, &zynqmp_op, 0, &zynqmp_op } +#define ZYNQMP_FPGA_FLAGS (FPGA_LEGACY) #endif /* _ZYNQMPPL_H_ */ From 24307b06b71a3c9b4aa556eefdad1f8fcca116bd Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:05 +0300 Subject: [PATCH 33/48] fpga: zynqmp: add str2flags call Add a call to convert FPGA "compatible" string to a binary flag. Signed-off-by: Oleksandr Suvorov Tested-by: Ricardo Salveti Tested-by: Adrian Fiergolski Link: https://lore.kernel.org/r/20220722141614.297383-5-oleksandr.suvorov@foundries.io Signed-off-by: Michal Simek --- drivers/fpga/zynqmppl.c | 11 ++++++++++- include/xilinx.h | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/fpga/zynqmppl.c b/drivers/fpga/zynqmppl.c index 8ff12bf50a0..19d079c9d9f 100644 --- a/drivers/fpga/zynqmppl.c +++ b/drivers/fpga/zynqmppl.c @@ -304,10 +304,19 @@ static int zynqmp_pcap_info(xilinx_desc *desc) return ret; } +static int __maybe_unused zynqmp_str2flag(xilinx_desc *desc, const char *str) +{ + if (!strncmp(str, "u-boot,fpga-legacy", 18)) + return FPGA_LEGACY; + + return 0; +} + struct xilinx_fpga_op zynqmp_op = { .load = zynqmp_load, + .info = zynqmp_pcap_info, #if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) .loads = zynqmp_loads, + .str2flag = zynqmp_str2flag, #endif - .info = zynqmp_pcap_info, }; diff --git a/include/xilinx.h b/include/xilinx.h index d9e4b8da968..ff5486d98a7 100644 --- a/include/xilinx.h +++ b/include/xilinx.h @@ -60,6 +60,9 @@ struct xilinx_fpga_op { struct fpga_secure_info *fpga_sec_info); int (*dump)(xilinx_desc *desc, const void *buf, size_t bsize); int (*info)(xilinx_desc *desc); +#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) + int (*str2flag)(xilinx_desc *desc, const char *string); +#endif }; /* Generic Xilinx Functions From 7a9a0df89bf1cb9f7e78378f946f1d9c9b002d72 Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:06 +0300 Subject: [PATCH 34/48] fpga: xilinx: pass compatible flags to xilinx_load() This flag is used to check whether a Xilinx FPGA driver is able to load a particular FPGA bitstream image. Signed-off-by: Oleksandr Suvorov Tested-by: Ricardo Salveti Tested-by: Adrian Fiergolski Link: https://lore.kernel.org/r/20220722141614.297383-6-oleksandr.suvorov@foundries.io Signed-off-by: Michal Simek --- drivers/fpga/fpga.c | 2 +- drivers/fpga/xilinx.c | 2 +- include/xilinx.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c index 3b0a44b2420..efbac9f0c47 100644 --- a/drivers/fpga/fpga.c +++ b/drivers/fpga/fpga.c @@ -263,7 +263,7 @@ int fpga_load(int devnum, const void *buf, size_t bsize, bitstream_type bstype) case fpga_xilinx: #if defined(CONFIG_FPGA_XILINX) ret_val = xilinx_load(desc->devdesc, buf, bsize, - bstype); + bstype, 0); #else fpga_no_sup((char *)__func__, "Xilinx devices"); #endif diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c index 6bc1bc491fb..5dd721575ec 100644 --- a/drivers/fpga/xilinx.c +++ b/drivers/fpga/xilinx.c @@ -139,7 +139,7 @@ int fpga_loadbitstream(int devnum, char *fpgadata, size_t size, } int xilinx_load(xilinx_desc *desc, const void *buf, size_t bsize, - bitstream_type bstype) + bitstream_type bstype, int flags) { if (!xilinx_validate (desc, (char *)__FUNCTION__)) { printf ("%s: Invalid device descriptor\n", __FUNCTION__); diff --git a/include/xilinx.h b/include/xilinx.h index ff5486d98a7..0bbf14d8a1d 100644 --- a/include/xilinx.h +++ b/include/xilinx.h @@ -68,7 +68,7 @@ struct xilinx_fpga_op { /* Generic Xilinx Functions *********************************************************************/ int xilinx_load(xilinx_desc *desc, const void *image, size_t size, - bitstream_type bstype); + bitstream_type bstype, int flags); int xilinx_dump(xilinx_desc *desc, const void *buf, size_t bsize); int xilinx_info(xilinx_desc *desc); int xilinx_loadfs(xilinx_desc *desc, const void *buf, size_t bsize, From 282eed50ecb73c20dd35bf3ea7a579e79b20cd54 Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:07 +0300 Subject: [PATCH 35/48] fpga: pass compatible flags to fpga_load() These flags may be used to check whether an FPGA driver is able to load a particular FPGA bitstream image. Signed-off-by: Oleksandr Suvorov Tested-by: Ricardo Salveti Tested-by: Adrian Fiergolski Link: https://lore.kernel.org/r/20220722141614.297383-7-oleksandr.suvorov@foundries.io Signed-off-by: Michal Simek --- boot/image-board.c | 4 ++-- cmd/fpga.c | 8 ++++---- common/spl/spl_fit.c | 6 ++++-- drivers/fpga/fpga.c | 5 +++-- drivers/fpga/xilinx.c | 2 +- include/fpga.h | 2 +- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/boot/image-board.c b/boot/image-board.c index 03c866b5fa8..b846bff2491 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -705,14 +705,14 @@ int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, img_len, BIT_FULL); if (err) err = fpga_load(devnum, (const void *)img_data, - img_len, BIT_FULL); + img_len, BIT_FULL, 0); } else { name = "partial"; err = fpga_loadbitstream(devnum, (char *)img_data, img_len, BIT_PARTIAL); if (err) err = fpga_load(devnum, (const void *)img_data, - img_len, BIT_PARTIAL); + img_len, BIT_PARTIAL, 0); } if (err) diff --git a/cmd/fpga.c b/cmd/fpga.c index 3fdd0b35e80..c4651dd403e 100644 --- a/cmd/fpga.c +++ b/cmd/fpga.c @@ -178,7 +178,7 @@ static int do_fpga_load(struct cmd_tbl *cmdtp, int flag, int argc, if (ret) return ret; - return fpga_load(dev, (void *)fpga_data, data_size, BIT_FULL); + return fpga_load(dev, (void *)fpga_data, data_size, BIT_FULL, 0); } static int do_fpga_loadb(struct cmd_tbl *cmdtp, int flag, int argc, @@ -209,7 +209,7 @@ static int do_fpga_loadp(struct cmd_tbl *cmdtp, int flag, int argc, if (ret) return ret; - return fpga_load(dev, (void *)fpga_data, data_size, BIT_PARTIAL); + return fpga_load(dev, (void *)fpga_data, data_size, BIT_PARTIAL, 0); } #endif @@ -315,7 +315,7 @@ static int do_fpga_loadmk(struct cmd_tbl *cmdtp, int flag, int argc, data_size = image_get_data_size(hdr); } return fpga_load(dev, (void *)data, data_size, - BIT_FULL); + BIT_FULL, 0); } #endif #if defined(CONFIG_FIT) @@ -355,7 +355,7 @@ static int do_fpga_loadmk(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_FAILURE; } - return fpga_load(dev, fit_data, data_size, BIT_FULL); + return fpga_load(dev, fit_data, data_size, BIT_FULL, 0); } #endif default: diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 1bbf824684a..3c5a91916cc 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -581,6 +581,8 @@ static int spl_fit_upload_fpga(struct spl_fit_info *ctx, int node, { const char *compatible; int ret; + int devnum = 0; + int flags = 0; debug("FPGA bitstream at: %x, size: %x\n", (u32)fpga_image->load_addr, fpga_image->size); @@ -591,8 +593,8 @@ static int spl_fit_upload_fpga(struct spl_fit_info *ctx, int node, else if (strcmp(compatible, "u-boot,fpga-legacy")) printf("Ignoring compatible = %s property\n", compatible); - ret = fpga_load(0, (void *)fpga_image->load_addr, fpga_image->size, - BIT_FULL); + ret = fpga_load(devnum, (void *)fpga_image->load_addr, + fpga_image->size, BIT_FULL, flags); if (ret) { printf("%s: Cannot load the image to the FPGA\n", __func__); return ret; diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c index efbac9f0c47..185bd547cb5 100644 --- a/drivers/fpga/fpga.c +++ b/drivers/fpga/fpga.c @@ -252,7 +252,8 @@ int fpga_loads(int devnum, const void *buf, size_t size, /* * Generic multiplexing code */ -int fpga_load(int devnum, const void *buf, size_t bsize, bitstream_type bstype) +int fpga_load(int devnum, const void *buf, size_t bsize, bitstream_type bstype, + int flags) { int ret_val = FPGA_FAIL; /* assume failure */ const fpga_desc *desc = fpga_validate(devnum, buf, bsize, @@ -263,7 +264,7 @@ int fpga_load(int devnum, const void *buf, size_t bsize, bitstream_type bstype) case fpga_xilinx: #if defined(CONFIG_FPGA_XILINX) ret_val = xilinx_load(desc->devdesc, buf, bsize, - bstype, 0); + bstype, flags); #else fpga_no_sup((char *)__func__, "Xilinx devices"); #endif diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c index 5dd721575ec..d9951ca3ecf 100644 --- a/drivers/fpga/xilinx.c +++ b/drivers/fpga/xilinx.c @@ -135,7 +135,7 @@ int fpga_loadbitstream(int devnum, char *fpgadata, size_t size, dataptr += 4; printf(" bytes in bitstream = %d\n", swapsize); - return fpga_load(devnum, dataptr, swapsize, bstype); + return fpga_load(devnum, dataptr, swapsize, bstype, 0); } int xilinx_load(xilinx_desc *desc, const void *buf, size_t bsize, diff --git a/include/fpga.h b/include/fpga.h index ec5144334df..6365e1569e3 100644 --- a/include/fpga.h +++ b/include/fpga.h @@ -64,7 +64,7 @@ int fpga_count(void); const fpga_desc *const fpga_get_desc(int devnum); int fpga_is_partial_data(int devnum, size_t img_len); int fpga_load(int devnum, const void *buf, size_t bsize, - bitstream_type bstype); + bitstream_type bstype, int flags); int fpga_fsload(int devnum, const void *buf, size_t size, fpga_fs_info *fpga_fsinfo); int fpga_loads(int devnum, const void *buf, size_t size, From 2c60514d9aecf7fbbbe3c4cb3a4a4acc421e5239 Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:08 +0300 Subject: [PATCH 36/48] fpga: add fpga_compatible2flag Add a "compatible" string to binary flag converter, which uses a callback str2flag() of given FPGA driver if available. Signed-off-by: Oleksandr Suvorov Tested-by: Ricardo Salveti Tested-by: Adrian Fiergolski Link: https://lore.kernel.org/r/20220722141614.297383-8-oleksandr.suvorov@foundries.io Signed-off-by: Michal Simek --- drivers/fpga/fpga.c | 26 ++++++++++++++++++++++++++ include/fpga.h | 1 + 2 files changed, 27 insertions(+) diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c index 185bd547cb5..4db5c0a91e9 100644 --- a/drivers/fpga/fpga.c +++ b/drivers/fpga/fpga.c @@ -357,3 +357,29 @@ int fpga_info(int devnum) return fpga_dev_info(devnum); } + +#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) +int fpga_compatible2flag(int devnum, const char *compatible) +{ + const fpga_desc * const desc = fpga_get_desc(devnum); + + if (!desc) + return 0; + + switch (desc->devtype) { +#if defined(CONFIG_FPGA_XILINX) + case fpga_xilinx: + { + xilinx_desc *xdesc = (xilinx_desc *)desc->devdesc; + + if (xdesc->operations && xdesc->operations->str2flag) + return xdesc->operations->str2flag(xdesc, compatible); + } +#endif + default: + break; + } + + return 0; +} +#endif diff --git a/include/fpga.h b/include/fpga.h index 6365e1569e3..13b1bbee3ca 100644 --- a/include/fpga.h +++ b/include/fpga.h @@ -75,5 +75,6 @@ int fpga_dump(int devnum, const void *buf, size_t bsize); int fpga_info(int devnum); const fpga_desc *const fpga_validate(int devnum, const void *buf, size_t bsize, char *fn); +int fpga_compatible2flag(int devnum, const char *compatible); #endif /* _FPGA_H_ */ From 71f1a5392aadb5b6a43523b46040dea2ffbdd2ba Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:09 +0300 Subject: [PATCH 37/48] spl: fit: pass real compatible flags to fpga_load() Convert taken FPGA image "compatible" string to a binary compatible flag and pass it to an FPGA driver. Signed-off-by: Oleksandr Suvorov Tested-by: Ricardo Salveti Tested-by: Adrian Fiergolski Link: https://lore.kernel.org/r/20220722141614.297383-9-oleksandr.suvorov@foundries.io Signed-off-by: Michal Simek --- common/spl/spl_fit.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 3c5a91916cc..a35be529656 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -588,10 +588,15 @@ static int spl_fit_upload_fpga(struct spl_fit_info *ctx, int node, (u32)fpga_image->load_addr, fpga_image->size); compatible = fdt_getprop(ctx->fit, node, "compatible", NULL); - if (!compatible) + if (!compatible) { warn_deprecated("'fpga' image without 'compatible' property"); - else if (strcmp(compatible, "u-boot,fpga-legacy")) - printf("Ignoring compatible = %s property\n", compatible); + } else { + if (CONFIG_IS_ENABLED(FPGA_LOAD_SECURE)) + flags = fpga_compatible2flag(devnum, compatible); + if (strcmp(compatible, "u-boot,fpga-legacy")) + debug("Ignoring compatible = %s property\n", + compatible); + } ret = fpga_load(devnum, (void *)fpga_image->load_addr, fpga_image->size, BIT_FULL, flags); From 3e78481de94d94f753bbf05486734b8da394643f Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:10 +0300 Subject: [PATCH 38/48] fpga: xilinx: pass compatible flags to load() callback These flags may be used to check whether an FPGA driver is able to load a particular FPGA bitstream image. Signed-off-by: Oleksandr Suvorov Tested-by: Ricardo Salveti Tested-by: Adrian Fiergolski Link: https://lore.kernel.org/r/20220722141614.297383-10-oleksandr.suvorov@foundries.io Signed-off-by: Michal Simek --- drivers/fpga/spartan2.c | 2 +- drivers/fpga/spartan3.c | 2 +- drivers/fpga/versalpl.c | 2 +- drivers/fpga/virtex2.c | 2 +- drivers/fpga/xilinx.c | 2 +- drivers/fpga/zynqmppl.c | 2 +- drivers/fpga/zynqpl.c | 2 +- include/xilinx.h | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/fpga/spartan2.c b/drivers/fpga/spartan2.c index fe37752210b..47692e32076 100644 --- a/drivers/fpga/spartan2.c +++ b/drivers/fpga/spartan2.c @@ -40,7 +40,7 @@ static int spartan2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize); /* ------------------------------------------------------------------------- */ /* Spartan-II Generic Implementation */ static int spartan2_load(xilinx_desc *desc, const void *buf, size_t bsize, - bitstream_type bstype) + bitstream_type bstype, int flags) { int ret_val = FPGA_FAIL; diff --git a/drivers/fpga/spartan3.c b/drivers/fpga/spartan3.c index 4850c99352d..918f6db5065 100644 --- a/drivers/fpga/spartan3.c +++ b/drivers/fpga/spartan3.c @@ -45,7 +45,7 @@ static int spartan3_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize); /* ------------------------------------------------------------------------- */ /* Spartan-II Generic Implementation */ static int spartan3_load(xilinx_desc *desc, const void *buf, size_t bsize, - bitstream_type bstype) + bitstream_type bstype, int flags) { int ret_val = FPGA_FAIL; diff --git a/drivers/fpga/versalpl.c b/drivers/fpga/versalpl.c index c44a7d34557..d3876a8f541 100644 --- a/drivers/fpga/versalpl.c +++ b/drivers/fpga/versalpl.c @@ -27,7 +27,7 @@ static ulong versal_align_dma_buffer(ulong *buf, u32 len) } static int versal_load(xilinx_desc *desc, const void *buf, size_t bsize, - bitstream_type bstype) + bitstream_type bstype, int flags) { ulong bin_buf; int ret; diff --git a/drivers/fpga/virtex2.c b/drivers/fpga/virtex2.c index 2e764bdcd52..51b8d312056 100644 --- a/drivers/fpga/virtex2.c +++ b/drivers/fpga/virtex2.c @@ -83,7 +83,7 @@ static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize); static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize); static int virtex2_load(xilinx_desc *desc, const void *buf, size_t bsize, - bitstream_type bstype) + bitstream_type bstype, int flags) { int ret_val = FPGA_FAIL; diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c index d9951ca3ecf..8170c3368ef 100644 --- a/drivers/fpga/xilinx.c +++ b/drivers/fpga/xilinx.c @@ -151,7 +151,7 @@ int xilinx_load(xilinx_desc *desc, const void *buf, size_t bsize, return FPGA_FAIL; } - return desc->operations->load(desc, buf, bsize, bstype); + return desc->operations->load(desc, buf, bsize, bstype, flags); } #if defined(CONFIG_CMD_FPGA_LOADFS) diff --git a/drivers/fpga/zynqmppl.c b/drivers/fpga/zynqmppl.c index 19d079c9d9f..a0624567882 100644 --- a/drivers/fpga/zynqmppl.c +++ b/drivers/fpga/zynqmppl.c @@ -200,7 +200,7 @@ static int zynqmp_validate_bitstream(xilinx_desc *desc, const void *buf, } static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize, - bitstream_type bstype) + bitstream_type bstype, int flags) { ALLOC_CACHE_ALIGN_BUFFER(u32, bsizeptr, 1); u32 swap = 0; diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index 2de40109a81..d8ebd542abd 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -371,7 +371,7 @@ static int zynq_validate_bitstream(xilinx_desc *desc, const void *buf, } static int zynq_load(xilinx_desc *desc, const void *buf, size_t bsize, - bitstream_type bstype) + bitstream_type bstype, int flags) { unsigned long ts; /* Timestamp */ u32 isr_status, swap; diff --git a/include/xilinx.h b/include/xilinx.h index 0bbf14d8a1d..e5f6db33fa2 100644 --- a/include/xilinx.h +++ b/include/xilinx.h @@ -53,7 +53,7 @@ typedef struct { /* typedef xilinx_desc */ struct xilinx_fpga_op { int (*load)(xilinx_desc *desc, const void *buf, size_t bsize, - bitstream_type bstype); + bitstream_type bstype, int flags); int (*loadfs)(xilinx_desc *desc, const void *buf, size_t bsize, fpga_fs_info *fpga_fsinfo); int (*loads)(xilinx_desc *desc, const void *buf, size_t bsize, From fcd91cb782c9c659c5db65c9aa5fb7e0497de1ec Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:11 +0300 Subject: [PATCH 39/48] fpga: zynqmp: reduce zynqmppl_load() code Reduce the function code by calling xilinx_pm_request() once only. Use the same variable bsize_req to store either bstream size in bytes or an address of bstream size according to a type required by the firmware version. Remove obsolete debug(). Signed-off-by: Oleksandr Suvorov Tested-by: Ricardo Salveti Tested-by: Adrian Fiergolski Link: https://lore.kernel.org/r/20220722141614.297383-11-oleksandr.suvorov@foundries.io Signed-off-by: Michal Simek --- drivers/fpga/zynqmppl.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/fpga/zynqmppl.c b/drivers/fpga/zynqmppl.c index a0624567882..2791f931861 100644 --- a/drivers/fpga/zynqmppl.c +++ b/drivers/fpga/zynqmppl.c @@ -207,38 +207,33 @@ static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize, ulong bin_buf; int ret; u32 buf_lo, buf_hi; + u32 bsize_req = (u32)bsize; u32 ret_payload[PAYLOAD_ARG_CNT]; - bool xilfpga_old = false; if (zynqmp_firmware_version() <= PMUFW_V1_0) { puts("WARN: PMUFW v1.0 or less is detected\n"); puts("WARN: Not all bitstream formats are supported\n"); puts("WARN: Please upgrade PMUFW\n"); - xilfpga_old = true; if (zynqmp_validate_bitstream(desc, buf, bsize, bsize, &swap)) return FPGA_FAIL; bsizeptr = (u32 *)&bsize; flush_dcache_range((ulong)bsizeptr, (ulong)bsizeptr + sizeof(size_t)); + bsize_req = (u32)(uintptr_t)bsizeptr; bstype |= BIT(ZYNQMP_FPGA_BIT_NS); + } else { + bstype = 0; } bin_buf = zynqmp_align_dma_buffer((u32 *)buf, bsize, swap); - debug("%s called!\n", __func__); flush_dcache_range(bin_buf, bin_buf + bsize); buf_lo = (u32)bin_buf; buf_hi = upper_32_bits(bin_buf); - if (xilfpga_old) - ret = xilinx_pm_request(PM_FPGA_LOAD, buf_lo, - buf_hi, (u32)(uintptr_t)bsizeptr, - bstype, ret_payload); - else - ret = xilinx_pm_request(PM_FPGA_LOAD, buf_lo, - buf_hi, (u32)bsize, 0, ret_payload); - + ret = xilinx_pm_request(PM_FPGA_LOAD, buf_lo, buf_hi, + bsize_req, bstype, ret_payload); if (ret) printf("PL FPGA LOAD failed with err: 0x%08x\n", ret); From 5ab6a846349471be9b640da35d757d55dd8de487 Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:12 +0300 Subject: [PATCH 40/48] fpga: zynqmp: add bitstream compatible checking Check whether the FPGA ZynqMP driver supports the given bitstream image type. Signed-off-by: Oleksandr Suvorov Tested-by: Ricardo Salveti Tested-by: Adrian Fiergolski Link: https://lore.kernel.org/r/20220722141614.297383-12-oleksandr.suvorov@foundries.io Signed-off-by: Michal Simek --- drivers/fpga/zynqmppl.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/fpga/zynqmppl.c b/drivers/fpga/zynqmppl.c index 2791f931861..feaf34fff11 100644 --- a/drivers/fpga/zynqmppl.c +++ b/drivers/fpga/zynqmppl.c @@ -199,6 +199,28 @@ static int zynqmp_validate_bitstream(xilinx_desc *desc, const void *buf, return 0; } +#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) +static int zynqmp_check_compatible(xilinx_desc *desc, int flags) +{ + /* If no flags set, the image is legacy */ + if (!flags) + return 0; + + /* For legacy bitstream images no need for other methods exist */ + if ((flags & desc->flags) && flags == FPGA_LEGACY) + return 0; + + /* + * Other images are handled in secure callback loads(). Check + * callback existence besides image type support. + */ + if (desc->operations->loads && (flags & desc->flags)) + return 0; + + return FPGA_FAIL; +} +#endif + static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize, bitstream_type bstype, int flags) { @@ -210,6 +232,18 @@ static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize, u32 bsize_req = (u32)bsize; u32 ret_payload[PAYLOAD_ARG_CNT]; +#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) + ret = zynqmp_check_compatible(desc, flags); + if (ret) { + if (ret != -ENODATA) { + puts("Missing loads() operation or unsupported bitstream type\n"); + return FPGA_FAIL; + } + /* If flags is not set, the image treats as legacy */ + flags = FPGA_LEGACY; + } +#endif + if (zynqmp_firmware_version() <= PMUFW_V1_0) { puts("WARN: PMUFW v1.0 or less is detected\n"); puts("WARN: Not all bitstream formats are supported\n"); From a3a1afb747d4d71c3dd5ba01b2796cebd65c65cd Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:13 +0300 Subject: [PATCH 41/48] fpga: zynqmp: support loading authenticated images Add supporting new compatible string "u-boot,zynqmp-fpga-ddrauth" to handle loading authenticated images (DDR). Based on solution by Jorge Ramirez-Ortiz Signed-off-by: Oleksandr Suvorov Tested-by: Ricardo Salveti Link: https://lore.kernel.org/r/20220722141614.297383-13-oleksandr.suvorov@foundries.io Signed-off-by: Michal Simek --- boot/Kconfig | 4 ++-- doc/uImage.FIT/source_file_format.txt | 5 +++- drivers/fpga/zynqmppl.c | 33 +++++++++++++++++++++++---- include/xilinx.h | 1 + include/zynqmppl.h | 4 ++++ 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/boot/Kconfig b/boot/Kconfig index 17438b566d5..59d0c65c944 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -210,8 +210,8 @@ config SPL_LOAD_FIT 1. "loadables" images, other than FDTs, which do not have a "load" property will not be loaded. This limitation also applies to FPGA images with the correct "compatible" string. - 2. For FPGA images, only the "compatible" = "u-boot,fpga-legacy" - loading method is supported. + 2. For FPGA images, the supported "compatible" list is in the + doc/uImage.FIT/source_file_format.txt. 3. FDTs are only loaded for images with an "os" property of "u-boot". "linux" images are also supported with Falcon boot mode. diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt index f93ac6d1c7b..461e2af2a84 100644 --- a/doc/uImage.FIT/source_file_format.txt +++ b/doc/uImage.FIT/source_file_format.txt @@ -184,7 +184,10 @@ the '/images' node should have the following layout: Mandatory for types: "firmware", and "kernel". - compatible : compatible method for loading image. Mandatory for types: "fpga", and images that do not specify a load address. - To use the generic fpga loading routine, use "u-boot,fpga-legacy". + Supported compatible methods: + "u-boot,fpga-legacy" - the generic fpga loading routine. + "u-boot,zynqmp-fpga-ddrauth" - signed non-encrypted FPGA bitstream for + Xilinx Zynq UltraScale+ (ZymqMP) device. Optional nodes: - hash-1 : Each hash sub-node represents separate hash or checksum diff --git a/drivers/fpga/zynqmppl.c b/drivers/fpga/zynqmppl.c index feaf34fff11..fc55d7a388f 100644 --- a/drivers/fpga/zynqmppl.c +++ b/drivers/fpga/zynqmppl.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -202,9 +203,12 @@ static int zynqmp_validate_bitstream(xilinx_desc *desc, const void *buf, #if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) static int zynqmp_check_compatible(xilinx_desc *desc, int flags) { - /* If no flags set, the image is legacy */ + /* + * If no flags set, the image may be legacy, but we need to + * signal caller this situation with specific error code. + */ if (!flags) - return 0; + return -ENODATA; /* For legacy bitstream images no need for other methods exist */ if ((flags & desc->flags) && flags == FPGA_LEGACY) @@ -217,7 +221,7 @@ static int zynqmp_check_compatible(xilinx_desc *desc, int flags) if (desc->operations->loads && (flags & desc->flags)) return 0; - return FPGA_FAIL; + return -ENODEV; } #endif @@ -231,8 +235,9 @@ static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize, u32 buf_lo, buf_hi; u32 bsize_req = (u32)bsize; u32 ret_payload[PAYLOAD_ARG_CNT]; - #if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) + struct fpga_secure_info info = { 0 }; + ret = zynqmp_check_compatible(desc, flags); if (ret) { if (ret != -ENODATA) { @@ -242,6 +247,21 @@ static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize, /* If flags is not set, the image treats as legacy */ flags = FPGA_LEGACY; } + + switch (flags) { + case FPGA_LEGACY: + break; /* Handle the legacy image later in this function */ +#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) + case FPGA_XILINX_ZYNQMP_DDRAUTH: + /* DDR authentication */ + info.authflag = ZYNQMP_FPGA_AUTH_DDR; + info.encflag = FPGA_NO_ENC_OR_NO_AUTH; + return desc->operations->loads(desc, buf, bsize, &info); +#endif + default: + printf("Unsupported bitstream type %d\n", flags); + return FPGA_FAIL; + } #endif if (zynqmp_firmware_version() <= PMUFW_V1_0) { @@ -337,7 +357,10 @@ static int __maybe_unused zynqmp_str2flag(xilinx_desc *desc, const char *str) { if (!strncmp(str, "u-boot,fpga-legacy", 18)) return FPGA_LEGACY; - +#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) + if (!strncmp(str, "u-boot,zynqmp-fpga-ddrauth", 26)) + return FPGA_XILINX_ZYNQMP_DDRAUTH; +#endif return 0; } diff --git a/include/xilinx.h b/include/xilinx.h index e5f6db33fa2..97ee12cec42 100644 --- a/include/xilinx.h +++ b/include/xilinx.h @@ -39,6 +39,7 @@ typedef enum { /* typedef xilinx_family */ /* FPGA bitstream supported types */ #define FPGA_LEGACY BIT(0) +#define FPGA_XILINX_ZYNQMP_DDRAUTH BIT(1) typedef struct { /* typedef xilinx_desc */ xilinx_family family; /* part type */ diff --git a/include/zynqmppl.h b/include/zynqmppl.h index 8401a850afb..87ccd2f394c 100644 --- a/include/zynqmppl.h +++ b/include/zynqmppl.h @@ -25,6 +25,10 @@ extern struct xilinx_fpga_op zynqmp_op; +#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) +#define ZYNQMP_FPGA_FLAGS (FPGA_LEGACY | FPGA_XILINX_ZYNQMP_DDRAUTH) +#else #define ZYNQMP_FPGA_FLAGS (FPGA_LEGACY) +#endif #endif /* _ZYNQMPPL_H_ */ From b524f8fb1e94a8e649ba06a7cb87e6dcaa96ebc3 Mon Sep 17 00:00:00 2001 From: Adrian Fiergolski Date: Fri, 22 Jul 2022 17:16:14 +0300 Subject: [PATCH 42/48] fpga: zynqmp: support loading encrypted bitfiles Add supporting new compatible string "u-boot,zynqmp-fpga-enc" to handle loading encrypted bitfiles. This feature requires encrypted FSBL, as according to UG1085: "The CSU automatically locks out the AES key, stored in either BBRAM or eFUSEs, as a key source to the AES engine if the FSBL is not encrypted. This prevents using the BBRAM or eFUSE as the key source to the AES engine during run-time applications." Signed-off-by: Adrian Fiergolski Co-developed-by: Oleksandr Suvorov Signed-off-by: Oleksandr Suvorov Tested-by: Adrian Fiergolski Link: https://lore.kernel.org/r/20220722141614.297383-14-oleksandr.suvorov@foundries.io Signed-off-by: Michal Simek --- doc/uImage.FIT/source_file_format.txt | 2 ++ drivers/fpga/zynqmppl.c | 8 ++++++++ include/fpga.h | 1 + include/xilinx.h | 1 + include/zynqmppl.h | 4 +++- 5 files changed, 15 insertions(+), 1 deletion(-) diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt index 461e2af2a84..68701118409 100644 --- a/doc/uImage.FIT/source_file_format.txt +++ b/doc/uImage.FIT/source_file_format.txt @@ -188,6 +188,8 @@ the '/images' node should have the following layout: "u-boot,fpga-legacy" - the generic fpga loading routine. "u-boot,zynqmp-fpga-ddrauth" - signed non-encrypted FPGA bitstream for Xilinx Zynq UltraScale+ (ZymqMP) device. + "u-boot,zynqmp-fpga-enc" - encrypted FPGA bitstream for Xilinx Zynq + UltraScale+ (ZynqMP) device. Optional nodes: - hash-1 : Each hash sub-node represents separate hash or checksum diff --git a/drivers/fpga/zynqmppl.c b/drivers/fpga/zynqmppl.c index fc55d7a388f..d1491da02c3 100644 --- a/drivers/fpga/zynqmppl.c +++ b/drivers/fpga/zynqmppl.c @@ -257,6 +257,11 @@ static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize, info.authflag = ZYNQMP_FPGA_AUTH_DDR; info.encflag = FPGA_NO_ENC_OR_NO_AUTH; return desc->operations->loads(desc, buf, bsize, &info); + case FPGA_XILINX_ZYNQMP_ENC: + /* Encryption using device key */ + info.authflag = FPGA_NO_ENC_OR_NO_AUTH; + info.encflag = FPGA_ENC_DEV_KEY; + return desc->operations->loads(desc, buf, bsize, &info); #endif default: printf("Unsupported bitstream type %d\n", flags); @@ -360,6 +365,9 @@ static int __maybe_unused zynqmp_str2flag(xilinx_desc *desc, const char *str) #if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) if (!strncmp(str, "u-boot,zynqmp-fpga-ddrauth", 26)) return FPGA_XILINX_ZYNQMP_DDRAUTH; + + if (!strncmp(str, "u-boot,zynqmp-fpga-enc", 22)) + return FPGA_XILINX_ZYNQMP_ENC; #endif return 0; } diff --git a/include/fpga.h b/include/fpga.h index 13b1bbee3ca..a4e16401da7 100644 --- a/include/fpga.h +++ b/include/fpga.h @@ -20,6 +20,7 @@ /* device numbers must be non-negative */ #define FPGA_INVALID_DEVICE -1 +#define FPGA_ENC_DEV_KEY 0 #define FPGA_ENC_USR_KEY 1 #define FPGA_NO_ENC_OR_NO_AUTH 2 diff --git a/include/xilinx.h b/include/xilinx.h index 97ee12cec42..e4e29797988 100644 --- a/include/xilinx.h +++ b/include/xilinx.h @@ -40,6 +40,7 @@ typedef enum { /* typedef xilinx_family */ /* FPGA bitstream supported types */ #define FPGA_LEGACY BIT(0) #define FPGA_XILINX_ZYNQMP_DDRAUTH BIT(1) +#define FPGA_XILINX_ZYNQMP_ENC BIT(2) typedef struct { /* typedef xilinx_desc */ xilinx_family family; /* part type */ diff --git a/include/zynqmppl.h b/include/zynqmppl.h index 87ccd2f394c..acf75a8f079 100644 --- a/include/zynqmppl.h +++ b/include/zynqmppl.h @@ -26,7 +26,9 @@ extern struct xilinx_fpga_op zynqmp_op; #if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) -#define ZYNQMP_FPGA_FLAGS (FPGA_LEGACY | FPGA_XILINX_ZYNQMP_DDRAUTH) +#define ZYNQMP_FPGA_FLAGS (FPGA_LEGACY | \ + FPGA_XILINX_ZYNQMP_DDRAUTH | \ + FPGA_XILINX_ZYNQMP_ENC) #else #define ZYNQMP_FPGA_FLAGS (FPGA_LEGACY) #endif From f2dd6599df65dd307d7170f1b2fc0d38eb44ad75 Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Sat, 16 Jul 2022 12:28:46 +0530 Subject: [PATCH 43/48] spi: xilinx_spi: Add support for spi memory operations Add support for spi memory operations for xilinx AXI qspi driver. This provides an high-level interface to execute SPI memory operations by the controller. Remove existing spi transfer based implementation and use spi memory based exec_op() implementation for qspi IO operations. Simplified existing startup_block implementation. Signed-off-by: T Karthik Reddy Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/1657954727-31972-2-git-send-email-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- drivers/spi/xilinx_spi.c | 192 +++++++++++++++++++++++---------------- 1 file changed, 115 insertions(+), 77 deletions(-) diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index b892cdae9ba..09d4b01631f 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -73,7 +74,7 @@ #define XILSPI_MAX_XFER_BITS 8 #define XILSPI_SPICR_DFLT_ON (SPICR_MANUAL_SS | SPICR_MASTER_MODE | \ - SPICR_SPE) + SPICR_SPE | SPICR_MASTER_INHIBIT) #define XILSPI_SPICR_DFLT_OFF (SPICR_MASTER_INHIBIT | SPICR_MANUAL_SS) #define XILINX_SPI_IDLE_VAL GENMASK(7, 0) @@ -119,6 +120,15 @@ static int xilinx_spi_probe(struct udevice *bus) writel(SPISSR_RESET_VALUE, ®s->srr); + /* + * Reset RX & TX FIFO + * Enable Manual Slave Select Assertion, + * Set SPI controller into master mode, and enable it + */ + writel(SPICR_RXFIFO_RESEST | SPICR_TXFIFO_RESEST | + SPICR_MANUAL_SS | SPICR_MASTER_MODE | SPICR_SPE, + ®s->spicr); + return 0; } @@ -136,7 +146,10 @@ static void spi_cs_deactivate(struct udevice *dev) struct udevice *bus = dev_get_parent(dev); struct xilinx_spi_priv *priv = dev_get_priv(bus); struct xilinx_spi_regs *regs = priv->regs; + u32 reg; + reg = readl(®s->spicr) | SPICR_RXFIFO_RESEST | SPICR_TXFIFO_RESEST; + writel(reg, ®s->spicr); writel(SPISSR_OFF, ®s->spissr); } @@ -205,81 +218,24 @@ static u32 xilinx_spi_read_rxfifo(struct udevice *bus, u8 *rxp, u32 rxbytes) return i; } -static void xilinx_spi_startup_block(struct udevice *dev, unsigned int bytes, - const void *dout, void *din) +static int start_transfer(struct spi_slave *spi, const void *dout, void *din, u32 len) { - struct udevice *bus = dev_get_parent(dev); + struct udevice *bus = spi->dev->parent; struct xilinx_spi_priv *priv = dev_get_priv(bus); struct xilinx_spi_regs *regs = priv->regs; - struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); - const unsigned char *txp = dout; - unsigned char *rxp = din; - u32 reg; - u32 txbytes = bytes; - u32 rxbytes = bytes; + u32 count, txbytes, rxbytes; + int reg, ret; + const unsigned char *txp = (const unsigned char *)dout; + unsigned char *rxp = (unsigned char *)din; - /* - * This loop runs two times. First time to send the command. - * Second time to transfer data. After transferring data, - * it sets txp to the initial value for the normal operation. - */ - for ( ; priv->startup < 2; priv->startup++) { - xilinx_spi_fill_txfifo(bus, txp, txbytes); - reg = readl(®s->spicr) & ~SPICR_MASTER_INHIBIT; + txbytes = len; + rxbytes = len; + while (txbytes || rxbytes) { + /* Disable master transaction */ + reg = readl(®s->spicr) | SPICR_MASTER_INHIBIT; writel(reg, ®s->spicr); - xilinx_spi_read_rxfifo(bus, rxp, rxbytes); - txp = din; - - if (priv->startup) { - spi_cs_deactivate(dev); - spi_cs_activate(dev, slave_plat->cs); - txp = dout; - } - } -} - -static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) -{ - struct udevice *bus = dev_get_parent(dev); - struct xilinx_spi_priv *priv = dev_get_priv(bus); - struct xilinx_spi_regs *regs = priv->regs; - struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); - /* assume spi core configured to do 8 bit transfers */ - unsigned int bytes = bitlen / XILSPI_MAX_XFER_BITS; - const unsigned char *txp = dout; - unsigned char *rxp = din; - u32 txbytes = bytes; - u32 rxbytes = bytes; - u32 reg, count; - int ret; - - debug("spi_xfer: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", - dev_seq(bus), slave_plat->cs, bitlen, bytes, flags); - - if (bitlen == 0) - goto done; - - if (bitlen % XILSPI_MAX_XFER_BITS) { - printf("XILSPI warning: Not a multiple of %d bits\n", - XILSPI_MAX_XFER_BITS); - flags |= SPI_XFER_END; - goto done; - } - - if (flags & SPI_XFER_BEGIN) - spi_cs_activate(dev, slave_plat->cs); - - /* - * This is the work around for the startup block issue in - * the spi controller. SPI clock is passing through STARTUP - * block to FLASH. STARTUP block don't provide clock as soon - * as QSPI provides command. So first command fails. - */ - xilinx_spi_startup_block(dev, bytes, dout, din); - - while (txbytes && rxbytes) { count = xilinx_spi_fill_txfifo(bus, txp, txbytes); + /* Enable master transaction */ reg = readl(®s->spicr) & ~SPICR_MASTER_INHIBIT; writel(reg, ®s->spicr); txbytes -= count; @@ -293,21 +249,99 @@ static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen, return ret; } - debug("txbytes:0x%x,txp:0x%p\n", txbytes, txp); + reg = readl(®s->spicr) | SPICR_MASTER_INHIBIT; + writel(reg, ®s->spicr); count = xilinx_spi_read_rxfifo(bus, rxp, rxbytes); rxbytes -= count; if (rxp) rxp += count; - debug("rxbytes:0x%x rxp:0x%p\n", rxbytes, rxp); } - done: - if (flags & SPI_XFER_END) - spi_cs_deactivate(dev); - return 0; } +static void xilinx_spi_startup_block(struct spi_slave *spi) +{ + struct dm_spi_slave_plat *slave_plat = + dev_get_parent_plat(spi->dev); + unsigned char txp; + unsigned char rxp[8]; + + /* + * Perform a dummy read as a work around for + * the startup block issue. + */ + spi_cs_activate(spi->dev, slave_plat->cs); + txp = 0x9f; + start_transfer(spi, (void *)&txp, NULL, 1); + + start_transfer(spi, NULL, (void *)rxp, 6); + + spi_cs_deactivate(spi->dev); +} + +static int xilinx_spi_mem_exec_op(struct spi_slave *spi, + const struct spi_mem_op *op) +{ + struct dm_spi_slave_plat *slave_plat = + dev_get_parent_plat(spi->dev); + static u32 startup; + u32 dummy_len, ret; + + /* + * This is the work around for the startup block issue in + * the spi controller. SPI clock is passing through STARTUP + * block to FLASH. STARTUP block don't provide clock as soon + * as QSPI provides command. So first command fails. + */ + if (!startup) { + xilinx_spi_startup_block(spi); + startup++; + } + + spi_cs_activate(spi->dev, slave_plat->cs); + + if (op->cmd.opcode) { + ret = start_transfer(spi, (void *)&op->cmd.opcode, NULL, 1); + if (ret) + goto done; + } + if (op->addr.nbytes) { + int i; + u8 addr_buf[4]; + + for (i = 0; i < op->addr.nbytes; i++) + addr_buf[i] = op->addr.val >> + (8 * (op->addr.nbytes - i - 1)); + + ret = start_transfer(spi, (void *)addr_buf, NULL, + op->addr.nbytes); + if (ret) + goto done; + } + if (op->dummy.nbytes) { + dummy_len = op->dummy.nbytes * op->data.buswidth; + ret = start_transfer(spi, NULL, NULL, dummy_len); + if (ret) + goto done; + } + if (op->data.nbytes) { + if (op->data.dir == SPI_MEM_DATA_IN) { + ret = start_transfer(spi, NULL, + op->data.buf.in, op->data.nbytes); + } else { + ret = start_transfer(spi, op->data.buf.out, + NULL, op->data.nbytes); + } + if (ret) + goto done; + } +done: + spi_cs_deactivate(spi->dev); + + return ret; +} + static int xilinx_spi_set_speed(struct udevice *bus, uint speed) { struct xilinx_spi_priv *priv = dev_get_priv(bus); @@ -343,12 +377,16 @@ static int xilinx_spi_set_mode(struct udevice *bus, uint mode) return 0; } +static const struct spi_controller_mem_ops xilinx_spi_mem_ops = { + .exec_op = xilinx_spi_mem_exec_op, +}; + static const struct dm_spi_ops xilinx_spi_ops = { .claim_bus = xilinx_spi_claim_bus, .release_bus = xilinx_spi_release_bus, - .xfer = xilinx_spi_xfer, .set_speed = xilinx_spi_set_speed, .set_mode = xilinx_spi_set_mode, + .mem_ops = &xilinx_spi_mem_ops, }; static const struct udevice_id xilinx_spi_ids[] = { From 557832bd88351ffc0b8e43720b98700fe74f68b2 Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Sat, 16 Jul 2022 12:28:47 +0530 Subject: [PATCH 44/48] spi: xilinx_spi: Add support ops to axi qspi driver Add support_ops function to check controller supported operations by spi-mem framework. Current default support ops function does not allow dummy buswidth no more than 1, unless we are using buswidth is 4 for TX. In order to support dummy buswidth > 1 by spi-nor framework we are adding explicit support_ops to check controller supported operations. Fix dummy bytes calculation incase of valid dummy bytes when dummy buswidth is > 1. Current dummy bytes calculation does not provide correct dummy values for dummy buswidth > 1. Signed-off-by: T Karthik Reddy Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/1657954727-31972-3-git-send-email-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- drivers/spi/xilinx_spi.c | 46 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 09d4b01631f..4e9115dafee 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -320,7 +320,9 @@ static int xilinx_spi_mem_exec_op(struct spi_slave *spi, goto done; } if (op->dummy.nbytes) { - dummy_len = op->dummy.nbytes * op->data.buswidth; + dummy_len = (op->dummy.nbytes * op->data.buswidth) / + op->dummy.buswidth; + ret = start_transfer(spi, NULL, NULL, dummy_len); if (ret) goto done; @@ -342,6 +344,47 @@ done: return ret; } +static int xilinx_qspi_check_buswidth(struct spi_slave *slave, u8 width) +{ + u32 mode = slave->mode; + + switch (width) { + case 1: + return 0; + case 2: + if (mode & SPI_RX_DUAL) + return 0; + break; + case 4: + if (mode & SPI_RX_QUAD) + return 0; + break; + } + + return -EOPNOTSUPP; +} + +bool xilinx_qspi_mem_exec_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + if (xilinx_qspi_check_buswidth(slave, op->cmd.buswidth)) + return false; + + if (op->addr.nbytes && + xilinx_qspi_check_buswidth(slave, op->addr.buswidth)) + return false; + + if (op->dummy.nbytes && + xilinx_qspi_check_buswidth(slave, op->dummy.buswidth)) + return false; + + if (op->data.dir != SPI_MEM_NO_DATA && + xilinx_qspi_check_buswidth(slave, op->data.buswidth)) + return false; + + return true; +} + static int xilinx_spi_set_speed(struct udevice *bus, uint speed) { struct xilinx_spi_priv *priv = dev_get_priv(bus); @@ -379,6 +422,7 @@ static int xilinx_spi_set_mode(struct udevice *bus, uint mode) static const struct spi_controller_mem_ops xilinx_spi_mem_ops = { .exec_op = xilinx_spi_mem_exec_op, + .supports_op = xilinx_qspi_mem_exec_op, }; static const struct dm_spi_ops xilinx_spi_ops = { From 1acb70393f2719c70d92f52d91be2525fa1db679 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Fri, 15 Jul 2022 19:31:16 +0530 Subject: [PATCH 45/48] spi: zynq_qspi: Add child pre probe function Add child pre probe function in the driver. Update max_hz of priv from spi_slave structure. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/1657893679-20039-2-git-send-email-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- drivers/spi/zynq_qspi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index b69d992b28a..066a0c60027 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -94,6 +94,7 @@ struct zynq_qspi_priv { u8 mode; u8 fifo_depth; u32 freq; /* required frequency */ + u32 max_hz; const void *tx_buf; void *rx_buf; unsigned len; @@ -174,6 +175,16 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv) writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, ®s->enr); } +static int zynq_qspi_child_pre_probe(struct udevice *bus) +{ + struct spi_slave *slave = dev_get_parent_priv(bus); + struct zynq_qspi_priv *priv = dev_get_priv(bus->parent); + + priv->max_hz = slave->max_hz; + + return 0; +} + static int zynq_qspi_probe(struct udevice *bus) { struct zynq_qspi_plat *plat = dev_get_plat(bus); @@ -746,4 +757,5 @@ U_BOOT_DRIVER(zynq_qspi) = { .plat_auto = sizeof(struct zynq_qspi_plat), .priv_auto = sizeof(struct zynq_qspi_priv), .probe = zynq_qspi_probe, + .child_pre_probe = zynq_qspi_child_pre_probe, }; From e09784728689de7949d4cdd559a9590e0bfcc702 Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Fri, 15 Jul 2022 19:31:17 +0530 Subject: [PATCH 46/48] spi: zynq_qspi: Use dummy buswidth in dummy byte calculation Fix dummy bytes calculation incase of valid dummy bytes when dummy buswidth is > 1. Current dummy bytes calculation does not provide correct dummy values for dummy buswidth > 1. Signed-off-by: T Karthik Reddy Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/1657893679-20039-3-git-send-email-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- drivers/spi/zynq_qspi.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index 066a0c60027..b138c3c38a1 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -679,6 +679,7 @@ static int zynq_qspi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) { int op_len, pos = 0, ret, i; + u32 dummy_bytes = 0; unsigned int flag = 0; const u8 *tx_buf = NULL; u8 *rx_buf = NULL; @@ -691,6 +692,11 @@ static int zynq_qspi_exec_op(struct spi_slave *slave, } op_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes; + if (op->dummy.nbytes) { + op_len = op->cmd.nbytes + op->addr.nbytes + + op->dummy.nbytes / op->dummy.buswidth; + dummy_bytes = op->dummy.nbytes / op->dummy.buswidth; + } u8 op_buf[op_len]; @@ -704,8 +710,8 @@ static int zynq_qspi_exec_op(struct spi_slave *slave, pos += op->addr.nbytes; } - if (op->dummy.nbytes) - memset(op_buf + pos, 0xff, op->dummy.nbytes); + if (dummy_bytes) + memset(op_buf + pos, 0xff, dummy_bytes); /* 1st transfer: opcode + address + dummy cycles */ /* Make sure to set END bit if no tx or rx data messages follow */ From bc4795850bdd971fe7ff5014a9283b975368da95 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 15 Jul 2022 19:31:18 +0530 Subject: [PATCH 47/48] spi: zynq_qspi: Add support for zynq_qspi_mem_exec_op Add support_ops function zynq_qspi_mem_exec_op to check controller supported operations by spi-mem framework. Current default support ops function does not allow dummy buswidth no more than 1, unless we are using buswidth is 4 for TX. Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/1657893679-20039-4-git-send-email-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- drivers/spi/zynq_qspi.c | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index b138c3c38a1..52db7b3f219 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -736,8 +736,50 @@ static int zynq_qspi_exec_op(struct spi_slave *slave, return 0; } +static int zynq_qspi_check_buswidth(struct spi_slave *slave, u8 width) +{ + u32 mode = slave->mode; + + switch (width) { + case 1: + return 0; + case 2: + if (mode & SPI_RX_DUAL) + return 0; + break; + case 4: + if (mode & SPI_RX_QUAD) + return 0; + break; + } + + return -EOPNOTSUPP; +} + +bool zynq_qspi_mem_exec_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + if (zynq_qspi_check_buswidth(slave, op->cmd.buswidth)) + return false; + + if (op->addr.nbytes && + zynq_qspi_check_buswidth(slave, op->addr.buswidth)) + return false; + + if (op->dummy.nbytes && + zynq_qspi_check_buswidth(slave, op->dummy.buswidth)) + return false; + + if (op->data.dir != SPI_MEM_NO_DATA && + zynq_qspi_check_buswidth(slave, op->data.buswidth)) + return false; + + return true; +} + static const struct spi_controller_mem_ops zynq_qspi_mem_ops = { .exec_op = zynq_qspi_exec_op, + .supports_op = zynq_qspi_mem_exec_op, }; static const struct dm_spi_ops zynq_qspi_ops = { From 2a75bc1303b34e88745fcecfeacbe94f2a4bd1e2 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 15 Jul 2022 19:31:19 +0530 Subject: [PATCH 48/48] spi: zynq_qspi: Fix programming qspi speed When programming qspi flash speed we need to check the requested flash speed not to exceed the spi max frequency. In the current implementation we are checking qspi ref clk instead. This commit fixes the issue by checking the requested speed and programs the specified max frequency. Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/1657893679-20039-5-git-send-email-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- drivers/spi/zynq_qspi.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index 52db7b3f219..00e3ffcd1df 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -622,15 +622,12 @@ static int zynq_qspi_set_speed(struct udevice *bus, uint speed) uint32_t confr; u8 baud_rate_val = 0; - if (speed > plat->frequency) - speed = plat->frequency; + if (!speed || speed > priv->max_hz) + speed = priv->max_hz; /* Set the clock frequency */ confr = readl(®s->cr); - if (speed == 0) { - /* Set baudrate x8, if the freq is 0 */ - baud_rate_val = 0x2; - } else if (plat->speed_hz != speed) { + if (plat->speed_hz != speed) { while ((baud_rate_val < ZYNQ_QSPI_CR_BAUD_MAX) && ((plat->frequency / (2 << baud_rate_val)) > speed))