aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/mach-octeon/lowlevel_init.S
blob: 56d1d2261e53f8627c90db14fd2f782fdc7e1e3a (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
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2020 Stefan Roese <sr@denx.de>
 */

#include <config.h>
#include <asm-offsets.h>
#include <asm/cacheops.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <asm/asm.h>
#include <mach/octeon-model.h>

#define COP0_CVMCTL_REG		$9,7	/* Cavium control */
#define COP0_CVMMEMCTL_REG	$11,7	/* Cavium memory control */
#define COP0_PROC_ID_REG	$15,0

	.set noreorder

LEAF(lowlevel_init)

	/* Set LMEMSZ in CVMMEMCTL register */
	dmfc0	a0, COP0_CVMMEMCTL_REG
	dins	a0, zero, 0, 9
	mfc0	a4, COP0_PROC_ID_REG
	li	a5, OCTEON_CN63XX_PASS1_0 /* Octeon cn63xx pass1 chip id */
	bgt	a5, a4, 2f
	 ori	 a0, 0x104	/* setup 4 lines of scratch */
	ori	a6, a5, 8	/* Octeon cn63xx pass2 chip id */
	bge	a4, a6, 2f
	 nop
	li	a6, 4
	ins	a0, a6, 11, 4	/* Set WBTHRESH=4 as per Core-14752 errata */
2:
	dmtc0	a0, COP0_CVMMEMCTL_REG

	/* Set REPUN bit in CVMCTL register */
	dmfc0	a0, COP0_CVMCTL_REG
	ori	a0, 1<<14	/* enable fixup of unaligned mem access */
	dmtc0	a0, COP0_CVMCTL_REG

	jr	ra
	 nop
	END(lowlevel_init)

LEAF(mips_mach_early_init)

	move    s0, ra

	bal	__dummy
	 nop

__dummy:
	/* Get the actual address that we are running at */
	PTR_LA	a7, __dummy
	dsubu	t3, ra, a7	/* t3 now has reloc offset */

	PTR_LA	t1, _start
	daddu	t0, t1, t3	/* t0 now has actual address of _start */

	/* Calculate end address of copy loop */
	PTR_LA	t2, _end
	daddiu	t2, t2, 0x4000	/* Increase size to include appended DTB */
	daddiu	t2, t2, 127
	ins	t2, zero, 0, 7	/* Round up to cache line for memcpy */

	/* Copy ourself to the L2 cache from flash, 32 bytes at a time */
1:
	ld	a0, 0(t0)
	ld	a1, 8(t0)
	ld	a2, 16(t0)
	ld	a3, 24(t0)
	sd	a0, 0(t1)
	sd	a1, 8(t1)
	sd	a2, 16(t1)
	sd	a3, 24(t1)
	addiu	t0, 32
	addiu	t1, 32
	bne	t1, t2, 1b
	 nop

	sync

	/*
	 * Return to start.S now running from TEXT_BASE, which points
	 * to DRAM address space, which effectively is L2 cache now.
	 * This speeds up the init process extremely, especially the
	 * DDR init code.
	 */
	dsubu	s0, s0, t3	/* Fixup return address with reloc offset */
	jr.hb	s0		/* Jump back with hazard barrier */
	 nop

	END(mips_mach_early_init)

LEAF(nmi_bootvector)

	/*
	 * From Marvell original bootvector setup
	 */
	mfc0	k0, CP0_STATUS
	/* Enable 64-bit addressing, set ERL (should already be set) */
	ori	k0, 0x84
	mtc0	k0, CP0_STATUS
	/* Core-14345, clear L1 Dcache virtual tags if the core hit an NMI */
	cache	17, 0($0)

	/*
	 * Needed for Linux kernel booting, otherwise it hangs while
	 * zero'ing all of CVMSEG
	 */
	dmfc0	a0, COP0_CVMMEMCTL_REG
	dins	a0, zero, 0, 9
	ori	a0, 0x104	/* setup 4 lines of scratch */
	dmtc0	a0, COP0_CVMMEMCTL_REG

	/*
	 * Load parameters and entry point
	 */
	PTR_LA	t9, nmi_handler_para
	sync

	ld	s0, 0x00(t9)
	ld	a0, 0x08(t9)
	ld	a1, 0x10(t9)
	ld	a2, 0x18(t9)
	ld	a3, 0x20(t9)

	/* Finally jump to entry point (start kernel etc) */
	j	s0
	 nop

	END(nmi_bootvector)

	/*
	 * Add here some space for the NMI parameters (entry point and args)
	 */
	.globl nmi_handler_para
nmi_handler_para:
	.dword	0	// entry-point
	.dword	0	// arg0
	.dword	0	// arg1
	.dword	0	// arg2
	.dword	0	// arg3