From 41d7f6744894a464785fa4589a648f1151685978 Mon Sep 17 00:00:00 2001 From: Ayan Kumar Halder Date: Wed, 22 Jun 2022 10:26:57 +0200 Subject: 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 6a6e746..7c81a82 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 c342e6b..bf7569d 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 dae8f06..fbc6e75 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; -- cgit v1.1 From 156cb2af92c244fae15c8fbdab293d88d451edcf Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 29 Jun 2022 11:13:14 +0200 Subject: 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 7c2bfa3..ac349a9 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 */ + }; }; }; }; -- cgit v1.1 From 71f07731488e9ade674ee396208317ab2db3cce1 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Mon, 27 Jun 2022 14:22:45 +0530 Subject: 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 e978b67..8f4071c 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, -- cgit v1.1 From 5e0e1a86d327d0e3330aee737559dd15a3b27bd7 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Fri, 15 Jul 2022 01:40:25 -0500 Subject: 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 090fb1a..fcf3fb2 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", -- cgit v1.1 From fcbc43bd508afbb5b7ffa9682dc22e1f5e0912d4 Mon Sep 17 00:00:00 2001 From: Stefan Herbrechtsmeier Date: Thu, 14 Jul 2022 15:47:33 +0200 Subject: 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 2352fc9..cb85ee4 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 0574ee9..f04fa64 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 a248cbf..c481a69 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 df0365b..b02fec6 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 82510f1..49e2758 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 89622d1..6776bd9 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 -- cgit v1.1 From e3521e9c69af1818fac28d980bf956fc8a7ceabe Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 4 Jul 2022 16:09:00 +0200 Subject: 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 6776bd9..bee4816 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 -- cgit v1.1 From b09e462482b4b84f5d99986514db5fe8d10f4c2f Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Jul 2022 10:47:16 +0200 Subject: 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 a59a5e6..fc22bef 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 2e1e286..c1ac339 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(); -- cgit v1.1 From 7c1860fce4e369bdcabc1f574feb6b9af19999a3 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Thu, 7 Jul 2022 10:45:36 +0200 Subject: 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 ab277ca..1476d78 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 f72996a..f21fe67 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; -- cgit v1.1 From 65168910adaae3a4ac91fd5acf30941a28facc0e Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Thu, 7 Jul 2022 10:45:37 +0200 Subject: 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 ed6c5df..628addd 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 fc22bef..9f086f3 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 27729db..9cade92 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 af946b8..31b6659 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 d365705..e52aa75 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 c1ac339..670d9c9 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 57cba5c..1bcdb3e 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 106c395..f7c6e3e 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 cfc1c65..03c866b 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) { -- cgit v1.1 From a5bd1fe863907f27c68e30d8ef030649f4bf7d5f Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Jul 2022 10:45:38 +0200 Subject: 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 5963dd9..1474434 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 c481a69..16f1d49 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 b02fec6..cfaffa1 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 49e2758..e6d4308 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 -- cgit v1.1 From 2075215dd968b5488f87a59c4d3494a8b8c1460d Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Jul 2022 12:52:26 +0200 Subject: 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 d7e6626..c90c54d 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 -- cgit v1.1 From 34b01c22ccd2cf55a85a05c8d542bab0523f76c0 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Jul 2022 12:59:42 +0200 Subject: 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 97203b5..ea93061 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") -- cgit v1.1 From 7e9c2cd4e46cb93c22ea513c24c83b07873deac6 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Jul 2022 13:06:16 +0200 Subject: 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 6c4fd9a..86c14d5 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 -- cgit v1.1 From 165694b1254909953eea9768ea3d914555c17cc5 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 7 Jul 2022 13:10:53 +0200 Subject: 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 --- include/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 0000000..895424e --- /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 -- cgit v1.1 From bb7468b4c9d7ce0f7cdd5bc5eae11e8fe87250cf Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 8 Jul 2022 08:15:05 +0200 Subject: 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 fcf3fb2..5f31d8a 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", -- cgit v1.1 From 65fc1697dbfbf61680e6a9cdad0a2d7dd2f9bed9 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 8 Jul 2022 08:15:06 +0200 Subject: 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 5f31d8a..2d2a2ed 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; -- cgit v1.1 From c6bceb4e360d704fb9746541c18a1a08f49353fc Mon Sep 17 00:00:00 2001 From: Kunihiko Hayashi Date: Wed, 13 Jul 2022 10:38:59 +0900 Subject: 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 83adfb5..295337a 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; -- cgit v1.1 From ee5a4b87a1a57607db28fafa2692dabf92c64570 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 21 Jul 2022 16:19:17 +0200 Subject: 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 5f2afb9..b0c11aa 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; -- cgit v1.1 From 4a1bfcd7aa6f2138a8431a916d4202a66ab65a6c Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 21 Jul 2022 16:19:18 +0200 Subject: 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 b0c11aa..9b4aded 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) { -- cgit v1.1 From 9df50817405b358c5dd8c669030de7b1f8b15cb8 Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Wed, 20 Jul 2022 03:59:57 -0600 Subject: 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 b577141..69a7b4c 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 4e3f907..52c08c4 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" }, { } }; -- cgit v1.1 From c0ce59aaacfd139f75f57181f0e15a3efbd7b3fc Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 20 Jul 2022 03:59:58 -0600 Subject: 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 7f0bcb2..d2490fe 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 -- cgit v1.1 From 9dac63b6f4df17398345d4ea4f771fcf9e5e4547 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Wed, 20 Jul 2022 03:59:59 -0600 Subject: 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 bee4816..22ddbf3 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 -- cgit v1.1 From c9f12ed9bcb973297a33f50e1fa28506118bcb91 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 22 Jul 2022 02:46:54 -0600 Subject: 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 b0cd647..325e4dd 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 86c14d5..52bc20f 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); -- cgit v1.1 From 2e40ab1f215641c53d2c60baa347892d159cafc9 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 22 Jul 2022 02:46:55 -0600 Subject: 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 325e4dd..76ddc6b 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; }; -- cgit v1.1 From 7b4e365e49c76df88917883bd59dc9799131bac2 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 22 Jul 2022 02:46:56 -0600 Subject: 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 22ddbf3..e5ac26e 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 -- cgit v1.1 From cce33515010287a5bd7f4b6f9ebce0f56268a7f1 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 22 Jul 2022 02:46:57 -0600 Subject: 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 1c12eac..9fffb4e 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 959cce9..3e4ec47 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 52bc20f..f7a4a39 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_ */ -- cgit v1.1 From 5f53e534ac15ad63ee530a43536b8da6c30cd36d Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 22 Jul 2022 02:46:58 -0600 Subject: 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 d2490fe..7b58531 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 73db2af..acbdce1 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. -- cgit v1.1 From e8ffc1dfcb1b4a7465ae7ec2b45569f0f27ff501 Mon Sep 17 00:00:00 2001 From: Alexander Dahl Date: Thu, 21 Jul 2022 15:31:21 +0200 Subject: 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 ff0df37..8c31e5c 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 7671951..78d9588 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 b3e0537..0fd2290e 100644 --- a/drivers/fpga/virtex2.c +++ b/drivers/fpga/virtex2.c @@ -46,13 +46,6 @@ #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 */ #ifndef CONFIG_SYS_FPGA_CHECK_ERROR -- cgit v1.1 From 8c09cb6f4dc5eda57d2e9e76ee8b0f4e2e340071 Mon Sep 17 00:00:00 2001 From: Alexander Dahl Date: Thu, 21 Jul 2022 15:31:22 +0200 Subject: 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 8c31e5c..2c4bde0 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 3a44c7e..9f5cb87 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 78d9588..696ea92 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 3435400..fe37752 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 0fd2290e..2e764bd 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 a8265e9..da4d497 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 efc2f3b..fc07c5d 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 -- cgit v1.1 From fb2b88567d3b06095b089e70f75160a107710ea8 Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:02 +0300 Subject: 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 b3820f1..a8260aa 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 696ea92..e07a9cf 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 fe3dfa1..3b0a44b 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 cbebefb..6bc1bc4 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 6b39486..8ff12bf 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, -- cgit v1.1 From f18adf106576f298ead743a02800c6fdc90d884c Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:03 +0300 Subject: 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 ab4537b..362943b 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 -- cgit v1.1 From d7fcbfc19b4e83930a90c834046d4bf7dc3adefe Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:04 +0300 Subject: 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 69b818f..ac595ee 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 81663e0..d8f39be 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 f7c6e3e..57259b6 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 b94c82e..0cc101b 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 362943b..d9e4b8d 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 35cfe17..8401a85 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_ */ -- cgit v1.1 From 24307b06b71a3c9b4aa556eefdad1f8fcca116bd Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:05 +0300 Subject: 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 8ff12bf..19d079c 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 d9e4b8d..ff5486d 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 -- cgit v1.1 From 7a9a0df89bf1cb9f7e78378f946f1d9c9b002d72 Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:06 +0300 Subject: 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 3b0a44b..efbac9f 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 6bc1bc4..5dd7215 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 ff5486d..0bbf14d 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, -- cgit v1.1 From 282eed50ecb73c20dd35bf3ea7a579e79b20cd54 Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:07 +0300 Subject: 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 03c866b..b846bff 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 3fdd0b3..c4651dd 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 1bbf824..3c5a919 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 efbac9f..185bd54 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 5dd7215..d9951ca 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 ec51443..6365e15 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, -- cgit v1.1 From 2c60514d9aecf7fbbbe3c4cb3a4a4acc421e5239 Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:08 +0300 Subject: 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 185bd54..4db5c0a 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 6365e15..13b1bbe 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_ */ -- cgit v1.1 From 71f1a5392aadb5b6a43523b46040dea2ffbdd2ba Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:09 +0300 Subject: 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 3c5a919..a35be52 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); -- cgit v1.1 From 3e78481de94d94f753bbf05486734b8da394643f Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:10 +0300 Subject: 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 fe37752..47692e3 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 4850c99..918f6db 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 c44a7d3..d3876a8 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 2e764bd..51b8d31 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 d9951ca..8170c33 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 19d079c..a062456 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 2de4010..d8ebd54 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 0bbf14d..e5f6db3 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, -- cgit v1.1 From fcd91cb782c9c659c5db65c9aa5fb7e0497de1ec Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:11 +0300 Subject: 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 a062456..2791f93 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); -- cgit v1.1 From 5ab6a846349471be9b640da35d757d55dd8de487 Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:12 +0300 Subject: 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 2791f93..feaf34f 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"); -- cgit v1.1 From a3a1afb747d4d71c3dd5ba01b2796cebd65c65cd Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Fri, 22 Jul 2022 17:16:13 +0300 Subject: 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 17438b5..59d0c65 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 f93ac6d..461e2af 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 feaf34f..fc55d7a 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 e5f6db3..97ee12c 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 8401a85..87ccd2f 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_ */ -- cgit v1.1 From b524f8fb1e94a8e649ba06a7cb87e6dcaa96ebc3 Mon Sep 17 00:00:00 2001 From: Adrian Fiergolski Date: Fri, 22 Jul 2022 17:16:14 +0300 Subject: 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 461e2af..6870111 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 fc55d7a..d1491da 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 13b1bbe..a4e1640 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 97ee12c..e4e2979 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 87ccd2f..acf75a8 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 -- cgit v1.1 From f2dd6599df65dd307d7170f1b2fc0d38eb44ad75 Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Sat, 16 Jul 2022 12:28:46 +0530 Subject: 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 | 194 ++++++++++++++++++++++++++++------------------- 1 file changed, 116 insertions(+), 78 deletions(-) diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index b892cda..09d4b01 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; - - /* - * 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; + u32 count, txbytes, rxbytes; + int reg, ret; + const unsigned char *txp = (const unsigned char *)dout; + unsigned char *rxp = (unsigned char *)din; + + 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[] = { -- cgit v1.1 From 557832bd88351ffc0b8e43720b98700fe74f68b2 Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Sat, 16 Jul 2022 12:28:47 +0530 Subject: 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 09d4b01..4e9115d 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 = { -- cgit v1.1 From 1acb70393f2719c70d92f52d91be2525fa1db679 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Fri, 15 Jul 2022 19:31:16 +0530 Subject: 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 b69d992..066a0c6 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, }; -- cgit v1.1 From e09784728689de7949d4cdd559a9590e0bfcc702 Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Fri, 15 Jul 2022 19:31:17 +0530 Subject: 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 066a0c6..b138c3c 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 */ -- cgit v1.1 From bc4795850bdd971fe7ff5014a9283b975368da95 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 15 Jul 2022 19:31:18 +0530 Subject: 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 b138c3c..52db7b3 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 = { -- cgit v1.1 From 2a75bc1303b34e88745fcecfeacbe94f2a4bd1e2 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 15 Jul 2022 19:31:19 +0530 Subject: 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 52db7b3..00e3ffc 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)) -- cgit v1.1