All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup
@ 2020-08-05 11:23 Michal Simek
  2020-08-05 11:23 ` [PATCH 1/8] xilinx: zynqmp: synchronize firmware call return payload Michal Simek
                   ` (8 more replies)
  0 siblings, 9 replies; 12+ messages in thread
From: Michal Simek @ 2020-08-05 11:23 UTC (permalink / raw)
  To: u-boot

Hi,

This patch series is intended to cleanup the functions used to get
the silicon name for ZynqMPSoC devices. It make use the firmware driver
rather than SMC call and impements more understandable agorithm to
compute the device name.

Thanks,
Ibai/Michal


Ibai Erkiaga (7):
  xilinx: zynqmp: synchronize firmware call return payload
  xilinx: zynqmp: merge firmware calls for EL2 and EL3
  xilinx: zynqmp: get chip ID using firmware driver
  xilinx: zynqmp: get chip ID at EL3
  xilinx: zynqmp: remove chip_id function
  xilinx: zynqmp: refactor silicon name function
  xilinx: zynqmp: fix incorrect map not align with IPI HW

Michal Simek (1):
  xilinx: zynqmp: Remove one static variable

 arch/arm/mach-versal/include/mach/sys_proto.h |   2 -
 arch/arm/mach-zynqmp/include/mach/sys_proto.h |   3 -
 board/xilinx/versal/cmds.c                    |   2 +-
 board/xilinx/zynqmp/zynqmp.c                  | 379 +++++++-----------
 drivers/firmware/firmware-zynqmp.c            |  84 ++--
 drivers/fpga/versalpl.c                       |   2 +-
 drivers/mailbox/zynqmp-ipi.c                  |  14 +-
 include/zynqmp_firmware.h                     |   9 +
 8 files changed, 206 insertions(+), 289 deletions(-)

