summaryrefslogtreecommitdiffstats
path: root/plat/arm/board/rdv1mc/rdv1mc_plat.c
blob: d8594006679548bc50c4e0d3fa875d734a60d9d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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
128
129
130
131
/*
 * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <common/debug.h>
#include <drivers/arm/gic600_multichip.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <sgi_soc_platform_def.h>
#include <sgi_plat.h>

#if defined(IMAGE_BL31)
static const mmap_region_t rdv1mc_dynamic_mmap[] = {
	ARM_MAP_SHARED_RAM_REMOTE_CHIP(1),
	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
	SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1),
#if (CSS_SGI_CHIP_COUNT > 2)
	ARM_MAP_SHARED_RAM_REMOTE_CHIP(2),
	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(2),
	SOC_CSS_MAP_DEVICE_REMOTE_CHIP(2),
#endif
#if (CSS_SGI_CHIP_COUNT > 3)
	ARM_MAP_SHARED_RAM_REMOTE_CHIP(3),
	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(3),
	SOC_CSS_MAP_DEVICE_REMOTE_CHIP(3)
#endif
};

static struct gic600_multichip_data rdv1mc_multichip_data __init = {
	.rt_owner_base = PLAT_ARM_GICD_BASE,
	.rt_owner = 0,
	.chip_count = CSS_SGI_CHIP_COUNT,
	.chip_addrs = {
		PLAT_ARM_GICD_BASE >> 16,
		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
#if (CSS_SGI_CHIP_COUNT > 2)
		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
#endif
#if (CSS_SGI_CHIP_COUNT > 3)
		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
#endif
	},
	.spi_ids = {
		{32, 255},
		{0, 0},
#if (CSS_SGI_CHIP_COUNT > 2)
		{0, 0},
#endif
#if (CSS_SGI_CHIP_COUNT > 3)
		{0, 0},
#endif
	}
};

static uintptr_t rdv1mc_multichip_gicr_frames[] = {
	/* Chip 0's GICR Base */
	PLAT_ARM_GICR_BASE,
	/* Chip 1's GICR BASE */
	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),
#if (CSS_SGI_CHIP_COUNT > 2)
	/* Chip 2's GICR BASE */
	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2),
#endif
#if (CSS_SGI_CHIP_COUNT > 3)
	/* Chip 3's GICR BASE */
	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3),
#endif
	UL(0)	/* Zero Termination */
};
#endif /* IMAGE_BL31 */

unsigned int plat_arm_sgi_get_platform_id(void)
{
	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
				& SID_SYSTEM_ID_PART_NUM_MASK;
}

unsigned int plat_arm_sgi_get_config_id(void)
{
	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
}

unsigned int plat_arm_sgi_get_multi_chip_mode(void)
{
	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
			SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
}

/*
 * bl31_platform_setup_function is guarded by IMAGE_BL31 macro because
 * PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not
 * for other stages.
 */
#if defined(IMAGE_BL31)
void bl31_platform_setup(void)
{
	int ret;
	unsigned int i;

	if ((plat_arm_sgi_get_multi_chip_mode() == 0) &&
			(CSS_SGI_CHIP_COUNT > 1)) {
		ERROR("Chip Count is set to %u but multi-chip mode is not "
			"enabled\n", CSS_SGI_CHIP_COUNT);
		panic();
	} else if ((plat_arm_sgi_get_multi_chip_mode() == 1) &&
			(CSS_SGI_CHIP_COUNT > 1)) {
		INFO("Enabling support for multi-chip in RD-V1-MC\n");

		for (i = 0; i < ARRAY_SIZE(rdv1mc_dynamic_mmap); i++) {
			ret = mmap_add_dynamic_region(
					rdv1mc_dynamic_mmap[i].base_pa,
					rdv1mc_dynamic_mmap[i].base_va,
					rdv1mc_dynamic_mmap[i].size,
					rdv1mc_dynamic_mmap[i].attr);
			if (ret != 0) {
				ERROR("Failed to add dynamic mmap entry "
						"(ret=%d)\n", ret);
				panic();
			}
		}

		plat_arm_override_gicr_frames(
			rdv1mc_multichip_gicr_frames);
		gic600_multichip_init(&rdv1mc_multichip_data);
	}

	sgi_bl31_common_platform_setup();
}
#endif /* IMAGE_BL31 */