1/*
2 * BCM47XX Denali based memory controller initialization
3 *
4 * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * $Id: aisdram.S,v 1.37 2011-01-20 04:26:45 $
19 */
20
21#include <hndsoc.h>
22#include <bcmdevs.h>
23#include <bcmnvram.h>
24#include <sbsdram.h>
25#include <sbmemc.h>
26#include <sbsocram.h>
27#include <dmemc_core.h>
28#include <amemc_core.h>
29#include <sbchipc.h>
30
31#if	defined(NFLASH_SUPPORT)
32#include <nflash.h>
33#endif
34
35#include <mipsinc.h>
36
37
38/* Debug macro - write a number to a pair of chipc regs - use it with caution,
39 *  the registers being used only exist in chip rev >= 22, meaning NOT in 5354
40 *  and previous chips. Also,  it changes k0 and k1 registers.
41 *  Value can be read from epidiag -j using "pci r 0x180000d0 4"
42 */
43#ifdef	BCMDBG
44
45#if	defined(IL_BIGENDIAN) && defined(BCMHND74K)
46#define	BPADDR_OFF	4
47#define	BPDATA_OFF	12
48#else
49#define	BPADDR_OFF	0
50#define	BPDATA_OFF	8
51#endif
52
53#define TRACEINIT(x) \
54	li	k0,KSEG1ADDR(0x180000d0); \
55	li	k1,x; \
56	sw	k1,BPADDR_OFF(k0)
57
58#define TRACE(x) \
59	li	k1,x; \
60	sw	k1,BPADDR_OFF(k0)
61
62#define TRACE2(x) \
63	li	k1,x; \
64	sw	k1,BPDATA_OFF(k0)
65
66#else
67#define TRACEINIT(x)
68#define TRACE(x)
69#define TRACE2(x)
70#endif	/* BCMDBG */
71	.text
72
73dmemc_init:
74	.word	0,	0x00000101
75	.word	1,	0x01030100
76	.word	2,	0x01030101
77	.word	3,	0x01010101
78	.word	5,	0x00000100
79	.word	7,	0x01010000
80	.word	8,	0x00000100
81	.word	9,	0x00000100
82	.word	10,	0x01010101
83	.word	12,	0x00010200
84	.word	16,	0x0f00000a
85	.word	20,	0x64000000
86	.word	27,	0x00000001
87	.word	28,	0x0039000a
88	.word	29,	0x081b002b
89	.word	30,	0x00000000
90	.word	31,	0x00000000
91	.word	33,	0x000200c8
92	.word	35,	0x000000c8
93	.word	36,	0x00000000
94	.word	125,	0x01010000
95	.word	126,	0x02000100
96	.word	129,	0x02000200
97	.word	132,	0x00000000
98	.word	138,	0x00000000
99	.word	139,	0x00000000
100	.word	151,	0x00000005
101	.word	DMEMC_TABLE_END
102
103sdr_init:
104	.word	4,	0x00000100
105	.word	6,	0x00000000
106	.word	11,	0x00030001
107	.word	14,	0x00020000
108	.word	15,	0x0f000102
109	.word	17,	0x05000002
110	.word	18,	0x00000003
111	.word	19,	0x00090200
112	.word	21,	0x70006400
113	.word	22,	0x7f000070
114	.word	23,	0x00400000
115	.word	24,	0x09030600
116	.word	25,	0x00170017
117	.word	32,	0x00320000
118	.word	34,	0x000a4186
119	.word	DMEMC_TABLE_END
120
121ddr1_init:
122	.word	4,	0x00000100
123	.word	6,	0x00000100
124	.word	11,	0x00030000
125	.word	14,	0x02030200
126	.word	15,	0x0f010203
127	.word	17,	0x06000002
128	.word	18,	0x00000006
129	.word	19,	0x0010010e
130	.word	21,	0x20006400
131	.word	22,	0x5700002a
132	.word	23,	0x00340000
133	.word	24,	0x0e030800
134	.word	25,	0x000f000f
135	.word	26,	0x000f000f
136	.word	32,	0x00000000
137	.word	34,	0x000d2d89
138	.word	127,	0x00000001
139	.word	128,	0x07000300
140	.word	130,	0x00010103
141	.word	131,	0x00000200
142	.word	133,	0x06120000
143	.word	134,	0x06120612
144	.word	135,	0x06120612
145	.word	136,	0x00000612
146	.word	137,	0x00000032
147	.word	140,	0x001f4008
148	.word	141,	0x001f4008
149	.word	142,	0x002ee004
150	.word	143,	0x002ee004
151	.word	146,	0x000f0033
152	.word	147,	0xf4103c17
153	.word	148,	0xf4103c17
154	.word	149,	0x26c00301
155	.word	150,	0x26c00301
156	.word	DMEMC_TABLE_END
157
158ddr2_init:
159	.word	4,	0x00010100
160	.word	6,	0x00000000
161	.word	11,	0x00030000
162	.word	14,	0x02030203
163	.word	15,	0x0f030204
164	.word	17,	0x08000002
165	.word	18,	0x00000004
166	.word	19,	0x000f020e
167	.word	21,	0x16006400
168	.word	22,	0x6026162a
169	.word	23,	0x00340000
170	.word	24,	0x35060c00
171	.word	25,	0x00200020
172	.word	26,	0x00200020
173	.word	32,	0x006b0000
174	.word	34,	0x003848e1
175	.word	127,	0x00000002
176	.word	128,	0x07000404
177	.word	130,	0x03020304
178	.word	131,	0x00000400
179	.word	133,	0x081b0000
180	.word	134,	0x081b081b
181	.word	135,	0x081b081b
182	.word	136,	0x0000081b
183	.word	137,	0x00400642
184	.word	140,	0x00164008
185	.word	141,	0x00164008
186	.word	142,	0x00236004
187	.word	143,	0x00236004
188	.word	146,	0x000f0133
189	.word	147,	0xf4112c17
190	.word	148,	0xf4112c17
191	.word	149,	0x26c00300
192	.word	150,	0x26c00300
193	.word	DMEMC_TABLE_END
194
195#if	defined(NFLASH_SUPPORT)
196nfl_pagesz_map:
197	/* page size mapping */
198	.word	0x200, 0x800, 0x1000, 0x2000
199
200nfl_blksz_map:
201	/* block size mapping */
202	.word	0x4000, 0x20000, 0x2000, 0x80000, 0x40000, 0, 0, 0
203#endif
204
205	/* Register conventions.
206	 *	Inherited from sisdram.S:
207	 *		s2 = SI_ENUM_BASE
208	 *		s5 = Relocation factor
209	 *		s6 = ChipId reg
210	 *		s7 = ChipType
211	 *	Local:
212	 *		s0 = sdram_config + sdram_refresh values
213	 *		s1 = package opt
214	 *		s3 = Controller corerev
215	 *		s4 = Controller coreid
216	 *		s8 = config_ncdl
217	 *		a1 = dmemc regs
218	 *		a2 = dmemc DMP regs
219	 *		a3 = memory type (sdr,ddr1,ddr2)
220	 */
221
222LEAF(ai_draminit)
223	.set	mips32
224	.set	noreorder
225
226	TRACE(0x415301)
227
228	move	t6,ra
229
230	/* Scan for a Denali DDR controller (a0) */
231	lw	a0,CC_EROMPTR(s2)
232	li	t0,KSEG1			# t0 = KSEG1
233	or	a0,a0,t0			# a0 points to the EROM
234	TRACE(0x415302)
2351:
236#if	defined(IL_BIGENDIAN) && defined(BCMHND74K)
237	xor	t0,a0,4
238	lw	t0,0(t0)
239	add	t3,a0,4
240	xor	t3,t3,4
241	lw	t3,0(t3)
242#else
243	lw	t0,0(a0)			# t0 = CIA
244	lw	t3,4(a0)			# t3 = CIB
245#endif
246	and	t1,t0,ER_TAG
247	TRACE(0x415303)
248	beq	t1,ER_END,noctrl
249	nop
250	TRACE(0x415304)
251	beq	t1,ER_CI,2f
252	nop
253	TRACE(0x415305)
254	b	1b
255	addi	a0,4
256
2572:	TRACE(0x415306)
258	and	s4,t0,CIA_CID_MASK
259	srl	s4,s4,CIA_CID_SHIFT		# s4 has controler coreid
260
261	beq	s4,DMEMC_CORE_ID,founddmemc
262	nop
263
264	beq	s4,DMEMS_CORE_ID,founddmemc
265	nop
266
267	beq	s4,AMEMC_CORE_ID,founddmemc
268	nop
269
270	b	1b
271	addi	a0,8				# Skip CIB too
272
273	/* No DMEMC controller found */
274noctrl:	TRACE(0x415307)
275	jr	t6
276	li	v0,-1
277
278
279founddmemc:
280	TRACE(0x415308)
281	/* If we found the controller, but we are already in RAM, there is nothing
282	 * to do. This will change if/when we have an AI chip with MIPS and
283	 * SOCRAM only.
284	 */
285	bnez	s5,1f				# Not running from RAM, go ahead
286	nop
287
288	jr	t6				# Return with 0 rc.
289	move	v0,zero
290
291	/* We'll cheat a little: memory controllers don't have master ports, so
292	 * the EROM entry right after the CIDs is the slave port for the registers
293	 */
2941:
295#if	defined(IL_BIGENDIAN) && defined(BCMHND74K)
296	add	a1,a0,8
297	xor	a1,a1,4
298	lw	a1,0(a1)
299#else
300	lw	a1,8(a0)
301#endif
302	li	t2,AD_ADDR_MASK
303	and	a1,a1,t2
304	li	t0,KSEG1			# t0 = KSEG1
305	or	a1,a1,t0			# a1: dmemc regs
306	/* after that, the first slave wrapper will be its DMP registers */
307	addi	a0,12
3081:
309#if	defined(IL_BIGENDIAN) && defined(BCMHND74K)
310	xor	t0,a0,4
311	lw	t0,0(t0)
312#else
313	lw	t0,0(a0)
314#endif
315	and	t1,t0,ER_TAG
316	beq	t1,ER_ADD,addesc
317	nop
318	b	1b
319	addi	a0,4
320
321addesc:	and	t1,t0,AD_ST_MASK
322	beq	t1,AD_ST_SWRAP,swrap
323	nop
324	b	1b
325	addi	a0,4
326
327swrap:	and	a2,t0,t2
328	li	t0,KSEG1			# t0 = KSEG1
329	or	a2,a2,t0			# a2: dmemc DMP regs
330
331	/* Got our core, reset it */
332	TRACE(0x415309)
333	bal	ai_core_reset
334	nop
335
336	/* Get package option for later */
337	TRACE(0x41530a)
338	li	t0,CID_PKG_MASK
339	and	t0,t0,s6
340	srl	s1,t0,CID_PKG_SHIFT		# s1 = package opt
341
342	/* Find out the type of memory from the straps */
343	/* Corerevs 0 & 1 did not have this register, so we have to
344	 * check the corerev and use chipstatus for those two.
345	 */
346	and	t3,t3,CIB_REV_MASK
347	srl	s3,t3,CIB_REV_SHIFT		# s3 = core revision
348	beq     s4,DMEMS_CORE_ID,1f
349	nop
350
351	/* Go find nvram if the controller is AMEMC. */
352	beq     s4,AMEMC_CORE_ID,find_nvram
353	nop
354
355	ble	s3,1,is16x
356	nop
357
3581:	/* Not a 4716/47162 (a0?) read the stat register */
359	lw	t0,DMEMC_STAT(a1)
360	li	t1,DM_STAT_MASK
361	and	a3,t0,t1			# a3 == 4 if ddr2, 2 if ddr1, 1 if sdr.
362	b	find_nvram
363	nop
364
365	/* Check chipc:	chipstatus for the ddr1/ddr2 strapping option */
366is16x:	TRACE(0x41530b)
367	lw	t0,CC_CHIPST(s2)
368	li	t1,0x200
369	and	t0,t0,t1
370	beqz	t0,find_nvram
371	li	a3,DM_STAT_DDR2
372
373	li	a3,DM_STAT_DDR1
374
375	/* Read sdram_config from nvram */
376find_nvram:
377	TRACE(0x41530c)
378	li	t0,KSEG1ADDR(SI_FLASH2 - MAX_NVRAM_SPACE)
379	li	t1,FLASH_MIN
380	li	t2,SI_FLASH2_SZ
381	li	t3,NVRAM_MAGIC
382#ifndef SDRAM_PARAM_FROM_EMBEDDED_NVRAM
383#if	defined(NFLASH_SUPPORT)
384	/* Take care of 5357 NAND boot */
385	li	t4,CID_ID_MASK
386	and	t4,t4,s6
387	bne	t4,BCM5357_CHIP_ID,1f
388	nop
389	lw	t5,CC_CHIPST(s2)
390	li	t4,0x10
391	and	t4,t4,t5
392	beqz	t4,1f
393	nop
394
395	la	t4,nfl_size_block
396	add	t4,t4,s5
397	jalr	t4
398	nop
399	beqz	v0,embedded_nv
400	nop
401
402	/* skip bad blocks and locate nvram */
403	move	t1,v0					# block size
404	move	t2,t1
405check_badb:
406	move	a0,t2
407	move	t0,a1					# save a1
408	move	a1,v1					# page size
409	la	t4,nfl_check_badb
410	add	t4,t4,s5
411	jalr	t4
412	nop
413	move	a1,t0					# restore a1
414	bnez	v0,skip_badb
415	nop
416
417	li	t0,KSEG1ADDR(SI_FLASH1)
418	add	t4,t0,t2
419	lw	t5,0(t4)
420	beq	t3,t5,read_config
421	nop
422skip_badb:
423	add	t2,t2,t1
424	li	t5,SI_FLASH1_SZ
425	blt	t2,t5,check_badb
426	nop
427	b	embedded_nv
428	nop
429#endif
430
4311:	add	t4,t0,t1
432	lw	t5,0(t4)
433	beq	t3,t5,read_config
434	nop
435
436	sll	t1,t1,1
437	ble	t1,t2,1b
438	nop
439#endif
440#if	defined(NFLASH_SUPPORT)
441embedded_nv:
442#endif
443	/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
444	TRACE(0x41530d)
445	li	t4,KSEG1ADDR(SI_FLASH1 + 0x1000)
446	lw	t5,0(t4)
447	beq	t3,t5,read_config
448	nop
449
450	TRACE(0x41530e)
451	li	t4,KSEG1ADDR(SI_FLASH1 + 0x400)
452	lw	t5,0(t4)
453	beq	t3,t5,read_config
454	nop
455
456	/* No nvram, pick sone defaults */
457
458	/* assume DDRM16MX16 if ddr1 */
459	TRACE(0x41530f)
460	bne	a3,DM_STAT_DDR1,1f
461	nop
462
463	beq	s4,DMEMC_CORE_ID,init_dmemc
464	li	s0,0x283		# Value for dmemc
465
466	/* Use DDR1M16MX16 if QT and DDR1M32MX16 otherwise */
467	beq	s1,HWSIM_PKG_ID,init_dmemc
468	li	s0,0x103		# Value for dmems
469
470	b	init_dmemc
471	li	s0,0x003		# Value for dmems at 200MHz
472
4731:	beq	a3,DM_STAT_SDR,init_dmemc
474	li	s0,0x002		# Value for SDR
475
476	/* For ddr2, use DDR2M32X16X2 if QT and DDR2M128X16X2 otherwise */
477	beq	s1,HWSIM_PKG_ID,init_dmemc
478	li	s0,0x104
479
480	b	init_dmemc
481	li	s0,0x144
482
483read_config:
484	/* sdram_config is a 16bit value 12 bytes inside the nvram hdr.
485	 * Currently it is defined as:
486	 *	10:8	column_size as per control13
487	 *	7	reduc i.e. memory is half the width of the controller
488	 *	6	8 banks
489	 *	5	bypass
490	 *	2:0	cas latency
491	 *
492	 * sdram_refresh:
493	 *	15:8	delay_dqs_0
494	 *	7:0	clk_wr_delay, or clk_wr_delay_0 (for corerev >= 2)
495	 *
496	 * sdram_ncdl:	control22
497	 *	31:24	clk_dqs_delay, or clk_wr_delay_1 (for corerev >= 2)
498	 *	23:16	delay_dqs_3
499	 *	15:8	delay_dqs_2
500	 *	7:0	delay_dqs_1
501	 */
502	TRACE(0x415310)
503	lw	s0,12(t4)	# Pick up sdram_config & sdram_refresh
504
505	/* Determine if it is DMEMC or AMEMC */
506	bne s4,AMEMC_CORE_ID,init_dmemc
507	lw	s8,16(t4)	# Pick up sdram_ncdl
508
509	/* Initailize AMEMC */
510	la	t2,ai_amemcinit
511	add	t2,t2,s5
512	jalr	t2
513	nop
514
515	jr	t6
516	move	v0,zero
517
518	/* Initialize DMEMC/DMEMS */
519init_dmemc:
520	/* For DDR2, init pvt controller */
521	bne	a3,DM_STAT_DDR2,init_regs
522	nop
523
524	TRACE(0x415311)
525	li	t0,1
526	sw	t0,DMEMC_PVTGROUPJ(a1)
527	sw	zero,DMEMC_PVTGROUPA(a1)
528	sw	t0,DMEMC_PVTGROUPA(a1)
529
530	/* Init the common regs */
531init_regs:
532	TRACE(0x415312)
533	la	a0,dmemc_init
534	bal	dmemc_init_regs			# dmemc_init_regs(a0): Inits from the table @ a0
535	nop
536
537	la	a0,sdr_init
538	beq	a3,DM_STAT_SDR,1f
539	nop
540
541	TRACE(0x415313)
542	la	a0,ddr1_init
543	beq	a3,DM_STAT_DDR1,1f
544	nop
545
546	TRACE(0x415314)
547	la	a0,ddr2_init
5481:	bal	dmemc_init_regs
549	nop
550
551	/* Fixup differences between dmems & dmemc */
552fixs:	bne	s4,DMEMS_CORE_ID,fix2
553	nop
554
555	lw	t1,DMEMC_DDR_CTRL(a1)
556	li	t2,0x00000001			# Set DDR_CTRL bit 0 if SDR
557	or	t1,t1,t2
558	li	t0,0x02020002
559	beq	a3,DM_STAT_SDR,1f
560	nop
561
562	li	t0,0x18006400
563	sw	t0,DMEMC_CONTROL21(a1)
564	li	t0,0x7f000018			# DLL DQS delay for DDR1
565	sw	t0,DMEMC_CONTROL22(a1)
566	li	t0,0x00500000
567	sw	t0,DMEMC_CONTROL23(a1)
568	li	t0,0x00320000			# Change MRS data for DDR1
569	sw	t0,DMEMC_CONTROL32(a1)
570
571	li	t0,0x02000002
572	li	t2,~0x00000001			# Clear DDR_CTRL bit 0 if DDR1
573	and	t1,t1,t2
574
5751:	sw	t0,DMEMC_CONTROL52(a1)
576	sw	t1,DMEMC_DDR_CTRL(a1)
577	li	t0,0x00000001
578	sw	t0,DMEMC_CONTROL53(a1)
579
580	/* Fixup differences in 47162 */
581fix2:	li	t0,CID_ID_MASK
582	and	t0,t0,s6
583	bne	t0,BCM47162_CHIP_ID,nvover
584	nop
585
586	li	t0,0x16006400
587	sw	t0,DMEMC_CONTROL21(a1)
588	li	t0,0x00480000
589	sw	t0,DMEMC_CONTROL23(a1)
590
591	/* Presumaby this is for DDR1 only? */
592	li	t0,0x61161616
593	sw	t0,DMEMC_CONTROL22(a1)
594
595	/* Override the dll delays from nvram if provided */
596nvover:	beqz	s8,chtref
597	nop
598
599	# Check for dmems (any rev)
600	beq	s4,DMEMS_CORE_ID,old_ncdl
601	nop
602
603	# Dmemc rev < 2?
604	ble	s3,1,old_ncdl
605	nop
606
607	li	t0,0x7f000000
608	and	t0,t0,s0		# delay_dqs_0
609	srl	t0,t0,15
610	lw	t1,DMEMC_CONTROL140(a1)
611	li	t2,~0x0000fe00
612	and	t1,t1,t2
613	or	t0,t0,t1
614	sw	t0,DMEMC_CONTROL140(a1)
615
616	li	t0,0x7f
617	and	t0,t0,s8		# delay_dqs_1
618	sll	t0,t0,9
619	lw	t1,DMEMC_CONTROL141(a1)
620	and	t1,t1,t2
621	or	t0,t0,t1
622	sw	t0,DMEMC_CONTROL141(a1)
623
624	li	t0,0x7f0000
625	and	t0,t0,s0		# clk_wr_delay_0
626	srl	t0,t0,8
627	lw	t1,DMEMC_CONTROL142(a1)
628	li	t2,~0x00007f00
629	and	t1,t1,t2
630	or	t0,t0,t1
631	sw	t0,DMEMC_CONTROL142(a1)
632
633	li	t0,0x7f000000
634	and	t0,t0,s8		# clk_wr_delay_1
635	srl	t0,t0,16
636	lw	t1,DMEMC_CONTROL143(a1)
637	and	t1,t1,t2
638	or	t0,t0,t1
639	sw	t0,DMEMC_CONTROL143(a1)
640
641	b	chtref
642	nop
643
644old_ncdl:
645	li	t0,0x7f000000
646	and	t0,t0,s0		# delay_dqs_0
647	or	t0,t0,0x6400
648	sw	t0,DMEMC_CONTROL21(a1)
649	li	t0,0x007f0000
650	and	t0,t0,s0		# clk_wr_delay
651	sw	t0,DMEMC_CONTROL23(a1)
652
653	sw	s8,DMEMC_CONTROL22(a1)
654
655chtref:
656	lw	t0,8(t4)		# Pick up sdram_init value for TREF
657	lw	t2,DMEMC_CONTROL29(a1)
658	beq	s4,DMEMS_CORE_ID,1f
659	nop
660
661	# Dmemc rev < 2?
662	ble	s3,1,chhalf
663	nop
664
665	li	t1,0x3fff0000
666	and	t0,t0,t1
667	beqz	t0,chhalf
668	nop
669
670	li	t1,~0x3fff0000
671	and	t2,t2,t1
672	b	settref
673	nop
6741:
675	li	t1,0x0fff0000
676	and	t0,t0,t1
677	beqz	t0,chhalf
678	nop
679
680	li	t1,~0x0fff0000
681	and	t2,t2,t1
682
683settref:
684	or	t0,t0,t2
685	sw	t0,DMEMC_CONTROL29(a1)
686
687	/* Check for half-width */
688chhalf:	li	t0,0x80
689	and	t0,t0,s0
690	beqz	t0,ch8banks
691	nop
692
693setreduc:
694	/* Set reduc bit if half-wide */
695	TRACE(0x415315)
696	lw	t0,DMEMC_CONTROL08(a1)
697	li	t1,0x01000000
698	or	t0,t0,t1
699	sw	t0,DMEMC_CONTROL08(a1)
700
701	/* Check for 8-bank DDRs */
702ch8banks:
703	li	t0,0x40
704	and	t0,t0,s0
705	beqz	t0,docaslat
706	nop
707
708	/* Change regs for 8-bank DDRs */
709do8banks:
710	lw	t0,DMEMC_CONTROL05(a1)
711	li	t1,0x00010000
712	or	t0,t0,t1
713	sw	t0,DMEMC_CONTROL05(a1)
714
715	lw	t0,DMEMC_CONTROL19(a1)
716	li	t1,0x0000000e
717	or	t0,t0,t1
718	sw	t0,DMEMC_CONTROL19(a1)
719
720	lw	t0,DMEMC_CONTROL24(a1)
721	li	t1,~0xff000000
722	li	t2,0x22000000
723	and	t0,t0,t1
724	or	t0,t0,t2
725	sw	t0,DMEMC_CONTROL24(a1)
726
727	lw	t0,DMEMC_CONTROL34(a1)
728	li	t1,~0x00ff0000
729	li	t2,0x00250000
730	and	t0,t0,t1
731	or	t0,t0,t2
732	sw	t0,DMEMC_CONTROL34(a1)
733
734	/* Set the right value for column size and CAS latency */
735docaslat:
736	TRACE(0x415316)
737	li	t0,0x0707
738	and	t0,t0,s0
739	sw	t0,DMEMC_CONTROL13(a1)
740	andi	t0,s0,7			# Isolate cas
741	beq	s4,DMEMS_CORE_ID,setcaslin
742	nop
743	ble	s3,1,setcaslin
744	nop
745	/* Additional settings required for dmemc rev >= 2 */
746	sll	t1,t0,8
747	and	t1,0xf00
748	bne	a3,DM_STAT_DDR1,1f
749	nop
750	and	t1,0x300
7511:	lw	t2,DMEMC_CONTROL128(a1)
752	and	t2,~0xf00
753	or	t2,t2,t1
754	sw	t2,DMEMC_CONTROL128(a1)
755	sll	t1,t0,4
756	lw	t2,DMEMC_CONTROL137(a1)
757	and	t2,~0x70
758	or	t2,t2,t1
759	sw	t2,DMEMC_CONTROL137(a1)
760	bne	a3,DM_STAT_DDR2,setcaslin
761	nop
762	sub	t1,t0,1
763	sll	t1,8
764	lw	t2,DMEMC_CONTROL130(a1)
765	and	t2,~0xf00
766	or	t2,t2,t1
767	sw	t2,DMEMC_CONTROL130(a1)
768	sll	t1,8
769	lw	t2,DMEMC_CONTROL15(a1)
770	and	t2,~0xf0000
771	or	t2,t2,t1
772	sw	t2,DMEMC_CONTROL15(a1)
773setcaslin:
774	/* Set caslat_lin and caslat_lin_gate */
775	lw	t2,DMEMC_CONTROL16(a1)
776	/* Take care of fractional CAS latencies for DDR1 */
777	li	t3,0
778	bne	a3,DM_STAT_DDR1,1f
779	nop
780	andi	t1,t0,4
781	beqz	t1,1f
782	nop
783	andi	t0,t0,3			# take off half bit
784	li	t3,1
7851:	sll	t0,t0,1			#  * 2
786	add	t0,t0,t3
787	addi	t1,t0,1			#  + 1 => caslin
788	sll	t1,t1,8
789	or	t2,t2,t1
790	addi	t0,t0,-1		# and -1 => caslin_gate
791	sll	t0,t0,16
792	or	t2,t0,t2
793	sw	t2,DMEMC_CONTROL16(a1)
794
795	/* Finally set bypass mode if needed, but always for quickturn */
796ckbyp:	beq	s1,HWSIM_PKG_ID,dobypass
797	nop
798	li	t0,0x20
799	and	t0,t0,s0
800	beqz	t0,ckvsim
801	nop
802
803dobypass:
804	TRACE(0x415317)
805
806	beq	s4,DMEMS_CORE_ID,1f
807	nop
808
809	bgt	s3,1,4f
810	nop
811
8121:	li	t0,0x00170017
813	beq	a3,DM_STAT_SDR,2f
814	nop
815
816	li	t0,0x000f000f
817	beq	a3,DM_STAT_DDR1,2f
818	nop
819
820	li	t0,0x00200020
821
8222:	sw	t0,DMEMC_CONTROL25(a1)
823	beq	s4,DMEMS_CORE_ID,3f
824	nop
825	sw	t0,DMEMC_CONTROL26(a1)
826
8273:	lw	t0,DMEMC_CONTROL28(a1)
828	li	t1,0x00ff0000
829	or	t0,t0,t1
830	sw	t0,DMEMC_CONTROL28(a1)
831
8324:	lw	t0,DMEMC_CONTROL29(a1)
833	li	t1,~0x000000ff
834	li	t2,0x0000005f
835	and	t0,t0,t1
836	or	t0,t0,t2
837	sw	t0,DMEMC_CONTROL29(a1)
838
839	lw	t0,DMEMC_CONTROL05(a1)
840	li	t1,0x00000001
841	or	t0,t0,t1
842	sw	t0,DMEMC_CONTROL05(a1)
843
844	beq	s4,DMEMS_CORE_ID,ckvsim
845	nop
846
847	ble	s3,1,ckvsim
848	nop
849
850	lw	t0,DMEMC_CONTROL140(a1)
851	li	t1,0x10000000
852	or	t0,t0,t1
853	sw	t0,DMEMC_CONTROL140(a1)
854
855	lw	t0,DMEMC_CONTROL141(a1)
856	or	t0,t0,t1
857	sw	t0,DMEMC_CONTROL141(a1)
858
859	/* For vsim change tinit so sims run faster */
860ckvsim:	bne	s1,HDLSIM_PKG_ID,turnon
861	nop
862
863	TRACE(0x415318)
864	li	t0,0x36
865	sw	t0,DMEMC_CONTROL36(a1)
866
867turnon:
868	/* We are ready, turn controller on */
869	TRACE(0x415319)
870	lw	t0,DMEMC_CONTROL09(a1)		# Read current control09 reg
871	or	t0,t0,DMC09_START		# Add start bit
872	sw	t0,DMEMC_CONTROL09(a1)		# Start the controller
873
874	beq	s4,DMEMS_CORE_ID,2f
875	nop
876
877	ble	s3,1,2f
878	nop
879
8801:	lw	t0,DMEMC_CONTROL133(a1)		# Poll for INT_INIT_DONE (dmemc >=2)
881	and	t1,t0,DM_INT_INIT_DONE
882	beqz	t1,1b
883	nop
884	/* Bypass mode programming */
885	lw	t0,DMEMC_CONTROL05(a1)
886	li	t1,0x00000001
887	and	t0,t0,t1
888	beqz	t0,ack_ints
889	nop
890	lw	t1,DMEMC_CONTROL144(a1)
891	srl	t1,t1,3
892	lw	t2,DMEMC_CONTROL140(a1)
893	li	t0,~0x03ff0000
894	and	t2,t2,t0
895	sll	t0,t1,16
896	or	t2,t2,t0
897	sw	t2,DMEMC_CONTROL140(a1)
898
899	lw	t2,DMEMC_CONTROL142(a1)
900	li	t0,~0x01ff8000
901	and	t2,t2,t0
902	sll	t0,t1,1
903	add	t0,t0,t1
904	li	t1,0x3ff
905	and	t0,t0,t1
906	sll	t0,t0,15
907	or	t2,t2,t0
908	sw	t2,DMEMC_CONTROL142(a1)
909
910	lw	t1,DMEMC_CONTROL145(a1)
911	srl	t1,t1,3
912	lw	t2,DMEMC_CONTROL141(a1)
913	li	t0,~0x03ff0000
914	and	t2,t2,t0
915	sll	t0,t1,16
916	or	t2,t2,t0
917	sw	t2,DMEMC_CONTROL141(a1)
918
919	lw	t2,DMEMC_CONTROL143(a1)
920	li	t0,~0x01ff8000
921	and	t2,t2,t0
922	sll	t0,t1,1
923	add	t0,t0,t1
924	li	t1,0x3ff
925	and	t0,t0,t1
926	sll	t0,t0,15
927	or	t2,t2,t0
928	sw	t2,DMEMC_CONTROL143(a1)
929ack_ints:
930	/* Clear any pending interrupts from dmemc */
931	li	t1,DMC132_INTACK_MASK
932	and	t0,t0,t1			# t0 = control133 & mask
933	lw	t2,DMEMC_CONTROL132(a1)
934	not	t1
935	and	t2,t1,t2			# t2 = control132 & ~mask
936	or	t0,t0,t2			# Or them and ...
937	sw	t0,DMEMC_CONTROL132(a1)		# Ack all ints
938	b	3f
939	nop
940
9412:	lw	t0,DMEMC_CONTROL24(a1)		# Poll for INT_INIT_DONE (dmems & dmemc<2)
942	and	t1,t0,DM_INT_INIT_DONE
943	beqz	t1,2b
944	nop
945	/* Clear any pending interrupts from dmemc */
946	li	t1,DMC23_INTACK_MASK
947	and	t0,t0,t1			# t0 = control24 & mask
948	lw	t2,DMEMC_CONTROL23(a1)
949	not	t1
950	and	t2,t1,t2			# t2 = control23 & ~mask
951	or	t0,t0,t2			# Or them and ...
952	sw	t0,DMEMC_CONTROL23(a1)		# Ack all ints
953
9543:	jr	t6
955	li	v0,0
956
957	/* Reset core using DMP regs at (a2) */
958ai_core_reset:
959	/* Set reset while enabling the clock */
960	li	t9,(SICF_FGC | SICF_CLOCK_EN)
961	li	t8,AIRC_RESET
962	sw	t9,AI_IOCTRLSET(a2)
963	sw	t8,AI_RESETCTRL(a2)
964
965	/* Read back and delay */
966	lw	t8,AI_RESETCTRL(a2)
967	lw	t8,AI_RESETCTRL(a2)
968	lw	t8,AI_RESETCTRL(a2)
969
970	/* Clear reset */
971	li	t8,0
972	sw	t8,AI_RESETCTRL(a2)
973
974	/* Read back and delay */
975	lw	t8,AI_RESETCTRL(a2)
976	lw	t8,AI_RESETCTRL(a2)
977	lw	t8,AI_RESETCTRL(a2)
978
979	/* Clear Force Gated Clock */
980	li	t9,SICF_FGC
981	sw	t9,AI_IOCTRLCLEAR(a2)
982
983	/* Read back and delay */
984	lw	t9,AI_IOCTRL(a2)
985	lw	t9,AI_IOCTRL(a2)
986	lw	t9,AI_IOCTRL(a2)
987
988	jr	ra
989	nop
990
991	/* Use table at (a0) to init dmemc regs.
992	 * Assumes (a1) points to the regs.
993	 */
994dmemc_init_regs:
995	beq     s4,DMEMS_CORE_ID,loop_regs
996	li	t3,128
997
998	ble	s3,1,loop_regs
999	nop
1000
1001	li	t3,256
1002
1003loop_regs:
1004	add	a0,a0,s5			# Relocate address
1005	li	t0,DMEMC_TABLE_END
10061:	lw	t1,0(a0)			# Pick up reg num
1007	bge	t1,t3,2f			# Return if the reg num >= num of supported regs
1008	nop
1009	beq	t1,t0,2f			# Return if done
1010	nop
1011
1012	lw	t2,4(a0)			# Get reg value
1013	sll	t1,2				# Reg num * 4 is reg offset
1014	addu	t1,a1,t1
1015#if	defined(IL_BIGENDIAN) && defined(BCMHND74K)
1016	xor	t1,t1,4
1017#endif
1018	sw	t2,0(t1)			# Write reg
1019	b	1b
1020	addi	a0,8
1021
10222:	jr	ra
1023	nop
1024
1025END(ai_draminit)
1026
1027#if	defined(NFLASH_SUPPORT)
1028LEAF(nfl_size_block)
1029	lw	t9,CC_NAND_CONFIG(s2)
1030	li	t8,0x3
1031	sll	t8,20
1032	and	t8,t8,t9
1033	srl	t8,18				# index = (ncf & (0x3 << 20) >> 18)
1034	la	a0,nfl_pagesz_map
1035	add	a0,a0,s5			# Relocate address
1036	add	t8,t8,a0
1037	lw	v1,0(t8)
1038
1039	li	t8,0x7
1040	sll	t8,28
1041	and	t8,t8,t9
1042	srl	t8,26				# index = (ncf & (0x7 << 28) >> 26)
1043	la	a0,nfl_blksz_map
1044	add	a0,a0,s5			# Relocate address
1045	add	t8,t8,a0
1046	lw	v0,0(t8)
1047	jr	ra
1048	nop
1049END(nfl_size_block)
1050
1051	.balign 0x200
1052
1053
1054LEAF(nfl_check_badb)
1055	add	t9,a0,zero
1056	move	t5,zero
1057check_spare:
1058	/* Wait until nflash controller interface ready */
1059	li	v0,NIST_CTRL_READY
1060	li	t8,NIST_FLASH_READY
1061	or	v0,v0,t8
10621:	lw	t8,CC_NAND_INTFC_STATUS(s2)
1063	and	t7,t8,v0
1064	bne	t7,v0,1b
1065	nop
1066
1067	sw	t9,CC_NAND_CMD_ADDR(s2)
1068	lw	t9,CC_NAND_CMD_ADDR(s2)		# read back
1069	li	t9,NCMD_SPARE_RD
1070	sw	t9,CC_NAND_CMD_START(s2)
1071	lw	t9,CC_NAND_CMD_START(s2)	# read back
1072	/* Polling */
1073	li	t9,NIST_CTRL_READY
1074	li	t8,NIST_FLASH_READY
1075	or	t9,t9,t8
10761:	lw	t8,CC_NAND_INTFC_STATUS(s2)
1077	and	t7,t8,t9
1078	bne	t7,t9,1b
1079	nop
1080	/* Check spare valid */
1081	li	t9,NIST_SPARE_VALID
1082	and	t7,t8,t9
1083	beqz	t7,badb
1084	nop
1085	/* Check spare byte */
1086	lw	t9,CC_NAND_SPARE_RD_0(s2)
1087	li	t8,0xff
1088	and	t7,t8,t9
1089	bne	t7,t8,badb
1090	nop
1091	/* Read next page */
1092	add	t9,a0,a1
1093	add	t5,t5,1
1094	beq	t5,1,check_spare
1095	nop
1096
1097	jr	ra
1098	li	v0,0
1099badb:
1100	jr	ra
1101	li	v0,1
1102END(nfl_check_badb)
1103#endif
1104
1105/*  *********************************************************************
1106    *  AI_AMEMCINIT
1107    *
1108    *  AI version of DDR / memory controller initialization
1109    *
1110    *  This routine deals with DDR23_PHY and PL341 MEMC.
1111    *
1112    ********************************************************************* */
1113/* Convenient macro for writing registers (use t0 for base) */
1114#define ddr_write(offset, value)   \
1115    li      a0, (value);           \
1116    sw      a0, offset(t0);
1117
1118LEAF(ai_amemcinit)
1119        .set    noreorder
1120
1121        /*
1122         * ddr23_phy_init
1123         */
1124
1125        li      t0, KSEG1ADDR(AI_DDRPHY_BASE)
1126
1127#ifndef CFG_QUICKTURN
1128
1129        li      t2, 0x10000000
1130        li      t3, 0
1131        li      t5, 0
11322:
1133        /* Do recalibration */
1134        beq     t5, PVT_MAX_RETRY, 9f
1135        lw      t7, DDR23PHY_ZQ_PVT_COMP_CTL(t0)
1136        ddr_write(DDR23PHY_ZQ_PVT_COMP_CTL, 0x04000000);
11371:
1138        /* Wait until sample_done == 1 */
1139        lw      t1, DDR23PHY_ZQ_PVT_COMP_CTL(t0)
1140        and     t1, t1, t2;
1141        beq     t1, zero, 1b
1142        nop
1143
1144        /* Increase total retry count */
1145        add     t5, t5, 1
1146
1147        /* Check if the result is the same as previous one */
1148        lw      t1, DDR23PHY_ZQ_PVT_COMP_CTL(t0)
1149        beq     t1, t7, 3f
1150        nop
1151
1152        /* If not, clear matched count */
1153        b       2b
1154        li      t3, 0
11553:
1156        /* If so, increase matched count; continue if matched count == 3 */
1157        add     t3, t3, 1
1158        bne     t3, PVT_MATCHED_COUNT, 2b
1159        nop
11609:
1161
1162        /* setup PLL */
1163        ddr_write(DDR23PHY_PLL_CONFIG,      0x8000000c);
1164        ddr_write(DDR23PHY_PLL_PRE_DIVIDER,
1165                0x00000011 + (PLL_NDIV_INT_VAL << 8));
1166        ddr_write(DDR23PHY_PLL_DIVIDER,     0x02000000);
1167        ddr_write(DDR23PHY_PLL_CONFIG,      0x80000008);
1168
1169        /* Wait for PLL locked */
1170        li      t2, 1;
11711:      /* Wait until lock == 1 */
1172        lw      t1, DDR23PHY_PLL_STATUS(t0)
1173        and     t1, t1, t2;
1174        beq     t1, zero, 1b
1175        nop
1176
1177        /* De-assert PLL reset */
1178        ddr_write(DDR23PHY_PLL_CONFIG,      0x80000000);
1179        ddr_write(DDR23PHY_PLL_CONFIG,      0x00000000);
1180
1181        /*
1182         * Calibrate VDL
1183         */
1184
1185        /* calib_once + calib_fast (for all BL) */
1186        ddr_write(DDR23PHY_BL3_VDL_CALIBRATE, 0x00000003);
1187        ddr_write(DDR23PHY_BL2_VDL_CALIBRATE, 0x00000003);
1188        ddr_write(DDR23PHY_BL1_VDL_CALIBRATE, 0x00000003);
1189        ddr_write(DDR23PHY_BL0_VDL_CALIBRATE, 0x00000003);
1190
1191        li      t2, 0x0000003;
1192        li      t0, KSEG1ADDR(AI_DDRPHY_BASE)
11931:      /* Wait until calib_idle == 1 and locked for all BL */
1194        lw      t1, DDR23PHY_BL3_VDL_STATUS(t0)
1195        and     t1, t1, t2;
1196        beq     t1, zero, 1b
1197        nop
1198        lw      t1, DDR23PHY_BL2_VDL_STATUS(t0)
1199        and     t1, t1, t2;
1200        beq     t1, zero, 1b
1201        nop
1202        lw      t1, DDR23PHY_BL1_VDL_STATUS(t0)
1203        and     t1, t1, t2;
1204        beq     t1, zero, 1b
1205        nop
1206        lw      t1, DDR23PHY_BL0_VDL_STATUS(t0)
1207        and     t1, t1, t2;
1208        beq     t1, zero, 1b
1209        nop
1210
1211        /* VDL override */
1212        lw      t1, DDR23PHY_BL0_VDL_STATUS(t0)
1213        srl     t1, t1, 8
1214        andi    t2, t1, 0x3f                        /* VDL step size */
1215        li      t1, 1
1216        sll     t1, 16
1217        or      t2, t2, t1                          /* ovr_en */
1218        li      t1, 1
1219        sll     t1, 20
1220        or      t2, t2, t1                          /* ovr_force */
1221        sw      t2, DDR23PHY_STATIC_VDL_OVERRIDE(t0)
1222
1223#endif /* !CFG_QUICKTURN */
1224
1225        /*
1226         * Memory controller PL341 initialization
1227         */
1228
1229        /* De-assert core reset */
1230        move	t0, a2	# AMEMC DMP regs
1231        ddr_write(AI_RESETCTRL, 0x00000000)
1232
1233        move	t0, a1 # AMEMC regs
1234
1235#ifdef CFG_DDR_REFRESH_PRD
1236        /* refresh_prd */
1237        ddr_write(PL341_refresh_prd, MEMCYCLES_MIN(CFG_DDR_REFRESH_PRD));
1238#endif
1239
1240#ifdef CFG_DDR_T_MRD
1241        /* MRD time [6:0] */
1242        ddr_write(PL341_t_mrd, MEMCYCLES(CFG_DDR_T_MRD));
1243#endif
1244
1245#ifdef CFG_DDR_T_RAS
1246        /* ras time [4:0] */
1247        ddr_write(PL341_t_ras, MEMCYCLES(CFG_DDR_T_RAS));
1248#endif
1249
1250#ifdef CFG_DDR_T_RC
1251        /* t_rc [4:0] */
1252        ddr_write(PL341_t_rc, MEMCYCLES(CFG_DDR_T_RC));
1253#endif
1254
1255#ifdef CFG_DDR_T_RCD
1256        /* t_rcd [4:0] */
1257        ddr_write(PL341_t_rcd, MEMCYCLES(CFG_DDR_T_RCD));
1258#endif
1259
1260#ifdef CFG_DDR_T_RFC
1261        /* t_rfc [6:0]  schedule_rfc[14:8] */
1262        ddr_write(PL341_t_rfc,
1263            ((MEMCYCLES(CFG_DDR_T_RFC) - 3) << 8) | MEMCYCLES(CFG_DDR_T_RFC));
1264#endif
1265
1266#ifdef CFG_DDR_T_RP
1267        /* t_rp [3:0] */
1268        ddr_write(PL341_t_rp,
1269            ((MEMCYCLES(CFG_DDR_T_RP) - 3) << 8) | MEMCYCLES(CFG_DDR_T_RP));
1270#endif
1271
1272#ifdef CFG_DDR_T_RRD
1273        /* t_rrd [2:0] */
1274        ddr_write(PL341_t_rrd, MEMCYCLES(CFG_DDR_T_RRD));
1275#endif
1276
1277#ifdef CFG_DDR_T_WR
1278        /* t_wr */
1279        ddr_write(PL341_t_wr, MEMCYCLES(CFG_DDR_T_WR));
1280#endif
1281
1282#ifdef CFG_DDR_T_WTR
1283        /* t_wtr */
1284        ddr_write(PL341_t_wtr, MEMCYCLES(CFG_DDR_T_WTR));
1285#endif
1286
1287#ifdef CFG_DDR_T_XP
1288        /* t_xp[7:0] */
1289        ddr_write(PL341_t_xp, MEMCYCLES(CFG_DDR_T_XP));
1290#endif
1291
1292#ifdef CFG_DDR_T_XSR
1293        /* t_xsr[7:0] */
1294        ddr_write(PL341_t_xsr, MEMCYCLES(CFG_DDR_T_XSR));
1295#endif
1296
1297#ifdef CFG_DDR_T_ESR
1298        /* t_esr[7:0] */
1299        ddr_write(PL341_t_esr, MEMCYCLES(CFG_DDR_T_ESR));
1300#endif
1301
1302#ifdef CFG_DDR_T_FAW
1303        /* t_faw */
1304        ddr_write(PL341_t_faw,
1305            ((MEMCYCLES(CFG_DDR_T_FAW) - 3) << 8) | MEMCYCLES(CFG_DDR_T_FAW));
1306#endif
1307
1308        /* Check if sdram_config is nonzero */
1309        and	t1, s0, 0xffff
1310        bne	t1, $0, sdram_mem_cfg
1311        nop
1312
1313        /* sdram_config is 0, configure by code-default values */
1314        /* Figure out if it's a low cost package */
1315        andi	t1, s1, 0x03
1316
1317        /* Standard package, assume 1024-column, 32-bit, 8-bank DDR */
1318        beq	t1, $0, sdram_mem_cfg
1319        li	s0, (0x0140 | CFG_DDR_CAS_LATENCY)
1320
1321        /* Low cost package, assume 1024-column, 16-bit, 8-bank DDR */
1322        li	s0, (0x01c0 | CFG_DDR_CAS_LATENCY)
1323
1324sdram_mem_cfg:
1325        /* CAS Latency:
1326        *  sdram_config[2:0]: CAS latency
1327        *  PL341_cas_latency[3:1]: CL range from 2 to 6
1328        *  PL341_write_latency[2:0]: CL - 1
1329        */
1330        andi	t1, s0, 0x07
1331        sll	t2, t1, 1
1332        sw	t2, PL341_cas_latency(a1)
1333        subu	t2, t1, 1
1334        sw	t2, PL341_write_latency(a1)
1335
1336        /* PL341_memory_cfg: Rows and Columns */
1337        lw	t2, PL341_memory_cfg(a1)	# Read PL341_memory_cfg
1338
1339        /* Columns:
1340        *  sdram_config[10:8]: 0=2048; 1=1024; 2=512; 3=256 columns
1341        *  PL341_memory_cfg[2:0]: 1=9-bit; 2=10-bit; 3=11-bit; Others=Reserved.
1342        */
1343        li	t3, ~0x7			# columns(bit2:0)
1344        and	t2, t2, t3		# clear column
1345        srl	t1, s0, 8			# Column fields from sdram_config s0(bit10:8)
1346        andi	t1, t1, 0x07
1347        li	t3, 0x3
1348        subu	t1, t3, t1
1349        andi	t1, t1, 0x07
1350        or	t2, t2, t1
1351        sw	t2, PL341_memory_cfg(a1)
1352
1353        /* PL341_memory_cfg2: Bus width and Banks */
1354        lw	t2, PL341_memory_cfg2(a1)	# Read PL341_memory_cfg2
1355
1356        /* Low cost package is 16-bit bus */
1357        andi	t1, s1, 0x03
1358        li	t3, ~0xc0
1359        bne	t1, $0, 2f	# nonzero: low cost package with 16-bit bus
1360        and	t2, t2, t3	# Clear bit[7:6] to work in 16-bit mode
1361
1362        /* Bus width:
1363        *  sdram_config[7]: 0 default bus width, 1: reduced width
1364        *  PL341_memory_cfg2[7:6]: 00 for 16bit, 01=32bit, 10=64bit, 11=reserved
1365        */
1366        andi	t1, s0, 0x80
1367        bne	t1, $0, 2f	# Work in 16-bit mode
1368        nop
1369        or	t2, t2, 0x40	# Set bit[7:6] to 32-bit mode
13702:
1371        /* Banks:
1372        *  sdram_config[6]: 0 for 4 banks, 1 for 8 banks
1373        *  PL341_memory_cfg2[5:4]: 00 for 4 banks, 11 for 8 banks
1374        */
1375        andi	t1, s0, 0x40	# Bank configuration
1376        li	t3, ~0x30
1377        beq	t1, $0, 1f
1378        and	t2, t2, t3	# Clear bit[5:4] to work in 4-bank mode
1379        or	t2, t2, 0x30	# Set bit[5:4] to 11 for 8-bank mode
13801:
1381        sw	t2, PL341_memory_cfg2(a1);
1382
1383        /* chip0 configuration */
1384        ddr_write(PL341_chip_0_cfg, 0x00000000);
1385
1386        /* user_config0 */
1387        ddr_write(PL341_user_config0, 0x00000003);
1388
1389        /*
1390         * DDR2 chip initialization
1391         */
1392
1393        /* Issue NOP */
1394        ddr_write(PL341_direct_cmd, MCHIP_CMD_NOP);
1395
1396        /* issue precharge all */
1397        ddr_write(PL341_direct_cmd, MCHIP_CMD_PRECHARGE_ALL);
1398
1399        /* Set EMR2 */
1400        ddr_write(PL341_direct_cmd, MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(2));
1401
1402        /* Set EMR3 */
1403        ddr_write(PL341_direct_cmd, MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(3));
1404
1405        /* DLL Enable */
1406        ddr_write(PL341_direct_cmd,
1407            MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(1) |
1408            MCHIP_EMR1_DLL_DISABLE(0)
1409            );
1410
1411        /* DLL Reset */
1412        /* Set CAS to external memory devices */
1413        lw	t1, PL341_cas_latency(a1)		# CAS value in bit3:1
1414        li	t2, (MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(0) | \
1415            MCHIP_MR_WRITE_RECOVERY(MEMCYCLES(CFG_DDR_T_WR)) | \
1416            MCHIP_MR_DLL_RESET(1) | MCHIP_MR_BURST_LENGTH)
1417        sll	t1, t1, 3		# Shift to bit6:4 for DDR MRS register
1418        or	t2, t2, t1
1419        sw	t2, PL341_direct_cmd(a1)
1420
1421        /* issue precharge all */
1422        ddr_write(PL341_direct_cmd, MCHIP_CMD_PRECHARGE_ALL);
1423
1424        /* auto-refresh 2 times */
1425        ddr_write(PL341_direct_cmd, MCHIP_CMD_AUTO_REFRESH);
1426        ddr_write(PL341_direct_cmd, MCHIP_CMD_AUTO_REFRESH);
1427
1428        /* DLL Reset=0 (Un-Reset DLL) */
1429        and	t2, t2, ~MCHIP_MR_DLL_RESET(1)
1430        sw	t2, PL341_direct_cmd(a1)
1431
1432        /* DLL Enable & RTT 75ohm */
1433        ddr_write(PL341_direct_cmd,
1434            MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(1) |
1435            MCHIP_EMR1_DLL_DISABLE(0) | MCHIP_EMR1_RTT_75_OHM |
1436            MCHIP_EMR1_OCD_CALI_EXIT
1437            );
1438
1439        /* OCD Defaults */
1440        ddr_write(PL341_direct_cmd,
1441            MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(1) |
1442            MCHIP_EMR1_DLL_DISABLE(0) | MCHIP_EMR1_RTT_75_OHM |
1443            MCHIP_EMR1_OCD_CALI_DEFAULT
1444            );
1445
1446        /* OCD Exit */
1447        ddr_write(PL341_direct_cmd,
1448            MCHIP_CMD_MODE_REG | MCHIP_MODEREG_SEL(1) |
1449            MCHIP_EMR1_DLL_DISABLE(0) | MCHIP_EMR1_RTT_75_OHM |
1450            MCHIP_EMR1_OCD_CALI_EXIT
1451            );
1452
1453        /* set MEMC to GO */
1454        ddr_write(PL341_memc_cmd, 0);
1455        nop
1456        nop
1457
1458        jr      ra
1459        nop
1460
1461        .set    reorder
1462END(ai_amemcinit)
1463