973c56dc83919b145f54136731cf12ef4bb43c69
2 * Copyright (C) 2018 Marvell International Ltd.
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
8 #include <armada_common.h>
11 #include <cp110_setup.h>
13 #include <marvell_plat_priv.h> /* timer functionality */
15 #include <platform_def.h>
17 #include "mss_scp_bootloader.h"
19 /* IO windows configuration */
20 #define IOW_GCR_OFFSET (0x70)
22 /* MSS windows configuration */
23 #define MSS_AEBR(base) (base + 0x160)
24 #define MSS_AIBR(base) (base + 0x164)
25 #define MSS_AEBR_MASK 0xFFF
26 #define MSS_AIBR_MASK 0xFFF
28 #define MSS_EXTERNAL_SPACE 0x50000000
29 #define MSS_EXTERNAL_ACCESS_BIT 28
30 #define MSS_EXTERNAL_ADDR_MASK 0xfffffff
31 #define MSS_INTERNAL_ACCESS_BIT 28
33 struct addr_map_win ccu_mem_map
[] = {
34 {MVEBU_CP_REGS_BASE(0), 0x4000000, IO_0_TID
}
37 /* Since the scp_bl2 image can contain firmware for cp1 and cp0 coprocessors,
38 * the access to cp0 and cp1 need to be provided. More precisely it is
40 * - get the information about device id which is stored in CP0 registers
41 * (to distinguish between cases where we have cp0 and cp1 or standalone cp0)
42 * - get the access to cp which is needed for loading fw for cp0/cp1
44 * This function configures ccu windows accordingly.
46 * Note: there is no need to restore previous ccu configuration, since in next
47 * phase (BL31) the init_ccu will be called (via apn806_init/
48 * bl31_plat_arch_setu) and therefore the ccu configuration will be overwritten.
50 static int bl2_plat_mmap_init(void)
52 int cfg_num
, win_id
, cfg_idx
;
54 cfg_num
= ARRAY_SIZE(ccu_mem_map
);
56 /* CCU window-0 should not be counted - it's already used */
57 if (cfg_num
> (MVEBU_CCU_MAX_WINS
- 1)) {
58 ERROR("BL2: %s: trying to open too many windows\n", __func__
);
62 /* Enable required CCU windows
63 * Do not touch CCU window 0,
64 * it's used for the internal registers access
66 for (cfg_idx
= 0, win_id
= 1; cfg_idx
< cfg_num
; cfg_idx
++, win_id
++) {
67 /* Enable required CCU windows */
68 ccu_win_check(&ccu_mem_map
[cfg_idx
]);
69 ccu_enable_win(MVEBU_AP0
, &ccu_mem_map
[cfg_idx
], win_id
);
72 /* Set the default target id to PIDI */
73 mmio_write_32(MVEBU_IO_WIN_BASE(MVEBU_AP0
) + IOW_GCR_OFFSET
, PIDI_TID
);
78 /*****************************************************************************
79 * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
80 * Return 0 on success, -1 otherwise.
81 *****************************************************************************
83 int bl2_plat_handle_scp_bl2(image_info_t
*scp_bl2_image_info
)
87 INFO("BL2: Initiating SCP_BL2 transfer to SCP\n");
89 /* initialize time (for delay functionality) */
90 plat_delay_timer_init();
92 ret
= bl2_plat_mmap_init();
96 ret
= scp_bootloader_transfer((void *)scp_bl2_image_info
->image_base
,
97 scp_bl2_image_info
->image_size
);
100 INFO("BL2: SCP_BL2 transferred to SCP\n");
102 ERROR("BL2: SCP_BL2 transfer failure\n");
107 uintptr_t bl2_plat_get_cp_mss_regs(int ap_idx
, int cp_idx
)
109 return MVEBU_CP_REGS_BASE(cp_idx
) + 0x280000;
112 uintptr_t bl2_plat_get_ap_mss_regs(int ap_idx
)
114 return MVEBU_REGS_BASE
+ 0x580000;
117 uint32_t bl2_plat_get_cp_count(int ap_idx
)
119 uint32_t revision
= cp110_device_id_get(MVEBU_CP_REGS_BASE(0));
123 if (revision
== MVEBU_80X0_DEV_ID
||
124 revision
== MVEBU_80X0_CP115_DEV_ID
)
130 uint32_t bl2_plat_get_ap_count(void)
132 /* A8040 and A7040 have only one AP */
136 void bl2_plat_configure_mss_windows(uintptr_t mss_regs
)
138 /* set AXI External and Internal Address Bus extension */
139 mmio_write_32(MSS_AEBR(mss_regs
),
140 ((0x0 >> MSS_EXTERNAL_ACCESS_BIT
) & MSS_AEBR_MASK
));
141 mmio_write_32(MSS_AIBR(mss_regs
),
142 ((mss_regs
>> MSS_INTERNAL_ACCESS_BIT
) & MSS_AIBR_MASK
));