Subversion Repositories freemyipod

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
973 user890104 1
@
2
@
3
@    emCORE Loader for iPod Nano 4G
4
@
5
@    Copyright 2011 TheSeven, Farthen
6
@
7
@
8
@    This file is part of emCORE.
9
@
10
@    emCORE is free software: you can redistribute it and/or
11
@    modify it under the terms of the GNU General Public License as
12
@    published by the Free Software Foundation, either version 2 of the
13
@    License, or (at your option) any later version.
14
@
15
@    emCORE is distributed in the hope that it will be useful,
16
@    but WITHOUT ANY WARRANTY; without even the implied warranty of
17
@    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18
@    See the GNU General Public License for more details.
19
@
20
@    You should have received a copy of the GNU General Public License along
21
@    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
22
@
23
@
24
 
25
 
26
#include "build/version.h"
27
 
28
 
29
.global _start
30
_start:
31
	msr	cpsr_c, #0xd3
32
	mrc	p15, 0, r0,c1,c0
33
	bic	r0, r0, #1
34
	mcr	p15, 0, r0,c1,c0 @ disable mmu
35
 
36
	mov	lr, #0
37
	adr	sp, values1
38
	mcr	p15, 0, lr,c7,c14,0 @ clean & invalidate data cache
39
	mcr	p15, 0, lr,c7,c10,4 @ drain write buffer
40
	mcr	p15, 0, lr,c7,c5    @ invalidate instruction cache
41
	mcr	p15, 0, lr,c7,c5,4  @ flush prefetch buffer
42
	mcr	p15, 0, lr,c8,c7    @ invalidate all unlocked entries in the TLB
43
	mcr	p15, 0, lr,c13,c0,0 @ disable context id register
44
 
45
 
46
.macro block0_constpool    @ Block 0 (MMU, DMA) register map:
47
                           @ R0: Unused
48
                           @ R1: Unused
49
                           @ R2: Unused
50
                           @ R3: Scratchpad
51
	.word	0x00000FFF @ R4: DMA maximum transfer size
52
	.word	0x00012C00 @ R5: LCD framebuffer pixel count
53
	.word	0x22006800 @ R6: LCD framebuffer address
54
	.word	0x38300040 @ R7: LCD data port address
55
	.word	0x2202D000 @ R8: LCD DMA linked list address
56
	.word	0x74240000 @ R9: LCD DMA channel settings
57
	.word	0x0005187D @ R10: CP15r1
58
	.word	0x2202C000 @ R11: First level page table
59
	.word	0x00000C1E @ R12: Default segment flags
60
                           @ R13: Constant pool pointer
61
.endm                      @ R14: 0
62
 
63
	ldmia	sp!, {r4-r12}
64
	mcr	p15, 0, r11,c2,c0 @ set first level translation table
65
	mov	r3, #-1
66
	mcr	p15, 0, r3,c3,c0 @ disable domain access control                  @ R3: Unused
67
	orr	r0, r12, #0x22000000
68
	str	r0, [r11], #4
69
	add	r12, r12, #0x00100000
70
mmuloop:
71
	str	r12, [r11], #4
72
	add	r12, r12, #0x00100000
73
	cmp	r12, #0x38000000
74
	biccs	r12, r12, #0xc
75
	tst	r12, #0x40000000
76
	beq	mmuloop
77
                                                                                  @ R11: LCD DMA descriptor head
78
                                                                                  @ R12: Unused
79
	mcr	p15, 0, r10,c1,c0                                                 @ R10: Unused
80
 
81
dmaloop:
82
	add	r8, r8, #0x10
83
	bic	r9, r9, r4
84
	cmp	r4, r5
85
	movcs	r4, r5
86
	movcs	r8, #0
87
	orr	r9, r9, r4
88
	stmia	r11!, {r6-r9}
89
	add	r6, r6, r4,lsl#1
90
	subs	r5, r5, r4
91
	bne	dmaloop
92
 
93
.macro block1_constpool    @ Block 1 (SYSCON) register map:
94
	.word	0x000327E5 @ R0: PWRCON(0)
95
	.word	0xFE2BED6D @ R1: PWRCON(1)
96
	.word	0x00DCF779 @ R2: PWRCON(4)
97
	.word	0x003E3E00 @ R3
98
	.word	0x06008501 @ R4
99
	.word	0x00009DBC @ R5
100
	.word	0x00404040 @ R6
101
	.word	0x40001000 @ R7
102
	.word	0x80008000 @ R8
103
	.word	0x38501000 @ R9
104
	.word	0xE02BED4D @ R10: PWRCON(1) during timer setup
105
	.word	0x001CF700 @ R11: PWRCON(4) during timer setup
106
	.word	0x3C500000 @ R12: SYSCON base address
107
                           @ R13: Constant pool pointer
108
.endm                      @ R14: 0
109
 
110
	ldmia	sp!, {r0-r12}
