Commit 7b3bd9a7988a8b4c8ba22a52b4927e8e59819b12

Authored by J. German Rivera
Committed by York Sun
1 parent 4f2532c4a4

drivers/mc: Migrated MC Flibs to 0.5.2

Upgrade Manage Complex (MC) flib API to 0.5.2. Rename directory
fsl_mc to fsl-mc. Change the fsl-mc node in Linux device tree
from "fsl,dprcr" to "fsl-mc". Print MC version info when
appropriate.

Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
Signed-off-by: Lijun Pan <Lijun.Pan@freescale.com>
Reviewed-by: York Sun <yorksun@freescale.com>

Showing 16 changed files with 880 additions and 340 deletions Side-by-side Diff

arch/arm/cpu/armv8/fsl-lsch3/cpu.c
... ... @@ -10,10 +10,10 @@
10 10 #include <asm/armv8/mmu.h>
11 11 #include <asm/io.h>
12 12 #include <asm/arch-fsl-lsch3/immap_lsch3.h>
  13 +#include <fsl-mc/fsl_mc.h>
13 14 #include "cpu.h"
14 15 #include "mp.h"
15 16 #include "speed.h"
16   -#include <fsl_mc.h>
17 17  
18 18 DECLARE_GLOBAL_DATA_PTR;
19 19  
board/freescale/ls2085a/ls2085a.c
... ... @@ -12,7 +12,7 @@
12 12 #include <asm/io.h>
13 13 #include <fdt_support.h>
14 14 #include <libfdt.h>
15   -#include <fsl_mc.h>
  15 +#include <fsl-mc/fsl_mc.h>
16 16 #include <environment.h>
17 17  
18 18 DECLARE_GLOBAL_DATA_PTR;
... ... @@ -98,7 +98,21 @@
98 98 {
99 99 int offset;
100 100  
101   - offset = fdt_path_offset(fdt, "/fsl,dprc@0");
  101 + offset = fdt_path_offset(fdt, "/fsl-mc");
  102 +
  103 + /*
  104 + * TODO: Remove this when backward compatibility
  105 + * with old DT node (fsl,dprc@0) is no longer needed.
  106 + */
  107 + if (offset < 0)
  108 + offset = fdt_path_offset(fdt, "/fsl,dprc@0");
  109 +
  110 + if (offset < 0) {
  111 + printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n",
  112 + __func__, offset);
  113 + return;
  114 + }
  115 +
102 116 if (get_mc_boot_status() == 0)
103 117 fdt_status_okay(fdt, offset);
104 118 else
drivers/net/Makefile
... ... @@ -65,6 +65,6 @@
65 65 obj-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \
66 66 xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o
67 67 obj-$(CONFIG_ZYNQ_GEM) += zynq_gem.o
68   -obj-$(CONFIG_FSL_MC_ENET) += fsl_mc/
  68 +obj-$(CONFIG_FSL_MC_ENET) += fsl-mc/
69 69 obj-$(CONFIG_VSC9953) += vsc9953.o
drivers/net/fsl-mc/Makefile
  1 +#
  2 +# Copyright 2014 Freescale Semiconductor, Inc.
  3 +#
  4 +# SPDX-License-Identifier: GPL-2.0+
  5 +#
  6 +
  7 +# Layerscape MC driver
  8 +obj-y += mc.o \
  9 + mc_sys.o \
  10 + dpmng.o
drivers/net/fsl-mc/dpmng.c
  1 +/* Copyright 2014 Freescale Semiconductor Inc.
  2 + *
  3 + * SPDX-License-Identifier: GPL-2.0+
  4 + */
  5 +#include <fsl-mc/fsl_mc_sys.h>
  6 +#include <fsl-mc/fsl_mc_cmd.h>
  7 +#include <fsl-mc/fsl_dpmng.h>
  8 +#include "fsl_dpmng_cmd.h"
  9 +
  10 +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
  11 +{
  12 + struct mc_command cmd = { 0 };
  13 + int err;
  14 +
  15 + /* prepare command */
  16 + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION,
  17 + MC_CMD_PRI_LOW, 0);
  18 +
  19 + /* send command to mc*/
  20 + err = mc_send_command(mc_io, &cmd);
  21 + if (err)
  22 + return err;
  23 +
  24 + /* retrieve response parameters */
  25 + DPMNG_RSP_GET_VERSION(cmd, mc_ver_info);
  26 +
  27 + return 0;
  28 +}
  29 +
  30 +int dpmng_reset_aiop(struct fsl_mc_io *mc_io, int container_id,
  31 + int aiop_tile_id)
  32 +{
  33 + struct mc_command cmd = { 0 };
  34 +
  35 + /* prepare command */
  36 + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_AIOP,
  37 + MC_CMD_PRI_LOW, 0);
  38 + DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id);
  39 +
  40 + /* send command to mc*/
  41 + return mc_send_command(mc_io, &cmd);
  42 +}
  43 +
  44 +int dpmng_load_aiop(struct fsl_mc_io *mc_io,
  45 + int container_id,
  46 + int aiop_tile_id,
  47 + uint64_t img_iova,
  48 + uint32_t img_size)
  49 +{
  50 + struct mc_command cmd = { 0 };
  51 +
  52 + /* prepare command */
  53 + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_LOAD_AIOP,
  54 + MC_CMD_PRI_LOW,
  55 + 0);
  56 + DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size,
  57 + img_iova);
  58 +
  59 + /* send command to mc*/
  60 + return mc_send_command(mc_io, &cmd);
  61 +}
  62 +
  63 +int dpmng_run_aiop(struct fsl_mc_io *mc_io,
  64 + int container_id,
  65 + int aiop_tile_id,
  66 + const struct dpmng_aiop_run_cfg *cfg)
  67 +{
  68 + struct mc_command cmd = { 0 };
  69 +
  70 + /* prepare command */
  71 + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RUN_AIOP,
  72 + MC_CMD_PRI_LOW,
  73 + 0);
  74 + DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg);
  75 +
  76 + /* send command to mc*/
  77 + return mc_send_command(mc_io, &cmd);
  78 +}
  79 +
  80 +int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io)
  81 +{
  82 + struct mc_command cmd = { 0 };
  83 +
  84 + /* prepare command */
  85 + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_MC_PORTAL,
  86 + MC_CMD_PRI_LOW,
  87 + 0);
  88 +
  89 + /* send command to mc*/
  90 + return mc_send_command(mc_io, &cmd);
  91 +}