-- 
2.27.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/8] xilinx: zynqmp: synchronize firmware call return payload
  2020-08-05 11:23 [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup Michal Simek
@ 2020-08-05 11:23 ` Michal Simek
  2020-08-05 11:23 ` [PATCH 2/8] xilinx: zynqmp: merge firmware calls for EL2 and EL3 Michal Simek
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Michal Simek @ 2020-08-05 11:23 UTC (permalink / raw)
  To: u-boot

From: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>

Removes duplicated definition of PAYLOAD_ARG_CNT and define it in the
firmware driver. Additionally fixes payload buffer declarations without
macro usage

Signed-off-by: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 arch/arm/mach-versal/include/mach/sys_proto.h | 2 --
 arch/arm/mach-zynqmp/include/mach/sys_proto.h | 2 --
 board/xilinx/versal/cmds.c                    | 2 +-
 drivers/fpga/versalpl.c                       | 2 +-
 include/zynqmp_firmware.h                     | 9 +++++++++
 5 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-versal/include/mach/sys_proto.h b/arch/arm/mach-versal/include/mach/sys_proto.h
index cfd480bec17e..05934c28d67f 100644
--- a/arch/arm/mach-versal/include/mach/sys_proto.h
+++ b/arch/arm/mach-versal/include/mach/sys_proto.h
@@ -8,7 +8,5 @@ enum {
 	TCM_SPLIT,
 };
 
-#define PAYLOAD_ARG_CNT	5U
-
 void tcm_init(u8 mode);
 void mem_map_fill(void);
diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h
index 2974ffbc2f56..4078f958fc61 100644
--- a/arch/arm/mach-zynqmp/include/mach/sys_proto.h
+++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h
@@ -7,8 +7,6 @@
 #ifndef _ASM_ARCH_SYS_PROTO_H
 #define _ASM_ARCH_SYS_PROTO_H
 
-#define PAYLOAD_ARG_CNT		5
-
 #define ZYNQMP_CSU_SILICON_VER_MASK	0xF
 #define KEY_PTR_LEN	32
 
diff --git a/board/xilinx/versal/cmds.c b/board/xilinx/versal/cmds.c
index 981c80ee4742..f5735d0c62c0 100644
--- a/board/xilinx/versal/cmds.c
+++ b/board/xilinx/versal/cmds.c
@@ -16,7 +16,7 @@ static int do_versal_load_pdi(struct cmd_tbl *cmdtp, int flag, int argc,
 			      char * const argv[])
 {
 	u32 buf_lo, buf_hi;
-	u32 ret_payload[5];
+	u32 ret_payload[PAYLOAD_ARG_CNT];
 	ulong addr, *pdi_buf;
 	size_t len;
 	int ret;
diff --git a/drivers/fpga/versalpl.c b/drivers/fpga/versalpl.c
index 8e2ef4f0da99..c44a7d345575 100644
--- a/drivers/fpga/versalpl.c
+++ b/drivers/fpga/versalpl.c
@@ -32,7 +32,7 @@ static int versal_load(xilinx_desc *desc, const void *buf, size_t bsize,
 	ulong bin_buf;
 	int ret;
 	u32 buf_lo, buf_hi;
-	u32 ret_payload[5];
+	u32 ret_payload[PAYLOAD_ARG_CNT];
 
 	bin_buf = versal_align_dma_buffer((ulong *)buf, bsize);
 
diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h
index 93d771ece26a..2c44951f8618 100644
--- a/include/zynqmp_firmware.h
+++ b/include/zynqmp_firmware.h
@@ -77,6 +77,15 @@ enum pm_api_id {
 
 #define PMUFW_V1_0      ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0)
 
+/*
+ * Return payload size
+ * Not every firmware call expects the same amount of return bytes, however the
+ * firmware driver always copies 5 bytes from RX buffer to the ret_payload
+ * buffer. Therefore allocating with this defined value is recommended to avoid
+ * overflows.
+ */
+#define PAYLOAD_ARG_CNT	5U
+
 unsigned int zynqmp_firmware_version(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,
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/8] xilinx: zynqmp: merge firmware calls for EL2 and EL3
  2020-08-05 11:23 [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup Michal Simek
  2020-08-05 11:23 ` [PATCH 1/8] xilinx: zynqmp: synchronize firmware call return payload Michal Simek
@ 2020-08-05 11:23 ` Michal Simek
  2020-08-05 11:23 ` [PATCH 3/8] xilinx: zynqmp: get chip ID using firmware driver Michal Simek
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Michal Simek @ 2020-08-05 11:23 UTC (permalink / raw)
  To: u-boot

From: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>

This patch merges ZynqMP firmware calls under xilinx_pm_request in order
to make trainsparent the EL. Calls at EL3 are send through IPI messages
and EL2 through SMC calls.

The EL2 call uses fixed payload and arg size as the EL3 call. The
firmware is capable to handle PMUFW_PAYLOAD_ARG_CNT bytes but the
firmware API is limited by the SMC call size.

Signed-off-by: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/firmware/firmware-zynqmp.c | 84 +++++++++++++++---------------
 1 file changed, 41 insertions(+), 43 deletions(-)

diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index 66edc1693016..41394d487ad5 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -37,6 +37,7 @@ static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
 	if (!(zynqmp_power.tx_chan.dev) || !(&zynqmp_power.rx_chan.dev))
 		return -EINVAL;
 
+	debug("%s, Sending IPI message with ID: 0x%0x\n", __func__, req[0]);
 	msg.buf = (u32 *)req;
 	msg.len = req_len;
 	ret = mbox_send(&zynqmp_power.tx_chan, &msg);
@@ -54,14 +55,6 @@ static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
 	return ret;
 }
 
-static int send_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
-{
-	if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3)
-		return ipi_req(req, req_len, res, res_maxlen);
-
-	return xilinx_pm_request(req[0], 0, 0, 0, 0, res);
-}
-
 unsigned int zynqmp_firmware_version(void)
 {
 	int ret;
@@ -74,9 +67,9 @@ unsigned int zynqmp_firmware_version(void)
 	 * asking PMUFW again.
 	 **/
 	if (pm_api_version == ZYNQMP_PM_VERSION_INVALID) {
-		const u32 request[] = { PM_GET_API_VERSION };
 
-		ret = send_req(request, ARRAY_SIZE(request), ret_payload, 2);
+		ret = xilinx_pm_request(PM_GET_API_VERSION, 0, 0, 0, 0,
+					ret_payload);
 		if (ret)
 			panic("PMUFW is not found - Please load it!\n");
 
@@ -97,16 +90,13 @@ unsigned int zynqmp_firmware_version(void)
  */
 void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size)
 {
-	const u32 request[] = {
-		PM_SET_CONFIGURATION,
-		(u32)((u64)cfg_obj)
-	};
-	u32 response = 0;
 	int err;
+	u32 ret_payload[PAYLOAD_ARG_CNT];
 
 	printf("Loading new PMUFW cfg obj (%ld bytes)\n", size);
 
-	err = send_req(request, ARRAY_SIZE(request), &response, 1);
+	err = xilinx_pm_request(PM_SET_CONFIGURATION, (u32)(u64)cfg_obj, 0, 0,
+				0, ret_payload);
 	if (err == XST_PM_NO_ACCESS) {
 		printf("PMUFW no permission to change config object\n");
 		return;
@@ -115,10 +105,10 @@ void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size)
 	if (err)
 		printf("Cannot load PMUFW configuration object (%d)\n", err);
 
-	if (response)
-		printf("PMUFW returned 0x%08x status!\n", response);
+	if (ret_payload[0])
+		printf("PMUFW returned 0x%08x status!\n", ret_payload[0]);
 
-	if ((err || response) && IS_ENABLED(CONFIG_SPL_BUILD))
+	if ((err || ret_payload[0]) && IS_ENABLED(CONFIG_SPL_BUILD))
 		panic("PMUFW config object loading failed in EL3\n");
 }
 
@@ -164,32 +154,40 @@ U_BOOT_DRIVER(zynqmp_power) = {
 int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
 				     u32 arg3, u32 *ret_payload)
 {
-	/*
-	 * Added SIP service call Function Identifier
-	 * Make sure to stay in x0 register
-	 */
-	struct pt_regs regs;
-
-	if (current_el() == 3) {
-		printf("%s: Can't call SMC from EL3 context\n", __func__);
-		return -EPERM;
-	}
-
-	regs.regs[0] = PM_SIP_SVC | api_id;
-	regs.regs[1] = ((u64)arg1 << 32) | arg0;
-	regs.regs[2] = ((u64)arg3 << 32) | arg2;
+	debug("%s@EL%d, API ID: 0x%0x\n", __func__, current_el(), api_id);
+
+	if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
+		/*
+		 * Use fixed payload and arg size as the EL2 call. The firmware
+		 * is capable to handle PMUFW_PAYLOAD_ARG_CNT bytes but the
+		 * firmware API is limited by the SMC call size
+		 */
+		u32 regs[] = {api_id, arg0, arg1, arg2, arg3};
+
+		ipi_req(regs, PAYLOAD_ARG_CNT, ret_payload, PAYLOAD_ARG_CNT);
+	} else {
+		/*
+		 * Added SIP service call Function Identifier
+		 * Make sure to stay in x0 register
+		 */
+		struct pt_regs regs;
+
+		regs.regs[0] = PM_SIP_SVC | api_id;
+		regs.regs[1] = ((u64)arg1 << 32) | arg0;
+		regs.regs[2] = ((u64)arg3 << 32) | arg2;
+
+		smc_call(&regs);
+
+		if (ret_payload) {
+			ret_payload[0] = (u32)regs.regs[0];
+			ret_payload[1] = upper_32_bits(regs.regs[0]);
+			ret_payload[2] = (u32)regs.regs[1];
+			ret_payload[3] = upper_32_bits(regs.regs[1]);
+			ret_payload[4] = (u32)regs.regs[2];
+		}
 
-	smc_call(&regs);
-
-	if (ret_payload) {
-		ret_payload[0] = (u32)regs.regs[0];
-		ret_payload[1] = upper_32_bits(regs.regs[0]);
-		ret_payload[2] = (u32)regs.regs[1];
-		ret_payload[3] = upper_32_bits(regs.regs[1]);
-		ret_payload[4] = (u32)regs.regs[2];
 	}
-
-	return regs.regs[0];
+	return (ret_payload) ? ret_payload[0] : 0;
 }
 
 static const struct udevice_id zynqmp_firmware_ids[] = {
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/8] xilinx: zynqmp: get chip ID using firmware driver
  2020-08-05 11:23 [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup Michal Simek
  2020-08-05 11:23 ` [PATCH 1/8] xilinx: zynqmp: synchronize firmware call return payload Michal Simek
  2020-08-05 11:23 ` [PATCH 2/8] xilinx: zynqmp: merge firmware calls for EL2 and EL3 Michal Simek
@ 2020-08-05 11:23 ` Michal Simek
  2020-08-05 11:23 ` [PATCH 4/8] xilinx: zynqmp: get chip ID at EL3 Michal Simek
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Michal Simek @ 2020-08-05 11:23 UTC (permalink / raw)
  To: u-boot

From: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>

Current implementation for getting chip ID uses either raw access on EL3
or a SMC call to get the silicon information. Following change
simplifies the code using always the firmware driver.

Signed-off-by: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 board/xilinx/zynqmp/zynqmp.c | 79 ++++++++++++------------------------
 1 file changed, 27 insertions(+), 52 deletions(-)

diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 8a4df6fc1ab6..cf5febc4c41c 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -199,60 +199,34 @@ static const struct {
 
 int chip_id(unsigned char id)
 {
-	struct pt_regs regs;
 	int val = -EINVAL;
+	u32 ret_payload[PAYLOAD_ARG_CNT];
 
-	if (current_el() != 3) {
-		regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
-		regs.regs[1] = 0;
-		regs.regs[2] = 0;
-		regs.regs[3] = 0;
-
-		smc_call(&regs);
-
-		/*
-		 * SMC returns:
-		 * regs[0][31:0]  = status of the operation
-		 * regs[0][63:32] = CSU.IDCODE register
-		 * regs[1][31:0]  = CSU.version register
-		 * regs[1][63:32] = CSU.IDCODE2 register
-		 */
-		switch (id) {
-		case IDCODE:
-			regs.regs[0] = upper_32_bits(regs.regs[0]);
-			regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
-					ZYNQMP_CSU_IDCODE_SVD_MASK;
-			regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
-			val = regs.regs[0];
-			break;
-		case VERSION:
-			regs.regs[1] = lower_32_bits(regs.regs[1]);
-			regs.regs[1] &= ZYNQMP_CSU_SILICON_VER_MASK;
-			val = regs.regs[1];
-			break;
-		case IDCODE2:
-			regs.regs[1] = lower_32_bits(regs.regs[1]);
-			regs.regs[1] >>= ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
-			val = regs.regs[1];
-			break;
-		default:
-			printf("%s, Invalid Req:0x%x\n", __func__, id);
-		}
-	} else {
-		switch (id) {
-		case IDCODE:
-			val = readl(ZYNQMP_CSU_IDCODE_ADDR);
-			val &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
-			       ZYNQMP_CSU_IDCODE_SVD_MASK;
-			val >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
-			break;
-		case VERSION:
-			val = readl(ZYNQMP_CSU_VER_ADDR);
-			val &= ZYNQMP_CSU_SILICON_VER_MASK;
-			break;
-		default:
-			printf("%s, Invalid Req:0x%x\n", __func__, id);
-		}
+	xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
+
+	/*
+	 * Firmware returns:
+	 * payload[0][31:0]  = status of the operation
+	 * payload[1]] = IDCODE
+	 * payload[2][19:0]  = Version
+	 * payload[2][28:20] = EXTENDED_IDCODE
+	 * payload[2][29] = PL_INIT
+	 */
+	switch (id) {
+	case IDCODE:
+		val = ret_payload[1];
+		val &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
+			ZYNQMP_CSU_IDCODE_SVD_MASK;
+		val >>=	ZYNQMP_CSU_IDCODE_SVD_SHIFT;
+		break;
+	case VERSION:
+		val = ret_payload[2] & ZYNQMP_CSU_SILICON_VER_MASK;
+		break;
+	case IDCODE2:
+		val = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
+		break;
+	default:
+		printf("%s, Invalid Req:0x%x\n", __func__, id);
 	}
 
 	return val;
@@ -277,6 +251,7 @@ static char *zynqmp_get_silicon_idcode_name(void)
 
 	id = chip_id(IDCODE);
 	ver = chip_id(IDCODE2);
+	debug("%s, ID: 0x%0X, Ver: 0x%0X\r\n", __func__, id, ver);
 
 	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
 		if (zynqmp_devices[i].id == id) {
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/8] xilinx: zynqmp: get chip ID at EL3
  2020-08-05 11:23 [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup Michal Simek
                   ` (2 preceding siblings ...)
  2020-08-05 11:23 ` [PATCH 3/8] xilinx: zynqmp: get chip ID using firmware driver Michal Simek
@ 2020-08-05 11:23 ` Michal Simek
  2020-08-05 11:23 ` [PATCH 5/8] xilinx: zynqmp: remove chip_id function Michal Simek
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Michal Simek @ 2020-08-05 11:23 UTC (permalink / raw)
  To: u-boot

From: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>

Modify the board init function to allow getting the chip ID when U-Boot
proper is executed at EL3.

Signed-off-by: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 board/xilinx/zynqmp/zynqmp.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index cf5febc4c41c..2b95a61dd0aa 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -362,12 +362,10 @@ int board_init(void)
 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
     !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
     defined(CONFIG_SPL_BUILD))
-	if (current_el() != 3) {
-		zynqmppl.name = zynqmp_get_silicon_idcode_name();
-		printf("Chip ID:\t%s\n", zynqmppl.name);
-		fpga_init();
-		fpga_add(fpga_xilinx, &zynqmppl);
-	}
+	zynqmppl.name = zynqmp_get_silicon_idcode_name();
+	printf("Chip ID:\t%s\n", zynqmppl.name);
+	fpga_init();
+	fpga_add(fpga_xilinx, &zynqmppl);
 #endif
 
 	if (current_el() == 3)
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/8] xilinx: zynqmp: remove chip_id function
  2020-08-05 11:23 [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup Michal Simek
                   ` (3 preceding siblings ...)
  2020-08-05 11:23 ` [PATCH 4/8] xilinx: zynqmp: get chip ID at EL3 Michal Simek
@ 2020-08-05 11:23 ` Michal Simek
  2020-08-05 11:23 ` [PATCH 6/8] xilinx: zynqmp: refactor silicon name function Michal Simek
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Michal Simek @ 2020-08-05 11:23 UTC (permalink / raw)
  To: u-boot

From: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>

Remove chip_id function and integrate the firmware call in the
zynqmp_get_silicon_idcode_name function. The change avoids querying the
firmware twice and makes the code bit more clear.

Signed-off-by: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 arch/arm/mach-zynqmp/include/mach/sys_proto.h |  1 -
 board/xilinx/zynqmp/zynqmp.c                  | 57 +++++++------------
 2 files changed, 20 insertions(+), 38 deletions(-)

diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h
index 4078f958fc61..f2b3ceab1358 100644
--- a/arch/arm/mach-zynqmp/include/mach/sys_proto.h
+++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h
@@ -49,7 +49,6 @@ int zynqmp_mmio_read(const u32 address, u32 *value);
 
 void initialize_tcm(bool mode);
 void mem_map_fill(void);
-int chip_id(unsigned char id);
 #if defined(CONFIG_SYS_MEM_RSVD_FOR_MMU) || defined(CONFIG_DEFINE_TCM_OCM_MMAP)
 void tcm_init(u8 mode);
 #endif
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 2b95a61dd0aa..2a430a9e4638 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -197,41 +197,6 @@ static const struct {
 };
 #endif
 
-int chip_id(unsigned char id)
-{
-	int val = -EINVAL;
-	u32 ret_payload[PAYLOAD_ARG_CNT];
-
-	xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
-
-	/*
-	 * Firmware returns:
-	 * payload[0][31:0]  = status of the operation
-	 * payload[1]] = IDCODE
-	 * payload[2][19:0]  = Version
-	 * payload[2][28:20] = EXTENDED_IDCODE
-	 * payload[2][29] = PL_INIT
-	 */
-	switch (id) {
-	case IDCODE:
-		val = ret_payload[1];
-		val &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
-			ZYNQMP_CSU_IDCODE_SVD_MASK;
-		val >>=	ZYNQMP_CSU_IDCODE_SVD_SHIFT;
-		break;
-	case VERSION:
-		val = ret_payload[2] & ZYNQMP_CSU_SILICON_VER_MASK;
-		break;
-	case IDCODE2:
-		val = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
-		break;
-	default:
-		printf("%s, Invalid Req:0x%x\n", __func__, id);
-	}
-
-	return val;
-}
-
 #define ZYNQMP_VERSION_SIZE		9
 #define ZYNQMP_PL_STATUS_BIT		9
 #define ZYNQMP_IPDIS_VCU_BIT		8
@@ -248,9 +213,27 @@ static char *zynqmp_get_silicon_idcode_name(void)
 	u32 i, id, ver, j;
 	char *buf;
 	static char name[ZYNQMP_VERSION_SIZE];
+	u32 ret_payload[PAYLOAD_ARG_CNT];
+
+	xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
+
+	/*
+	 * Firmware returns:
+	 * payload[0][31:0]  = status of the operation
+	 * payload[1]] = IDCODE
+	 * payload[2][19:0]  = Version
+	 * payload[2][28:20] = EXTENDED_IDCODE
+	 * payload[2][29] = PL_INIT
+	 */
+
+	/* Get IDCODE field */
+	id = ret_payload[1];
+	id &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | ZYNQMP_CSU_IDCODE_SVD_MASK;
+	id >>=	ZYNQMP_CSU_IDCODE_SVD_SHIFT;
+
+	/* Shift silicon version info */
+	ver = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
 
-	id = chip_id(IDCODE);
-	ver = chip_id(IDCODE2);
 	debug("%s, ID: 0x%0X, Ver: 0x%0X\r\n", __func__, id, ver);
 
 	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/8] xilinx: zynqmp: refactor silicon name function
  2020-08-05 11:23 [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup Michal Simek
                   ` (4 preceding siblings ...)
  2020-08-05 11:23 ` [PATCH 5/8] xilinx: zynqmp: remove chip_id function Michal Simek
@ 2020-08-05 11:23 ` Michal Simek
  2020-08-19  7:34   ` Michal Simek
  2020-08-05 11:23 ` [PATCH 7/8] xilinx: zynqmp: fix incorrect map not align with IPI HW Michal Simek
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 12+ messages in thread
From: Michal Simek @ 2020-08-05 11:23 UTC (permalink / raw)
  To: u-boot

From: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>

Current algorithm used to get the silicon name is bit complicated and
hard to follow. Updated to use more straightforward mechanism based on
the Device ID code table (Table 1-2). The full IDCODE register is used
(except device revision bits [31:28]) to get the device name and IDCODE2
value is used for identifying the variant.

Additionally to make the algorithm bit more clear it also save some space
as the devices table is slightly bit smaller.

Signed-off-by: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 board/xilinx/zynqmp/zynqmp.c | 299 +++++++++++++++--------------------
 1 file changed, 126 insertions(+), 173 deletions(-)

diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 2a430a9e4638..383125087255 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -38,180 +38,123 @@
 
 #include "pm_cfg_obj.h"
 
+#define ZYNQMP_VERSION_SIZE	7
+#define EFUSE_VCU_DIS_MASK     0x100
+#define EFUSE_VCU_DIS_SHIFT    8
+#define EFUSE_GPU_DIS_MASK     0x20
+#define EFUSE_GPU_DIS_SHIFT    5
+#define IDCODE2_PL_INIT_MASK   0x200
+#define IDCODE2_PL_INIT_SHIFT  9
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
-    !defined(CONFIG_SPL_BUILD)
+    !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
+    defined(CONFIG_SPL_BUILD))
+
 static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
 
+enum {
+	ZYNQMP_VARIANT_EG = BIT(0U),
+	ZYNQMP_VARIANT_EV = BIT(1U),
+	ZYNQMP_VARIANT_CG = BIT(2U),
+	ZYNQMP_VARIANT_DR = BIT(3U),
+};
+
 static const struct {
 	u32 id;
-	u32 ver;
-	char *name;
-	bool evexists;
+	u8 device;
+	u8 variants;
 } zynqmp_devices[] = {
 	{
-		.id = 0x10,
-		.name = "3eg",
-	},
-	{
-		.id = 0x10,
-		.ver = 0x2c,
-		.name = "3cg",
-	},
-	{
-		.id = 0x11,
-		.name = "2eg",
-	},
-	{
-		.id = 0x11,
-		.ver = 0x2c,
-		.name = "2cg",
-	},
-	{
-		.id = 0x20,
-		.name = "5ev",
-		.evexists = 1,
-	},
-	{
-		.id = 0x20,
-		.ver = 0x100,
-		.name = "5eg",
-		.evexists = 1,
-	},
-	{
-		.id = 0x20,
-		.ver = 0x12c,
-		.name = "5cg",
-		.evexists = 1,
-	},
-	{
-		.id = 0x21,
-		.name = "4ev",
-		.evexists = 1,
-	},
-	{
-		.id = 0x21,
-		.ver = 0x100,
-		.name = "4eg",
-		.evexists = 1,
-	},
-	{
-		.id = 0x21,
-		.ver = 0x12c,
-		.name = "4cg",
-		.evexists = 1,
-	},
-	{
-		.id = 0x30,
-		.name = "7ev",
-		.evexists = 1,
-	},
-	{
-		.id = 0x30,
-		.ver = 0x100,
-		.name = "7eg",
-		.evexists = 1,
-	},
-	{
-		.id = 0x30,
-		.ver = 0x12c,
-		.name = "7cg",
-		.evexists = 1,
-	},
-	{
-		.id = 0x38,
-		.name = "9eg",
-	},
-	{
-		.id = 0x38,
-		.ver = 0x2c,
-		.name = "9cg",
+		.id = 0x04711093,
+		.device = 2,
+		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
 	},
 	{
-		.id = 0x39,
-		.name = "6eg",
+		.id = 0x04710093,
+		.device = 3,
+		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
 	},
 	{
-		.id = 0x39,
-		.ver = 0x2c,
-		.name = "6cg",
+		.id = 0x04721093,
+		.device = 4,
+		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
+			ZYNQMP_VARIANT_EV,
 	},
 	{
-		.id = 0x40,
-		.name = "11eg",
-	},
-	{ /* For testing purpose only */
-		.id = 0x50,
-		.ver = 0x2c,
-		.name = "15cg",
+		.id = 0x04720093,
+		.device = 5,
+		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
+			ZYNQMP_VARIANT_EV,
 	},
 	{
-		.id = 0x50,
-		.name = "15eg",
+		.id = 0x04739093,
+		.device = 6,
+		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
 	},
 	{
-		.id = 0x58,
-		.name = "19eg",
+		.id = 0x04730093,
+		.device = 7,
+		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
+			ZYNQMP_VARIANT_EV,
 	},
 	{
-		.id = 0x59,
-		.name = "17eg",
+		.id = 0x04738093,
+		.device = 9,
+		.variants = ZYNQMP_VARIANT_EG,
 	},
 	{
-		.id = 0x61,
-		.name = "21dr",
+		.id = 0x04740093,
+		.device = 11,
+		.variants = ZYNQMP_VARIANT_EG,
 	},
 	{
-		.id = 0x63,
-		.name = "23dr",
+		.id = 0x04750093,
+		.device = 15,
+		.variants = ZYNQMP_VARIANT_EG,
 	},
 	{
-		.id = 0x65,
-		.name = "25dr",
+		.id = 0x04759093,
+		.device = 17,
+		.variants = ZYNQMP_VARIANT_EG,
 	},
 	{
-		.id = 0x64,
-		.name = "27dr",
+		.id = 0x04758093,
+		.device = 19,
+		.variants = ZYNQMP_VARIANT_EG,
 	},
 	{
-		.id = 0x60,
-		.name = "28dr",
+		.id = 0x047E1093,
+		.device = 21,
+		.variants = ZYNQMP_VARIANT_DR,
 	},
 	{
-		.id = 0x62,
-		.name = "29dr",
+		.id = 0x047E5093,
+		.device = 25,
+		.variants = ZYNQMP_VARIANT_DR,
 	},
 	{
-		.id = 0x66,
-		.name = "39dr",
+		.id = 0x047E4093,
+		.device = 27,
+		.variants = ZYNQMP_VARIANT_DR,
 	},
 	{
-		.id = 0x7b,
-		.name = "48dr",
+		.id = 0x047E0093,
+		.device = 28,
+		.variants = ZYNQMP_VARIANT_DR,
 	},
 	{
-		.id = 0x7e,
-		.name = "49dr",
+		.id = 0x047E2093,
+		.device = 29,
+		.variants = ZYNQMP_VARIANT_DR,
 	},
 };
-#endif
-
-#define ZYNQMP_VERSION_SIZE		9
-#define ZYNQMP_PL_STATUS_BIT		9
-#define ZYNQMP_IPDIS_VCU_BIT		8
-#define ZYNQMP_PL_STATUS_MASK		BIT(ZYNQMP_PL_STATUS_BIT)
-#define ZYNQMP_CSU_VERSION_MASK		~(ZYNQMP_PL_STATUS_MASK)
-#define ZYNQMP_CSU_VCUDIS_VER_MASK	ZYNQMP_CSU_VERSION_MASK & \
-					~BIT(ZYNQMP_IPDIS_VCU_BIT)
-#define MAX_VARIANTS_EV			3
 
-#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
-	!defined(CONFIG_SPL_BUILD)
 static char *zynqmp_get_silicon_idcode_name(void)
 {
-	u32 i, id, ver, j;
-	char *buf;
+	u32 i;
+	u32 idcode, idcode2;
 	static char name[ZYNQMP_VERSION_SIZE];
 	u32 ret_payload[PAYLOAD_ARG_CNT];
 
@@ -226,58 +169,68 @@ static char *zynqmp_get_silicon_idcode_name(void)
 	 * payload[2][29] = PL_INIT
 	 */
 
-	/* Get IDCODE field */
-	id = ret_payload[1];
-	id &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | ZYNQMP_CSU_IDCODE_SVD_MASK;
-	id >>=	ZYNQMP_CSU_IDCODE_SVD_SHIFT;
-
-	/* Shift silicon version info */
-	ver = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
-
-	debug("%s, ID: 0x%0X, Ver: 0x%0X\r\n", __func__, id, ver);
+	idcode  = ret_payload[1];
+	idcode2 = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
+	debug("%s, IDCODE: 0x%0X, IDCODE2: 0x%0X\r\n", __func__, idcode,
+	      idcode2);
 
 	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
-		if (zynqmp_devices[i].id == id) {
-			if (zynqmp_devices[i].evexists &&
-			    !(ver & ZYNQMP_PL_STATUS_MASK))
-				break;
-			if (zynqmp_devices[i].ver == (ver &
-			    ZYNQMP_CSU_VERSION_MASK))
-				break;
-		}
+		if (zynqmp_devices[i].id == (idcode & 0x0FFFFFFF))
+			break;
 	}
 
 	if (i >= ARRAY_SIZE(zynqmp_devices))
 		return "unknown";
 
+	/* Add device prefix to the name */
 	strncat(name, "zu", 2);
-	if (!zynqmp_devices[i].evexists ||
-	    (ver & ZYNQMP_PL_STATUS_MASK)) {
-		strncat(name, zynqmp_devices[i].name,
-			ZYNQMP_VERSION_SIZE - 3);
-		return name;
-	}
-
-	/*
-	 * Here we are means, PL not powered up and ev variant
-	 * exists. So, we need to ignore VCU disable bit(8) in
-	 * version and findout if its CG or EG/EV variant.
-	 */
-	for (j = 0; j < MAX_VARIANTS_EV; j++, i++) {
-		if ((zynqmp_devices[i].ver & ~BIT(ZYNQMP_IPDIS_VCU_BIT)) ==
-		    (ver & ZYNQMP_CSU_VCUDIS_VER_MASK)) {
-			strncat(name, zynqmp_devices[i].name,
-				ZYNQMP_VERSION_SIZE - 3);
-			break;
+	strncat(&name[2], simple_itoa(zynqmp_devices[i].device), 2);
+
+	if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EV) {
+		/* Devices with EV variant might be EG/CG/EV family */
+		if (idcode2 & IDCODE2_PL_INIT_MASK) {
+			u32 family = ((idcode2 & EFUSE_VCU_DIS_MASK) >>
+				      EFUSE_VCU_DIS_SHIFT) << 1 |
+				     ((idcode2 & EFUSE_GPU_DIS_MASK) >>
+				      EFUSE_GPU_DIS_SHIFT);
+
+			/*
+			 * Get family name based on extended idcode values as
+			 * determined on UG1087, EXTENDED_IDCODE register
+			 * description
+			 */
+			switch (family) {
+			case 0x00:
+				strncat(name, "ev", 2);
+				break;
+			case 0x10:
+				strncat(name, "eg", 2);
+				break;
+			case 0x11:
+				strncat(name, "cg", 2);
+				break;
+			default:
+				/* Do not append family name*/
+				break;
+			}
+		} else {
+			/*
+			 * When PL powered down the VCU Disable efuse cannot be
+			 * read. So, ignore the bit and just findout if it is CG
+			 * or EG/EV variant.
+			 */
+			strncat(name, (idcode2 & EFUSE_GPU_DIS_MASK) ? "cg" :
+				"e", 2);
 		}
-	}
-
-	if (j >= MAX_VARIANTS_EV)
-		return "unknown";
-
-	if (strstr(name, "eg") || strstr(name, "ev")) {
-		buf = strstr(name, "e");
-		*buf = '\0';
+	} else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_CG) {
+		/* Devices with CG variant might be EG or CG family */
+		strncat(name, (idcode2 & EFUSE_GPU_DIS_MASK) ? "cg" : "eg", 2);
+	} else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EG) {
+		strncat(name, "eg", 2);
+	} else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_DR) {
+		strncat(name, "dr", 2);
+	} else {
+		debug("Variant not identified\n");
 	}
 
 	return name;
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 7/8] xilinx: zynqmp: fix incorrect map not align with IPI HW
  2020-08-05 11:23 [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup Michal Simek
                   ` (5 preceding siblings ...)
  2020-08-05 11:23 ` [PATCH 6/8] xilinx: zynqmp: refactor silicon name function Michal Simek
@ 2020-08-05 11:23 ` Michal Simek
  2020-08-05 11:23 ` [PATCH 8/8] xilinx: zynqmp: Remove one static variable Michal Simek
  2020-08-20  7:55 ` [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup Michal Simek
  8 siblings, 0 replies; 12+ messages in thread
From: Michal Simek @ 2020-08-05 11:23 UTC (permalink / raw)
  To: u-boot

From: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>

Current IPI module register description is not align with IPI HW. The
registers with the wrong offset are not used so it does not cause real
issues. This patch aligns the register description.

Additionally comments added to explain why recv function does not check
any flag prior copying rx data.

Fixes: 660b0c77d816 ("mailbox: zynqmp: ipi mailbox driver")
Signed-off-by: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/mailbox/zynqmp-ipi.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/mailbox/zynqmp-ipi.c b/drivers/mailbox/zynqmp-ipi.c
index f206a27a79e4..746377e557cb 100644
--- a/drivers/mailbox/zynqmp-ipi.c
+++ b/drivers/mailbox/zynqmp-ipi.c
@@ -24,10 +24,12 @@
 struct ipi_int_regs {
 	u32 trig; /* 0x0  */
 	u32 obs;  /* 0x4  */
-	u32 ist;  /* 0x8  */
-	u32 imr;  /* 0xC  */
-	u32 ier;  /* 0x10 */
-	u32 idr;  /* 0x14 */
+	u32 dummy0;
+	u32 dummy1;
+	u32 isr;  /* 0x10  */
+	u32 imr;  /* 0x14  */
+	u32 ier;  /* 0x18 */
+	u32 idr;  /* 0x1C */
 };
 
 #define ipi_int_apu ((struct ipi_int_regs *)IPI_INT_REG_BASE_APU)
@@ -66,6 +68,10 @@ static int zynqmp_ipi_recv(struct mbox_chan *chan, void *data)
 	struct zynqmp_ipi *zynqmp = dev_get_priv(chan->dev);
 	u32 *mbx = (u32 *)zynqmp->local_res_regs;
 
+	/*
+	 * PMU Firmware does not trigger IPI interrupt for API call responses so
+	 * there is no need to check ISR flags
+	 */
 	for (size_t i = 0; i < msg->len; i++)
 		msg->buf[i] = readl(&mbx[i]);
 
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 8/8] xilinx: zynqmp: Remove one static variable
  2020-08-05 11:23 [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup Michal Simek
                   ` (6 preceding siblings ...)
  2020-08-05 11:23 ` [PATCH 7/8] xilinx: zynqmp: fix incorrect map not align with IPI HW Michal Simek
@ 2020-08-05 11:23 ` Michal Simek
  2020-08-19  7:38   ` Michal Simek
  2020-08-20  7:55 ` [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup Michal Simek
  8 siblings, 1 reply; 12+ messages in thread
From: Michal Simek @ 2020-08-05 11:23 UTC (permalink / raw)
  To: u-boot

There is no reason to have name variable saved in BSS section when it
doesn't need to be really used. That's why remove static from variable
definition and use strdup() to duplicate string with exact size from malloc
area instead.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 board/xilinx/zynqmp/zynqmp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 383125087255..e8ea3c5a4975 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -155,7 +155,7 @@ static char *zynqmp_get_silicon_idcode_name(void)
 {
 	u32 i;
 	u32 idcode, idcode2;
-	static char name[ZYNQMP_VERSION_SIZE];
+	char name[ZYNQMP_VERSION_SIZE];
 	u32 ret_payload[PAYLOAD_ARG_CNT];
 
 	xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
@@ -183,7 +183,7 @@ static char *zynqmp_get_silicon_idcode_name(void)
 		return "unknown";
 
 	/* Add device prefix to the name */
-	strncat(name, "zu", 2);
+	strncpy(name, "zu", ZYNQMP_VERSION_SIZE);
 	strncat(&name[2], simple_itoa(zynqmp_devices[i].device), 2);
 
 	if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EV) {
@@ -233,7 +233,7 @@ static char *zynqmp_get_silicon_idcode_name(void)
 		debug("Variant not identified\n");
 	}
 
-	return name;
+	return strdup(name);
 }
 #endif
 
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/8] xilinx: zynqmp: refactor silicon name function
  2020-08-05 11:23 ` [PATCH 6/8] xilinx: zynqmp: refactor silicon name function Michal Simek
@ 2020-08-19  7:34   ` Michal Simek
  0 siblings, 0 replies; 12+ messages in thread
From: Michal Simek @ 2020-08-19  7:34 UTC (permalink / raw)
  To: u-boot

Hi,

st 5. 8. 2020 v 13:24 odes?latel Michal Simek <michal.simek@xilinx.com> napsal:
>
> From: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>
>
> Current algorithm used to get the silicon name is bit complicated and
> hard to follow. Updated to use more straightforward mechanism based on
> the Device ID code table (Table 1-2). The full IDCODE register is used
> (except device revision bits [31:28]) to get the device name and IDCODE2
> value is used for identifying the variant.
>
> Additionally to make the algorithm bit more clear it also save some space
> as the devices table is slightly bit smaller.
>
> Signed-off-by: Ibai Erkiaga <ibai.erkiaga-elorza@xilinx.com>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> ---
>
>  board/xilinx/zynqmp/zynqmp.c | 299 +++++++++++++++--------------------
>  1 file changed, 126 insertions(+), 173 deletions(-)
>
> diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
> index 2a430a9e4638..383125087255 100644
> --- a/board/xilinx/zynqmp/zynqmp.c
> +++ b/board/xilinx/zynqmp/zynqmp.c
> @@ -38,180 +38,123 @@
>
>  #include "pm_cfg_obj.h"
>
> +#define ZYNQMP_VERSION_SIZE    7
> +#define EFUSE_VCU_DIS_MASK     0x100
> +#define EFUSE_VCU_DIS_SHIFT    8
> +#define EFUSE_GPU_DIS_MASK     0x20
> +#define EFUSE_GPU_DIS_SHIFT    5
> +#define IDCODE2_PL_INIT_MASK   0x200
> +#define IDCODE2_PL_INIT_SHIFT  9
> +
>  DECLARE_GLOBAL_DATA_PTR;
>
>  #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
> -    !defined(CONFIG_SPL_BUILD)
> +    !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
> +    defined(CONFIG_SPL_BUILD))
> +
>  static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
>
> +enum {
> +       ZYNQMP_VARIANT_EG = BIT(0U),
> +       ZYNQMP_VARIANT_EV = BIT(1U),
> +       ZYNQMP_VARIANT_CG = BIT(2U),
> +       ZYNQMP_VARIANT_DR = BIT(3U),
> +};
> +
>  static const struct {
>         u32 id;
> -       u32 ver;
> -       char *name;
> -       bool evexists;
> +       u8 device;
> +       u8 variants;
>  } zynqmp_devices[] = {
>         {
> -               .id = 0x10,
> -               .name = "3eg",
> -       },
> -       {
> -               .id = 0x10,
> -               .ver = 0x2c,
> -               .name = "3cg",
> -       },
> -       {
> -               .id = 0x11,
> -               .name = "2eg",
> -       },
> -       {
> -               .id = 0x11,
> -               .ver = 0x2c,
> -               .name = "2cg",
> -       },
> -       {
> -               .id = 0x20,
> -               .name = "5ev",
> -               .evexists = 1,
> -       },
> -       {
> -               .id = 0x20,
> -               .ver = 0x100,
> -               .name = "5eg",
> -               .evexists = 1,
> -       },
> -       {
> -               .id = 0x20,
> -               .ver = 0x12c,
> -               .name = "5cg",
> -               .evexists = 1,
> -       },
> -       {
> -               .id = 0x21,
> -               .name = "4ev",
> -               .evexists = 1,
> -       },
> -       {
> -               .id = 0x21,
> -               .ver = 0x100,
> -               .name = "4eg",
> -               .evexists = 1,
> -       },
> -       {
> -               .id = 0x21,
> -               .ver = 0x12c,
> -               .name = "4cg",
> -               .evexists = 1,
> -       },
> -       {
> -               .id = 0x30,
> -               .name = "7ev",
> -               .evexists = 1,
> -       },
> -       {
> -               .id = 0x30,
> -               .ver = 0x100,
> -               .name = "7eg",
> -               .evexists = 1,
> -       },
> -       {
> -               .id = 0x30,
> -               .ver = 0x12c,
> -               .name = "7cg",
> -               .evexists = 1,
> -       },
> -       {
> -               .id = 0x38,
> -               .name = "9eg",
> -       },
> -       {
> -               .id = 0x38,
> -               .ver = 0x2c,
> -               .name = "9cg",
> +               .id = 0x04711093,
> +               .device = 2,
> +               .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
>         },
>         {
> -               .id = 0x39,
> -               .name = "6eg",
> +               .id = 0x04710093,
> +               .device = 3,
> +               .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
>         },
>         {
> -               .id = 0x39,
> -               .ver = 0x2c,
> -               .name = "6cg",
> +               .id = 0x04721093,
> +               .device = 4,
> +               .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
> +                       ZYNQMP_VARIANT_EV,
>         },
>         {
> -               .id = 0x40,
> -               .name = "11eg",
> -       },
> -       { /* For testing purpose only */
> -               .id = 0x50,
> -               .ver = 0x2c,
> -               .name = "15cg",
> +               .id = 0x04720093,
> +               .device = 5,
> +               .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
> +                       ZYNQMP_VARIANT_EV,
>         },
>         {
> -               .id = 0x50,
> -               .name = "15eg",
> +               .id = 0x04739093,
> +               .device = 6,
> +               .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
>         },
>         {
> -               .id = 0x58,
> -               .name = "19eg",
> +               .id = 0x04730093,
> +               .device = 7,
> +               .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
> +                       ZYNQMP_VARIANT_EV,
>         },
>         {
> -               .id = 0x59,
> -               .name = "17eg",
> +               .id = 0x04738093,
> +               .device = 9,
> +               .variants = ZYNQMP_VARIANT_EG,
>         },
>         {
> -               .id = 0x61,
> -               .name = "21dr",
> +               .id = 0x04740093,
> +               .device = 11,
> +               .variants = ZYNQMP_VARIANT_EG,
>         },
>         {
> -               .id = 0x63,
> -               .name = "23dr",
> +               .id = 0x04750093,
> +               .device = 15,
> +               .variants = ZYNQMP_VARIANT_EG,
>         },
>         {
> -               .id = 0x65,
> -               .name = "25dr",
> +               .id = 0x04759093,
> +               .device = 17,
> +               .variants = ZYNQMP_VARIANT_EG,
>         },
>         {
> -               .id = 0x64,
> -               .name = "27dr",
> +               .id = 0x04758093,
> +               .device = 19,
> +               .variants = ZYNQMP_VARIANT_EG,
>         },
>         {
> -               .id = 0x60,
> -               .name = "28dr",
> +               .id = 0x047E1093,
> +               .device = 21,
> +               .variants = ZYNQMP_VARIANT_DR,
>         },
>         {
> -               .id = 0x62,
> -               .name = "29dr",
> +               .id = 0x047E5093,
> +               .device = 25,
> +               .variants = ZYNQMP_VARIANT_DR,
>         },
>         {
> -               .id = 0x66,
> -               .name = "39dr",
> +               .id = 0x047E4093,
> +               .device = 27,
> +               .variants = ZYNQMP_VARIANT_DR,
>         },
>         {
> -               .id = 0x7b,
> -               .name = "48dr",
> +               .id = 0x047E0093,
> +               .device = 28,
> +               .variants = ZYNQMP_VARIANT_DR,
>         },
>         {
> -               .id = 0x7e,
> -               .name = "49dr",
> +               .id = 0x047E2093,
> +               .device = 29,
> +               .variants = ZYNQMP_VARIANT_DR,
>         },
>  };
> -#endif
> -
> -#define ZYNQMP_VERSION_SIZE            9
> -#define ZYNQMP_PL_STATUS_BIT           9
> -#define ZYNQMP_IPDIS_VCU_BIT           8
> -#define ZYNQMP_PL_STATUS_MASK          BIT(ZYNQMP_PL_STATUS_BIT)
> -#define ZYNQMP_CSU_VERSION_MASK                ~(ZYNQMP_PL_STATUS_MASK)
> -#define ZYNQMP_CSU_VCUDIS_VER_MASK     ZYNQMP_CSU_VERSION_MASK & \
> -                                       ~BIT(ZYNQMP_IPDIS_VCU_BIT)
> -#define MAX_VARIANTS_EV                        3
>
> -#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
> -       !defined(CONFIG_SPL_BUILD)
>  static char *zynqmp_get_silicon_idcode_name(void)
>  {
> -       u32 i, id, ver, j;
> -       char *buf;
> +       u32 i;
> +       u32 idcode, idcode2;
>         static char name[ZYNQMP_VERSION_SIZE];
>         u32 ret_payload[PAYLOAD_ARG_CNT];
>
> @@ -226,58 +169,68 @@ static char *zynqmp_get_silicon_idcode_name(void)
>          * payload[2][29] = PL_INIT
>          */
>
> -       /* Get IDCODE field */
> -       id = ret_payload[1];
> -       id &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | ZYNQMP_CSU_IDCODE_SVD_MASK;
> -       id >>=  ZYNQMP_CSU_IDCODE_SVD_SHIFT;
> -
> -       /* Shift silicon version info */
> -       ver = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
> -
> -       debug("%s, ID: 0x%0X, Ver: 0x%0X\r\n", __func__, id, ver);
> +       idcode  = ret_payload[1];
> +       idcode2 = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
> +       debug("%s, IDCODE: 0x%0X, IDCODE2: 0x%0X\r\n", __func__, idcode,
> +             idcode2);
>
>         for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
> -               if (zynqmp_devices[i].id == id) {
> -                       if (zynqmp_devices[i].evexists &&
> -                           !(ver & ZYNQMP_PL_STATUS_MASK))
> -                               break;
> -                       if (zynqmp_devices[i].ver == (ver &
> -                           ZYNQMP_CSU_VERSION_MASK))
> -                               break;
> -               }
> +               if (zynqmp_devices[i].id == (idcode & 0x0FFFFFFF))
> +                       break;
>         }
>
>         if (i >= ARRAY_SIZE(zynqmp_devices))
>                 return "unknown";
>
> +       /* Add device prefix to the name */
>         strncat(name, "zu", 2);
> -       if (!zynqmp_devices[i].evexists ||
> -           (ver & ZYNQMP_PL_STATUS_MASK)) {
> -               strncat(name, zynqmp_devices[i].name,
> -                       ZYNQMP_VERSION_SIZE - 3);
> -               return name;
> -       }
> -
> -       /*
> -        * Here we are means, PL not powered up and ev variant
> -        * exists. So, we need to ignore VCU disable bit(8) in
> -        * version and findout if its CG or EG/EV variant.
> -        */
> -       for (j = 0; j < MAX_VARIANTS_EV; j++, i++) {
> -               if ((zynqmp_devices[i].ver & ~BIT(ZYNQMP_IPDIS_VCU_BIT)) ==
> -                   (ver & ZYNQMP_CSU_VCUDIS_VER_MASK)) {
> -                       strncat(name, zynqmp_devices[i].name,
> -                               ZYNQMP_VERSION_SIZE - 3);
> -                       break;
> +       strncat(&name[2], simple_itoa(zynqmp_devices[i].device), 2);
> +
> +       if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EV) {
> +               /* Devices with EV variant might be EG/CG/EV family */
> +               if (idcode2 & IDCODE2_PL_INIT_MASK) {
> +                       u32 family = ((idcode2 & EFUSE_VCU_DIS_MASK) >>
> +                                     EFUSE_VCU_DIS_SHIFT) << 1 |
> +                                    ((idcode2 & EFUSE_GPU_DIS_MASK) >>
> +                                     EFUSE_GPU_DIS_SHIFT);
> +
> +                       /*
> +                        * Get family name based on extended idcode values as
> +                        * determined on UG1087, EXTENDED_IDCODE register
> +                        * description
> +                        */
> +                       switch (family) {
> +                       case 0x00:
> +                               strncat(name, "ev", 2);
> +                               break;
> +                       case 0x10:
> +                               strncat(name, "eg", 2);
> +                               break;
> +                       case 0x11:
> +                               strncat(name, "cg", 2);
> +                               break;
> +                       default:
> +                               /* Do not append family name*/
> +                               break;
> +                       }
> +               } else {
> +                       /*
> +                        * When PL powered down the VCU Disable efuse cannot be
> +                        * read. So, ignore the bit and just findout if it is CG
> +                        * or EG/EV variant.
> +                        */
> +                       strncat(name, (idcode2 & EFUSE_GPU_DIS_MASK) ? "cg" :
> +                               "e", 2);
>                 }
> -       }
> -
> -       if (j >= MAX_VARIANTS_EV)
> -               return "unknown";
> -
> -       if (strstr(name, "eg") || strstr(name, "ev")) {
> -               buf = strstr(name, "e");
> -               *buf = '\0';
> +       } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_CG) {
> +               /* Devices with CG variant might be EG or CG family */
> +               strncat(name, (idcode2 & EFUSE_GPU_DIS_MASK) ? "cg" : "eg", 2);
> +       } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EG) {
> +               strncat(name, "eg", 2);
> +       } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_DR) {
> +               strncat(name, "dr", 2);
> +       } else {
> +               debug("Variant not identified\n");
>         }
>
>         return name;
> --
> 2.27.0
>