111
	str	r0, [r12,#0x48]  @ PWRCON0 ...                                    @ R0: Scratchpad
112
	str	r1, [r12,#0x4c]
113
	mov	r0, #0x73
114
	str	r0, [r12,#0x58]
115
	mov	r0, #0xff
116
	str	r0, [r12,#0x68]
117
	str	r2, [r12,#0x6c]  @ ... PWRCON4
118
	str	lr, [r12]
119
sysconwait1:
120
	ldr	r0, [r12]
121
	tst	r0, #0xf
122
	bne	sysconwait1      @ while ([SYSCON] & 0xf)
123
 
124
	str	lr, [r12,#0x04]
125
sysconwait2:
126
	ldr	r0, [r12,#0x04]
127
	tst	r0, r3
128
	bne	sysconwait2      @ while ([SYSCON+4] & 0x003E3E00)
129
 
130
	mov	r0, #0x7
131
	str	r0, [r12,#0x44]
132
	str	lr, [r12,#0x44]
133
	str	lr, [r12,#0x3c]
134
	str	r4, [r12,#0x20]                                                   @ R4: Scratchpad
135
	str	r5, [r12,#0x30]
136
	mov	r5, #1                                                            @ R5: 1
137
	str	r5, [r12,#0x44]
138
	orr	r4, r0, #0x10000
139
	str	r4, [r12,#0x44]
140
sysconwait3:
141
	ldr	r4, [r12,#0x40]
142
	tst	r4, #0x1
143
	beq	sysconwait3      @ while (!([SYSCON+0x40] & 1))
144
 
145
	str	r6, [r12,#0x04]                                                   @ R6: Unused
146
	add	r3, r3, #0x3e                                                     @ R3: 0x003E3E3E
147
sysconwait4:
148
	ldr	r4, [r12,#0x04]
149
	tst	r4, r3                                                            @ R3: Unused
150
	bne	sysconwait4
151
 
152
	str	r7, [r12]                                                         @ R7: Unused
153
sysconwait5:
154
	ldr	r2, [r12]
155
	tst	r4, #0xf
156
	bne	sysconwait5
157
 
158
	str	r8, [r12,#0x08]
159
	orr	r4, r8, r8,lsr#1                                                  @ R8: Unused
160
	str	r4, [r12,#0x0c]
161
	mov	r4, #0xc000
162
	str	r4, [r12,#0x10]
163
	mov	r4, #0x8000
164
	str	r4, [r12,#0x14]
165
	str	r4, [r12,#0x70]
166
	mov	r4, #2
167
	str	r4, [r9]                                                          @ R9: Unused
168
	mov	r0, #0x10                                                         @ R5: 0x10
169
 
170
                           @ Block 2 (TIMER) register map:
171
                           @ R0: 1
172
                           @ R1: PWRCON(1)
173
                           @ R2: PWRCON(4)
174
                           @ R3: Scratchpad
175
                           @ R4: Scratchpad
176
                           @ R5: 0x10
177
                           @ R6: Unused
178
                           @ R7: Unused
179
                           @ R8: Unused
180
                           @ R9: Unused
181
                           @ R10: PWRCON(1) during timer setup
182
                           @ R11: PWRCON(4) during timer setup
183
                           @ R12: SYSCON base address
184
                           @ R13: Constant pool pointer
185
                           @ R14: 0
186
 
187
	str	r10, [r12,#0x4c]     @ PWRCON(1) for timer setup                  @ R10: Unused
188
	mov	r4, #0x13
189
	str	r4, [r12,#0x58]             @ PWRCON(2) for timer setup
190
	str	r11, [r12,#0x6c]     @ PWRCON(4) for timer setup                  @ R11: Unused
191
	orr     r11, r12, #0x00200000                                             @ R11: TIMER base address
192
	str	r0, [r11,#0x4]       @ TACMD = 0x10
193
	str	r0, [r11,#0x24]      @ TBCMD = 0x10
194
	str	r0, [r11,#0x44]      @ TCCMD = 0x10
195
	str	r0, [r11,#0x64]      @ TDCMD = 0x10
196
	mov	r3, #0x40
197
	str	r3, [r11,#0xa0]      @ TECON = 0x40
198
	mov	r3, #0xb
199
	str	r3, [r11,#0xb0]      @ TEPRE = 0xb
200
	mov	r4, #-1                                                           @ R4: -1
201
	str	r4, [r11,#0xa8]      @ TEDATA0 = 0xFFFFFFFF
202
	mov	r3, #0x3
203
	str	r3, [r11,#0xa4]      @ TECMD = 0x3
204
	str	r0, [r11,#0xc4]      @ TFCMD = 0x10
205
	str	r0, [r11,#0xe4]      @ TGCMD = 0x10
206
	str	r0, [r11,#0x104]     @ THCMD = 0x10
207
	str	r4, [r11,#0x118]     @ THCMD = 0xFFFFFFFF
208
	str	r1, [r12,#0x4c]      @ PWRCON(1)                                  @ R1: Unused
209
	mov	r3, #0x73
210
	str	r3, [r12,#0x58]      @ PWRCON(2)
211
	str	r2, [r12,#0x6c]      @ PWRCON(4)                                  @ R2: Unused
212
	orr	r10, r11, #0x00800000                                             @ R10: GPIO base address
213
 
214
                           @ Block 3 (GPIO) register map:
215
                           @ R0: Unused
216
                           @ R1: Unused
217
                           @ R2: Unused
218
                           @ R3: Scratchpad
219
                           @ R4: -1
220
                           @ R5: 1
221
                           @ R6: Unused
222
                           @ R7: Unused
223
                           @ R8: Unused
224
                           @ R9: Unused
225
                           @ R10: GPIO base address
226
                           @ R11: TIMER base address
227
                           @ R12: SYSCON base address
228
                           @ R13: Constant pool pointer
229
                           @ R14: 0
230
 
231
.macro gpio_initdata
232
	.word	0x3202EEEE @ PCON0
233
	.word	0xE0EE2253 @ PCON1
234
	.word	0x2223EEEE @ PCON2
235
	.word	0x33333332 @ PCON3
236
	.word	0xFF333E33 @ PCON4
237
	.word	0xE0FEE200 @ PCON5
238
	.word	0x2222222E @ PCON6
239
	.word	0x22222222 @ PCON7
240
	.word	0xEEEEEEE2 @ PCON8
241
	.word	0xEEE0EEEE @ PCON9
242
	.word	0x2EEEEEEE @ PCONA
243
	.word	0xEEEE0222 @ PCONB
244
	.word	0xEEEEE00E @ PCONC
245
	.word	0xEEEEEEEE @ PCOND
246
	.word	0xEEEEEEEE @ PCONE
247
.endm
248
 
249
	ldr	r3, [sp], #0x4
250
	str	r3, [r10], #0xc                                                   @ R10: PCONx iterator
251
	mov	r3, #0x20
252
	str	r3, [r10], #0x4     @ PCON0 + 0xc = 0x20
253
	mov	r3, #0x40
254
	str	r3, [r10], #0x10    @ PCON0 + 0x10 = 0x40
255
	add	r9, r10, #0x1a0                                                   @ R9: Iterator limit
256
gpioloop1:
257
	ldr	r3, [sp], #0x4
258
	str	r3, [r10], #0xc
259
	str	lr, [r10], #0x4     @ PCON + 0xc = 0
260
	str	lr, [r10], #0x10    @ PCON + 0x10 = 0
261
	cmp	r10, r9
262
	bls	gpioloop1
263
                                                                                  @ R10: 0x3CF001E0
264
	ldr	r3, [r10,#0x1a8]
265
	bic	r3, r3, #2
266
	orr	r3, r3, #1
267
	str	r3, [r10,#0x1a8]
268
	sub	r8, r11, #0x00300000                                              @ R8: 0x39700000 (iterator)
269
	mov	r9, #6                                                            @ R9: Iterations remaining
270
gpioloop2:
271
	str	r14, [r8,#0x80]
272
	str	r4, [r8,#0xa0]
273
	str	r14, [r8,#0xc0]
274
	str	r14, [r8,#0xe0]
275
	add	r8, r8, #4
276
	subs	r9, r9, #1
277
	bne	gpioloop2
278
                                                                                  @ R9: 0
279
	ldr	r8, [r10,#-0x180]                                                 @ R8: PCON3 backup
280
	and	r3, r8, #0xff
281
	str	r3, [r10,#-0x180]   @ *PCON3 &= 0xff
282
	mov	r0, #0x3e8                                                        @ R0: Scratchpad
283
	bl	udelay                                                            @ R14: Return address
284
	ldr	r3, [r10,#-0x17c]
285
	and	r3, r3, #0xfc
286
	mov	r6, r3, lsr #0x2                                                  @ R6: Data for first PMU access
287
	str	r8, [r10,#-0x180]
288
	bic	r10, r11, #0x00100000                                             @ R10: I2C base address
289
 
290
                           @ Block 4 (I2C) register map:
291
                           @ R0: Scratchpad
292
                           @ R1: Scratchpad
293
                           @ R2: Unused
294
                           @ R3: Unused
295
                           @ R4: -1
296
                           @ R5: 1
297
                           @ R6: Data for first PMU access
298
                           @ R7: Unused
299
                           @ R8: Unused
300
                           @ R9: 0
301
                           @ R10: I2C base address
302
                           @ R11: TIMER base address
303
                           @ R12: SYSCON base address
304
                           @ R13: Constant pool pointer
305
                           @ R14: Return address / Scratchpad
306
 
307
	bl	i2cwaitrdy
308
	mov	r1, #0x40
309
	str	r1, [r10,#0x08]
310
	bl	i2cwaitrdy
311
	str	r5, [r10,#0x14]
312
	bl	i2cwaitrdy
313
	str	r9, [r10,#0x18]
314
	bl	i2cwaitrdy
315
	mov	r0, #0x80
316
	str	r0, [r10,#0x04]
317
	bl	i2cwaitrdy
318
	str	r9, [r10]
319
	bl	i2cwaitrdy
320
	str	r9, [r10,#0x04]
321
	bl	i2cwaitrdy
322
	str	r1, [r10,#0x0c]
323
	bl	i2cwaitrdy
324
	orr	r0, r5, #0x180
325
	str	r0, [r10]
326
	bl	i2cwaitrdy
327
	mov	r0, #0x10
328
	str	r0, [r10,#0x04]
329
	bl	i2cwaitrdy
330
 
331
                           @ Block 5 (PMU) register map:
332
                           @ R0: Address / Scratchpad (trashed by pmubatch)
333
                           @ R1: Data / Scratchpad (trashed by pmubatch)
334
                           @ R2: Scratchpad (set to 0xb7 by pmu accesses)
335
                           @ R3: Scratchpad (set to 0x10 by pmu accesses)
336
                           @ R4: Scratchpad (trashed by pmu accesses)
337
                           @ R5: 1
338
                           @ R6: Data for first PMU access
339
                           @ R7: Scratchpad (trashed by pmubatch)
340
                           @ R8: Used to store warmboot flag
341
                           @ R9: 0 / pmubatch transfer count (reset to 0 by pmubatch)
342
                           @ R10: I2C base address
343
                           @ R11: TIMER base address
344
                           @ R12: SYSCON base address
345
                           @ R13: Constant pool / pmubatch data pointer
346
                           @ R14: Return address / Scratchpad
347
 
348
	mov	r0, #0x7f
349
	mov	r1, r6
350
	bl	pmuwrite
351
	mov	r0, #0x02
352
	bl	pmuread
353
	ands	r8, r1, #0x80                                                     @ R8: Warmboot flag
354
	beq	pmu_coldboot
355
	mov	r1, #0x80
356
	bl	pmuwrite
357
pmu_coldboot:
358
.macro pmu_batch_1
359
pmu_batch_1_begin:
360
	.byte	0x14, 0x13
361
	.byte	0x15, 0x0d
362
	.byte	0x0b, 0x22
363
pmu_batch_1_end:
364
.endm
365
	mov	r9, #(pmu_batch_1_end - pmu_batch_1_begin) / 2
366
	bl	pmubatch
367
	tst	r6, #1                                                            @ R6: Unused
368
	beq	pmu_skip
369
	mov	r0, #0x0d
370
	bl	pmuread
371
	and	r1, r1, #0xdf
372
	bl	pmuwrite
373
pmu_skip:
374
.macro pmu_batch_2
375
pmu_batch_2_begin:
376
	.byte	0x1f, 0x14
377
	.byte	0x1a, 0xb2
378
	.byte	0x1a, 0xb2
379
	.byte	0x19, 0x14
380
	.byte	0x21, 0x06
381
	.byte	0x1d, 0x12
382
pmu_batch_2_end:
383
.endm
384
	mov	r9, #(pmu_batch_2_end - pmu_batch_2_begin) / 2
385
	bl	pmubatch
386
	mov	r0, #0x10
387
	bl	pmuread
388
	bic	r1, r1, #0x80
389
	orr	r1, r1, #0x60
390
	bl	pmuwrite
391
.macro pmu_batch_3
392
pmu_batch_3_begin:
393
	.byte	0x44, 0x72
394
pmu_batch_3_end:
395
.endm
396
	mov	r9, #(pmu_batch_3_end - pmu_batch_3_begin) / 2
397
	bl	pmubatch
398
	mov	r0, #0x40
399
	bl	pmuread
400
	orr	r1, r1, #0x40
401
	bl	pmuwrite
402
	mov	r0, #0x33
403
	bl	pmuread
404
	and	r1, r1, #0x03
405
	orr	r1, r1, #0x50
406
	bl	pmuwrite
407
	mov	r0, #0x34
408
	bl	pmuread
409
	and	r1, r1, #0x80
410
	orr	r1, r1, #0x54
411
	bl	pmuwrite
412
.macro pmu_batch_4
413
pmu_batch_4_begin:
414
	.byte	0x22, 0x00
415
	.byte	0x07, 0x50
416
	.byte	0x08, 0xfe
417
	.byte	0x09, 0x2b
418
	.byte	0x01, 0xff
419
	.byte	0x02, 0xff
420
	.byte	0x03, 0xff
421
pmu_batch_4_end:
422
.endm
423
	mov	r9, #(pmu_batch_4_end - pmu_batch_4_begin) / 2
424
	bl	pmubatch
425
	cmp	r8, #0
426
	bne	pmu_warmboot
427
	mov	r0, #0x30
428
	mov	r1, #0x64
429
	bl	pmuwrite
430
pmu_warmboot:
431
	mov	r0, #0x31
432
	bl	pmuread
433
	bic	r1, r1, #0x01
434
	bl	pmuwrite
435
.macro pmu_batch_5
436
pmu_batch_5_begin:
437
	.byte	0x0a, 0x70
438
	.byte	0x13, 0x02
439
pmu_batch_5_end:
440
.endm
441
	mov	r9, #(pmu_batch_5_end - pmu_batch_5_begin) / 2
442
	bl	pmubatch
443
 
444
	orr	lr, r11, #0x00800000                                              @ R14: GPIO base address
445
	str	r9, [lr,#0x384]
446
	orr	lr, r11, #0x01000000                                              @ R14: MIU base address
447
	str	r5, [lr]
448
	ldrh	r0, [sp], #2
449
	str	r0, [lr,#0x100]
450
	mov	r0, #0xff
451
	str	r0, [lr,#0x11c]
452
	str	r0, [lr,#0x120]
453
 
454
.macro block6_constpool           @ Block 6 (SDRAM) register map:
455
	.hword	0x1030
456
	.word	0x008AAC25 @ R0
457
	.word	0x050D67E5 @ R1
458
	.word	0x0002000B @ R2
459
	.word	0x0003B3B2 @ R3
460
	.word	0xFF53B3B0 @ R4
461
	.word	0x00008040 @ R5
462
	.word	0x8000100F @ R6: For LCD init at end of block
463
	.word	0x41000c20 @ R7: For LCD init at end of block
464
                           @ R8: Warmboot flag
465
                           @ R9: 0
466
                           @ R10: I2C base address
467
                           @ R11: TIMER base address
468
                           @ R12: SYSCON base address
469
                           @ R13: Constant pool pointer
470
.endm                      @ R14: MIU base address
471
 
472
	ldmia	sp!, {r0-r7}
473
	str	r0, [lr,#0x114]                                                   @ R0: Unused
474
	str	r1, [lr,#0x124]                                                   @ R1: Unused
475
	mov	r0, #8                                                            @ R0: Scratchpad
476
	str	r0, [lr,#0x118]
477
	str	r2, [lr,#0x108]
478
	mov	r0, #4
479
	str	r0, [lr,#0x148]
480
	str	r9, [lr,#0x14c]
481
	str	r3, [lr,#0x140]
482
miu_wait1:
483
	ldr	r0, [lr,#0x140]
484
	tst	r0, #2
485
	beq	miu_wait1
486
	add	r0, r3, #1                                                        @ R3: Unused
487
	str	r0, [lr,#0x140]
488
miu_wait2:
489
	ldr	r0, [lr,#0x144]
490
	mvn	r0, r0
491
	tst	r0, #3
492
	bne	miu_wait2
493
	ldr	r1, [lr,#0x144]                                                   @ R1: Scratchpad
494
	mov	r0, #0x0ff00000
495
	and	r0, r0, r1, lsl#2
496
	add	r0, r0, r4                                                        @ R4: Unused
497
	str	r0, [lr,#0x140]
498
	mov	r0, #0x10
499
	str	r0, [lr,#0x150]
500
	cmp	r8, #0                                                            @ R8: Unused
501
	sub	r8, r10, #0x04300000                                              @ R8: LCD base address
502
	str	r6, [r12,#0x08]                                                   @ R6: Unused
503
	str	r7, [r8]                                                          @ R7: Unused
504
	mov	r0, #0x11
505
	str	r0, [r8,#0x20]
506
	mov	r3, #0x33                                                         @ R3: 0x33
507
	beq	miu_coldboot
508
	str	r0, [lr,#0x104]
509
	b	miu_common
510
miu_coldboot:
511
	str	r3, [lr,#0x104]
512
	orr	r0, r3, #0x200
513
	str	r0, [lr,#0x104]
514
miu_wait3:
515
	ldr	r0, [lr,#0x104]
516
	tst	r0, #0x110000
517
	bne	miu_wait3
518
	str	r3, [lr,#0x104]
519
	str	r3, [lr,#0x104]
520
	str	r3, [lr,#0x104]
521
	orr	r1, r3, #0x300
522
	str	r1, [lr,#0x104]
523
miu_wait4:
524
	ldr	r0, [lr,#0x104]
525
	tst	r0, #0x110000
526
	bne	miu_wait4
527
	str	r3, [lr,#0x104]
528
	str	r3, [lr,#0x104]
529
	str	r3, [lr,#0x104]
530
	str	r1, [lr,#0x104]
531
miu_wait5:
532
	ldr	r0, [lr,#0x104]
533
	tst	r0, #0x110000
534
	bne	miu_wait5
535
	str	r3, [lr,#0x104]
536
	str	r3, [lr,#0x104]
537
	str	r3, [lr,#0x104]
538
	str	r3, [lr,#0x110]
539
	orr	r0, r3, #0x100
540
	str	r0, [lr,#0x104]
541
miu_wait6:
542
	ldr	r0, [lr,#0x104]
543
	tst	r0, #0x110000
544
	bne	miu_wait6
545
	str	r3, [lr,#0x104]
546
	str	r3, [lr,#0x104]
547
	str	r3, [lr,#0x104]
548
	str	r5, [lr,#0x110]                                                   @ R5: Unused
549
	str	r1, [lr,#0x104]
550
miu_wait7:
551
	ldr	r0, [lr,#0x104]
552
	tst	r0, #0x110000
553
	bne	miu_wait7
554
	str	r3, [lr,#0x104]
555
	str	r3, [lr,#0x104]
556
miu_common:
557
	str	r3, [lr,#0x104]                                                   @ R3: Unused
558
	mov	r0, #0x40
559
	str	r0, [lr,#0x10c]
560
	ldr	r0, [lr,#0x100]
561
	orr	r0, r0, #0x9100000
562
	str	r0, [lr,#0x100]
563
	mov	r0, #0x19
564
	str	r0, [lr,#0x11c]
565
	mov	r0, #1
566
	str	r0, [lr,#0x120]
567
	orr	r1, r2, #0x1000                                                   @ R2: Unused
568
	str	r1, [lr,#0x108]
569
	str	r0, [lr,#0x08]
570
	mov	r1, #0x3e000000
571
	mov	r0, #0x1f
572
	str	r0, [r1,#0x08]
573
 
574
                           @ Block 7 (LCD) register map:
575
                           @ R0: Cmd/Data to be written / Scratchpad
576
                           @ R1: Scratchpad
577
                           @ R2: Scratchpad
578
                           @ R3: Scratchpad
579
                           @ R4: Scratchpad
580
                           @ R5: Scratchpad
581
                           @ R6: Unused
582
                           @ R7: Unused
583
                           @ R8: LCD base address
584
                           @ R9: 0
585
                           @ R10: I2C base address
586
                           @ R11: TIMER base address
587
                           @ R12: SYSCON base address
588
                           @ R13: LCD init script pointer / Scratchpad
589
                           @ R14: Return address / Scratchpad
590
 
591
.macro lcd_sequences
592
lcd_sequences_begin:
593
	.word	lcd_sequence_c4 - lcd_sequences_begin
594
	.word	lcd_sequence_d5 - lcd_sequences_begin
595
	.word	lcd_sequence_e6 - lcd_sequences_begin
596
	.word	lcd_sequence_b3 - lcd_sequences_begin
597
lcd_sequence_b3:
598
.byte 0x01, 0x11, 0xf8, 0x01, 0x13, 0x01, 0x29, 0x80
599
	.byte	0x01, 0x11
600
	.byte	0xf8
601
	.byte	0x02, 0xfe, 0x00
602
	.byte	0x02, 0xef, 0x80
603
	.byte	0x02, 0xc0, 0x0c
604
	.byte	0x02, 0xc1, 0x03
605
	.byte	0x03, 0xc2, 0x12, 0x00
606
	.byte	0x03, 0xc3, 0x12, 0x00
607
	.byte	0x03, 0xc4, 0x12, 0x00
608
	.byte	0x03, 0xc5, 0x3a, 0x3e
609
	.byte	0x03, 0xb1, 0x6a, 0x15
610
	.byte	0x03, 0xb2, 0x5f, 0x3f
611
	.byte	0x03, 0xb3, 0x5f, 0x3f
612
	.byte	0x02, 0xb4, 0x02
613
	.byte	0x03, 0xb6, 0x12, 0x02
614
	.byte	0x02, 0x35, 0x00
615
	.byte	0x02, 0x26, 0x10
616
	.byte	0x0c, 0xe0, 0x0f, 0x42, 0x24, 0x01, 0x00, 0x02, 0xa6, 0x98, 0x05, 0x04, 0x15
617
	.byte	0x0c, 0xe1, 0x00, 0x21, 0x44, 0x02, 0x0f, 0x05, 0x89, 0x6a, 0x02, 0x15, 0x04
618
	.byte	0x0c, 0xe2, 0x7e, 0x04, 0x43, 0x40, 0x00, 0x02, 0x13, 0x00, 0x00, 0x01, 0x0b
619
	.byte	0x0c, 0xe3, 0x40, 0x40, 0x03, 0x74, 0x0e, 0x00, 0x00, 0x31, 0x02, 0x0b, 0x01
620
	.byte	0x0c, 0xe4, 0x5a, 0x43, 0x67, 0x56, 0x00, 0x02, 0x67, 0x72, 0x00, 0x05, 0x12
621
	.byte	0x0c, 0xe5, 0x50, 0x66, 0x47, 0x53, 0x0a, 0x00, 0x27, 0x76, 0x02, 0x12, 0x05
622
	.byte	0x02, 0x3a, 0x06
623
	.byte	0x01, 0x13
624
	.byte	0x01, 0x29
625
	.byte	0x80
626
lcd_sequence_c4:
627
	.byte	0x01, 0x01
628
	.byte	0x85
629
	.byte	0x02, 0xc0, 0x00
630
	.byte	0x02, 0xc1, 0x03
631
	.byte	0x02, 0xc2, 0x34
632
	.byte	0x03, 0xc3, 0x72, 0x03
633
	.byte	0x03, 0xc4, 0x73, 0x03
634
	.byte	0x03, 0xc5, 0x3c, 0x3c
635
	.byte	0x02, 0xfe, 0x00
636
	.byte	0x03, 0xb1, 0x6a, 0x15
637
	.byte	0x03, 0xb2, 0x6a, 0x15
638
	.byte	0x03, 0xb3, 0x6a, 0x15
639
	.byte	0x02, 0xb4, 0x02
640
	.byte	0x03, 0xb6, 0x12, 0x02
641
	.byte	0x02, 0x35, 0x00
642
	.byte	0x02, 0x26, 0x10
643
	.byte	0x0c, 0xe0, 0x77, 0x52, 0x76, 0x53, 0x03, 0x03, 0x57, 0x42, 0x10, 0x18, 0x09
644
	.byte	0x0c, 0xe1, 0x0d, 0x00, 0x23, 0x66, 0x0f, 0x15, 0x4d, 0x85, 0x08, 0x02, 0x10
645
	.byte	0x0c, 0xe2, 0x39, 0x60, 0x77, 0x05, 0x03, 0x07, 0x96, 0x64, 0x0d, 0x1a, 0x0a
646
	.byte	0x0c, 0xe3, 0x3f, 0x10, 0x16, 0x44, 0x0e, 0x04, 0x6c, 0x44, 0x04, 0x03, 0x0b
647
	.byte	0x0c, 0xe4, 0x00, 0x61, 0x77, 0x04, 0x02, 0x04, 0x72, 0x32, 0x09, 0x19, 0x06
648
	.byte	0x0c, 0xe5, 0x4f, 0x42, 0x27, 0x67, 0x0f, 0x02, 0x26, 0x33, 0x01, 0x03, 0x09
649
	.byte	0x02, 0x36, 0x00
650
	.byte	0x01, 0x11
651
	.byte	0x01, 0x29
652
	.byte	0x80
653
lcd_sequence_d5:
654
.byte 0x01, 0x01, 0x85, 0x01, 0x11, 0x01, 0x29, 0x80
655
	.byte	0x02, 0xfe, 0x00
656
	.byte	0x02, 0xc0, 0x01
657
	.byte	0x02, 0xc1, 0x01
658
	.byte	0x03, 0xc2, 0x03, 0x00
659
	.byte	0x03, 0xc3, 0x01, 0x00
660
	.byte	0x03, 0xc4, 0x03, 0x00
661
	.byte	0x03, 0xc5, 0x34, 0x34
662
	.byte	0x02, 0xc7, 0x00
663
	.byte	0x03, 0xb1, 0x6d, 0x15
664
	.byte	0x03, 0xb2, 0x6d, 0x15
665
	.byte	0x03, 0xb3, 0x6d, 0x15
666
	.byte	0x02, 0xb4, 0x03
667
	.byte	0x03, 0xb6, 0x11, 0x02
668
	.byte	0x02, 0x35, 0x00
669
	.byte	0x02, 0x26, 0x10
670
	.byte	0x0c, 0xe0, 0x23, 0x42, 0x20, 0x42, 0x0e, 0x01, 0xf5, 0xeb, 0x1e, 0x05, 0x18
671
	.byte	0x0c, 0xe1, 0x5f, 0x22, 0x36, 0x21, 0x03, 0x1e, 0xfe, 0x7b, 0x02, 0x07, 0x18
672
	.byte	0x0c, 0xe2, 0x5f, 0x34, 0x53, 0x77, 0x0a, 0x00, 0x70, 0xf4, 0x14, 0x06, 0x0f
673
	.byte	0x0c, 0xe3, 0x0f, 0x23, 0x31, 0x54, 0x0f, 0x0b, 0x8e, 0x08, 0x00, 0x05, 0x15
674
	.byte	0x0c, 0xe4, 0x5f, 0x33, 0x42, 0x14, 0x0e, 0x04, 0xa6, 0xf7, 0x0e, 0x00, 0x14
675
	.byte	0x0c, 0xe5, 0x0c, 0x43, 0x44, 0x44, 0x0d, 0x0d, 0x7f, 0x39, 0x03, 0x02, 0x10
676
	.byte	0x02, 0x3a, 0x66
677
	.byte	0x02, 0x36, 0x00
678
	.byte	0x01, 0x11
679
	.byte	0x01, 0x29
680
	.byte	0x80
681
lcd_sequence_e6:
682
.byte 0x01, 0x11, 0xf8, 0x01, 0x13, 0x01, 0x29, 0x80
683
	.byte	0x01, 0x11
684
	.byte	0xf8
685
	.byte	0x02, 0xfe, 0x00
686
	.byte	0x02, 0xef, 0x80
687
	.byte	0x02, 0xc0, 0x13
688
	.byte	0x02, 0xc1, 0x03
689
	.byte	0x03, 0xc2, 0x12, 0x00
690
	.byte	0x03, 0xc3, 0x12, 0x00
691
	.byte	0x03, 0xc4, 0x12, 0x00
692
	.byte	0x03, 0xc5, 0x2a, 0x3c
693
	.byte	0x03, 0xb1, 0x6a, 0x15
694
	.byte	0x03, 0xb2, 0x5f, 0x3f
695
	.byte	0x03, 0xb3, 0x5f, 0x3f
696
	.byte	0x02, 0xb4, 0x02
697
	.byte	0x03, 0xb6, 0x12, 0x02
698
	.byte	0x02, 0x35, 0x00
699
	.byte	0x02, 0x26, 0x10
700
	.byte	0x0c, 0xe0, 0x0f, 0x53, 0x45, 0x07, 0x00, 0x00, 0xb9, 0xf6, 0x08, 0x04, 0x18
701
	.byte	0x0c, 0xe1, 0x00, 0x47, 0x55, 0x03, 0x0f, 0x08, 0x6f, 0x9b, 0x00, 0x18, 0x04
702
	.byte	0x0c, 0xe2, 0x7e, 0x03, 0x54, 0x75, 0x00, 0x00, 0x3a, 0x52, 0x03, 0x02, 0x10
703
	.byte	0x0c, 0xe3, 0x70, 0x55, 0x04, 0x73, 0x0e, 0x03, 0x25, 0xa3, 0x00, 0x10, 0x02
704
	.byte	0x0c, 0xe4, 0x1a, 0x72, 0x33, 0x76, 0x00, 0x00, 0xeb, 0x97, 0x03, 0x05, 0x17
705
	.byte	0x0c, 0xe5, 0x70, 0x36, 0x73, 0x12, 0x0a, 0x03, 0x79, 0xbe, 0x00, 0x17, 0x05
706
	.byte	0x02, 0x3a, 0x06
707
	.byte	0x01, 0x13
708
	.byte	0x01, 0x29
709
	.byte	0x80
710
lcd_sequences_end:
711
.endm
712
 
713
	mov	r0, #4
714
	bl	sendlcdc
715
	bl	readlcd
716
	bl	readlcd
717
	bl	readlcd
718
	and	r0, r0, #3
719
	ldr	r0, [sp,r0,lsl#2]
720
	add	sp, sp, r0
721
lcdloop:
722
	ldrb	r1, [sp], #1
723
	tst	r1, #0x80
724
	beq	lcddata
725
	bics	r1, r1, #0x80
726
	beq	lcddone
727
	mov	r0, r1,lsl#10
728
	bl	udelay
729
	b	lcdloop
730
lcddata:
731
	ldrb	r0, [sp], #1
732
	bl	sendlcdc
733
lcdbyte:
734
	subs	r1, r1, #1
735
	beq	lcdloop
736
	ldrb	r0, [sp], #1
737
	bl	sendlcdd
738
	b	lcdbyte
739
 
740
values1:
741
	block0_constpool
742
	block1_constpool
743
	gpio_initdata
744
	pmu_batch_1
745
	pmu_batch_2
746
	pmu_batch_3
747
	pmu_batch_4
748
	pmu_batch_5
749
	block6_constpool
750
	lcd_sequences
751
 
752
	.align	1
753
	.code	16
754
thumb_nrv2e_d8:
755
	mov r7,r2
756
        mov r4,#1; neg r5,r4 @ r5= -1 initial condition
757
        lsl r4,#31 @ 1<<31: refill next time
758
        mov r6,#5
759
        lsl r6,#8 @ 0x500 @ nrv2e M2_MAX_OFFSET
760
        b top_n2e
761
 
762
nrv2e_done:
763
	blx execfirmware
764
 
765
get1_n2e: @ In: Carry set [from adding 0x80000000 (1<<31) to itself]
766
        ldrb r4,[r0] @ zero-extend next byte
767
        adc r4,r4 @ double and insert CarryIn as low bit
768
        add r0,#1
769
        lsl r4,#24 @ move to top byte, and set CarryOut from old bit 8
770
        mov pc,lr @ return, stay in current (THUMB) mode
771
 
772
lit_n2e:
773
        ldrb r3,[r0]; add r0,#1
774
        strb r3,[r2]; add r2,#1
775
top_n2e:
776
        add r4,r4; mov lr,pc; beq get1_n2e; bcs lit_n2e
777
        mov r1,#1; b getoff_n2e
778
 
779
off_n2e:
780
        sub r1,#1
781
        add r4,r4; mov lr,pc; beq get1_n2e; adc r1,r1
782
getoff_n2e:
783
        add r4,r4; mov lr,pc; beq get1_n2e; adc r1,r1
784
        add r4,r4; mov lr,pc; beq get1_n2e; bcc off_n2e
785
 
786
        sub r3,r1,#3 @ set Carry
787
        mov r1,#0 @ Carry unaffected
788
        blo offprev_n2e @ r1 was 2; tests Carry only
789
        lsl r3,#8
790
        ldrb r5,[r0]; add r0,#1 @ low 7+1 r4
791
        orr r5,r3
792
        mvn r5,r5; beq nrv2e_done @ r5= ~r5
793
        asr r5,#1; bcs lenlast_n2e
794
        b lenmore_n2e
795
 
796
offprev_n2e:
797
        add r4,r4; mov lr,pc; beq get1_n2e; bcs lenlast_n2e
798
lenmore_n2e:
799
        mov r1,#1
800
        add r4,r4; mov lr,pc; beq get1_n2e; bcs lenlast_n2e
801
len_n2e:
802
        add r4,r4; mov lr,pc; beq get1_n2e; adc r1,r1
803
        add r4,r4; mov lr,pc; beq get1_n2e; bcc len_n2e
804
        add r1,#6-2
805
        b gotlen_n2e
806
 
807
lenlast_n2e:
808
        add r4,r4; mov lr,pc; beq get1_n2e; adc r1,r1 @ 0,1,2,3
809
        add r1,#2
810
gotlen_n2e: @ 'cmn': add the inputs, set condition codes, discard the sum
811
        cmn r6,r5; bcs near_n2e @ within M2_MAX_OFFSET
812
        add r1,#1 @ too far away, so minimum match length is 3
813
near_n2e:
814
        ldrb r3,[r2] @ force cacheline allocate
815
copy_n2e:
816
        ldrb r3,[r2,r5]
817
        strb r3,[r2]; add r2,#1
818
        sub r1,#1; bne copy_n2e
819
        b top_n2e
820
	.code	32
821
 
822
font:
823
	.byte	0, 0, 0, 0, 0
824
	.byte	0, 0, 95, 0, 0
825
	.byte	0, 7, 0, 7, 0
826
	.byte	20, 127, 20, 127, 20
827
	.byte	36, 42, 127, 42, 18
828
	.byte	35, 19, 8, 100, 98
829
	.byte	54, 73, 85, 34, 80
830
	.byte	5, 3, 0, 0, 0
831
	.byte	28, 34, 65, 0, 0
832
	.byte	0, 0, 65, 34, 28
833
	.byte	20, 8, 62, 8, 20
834
	.byte	8, 8, 62, 8, 8
835
	.byte	0, -96, 96, 0, 0
836
	.byte	8, 8, 8, 8, 8
837
	.byte	0, 96, 96, 0, 0
838
	.byte	32, 16, 8, 4, 2
839
	.byte	62, 81, 73, 69, 62
840
	.byte	0, 66, 127, 64, 0
841
	.byte	66, 97, 81, 73, 70
842
	.byte	33, 65, 69, 75, 49
843
	.byte	24, 20, 18, 127, 16
844
	.byte	39, 69, 69, 69, 57
845
	.byte	60, 74, 73, 73, 48
846
	.byte	1, 113, 9, 5, 3
847
	.byte	54, 73, 73, 73, 54
848
	.byte	6, 73, 73, 41, 30
849
	.byte	0, 54, 54, 0, 0
850
	.byte	0, 86, 54, 0, 0
851
	.byte	8, 20, 34, 65, 0
852
	.byte	20, 20, 20, 20, 20
853
	.byte	0, 65, 34, 20, 8
854
	.byte	2, 1, 81, 9, 6
855
	.byte	50, 73, 121, 65, 62
856
	.byte	124, 18, 17, 18, 124
857
	.byte	127, 73, 73, 73, 62
858
	.byte	62, 65, 65, 65, 34
859
	.byte	127, 65, 65, 34, 28
860
	.byte	127, 73, 73, 73, 65
861
	.byte	127, 9, 9, 9, 1
862
	.byte	62, 65, 73, 73, 58
863
	.byte	127, 8, 8, 8, 127
864
	.byte	0, 65, 127, 65, 0
865
	.byte	32, 64, 65, 63, 1
866
	.byte	127, 8, 20, 34, 65
867
	.byte	127, 64, 64, 64, 64
868
	.byte	127, 2, 12, 2, 127
869
	.byte	127, 4, 8, 16, 127
870
	.byte	62, 65, 65, 65, 62
871
	.byte	127, 9, 9, 9, 6
872
	.byte	62, 65, 81, 33, 94
873
	.byte	127, 9, 25, 41, 70
874
	.byte	38, 73, 73, 73, 50
875
	.byte	1, 1, 127, 1, 1
876
	.byte	63, 64, 64, 64, 63
877
	.byte	31, 32, 64, 32, 31
878
	.byte	127, 32, 24, 32, 127
879
	.byte	99, 20, 8, 20, 99
880
	.byte	3, 4, 120, 4, 3
881
	.byte	97, 81, 73, 69, 67
882
	.byte	0, 127, 65, 65, 0
883
	.byte	2, 4, 8, 16, 32
884
	.byte	0, 65, 65, 127, 0
885
	.byte	4, 2, 1, 2, 4
886
	.byte	64, 64, 64, 64, 64
887
	.byte	1, 2, 4, 0, 0
888
	.byte	32, 84, 84, 84, 120
889
	.byte	127, 68, 68, 68, 56
890
	.byte	56, 68, 68, 68, 40
891
	.byte	56, 68, 68, 68, 127
892
	.byte	56, 84, 84, 84, 24
893
	.byte	8, 126, 9, 1, 2
894
	.byte	8, 84, 84, 84, 60
895
	.byte	127, 4, 4, 4, 120
896
	.byte	0, 68, 125, 64, 0
897
	.byte	32, 64, 64, 61, 0
898
	.byte	127, 16, 40, 68, 0
899
	.byte	0, 65, 127, 64, 0
900
	.byte	124, 4, 24, 4, 120
901
	.byte	124, 8, 4, 4, 120
902
	.byte	56, 68, 68, 68, 56
903
	.byte	124, 20, 20, 20, 24
904
	.byte	8, 20, 20, 20, 124
905
	.byte	124, 8, 4, 4, 8
906
	.byte	72, 84, 84, 84, 32
907
	.byte	4, 63, 68, 64, 32
908
	.byte	60, 64, 64, 32, 124
909
	.byte	28, 32, 64, 32, 28
910
	.byte	60, 64, 56, 64, 60
911
	.byte	68, 40, 16, 40, 68
912
	.byte	12, 80, 80, 80, 60
913
	.byte	68, 100, 84, 76, 68
914
	.byte	0, 8, 54, 65, 0
915
	.byte	0, 0, 119, 0, 0
916
	.byte	0, 65, 54, 8, 0
917
	.byte	2, 1, 2, 4, 2
918
 
919
errormessage:
920
	.ascii "File not found!\0"
921
 
922
bootfilename:
923
	.ascii "emcore  "
924
 
925
text:
926
	.ascii "emCORE Loader v"
927
	.ascii VERSION
928
	.ascii " r"
929
	.ascii VERSION_SVN
930
	.ascii "\0"
931
	.ascii "Loading emCORE...\0"
932
 
933
	.align	2
934
 
935
execfirmware:
936
	mcr	p15, 0, r9,c7,c14,0 @ clean & invalidate data cache
937
	bx	r7
938
 
939
                           @ rendertext register map:
940
                           @ R0: Pointer to string, will be incremented
941
                           @ R1: Framebuffer address, will be incremented
942
                           @ R2: Color
943
                           @ R3: Trashed
944
                           @ R4: Trashed
945
                           @ R4: Trashed
946
                           @ R9: Set to 0
947
                           @ R14: Return address
948
 
949
rendertext:
950
	ldrb	r3, [r0], #1
951
	cmp	r3, #0
952
	moveq	pc, lr
953
	adr	r5, font
954
	sub	r3, r3, #0x20
955
	cmp	r3, #0x5f
956
	addcc	r5, r3,lsl#2
957
	addcc	r5, r3
958
	mov	r3, #5
959
rendertext_col:
960
	mov	r4, r1
961
	ldrb	r9, [r5], #1
962
rendertext_row:
963
	tst	r9, #1
964
	strneh	r2, [r4]
965
	add	r4, r4, #480
966
	movs	r9, r9,lsr#1
967
	bne	rendertext_row
968
	add	r1, r1, #2
969
	subs	r3, r3, #1
970
	bne	rendertext_col
971
	add	r1, r1, #2
972
	b	rendertext
973
 
974
lcd_mode:
975
	.word	0x41100db8
976
 
977
 
978
                           @ Block 8 (DRAW) register map:
979
                           @ R0: Scratchpad
980
                           @ R1: Scratchpad
981
                           @ R2: Scratchpad
982
                           @ R3: Scratchpad
983
                           @ R4: Scratchpad
984
                           @ R5: Scratchpad
985
                           @ R6: Unused
986
                           @ R7: Unused
987
                           @ R8: LCD base address
988
                           @ R9: 0
989
                           @ R10: I2C base address
990
                           @ R11: TIMER base address
991
                           @ R12: SYSCON base address
992
                           @ R13: Scratchpad
993
                           @ R14: Return address / Scratchpad
994
 
995
lcddone:
996
	ldr	r0, lcd_mode
997
	str	r0, [r8]
998
	mov	r1, #0x22000000
999
	orr	r1, r1, #0x6800
1000
	add	r2, r1, #0x25800
1001
	mov	r0, #-1
1002
fillbuff:
1003
	str	r0, [r2,#-4]!
1004
	cmp	r1, r2
1005
	bne	fillbuff
1006
	mov	sp, r1
1007
	adr	r0, text
1008
	mov	r2, #0
1009
	bl	rendertext
1010
	add	r1, sp, #0x1e00
1011
printerror:
1012
	bl	rendertext
1013
	mcr	p15, 0, r9,c7,c10,0 @ clean data cache
1014
	mcr	p15, 0, r9,c7,c10,4 @ drain write buffer
1015
	mov	r0, #0x2a
1016
	bl	sendlcdc
1017
	mov	r0, #0
1018
	bl	sendlcdd
1019
	mov	r0, #0xef
1020
	bl	sendlcdd
1021
	mov	r0, #0x2b
1022
	bl	sendlcdc
1023
	mov	r0, #0
1024
	bl	sendlcdd
1025
	mov	r0, #0x200
1026
	orr	r0, r0, #0x3f
1027
	bl	sendlcdd
1028
	mov	r0, #0x2c
1029
	bl	sendlcdc
1030
blit:
1031
	sub	lr, r8, #0x00100000
1032
	mov	sp, #1
1033
	str	sp, [lr,#0x30]
1034
	mov	sp, #0x22000000
1035
	orr	sp, sp, #0x2d000
1036
	add	lr, lr, #0x100
1037
	mov	r4, #0x8800
1038
	orr	r4, r4, #0xc1
1039
	ldmia	sp, {r0-r3}
1040
	stmia	lr, {r0-r4}
1041
@	tst	r5, #0xff
1042
@failed:
1043
@	bne	failed
1044
	mov	r0, #0x30
1045
	mov	r1, #120
1046
	bl	pmuwrite
1047
	mov	r0, #0x31
1048
	mov	r1, #1
1049
	bl	pmuwrite
1050
 
1051
 
1052
hang: b hang
1053
 
1054
                           @ udelay register map:
1055
                           @ R0: Microseconds
1056
                           @ R1: Trashed
1057
                           @ R11: TIMER base address
1058
                           @ R14: Return address
1059
 
1060
udelay:
1061
	ldr	r1, [r11,#0xb4]
1062
	add	r0, r0, r1
1063
udelayloop:
1064
	ldr	r1, [r11,#0xb4]
1065
	cmp	r1, r0
1066
	bmi	udelayloop
1067
	mov	pc, lr
1068
 
1069
                           @ i2cwaitrdy register map:
1070
                           @ R9: Set to 0
1071
                           @ R10: I2C base address
1072
                           @ R14: Return address
1073
 
1074
i2cwaitrdy:
1075
	ldr	r9, [r10,#0x10]
1076
	cmp	r9, #0
1077
	bne	i2cwaitrdy
1078
	mov	pc, lr
1079
 
1080
                           @ i2cwait register map:
1081
                           @ R3: Set to 0x10
1082
                           @ R10: I2C base address
1083
                           @ R14: Return address
1084
 
1085
i2cwait:
1086
	ldr	r3, [r10]
1087
	ands	r3, #0x10
1088
	beq	i2cwait
1089
	mov	pc, lr
1090
 
1091
                           @ pmuwrite register map:
1092
                           @ R0: Address
1093
                           @ R1: Data
1094
                           @ R2: Set to 0xb7
1095
                           @ R3: Set to 0x10
1096
                           @ R4: Return address backup
1097
                           @ R10: I2C base address
1098
                           @ R14: Return address / Scratchpad
1099
 
1100
pmuwrite:
1101
	mov	r4, lr
1102
	mov	lr, #0xe6
1103
	str	lr, [r10,#0x0c]
1104
	mov	lr, #0xf0
1105
	str	lr, [r10,#0x04]
1106
	mov	r2, #0xb7
1107
	str	r2, [r10]
1108
	bl	i2cwait
1109
	str	r0, [r10,#0x0c]
1110
	str	r2, [r10]
1111
	bl	i2cwait
1112
	str	r1, [r10,#0x0c]
1113
	str	r2, [r10]
1114
	bl	i2cwait
1115
	mov	lr, #0xd0
1116
	str	lr, [r10,#0x04]
1117
	str	r2, [r10]
1118
pmuwrite_wait:
1119
	ldr	lr, [r10,#0x04]
1120
	tst	lr, #0x20
1121
	bne	pmuwrite_wait
1122
	mov	pc, r4
1123
 
1124
                           @ pmuread register map:
1125
                           @ R0: Address
1126
                           @ R1: Data
1127
                           @ R2: Set to 0xb7
1128
                           @ R3: Set to 0x10
1129
                           @ R4: Return address backup
1130
                           @ R10: I2C base address
1131
                           @ R14: Return address / Scratchpad
1132
 
1133
pmuread:
1134
	mov	r4, lr
1135
	mov	lr, #0xe6
1136
	str	lr, [r10,#0x0c]
1137
	mov	lr, #0xf0
1138
	str	lr, [r10,#0x04]
1139
	mov	r2, #0xb7
1140
	str	r2, [r10]
1141
	bl	i2cwait
1142
	str	r0, [r10,#0x0c]
1143
	str	r2, [r10]
1144
	bl	i2cwait
1145
	mov	r1, #0xe7
1146
	str	r1, [r10,#0x0c]
1147
	mov	r1, #0xb0
1148
	str	r1, [r10,#0x04]
1149
	str	r2, [r10]
1150
	bl	i2cwait
1151
	mov	r1, #0x37
1152
	str	r1, [r10]
1153
	bl	i2cwait
1154
	ldr	r1, [r10,#0x0c]
1155
	mov	lr, #0x90
1156
	str	lr, [r10,#0x04]
1157
	str	r2, [r10]
1158
pmuread_wait:
1159
	ldr	lr, [r10,#0x04]
1160
	tst	lr, #0x20
1161
	bne	pmuread_wait
1162
	mov	pc, r4
1163
 
1164
                           @ pmubatch register map:
1165
                           @ R0: Scratchpad
1166
                           @ R1: Scratchpad
1167
                           @ R2: Set to 0xb7
1168
                           @ R3: Set to 0x10
1169
                           @ R4: Inner return address backup
1170
                           @ R7: Outer return address backup
1171
                           @ R9: Number of address-data pairs to be sent (must be >0), will be reset to 0
1172
                           @ R10: I2C base address
1173
                           @ R13: Address-data pair list pointer (will be incremented)
1174
                           @ R14: Return address / Scratchpad
1175
 
1176
pmubatch:
1177
	mov	r7, lr
1178
pmubatch_loop:
1179
	ldrb	r0, [sp], #1
1180
	ldrb	r1, [sp], #1
1181
	bl	pmuwrite
1182
	subs	r9, r9, #1
1183
	bne	pmubatch_loop
1184
	mov	pc, r7
1185
 
1186
                           @ sendlcdc register map:
1187
                           @ R0: Command to be sent
1188
                           @ R8: LCD base address
1189
                           @ R9: Will be set to 0
1190
                           @ R14: Return address
1191
 
1192
sendlcdc:
1193
	ldr	r9, [r8,#0x1c]
1194
	ands	r9, r9, #0x10
1195
	bne	sendlcdc
1196
	str	r0, [r8,#0x04]
1197
	mov	pc, lr
1198
 
1199
                           @ sendlcdd register map:
1200
                           @ R0: Data to be sent
1201
                           @ R8: LCD base address
1202
                           @ R9: Will be set to 0
1203
                           @ R14: Return address
1204
 
1205
sendlcdd:
1206
	ldr	r9, [r8,#0x1c]
1207
	ands	r9, r9, #0x10
1208
	bne	sendlcdd
1209
	str	r0, [r8,#0x40]
1210
	mov	pc, lr
1211
 
1212
                           @ readlcd register map:
1213
                           @ R0: Result data
1214
                           @ R8: LCD base address
1215
                           @ R14: Return address
1216
 
1217
readlcd:
1218
	ldr	r0, [r8,#0x1c]
1219
	tst	r0, #2
1220
	beq	readlcd
1221
	str	r0, [r8,#0x10]
1222
readlcd_wait:
1223
	ldr	r0, [r8,#0x1c]
1224
	tst	r0, #0x1
1225
	beq	readlcd_wait
1226
	ldr	r0, [r8,#0x14]
1227
	mov	r0, r0,lsr#1
1228
	mov	pc, lr