drivers/net/fsl-mc/fsl_dpmng_cmd.h
  1 +/* Copyright 2014 Freescale Semiconductor Inc.
  2 + *
  3 + * SPDX-License-Identifier: GPL-2.0+
  4 + */
  5 +#ifndef __FSL_DPMNG_CMD_H
  6 +#define __FSL_DPMNG_CMD_H
  7 +
  8 +/* Command IDs */
  9 +#define DPMNG_CMDID_GET_VERSION 0x831
  10 +#define DPMNG_CMDID_RESET_AIOP 0x832
  11 +#define DPMNG_CMDID_LOAD_AIOP 0x833
  12 +#define DPMNG_CMDID_RUN_AIOP 0x834
  13 +#define DPMNG_CMDID_RESET_MC_PORTAL 0x835
  14 +
  15 +/* cmd, param, offset, width, type, arg_name */
  16 +#define DPMNG_RSP_GET_VERSION(cmd, mc_ver_info) \
  17 +do { \
  18 + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mc_ver_info->revision); \
  19 + MC_RSP_OP(cmd, 0, 32, 32, uint32_t, mc_ver_info->major); \
  20 + MC_RSP_OP(cmd, 1, 0, 32, uint32_t, mc_ver_info->minor); \
  21 +} while (0)
  22 +
  23 +/* cmd, param, offset, width, type, arg_name */
  24 +#define DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id) \
  25 +do { \
  26 + MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
  27 + MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
  28 +} while (0)
  29 +
  30 +/* cmd, param, offset, width, type, arg_name */
  31 +#define DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size, \
  32 + img_iova) \
  33 +do { \
  34 + MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
  35 + MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
  36 + MC_CMD_OP(cmd, 1, 0, 32, uint32_t, img_size); \
  37 + MC_CMD_OP(cmd, 2, 0, 64, uint64_t, img_iova); \
  38 +} while (0)
  39 +
  40 +/* cmd, param, offset, width, type, arg_name */
  41 +#define DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg) \
  42 +do { \
  43 + MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
  44 + MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
  45 + MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->cores_mask); \
  46 + MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options); \
  47 +} while (0)
  48 +
  49 +#endif /* __FSL_DPMNG_CMD_H */
