summaryrefslogtreecommitdiff
path: root/board/imgtec/malta/lowlevel_init.S
blob: 534db1d83245b010a086fc8523741ce2235068cd (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
/*
 * Copyright (C) 2013 Gabor Juhos <juhosg@openwrt.org>
 *
 * SPDX-License-Identifier:	GPL-2.0
 */

#include <config.h>
#include <gt64120.h>
#include <msc01.h>
#include <pci.h>

#include <asm/addrspace.h>
#include <asm/regdef.h>
#include <asm/malta.h>
#include <asm/mipsregs.h>

#ifdef CONFIG_SYS_BIG_ENDIAN
#define CPU_TO_GT32(_x)		((_x))
#else
#define CPU_TO_GT32(_x) (					\
	(((_x) & 0xff) << 24) | (((_x) & 0xff00) << 8) |	\
	(((_x) & 0xff0000) >> 8) | (((_x) & 0xff000000) >> 24))
#endif

	.text
	.set noreorder

	.globl	lowlevel_init
lowlevel_init:
	/* disable any L2 cache for now */
	sync
	mfc0	t0, CP0_CONFIG, 2
	ori	t0, t0, 0x1 << 12
	mtc0	t0, CP0_CONFIG, 2

	/* detect the core card */
	li	t0, KSEG1ADDR(MALTA_REVISION)
	lw	t0, 0(t0)
	srl	t0, t0, MALTA_REVISION_CORID_SHF
	andi	t0, t0, (MALTA_REVISION_CORID_MSK >> \
			 MALTA_REVISION_CORID_SHF)

	/* core cards using the gt64120 system controller */
	li	t1, MALTA_REVISION_CORID_CORE_LV
	beq	t0, t1, _gt64120

	/* core cards using the MSC01 system controller */
	 li	t1, MALTA_REVISION_CORID_CORE_FPGA6
	beq	t0, t1, _msc01
	 nop

	/* unknown system controller */
	b	.
	 nop

	/*
	 * Load BAR registers of GT64120 as done by YAMON
	 *
	 * based on a patch sent by Antony Pavlov <antonynpavlov@gmail.com>
	 * to the barebox mailing list.
	 * The subject of the original patch:
	 *   'MIPS: qemu-malta: add YAMON-style GT64120 memory map'
	 * URL:
	 * http://www.mail-archive.com/barebox@lists.infradead.org/msg06128.html
	 *
	 * based on write_bootloader() in qemu.git/hw/mips_malta.c
	 * see GT64120 manual and qemu.git/hw/gt64xxx.c for details
	 */
_gt64120:
	/* move GT64120 registers from 0x14000000 to 0x1be00000 */
	li	t1, KSEG1ADDR(GT_DEF_BASE)
	li	t0, CPU_TO_GT32(0xdf000000)
	sw	t0, GT_ISD_OFS(t1)

	/* setup MEM-to-PCI0 mapping */
	li	t1, KSEG1ADDR(MALTA_GT_BASE)

	/* setup PCI0 io window to 0x18000000-0x181fffff */
	li	t0, CPU_TO_GT32(0xc0000000)
	sw	t0, GT_PCI0IOLD_OFS(t1)
	li	t0, CPU_TO_GT32(0x40000000)
	sw	t0, GT_PCI0IOHD_OFS(t1)

	/* setup PCI0 mem windows */
	li	t0, CPU_TO_GT32(0x80000000)
	sw	t0, GT_PCI0M0LD_OFS(t1)
	li	t0, CPU_TO_GT32(0x3f000000)
	sw	t0, GT_PCI0M0HD_OFS(t1)

	li	t0, CPU_TO_GT32(0xc1000000)
	sw	t0, GT_PCI0M1LD_OFS(t1)
	li	t0, CPU_TO_GT32(0x5e000000)
	sw	t0, GT_PCI0M1HD_OFS(t1)

	jr	ra
	 nop

	/*
	 *
	 */
