[U-Boot] [PATCH 1/3] driver/mc: Add Layerscape Management Complex hardware interface

Management Complex (MC) Portal is an interface between MC firmware and U-boot/Linux. U-boot/Linux could interact with MC firmware through sending/receiving MC commands to/from MC firmware. This patch enables the hardware interface between MC firmware and U-boot/Linux. Current patch supports MC portal flib version 0.4.
Signed-off-by: Lijun Pan Lijun.Pan@freescale.com --- include/layerscape/mc_hardware/fsl_mc_cmd_common.h | 54 ++++++++++++++++++ .../layerscape/mc_hardware/fsl_mc_dpmng_commands.h | 60 ++++++++++++++++++++ include/layerscape/mc_hardware/fsl_mc_io.h | 65 ++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 include/layerscape/mc_hardware/fsl_mc_cmd_common.h create mode 100644 include/layerscape/mc_hardware/fsl_mc_dpmng_commands.h create mode 100644 include/layerscape/mc_hardware/fsl_mc_io.h
diff --git a/include/layerscape/mc_hardware/fsl_mc_cmd_common.h b/include/layerscape/mc_hardware/fsl_mc_cmd_common.h new file mode 100644 index 0000000..bf2a3d0 --- /dev/null +++ b/include/layerscape/mc_hardware/fsl_mc_cmd_common.h @@ -0,0 +1,54 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __FSL_MC_CMD_COMMON_H +#define __FSL_MC_CMD_COMMON_H + +#define MC_CMD_NUM_OF_PARAMS 7 + +struct mc_command { + uint64_t header; + uint64_t params[MC_CMD_NUM_OF_PARAMS]; +}; + +enum mc_cmd_status { + MC_CMD_STATUS_OK = 0x0, /* passed */ + MC_CMD_STATUS_READY = 0x1, /* Ready to be processed */ + MC_CMD_STATUS_AUTH_ERR = 0x3, /* Authentication error */ + MC_CMD_STATUS_NO_PRIVILEGE = 0x4, + MC_CMD_STATUS_DMA_ERR = 0x5, + MC_CMD_STATUS_CONFIG_ERR = 0x6, + MC_CMD_STATUS_TIMEOUT = 0x7, + MC_CMD_STATUS_NO_RESOURCE = 0x8, + MC_CMD_STATUS_NO_MEMORY = 0x9, + MC_CMD_STATUS_BUSY = 0xA, + MC_CMD_STATUS_UNSUPPORTED_OP = 0xB, + MC_CMD_STATUS_INVALID_STATE = 0xC +}; + +/* + * MC command priorities + */ +enum mc_cmd_priorities { + CMDIF_PRI_LOW = 0, /* Low Priority command indication */ + CMDIF_PRI_HIGH = 1 /* High Priority command indication */ +}; + +static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id, + uint8_t cmd_size, + uint8_t priority, uint16_t auth_id) +{ + uint64_t header; + + header = (cmd_id & 0xfffULL) << 52; + header |= (auth_id & 0x3ffULL) << 38; + header |= (cmd_size & 0x3fULL) << 31; + header |= (priority & 0x1ULL) << 15; + header |= (MC_CMD_STATUS_READY & 0xff) << 16; + + return header; +} +#endif /* __FSL_MC_CMD_COMMON_H */ diff --git a/include/layerscape/mc_hardware/fsl_mc_dpmng_commands.h b/include/layerscape/mc_hardware/fsl_mc_dpmng_commands.h new file mode 100644 index 0000000..fa3c078 --- /dev/null +++ b/include/layerscape/mc_hardware/fsl_mc_dpmng_commands.h @@ -0,0 +1,60 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * fsl_mc_dpmng_commands.h + * Management Complex (MC) Data Path Management commands + */ +#ifndef _FSL_MC_DPMNG_COMMANDS_H +#define _FSL_MC_DPMNG_COMMANDS_H + +#include <layerscape/mc_hardware/fsl_mc_cmd_common.h> +#include <linux/compat.h> + +/* + * Define Management Complex firmware version information + */ +#define MC_VER_MAJOR 2 +#define MC_VER_MINOR 0 + +/* + * Management Complex firmware version information + */ +struct mc_version { + uint32_t major; + /* Major version number: incremented on API compatibility changes */ + uint32_t minor; + /* Minor version number: incremented on API additions (backward + * compatible); reset when major version is incremented. */ + uint32_t revision; + /* Internal revision number: incremented on implementation changes + * and/or bug fixes that have no impact on API */ +}; + +/* + * Retrieves the Management Complex firmware version information + */ +#define DPMNG_CMDID_GET_VERSION 0x831 +#define DPMNG_CMDSZ_GET_VERSION (8 * 2) + +static inline void build_cmd_mc_get_version(struct mc_command *cmd) +{ + cmd->header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION, + DPMNG_CMDSZ_GET_VERSION, + CMDIF_PRI_LOW, 0); + + memset(cmd->params, 0, sizeof(cmd->params)); +} + +static inline void parse_resp_mc_get_version(struct mc_command *cmd, + struct mc_version *mc_ver_info) +{ + mc_ver_info->revision = lower_32_bits(cmd->params[0]); + mc_ver_info->major = upper_32_bits(cmd->params[0]); + mc_ver_info->minor = cmd->params[1] & 0xff; +} + +#endif /* _FSL_MC_DPMNG_COMMANDS_H */ diff --git a/include/layerscape/mc_hardware/fsl_mc_io.h b/include/layerscape/mc_hardware/fsl_mc_io.h new file mode 100644 index 0000000..f121238 --- /dev/null +++ b/include/layerscape/mc_hardware/fsl_mc_io.h @@ -0,0 +1,65 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __FSL_MC_IO_H +#define __FSL_MC_IO_H + +#include <layerscape/mc_hardware/fsl_mc_cmd_common.h> + +/** + * mc_write_command - writes a command to a Management Complex (MC) portal + * + * @portal_regs: pointer to an MC portal's MMIO registers + * @cmd: pointer to a filled command + */ +static inline void __must_check mc_write_command(struct mc_command __iomem * + portal_regs, + struct mc_command *cmd) +{ + int i; + + /* copy command parameters into the portal MMIO registers */ + for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++) + writeq(cmd->params[i], &portal_regs->params[i]); + + /* submit the command by writing the header */ + writeq(cmd->header, &portal_regs->header); +} + +/** + * mc_read_response - reads the response for the last MC command from a + * Management Complex (MC) portal + * + * @portal_regs: pointer to an MC portal's MMIO registers + * @response: pointer to command response buffer + * + * Returns MC_CMD_STATUS_OK on Success; Error code otherwise. + */ +static inline enum mc_cmd_status __must_check mc_read_response(struct mc_command + __iomem * + portal_regs, + struct mc_command + *response) +{ + int i; + enum mc_cmd_status status; + + /* Copy command response header from MC portal MMIO space: */ + response->header = readq(&portal_regs->header); + status = (response->header >> 16) & 0xff; + + if (status != MC_CMD_STATUS_OK) + goto out; + + /* Copy command response data from MC portal MMIO space: */ + for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++) + response->params[i] = readq(&portal_regs->params[i]); + +out: + return status; +} + +#endif /* __FSL_MC_IO_H */