drivers/net/fsl-mc/mc.c
  1 +/*
  2 + * Copyright (C) 2014 Freescale Semiconductor
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + */
  6 +
  7 +#include <errno.h>
  8 +#include <asm/io.h>
  9 +#include <fsl-mc/fsl_mc.h>
  10 +#include <fsl-mc/fsl_mc_sys.h>
  11 +#include <fsl-mc/fsl_dpmng.h>
  12 +
  13 +DECLARE_GLOBAL_DATA_PTR;
  14 +static int mc_boot_status;
  15 +
  16 +/**
  17 + * Copying MC firmware or DPL image to DDR
  18 + */
  19 +static int mc_copy_image(const char *title,
  20 + u64 image_addr, u32 image_size, u64 mc_ram_addr)
  21 +{
  22 + debug("%s copied to address %p\n", title, (void *)mc_ram_addr);
  23 + memcpy((void *)mc_ram_addr, (void *)image_addr, image_size);
  24 + return 0;
  25 +}
  26 +
  27 +/**
  28 + * MC firmware FIT image parser checks if the image is in FIT
  29 + * format, verifies integrity of the image and calculates
  30 + * raw image address and size values.
  31 + * Returns 0 on success and a negative errno on error.
  32 + * task fail.
  33 + **/
  34 +int parse_mc_firmware_fit_image(const void **raw_image_addr,
  35 + size_t *raw_image_size)
  36 +{
  37 + int format;
  38 + void *fit_hdr;
  39 + int node_offset;
  40 + const void *data;
  41 + size_t size;
  42 + const char *uname = "firmware";
  43 +
  44 + /* Check if the image is in NOR flash */
  45 +#ifdef CONFIG_SYS_LS_MC_FW_IN_NOR
  46 + fit_hdr = (void *)CONFIG_SYS_LS_MC_FW_ADDR;
  47 +#else
  48 +#error "No CONFIG_SYS_LS_MC_FW_IN_xxx defined"
  49 +#endif
  50 +
  51 + /* Check if Image is in FIT format */
  52 + format = genimg_get_format(fit_hdr);
  53 +
  54 + if (format != IMAGE_FORMAT_FIT) {
  55 + printf("fsl-mc: ERROR: Bad firmware image (not a FIT image)\n");
  56 + return -EINVAL;
  57 + }
  58 +
  59 + if (!fit_check_format(fit_hdr)) {
  60 + printf("fsl-mc: ERROR: Bad firmware image (bad FIT header)\n");
  61 + return -EINVAL;
  62 + }
  63 +
  64 + node_offset = fit_image_get_node(fit_hdr, uname);
  65 +
  66 + if (node_offset < 0) {
  67 + printf("fsl-mc: ERROR: Bad firmware image (missing subimage)\n");
  68 + return -ENOENT;
  69 + }
  70 +
  71 + /* Verify MC firmware image */
  72 + if (!(fit_image_verify(fit_hdr, node_offset))) {
  73 + printf("fsl-mc: ERROR: Bad firmware image (bad CRC)\n");
  74 + return -EINVAL;
  75 + }
  76 +
  77 + /* Get address and size of raw image */
  78 + fit_image_get_data(fit_hdr, node_offset, &data, &size);
  79 +
  80 + *raw_image_addr = data;
  81 + *raw_image_size = size;
  82 +
  83 + return 0;
  84 +}
  85 +
  86 +int mc_init(bd_t *bis)
  87 +{
  88 + int error = 0;
  89 + int timeout = 200000;
  90 + struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
  91 + u64 mc_ram_addr;
  92 + u64 mc_dpl_offset;
  93 + u32 reg_gsr;
  94 + u32 mc_fw_boot_status;
  95 + void *dpl_fdt_hdr;
  96 + int dpl_size;
  97 + const void *raw_image_addr;
  98 + size_t raw_image_size = 0;
  99 + struct fsl_mc_io mc_io;
  100 + int portal_id;
  101 + struct mc_version mc_ver_info;
  102 +
  103 + /*
  104 + * The MC private DRAM block was already carved at the end of DRAM
  105 + * by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE:
  106 + */
  107 + if (gd->bd->bi_dram[1].start) {
  108 + mc_ram_addr =
  109 + gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size;
  110 + } else {
  111 + mc_ram_addr =
  112 + gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
  113 + }
  114 +
  115 + /*
  116 + * Management Complex cores should be held at reset out of POR.
  117 + * U-boot should be the first software to touch MC. To be safe,
  118 + * we reset all cores again by setting GCR1 to 0. It doesn't do
  119 + * anything if they are held at reset. After we setup the firmware
  120 + * we kick off MC by deasserting the reset bit for core 0, and
  121 + * deasserting the reset bits for Command Portal Managers.
  122 + * The stop bits are not touched here. They are used to stop the
  123 + * cores when they are active. Setting stop bits doesn't stop the
  124 + * cores from fetching instructions when they are released from
  125 + * reset.
  126 + */
  127 + out_le32(&mc_ccsr_regs->reg_gcr1, 0);
  128 + dmb();
  129 +
  130 + error = parse_mc_firmware_fit_image(&raw_image_addr, &raw_image_size);
  131 + if (error != 0)
  132 + goto out;
  133 + /*
  134 + * Load the MC FW at the beginning of the MC private DRAM block:
  135 + */
  136 + mc_copy_image("MC Firmware",
  137 + (u64)raw_image_addr, raw_image_size, mc_ram_addr);
  138 +
  139 + /*
  140 + * Get address and size of the DPL blob stored in flash:
  141 + */
  142 +#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR
  143 + dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR;
  144 +#else
  145 +#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined"
  146 +#endif
  147 +
  148 + error = fdt_check_header(dpl_fdt_hdr);
  149 + if (error != 0) {
  150 + printf("fsl-mc: ERROR: Bad DPL image (bad header)\n");
  151 + goto out;
  152 + }
  153 +
  154 + dpl_size = fdt_totalsize(dpl_fdt_hdr);
  155 + if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) {
  156 + printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n",
  157 + dpl_size);
  158 + error = -EINVAL;
  159 + goto out;
  160 + }
  161 +
  162 + /*
  163 + * Calculate offset in the MC private DRAM block at which the MC DPL
  164 + * blob is to be placed:
  165 + */
  166 +#ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET
  167 + BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
  168 + CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
  169 +
  170 + mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET;
  171 +#else
  172 + mc_dpl_offset = mc_get_dram_block_size() -
  173 + roundup(CONFIG_SYS_LS_MC_DPL_MAX_LENGTH, 4096);
  174 +
  175 + if ((mc_dpl_offset & 0x3) != 0 || mc_dpl_offset > 0xffffffff) {
  176 + printf("%s: Invalid MC DPL offset: %llu\n",
  177 + __func__, mc_dpl_offset);
  178 + error = -EINVAL;
  179 + goto out;
  180 + }
  181 +#endif
  182 +
  183 + /*
  184 + * Load the MC DPL blob at the far end of the MC private DRAM block:
  185 + *
  186 + * TODO: Should we place the DPL at a different location to match
  187 + * assumptions of MC firmware about its memory layout?
  188 + */
  189 + mc_copy_image("MC DPL blob",
  190 + (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset);
  191 +
  192 + debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
  193 +
  194 + /*
  195 + * Tell MC where the MC Firmware image was loaded in DDR:
  196 + */
  197 + out_le32(&mc_ccsr_regs->reg_mcfbalr, (u32)mc_ram_addr);
  198 + out_le32(&mc_ccsr_regs->reg_mcfbahr, (u32)((u64)mc_ram_addr >> 32));
  199 + out_le32(&mc_ccsr_regs->reg_mcfapr, MCFAPR_BYPASS_ICID_MASK);
  200 +
  201 + /*
  202 + * Tell MC where the DPL blob was loaded in DDR, by indicating
  203 + * its offset relative to the beginning of the DDR block
  204 + * allocated to the MC firmware. The MC firmware is responsible
  205 + * for checking that there is no overlap between the DPL blob
  206 + * and the runtime heap and stack of the MC firmware itself.
  207 + *
  208 + * NOTE: bits [31:2] of this offset need to be stored in bits [29:0] of
  209 + * the GSR MC CCSR register. So, this offset is assumed to be 4-byte
  210 + * aligned.
  211 + * Care must be taken not to write 1s into bits 31 and 30 of the GSR in
  212 + * this case as the SoC COP or PIC will be signaled.
  213 + */
  214 + out_le32(&mc_ccsr_regs->reg_gsr, (u32)(mc_dpl_offset >> 2));
  215 +
  216 + printf("\nfsl-mc: Booting Management Complex ...\n");
  217 +
  218 + /*
  219 + * Deassert reset and release MC core 0 to run
  220 + */
  221 + out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST);
  222 + dmb();
  223 + debug("Polling mc_ccsr_regs->reg_gsr ...\n");
  224 +
  225 + for (;;) {
  226 + reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr);
  227 + mc_fw_boot_status = (reg_gsr & GSR_FS_MASK);
  228 + if (mc_fw_boot_status & 0x1)
  229 + break;
  230 +
  231 + udelay(1000); /* throttle polling */
  232 + if (timeout-- <= 0)
  233 + break;
  234 + }
  235 +
  236 + if (timeout <= 0) {
  237 + printf("fsl-mc: timeout booting management complex firmware\n");
  238 +
  239 + /* TODO: Get an error status from an MC CCSR register */
  240 + error = -ETIMEDOUT;
  241 + goto out;
  242 + }
  243 +
  244 + if (mc_fw_boot_status != 0x1) {
  245 + /*
  246 + * TODO: Identify critical errors from the GSR register's FS
  247 + * field and for those errors, set error to -ENODEV or other
  248 + * appropriate errno, so that the status property is set to
  249 + * failure in the fsl,dprc device tree node.
  250 + */
  251 + printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n",
  252 + reg_gsr);
  253 + }
  254 +
  255 + /*
  256 + * TODO: need to obtain the portal_id for the root container from the
  257 + * DPL
  258 + */
  259 + portal_id = 0;
  260 +
  261 + /*
  262 + * Check that the MC firmware is responding portal commands:
  263 + */
  264 + mc_io.mmio_regs = SOC_MC_PORTAL_ADDR(portal_id);
  265 + debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n",
  266 + portal_id, mc_io.mmio_regs);
  267 +
  268 + error = mc_get_version(&mc_io, &mc_ver_info);
  269 + if (error != 0) {
  270 + printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n",
  271 + error);
  272 + goto out;
  273 + }
  274 +
  275 + if (MC_VER_MAJOR != mc_ver_info.major)
  276 + printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n",
  277 + mc_ver_info.major, MC_VER_MAJOR);
  278 +
  279 + if (MC_VER_MINOR != mc_ver_info.minor)
  280 + printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n",
  281 + mc_ver_info.minor, MC_VER_MINOR);
  282 +
  283 + printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n",
  284 + mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision,
  285 + mc_fw_boot_status);
  286 +out:
  287 + if (error != 0)
  288 + mc_boot_status = -error;
  289 + else
  290 + mc_boot_status = 0;
  291 +
  292 + return error;
  293 +}
  294 +
  295 +int get_mc_boot_status(void)
  296 +{
  297 + return mc_boot_status;
  298 +}
  299 +
  300 +/**
  301 + * Return the actual size of the MC private DRAM block.
  302 + *
  303 + * NOTE: For now this function always returns the minimum required size,
  304 + * However, in the future, the actual size may be obtained from an environment
  305 + * variable.
  306 + */
  307 +unsigned long mc_get_dram_block_size(void)
  308 +{
  309 + return CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
  310 +}
