summaryrefslogtreecommitdiff
path: root/arch/arm/mach-socfpga/misc_arria10.c
blob: 480fabc3bc1cb08a99797d6863c487482446c671 (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2016-2021 Intel Corporation
 */

#include <altera.h>
#include <common.h>
#include <errno.h>
#include <fdtdec.h>
#include <init.h>
#include <miiphy.h>
#include <netdev.h>
#include <ns16550.h>
#include <spi_flash.h>
#include <watchdog.h>
#include <asm/arch/fpga_manager.h>
#include <asm/arch/misc.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/reset_manager.h>
#include <asm/arch/reset_manager_arria10.h>
#include <asm/arch/sdram_arria10.h>
#include <asm/arch/system_manager.h>
#include <asm/arch/nic301.h>
#include <asm/io.h>
#include <asm/pl310.h>
#include <linux/sizes.h>

#define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q1_3	0x08
#define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q2_11	0x58
#define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q3_3	0x68
#define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q1_7	0x18
#define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7	0x78
#define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3	0x98

#define REGULAR_BOOT_MAGIC	0xd15ea5e
#define PERIPH_RBF_PROG_FORCE	0x50455249

#define QSPI_S25FL_SOFT_RESET_COMMAND	0x00f0ff82
#define QSPI_N25_SOFT_RESET_COMMAND	0x00000001
#define QSPI_NO_SOFT_RESET		0x00000000

/*
 * FPGA programming support for SoC FPGA Arria 10
 */
static Altera_desc altera_fpga[] = {
	{
		/* Family */
		Altera_SoCFPGA,
		/* Interface type */
		fast_passive_parallel,
		/* No limitation as additional data will be ignored */
		-1,
		/* No device function table */
		NULL,
		/* Base interface address specified in driver */
		NULL,
		/* No cookie implementation */
		0
	},
};

#if defined(CONFIG_SPL_BUILD)
static struct pl310_regs *const pl310 =
	(struct pl310_regs *)CONFIG_SYS_PL310_BASE;
static const struct socfpga_noc_fw_ocram *noc_fw_ocram_base =
	(void *)SOCFPGA_SDR_FIREWALL_OCRAM_ADDRESS;

/*
+ * This function initializes security policies to be consistent across
+ * all logic units in the Arria 10.
+ *
+ * The idea is to set all security policies to be normal, nonsecure
+ * for all units.
+ */
void socfpga_init_security_policies(void)
{
	/* Put OCRAM in non-secure */
	writel(0x003f0000, &noc_fw_ocram_base->region0);
	writel(0x1, &noc_fw_ocram_base->enable);

	/* Put DDR in non-secure */
	writel(0xffff0000, SOCFPGA_SDR_FIREWALL_L3_ADDRESS + 0xc);
	writel(0x1, SOCFPGA_SDR_FIREWALL_L3_ADDRESS);

	/* Enable priviledged and non-priviledged access to L4 peripherals */
	writel(~0, SOCFPGA_NOC_L4_PRIV_FLT_OFST);

	/* Enable secure and non-secure transactions to bridges */
	writel(~0, SOCFPGA_NOC_FW_H2F_SCR_OFST);
	writel(~0, SOCFPGA_NOC_FW_H2F_SCR_OFST + 4);

	writel(0x0007FFFF,
	       socfpga_get_sysmgr_addr() + SYSMGR_A10_ECC_INTMASK_SET);
}

void socfpga_sdram_remap_zero(void)
{
	/* Configure the L2 controller to make SDRAM start at 0 */
	writel(0x1, &pl310->pl310_addr_filter_start);
}
#endif

int arch_early_init_r(void)
{
	/* Add device descriptor to FPGA device table */
	socfpga_fpga_add(&altera_fpga[0]);

	return 0;
}

/*
 * Print CPU information
 */
#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
	const u32 bootinfo = readl(socfpga_get_sysmgr_addr() +
				   SYSMGR_A10_BOOTINFO);
	const u32 bsel = SYSMGR_GET_BOOTINFO_BSEL(bootinfo);

	puts("CPU:   Altera SoCFPGA Arria 10\n");

	printf("BOOT:  %s\n", bsel_str[bsel].name);
	return 0;
}
#endif

void do_bridge_reset(int enable, unsigned int mask)
{
	if (enable) {
		if (is_fpgamgr_user_mode()) {
			socfpga_reset_deassert_bridges_handoff();
		} else {
			puts("Bridges: Failed to enable because FPGA is not ");
			puts("in user mode\n");
		}
	} else {
		socfpga_bridges_reset();
	}
}

