123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Copyright (C) 2020-2021 Intel Corporation <www.intel.com>
- *
- */
- #include <asm/arch/handoff_soc64.h>
- #include <asm/io.h>
- #include <common.h>
- #include <errno.h>
- #include "log.h"
- 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;
- #endif
- default:
- debug("%s: Unknown endianness!!\n", __func__);
- return UNKNOWN_ENDIANNESS;
- }
- }
- static int getting_endianness(void *handoff_address, 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;
- }
- }
- return 0;
- }
- int socfpga_get_handoff_size(void *handoff_address)
- {
- u32 size;
- int ret;
- enum endianness endian_t;
- ret = getting_endianness(handoff_address, &endian_t);
- if (ret)
- return ret;
- size = readl(handoff_address + SOC64_HANDOFF_OFFSET_LENGTH);
- if (endian_t == BIG_ENDIAN)
- size = swab32(size);
- size = (size - SOC64_HANDOFF_OFFSET_DATA) / sizeof(u32);
- debug("%s: handoff address = 0x%p handoff size = 0x%08x\n", __func__,
- (u32 *)handoff_address, size);
- return size;
- }
- int socfpga_handoff_read(void *handoff_address, void *table, u32 table_len)
- {
- u32 temp;
- u32 *table_x32 = table;
- u32 i = 0;
- int ret;
- enum endianness endian_t;
- ret = getting_endianness(handoff_address, &endian_t);
- if (ret)
- return ret;
- temp = readl(handoff_address + SOC64_HANDOFF_OFFSET_DATA +
- (i * sizeof(u32)));
- 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;
- }
|