drivers/net/fsl-mc/mc_sys.c
  1 +/*
  2 + * Freescale Layerscape MC I/O wrapper
  3 + *
  4 + * Copyright (C) 2014 Freescale Semiconductor, Inc.
  5 + * Author: German Rivera <German.Rivera@freescale.com>
  6 + *
  7 + * SPDX-License-Identifier: GPL-2.0+
  8 + */
  9 +
  10 +#include <fsl-mc/fsl_mc_sys.h>
  11 +#include <fsl-mc/fsl_mc_cmd.h>
  12 +#include <common.h>
  13 +#include <errno.h>
  14 +#include <asm/io.h>
  15 +
  16 +#define MC_CMD_HDR_READ_CMDID(_hdr) \
  17 + ((uint16_t)u64_dec((_hdr), MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S))
  18 +
  19 +/**
  20 + * mc_send_command - Send MC command and wait for response
  21 + *
  22 + * @mc_io: Pointer to MC I/O object to be used
  23 + * @cmd: MC command buffer. On input, it contains the command to send to the MC.
  24 + * On output, it contains the response from the MC if any.
  25 + *
  26 + * Depending on the sharing option specified when creating the MC portal
  27 + * wrapper, this function will use a spinlock or mutex to ensure exclusive
  28 + * access to the MC portal from the point when the command is sent until a
  29 + * response is received from the MC.
  30 + */
  31 +int mc_send_command(struct fsl_mc_io *mc_io,
  32 + struct mc_command *cmd)
  33 +{
  34 + enum mc_cmd_status status;
  35 + int timeout = 2000;
  36 +
  37 + mc_write_command(mc_io->mmio_regs, cmd);
  38 +
  39 + for ( ; ; ) {
  40 + status = mc_read_response(mc_io->mmio_regs, cmd);
  41 + if (status != MC_CMD_STATUS_READY)
  42 + break;
  43 +
  44 + if (--timeout == 0) {
  45 + printf("Error: Timeout waiting for MC response\n");
  46 + return -ETIMEDOUT;
  47 + }
  48 +
  49 + udelay(500);
  50 + }
  51 +
  52 + if (status != MC_CMD_STATUS_OK) {
  53 + printf("Error: MC command failed (portal: %p, obj handle: %#x, command: %#x, status: %#x)\n",
  54 + mc_io->mmio_regs,
  55 + (unsigned int)MC_CMD_HDR_READ_AUTHID(cmd->header),
  56 + (unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header),
  57 + (unsigned int)status);
  58 +
  59 + return -EIO;
  60 + }
  61 +
  62 + return 0;
  63 +}
