
On Fri, Apr 30, 2021 at 3:39 PM Siew Chin Lim elly.siew.chin.lim@intel.com wrote:
N5X support both HPS handoff data and DDR handoff data. Existing HPS handoff functions are restructured to support both existing devices and N5X device.
Signed-off-by: Siew Chin Lim elly.siew.chin.lim@intel.com Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com
v2:
- Enabled auto detect the endianness from the magic word
- Merged and simplifying the big and little endian flow
.../mach-socfpga/include/mach/handoff_soc64.h | 38 +++++- arch/arm/mach-socfpga/system_manager_soc64.c | 18 +-- arch/arm/mach-socfpga/wrap_handoff_soc64.c | 126 +++++++++++++----- 3 files changed, 136 insertions(+), 46 deletions(-)
[...]
@@ -10,12 +10,54 @@ #include <errno.h> #include "log.h"
-int socfpga_get_handoff_size(void *handoff_address, enum endianness endian) +static enum endianness check_endianness(u32 handoff) +{
switch (handoff) {
case SOC64_HANDOFF_MAGIC_BOOT:
case SOC64_HANDOFF_MAGIC_MUX:
case SOC64_HANDOFF_MAGIC_IOCTL:
case SOC64_HANDOFF_MAGIC_FPGA:
case SOC64_HANDOFF_MAGIC_DELAY:
case SOC64_HANDOFF_MAGIC_CLOCK:
case SOC64_HANDOFF_MAGIC_MISC:
return BIG_ENDIAN;
+#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X)
case SOC64_HANDOFF_DDR_UMCTL2_MAGIC:
debug("%s: umctl2 handoff data\n", __func__);
return LITTLE_ENDIAN;
case SOC64_HANDOFF_DDR_PHY_MAGIC:
debug("%s: PHY handoff data\n", __func__);
return LITTLE_ENDIAN;
case SOC64_HANDOFF_DDR_PHY_INIT_ENGINE_MAGIC:
debug("%s: PHY engine handoff data\n", __func__);
return LITTLE_ENDIAN;
Can merge to one 'return' and print the 'handoff' if needed.
+#endif
default:
debug("%s: Unknown endianness!!\n", __func__);
return UNKNOWN_ENDIANNESS;
}
+}
+int socfpga_get_handoff_size(void *handoff_address) { u32 size;
enum endianness endian_t;
/* Checking handoff data is little endian ? */
endian_t = check_endianness(readl(handoff_address));
if (endian_t == UNKNOWN_ENDIANNESS) {
/* Trying to check handoff data is big endian? */
endian_t = check_endianness(swab32(readl(handoff_address)));
if (endian_t == UNKNOWN_ENDIANNESS) {
debug("%s: Cannot find HANDOFF MAGIC ", __func__);
debug("at addr 0x%p\n", (u32 *)handoff_address);
return -EPERM;
}
} size = readl(handoff_address + SOC64_HANDOFF_OFFSET_LENGTH);
if (endian == BIG_ENDIAN)
if (endian_t == BIG_ENDIAN) size = swab32(size); size = (size - SOC64_HANDOFF_OFFSET_DATA) / sizeof(u32);
@@ -26,41 +68,61 @@ int socfpga_get_handoff_size(void *handoff_address, enum endianness endian) return size; }
-int socfpga_handoff_read(void *handoff_address, void *table, u32 table_len,
enum endianness big_endian)
+int socfpga_handoff_read(void *handoff_address, void *table, u32 table_len) {
u32 temp, i;
u32 temp; u32 *table_x32 = table;
u32 i = 0;
enum endianness endian_t;
/* Checking handoff data is little endian ? */
endian_t = check_endianness(readl(handoff_address));
This code is similar in socfpga_get_handoff_size(). Can have a function to get the endianness.
debug("%s: handoff addr = 0x%p ", __func__, (u32 *)handoff_address);
if (big_endian) {
if (swab32(readl(SOC64_HANDOFF_BASE)) == SOC64_HANDOFF_MAGIC_BOOT) {
debug("Handoff table address = 0x%p ", table_x32);
debug("table length = 0x%x\n", table_len);
debug("%s: handoff data =\n{\n", __func__);
for (i = 0; i < table_len; i++) {
temp = readl(handoff_address +
SOC64_HANDOFF_OFFSET_DATA +
(i * sizeof(u32)));
*table_x32 = swab32(temp);
if (!(i % 2))
debug(" No.%d Addr 0x%08x: ", i,
*table_x32);
else
debug(" 0x%08x\n", *table_x32);
table_x32++;
}
debug("\n}\n");
} else {
debug("%s: Cannot find SOC64_HANDOFF_MAGIC_BOOT ", __func__);
debug("at addr 0x%p\n", (u32 *)handoff_address);
if (endian_t == UNKNOWN_ENDIANNESS) {
/* Trying to check handoff data is big endian? */
endian_t = check_endianness(swab32(readl(handoff_address)));
if (endian_t == UNKNOWN_ENDIANNESS) {
debug("%s: Cannot find HANDOFF MAGIC ", __func__);
debug("at addr 0x%p\n", (u32 *)handoff_address); return -EPERM; } }
temp = readl(handoff_address + SOC64_HANDOFF_OFFSET_DATA +
(i * sizeof(u32)));
When this can't be done in the 'for' loop below?
if (endian_t == BIG_ENDIAN) {
debug("%s: Handoff addr = 0x%p ", __func__, (u32 *)handoff_address);
debug("Handoff table address = 0x%p ", table_x32);
debug("table length = 0x%x\n", table_len);
debug("%s: handoff data =\n{\n", __func__);
*table_x32 = swab32(temp);
} else if (endian_t == LITTLE_ENDIAN) {
debug(" {\n");
*table_x32 = temp;
}
debug(" No.%d Addr 0x%08x: ", i, *table_x32);
for (i = 1; i < table_len; i++) {
table_x32++;
temp = readl(handoff_address +
SOC64_HANDOFF_OFFSET_DATA +
(i * sizeof(u32)));
if (endian_t == BIG_ENDIAN)
*table_x32 = swab32(temp);
else if (endian_t == LITTLE_ENDIAN)
*table_x32 = temp;
if (!(i % 2))
debug(" No.%d Addr 0x%08x: ", i,
*table_x32);
else
debug(" 0x%08x\n", *table_x32);
}
debug("\n}\n");
return 0;
}
Regards Ley Foon