Please ignore this patch because it removes support for several DR devices.

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 8/8] xilinx: zynqmp: Remove one static variable
  2020-08-05 11:23 ` [PATCH 8/8] xilinx: zynqmp: Remove one static variable Michal Simek
@ 2020-08-19  7:38   ` Michal Simek
  0 siblings, 0 replies; 12+ messages in thread
From: Michal Simek @ 2020-08-19  7:38 UTC (permalink / raw)
  To: u-boot

st 5. 8. 2020 v 13:24 odes?latel Michal Simek <michal.simek@xilinx.com> napsal:
>
> There is no reason to have name variable saved in BSS section when it
> doesn't need to be really used. That's why remove static from variable
> definition and use strdup() to duplicate string with exact size from malloc
> area instead.
>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> ---
>
>  board/xilinx/zynqmp/zynqmp.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
> index 383125087255..e8ea3c5a4975 100644
> --- a/board/xilinx/zynqmp/zynqmp.c
> +++ b/board/xilinx/zynqmp/zynqmp.c
> @@ -155,7 +155,7 @@ static char *zynqmp_get_silicon_idcode_name(void)
>  {
>         u32 i;
>         u32 idcode, idcode2;
> -       static char name[ZYNQMP_VERSION_SIZE];
> +       char name[ZYNQMP_VERSION_SIZE];
>         u32 ret_payload[PAYLOAD_ARG_CNT];
>
>         xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
> @@ -183,7 +183,7 @@ static char *zynqmp_get_silicon_idcode_name(void)
>                 return "unknown";
>
>         /* Add device prefix to the name */
> -       strncat(name, "zu", 2);
> +       strncpy(name, "zu", ZYNQMP_VERSION_SIZE);
>         strncat(&name[2], simple_itoa(zynqmp_devices[i].device), 2);
>
>         if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EV) {
> @@ -233,7 +233,7 @@ static char *zynqmp_get_silicon_idcode_name(void)
>                 debug("Variant not identified\n");
>         }
>
> -       return name;
> +       return strdup(name);
>  }
>  #endif
>
> --
> 2.27.0
>