drivers/net/fsl_mc/Makefile
1   -#
2   -# Copyright 2014 Freescale Semiconductor, Inc.
3   -#
4   -# SPDX-License-Identifier: GPL-2.0+
5   -#
6   -
7   -# Layerscape MC driver
8   -obj-y += mc.o
drivers/net/fsl_mc/mc.c
1   -/*
2   - * Copyright (C) 2014 Freescale Semiconductor
3   - *
4   - * SPDX-License-Identifier: GPL-2.0+
5   - */
6   -#include <errno.h>
7   -#include <asm/io.h>
8   -#include <fsl_mc.h>
9   -
10   -DECLARE_GLOBAL_DATA_PTR;
11   -static int mc_boot_status;
12   -
13   -/**
14   - * Copying MC firmware or DPL image to DDR
15   - */
16   -static int mc_copy_image(const char *title,
17   - u64 image_addr, u32 image_size, u64 mc_ram_addr)
18   -{
19   - debug("%s copied to address %p\n", title, (void *)mc_ram_addr);
20   - memcpy((void *)mc_ram_addr, (void *)image_addr, image_size);
21   - return 0;
22   -}
23   -
24   -/**
25   - * MC firmware FIT image parser checks if the image is in FIT
26   - * format, verifies integrity of the image and calculates
27   - * raw image address and size values.
28   - * Returns 0 if success and 1 if any of the above mentioned
29   - * task fail.
30   - **/
31   -
32   -int parse_mc_firmware_fit_image(const void **raw_image_addr,
33   - size_t *raw_image_size)
34   -{
35   - int format;
36   - void *fit_hdr;
37   - int node_offset;
38   - const void *data;
39   - size_t size;
40   - const char *uname = "firmware";
41   -
42   - /* Check if the image is in NOR flash*/
43   -#ifdef CONFIG_SYS_LS_MC_FW_IN_NOR
44   - fit_hdr = (void *)CONFIG_SYS_LS_MC_FW_ADDR;
45   -#else
46   -#error "No CONFIG_SYS_LS_MC_FW_IN_xxx defined"
47   -#endif
48   -
49   - /* Check if Image is in FIT format */
50   - format = genimg_get_format(fit_hdr);
51   -
52   - if (format != IMAGE_FORMAT_FIT) {
53   - debug("Not a FIT image\n");
54   - return 1;
55   - }
56   -
57   - if (!fit_check_format(fit_hdr)) {
58   - debug("Bad FIT image format\n");
59   - return 1;
60   - }
61   -
62   - node_offset = fit_image_get_node(fit_hdr, uname);
63   -
64   - if (node_offset < 0) {
65   - debug("Can not find %s subimage\n", uname);
66   - return 1;
67   - }
68   -
69   - /* Verify MC firmware image */
70   - if (!(fit_image_verify(fit_hdr, node_offset))) {
71   - debug("Bad MC firmware hash");
72   - return 1;
73   - }
74   -
75   - /* Get address and size of raw image */
76   - fit_image_get_data(fit_hdr, node_offset, &data, &size);
77   -
78   - *raw_image_addr = data;
79   - *raw_image_size = size;
80   -
81   - return 0;
82   -}
83   -
84   -int mc_init(bd_t *bis)
85   -{
86   - int error = 0;
87   - int timeout = 200000;
88   - struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
89   - u64 mc_ram_addr;
90   - u64 mc_dpl_offset;
91   - u32 reg_gsr;
92   - u32 mc_fw_boot_status;
93   - void *fdt_hdr;
94   - int dpl_size;
95   - const void *raw_image_addr;
96   - size_t raw_image_size = 0;
97   -
98   - BUILD_BUG_ON(CONFIG_SYS_LS_MC_FW_LENGTH % 4 != 0);
99   -
100   - /*
101   - * The MC private DRAM block was already carved at the end of DRAM
102   - * by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE:
103   - */
104   - if (gd->bd->bi_dram[1].start) {
105   - mc_ram_addr =
106   - gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size;
107   - } else {
108   - mc_ram_addr =
109   - gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
110   - }
111   -
112   - /*
113   - * Management Complex cores should be held at reset out of POR.
114   - * U-boot should be the first software to touch MC. To be safe,
115   - * we reset all cores again by setting GCR1 to 0. It doesn't do
116   - * anything if they are held at reset. After we setup the firmware
117   - * we kick off MC by deasserting the reset bit for core 0, and
118   - * deasserting the reset bits for Command Portal Managers.
119   - * The stop bits are not touched here. They are used to stop the
120   - * cores when they are active. Setting stop bits doesn't stop the
121   - * cores from fetching instructions when they are released from
122   - * reset.
123   - */
124   - out_le32(&mc_ccsr_regs->reg_gcr1, 0);
125   - dmb();
126   -
127   - error = parse_mc_firmware_fit_image(&raw_image_addr, &raw_image_size);
128   - if (error != 0)
129   - goto out;
130   - /*
131   - * Load the MC FW at the beginning of the MC private DRAM block:
132   - */
133   - mc_copy_image(
134   - "MC Firmware",
135   - (u64)raw_image_addr,
136   - raw_image_size,
137   - mc_ram_addr);
138   -
139   - /*
140   - * Calculate offset in the MC private DRAM block at which the MC DPL
141   - * blob is to be placed:
142   - */
143   -#ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET
144   - BUILD_BUG_ON(
145   - (CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
146   - CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
147   -
148   - mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET;
149   -#else
150   - mc_dpl_offset = mc_get_dram_block_size() -
151   - roundup(CONFIG_SYS_LS_MC_DPL_LENGTH, 4096);
152   -
153   - if ((mc_dpl_offset & 0x3) != 0 || mc_dpl_offset > 0xffffffff) {
154   - printf("%s: Invalid MC DPL offset: %llu\n",
155   - __func__, mc_dpl_offset);
156   - error = -EINVAL;
157   - goto out;
158   - }
159   -#endif
160   -
161   - /* Check if DPL image is in NOR flash */
162   -#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR
163   - fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR;
164   -#else
165   -#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined"
166   -#endif
167   -
168   - dpl_size = fdt_totalsize(fdt_hdr);
169   -
170   - /*
171   - * Load the MC DPL blob at the far end of the MC private DRAM block:
172   - */
173   - mc_copy_image(
174   - "MC DPL blob",
175   - (u64)fdt_hdr,
176   - dpl_size,
177   - mc_ram_addr + mc_dpl_offset);
178   -
179   - debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
180   -
181   - /*
182   - * Tell MC where the MC Firmware image was loaded in DDR:
183   - */
184   - out_le32(&mc_ccsr_regs->reg_mcfbalr, (u32)mc_ram_addr);
185   - out_le32(&mc_ccsr_regs->reg_mcfbahr, (u32)((u64)mc_ram_addr >> 32));
186   - out_le32(&mc_ccsr_regs->reg_mcfapr, MCFAPR_BYPASS_ICID_MASK);
187   -
188   - /*
189   - * Tell MC where the DPL blob was loaded in DDR, by indicating
190   - * its offset relative to the beginning of the DDR block
191   - * allocated to the MC firmware. The MC firmware is responsible
192   - * for checking that there is no overlap between the DPL blob
193   - * and the runtime heap and stack of the MC firmware itself.
194   - *
195   - * NOTE: bits [31:2] of this offset need to be stored in bits [29:0] of
196   - * the GSR MC CCSR register. So, this offset is assumed to be 4-byte
197   - * aligned.
198   - * Care must be taken not to write 1s into bits 31 and 30 of the GSR in
199   - * this case as the SoC COP or PIC will be signaled.
200   - */
201   - out_le32(&mc_ccsr_regs->reg_gsr, (u32)(mc_dpl_offset >> 2));
202   -
203   - /*
204   - * Deassert reset and release MC core 0 to run
205   - */
206   - out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST);
207   - dmb();
208   - debug("Polling mc_ccsr_regs->reg_gsr ...\n");
209   -
210   - for (;;) {
211   - reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr);
212   - mc_fw_boot_status = (reg_gsr & GSR_FS_MASK);
213   - if (mc_fw_boot_status & 0x1)
214   - break;
215   -
216   - udelay(1000); /* throttle polling */
217   - if (timeout-- <= 0)
218   - break;
219   - }
220   -
221   - if (timeout <= 0) {
222   - printf("%s: timeout booting management complex firmware\n",
223   - __func__);
224   -
225   - /* TODO: Get an error status from an MC CCSR register */
226   - error = -ETIMEDOUT;
227   - goto out;
228   - }
229   -
230   - printf("Management complex booted (boot status: %#x)\n",
231   - mc_fw_boot_status);
232   -
233   - if (mc_fw_boot_status != 0x1) {
234   - /*
235   - * TODO: Identify critical errors from the GSR register's FS
236   - * field and for those errors, set error to -ENODEV or other
237   - * appropriate errno, so that the status property is set to
238   - * failure in the fsl,dprc device tree node.
239   - */
240   - }
241   -
242   -out:
243   - if (error != 0)
244   - mc_boot_status = -error;
245   - else
246   - mc_boot_status = 0;
247   -
248   - return error;
249   -}
250   -
251   -int get_mc_boot_status(void)
252   -{
253   - return mc_boot_status;
254   -}
255   -
256   -/**
257   - * Return the actual size of the MC private DRAM block.
258   - *
259   - * NOTE: For now this function always returns the minimum required size,
260   - * However, in the future, the actual size may be obtained from an environment
261   - * variable.
262   - */
263   -unsigned long mc_get_dram_block_size(void)
264   -{
265   - return CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
266   -}
include/configs/ls2085a_common.h
... ... @@ -207,12 +207,10 @@
207 207 #define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024)
208 208 #define CONFIG_SYS_LS_MC_FW_IN_NOR
209 209 #define CONFIG_SYS_LS_MC_FW_ADDR 0x580200000ULL
210   -/* TODO Actual FW length needs to be determined at runtime from FW header */
211   -#define CONFIG_SYS_LS_MC_FW_LENGTH (4U * 1024 * 1024)
212 210 #define CONFIG_SYS_LS_MC_DPL_IN_NOR
213 211 #define CONFIG_SYS_LS_MC_DPL_ADDR 0x5806C0000ULL
214 212 /* TODO Actual DPL max length needs to be confirmed with the MC FW team */
215   -#define CONFIG_SYS_LS_MC_DPL_LENGTH 4096
  213 +#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH (256 * 1024)