Management Complex wrapper functions are built upon the Management Complex hardware interface. These wrapper functions are OS dependent, which vary in U-boot and Linux. Current patch supports MC portal flib version 0.4.
Signed-off-by: Lijun Pan Lijun.Pan@freescale.com --- arch/arm/cpu/armv8/fsl-lsch3/cpu.c | 2 +- board/freescale/ls2085a/ls2085a.c | 2 +- drivers/net/fsl_mc/Makefile | 4 +- drivers/net/fsl_mc/fsl_mc_dpmng_cmd_wrappers.c | 29 +++++++++ drivers/net/fsl_mc/fsl_mc_io_wrapper.c | 89 ++++++++++++++++++++++++++ drivers/net/fsl_mc/mc.c | 2 +- include/{ => layerscape}/fsl_mc.h | 0 include/layerscape/fsl_mc_dpmng_cmd_wrappers.h | 19 ++++++ include/layerscape/fsl_mc_io_wrapper.h | 25 ++++++++ 9 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 drivers/net/fsl_mc/fsl_mc_dpmng_cmd_wrappers.c create mode 100644 drivers/net/fsl_mc/fsl_mc_io_wrapper.c rename include/{ => layerscape}/fsl_mc.h (100%) create mode 100644 include/layerscape/fsl_mc_dpmng_cmd_wrappers.h create mode 100644 include/layerscape/fsl_mc_io_wrapper.h
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c index c129d03..e05567e 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c +++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c @@ -10,9 +10,9 @@ #include <asm/armv8/mmu.h> #include <asm/io.h> #include <asm/arch-fsl-lsch3/immap_lsch3.h> +#include <layerscape/fsl_mc.h> #include "cpu.h" #include "speed.h" -#include <fsl_mc.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/board/freescale/ls2085a/ls2085a.c b/board/freescale/ls2085a/ls2085a.c index a18db1d..263a604 100644 --- a/board/freescale/ls2085a/ls2085a.c +++ b/board/freescale/ls2085a/ls2085a.c @@ -12,7 +12,7 @@ #include <asm/io.h> #include <fdt_support.h> #include <libfdt.h> -#include <fsl_mc.h> +#include <layerscape/fsl_mc.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/drivers/net/fsl_mc/Makefile b/drivers/net/fsl_mc/Makefile index 4834086..1470c40 100644 --- a/drivers/net/fsl_mc/Makefile +++ b/drivers/net/fsl_mc/Makefile @@ -5,4 +5,6 @@ #
# Layerscape MC driver -obj-y += mc.o +obj-y += mc.o \ + fsl_mc_io_wrapper.o \ + fsl_mc_dpmng_cmd_wrappers.o diff --git a/drivers/net/fsl_mc/fsl_mc_dpmng_cmd_wrappers.c b/drivers/net/fsl_mc/fsl_mc_dpmng_cmd_wrappers.c new file mode 100644 index 0000000..613439f --- /dev/null +++ b/drivers/net/fsl_mc/fsl_mc_dpmng_cmd_wrappers.c @@ -0,0 +1,29 @@ +/* + * Freescale Layerscape MC DPMNG command wrappers + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * Author: German Rivera German.Rivera@freescale.com + * Lijun Pan Lijun.Pan@freescale.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/types.h> +#include <linux/string.h> +#include <layerscape/fsl_mc_dpmng_cmd_wrappers.h> +#include <layerscape/fsl_mc_io_wrapper.h> + +int mc_get_version(struct mc_portal_wrapper *mc_portal, + struct mc_version *mc_ver_info) +{ + int error; + struct mc_command cmd; + + build_cmd_mc_get_version(&cmd); + error = mc_portal_wrapper_send_command(mc_portal, &cmd); + if (error < 0) + return error; + + parse_resp_mc_get_version(&cmd, mc_ver_info); + return 0; +} diff --git a/drivers/net/fsl_mc/fsl_mc_io_wrapper.c b/drivers/net/fsl_mc/fsl_mc_io_wrapper.c new file mode 100644 index 0000000..47938a7 --- /dev/null +++ b/drivers/net/fsl_mc/fsl_mc_io_wrapper.c @@ -0,0 +1,89 @@ +/* + * Freescale Layerscape MC I/O wrapper + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * Author: German Rivera German.Rivera@freescale.com + * Lijun Pan Lijun.Pan@freescale.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <asm/io.h> +#include <layerscape/fsl_mc_io_wrapper.h> +#include <layerscape/mc_hardware/fsl_mc_io.h> + +/** + * mc_portal_wrapper_send_command - Send MC command and wait for response + * + * @mc_portal: Pointer to MC portal wrapper to be used + * @cmd: MC command buffer. On input, it contains the command to send to the MC. + * On output, it contains the response from the MC if any. + * + * Depending on the sharing option specified when creating the MC portal + * wrapper, this function will use a spinlock or mutex to ensure exclusive + * access to the MC portal from the point when the command is sent until a + * response is received from the MC. + */ +int mc_portal_wrapper_send_command(struct mc_portal_wrapper *mc_portal, + struct mc_command *cmd) +{ + enum mc_cmd_status status; + int error; + int timeout = 2000; + + mc_write_command(mc_portal->mmio_regs, cmd); + + do { + udelay(1000); /* throttle polling */ + if (timeout-- <= 0) { + error = -ETIMEDOUT; + goto out; + } + status = mc_read_response(mc_portal->mmio_regs, cmd); + } while (status == MC_CMD_STATUS_READY); + /* MC_CMD_STATUS_READY means command has been send to MC portal, it is + * ready to read the result from the MC portal. */ + + switch (status) { + case MC_CMD_STATUS_OK: + error = 0; + break; + case MC_CMD_STATUS_AUTH_ERR: + error = -EACCES; /* Authentication error */ + break; + case MC_CMD_STATUS_NO_PRIVILEGE: + error = -EPERM; /* Permission denied */ + break; + case MC_CMD_STATUS_DMA_ERR: + error = -EIO; /* Input/Output error */ + break; + case MC_CMD_STATUS_CONFIG_ERR: + error = -EINVAL; /* Device not configured */ + break; + case MC_CMD_STATUS_TIMEOUT: + error = -ETIMEDOUT; /* Operation timed out */ + break; + case MC_CMD_STATUS_NO_RESOURCE: + error = -ENAVAIL; /* Resource temporarily unavailable */ + break; + case MC_CMD_STATUS_NO_MEMORY: + error = -ENOMEM; /* Cannot allocate memory */ + break; + case MC_CMD_STATUS_BUSY: + error = -EBUSY; /* Device busy */ + break; + case MC_CMD_STATUS_UNSUPPORTED_OP: + error = -EINVAL; /* Operation not supported by device */ + break; + case MC_CMD_STATUS_INVALID_STATE: + error = -ENODEV; /* Invalid device state */ + break; + default: + error = -EINVAL; + } + +out: + return error; +} diff --git a/drivers/net/fsl_mc/mc.c b/drivers/net/fsl_mc/mc.c index df84568..e8ee4f3 100644 --- a/drivers/net/fsl_mc/mc.c +++ b/drivers/net/fsl_mc/mc.c @@ -5,7 +5,7 @@ */ #include <errno.h> #include <asm/io.h> -#include <fsl_mc.h> +#include <layerscape/fsl_mc.h>
DECLARE_GLOBAL_DATA_PTR; static int mc_boot_status; diff --git a/include/fsl_mc.h b/include/layerscape/fsl_mc.h similarity index 100% rename from include/fsl_mc.h rename to include/layerscape/fsl_mc.h diff --git a/include/layerscape/fsl_mc_dpmng_cmd_wrappers.h b/include/layerscape/fsl_mc_dpmng_cmd_wrappers.h new file mode 100644 index 0000000..532db1e --- /dev/null +++ b/include/layerscape/fsl_mc_dpmng_cmd_wrappers.h @@ -0,0 +1,19 @@ +/* + * Freescale Layerscape Management Complex (MC) dpmng command wrappers + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _FSL_MC_DPMNG_CMD_WRAPPERS_H +#define _FSL_MC_DPMNG_CMD_WRAPPERS_H + +#include <layerscape/mc_hardware/fsl_mc_dpmng_commands.h> + +struct mc_portal_wrapper; + +int mc_get_version(struct mc_portal_wrapper *mc_portal, + struct mc_version *mc_ver_info); + +#endif /* _FSL_MC_DPMNG_CMD_WRAPPERS_H */ diff --git a/include/layerscape/fsl_mc_io_wrapper.h b/include/layerscape/fsl_mc_io_wrapper.h new file mode 100644 index 0000000..6aed2ce --- /dev/null +++ b/include/layerscape/fsl_mc_io_wrapper.h @@ -0,0 +1,25 @@ +/* + * Freescale Layerscape Management Complex (MC) I/O wrapper + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _FSL_MC_IO_WRAPPER_H +#define _FSL_MC_IO_WRAPPER_H + +#include <asm/io.h> + +/* + * struct mc_portal_wrapper - MC command portal wrapper object + */ +struct mc_portal_wrapper { + struct mc_command __iomem *mmio_regs; +}; + +int __must_check mc_portal_wrapper_send_command(struct mc_portal_wrapper + *mc_portal, + struct mc_command *cmd); + +#endif /* _FSL_MC_IO_WRAPPER_H */