This patch depends on 6/8 that's why please ignore it too.

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup
  2020-08-05 11:23 [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup Michal Simek
                   ` (7 preceding siblings ...)
  2020-08-05 11:23 ` [PATCH 8/8] xilinx: zynqmp: Remove one static variable Michal Simek
@ 2020-08-20  7:55 ` Michal Simek
  8 siblings, 0 replies; 12+ messages in thread
From: Michal Simek @ 2020-08-20  7:55 UTC (permalink / raw)
  To: u-boot

st 5. 8. 2020 v 13:23 odes?latel Michal Simek <michal.simek@xilinx.com> napsal:
>
> Hi,
>
> This patch series is intended to cleanup the functions used to get
> the silicon name for ZynqMPSoC devices. It make use the firmware driver
> rather than SMC call and impements more understandable agorithm to
> compute the device name.
>
> Thanks,
> Ibai/Michal
>
>
> Ibai Erkiaga (7):
>   xilinx: zynqmp: synchronize firmware call return payload
>   xilinx: zynqmp: merge firmware calls for EL2 and EL3
>   xilinx: zynqmp: get chip ID using firmware driver
>   xilinx: zynqmp: get chip ID at EL3
>   xilinx: zynqmp: remove chip_id function

Applied all above.

>   xilinx: zynqmp: refactor silicon name function

This one needs to be fixed that's why not applied.

>   xilinx: zynqmp: fix incorrect map not align with IPI HW

Applied this one

>
> Michal Simek (1):
>   xilinx: zynqmp: Remove one static variable

It depends on the patch above that's why it is not applied.

Thanks,
Michal


-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-08-20  7:55 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-05 11:23 [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup Michal Simek
2020-08-05 11:23 ` [PATCH 1/8] xilinx: zynqmp: synchronize firmware call return payload Michal Simek
2020-08-05 11:23 ` [PATCH 2/8] xilinx: zynqmp: merge firmware calls for EL2 and EL3 Michal Simek
2020-08-05 11:23 ` [PATCH 3/8] xilinx: zynqmp: get chip ID using firmware driver Michal Simek
2020-08-05 11:23 ` [PATCH 4/8] xilinx: zynqmp: get chip ID at EL3 Michal Simek
2020-08-05 11:23 ` [PATCH 5/8] xilinx: zynqmp: remove chip_id function Michal Simek
2020-08-05 11:23 ` [PATCH 6/8] xilinx: zynqmp: refactor silicon name function Michal Simek
2020-08-19  7:34   ` Michal Simek
2020-08-05 11:23 ` [PATCH 7/8] xilinx: zynqmp: fix incorrect map not align with IPI HW Michal Simek
2020-08-05 11:23 ` [PATCH 8/8] xilinx: zynqmp: Remove one static variable Michal Simek
2020-08-19  7:38   ` Michal Simek
2020-08-20  7:55 ` [PATCH 0/8] xilinx: zynqmp: Silicon name cleanup Michal Simek

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.