216 214 #define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0xe00000
217 215  
218 216 /* Carve the MC private DRAM block from the end of DRAM */
include/fsl-mc/fsl_dpmng.h
  1 +/* Copyright 2014 Freescale Semiconductor Inc.
  2 + *
  3 + * SPDX-License-Identifier: GPL-2.0+
  4 + */
  5 +/*!
  6 + * @file fsl_dpmng.h
  7 + * @brief Management Complex General API
  8 + */
  9 +
  10 +#ifndef __FSL_DPMNG_H
  11 +#define __FSL_DPMNG_H
  12 +
  13 +/*!
  14 + * @Group grp_dpmng Management Complex General API
  15 + *
  16 + * @brief Contains general API for the Management Complex firmware
  17 + * @{
  18 + */
  19 +
  20 +struct fsl_mc_io;
  21 +
  22 +/**
  23 + * @brief Management Complex firmware version information
  24 + */
  25 +#define MC_VER_MAJOR 4
  26 +#define MC_VER_MINOR 0
  27 +
  28 +struct mc_version {
  29 + uint32_t major;
  30 + /*!< Major version number: incremented on API compatibility changes */
  31 + uint32_t minor;
  32 + /*!< Minor version number: incremented on API additions (that are
  33 + * backward compatible); reset when major version is incremented
  34 + */
  35 + uint32_t revision;
  36 + /*!< Internal revision number: incremented on implementation changes
  37 + * and/or bug fixes that have no impact on API
  38 + */
  39 +};
  40 +
  41 +/**
  42 + * @brief Retrieves the Management Complex firmware version information
  43 + *
  44 + * @param[in] mc_io Pointer to opaque I/O object
  45 + * @param[out] mc_ver_info Pointer to version information structure
  46 + *
  47 + * @returns '0' on Success; Error code otherwise.
  48 + */
  49 +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info);
  50 +
  51 +/**
  52 + * @brief Resets an AIOP tile
  53 + *
  54 + * @param[in] mc_io Pointer to opaque I/O object
  55 + * @param[in] container_id AIOP container ID
  56 + * @param[in] aiop_tile_id AIOP tile ID to reset
  57 + *
  58 + * @returns '0' on Success; Error code otherwise.
  59 + */
  60 +int dpmng_reset_aiop(struct fsl_mc_io *mc_io,
  61 + int container_id,
  62 + int aiop_tile_id);
  63 +
  64 +/**
  65 + * @brief Loads an image to AIOP tile
  66 + *
  67 + * @param[in] mc_io Pointer to opaque I/O object
  68 + * @param[in] container_id AIOP container ID
  69 + * @param[in] aiop_tile_id AIOP tile ID to reset
  70 + * @param[in] img_iova I/O virtual address of AIOP ELF image
  71 + * @param[in] img_size Size of AIOP ELF image in memory (in bytes)
  72 + *
  73 + * @returns '0' on Success; Error code otherwise.
  74 + */
  75 +int dpmng_load_aiop(struct fsl_mc_io *mc_io,
  76 + int container_id,
  77 + int aiop_tile_id,
  78 + uint64_t img_iova,
  79 + uint32_t img_size);
  80 +
  81 +/**
  82 + * @brief AIOP run configuration
  83 + */
  84 +struct dpmng_aiop_run_cfg {
  85 + uint32_t cores_mask;
  86 + /*!< Mask of AIOP cores to run (core 0 in most significant bit) */
  87 + uint64_t options;
  88 + /*!< Execution options (currently none defined) */
  89 +};
  90 +
  91 +/**
  92 + * @brief Starts AIOP tile execution
  93 + *
  94 + * @param[in] mc_io Pointer to MC portal's I/O object
  95 + * @param[in] container_id AIOP container ID
  96 + * @param[in] aiop_tile_id AIOP tile ID to reset
  97 + * @param[in] cfg AIOP run configuration
  98 + *
  99 + * @returns '0' on Success; Error code otherwise.
  100 + */
  101 +int dpmng_run_aiop(struct fsl_mc_io *mc_io,
  102 + int container_id,
  103 + int aiop_tile_id,
  104 + const struct dpmng_aiop_run_cfg *cfg);
  105 +
  106 +/**
  107 + * @brief Resets MC portal
  108 + *
  109 + * This function closes all object handles (tokens) that are currently
  110 + * open in the MC portal on which the command is submitted. This allows
  111 + * cleanup of stale handles that belong to non-functional user processes.
  112 + *
  113 + * @param[in] mc_io Pointer to MC portal's I/O object
  114 + *
  115 + * @returns '0' on Success; Error code otherwise.
  116 + */
  117 +int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io);
  118 +
  119 +/** @} */
  120 +
  121 +#endif /* __FSL_DPMNG_H */