/*
 * This function set/unset flag with number "0x50455249" to
 * handoff register isw_handoff[7] - 0xffd0624c
 * This flag is used to force periph RBF program regardless FPGA status
 * and double periph RBF config are needed on some devices or boards to
 * stabilize the IO config system.
 */
void force_periph_program(unsigned int status)
{
	if (status)
		writel(PERIPH_RBF_PROG_FORCE, socfpga_get_sysmgr_addr() +
		       SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7);
	else
		writel(0, socfpga_get_sysmgr_addr() +
		       SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7);
}

/*
 * This function is used to check whether
 * handoff register isw_handoff[7] contains
 * flag for forcing the periph RBF program "0x50455249".
 */
bool is_periph_program_force(void)
{
	unsigned int status;

	status = readl(socfpga_get_sysmgr_addr() +
		       SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7);

	if (status == PERIPH_RBF_PROG_FORCE)
		return true;
	else
		return false;
}

/*
 * This function set/unset magic number "0xd15ea5e" to
 * handoff register isw_handoff[7] - 0xffd0624c
 * This magic number is part of boot progress tracking
 * and it's required for warm reset workaround on MPFE hang issue.
 */
void set_regular_boot(unsigned int status)
{
	if (status)
		writel(REGULAR_BOOT_MAGIC, socfpga_get_sysmgr_addr() +
		       SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7);
	else
		writel(0, socfpga_get_sysmgr_addr() +
		       SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7);
}

/*
 * This function is used to check whether
 * handoff register isw_handoff[7] contains
 * magic number "0xd15ea5e".
 */
bool is_regular_boot_valid(void)
{
	unsigned int status;

	status = readl(socfpga_get_sysmgr_addr() +
		       SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7);
	if (status == REGULAR_BOOT_MAGIC)
		return true;
	else
		return false;
}

#if IS_ENABLED(CONFIG_CADENCE_QSPI)
/* This function is used to trigger software reset
 * to the QSPI flash. On some boards, the QSPI flash reset may
 * not be connected to the HPS warm reset.
 */
int qspi_flash_software_reset(void)
{
	struct udevice *flash;
	int ret;

	/* Get the flash info */
	ret = spi_flash_probe_bus_cs(CONFIG_SF_DEFAULT_BUS,
				     CONFIG_SF_DEFAULT_CS,
				     CONFIG_SF_DEFAULT_SPEED,
				     CONFIG_SF_DEFAULT_MODE,
				     &flash);
	if (ret) {
		debug("Failed to initialize SPI flash at ");
		debug("%u:%u (error %d)\n", CONFIG_SF_DEFAULT_BUS,
		      CONFIG_SF_DEFAULT_CS, ret);
		return -ENODEV;
	}

	if (!flash)
		return -EINVAL;

	/*
	 * QSPI flash software reset command, for the case where
	 * no HPS reset connected to QSPI flash reset
	 */
	if (!memcmp(flash->name, "N25", SZ_1 + SZ_2))
		writel(QSPI_N25_SOFT_RESET_COMMAND, socfpga_get_sysmgr_addr() +
		       SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND);
	else if (!memcmp(flash->name, "S25FL", SZ_1 + SZ_4))
		writel(QSPI_S25FL_SOFT_RESET_COMMAND,
		       socfpga_get_sysmgr_addr() +
		       SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND);
	else /* No software reset */
		writel(QSPI_NO_SOFT_RESET, socfpga_get_sysmgr_addr() +
		       SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND);

	return 0;
}
#endif

void dram_bank_mmu_setup(int bank)
{
	struct bd_info *bd = gd->bd;
	u32 start, size;
	int i;

	/* If we're still in OCRAM, don't set the XN bit on it */
	if (!(gd->flags & GD_FLG_RELOC)) {
		set_section_dcache(
			CONFIG_SYS_INIT_RAM_ADDR >> MMU_SECTION_SHIFT,
			DCACHE_WRITETHROUGH);
	}

	/*
	 * The default implementation of this function allows the DRAM dcache
	 * to be enabled only after relocation. However, to speed up ECC
	 * initialization, we want to be able to enable DRAM dcache before
	 * relocation, so we don't check GD_FLG_RELOC (this assumes bd->bi_dram
	 * is set first).
	 */
	start = bd->bi_dram[bank].start >> MMU_SECTION_SHIFT;
	size = bd->bi_dram[bank].size >> MMU_SECTION_SHIFT;
	for (i = start; i < start + size; i++)
		set_section_dcache(i, DCACHE_DEFAULT_OPTION);
}