summaryrefslogtreecommitdiffstats
path: root/board/Marvell/common/misc.S
blob: b3a089803aa5aba27e8a256fdf1d13732ef8f612 (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
#include <config.h>
#include <74xx_7xx.h>
#include "version.h"

#include <ppc_asm.tmpl>
#include <ppc_defs.h>

#include <asm/cache.h>
#include <asm/mmu.h>

#include "../include/mv_gen_reg.h"

#ifdef CONFIG_ECC
	/* Galileo specific asm code for initializing ECC */
	.globl board_relocate_rom
board_relocate_rom:
	mflr	r7
	/* update the location of the GT registers */
	lis	r11, CONFIG_SYS_GT_REGS@h
	/* if we're using ECC, we must use the DMA engine to copy ourselves */
	bl	start_idma_transfer_0
	bl	wait_for_idma_0
	bl	stop_idma_engine_0

	mtlr	r7
	blr

	.globl board_init_ecc
board_init_ecc:
	mflr	r7
	/* NOTE: r10 still contains the location we've been relocated to
	 * which happens to be TOP_OF_RAM - CONFIG_SYS_MONITOR_LEN */

	/* now that we're running from ram, init the rest of main memory
	 * for ECC use */
	lis	r8, CONFIG_SYS_MONITOR_LEN@h
	ori	r8, r8, CONFIG_SYS_MONITOR_LEN@l

	divw	r3, r10, r8

	/* set up the counter, and init the starting address */
	mtctr	r3
	li	r12, 0

	/* bytes per transfer */
	mr	r5, r8
about_to_init_ecc:
1:	mr	r3, r12
	mr	r4, r12
	bl	start_idma_transfer_0
	bl	wait_for_idma_0
	bl	stop_idma_engine_0
	add	r12, r12, r8
	bdnz	1b

	mtlr	r7
	blr

	/* r3:	dest addr
	 * r4:	source addr
	 * r5:	byte count
	 * r11: gt regbase
	 * trashes:	 r6, r5
	 */
start_idma_transfer_0:
	/* set the byte count, including the OWN bit */
	mr	r6, r11
	ori	r6, r6, CHANNEL0_DMA_BYTE_COUNT
	stwbrx	r5, 0, (r6)

	/* set the source address */
	mr	r6, r11
	ori	r6, r6, CHANNEL0_DMA_SOURCE_ADDRESS
	stwbrx	r4, 0, (r6)

	/* set the dest address */
	mr	r6, r11
	ori	r6, r6, CHANNEL0_DMA_DESTINATION_ADDRESS
	stwbrx	r3, 0, (r6)

	/* set the next record pointer */
	li	r5, 0
	mr	r6, r11
	ori	r6, r6, CHANNEL0NEXT_RECORD_POINTER
	stwbrx	r5, 0, (r6)

	/* set the low control register */
	/* bit 9 is NON chained mode, bit 31 is new style descriptors.
	   bit 12 is channel enable */
	ori	r5, r5, (1 << 12) | (1 << 12) | (1 << 11)
	/* 15 shifted by 16 (oris) == bit 31 */
	oris	r5, r5, (1 << 15)
	mr	r6, r11
	ori	r6, r6, CHANNEL0CONTROL
	stwbrx	r5, 0, (r6)

	blr

	/* this waits for the bytecount to return to zero, indicating
	 * that the trasfer is complete */
wait_for_idma_0:
	mr	r5, r11
	lis	r6, 0xff
	ori	r6, r6, 0xffff
	ori	r5, r5, CHANNEL0_DMA_BYTE_COUNT
1:	lwbrx	r4, 0, (r5)
	and.	r4, r4, r6
	bne	1b

	blr

	/* this turns off channel 0 of the idma engine */
stop_idma_engine_0:
	/* shut off the DMA engine */
	li	r5, 0
	mr	r6, r11
	ori	r6, r6, CHANNEL0CONTROL
	stwbrx	r5, 0, (r6)

	blr
#endif

#ifdef CONFIG_SYS_BOARD_ASM_INIT
	/* NOTE: trashes r3-r7 */
	.globl board_asm_init
board_asm_init:
	/* just move the GT registers to where they belong */
	lis	r3, CONFIG_SYS_DFL_GT_REGS@h
	ori	r3, r3, CONFIG_SYS_DFL_GT_REGS@l
	lis	r4, CONFIG_SYS_GT_REGS@h
	ori	r4, r4, CONFIG_SYS_GT_REGS@l
	li	r5, INTERNAL_SPACE_DECODE

	/* test to see if we've already moved */
	lwbrx	r6, r5, r4
	andi.	r6, r6, 0xffff
	/* check loading of R7 is: 0x0F80 should: 0xf800: DONE */
/*	rlwinm	r7, r4, 8, 16, 31
	rlwinm	r7, r4, 12, 16, 31	*/ /* original */
	rlwinm	r7, r4, 16, 16, 31
	/* -----------------------------------------------------*/
	cmp	cr0, r7, r6
	beqlr

	/* nope, have to move the registers */
	lwbrx	r6, r5, r3
	andis.	r6, r6, 0xffff
	or	r6, r6, r7
	stwbrx	r6, r5, r3

	/* now, poll for the change */
1:	lwbrx	r7, r5, r4
	cmp	cr0, r7, r6
	bne	1b

	/* done! */
	blr
#endif

/* For use of the debug LEDs */
	.global led_on0_relocated
led_on0_relocated:
	xor	r21, r21, r21
	xor	r18, r18, r18
	lis	r18, 0xFC80
	ori	r18, r18, 0x8000
	stw	r21, 0x0(r18)
/*	  stw	  r18, 0x0(r18) */
	sync
	blr

	.global led_off0_relocated
led_off0_relocated:
	xor	r21, r21, r21
	xor	r18, r18, r18
	lis	r18, 0xFC81
	ori	r18, r18, 0x4000
	stw	r21, 0x0(r18)
/*	  stw	  r18, 0x0(r18) */
	sync
	blr

	.global led_on0
led_on0:
	xor	r18, r18, r18
	lis	r18, 0x1c80
	ori	r18, r18, 0x8000
	stw	r18, 0x0(r18)
	sync
	blr

	.global led_off0
led_off0:
	xor	r18, r18, r18
	lis	r18, 0x1c81
	ori	r18, r18, 0x4000
	stw	r18, 0x0(r18)
	sync
	blr

	.global led_on1
led_on1:
	xor	r18, r18, r18
	lis	r18, 0x1c80
	ori	r18, r18, 0xc000
	stw	r18, 0x0(r18)
	sync
	blr

	.global led_off1
led_off1:
	xor	r18, r18, r18
	lis	r18, 0x1c81
	ori	r18, r18, 0x8000
	stw	r18, 0x0(r18)
	sync
	blr

	.global led_on2
led_on2:
	xor	r18, r18, r18
	lis	r18, 0x1c81
	ori	r18, r18, 0x0000
	stw	r18, 0x0(r18)
	sync
	blr

	.global led_off2
led_off2:
	xor	r18, r18, r18
	lis	r18, 0x1c81
	ori	r18, r18, 0xc000
	stw	r18, 0x0(r18)
	sync
	blr
OpenPOWER on IntegriCloud