_msc01:
	/* setup peripheral bus controller clock divide */
	li	t0, KSEG1ADDR(MALTA_MSC01_PBC_BASE)
	li	t1, 0x1 << MSC01_PBC_CLKCFG_SHF
	sw	t1, MSC01_PBC_CLKCFG_OFS(t0)

	/* tweak peripheral bus controller timings */
	li	t1, (0x1 << MSC01_PBC_CS0TIM_CDT_SHF) | \
		    (0x1 << MSC01_PBC_CS0TIM_CAT_SHF)
	sw	t1, MSC01_PBC_CS0TIM_OFS(t0)
	li	t1, (0x0 << MSC01_PBC_CS0RW_RDT_SHF) | \
		    (0x2 << MSC01_PBC_CS0RW_RAT_SHF) | \
		    (0x0 << MSC01_PBC_CS0RW_WDT_SHF) | \
		    (0x2 << MSC01_PBC_CS0RW_WAT_SHF)
	sw	t1, MSC01_PBC_CS0RW_OFS(t0)
	lw	t1, MSC01_PBC_CS0CFG_OFS(t0)
	li	t2, MSC01_PBC_CS0CFG_DTYP_MSK
	and	t1, t2
	ori	t1, (0x0 << MSC01_PBC_CS0CFG_ADM_SHF) | \
		    (0x3 << MSC01_PBC_CS0CFG_WSIDLE_SHF) | \
		    (0x10 << MSC01_PBC_CS0CFG_WS_SHF)
	sw	t1, MSC01_PBC_CS0CFG_OFS(t0)

	/* setup basic address decode */
	li	t0, KSEG1ADDR(MALTA_MSC01_BIU_BASE)
	li	t1, 0x0
	li	t2, -CONFIG_SYS_MEM_SIZE
	sw	t1, MSC01_BIU_MCBAS1L_OFS(t0)
	sw	t2, MSC01_BIU_MCMSK1L_OFS(t0)
	sw	t1, MSC01_BIU_MCBAS2L_OFS(t0)
	sw	t2, MSC01_BIU_MCMSK2L_OFS(t0)

	/* initialise IP1 - unused */
	li	t1, MALTA_MSC01_IP1_BASE
	li	t2, -MALTA_MSC01_IP1_SIZE
	sw	t1, MSC01_BIU_IP1BAS1L_OFS(t0)
	sw	t2, MSC01_BIU_IP1MSK1L_OFS(t0)
	sw	t1, MSC01_BIU_IP1BAS2L_OFS(t0)
	sw	t2, MSC01_BIU_IP1MSK2L_OFS(t0)

	/* initialise IP2 - PCI */
	li	t1, MALTA_MSC01_IP2_BASE1
	li	t2, -MALTA_MSC01_IP2_SIZE1
	sw	t1, MSC01_BIU_IP2BAS1L_OFS(t0)
	sw	t2, MSC01_BIU_IP2MSK1L_OFS(t0)
	li	t1, MALTA_MSC01_IP2_BASE2
	li	t2, -MALTA_MSC01_IP2_SIZE2
	sw	t1, MSC01_BIU_IP2BAS2L_OFS(t0)
	sw	t2, MSC01_BIU_IP2MSK2L_OFS(t0)

	/* initialise IP3 - peripheral bus controller */
	li	t1, MALTA_MSC01_IP3_BASE
	li	t2, -MALTA_MSC01_IP3_SIZE
	sw	t1, MSC01_BIU_IP3BAS1L_OFS(t0)
	sw	t2, MSC01_BIU_IP3MSK1L_OFS(t0)
	sw	t1, MSC01_BIU_IP3BAS2L_OFS(t0)
	sw	t2, MSC01_BIU_IP3MSK2L_OFS(t0)

	/* setup PCI memory */
	li	t0, KSEG1ADDR(MALTA_MSC01_PCI_BASE)
	li	t1, MALTA_MSC01_PCIMEM_BASE
	li	t2, (-MALTA_MSC01_PCIMEM_SIZE) & MSC01_PCI_SC2PMMSKL_MSK_MSK
	li	t3, MALTA_MSC01_PCIMEM_MAP
	sw	t1, MSC01_PCI_SC2PMBASL_OFS(t0)
	sw	t2, MSC01_PCI_SC2PMMSKL_OFS(t0)
	sw	t3, MSC01_PCI_SC2PMMAPL_OFS(t0)

	/* setup PCI I/O */
	li	t1, MALTA_MSC01_PCIIO_BASE
	li	t2, (-MALTA_MSC01_PCIIO_SIZE) & MSC01_PCI_SC2PIOMSKL_MSK_MSK
	li	t3, MALTA_MSC01_PCIIO_MAP
	sw	t1, MSC01_PCI_SC2PIOBASL_OFS(t0)
	sw	t2, MSC01_PCI_SC2PIOMSKL_OFS(t0)
	sw	t3, MSC01_PCI_SC2PIOMAPL_OFS(t0)

	/* setup PCI_BAR0 memory window */
	li	t1, -CONFIG_SYS_MEM_SIZE
	sw	t1, MSC01_PCI_BAR0_OFS(t0)

	/* setup PCI to SysCon/CPU translation */
	sw	t1, MSC01_PCI_P2SCMSKL_OFS(t0)
	sw	zero, MSC01_PCI_P2SCMAPL_OFS(t0)

	/* setup PCI vendor & device IDs */
	li	t1, (PCI_VENDOR_ID_MIPS << MSC01_PCI_HEAD0_VENDORID_SHF) | \
		    (PCI_DEVICE_ID_MIPS_MSC01 << MSC01_PCI_HEAD0_DEVICEID_SHF)
	sw	t1, MSC01_PCI_HEAD0_OFS(t0)

	/* setup PCI subsystem vendor & device IDs */
	sw	t1, MSC01_PCI_HEAD11_OFS(t0)

	/* setup PCI class, revision */
	li	t1, (PCI_CLASS_BRIDGE_HOST << MSC01_PCI_HEAD2_CLASS_SHF) | \
		    (0x1 << MSC01_PCI_HEAD2_REV_SHF)
	sw	t1, MSC01_PCI_HEAD2_OFS(t0)

	/* ensure a sane setup */
	sw	zero, MSC01_PCI_HEAD3_OFS(t0)
	sw	zero, MSC01_PCI_HEAD4_OFS(t0)
	sw	zero, MSC01_PCI_HEAD5_OFS(t0)
	sw	zero, MSC01_PCI_HEAD6_OFS(t0)
	sw	zero, MSC01_PCI_HEAD7_OFS(t0)
	sw	zero, MSC01_PCI_HEAD8_OFS(t0)
	sw	zero, MSC01_PCI_HEAD9_OFS(t0)
	sw	zero, MSC01_PCI_HEAD10_OFS(t0)
	sw	zero, MSC01_PCI_HEAD12_OFS(t0)
	sw	zero, MSC01_PCI_HEAD13_OFS(t0)
	sw	zero, MSC01_PCI_HEAD14_OFS(t0)
	sw	zero, MSC01_PCI_HEAD15_OFS(t0)

	/* setup PCI command register */
	li	t1, (PCI_COMMAND_FAST_BACK | \
		     PCI_COMMAND_SERR | \
		     PCI_COMMAND_PARITY | \
		     PCI_COMMAND_MASTER | \
		     PCI_COMMAND_MEMORY)
	sw	t1, MSC01_PCI_HEAD1_OFS(t0)

	/* setup PCI byte swapping */
#ifdef CONFIG_SYS_BIG_ENDIAN
	li	t1, (0x1 << MSC01_PCI_SWAP_BAR0_BSWAP_SHF) | \
		    (0x1 << MSC01_PCI_SWAP_IO_BSWAP_SHF)
	sw	t1, MSC01_PCI_SWAP_OFS(t0)
#else
	sw	zero, MSC01_PCI_SWAP_OFS(t0)
#endif

	/* enable PCI host configuration cycles */
	lw	t1, MSC01_PCI_CFG_OFS(t0)
	li	t2, MSC01_PCI_CFG_RA_MSK | \
		    MSC01_PCI_CFG_G_MSK | \
		    MSC01_PCI_CFG_EN_MSK
	or	t1, t1, t2
	sw	t1, MSC01_PCI_CFG_OFS(t0)

	jr	ra
	 nop