After the MC is booted, u-boot should print out the Management Complex version info where appropriate. Also, clean up the code to make checkpatch.pl happy.
Signed-off-by: Lijun Pan Lijun.Pan@freescale.com Signed-off-by: J. German Rivera German.Rivera@freescale.com --- drivers/net/fsl_mc/mc.c | 130 ++++++++++++++++++++++++++------------- include/configs/ls2085a_common.h | 2 +- 2 files changed, 88 insertions(+), 44 deletions(-)
diff --git a/drivers/net/fsl_mc/mc.c b/drivers/net/fsl_mc/mc.c index e8ee4f3..3c6b2ef 100644 --- a/drivers/net/fsl_mc/mc.c +++ b/drivers/net/fsl_mc/mc.c @@ -3,9 +3,12 @@ * * SPDX-License-Identifier: GPL-2.0+ */ + #include <errno.h> #include <asm/io.h> #include <layerscape/fsl_mc.h> +#include <layerscape/fsl_mc_io_wrapper.h> +#include <layerscape/fsl_mc_dpmng_cmd_wrappers.h>
DECLARE_GLOBAL_DATA_PTR; static int mc_boot_status; @@ -14,7 +17,7 @@ static int mc_boot_status; * Copying MC firmware or DPL image to DDR */ static int mc_copy_image(const char *title, - u64 image_addr, u32 image_size, u64 mc_ram_addr) + u64 image_addr, u32 image_size, u64 mc_ram_addr) { debug("%s copied to address %p\n", title, (void *)mc_ram_addr); memcpy((void *)mc_ram_addr, (void *)image_addr, image_size); @@ -25,10 +28,9 @@ static int mc_copy_image(const char *title, * MC firmware FIT image parser checks if the image is in FIT * format, verifies integrity of the image and calculates * raw image address and size values. - * Returns 0 if success and 1 if any of the above mentioned + * Returns 0 on success and a negative errno on error. * task fail. **/ - int parse_mc_firmware_fit_image(const void **raw_image_addr, size_t *raw_image_size) { @@ -39,7 +41,7 @@ int parse_mc_firmware_fit_image(const void **raw_image_addr, size_t size; const char *uname = "firmware";
- /* Check if the image is in NOR flash*/ + /* Check if the image is in NOR flash */ #ifdef CONFIG_SYS_LS_MC_FW_IN_NOR fit_hdr = (void *)CONFIG_SYS_LS_MC_FW_ADDR; #else @@ -50,26 +52,26 @@ int parse_mc_firmware_fit_image(const void **raw_image_addr, format = genimg_get_format(fit_hdr);
if (format != IMAGE_FORMAT_FIT) { - debug("Not a FIT image\n"); - return 1; + printf("fsl-mc: ERROR: Bad firmware image (not a FIT image)\n"); + return -EINVAL; }
if (!fit_check_format(fit_hdr)) { - debug("Bad FIT image format\n"); - return 1; + printf("fsl-mc: ERROR: Bad firmware image (bad FIT header)\n"); + return -EINVAL; }
node_offset = fit_image_get_node(fit_hdr, uname);
if (node_offset < 0) { - debug("Can not find %s subimage\n", uname); - return 1; + printf("fsl-mc: ERROR: Bad firmware image (missing subimage)\n"); + return -ENOENT; }
/* Verify MC firmware image */ if (!(fit_image_verify(fit_hdr, node_offset))) { - debug("Bad MC firmware hash"); - return 1; + printf("fsl-mc: ERROR: Bad firmware image (bad CRC)\n"); + return -EINVAL; }
/* Get address and size of raw image */ @@ -90,12 +92,13 @@ int mc_init(bd_t *bis) u64 mc_dpl_offset; u32 reg_gsr; u32 mc_fw_boot_status; - void *fdt_hdr; + void *dpl_fdt_hdr; int dpl_size; const void *raw_image_addr; size_t raw_image_size = 0; - - BUILD_BUG_ON(CONFIG_SYS_LS_MC_FW_LENGTH % 4 != 0); + struct mc_portal_wrapper mc_portal_wrapper; + int portal_id; + struct mc_version mc_ver_info;
/* * The MC private DRAM block was already carved at the end of DRAM @@ -130,25 +133,44 @@ int mc_init(bd_t *bis) /* * Load the MC FW at the beginning of the MC private DRAM block: */ - mc_copy_image( - "MC Firmware", - (u64)raw_image_addr, - raw_image_size, - mc_ram_addr); + mc_copy_image("MC Firmware", + (u64)raw_image_addr, raw_image_size, mc_ram_addr); + + /* + * Get address and size of the DPL blob stored in flash: + */ +#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR + dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR; +#else +#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined" +#endif + + error = fdt_check_header(dpl_fdt_hdr); + if (error != 0) { + printf("fsl-mc: ERROR: Bad DPL image (bad header)\n"); + goto out; + } + + dpl_size = fdt_totalsize(dpl_fdt_hdr); + if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) { + printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n", + dpl_size); + error = -EINVAL; + goto out; + }
/* * Calculate offset in the MC private DRAM block at which the MC DPL * blob is to be placed: */ #ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET - BUILD_BUG_ON( - (CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 || - CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff); + BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 || + CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET; #else mc_dpl_offset = mc_get_dram_block_size() - - roundup(CONFIG_SYS_LS_MC_DPL_LENGTH, 4096); + roundup(CONFIG_SYS_LS_MC_DPL_MAX_LENGTH, 4096);
if ((mc_dpl_offset & 0x3) != 0 || mc_dpl_offset > 0xffffffff) { printf("%s: Invalid MC DPL offset: %llu\n", @@ -158,23 +180,14 @@ int mc_init(bd_t *bis) } #endif
- /* Check if DPL image is in NOR flash */ -#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR - fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR; -#else -#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined" -#endif - - dpl_size = fdt_totalsize(fdt_hdr); - /* * Load the MC DPL blob at the far end of the MC private DRAM block: + * + * TODO: Should we place the DPL at a different location to match + * assumptions of MC firmware about its memory layout? */ - mc_copy_image( - "MC DPL blob", - (u64)fdt_hdr, - dpl_size, - mc_ram_addr + mc_dpl_offset); + mc_copy_image("MC DPL blob", + (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset);
debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
@@ -200,6 +213,8 @@ int mc_init(bd_t *bis) */ out_le32(&mc_ccsr_regs->reg_gsr, (u32)(mc_dpl_offset >> 2));
+ printf("\nfsl-mc: Booting Management Complex ...\n"); + /* * Deassert reset and release MC core 0 to run */ @@ -219,17 +234,13 @@ int mc_init(bd_t *bis) }
if (timeout <= 0) { - printf("%s: timeout booting management complex firmware\n", - __func__); + printf("fsl-mc: timeout booting management complex firmware\n");
/* TODO: Get an error status from an MC CCSR register */ error = -ETIMEDOUT; goto out; }
- printf("Management complex booted (boot status: %#x)\n", - mc_fw_boot_status); - if (mc_fw_boot_status != 0x1) { /* * TODO: Identify critical errors from the GSR register's FS @@ -237,8 +248,41 @@ int mc_init(bd_t *bis) * appropriate errno, so that the status property is set to * failure in the fsl,dprc device tree node. */ + printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n", + reg_gsr); }
+ /* + * TODO: need to obtain the portal_id for the root container from the + * DPL + */ + portal_id = 0; + + /* + * Check that the MC firmware is responding portal commands: + */ + mc_portal_wrapper.mmio_regs = SOC_MC_PORTAL_ADDR(portal_id); + debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n", + portal_id, mc_portal_wrapper.mmio_regs); + + error = mc_get_version(&mc_portal_wrapper, &mc_ver_info); + if (error != 0) { + printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n", + error); + goto out; + } + + if (MC_VER_MAJOR != mc_ver_info.major) + printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n", + mc_ver_info.major, MC_VER_MAJOR); + + if (MC_VER_MINOR != mc_ver_info.minor) + printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n", + mc_ver_info.minor, MC_VER_MINOR); + + printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n", + mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision, + mc_fw_boot_status); out: if (error != 0) mc_boot_status = -error; diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 2bd5a47..04ae519 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -138,7 +138,7 @@ #define CONFIG_SYS_LS_MC_DPL_IN_NOR #define CONFIG_SYS_LS_MC_DPL_ADDR 0x5806C0000ULL /* TODO Actual DPL max length needs to be confirmed with the MC FW team */ -#define CONFIG_SYS_LS_MC_DPL_LENGTH 4096 +#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH (256 * 1024) #define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0xe00000
/* Carve the MC private DRAM block from the end of DRAM */

On Fri, Aug 1, 2014 at 12:13 AM, Lijun Pan Lijun.Pan@freescale.com wrote:
After the MC is booted, u-boot should print out the Management Complex version info where appropriate. Also, clean up the code to make checkpatch.pl happy.
Signed-off-by: Lijun Pan Lijun.Pan@freescale.com Signed-off-by: J. German Rivera German.Rivera@freescale.com
Couldn't this be squashed into 1/3? This seems an extension to it which could be add in the iitial patch.
participants (2)
-
Lijun Pan
-
Otavio Salvador