include/fsl-mc/fsl_mc.h
  1 +/*
  2 + * Copyright (C) 2014 Freescale Semiconductor
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + */
  6 +
  7 +#ifndef __FSL_MC_H__
  8 +#define __FSL_MC_H__
  9 +
  10 +#include <common.h>
  11 +
  12 +#define MC_CCSR_BASE_ADDR \
  13 + ((struct mc_ccsr_registers __iomem *)0x8340000)
  14 +
  15 +#define BIT(x) (1 << (x))
  16 +#define GCR1_P1_STOP BIT(31)
  17 +#define GCR1_P2_STOP BIT(30)
  18 +#define GCR1_P1_DE_RST BIT(23)
  19 +#define GCR1_P2_DE_RST BIT(22)
  20 +#define GCR1_M1_DE_RST BIT(15)
  21 +#define GCR1_M2_DE_RST BIT(14)
  22 +#define GCR1_M_ALL_DE_RST (GCR1_M1_DE_RST | GCR1_M2_DE_RST)
  23 +#define GSR_FS_MASK 0x3fffffff
  24 +#define MCFAPR_PL_MASK (0x1 << 18)
  25 +#define MCFAPR_BMT_MASK (0x1 << 17)
  26 +#define MCFAPR_BYPASS_ICID_MASK \
  27 + (MCFAPR_PL_MASK | MCFAPR_BMT_MASK)
  28 +
  29 +#define SOC_MC_PORTALS_BASE_ADDR ((void __iomem *)0x00080C000000)
  30 +#define SOC_MC_PORTAL_STRIDE 0x10000
  31 +
  32 +#define SOC_MC_PORTAL_ADDR(_portal_id) \
  33 + ((void __iomem *)((uintptr_t)SOC_MC_PORTALS_BASE_ADDR + \
  34 + (_portal_id) * SOC_MC_PORTAL_STRIDE))
  35 +
  36 +struct mc_ccsr_registers {
  37 + u32 reg_gcr1;
  38 + u32 reserved1;
  39 + u32 reg_gsr;
  40 + u32 reserved2;
  41 + u32 reg_sicbalr;
  42 + u32 reg_sicbahr;
  43 + u32 reg_sicapr;
  44 + u32 reserved3;
  45 + u32 reg_mcfbalr;
  46 + u32 reg_mcfbahr;
  47 + u32 reg_mcfapr;
  48 + u32 reserved4[0x2f1];
  49 + u32 reg_psr;
  50 + u32 reserved5;
  51 + u32 reg_brr[2];
  52 + u32 reserved6[0x80];
  53 + u32 reg_error[];
  54 +};
  55 +
  56 +int mc_init(bd_t *bis);
  57 +
  58 +int get_mc_boot_status(void);
  59 +#endif
include/fsl-mc/fsl_mc_cmd.h
  1 +/* Copyright 2014 Freescale Semiconductor Inc.
  2 + *
  3 + * SPDX-License-Identifier: GPL-2.0+
  4 + */
  5 +#ifndef __FSL_MC_CMD_H
  6 +#define __FSL_MC_CMD_H
  7 +
  8 +#define MC_CMD_NUM_OF_PARAMS 7
  9 +
  10 +#define MAKE_UMASK64(_width) \
  11 + ((uint64_t)((_width) < 64 ? ((uint64_t)1 << (_width)) - 1 : -1))
  12 +
  13 +static inline uint64_t u64_enc(int lsoffset, int width, uint64_t val)
  14 +{
  15 + return (uint64_t)(((uint64_t)val & MAKE_UMASK64(width)) << lsoffset);
  16 +}
  17 +static inline uint64_t u64_dec(uint64_t val, int lsoffset, int width)
  18 +{
  19 + return (uint64_t)((val >> lsoffset) & MAKE_UMASK64(width));
  20 +}
  21 +
  22 +struct mc_command {
  23 + uint64_t header;
  24 + uint64_t params[MC_CMD_NUM_OF_PARAMS];
  25 +};
  26 +
  27 +enum mc_cmd_status {
  28 + MC_CMD_STATUS_OK = 0x0, /*!< Completed successfully */
  29 + MC_CMD_STATUS_READY = 0x1, /*!< Ready to be processed */
  30 + MC_CMD_STATUS_AUTH_ERR = 0x3, /*!< Authentication error */
  31 + MC_CMD_STATUS_NO_PRIVILEGE = 0x4, /*!< No privilege */
  32 + MC_CMD_STATUS_DMA_ERR = 0x5, /*!< DMA or I/O error */
  33 + MC_CMD_STATUS_CONFIG_ERR = 0x6, /*!< Configuration error */
  34 + MC_CMD_STATUS_TIMEOUT = 0x7, /*!< Operation timed out */
  35 + MC_CMD_STATUS_NO_RESOURCE = 0x8, /*!< No resources */
  36 + MC_CMD_STATUS_NO_MEMORY = 0x9, /*!< No memory available */
  37 + MC_CMD_STATUS_BUSY = 0xA, /*!< Device is busy */
  38 + MC_CMD_STATUS_UNSUPPORTED_OP = 0xB, /*!< Unsupported operation */
  39 + MC_CMD_STATUS_INVALID_STATE = 0xC /*!< Invalid state */
  40 +};
  41 +
  42 +#define MC_CMD_HDR_CMDID_O 52 /* Command ID field offset */
  43 +#define MC_CMD_HDR_CMDID_S 12 /* Command ID field size */
  44 +#define MC_CMD_HDR_AUTHID_O 38 /* Authentication ID field offset */
  45 +#define MC_CMD_HDR_AUTHID_S 10 /* Authentication ID field size */
  46 +#define MC_CMD_HDR_STATUS_O 16 /* Status field offset */
  47 +#define MC_CMD_HDR_STATUS_S 8 /* Status field size*/
  48 +#define MC_CMD_HDR_PRI_O 15 /* Priority field offset */
  49 +#define MC_CMD_HDR_PRI_S 1 /* Priority field size */
  50 +
  51 +#define MC_CMD_HDR_READ_STATUS(_hdr) \
  52 + ((enum mc_cmd_status)u64_dec((_hdr), \
  53 + MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S))
  54 +
  55 +#define MC_CMD_HDR_READ_AUTHID(_hdr) \
  56 + ((uint16_t)u64_dec((_hdr), MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S))
  57 +
  58 +#define MC_CMD_PRI_LOW 0 /*!< Low Priority command indication */
  59 +#define MC_CMD_PRI_HIGH 1 /*!< High Priority command indication */
  60 +
  61 +#define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \
  62 + ((_cmd).params[_param] |= u64_enc((_offset), (_width), _arg))
  63 +
  64 +#define MC_RSP_OP(_cmd, _param, _offset, _width, _type, _arg) \
  65 + (_arg = (_type)u64_dec(_cmd.params[_param], (_offset), (_width)))
  66 +
  67 +static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id,
  68 + uint8_t priority,
  69 + uint16_t auth_id)
  70 +{
  71 + uint64_t hdr;
  72 +
  73 + hdr = u64_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id);
  74 + hdr |= u64_enc(MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S, auth_id);
  75 + hdr |= u64_enc(MC_CMD_HDR_PRI_O, MC_CMD_HDR_PRI_S, priority);
  76 + hdr |= u64_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S,
  77 + MC_CMD_STATUS_READY);
  78 +
  79 + return hdr;
  80 +}
  81 +
  82 +/**
  83 + * mc_write_command - writes a command to a Management Complex (MC) portal
  84 + *
  85 + * @portal: pointer to an MC portal
  86 + * @cmd: pointer to a filled command
  87 + */
  88 +static inline void mc_write_command(struct mc_command __iomem *portal,
  89 + struct mc_command *cmd)
  90 +{
  91 + int i;
  92 +
  93 + /* copy command parameters into the portal */
  94 + for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
  95 + writeq(cmd->params[i], &portal->params[i]);
  96 +
  97 + /* submit the command by writing the header */
  98 + writeq(cmd->header, &portal->header);
  99 +}
  100 +
  101 +/**
  102 + * mc_read_response - reads the response for the last MC command from a
  103 + * Management Complex (MC) portal
  104 + *
  105 + * @portal: pointer to an MC portal
  106 + * @resp: pointer to command response buffer
  107 + *
  108 + * Returns MC_CMD_STATUS_OK on Success; Error code otherwise.
  109 + */
  110 +static inline enum mc_cmd_status mc_read_response(
  111 + struct mc_command __iomem *portal,
  112 + struct mc_command *resp)
  113 +{
  114 + int i;
  115 + enum mc_cmd_status status;
  116 +
  117 + /* Copy command response header from MC portal: */
  118 + resp->header = readq(&portal->header);
  119 + status = MC_CMD_HDR_READ_STATUS(resp->header);
  120 + if (status != MC_CMD_STATUS_OK)
  121 + return status;
  122 +
  123 + /* Copy command response data from MC portal: */
  124 + for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
  125 + resp->params[i] = readq(&portal->params[i]);
  126 +
  127 + return status;
  128 +}
  129 +
  130 +int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd);
  131 +
  132 +#endif /* __FSL_MC_CMD_H */
