From e6e3b9d7b55ce2563f9da0b5991605f15bd38163 Mon Sep 17 00:00:00 2001 From: Ricardo Salveti Date: Thu, 20 Jan 2022 16:17:30 -0300 Subject: [PATCH 01/29] xilinx: common: change bootm_size to not go beyond ram_top The available ram can be limited by ram_top as that depends on the reserved memory nodes provided by the device-tree (via board_get_usable_ram_top), so make sure to respect ram_top when setting up bootm_size to avoid overlapping reserved memory regions (e.g. memory used by OP-TEE). The same logic is available in env_get_bootm_size when bootm_size is not defined by the default environment. Signed-off-by: Ricardo Salveti Link: https://lore.kernel.org/r/20220120191730.2009270-1-ricardo@foundries.io Signed-off-by: Michal Simek --- board/xilinx/common/board.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 78a5d0efa8..6fce23197a 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -377,7 +377,7 @@ int board_late_init_xilinx(void) u32 ret = 0; int i, id, macid = 0; struct xilinx_board_description *desc; - phys_size_t bootm_size = gd->ram_size; + phys_size_t bootm_size = gd->ram_top - gd->ram_base; if (!CONFIG_IS_ENABLED(MICROBLAZE)) { ulong scriptaddr; From 19fdc166f78a68bec60ca13b0c71a739fb4d0a73 Mon Sep 17 00:00:00 2001 From: Greentime Hu Date: Thu, 20 Jan 2022 16:41:28 +0800 Subject: [PATCH 02/29] net: xilinx: fix the wrong dma base address issue If we just use fdtdec_get_addr_size_fixed to get "reg" it will use 64bit address cell to get the base address. soc { #address-cells = <1>; #size-cells = <1>; compatible ="SiFive,FU500-soc", "fu500-soc", "sifive-soc", "simple-bus"; ranges; L28: axidma@30010000 { #dma-cells = <1>; compatible = "xlnx,axi-dma-1.00.a"; axistream-connected = <&L27>; axistream-control-connected = <&L27>; clocks = <&L1>; interrupt-parent = <&L6>; interrupts = <32 33>; reg = <0x30010000 0x4000>; fdtdec_get_addr_size_fixed: reg: addr=3001000000004000 We should get the base address through its parent's address-cells and size-cells settings. So we should use fdtdec_get_addr_size_auto_parent() to get correct base address. After applying this patch, we can get the correct base address of dma by replacing fdtdec_get_addr_size_fixed() with fdtdec_get_addr_size_auto_parent(). fdtdec_get_addr_size_auto_parent: na=1, ns=1, fdtdec_get_addr_size_fixed: reg: addr=30010000 Signed-off-by: Greentime Hu Signed-off-by: Andy Chiu Link: https://lore.kernel.org/r/20220120084128.1892101-1-andy.chiu@sifive.com Signed-off-by: Michal Simek --- drivers/net/xilinx_axi_emac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 2ec76d0f52..f21addb4d0 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -832,8 +832,8 @@ static int axi_emac_of_to_plat(struct udevice *dev) printf("%s: axistream is not found\n", __func__); return -EINVAL; } - plat->dmatx = (struct axidma_reg *)fdtdec_get_addr(gd->fdt_blob, - offset, "reg"); + plat->dmatx = (struct axidma_reg *)fdtdec_get_addr_size_auto_parent + (gd->fdt_blob, 0, offset, "reg", 0, NULL, false); if (!plat->dmatx) { printf("%s: axi_dma register space not found\n", __func__); return -EINVAL; From 25a91f300578d5905029d5f44799ef71a755ff02 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Wed, 13 Oct 2021 19:04:47 +0200 Subject: [PATCH 03/29] arm64: zynqmp: Print the secure boot status information Output the secure boot configuration to the console. Signed-off-by: Jorge Ramirez-Ortiz Link: https://lore.kernel.org/r/20211013170447.10414-1-jorge@foundries.io Signed-off-by: Michal Simek --- arch/arm/mach-zynqmp/include/mach/hardware.h | 6 +++++- board/xilinx/zynqmp/zynqmp.c | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-zynqmp/include/mach/hardware.h b/arch/arm/mach-zynqmp/include/mach/hardware.h index e6a3ee4a57..a70d6d611b 100644 --- a/arch/arm/mach-zynqmp/include/mach/hardware.h +++ b/arch/arm/mach-zynqmp/include/mach/hardware.h @@ -152,8 +152,12 @@ struct apu_regs { #define CSU_JTAG_CHAIN_WR_SETUP GENMASK(1, 0) #define CSU_PCAP_PROG_RELEASE_PL BIT(0) +#define ZYNQMP_CSU_STATUS_AUTHENTICATED BIT(0) +#define ZYNQMP_CSU_STATUS_ENCRYPTED BIT(1) + struct csu_regs { - u32 reserved0[4]; + u32 status; + u32 reserved0[3]; u32 multi_boot; u32 reserved1[7]; u32 jtag_chain_status_wr; diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 2b5239ccb4..242e143cbf 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -373,6 +373,18 @@ static void restore_jtag(void) } #endif +static void print_secure_boot(void) +{ + u32 status = 0; + + if (zynqmp_mmio_read((ulong)&csu_base->status, &status)) + return; + + printf("Secure Boot:\t%sauthenticated, %sencrypted\n", + status & ZYNQMP_CSU_STATUS_AUTHENTICATED ? "" : "not ", + status & ZYNQMP_CSU_STATUS_ENCRYPTED ? "" : "not "); +} + #define PS_SYSMON_ANALOG_BUS_VAL 0x3210 #define PS_SYSMON_ANALOG_BUS_REG 0xFFA50914 @@ -413,6 +425,8 @@ int board_init(void) fpga_add(fpga_xilinx, &zynqmppl); #endif + /* display secure boot information */ + print_secure_boot(); if (current_el() == 3) printf("Multiboot:\t%d\n", multi_boot()); From 255537b5adbdfa9eb0fe750c79ad089e7c0e3990 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Sun, 30 Jan 2022 22:22:37 -0700 Subject: [PATCH 04/29] spi: zynq_qspi: Typecast rxbuf properly This patch typecasts and accesses rx buf properly as an unaligned rxbuf, typecasting with u16 and accessing it causes data abort exception and this patch fixes it. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220131052240.23403-2-ashok.reddy.soma@xilinx.com --- drivers/spi/zynq_qspi.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index cf6da5340a..34d39d66fb 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -230,12 +230,16 @@ static void zynq_qspi_read_data(struct zynq_qspi_priv *priv, u32 data, u8 size) priv->rx_buf += 1; break; case 2: - *((u16 *)priv->rx_buf) = data; - priv->rx_buf += 2; + *((u8 *)priv->rx_buf) = data; + priv->rx_buf += 1; + *((u8 *)priv->rx_buf) = (u8)(data >> 8); + priv->rx_buf += 1; break; case 3: - *((u16 *)priv->rx_buf) = data; - priv->rx_buf += 2; + *((u8 *)priv->rx_buf) = data; + priv->rx_buf += 1; + *((u8 *)priv->rx_buf) = (u8)(data >> 8); + priv->rx_buf += 1; byte3 = (u8)(data >> 16); *((u8 *)priv->rx_buf) = byte3; priv->rx_buf += 1; From a5a387a421105e671ee86a257eccf4d68aa1e7e7 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Sun, 30 Jan 2022 22:22:38 -0700 Subject: [PATCH 05/29] spi: zynq_qspi: Read only one byte at a time from txbuf Read only one byte at a time from txbuf as txbuf may not be aligned and accessing more than a byte at a time may cause alignment issues. This fixes the issue of data abort exception while writing to flash device. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220131052240.23403-3-ashok.reddy.soma@xilinx.com --- drivers/spi/zynq_qspi.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index 34d39d66fb..aa060d7940 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -276,13 +276,17 @@ static void zynq_qspi_write_data(struct zynq_qspi_priv *priv, *data |= 0xFFFFFF00; break; case 2: - *data = *((u16 *)priv->tx_buf); - priv->tx_buf += 2; + *data = *((u8 *)priv->tx_buf); + priv->tx_buf += 1; + *data |= (*((u8 *)priv->tx_buf) << 8); + priv->tx_buf += 1; *data |= 0xFFFF0000; break; case 3: - *data = *((u16 *)priv->tx_buf); - priv->tx_buf += 2; + *data = *((u8 *)priv->tx_buf); + priv->tx_buf += 1; + *data |= (*((u8 *)priv->tx_buf) << 8); + priv->tx_buf += 1; *data |= (*((u8 *)priv->tx_buf) << 16); priv->tx_buf += 1; *data |= 0xFF000000; From 30671860d746ead98296662c226be275041ed18a Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Sun, 30 Jan 2022 22:22:39 -0700 Subject: [PATCH 06/29] spi: zynq_qspi: Add a check for baudrate and set default if not in limits Add a check afer baudrate calculation to see if the resultant value falls within the range, else set it to default baudrate value. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220131052240.23403-4-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- drivers/spi/zynq_qspi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index aa060d7940..2963f48bb0 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -49,6 +49,9 @@ DECLARE_GLOBAL_DATA_PTR; #define ZYNQ_QSPI_CR_BAUD_SHIFT 3 /* Baud rate divisor shift */ #define ZYNQ_QSPI_CR_SS_SHIFT 10 /* Slave select shift */ +#define ZYNQ_QSPI_MAX_BAUD_RATE 0x7 +#define ZYNQ_QSPI_DEFAULT_BAUD_RATE 0x2 + #define ZYNQ_QSPI_FIFO_DEPTH 63 #define ZYNQ_QSPI_WAIT (CONFIG_SYS_HZ / 100) /* 10 ms */ @@ -621,6 +624,9 @@ static int zynq_qspi_set_speed(struct udevice *bus, uint speed) (2 << baud_rate_val)) > speed)) baud_rate_val++; + if (baud_rate_val > ZYNQ_QSPI_MAX_BAUD_RATE) + baud_rate_val = ZYNQ_QSPI_DEFAULT_BAUD_RATE; + plat->speed_hz = speed / (2 << baud_rate_val); } confr &= ~ZYNQ_QSPI_CR_BAUD_MASK; From bab0c02e3735c516405f83cf6d12df6c93cc933c Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Sun, 30 Jan 2022 22:22:40 -0700 Subject: [PATCH 07/29] spi: zynq_qspi: Add SPI memory operations to zynq qspi Spi memory operation interface is added to zynq qspi driver to provide an high-level interface to execute qspi controller specific memory operations by avoiding spi_mem_exec_op() from spi-mem framework. Signed-off-by: T Karthik Reddy Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220131052240.23403-5-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- drivers/spi/zynq_qspi.c | 61 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index 2963f48bb0..b69d992b28 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -16,6 +16,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -663,12 +664,72 @@ static int zynq_qspi_set_mode(struct udevice *bus, uint mode) return 0; } +static int zynq_qspi_exec_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + int op_len, pos = 0, ret, i; + unsigned int flag = 0; + const u8 *tx_buf = NULL; + u8 *rx_buf = NULL; + + if (op->data.nbytes) { + if (op->data.dir == SPI_MEM_DATA_IN) + rx_buf = op->data.buf.in; + else + tx_buf = op->data.buf.out; + } + + op_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes; + + u8 op_buf[op_len]; + + op_buf[pos++] = op->cmd.opcode; + + if (op->addr.nbytes) { + for (i = 0; i < op->addr.nbytes; i++) + op_buf[pos + i] = op->addr.val >> + (8 * (op->addr.nbytes - i - 1)); + + pos += op->addr.nbytes; + } + + if (op->dummy.nbytes) + memset(op_buf + pos, 0xff, op->dummy.nbytes); + + /* 1st transfer: opcode + address + dummy cycles */ + /* Make sure to set END bit if no tx or rx data messages follow */ + if (!tx_buf && !rx_buf) + flag |= SPI_XFER_END; + + ret = zynq_qspi_xfer(slave->dev, op_len * 8, op_buf, NULL, + flag | SPI_XFER_BEGIN); + if (ret) + return ret; + + /* 2nd transfer: rx or tx data path */ + if (tx_buf || rx_buf) { + ret = zynq_qspi_xfer(slave->dev, op->data.nbytes * 8, tx_buf, + rx_buf, flag | SPI_XFER_END); + if (ret) + return ret; + } + + spi_release_bus(slave); + + return 0; +} + +static const struct spi_controller_mem_ops zynq_qspi_mem_ops = { + .exec_op = zynq_qspi_exec_op, +}; + static const struct dm_spi_ops zynq_qspi_ops = { .claim_bus = zynq_qspi_claim_bus, .release_bus = zynq_qspi_release_bus, .xfer = zynq_qspi_xfer, .set_speed = zynq_qspi_set_speed, .set_mode = zynq_qspi_set_mode, + .mem_ops = &zynq_qspi_mem_ops, }; static const struct udevice_id zynq_qspi_ids[] = { From 927adc27abf8db8454a162102b00c0b272a28762 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 19 Jan 2022 12:03:23 +0100 Subject: [PATCH 08/29] zynqmp: Use the same style for macro definitions Use the same coding style for all macros. #defineNAMEVALUE Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/3960de81a04acbaaa01936f743d3d6b3876fe4b7.1642590201.git.michal.simek@xilinx.com --- include/zynqmp_firmware.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h index 0b068d7da2..cfd92d3fe5 100644 --- a/include/zynqmp_firmware.h +++ b/include/zynqmp_firmware.h @@ -342,20 +342,20 @@ enum pm_ioctl_id { IOCTL_AIE_ISR_CLEAR = 24, }; -#define PM_SIP_SVC 0xc2000000 +#define PM_SIP_SVC 0xc2000000 -#define ZYNQMP_PM_VERSION_MAJOR 1 -#define ZYNQMP_PM_VERSION_MINOR 0 -#define ZYNQMP_PM_VERSION_MAJOR_SHIFT 16 -#define ZYNQMP_PM_VERSION_MINOR_MASK 0xFFFF +#define ZYNQMP_PM_VERSION_MAJOR 1 +#define ZYNQMP_PM_VERSION_MINOR 0 +#define ZYNQMP_PM_VERSION_MAJOR_SHIFT 16 +#define ZYNQMP_PM_VERSION_MINOR_MASK 0xFFFF #define ZYNQMP_PM_VERSION \ ((ZYNQMP_PM_VERSION_MAJOR << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | \ ZYNQMP_PM_VERSION_MINOR) -#define ZYNQMP_PM_VERSION_INVALID ~0 +#define ZYNQMP_PM_VERSION_INVALID ~0 -#define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0) +#define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0) /* * Return payload size From af98bf62fab8f074822a225d7c2fb2a02a7734a8 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 19 Jan 2022 12:01:51 +0100 Subject: [PATCH 09/29] arm64: zynqmp: Remove SOM *u-boot.dtsi Disable mmc from u-boot.dtsi file because it was there only for kv260 board. With kr260 this is not needed because we will switch to full DT per board with SD/EMMC there too. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/3440d9f94361b4800658f313a5785f43ee84ecf3.1642590109.git.michal.simek@xilinx.com --- arch/arm/dts/zynqmp-sm-k26-revA-u-boot.dtsi | 21 -------------------- arch/arm/dts/zynqmp-smk-k26-revA-u-boot.dtsi | 21 -------------------- 2 files changed, 42 deletions(-) delete mode 100644 arch/arm/dts/zynqmp-sm-k26-revA-u-boot.dtsi delete mode 100644 arch/arm/dts/zynqmp-smk-k26-revA-u-boot.dtsi diff --git a/arch/arm/dts/zynqmp-sm-k26-revA-u-boot.dtsi b/arch/arm/dts/zynqmp-sm-k26-revA-u-boot.dtsi deleted file mode 100644 index 467df9f23a..0000000000 --- a/arch/arm/dts/zynqmp-sm-k26-revA-u-boot.dtsi +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * dts file for Xilinx ZynqMP K26/KV260 SD wiring - * - * (C) Copyright 2020 - 2021, Xilinx, Inc. - * - * Michal Simek - */ - -/* SD0 only supports 3.3V, no level shifter */ -&sdhci1 { /* on CC - MIO 39 - 51 */ - status = "okay"; - no-1-8-v; - disable-wp; - broken-cd; - xlnx,mio-bank = <1>; - /* Do not run SD in HS mode from bootloader */ - sdhci-caps-mask = <0 0x200000>; - sdhci-caps = <0 0>; - max-frequency = <19000000>; -}; diff --git a/arch/arm/dts/zynqmp-smk-k26-revA-u-boot.dtsi b/arch/arm/dts/zynqmp-smk-k26-revA-u-boot.dtsi deleted file mode 100644 index 34e6328fb6..0000000000 --- a/arch/arm/dts/zynqmp-smk-k26-revA-u-boot.dtsi +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * dts file for Xilinx ZynqMP Z2-VSOM - * - * (C) Copyright 2020 - 2021, Xilinx, Inc. - * - * Michal Simek - */ - -/* SD0 only supports 3.3V, no level shifter */ -&sdhci1 { /* FIXME - on CC - MIO 39 - 51 */ - status = "okay"; - no-1-8-v; - disable-wp; - broken-cd; - xlnx,mio-bank = <1>; - /* Do not run SD in HS mode from bootloader */ - sdhci-caps-mask = <0 0x200000>; - sdhci-caps = <0 0>; - max-frequency = <19000000>; -}; From 2f9dd4bfc7a2d618c9c76448dd7b3ce67c6ec4ce Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Sat, 12 Feb 2022 13:51:21 +0100 Subject: [PATCH 10/29] tools/zynqmp_pm_cfg_obj_convert.py: fix build with Vivado 2021.x This tool fails with a pm_cfg_obj.c file generated by Vitis 2021.2. This is because that version of Vitis added the PM_CONFIG_OBJECT_TYPE_BASE that was not previously generated, thus the script does not implement it. Reported-by: Neal Frager [report: https://lists.buildroot.org/pipermail/buildroot/2022-February/636639.html] Signed-off-by: Luca Ceresoli Link: https://lore.kernel.org/r/20220212125121.3398547-1-luca@lucaceresoli.net Signed-off-by: Michal Simek --- tools/zynqmp_pm_cfg_obj_convert.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/zynqmp_pm_cfg_obj_convert.py b/tools/zynqmp_pm_cfg_obj_convert.py index 0a44710e1e..239991a526 100755 --- a/tools/zynqmp_pm_cfg_obj_convert.py +++ b/tools/zynqmp_pm_cfg_obj_convert.py @@ -244,6 +244,8 @@ pm_define = { 'SUSPEND_TIMEOUT' : 0xFFFFFFFF, + 'PM_CONFIG_OBJECT_TYPE_BASE' : 0x1, + 'PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK' : 0x00000001, 'PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK' : 0x00000100, 'PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK' : 0x00000200, From e0283cbdfd49a437ef3cfdd662b196d2f70b5ea0 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 7 Feb 2022 10:27:37 +0100 Subject: [PATCH 11/29] power: zynqmp: Add power domain driver for ZynqMP Driver should be enabled by CONFIG_POWER_DOMAIN=y and CONFIG_ZYNQMP_POWER_DOMAIN=y. Power domain driver doesn't have own DT node but it uses zynqmp firmware DT node that's why there is a need to bind driver when firmware node is found. Driver itself is simple. It is sending pmufw config object overlay for enabling access to device which is done in ...domain_request(). In ...domain_on() capabilities are passed and node is requested. This should be bare minimum of required to get power domain driver working. Signed-off-by: Michal Simek Reviewed-by: Jaehoon Chung Link: https://lore.kernel.org/r/f4b9433b91c0b18c375b061c7a4e29d428f70547.1644226055.git.michal.simek@xilinx.com --- MAINTAINERS | 1 + drivers/firmware/firmware-zynqmp.c | 20 +++++ drivers/power/domain/Kconfig | 9 +++ drivers/power/domain/Makefile | 1 + drivers/power/domain/zynqmp-power-domain.c | 89 ++++++++++++++++++++++ include/zynqmp_firmware.h | 31 ++++++++ 6 files changed, 151 insertions(+) create mode 100644 drivers/power/domain/zynqmp-power-domain.c diff --git a/MAINTAINERS b/MAINTAINERS index dcdd99e368..8bcdea2e34 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -634,6 +634,7 @@ F: drivers/mtd/nand/raw/zynq_nand.c F: drivers/net/phy/xilinx_phy.c F: drivers/net/zynq_gem.c F: drivers/phy/phy-zynqmp.c +F: drivers/power/domain/zynqmp-power-domain.c F: drivers/serial/serial_zynq.c F: drivers/reset/reset-zynqmp.c F: drivers/rtc/zynqmp_rtc.c diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 839203ec82..8d78888eff 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -226,8 +227,27 @@ static const struct udevice_id zynqmp_firmware_ids[] = { { } }; +static int zynqmp_firmware_bind(struct udevice *dev) +{ + int ret; + struct udevice *child; + + if (IS_ENABLED(CONFIG_ZYNQMP_POWER_DOMAIN)) { + ret = device_bind_driver_to_node(dev, "zynqmp_power_domain", + "zynqmp_power_domain", + dev_ofnode(dev), &child); + if (ret) { + printf("zynqmp power domain driver is not bound: %d\n", ret); + return ret; + } + } + + return dm_scan_fdt_dev(dev); +} + U_BOOT_DRIVER(zynqmp_firmware) = { .id = UCLASS_FIRMWARE, .name = "zynqmp_firmware", .of_match = zynqmp_firmware_ids, + .bind = zynqmp_firmware_bind, }; diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig index 9aea5fcdf0..93d2599d83 100644 --- a/drivers/power/domain/Kconfig +++ b/drivers/power/domain/Kconfig @@ -88,4 +88,13 @@ config TI_POWER_DOMAIN help Generic power domain implementation for TI K3 devices. +config ZYNQMP_POWER_DOMAIN + bool "Enable the Xilinx ZynqMP Power domain driver" + depends on POWER_DOMAIN && ZYNQMP_FIRMWARE + help + Generic power domain implementation for Xilinx ZynqMP devices. + The driver should be enabled when system starts in very minimal + configuration and it is extended at run time. Then enabling + the driver will ensure that PMUFW enable access to requested IP. + endmenu diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile index 530ae35671..7c8af67dbd 100644 --- a/drivers/power/domain/Makefile +++ b/drivers/power/domain/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o obj-$(CONFIG_TEGRA186_POWER_DOMAIN) += tegra186-power-domain.o obj-$(CONFIG_TI_SCI_POWER_DOMAIN) += ti-sci-power-domain.o obj-$(CONFIG_TI_POWER_DOMAIN) += ti-power-domain.o +obj-$(CONFIG_ZYNQMP_POWER_DOMAIN) += zynqmp-power-domain.o diff --git a/drivers/power/domain/zynqmp-power-domain.c b/drivers/power/domain/zynqmp-power-domain.c new file mode 100644 index 0000000000..5383d09896 --- /dev/null +++ b/drivers/power/domain/zynqmp-power-domain.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021, Xilinx. Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define NODE_ID_LOCATION 5 + +static unsigned int xpm_configobject[] = { + /* HEADER */ + 2, /* Number of remaining words in the header */ + 1, /* Number of sections included in config object */ + PM_CONFIG_OBJECT_TYPE_OVERLAY, /* Type of Config object as overlay */ + /* SLAVE SECTION */ + + PM_CONFIG_SLAVE_SECTION_ID, /* Section ID */ + 1, /* Number of slaves */ + + 0, /* Node ID which will be changed below */ + PM_SLAVE_FLAG_IS_SHAREABLE, + PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK | + PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK | + PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK, /* IPI Mask */ +}; + +static int zynqmp_pm_request_node(const u32 node, const u32 capabilities, + const u32 qos, const enum zynqmp_pm_request_ack ack) +{ + return xilinx_pm_request(PM_REQUEST_NODE, node, capabilities, + qos, ack, NULL); +} + +static int zynqmp_power_domain_request(struct power_domain *power_domain) +{ + /* Record power domain id */ + xpm_configobject[NODE_ID_LOCATION] = power_domain->id; + + zynqmp_pmufw_load_config_object(xpm_configobject, sizeof(xpm_configobject)); + + return 0; +} + +static int zynqmp_power_domain_free(struct power_domain *power_domain) +{ + /* nop now */ + return 0; +} + +static int zynqmp_power_domain_on(struct power_domain *power_domain) +{ + return zynqmp_pm_request_node(power_domain->id, + ZYNQMP_PM_CAPABILITY_ACCESS, + ZYNQMP_PM_MAX_QOS, + ZYNQMP_PM_REQUEST_ACK_BLOCKING); +} + +static int zynqmp_power_domain_off(struct power_domain *power_domain) +{ + /* nop now */ + return 0; +} + +struct power_domain_ops zynqmp_power_domain_ops = { + .request = zynqmp_power_domain_request, + .rfree = zynqmp_power_domain_free, + .on = zynqmp_power_domain_on, + .off = zynqmp_power_domain_off, +}; + +static int zynqmp_power_domain_probe(struct udevice *dev) +{ + return 0; +} + +U_BOOT_DRIVER(zynqmp_power_domain) = { + .name = "zynqmp_power_domain", + .id = UCLASS_POWER_DOMAIN, + .probe = zynqmp_power_domain_probe, + .ops = &zynqmp_power_domain_ops, +}; diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h index cfd92d3fe5..19c004e919 100644 --- a/include/zynqmp_firmware.h +++ b/include/zynqmp_firmware.h @@ -371,4 +371,35 @@ void 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); +/* Type of Config Object */ +#define PM_CONFIG_OBJECT_TYPE_BASE 0x1U +#define PM_CONFIG_OBJECT_TYPE_OVERLAY 0x2U + +/* Section Id */ +#define PM_CONFIG_SLAVE_SECTION_ID 0x102U +#define PM_CONFIG_SET_CONFIG_SECTION_ID 0x107U + +/* Flag Option */ +#define PM_SLAVE_FLAG_IS_SHAREABLE 0x1U +#define PM_MASTER_USING_SLAVE_MASK 0x2U + +/* IPI Mask for Master */ +#define PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK 0x00000001 +#define PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK 0x00000100 +#define PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK 0x00000200 + +enum zynqmp_pm_request_ack { + ZYNQMP_PM_REQUEST_ACK_NO = 1, + ZYNQMP_PM_REQUEST_ACK_BLOCKING = 2, + ZYNQMP_PM_REQUEST_ACK_NON_BLOCKING = 3, +}; + +/* Node capabilities */ +#define ZYNQMP_PM_CAPABILITY_ACCESS 0x1U +#define ZYNQMP_PM_CAPABILITY_CONTEXT 0x2U +#define ZYNQMP_PM_CAPABILITY_WAKEUP 0x4U +#define ZYNQMP_PM_CAPABILITY_UNUSABLE 0x8U + +#define ZYNQMP_PM_MAX_QOS 100U + #endif /* _ZYNQMP_FIRMWARE_H_ */ From c750c6dbb29535efa01464d46afc6ccf999cf7c5 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 14 Jan 2022 13:25:35 +0100 Subject: [PATCH 12/29] xilinx: firmware: Introduce zynqmp_pmufw_node() for loading PMU fragments Introduce zynqmp_pmufw_node() for loading PMU configuration fragment for enabling IPs. Firmware driver has small overlay where NODE id is added and config fragment is sent to PMUFW. There is a need to build PMUFW with fragment support. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/636e8150bd4e2b1f988d59795772c685ceeec083.1642163135.git.michal.simek@xilinx.com --- drivers/firmware/firmware-zynqmp.c | 32 ++++++++++++++++++++++++++++++ include/zynqmp_firmware.h | 1 + 2 files changed, 33 insertions(+) diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 8d78888eff..05628da9b0 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -28,6 +28,38 @@ struct zynqmp_power { struct mbox_chan rx_chan; } zynqmp_power; +#define NODE_ID_LOCATION 5 + +static unsigned int xpm_configobject[] = { + /**********************************************************************/ + /* HEADER */ + 2, /* Number of remaining words in the header */ + 1, /* Number of sections included in config object */ + PM_CONFIG_OBJECT_TYPE_OVERLAY, /* Type of Config object as overlay */ + /**********************************************************************/ + /* SLAVE SECTION */ + + PM_CONFIG_SLAVE_SECTION_ID, /* Section ID */ + 1, /* Number of slaves */ + + 0, /* Node ID which will be changed below */ + PM_SLAVE_FLAG_IS_SHAREABLE, + PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK | + PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK | + PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK, /* IPI Mask */ +}; + +int zynqmp_pmufw_node(u32 id) +{ + /* Record power domain id */ + xpm_configobject[NODE_ID_LOCATION] = id; + + zynqmp_pmufw_load_config_object(xpm_configobject, + sizeof(xpm_configobject)); + + return 0; +} + static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen) { struct zynqmp_ipi_msg msg; diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h index 19c004e919..76c161806a 100644 --- a/include/zynqmp_firmware.h +++ b/include/zynqmp_firmware.h @@ -367,6 +367,7 @@ enum pm_ioctl_id { #define PAYLOAD_ARG_CNT 5U unsigned int zynqmp_firmware_version(void); +int zynqmp_pmufw_node(u32 id); void 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); From fac46bc446e0ca2e5bd8fa4d28f243ee4a1d8995 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 14 Jan 2022 13:25:38 +0100 Subject: [PATCH 13/29] arm64: zynqmp: Add command for disabling loading other overlays Add command "zynqmp pmufw node close" to disable permission to load additional pmufw config overlays. This command will make sure that any other sw will ask for changing permission. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/cfa5cc7909eb8deb23eb0f11c26954cbaddeb861.1642163135.git.michal.simek@xilinx.com --- board/xilinx/zynqmp/cmds.c | 16 ++++++++++++++++ drivers/firmware/firmware-zynqmp.c | 19 +++++++++++++++++++ include/zynqmp_firmware.h | 1 + 3 files changed, 36 insertions(+) diff --git a/board/xilinx/zynqmp/cmds.c b/board/xilinx/zynqmp/cmds.c index 5a277c712f..2ab9596248 100644 --- a/board/xilinx/zynqmp/cmds.c +++ b/board/xilinx/zynqmp/cmds.c @@ -209,6 +209,19 @@ static int do_zynqmp_pmufw(struct cmd_tbl *cmdtp, int flag, int argc, if (argc != cmdtp->maxargs) return CMD_RET_USAGE; + if (!strncmp(argv[2], "node", 4)) { + u32 id; + + if (!strncmp(argv[3], "close", 5)) + return zynqmp_pmufw_config_close(); + + id = dectoul(argv[3], NULL); + + printf("Enable permission for node ID %d\n", id); + + return zynqmp_pmufw_node(id); + } + addr = hextoul(argv[2], NULL); size = hextoul(argv[3], NULL); @@ -416,6 +429,9 @@ static char zynqmp_help_text[] = " lock(0)/split(1)\n" #endif "zynqmp pmufw address size - load PMU FW configuration object\n" + "zynqmp pmufw node - load PMU FW configuration object\n" + "zynqmp pmufw node close - disable config object loading\n" + " node: keyword, id: NODE_ID in decimal format\n" "zynqmp rsa srcaddr srclen mod exp rsaop -\n" " Performs RSA encryption and RSA decryption on blob of data\n" " at srcaddr and puts it back in srcaddr using modulus and\n" diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 05628da9b0..8d8492d99f 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -49,6 +49,25 @@ static unsigned int xpm_configobject[] = { PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK, /* IPI Mask */ }; +static unsigned int xpm_configobject_close[] = { + /**********************************************************************/ + /* HEADER */ + 2, /* Number of remaining words in the header */ + 1, /* Number of sections included in config object */ + PM_CONFIG_OBJECT_TYPE_OVERLAY, /* Type of Config object as overlay */ + /**********************************************************************/ + /* SET CONFIG SECTION */ + PM_CONFIG_SET_CONFIG_SECTION_ID, + 0U, /* Loading permission to Overlay config object */ +}; + +int zynqmp_pmufw_config_close(void) +{ + zynqmp_pmufw_load_config_object(xpm_configobject_close, + sizeof(xpm_configobject_close)); + return 0; +} + int zynqmp_pmufw_node(u32 id) { /* Record power domain id */ diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h index 76c161806a..50bf4ef395 100644 --- a/include/zynqmp_firmware.h +++ b/include/zynqmp_firmware.h @@ -368,6 +368,7 @@ enum pm_ioctl_id { 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 xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 *ret_payload); From 462f76bc002da9c1d0f4b27380a493dc7928df7e Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 7 Feb 2022 10:36:32 +0100 Subject: [PATCH 14/29] phy: zynqmp: Add support for sata and DP phy initialization DP is untested but just c&p from Linux driver. Sata is tested on kv260-revA board which has SATA connector populated. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/d231610160e76a2ad1b4a163e0e8db0ddc4733e2.1644226590.git.michal.simek@xilinx.com --- drivers/phy/phy-zynqmp.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/phy/phy-zynqmp.c b/drivers/phy/phy-zynqmp.c index 9dc3d426a3..08c1b6efcf 100644 --- a/drivers/phy/phy-zynqmp.c +++ b/drivers/phy/phy-zynqmp.c @@ -373,6 +373,29 @@ static void xpsgtr_bypass_scrambler_8b10b(struct xpsgtr_phy *gtr_phy) xpsgtr_write_phy(gtr_phy, L0_TX_DIG_61, L0_TM_DISABLE_SCRAMBLE_ENCODER); } +/* DP-specific initialization. */ +static void xpsgtr_phy_init_dp(struct xpsgtr_phy *gtr_phy) +{ + xpsgtr_write_phy(gtr_phy, L0_TXPMD_TM_45, + L0_TXPMD_TM_45_OVER_DP_MAIN | + L0_TXPMD_TM_45_ENABLE_DP_MAIN | + L0_TXPMD_TM_45_OVER_DP_POST1 | + L0_TXPMD_TM_45_OVER_DP_POST2 | + L0_TXPMD_TM_45_ENABLE_DP_POST2); + xpsgtr_write_phy(gtr_phy, L0_TX_ANA_TM_118, + L0_TX_ANA_TM_118_FORCE_17_0); +} + +/* SATA-specific initialization. */ +static void xpsgtr_phy_init_sata(struct xpsgtr_phy *gtr_phy) +{ + struct xpsgtr_dev *gtr_dev = gtr_phy->dev; + + xpsgtr_bypass_scrambler_8b10b(gtr_phy); + + writel(gtr_phy->lane, gtr_dev->siou + SATA_CONTROL_OFFSET); +} + /* SGMII-specific initialization. */ static void xpsgtr_phy_init_sgmii(struct xpsgtr_phy *gtr_phy) { @@ -427,9 +450,12 @@ static int xpsgtr_init(struct phy *x) case ICM_PROTOCOL_SGMII: xpsgtr_phy_init_sgmii(gtr_phy); break; - case ICM_PROTOCOL_DP: case ICM_PROTOCOL_SATA: - return -EINVAL; + xpsgtr_phy_init_sata(gtr_phy); + break; + case ICM_PROTOCOL_DP: + xpsgtr_phy_init_dp(gtr_phy); + break; } dev_dbg(gtr_dev->dev, "lane %u (type %u, protocol %u): init done\n", From f6f5451d469bb1541fe50dfe1661c114bc8b30b9 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 7 Feb 2022 10:36:33 +0100 Subject: [PATCH 15/29] scsi: ceva: Enable PHY and reset support Add phy and reset support for ceva sata IP. Phy and reset are optional properties that's why detect if description is available. If not just continue with operation. This code was tested on Xilinx Kria SOM kv260-revA with sata connector populated. Signed-off-by: Michal Simek Reviewed-by: Vladimir Oltean Link: https://lore.kernel.org/r/eb3adf649be866aab19fc70ecc0fc8921545b1ac.1644226590.git.michal.simek@xilinx.com --- drivers/ata/sata_ceva.c | 44 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/ata/sata_ceva.c b/drivers/ata/sata_ceva.c index b71f10223d..43bcc59cd2 100644 --- a/drivers/ata/sata_ceva.c +++ b/drivers/ata/sata_ceva.c @@ -6,9 +6,12 @@ #include #include #include +#include #include +#include #include #include +#include #include /* Vendor Specific Register Offsets */ @@ -181,6 +184,47 @@ static int sata_ceva_bind(struct udevice *dev) static int sata_ceva_probe(struct udevice *dev) { struct ceva_sata_priv *priv = dev_get_priv(dev); + struct phy phy; + int ret; + struct reset_ctl_bulk resets; + + ret = generic_phy_get_by_index(dev, 0, &phy); + if (!ret) { + dev_dbg(dev, "Perform PHY initialization\n"); + ret = generic_phy_init(&phy); + if (ret) + return ret; + } else if (ret != -ENOENT) { + dev_dbg(dev, "could not get phy (err %d)\n", ret); + return ret; + } + + /* reset is optional */ + ret = reset_get_bulk(dev, &resets); + if (ret && ret != -ENOTSUPP && ret != -ENOENT) { + dev_dbg(dev, "Getting reset fails (err %d)\n", ret); + return ret; + } + + /* Just trigger reset when reset is specified */ + if (!ret) { + dev_dbg(dev, "Perform IP reset\n"); + ret = reset_deassert_bulk(&resets); + if (ret) { + dev_dbg(dev, "Reset fails (err %d)\n", ret); + reset_release_bulk(&resets); + return ret; + } + } + + if (phy.dev) { + dev_dbg(dev, "Perform PHY power on\n"); + ret = generic_phy_power_on(&phy); + if (ret) { + dev_dbg(dev, "PHY power on failed (err %d)\n", ret); + return ret; + } + } ceva_init_sata(priv); From 25a5fa1c4caa9325814ebaa006fabbcd717fd77b Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 4 Feb 2022 08:36:54 +0100 Subject: [PATCH 16/29] video: Add missing dependency for DM_GPIO Seps driver also requires DM_GPIO to be enabled. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/da8c25c19e5c723ed16a2a6b8494dfb967328567.1643960212.git.michal.simek@xilinx.com --- drivers/video/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index cfa08b501b..ff8e11f648 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -675,7 +675,7 @@ config VIDEO_NX config VIDEO_SEPS525 bool "Enable video support for Seps525" - depends on DM_VIDEO + depends on DM_VIDEO && DM_GPIO help Enable support for the Syncoam PM-OLED display driver (RGB 160x128). Currently driver is supporting only SPI interface. From 753a29522c87833fd943e260d6d6748462c23d48 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 4 Feb 2022 08:40:48 +0100 Subject: [PATCH 17/29] xilinx: Remove GPIO_EXTRA_HEADER selection Platform specific headers are empty that's why there is no need to include them. That's why remove them for Zynq/ZynqMP and Versal. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/625b1be0b813e2b9a5323c0529f9c567bfe13e75.1643960446.git.michal.simek@xilinx.com --- arch/arm/Kconfig | 4 ---- arch/arm/mach-versal/include/mach/gpio.h | 6 ------ arch/arm/mach-zynq/include/mach/gpio.h | 10 ---------- arch/arm/mach-zynqmp/include/mach/gpio.h | 11 ----------- 4 files changed, 31 deletions(-) delete mode 100644 arch/arm/mach-versal/include/mach/gpio.h delete mode 100644 arch/arm/mach-zynq/include/mach/gpio.h delete mode 100644 arch/arm/mach-zynqmp/include/mach/gpio.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 6b11c3a50d..ae5002c9e4 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1138,7 +1138,6 @@ config ARCH_VERSAL select DM_MMC if MMC select DM_SERIAL select GICV3 - select GPIO_EXTRA_HEADER select OF_CONTROL select SOC_DEVICE imply BOARD_LATE_INIT @@ -1164,7 +1163,6 @@ config ARCH_ZYNQ select DM_SERIAL select DM_SPI select DM_SPI_FLASH - select GPIO_EXTRA_HEADER select OF_CONTROL select SPI select SPL_BOARD_INIT if SPL @@ -1191,7 +1189,6 @@ config ARCH_ZYNQMP_R5 select DM_ETH if NET select DM_MMC if MMC select DM_SERIAL - select GPIO_EXTRA_HEADER select OF_CONTROL imply CMD_DM imply DM_USB_GADGET @@ -1209,7 +1206,6 @@ config ARCH_ZYNQMP select DM_SPI_FLASH if DM_SPI imply FIRMWARE select GICV2 - select GPIO_EXTRA_HEADER select OF_CONTROL select SPL_BOARD_INIT if SPL select SPL_CLK if SPL diff --git a/arch/arm/mach-versal/include/mach/gpio.h b/arch/arm/mach-versal/include/mach/gpio.h deleted file mode 100644 index 677facba5e..0000000000 --- a/arch/arm/mach-versal/include/mach/gpio.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright 2016 - 2018 Xilinx, Inc. - */ - -/* Empty file - for compilation */ diff --git a/arch/arm/mach-zynq/include/mach/gpio.h b/arch/arm/mach-zynq/include/mach/gpio.h deleted file mode 100644 index 6143e24563..0000000000 --- a/arch/arm/mach-zynq/include/mach/gpio.h +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 2013 Xilinx, Inc. - * Copyright (c) 2015 DAVE Embedded Systems - */ - -#ifndef _ZYNQ_GPIO_H -#define _ZYNQ_GPIO_H - -#endif /* _ZYNQ_GPIO_H */ diff --git a/arch/arm/mach-zynqmp/include/mach/gpio.h b/arch/arm/mach-zynqmp/include/mach/gpio.h deleted file mode 100644 index 542a5fc3e9..0000000000 --- a/arch/arm/mach-zynqmp/include/mach/gpio.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright 2015 Xilinx, Inc. - */ - -#ifndef __ARCH_ZYNQMP_GPIO_H -#define __ARCH_ZYNQMP_GPIO_H - -/* Empty file - sdhci requires this. */ - -#endif From 4fef0a7b7ede545774d024d44c5a1cfe3d5bb383 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Sun, 13 Feb 2022 10:09:19 +0200 Subject: [PATCH 18/29] microblaze: exception: move privileged instruction exception out of v5 ifdef The privileged instruction exception seems to have been introduced in microblaze v7.00 along with MMU support, so having it wrapped in MICROBLAZE_v5 ifdefs seems incorrect. Move it out of the ifdef, since all recent microblaze versions support it. Signed-off-by: Ovidiu Panait Link: https://lore.kernel.org/r/20220213080925.1548411-1-ovidiu.panait@windriver.com Signed-off-by: Michal Simek --- arch/microblaze/cpu/exception.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/microblaze/cpu/exception.c b/arch/microblaze/cpu/exception.c index e9476abedb..f60f1fc693 100644 --- a/arch/microblaze/cpu/exception.c +++ b/arch/microblaze/cpu/exception.c @@ -37,10 +37,10 @@ void _hw_exception_handler (void) case 0x5: puts("Divide by zero exception\n"); break; -#ifdef MICROBLAZE_V5 case 0x7: puts("Priviledged or stack protection violation exception\n"); break; +#ifdef MICROBLAZE_V5 case 0x1000: puts("Exception in delay slot\n"); break; From 1669b3d1a0b56178ec8123c48fbf6dabe46b23a4 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Sun, 13 Feb 2022 10:09:20 +0200 Subject: [PATCH 19/29] microblaze: exception: migrate MICROBLAZE_V5 to Kconfig Also, rename it to XILINX_MICROBLAZE0_DELAY_SLOT_EXCEP, since it only covers delay slot exception support. Signed-off-by: Ovidiu Panait Link: https://lore.kernel.org/r/20220213080925.1548411-2-ovidiu.panait@windriver.com Signed-off-by: Michal Simek --- arch/microblaze/cpu/exception.c | 2 +- board/xilinx/microblaze-generic/Kconfig | 9 +++++++++ include/configs/microblaze-generic.h | 3 --- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/microblaze/cpu/exception.c b/arch/microblaze/cpu/exception.c index f60f1fc693..5601dde5b4 100644 --- a/arch/microblaze/cpu/exception.c +++ b/arch/microblaze/cpu/exception.c @@ -40,7 +40,7 @@ void _hw_exception_handler (void) case 0x7: puts("Priviledged or stack protection violation exception\n"); break; -#ifdef MICROBLAZE_V5 +#if CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_DELAY_SLOT_EXCEP) case 0x1000: puts("Exception in delay slot\n"); break; diff --git a/board/xilinx/microblaze-generic/Kconfig b/board/xilinx/microblaze-generic/Kconfig index e31257d335..117b476f3f 100644 --- a/board/xilinx/microblaze-generic/Kconfig +++ b/board/xilinx/microblaze-generic/Kconfig @@ -47,6 +47,15 @@ config XILINX_MICROBLAZE0_USR_EXCEP the exception vector table. The user exception vector is located at C_BASE_VECTORS + 0x8 address. +config XILINX_MICROBLAZE0_DELAY_SLOT_EXCEP + bool "MicroBlaze delay slot exception support" + default y + help + Enable this option if the MicroBlaze processor supports exceptions + caused by delay slot instructions (processor version >= v5.00). When + enabled, the hw exception handler will print a message indicating + whether the exception was triggered by a delay slot instruction. + config XILINX_MICROBLAZE0_VECTOR_BASE_ADDR hex "Location of MicroBlaze vectors" default 0x0 diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index ca749ed18a..fd5a9cf8b8 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -11,9 +11,6 @@ /* Microblaze is microblaze_0 */ #define XILINX_FSL_NUMBER 3 -/* MicroBlaze CPU */ -#define MICROBLAZE_V5 1 - #define CONFIG_SYS_BOOTM_LEN (64 * 1024 * 1024) /* uart */ From 7422b411757faa2a01487b43138f29b4fdde3c74 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Sun, 13 Feb 2022 10:09:21 +0200 Subject: [PATCH 20/29] microblaze: exception: fix delay slot exception handling The switch statement in _hw_exception_handler() only covers the rightmost 5 bits that encode the exception cause: switch (state & 0x1f) { ... } For this reason, the "0x1000" case will never be reached, because the 13th bit was zeroed out. To fix this, move delay slot exception handling before the switch statement (delay slot (DS) bit in Exception Status Register is independent of the exception cause (EC)). Signed-off-by: Ovidiu Panait Link: https://lore.kernel.org/r/20220213080925.1548411-3-ovidiu.panait@windriver.com Signed-off-by: Michal Simek --- arch/microblaze/cpu/exception.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/microblaze/cpu/exception.c b/arch/microblaze/cpu/exception.c index 5601dde5b4..64d5fe4a80 100644 --- a/arch/microblaze/cpu/exception.c +++ b/arch/microblaze/cpu/exception.c @@ -21,6 +21,11 @@ void _hw_exception_handler (void) printf("Hardware exception at 0x%x address\n", address); R17(address); printf("Return address from exception 0x%x\n", address); + + if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_DELAY_SLOT_EXCEP) && + (state & 0x1000)) + puts("Exception in delay slot\n"); + switch (state & 0x1f) { /* mask on exception cause */ case 0x1: puts("Unaligned data access exception\n"); @@ -40,11 +45,6 @@ void _hw_exception_handler (void) case 0x7: puts("Priviledged or stack protection violation exception\n"); break; -#if CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_DELAY_SLOT_EXCEP) - case 0x1000: - puts("Exception in delay slot\n"); - break; -#endif default: puts("Undefined cause\n"); break; From ee8161f7d182e57ea828f77a6b246c884c70b7cd Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Sun, 13 Feb 2022 10:09:22 +0200 Subject: [PATCH 21/29] microblaze: exception: fix return address for delay slot exceptions According to the MicroBlaze reference manual (xilinx2021.2/ug984/page-37): """ If an exception is caused by an instruction in a delay slot (that is, ESR[DS]=1), the exception handler should return execution to the address stored in BTR instead of the normal exception return address stored in R17. """ Adjust the code to print the proper return address for delay slot exceptions. Signed-off-by: Ovidiu Panait Link: https://lore.kernel.org/r/20220213080925.1548411-4-ovidiu.panait@windriver.com Signed-off-by: Michal Simek --- arch/microblaze/cpu/exception.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/microblaze/cpu/exception.c b/arch/microblaze/cpu/exception.c index 64d5fe4a80..f79e465e1f 100644 --- a/arch/microblaze/cpu/exception.c +++ b/arch/microblaze/cpu/exception.c @@ -20,11 +20,17 @@ void _hw_exception_handler (void) MFS(state, resr); printf("Hardware exception at 0x%x address\n", address); R17(address); - printf("Return address from exception 0x%x\n", address); if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_DELAY_SLOT_EXCEP) && - (state & 0x1000)) + (state & 0x1000)) { + /* + * For exceptions in delay slots, the return address is stored + * in the Branch Target Register (BTR), rather than R17. + */ + MFS(address, rbtr); + puts("Exception in delay slot\n"); + } switch (state & 0x1f) { /* mask on exception cause */ case 0x1: @@ -49,6 +55,8 @@ void _hw_exception_handler (void) puts("Undefined cause\n"); break; } + + printf("Return address from exception 0x%x\n", address); printf("Unaligned %sword access\n", ((state & 0x800) ? "" : "half")); printf("Unaligned %s access\n", ((state & 0x400) ? "store" : "load")); printf("Register R%x\n", (state & 0x3E) >> 5); From 339f489d524e8daa40a4ab0c64bfe65ef30f5fc6 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Sun, 13 Feb 2022 10:09:23 +0200 Subject: [PATCH 22/29] microblaze: exception: move unaligned access printfs inside switch case The unaligned access messages are only valid in the case of an unaligned data access exception. Do not print them for other types of hw exceptions. Signed-off-by: Ovidiu Panait Link: https://lore.kernel.org/r/20220213080925.1548411-5-ovidiu.panait@windriver.com Signed-off-by: Michal Simek --- arch/microblaze/cpu/exception.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/microblaze/cpu/exception.c b/arch/microblaze/cpu/exception.c index f79e465e1f..d37f04364a 100644 --- a/arch/microblaze/cpu/exception.c +++ b/arch/microblaze/cpu/exception.c @@ -35,6 +35,10 @@ void _hw_exception_handler (void) switch (state & 0x1f) { /* mask on exception cause */ case 0x1: puts("Unaligned data access exception\n"); + + printf("Unaligned %sword access\n", ((state & 0x800) ? "" : "half")); + printf("Unaligned %s access\n", ((state & 0x400) ? "store" : "load")); + printf("Register R%x\n", (state & 0x3E) >> 5); break; case 0x2: puts("Illegal op-code exception\n"); @@ -57,9 +61,6 @@ void _hw_exception_handler (void) } printf("Return address from exception 0x%x\n", address); - printf("Unaligned %sword access\n", ((state & 0x800) ? "" : "half")); - printf("Unaligned %s access\n", ((state & 0x400) ? "store" : "load")); - printf("Register R%x\n", (state & 0x3E) >> 5); hang(); } From d1114b83405ceaccd46bce96001e6da4fab3ae40 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Sun, 13 Feb 2022 10:09:24 +0200 Subject: [PATCH 23/29] microblaze: exception: fix unaligned data access register mask The correct mask for getting the source/destination register from ESR in the case of an unaligned access exception is 0x3E0. With this change, a dummy unaligned store produces the expected info: """ >> swi r5, r0, 0x111 ... Hardware exception at 0x111 address Unaligned data access exception Unaligned word access Unaligned store access Register R5 Return address from exception 0x7f99dfc ### ERROR ### Please RESET the board ### """ Signed-off-by: Ovidiu Panait Link: https://lore.kernel.org/r/20220213080925.1548411-6-ovidiu.panait@windriver.com Signed-off-by: Michal Simek --- arch/microblaze/cpu/exception.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/microblaze/cpu/exception.c b/arch/microblaze/cpu/exception.c index d37f04364a..d3640d3903 100644 --- a/arch/microblaze/cpu/exception.c +++ b/arch/microblaze/cpu/exception.c @@ -38,7 +38,7 @@ void _hw_exception_handler (void) printf("Unaligned %sword access\n", ((state & 0x800) ? "" : "half")); printf("Unaligned %s access\n", ((state & 0x400) ? "store" : "load")); - printf("Register R%x\n", (state & 0x3E) >> 5); + printf("Register R%x\n", (state & 0x3E0) >> 5); break; case 0x2: puts("Illegal op-code exception\n"); From f063100593942a33d8bf40dbc95b4b44e417a368 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 17 Feb 2022 14:28:38 +0100 Subject: [PATCH 24/29] xilinx: Enable OF_BOARD for zynq and zynqmp boards The commit 985503439762 ("fdt: Don't call board_fdt_blob_setup() without OF_BOARD") forced to enable OF_BOARD for platforms which provide DT externally. Zynq/ZynqMP boards are using this feature for a long time that's why there is a need to enable it by default. Also code expects to return error in case of error that's why also fill it. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/9f11bbffe2849f4da7d72712082d579262fe8fd8.1645104518.git.michal.simek@xilinx.com --- board/xilinx/common/board.c | 3 ++- configs/xilinx_zynq_virt_defconfig | 1 + configs/xilinx_zynqmp_virt_defconfig | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 6fce23197a..0068cb8792 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -319,7 +319,7 @@ __maybe_unused int xilinx_read_eeprom(void) return 0; } -#if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) +#if defined(CONFIG_OF_BOARD) void *board_fdt_blob_setup(int *err) { void *fdt_blob; @@ -355,6 +355,7 @@ void *board_fdt_blob_setup(int *err) debug("DTB is also not passed via %p\n", fdt_blob); + *err = -EINVAL; return NULL; } #endif diff --git a/configs/xilinx_zynq_virt_defconfig b/configs/xilinx_zynq_virt_defconfig index b19a7884ef..5d180455f8 100644 --- a/configs/xilinx_zynq_virt_defconfig +++ b/configs/xilinx_zynq_virt_defconfig @@ -59,6 +59,7 @@ CONFIG_CMD_MTDPARTS=y CONFIG_CMD_MTDPARTS_SPREAD=y CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y CONFIG_CMD_UBI=y +CONFIG_OF_BOARD=y CONFIG_OF_LIST="zynq-zc702 zynq-zc706 zynq-zc770-xm010 zynq-zc770-xm011 zynq-zc770-xm011-x16 zynq-zc770-xm012 zynq-zc770-xm013 zynq-cc108 zynq-microzed zynq-minized zynq-picozed zynq-zed zynq-zturn zynq-zturn-v5 zynq-zybo zynq-zybo-z7 zynq-dlc20-rev1.0" CONFIG_ENV_IS_NOWHERE=y CONFIG_ENV_IS_IN_FAT=y diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index 10fee3fd91..133a5638a8 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -82,6 +82,7 @@ CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y CONFIG_CMD_UBI=y CONFIG_PARTITION_TYPE_GUID=y CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_BOARD=y CONFIG_OF_LIST="avnet-ultra96-rev1 zynqmp-a2197-revA zynqmp-e-a2197-00-revA zynqmp-g-a2197-00-revA zynqmp-m-a2197-01-revA zynqmp-m-a2197-02-revA zynqmp-m-a2197-03-revA zynqmp-p-a2197-00-revA zynqmp-zc1232-revA zynqmp-zc1254-revA zynqmp-zc1751-xm015-dc1 zynqmp-zc1751-xm016-dc2 zynqmp-zc1751-xm017-dc3 zynqmp-zc1751-xm018-dc4 zynqmp-zc1751-xm019-dc5 zynqmp-zcu100-revC zynqmp-zcu102-rev1.1 zynqmp-zcu102-rev1.0 zynqmp-zcu102-revA zynqmp-zcu102-revB zynqmp-zcu104-revA zynqmp-zcu104-revC zynqmp-zcu106-revA zynqmp-zcu111-revA zynqmp-zcu1275-revA zynqmp-zcu1275-revB zynqmp-zcu1285-revA zynqmp-zcu208-revA zynqmp-zcu216-revA zynqmp-topic-miamimp-xilinx-xdp-v1r1 zynqmp-sm-k26-revA zynqmp-smk-k26-revA zynqmp-dlc21-revA" CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent interrupts iommus power-domains" CONFIG_ENV_IS_NOWHERE=y From 27703ba06ded72b735ad92214857d7628a273429 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 17 Feb 2022 14:28:39 +0100 Subject: [PATCH 25/29] arm64: zynqmp: Build psu_spl_init for SPL all the time ZYNQMP_PSU_INIT_ENABLED specifically saying that has connection to full U-Boot not SPL that's why build psu_spl_init for SPL all the time. Also disable ZYNQMP_PSU_INIT_ENABLED because it ends up in situation that psu_init() is called twice which is wrong. By default only SPL should call it. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/bf1e5d9a163f8853c7d951ad42965114ab0b1f50.1645104518.git.michal.simek@xilinx.com --- arch/arm/mach-zynqmp/Makefile | 2 +- configs/xilinx_zynqmp_virt_defconfig | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile index eb6c5112b3..4f9f6b56a9 100644 --- a/arch/arm/mach-zynqmp/Makefile +++ b/arch/arm/mach-zynqmp/Makefile @@ -6,6 +6,6 @@ obj-y += clk.o obj-y += cpu.o obj-$(CONFIG_MP) += mp.o -obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o +obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o psu_spl_init.o obj-$(CONFIG_SPL_ZYNQMP_DRAM_ECC_INIT) += ecc_spl_init.o obj-$(CONFIG_ZYNQMP_PSU_INIT_ENABLED) += psu_spl_init.o diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index 133a5638a8..5cdfa6c279 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -18,7 +18,6 @@ CONFIG_ZYNQ_MAC_IN_EEPROM=y CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20 CONFIG_CMD_FRU=y CONFIG_ZYNQMP_USB=y -CONFIG_ZYNQMP_PSU_INIT_ENABLED=y CONFIG_AHCI=y CONFIG_DISTRO_DEFAULTS=y CONFIG_SYS_LOAD_ADDR=0x8000000 From 83d2941fe9750f7d98d560d7782edcf31b574d3d Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 17 Feb 2022 14:28:40 +0100 Subject: [PATCH 26/29] arm64: zynqmp: Fix dependencies around ZYNQMP_PSU_INIT_ENABLED ZYNQMP_PSU_INIT_ENABLED is called only when BOARD_EARLY_INIT_F is defined that's why cover this dependency in Kconfig. board_early_init_f() is only part related to CONFIG_ZYNQMP_PSU_INIT_ENABLED which is disabled now that's why disable BOARD_EARLY_INIT_F and also build board_early_init_f() only when CONFIG_BOARD_EARLY_INIT_F is enabled. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/d89253ec1590cd513dcd4bfbedebae618bd6d605.1645104518.git.michal.simek@xilinx.com --- arch/arm/mach-zynqmp/Kconfig | 1 + board/xilinx/zynqmp/zynqmp.c | 2 ++ configs/xilinx_zynqmp_virt_defconfig | 1 - 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-zynqmp/Kconfig b/arch/arm/mach-zynqmp/Kconfig index f8b5906039..66045067d2 100644 --- a/arch/arm/mach-zynqmp/Kconfig +++ b/arch/arm/mach-zynqmp/Kconfig @@ -140,6 +140,7 @@ config DEFINE_TCM_OCM_MMAP config ZYNQMP_PSU_INIT_ENABLED bool "Include psu_init" + select BOARD_EARLY_INIT_F help Include psu_init to full u-boot. SPL include psu_init by default. diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 242e143cbf..3a10ed859d 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -313,6 +313,7 @@ static char *zynqmp_get_silicon_idcode_name(void) } #endif +#if defined(CONFIG_BOARD_EARLY_INIT_F) int board_early_init_f(void) { #if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED) @@ -345,6 +346,7 @@ int board_early_init_f(void) return 0; } +#endif static int multi_boot(void) { diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index 5cdfa6c279..7b295282e3 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -28,7 +28,6 @@ CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set CONFIG_USE_PREBOOT=y CONFIG_PREBOOT="run scsi_init;usb start" -CONFIG_BOARD_EARLY_INIT_F=y CONFIG_BOARD_EARLY_INIT_R=y CONFIG_SPL_STACK_R=y CONFIG_SPL_FPGA=y From 05f0f269b7a6e5c9b65e88bb8b691e28cb49da84 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 17 Feb 2022 14:28:41 +0100 Subject: [PATCH 27/29] ARM: zynq: Fix debug uart initialization The commit 0dba45864b2a ("arm: Init the debug UART") calls debug_uart_init() from crt0.S but it won't work because SOC is not configured yet. That's why create board_debug_uart_init() which calls ps7_init() earlier before the first access to UART. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/18e67e02a0c7190839a1ef3a11f3fd6babcf34cc.1645104518.git.michal.simek@xilinx.com --- arch/arm/Kconfig | 1 + arch/arm/mach-zynq/spl.c | 17 ++++++++++------- board/xilinx/zynq/board.c | 7 +++++++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ae5002c9e4..c5b21cd06e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1157,6 +1157,7 @@ config ARCH_ZYNQ select CLK select CLK_ZYNQ select CPU_V7A + select DEBUG_UART_BOARD_INIT if SPL && DEBUG_UART select DM select DM_ETH if NET select DM_MMC if MMC diff --git a/arch/arm/mach-zynq/spl.c b/arch/arm/mach-zynq/spl.c index b1a5184b68..fea1c9b12a 100644 --- a/arch/arm/mach-zynq/spl.c +++ b/arch/arm/mach-zynq/spl.c @@ -16,17 +16,20 @@ #include #include -void board_init_f(ulong dummy) +#if defined(CONFIG_DEBUG_UART_BOARD_INIT) +void board_debug_uart_init(void) { ps7_init(); +} +#endif + +void board_init_f(ulong dummy) +{ +#if !defined(CONFIG_DEBUG_UART_BOARD_INIT) + ps7_init(); +#endif arch_cpu_init(); - -#ifdef CONFIG_DEBUG_UART - /* Uart debug for sure */ - debug_uart_init(); - puts("Debug uart enabled\n"); /* or printch() */ -#endif } #ifdef CONFIG_SPL_BOARD_INIT diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 1111ad6fca..26ef048835 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -25,6 +25,13 @@ DECLARE_GLOBAL_DATA_PTR; +#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_DEBUG_UART_BOARD_INIT) +void board_debug_uart_init(void) +{ + /* Add initialization sequence if UART is not configured */ +} +#endif + int board_init(void) { if (IS_ENABLED(CONFIG_SPL_BUILD)) From 11381fba99dcadf9fa59dec08d78b730042ab134 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 17 Feb 2022 14:28:42 +0100 Subject: [PATCH 28/29] arm64: zynqmp: Fix debug uart initialization The commit 0dba45864b2a ("arm: Init the debug UART") calls debug_uart_init() from crt0.S but it won't work because SOC is not configured yet. That's why create board_debug_uart_init() which calls psu_init() via new psu_uboot_init() earlier before the first access to UART in SPL. In full U-Boot call psu_uboot_init() only when CONFIG_ZYNQMP_PSU_INIT_ENABLED is enabled. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/878dc2daaa8685346f889989fbfb98b2e44da7fb.1645104518.git.michal.simek@xilinx.com --- arch/arm/Kconfig | 1 + .../mach-zynqmp/include/mach/psu_init_gpl.h | 1 + arch/arm/mach-zynqmp/spl.c | 12 ++++++- board/xilinx/zynqmp/zynqmp.c | 34 +++++++++++++------ 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5b21cd06e..5e237d8621 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1199,6 +1199,7 @@ config ARCH_ZYNQMP select ARM64 select CLK select DM + select DEBUG_UART_BOARD_INIT if SPL && DEBUG_UART select DM_ETH if NET select DM_MAILBOX select DM_MMC if MMC diff --git a/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h b/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h index e37acda2f8..434a7fa20e 100644 --- a/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h +++ b/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h @@ -22,5 +22,6 @@ void prog_reg(unsigned long addr, unsigned long mask, int psu_init(void); unsigned long psu_post_config_data(void); +int psu_uboot_init(void); #endif /* _PSU_INIT_GPL_H_ */ diff --git a/arch/arm/mach-zynqmp/spl.c b/arch/arm/mach-zynqmp/spl.c index 6b836cbff2..b428fd5312 100644 --- a/arch/arm/mach-zynqmp/spl.c +++ b/arch/arm/mach-zynqmp/spl.c @@ -19,9 +19,19 @@ #include #include +#if defined(CONFIG_DEBUG_UART_BOARD_INIT) +void board_debug_uart_init(void) +{ + psu_uboot_init(); +} +#endif + void board_init_f(ulong dummy) { - board_early_init_f(); +#if !defined(CONFIG_DEBUG_UART_BOARD_INIT) + psu_uboot_init(); +#endif + board_early_init_r(); #ifdef CONFIG_SPL_ZYNQMP_DRAM_ECC_INIT zynqmp_ecc_init(); diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 3a10ed859d..70b3c81f12 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -313,10 +313,8 @@ static char *zynqmp_get_silicon_idcode_name(void) } #endif -#if defined(CONFIG_BOARD_EARLY_INIT_F) -int board_early_init_f(void) +int __maybe_unused psu_uboot_init(void) { -#if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED) int ret; ret = psu_init(); @@ -336,16 +334,30 @@ int board_early_init_f(void) /* Delay is required for clocks to be propagated */ udelay(1000000); -#endif - -#ifdef CONFIG_DEBUG_UART - /* Uart debug for sure */ - debug_uart_init(); - puts("Debug uart enabled\n"); /* or printch() */ -#endif - + return 0; } + +#if !defined(CONFIG_SPL_BUILD) +# if defined(CONFIG_DEBUG_UART_BOARD_INIT) +void board_debug_uart_init(void) +{ +# if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED) + psu_uboot_init(); +# endif +} +# endif + +# if defined(CONFIG_BOARD_EARLY_INIT_F) +int board_early_init_f(void) +{ + int ret = 0; +# if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED) && !defined(CONFIG_DEBUG_UART_BOARD_INIT) + ret = psu_uboot_init(); +# endif + return ret; +} +# endif #endif static int multi_boot(void) From 9bd4232f958b94fdd700e44897fb61bdc898b787 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 15 Feb 2022 08:57:52 +0100 Subject: [PATCH 29/29] arm64: zynqmp: Remove additional gpio header from dlc21 This header shouldn't be in this file and there is already pointer to dt-bindings/gpio/gpio.h. Fixes: d2d14383bae4 ("arm64: zynqmp: Add support for DLC21 (Smartlynq+) board") Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/266bc91073f1149f3f60b1c9c0ba509c48470e2e.1644911870.git.michal.simek@xilinx.com --- arch/arm/dts/zynqmp-dlc21-revA.dts | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/dts/zynqmp-dlc21-revA.dts b/arch/arm/dts/zynqmp-dlc21-revA.dts index cf0aadf03c..0461219ca3 100644 --- a/arch/arm/dts/zynqmp-dlc21-revA.dts +++ b/arch/arm/dts/zynqmp-dlc21-revA.dts @@ -12,7 +12,6 @@ #include "zynqmp-clk-ccf.dtsi" #include #include -#include / { model = "Smartlynq+ DLC21 RevA";