Commit 7b3bd9a7988a8b4c8ba22a52b4927e8e59819b12
Committed by
York Sun
1 parent
4f2532c4a4
Exists in
v2017.01-smarct4x
and in
37 other branches
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
- board/freescale/ls2085a/ls2085a.c
- drivers/net/Makefile
- drivers/net/fsl-mc/Makefile
- drivers/net/fsl-mc/dpmng.c
- drivers/net/fsl-mc/fsl_dpmng_cmd.h
- drivers/net/fsl-mc/mc.c
- drivers/net/fsl-mc/mc_sys.c
- drivers/net/fsl_mc/Makefile
- drivers/net/fsl_mc/mc.c
- include/configs/ls2085a_common.h
- include/fsl-mc/fsl_dpmng.h
- include/fsl-mc/fsl_mc.h
- include/fsl-mc/fsl_mc_cmd.h
- include/fsl-mc/fsl_mc_sys.h
- include/fsl_mc.h
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
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
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 |