plat_bl31_setup.c 3.46 KB
Newer Older
1
2
3
4
5
6
7
/*
 * Copyright (C) 2018 Marvell International Ltd.
 *
 * SPDX-License-Identifier:     BSD-3-Clause
 * https://spdx.org/licenses
 */

8
9
10
11
12
13
#include <common/debug.h>
#include <drivers/marvell/mci.h>
#include <drivers/marvell/mochi/ap_setup.h>
#include <drivers/marvell/mochi/cp110_setup.h>
#include <lib/mmio.h>

14
#include <armada_common.h>
15
16
#include <marvell_plat_priv.h>
#include <marvell_pm.h>
17
#include <mc_trustzone/mc_trustzone.h>
18
#include <plat_marvell.h>
19
#if MSS_SUPPORT
20
21
#include <mss_ipc_drv.h>
#include <mss_mem.h>
22
#include <mss_defs.h>
23
#endif
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

/* In Armada-8k family AP806/AP807, CP0 connected to PIDI
 * and CP1 connected to IHB via MCI #0
 */
#define MVEBU_MCI0		0

static _Bool pm_fw_running;

/* Set a weak stub for platforms that don't need to configure GPIO */
#pragma weak marvell_gpio_config
int marvell_gpio_config(void)
{
	return 0;
}

static void marvell_bl31_mpp_init(int cp)
{
	uint32_t reg;

	/* need to do for CP#0 only */
	if (cp)
		return;


	/*
	 * Enable CP0 I2C MPPs (MPP: 37-38)
	 * U-Boot rely on proper MPP settings for I2C EEPROM usage
	 * (only for CP0)
	 */
	reg = mmio_read_32(MVEBU_CP_MPP_REGS(0, 4));
	mmio_write_32(MVEBU_CP_MPP_REGS(0, 4), reg | 0x2200000);
}

57
#if MSS_SUPPORT
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
void marvell_bl31_mss_init(void)
{
	struct mss_pm_ctrl_block *mss_pm_crtl =
			(struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE;

	/* Check that the image was loaded successfully */
	if (mss_pm_crtl->handshake != HOST_ACKNOWLEDGMENT) {
		NOTICE("MSS PM is not supported in this build\n");
		return;
	}

	/* If we got here it means that the PM firmware is running */
	pm_fw_running = 1;

	INFO("MSS IPC init\n");

	if (mss_pm_crtl->ipc_state == IPC_INITIALIZED)
		mv_pm_ipc_init(mss_pm_crtl->ipc_base_address | MVEBU_REGS_BASE);
}
77
#endif
78
79
80
81
82
83

_Bool is_pm_fw_running(void)
{
	return pm_fw_running;
}

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/* For TrusTzone we treat the "target" field of addr_map_win
 * struct as attribute
 */
static const struct addr_map_win tz_map[] = {
	{PLAT_MARVELL_ATF_BASE, 0x200000, TZ_PERM_ABORT}
};

/* Configure MC TrustZone regions */
static void marvell_bl31_security_setup(void)
{
	int tz_nr, win_id;

	tz_nr = ARRAY_SIZE(tz_map);

	for (win_id = 0; win_id < tz_nr; win_id++)
		tz_enable_win(MVEBU_AP0, tz_map, win_id);
}

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* This function overruns the same function in marvell_bl31_setup.c */
void bl31_plat_arch_setup(void)
{
	int cp;
	uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE;

	/* initialize the timer for mdelay/udelay functionality */
	plat_delay_timer_init();

	/* configure apn806 */
	ap_init();

	/* In marvell_bl31_plat_arch_setup, el3 mmu is configured.
	 * el3 mmu configuration MUST be called after apn806_init, if not,
	 * this will cause an hang in init_io_win
	 * (after setting the IO windows GCR values).
	 */
	if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM ||
	    mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE)
		marvell_bl31_plat_arch_setup();

	for (cp = 0; cp < CP_COUNT; cp++) {
		cp110_init(MVEBU_CP_REGS_BASE(cp),
			   STREAM_ID_BASE + (cp * MAX_STREAM_ID_PER_CP));

		marvell_bl31_mpp_init(cp);
128
129
130
131
132

#if MSS_SUPPORT
		/* Release CP MSS CPU from reset once the CP init is done */
		mss_start_cp_cm3(cp);
#endif
133
134
	}

135
136
137
	for (cp = 1; cp < CP_COUNT; cp++)
		mci_link_tune(cp - 1);

138
#if MSS_SUPPORT
139
140
141
142
	/* initialize IPC between MSS and ATF */
	if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM ||
	    mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE)
		marvell_bl31_mss_init();
143
#endif
144
145
	/* Configure GPIO */
	marvell_gpio_config();
146
147

	marvell_bl31_security_setup();
148
}