include/fsl-mc/fsl_mc_sys.h
  1 +/*
  2 + * Freescale Layerscape Management Complex (MC) Environment-specific code
  3 + *
  4 + * Copyright (C) 2014 Freescale Semiconductor, Inc.
  5 + *
  6 + * SPDX-License-Identifier: GPL-2.0+
  7 + */
  8 +
  9 +#ifndef _FSL_MC_SYS_H
  10 +#define _FSL_MC_SYS_H
  11 +
  12 +#include <asm/io.h>
  13 +
  14 +struct mc_command;
  15 +
  16 +/*
  17 + * struct mc_portal_wrapper - MC command portal wrapper object
  18 + */
  19 +struct fsl_mc_io {
  20 + struct mc_command __iomem *mmio_regs;
  21 +};
  22 +
  23 +int mc_send_command(struct fsl_mc_io *mc_io,
  24 + struct mc_command *cmd);
  25 +
  26 +#endif /* _FSL_MC_SYS_H */
include/fsl_mc.h
1   -/*
2   - * Copyright (C) 2014 Freescale Semiconductor
3   - *
4   - * SPDX-License-Identifier: GPL-2.0+
5   - */
6   -
7   -#ifndef __FSL_MC_H__
8   -#define __FSL_MC_H__
9   -
10   -#include <common.h>
11   -
12   -#define MC_CCSR_BASE_ADDR \
13   - ((struct mc_ccsr_registers __iomem *)0x8340000)
14   -
15   -#define BIT(x) (1 << (x))
16   -#define GCR1_P1_STOP BIT(31)
17   -#define GCR1_P2_STOP BIT(30)
18   -#define GCR1_P1_DE_RST BIT(23)
19   -#define GCR1_P2_DE_RST BIT(22)
20   -#define GCR1_M1_DE_RST BIT(15)
21   -#define GCR1_M2_DE_RST BIT(14)
22   -#define GCR1_M_ALL_DE_RST (GCR1_M1_DE_RST | GCR1_M2_DE_RST)
23   -#define GSR_FS_MASK 0x3fffffff
24   -#define MCFAPR_PL_MASK (0x1 << 18)
25   -#define MCFAPR_BMT_MASK (0x1 << 17)
26   -#define MCFAPR_BYPASS_ICID_MASK \
27   - (MCFAPR_PL_MASK | MCFAPR_BMT_MASK)
28   -
29   -#define SOC_MC_PORTALS_BASE_ADDR ((void __iomem *)0x00080C000000)
30   -#define SOC_MC_PORTAL_STRIDE 0x10000
31   -
32   -#define SOC_MC_PORTAL_ADDR(_portal_id) \
33   - ((void __iomem *)((uintptr_t)SOC_MC_PORTALS_BASE_ADDR + \
34   - (_portal_id) * SOC_MC_PORTAL_STRIDE))
35   -
36   -struct mc_ccsr_registers {
37   - u32 reg_gcr1;
38   - u32 reserved1;
39   - u32 reg_gsr;
40   - u32 reserved2;
41   - u32 reg_sicbalr;
42   - u32 reg_sicbahr;
43   - u32 reg_sicapr;
44   - u32 reserved3;
45   - u32 reg_mcfbalr;
46   - u32 reg_mcfbahr;
47   - u32 reg_mcfapr;
48   - u32 reserved4[0x2f1];
49   - u32 reg_psr;
50   - u32 reserved5;
51   - u32 reg_brr[2];
52   - u32 reserved6[0x80];
53   - u32 reg_error[];
54   -};
55   -
56   -int mc_init(bd_t *bis);
57   -
58   -int get_mc_boot_status(void);
59   -#endif