1/*	$NetBSD: arm_pxa2x0.cpp,v 1.2 2008/04/28 20:23:20 martin Exp $	*/
2
3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by UCHIYAMA Yasushi.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <arm/arm_arch.h>
33#include <console.h>
34#include <memory.h>
35#include <arm/arm_pxa2x0.h>
36
37/*
38 * Intel XScale PXA 2x0
39 */
40
41#define	PAGE_SIZE		0x1000
42#define	DRAM_BANK_NUM		4		/* total 256MByte */
43#define	DRAM_BANK_SIZE		0x04000000	/* 64Mbyte */
44
45#define	DRAM_BANK0_START	0xa0000000
46#define	DRAM_BANK0_SIZE		DRAM_BANK_SIZE
47#define	DRAM_BANK1_START	0xa4000000
48#define	DRAM_BANK1_SIZE		DRAM_BANK_SIZE
49#define	DRAM_BANK2_START	0xa8000000
50#define	DRAM_BANK2_SIZE		DRAM_BANK_SIZE
51#define	DRAM_BANK3_START	0xac000000
52#define	DRAM_BANK3_SIZE		DRAM_BANK_SIZE
53#define	ZERO_BANK_START		0xe0000000
54#define	ZERO_BANK_SIZE		DRAM_BANK_SIZE
55
56__BEGIN_DECLS
57
58// 2nd bootloader
59void boot_func_pxa2x0(kaddr_t, kaddr_t, kaddr_t, kaddr_t);
60extern char boot_func_end_pxa2x0[];
61#define	BOOT_FUNC_START		reinterpret_cast <vaddr_t>(boot_func_pxa2x0)
62#define	BOOT_FUNC_END		reinterpret_cast <vaddr_t>(boot_func_end_pxa2x0)
63
64/* jump to 2nd loader */
65void FlatJump_pxa2x0(kaddr_t, kaddr_t, kaddr_t, kaddr_t);
66
67__END_DECLS
68
69PXA2X0Architecture::PXA2X0Architecture(Console *&cons, MemoryManager *&mem)
70	: ARMArchitecture(cons, mem)
71{
72	DPRINTF((TEXT("PXA-2x0 CPU.\n")));
73}
74
75PXA2X0Architecture::~PXA2X0Architecture(void)
76{
77}
78
79BOOL
80PXA2X0Architecture::init(void)
81{
82	if (!_mem->init()) {
83		DPRINTF((TEXT("can't initialize memory manager.\n")));
84		return FALSE;
85	}
86	// set D-RAM information
87	_mem->loadBank(DRAM_BANK0_START, DRAM_BANK_SIZE);
88	_mem->loadBank(DRAM_BANK1_START, DRAM_BANK_SIZE);
89	_mem->loadBank(DRAM_BANK2_START, DRAM_BANK_SIZE);
90	_mem->loadBank(DRAM_BANK3_START, DRAM_BANK_SIZE);
91
92	// set D-cache information
93	dcachesize = 32768 * 2;
94	DPRINTF((TEXT("D-cache size = %d\n"), dcachesize));
95
96#ifdef HW_TEST
97	DPRINTF((TEXT("Testing framebuffer.\n")));
98	testFramebuffer();
99
100	DPRINTF((TEXT("Testing UART.\n")));
101	testUART();
102#endif
103
104#ifdef REGDUMP
105	DPRINTF((TEXT("Dump peripheral registers.\n")));
106	dumpPeripheralRegs();
107#endif
108
109#ifdef CS0DUMP
110	uint32_t dumpsize = 1024 * 1024; // 1MB
111	DPRINTF((TEXT("Dump CS area (size = %d)\n"), dumpsize));
112	dumpCS0(dumpsize);
113#endif
114
115	return TRUE;
116}
117
118void
119PXA2X0Architecture::testFramebuffer(void)
120{
121	DPRINTF((TEXT("No framebuffer test yet.\n")));
122}
123
124void
125PXA2X0Architecture::testUART(void)
126{
127#define	COM_DATA		VOLATILE_REF8(uart + 0x00)
128#define COM_IIR			VOLATILE_REF8(uart + 0x08)
129#define	COM_LSR			VOLATILE_REF8(uart + 0x14)
130#define LSR_TXRDY		0x20
131#define	COM_TX_CHECK		while (!(COM_LSR & LSR_TXRDY))
132#define	COM_PUTCHAR(c)		(COM_DATA = (c))
133#define	COM_CLR_INTS		((void)COM_IIR)
134#define	_(c)								\
135__BEGIN_MACRO								\
136	COM_TX_CHECK;							\
137	COM_PUTCHAR(c);							\
138	COM_TX_CHECK;							\
139	COM_CLR_INTS;							\
140__END_MACRO
141
142	vaddr_t uart =
143	    _mem->mapPhysicalPage(0x40100000, 0x100, PAGE_READWRITE);
144
145	// Don't turn on the enable-UART bit in the IER; this seems to
146	// result in WinCE losing the port (and nothing working later).
147	// All that should be taken care of by using WinCE to open the
148	// port before we actually use it.
149
150	_('H');_('e');_('l');_('l');_('o');_(' ');
151	_('W');_('o');_('r');_('l');_('d');_('\r');_('\n');
152
153	_mem->unmapPhysicalPage(uart);
154}
155
156BOOL
157PXA2X0Architecture::setupLoader(void)
158{
159	vaddr_t v;
160	vsize_t sz = BOOT_FUNC_END - BOOT_FUNC_START;
161
162	// check 2nd bootloader size.
163	if (sz > _mem->getPageSize()) {
164		DPRINTF((TEXT("2nd bootloader size(%dbyte) is larger than page size(%d).\n"),
165		    sz, _mem->getPageSize()));
166		return FALSE;
167	}
168
169	// get physical mapped page and copy loader to there.
170	// don't writeback D-cache here. make sure to writeback before jump.
171	if (!_mem->getPage(v , _loader_addr)) {
172		DPRINTF((TEXT("can't get page for 2nd loader.\n")));
173		return FALSE;
174	}
175	DPRINTF((TEXT("2nd bootloader vaddr=0x%08x paddr=0x%08x\n"),
176	    (unsigned)v,(unsigned)_loader_addr));
177
178	memcpy(reinterpret_cast <LPVOID>(v),
179	    reinterpret_cast <LPVOID>(BOOT_FUNC_START), sz);
180	DPRINTF((TEXT("2nd bootloader copy done.\n")));
181
182	return TRUE;
183}
184
185void
186PXA2X0Architecture::jump(paddr_t info, paddr_t pvec)
187{
188	kaddr_t sp;
189	vaddr_t v;
190	paddr_t p;
191
192	// stack for bootloader
193	_mem->getPage(v, p);
194	sp = ptokv(p) + _mem->getPageSize();
195	DPRINTF((TEXT("sp for bootloader = %08x + %08x = %08x\n"),
196	    ptokv(p), _mem->getPageSize(), sp));
197
198	// writeback whole D-cache
199	WritebackDCache();
200
201	SetKMode(1);
202	FlatJump_pxa2x0(info, pvec, sp, _loader_addr);
203	// NOTREACHED
204	SetKMode(0);
205	DPRINTF((TEXT("Return from FlatJump_pxa2x0.\n")));
206}
207
208
209//
210// dump CS0
211//
212void
213PXA2X0Architecture::dumpCS0(uint32_t size)
214{
215	static char buf[0x1000];
216	vaddr_t mem;
217	uint32_t addr;
218	uint32_t off;
219	HANDLE fh;
220	unsigned long wrote;
221
222	fh = CreateFile(TEXT("rom.bin"), GENERIC_WRITE, FILE_SHARE_READ,
223	    0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
224	if (fh == INVALID_HANDLE_VALUE) {
225		DPRINTF((TEXT("can't open file. (%s)\n"), TEXT("rom.bin")));
226		return;
227	}
228
229	for (addr = 0; addr < size; addr += 0x1000) {
230		memset(buf, 0, sizeof(buf));
231		mem = _mem->mapPhysicalPage(addr, 0x1000, PAGE_READWRITE);
232		for (off = 0; off < 0x1000; off++) {
233			buf[off] = VOLATILE_REF8(mem + off);
234		}
235		_mem->unmapPhysicalPage(mem);
236		WriteFile(fh, buf, 0x1000, &wrote, 0);
237	}
238
239	CloseHandle(fh);
240}
241
242//
243// dump peripheral registers.
244//
245
246#ifdef REGDUMP
247#define	PXA250_GPIO_REG_NUM	3
248#define	PXA250_GPIO_NUM		96
249#define	PXA270_GPIO_REG_NUM	4
250#define	PXA270_GPIO_NUM		121
251
252static const TCHAR *pxa270_gpioName[PXA270_GPIO_NUM][7] =
253{
254/*0*/	{ TEXT("GPIO<0>"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""), },
255/*1*/	{ TEXT("GPIO<1>/nRESET_GPIO"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""), },
256/*2*/	{ TEXT("SYS_EN5"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""), },
257/*3*/	{ TEXT("GPIO<3>/PWR_SCL"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""), },
258/*4*/	{ TEXT("GPIO<4>/PWR_SDA"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""), },
259/*5*/	{ TEXT("PWR_CAP<0>"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""), },
260/*6*/	{ TEXT("PWR_CAP<1>"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""), },
261/*7*/	{ TEXT("PWR_CAP<2>"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""), },
262/*8*/	{ TEXT("PWR_CAP<3>"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""), },
263/*9*/	{ TEXT("GPIO<9>"),TEXT(""),TEXT(""),TEXT("FFCTS"),TEXT("HZ_CLK"),TEXT(""),TEXT("CHOUT<0>"), },
264/*10*/	{ TEXT("GPIO<10>"),TEXT("FFDCD"),TEXT(""),TEXT("USB_P3_57"),TEXT("HZ_CLK"),TEXT(""),TEXT("CHOUT<1>"), },
265/*11*/	{ TEXT("GPIO<11>"),TEXT("EXT_SYNC<0>"),TEXT("SSPRXD2"),TEXT("USB_P3_1"),TEXT("CHOUT<0>"),TEXT("PWM_OUT<2>"),TEXT("48_MHz"), },
266/*12*/	{ TEXT("GPIO<12>"),TEXT("EXT_SYNC<1>"),TEXT("CIF_DD<7>"),TEXT(""),TEXT("CHOUT<1>"),TEXT("PWM_OUT<3>"),TEXT("48_MHz"), },
267/*13*/	{ TEXT("GPIO<13>"),TEXT("CLK_EXT"),TEXT("KP_DKIN<7>"),TEXT("KP_MKIN<7>"),TEXT("SSPTXD2"),TEXT(""),TEXT(""), },
268/*14*/	{ TEXT("GPIO<14>"),TEXT("L_VSYNC"),TEXT("SSPSFRM2"),TEXT(""),TEXT(""),TEXT("SSPSFRM2"),TEXT("UCLK"), },
269/*15*/	{ TEXT("GPIO<15>"),TEXT(""),TEXT(""),TEXT(""),TEXT("nPCE<1>"),TEXT("nCS<1>"),TEXT(""), },
270/*16*/	{ TEXT("GPIO<16>"),TEXT("KP_MKIN<5>"),TEXT(""),TEXT(""),TEXT(""),TEXT("PWM_OUT<0>"),TEXT("FFTXD"), },
271/*17*/	{ TEXT("GPIO<17>"),TEXT("KP_MKIN<6>"),TEXT("CIF_DD<6>"),TEXT(""),TEXT(""),TEXT("PWM_OUT<1>"),TEXT(""), },
272/*18*/	{ TEXT("GPIO<18>"),TEXT("RDY"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""), },
273/*19*/	{ TEXT("GPIO<19>"),TEXT("SSPSCLK2"),TEXT(""),TEXT("FFRXD"),TEXT("SSPSCLK2"),TEXT("L_CS"),TEXT("nURST"), },
274/*20*/	{ TEXT("GPIO<20>"),TEXT("DREQ<0>"),TEXT("MBREQ"),TEXT(""),TEXT("nSDCS<2>"),TEXT(""),TEXT(""), },
275/*21*/	{ TEXT("GPIO<21>"),TEXT(""),TEXT(""),TEXT(""),TEXT("nSDCS<3>"),TEXT("DVAL<0>"),TEXT("MBGNT"), },
276/*22*/	{ TEXT("GPIO<22>"),TEXT("SSPEXTCLK2"),TEXT("SSPSCLK2EN"),TEXT("SSPSCLK2"),TEXT("KP_MKOUT<7>"),TEXT("SSPSYSCLK2"),TEXT("SSPSCLK2"), },
277/*23*/	{ TEXT("GPIO<23>"),TEXT(""),TEXT("SSPSCLK"),TEXT(""),TEXT("CIF_MCLK"),TEXT("SSPSCLK"),TEXT(""), },
278/*24*/	{ TEXT("GPIO<24>"),TEXT("CIF_FV"),TEXT("SSPSFRM"),TEXT(""),TEXT("CIF_FV"),TEXT("SSPSFRM"),TEXT(""), },
279/*25*/	{ TEXT("GPIO<25>"),TEXT("CIF_LV"),TEXT(""),TEXT(""),TEXT("CIF_LV"),TEXT("SSPTXD"),TEXT(""), },
280/*26*/	{ TEXT("GPIO<26>"),TEXT("SSPRXD"),TEXT("CIF_PCLK"),TEXT("FFCTS"),TEXT(""),TEXT(""),TEXT(""), },
281/*27*/	{ TEXT("GPIO<27>"),TEXT("SSPEXTCLK"),TEXT("SSPSCLKEN"),TEXT("CIF_DD<0>"),TEXT("SSPSYSCLK"),TEXT(""),TEXT("FFRTS"), },
282/*28*/	{ TEXT("GPIO<28>"),TEXT("AC97_BITCLK"),TEXT("I2S_BITCLK"),TEXT("SSPSFRM"),TEXT("I2S_BITCLK"),TEXT(""),TEXT("SSPSFRM"), },
283/*29*/	{ TEXT("GPIO<29>"),TEXT("AC97_SDATA_IN_0"),TEXT("I2S_SDATA_IN"),TEXT("SSPSCLK"),TEXT("SSPRXD2"),TEXT(""),TEXT("SSPSCLK"), },
284/*30*/	{ TEXT("GPIO<30>"),TEXT(""),TEXT(""),TEXT(""),TEXT("I2S_SDATA_OUT"),TEXT("AC97_SDATA_OUT"),TEXT("USB_P3_2"), },
285/*31*/	{ TEXT("GPIO<31>"),TEXT(""),TEXT(""),TEXT(""),TEXT("I2S_SYNC"),TEXT("AC97_SYNC"),TEXT("USB_P3_6"), },
286/*32*/	{ TEXT("GPIO<32>"),TEXT(""),TEXT(""),TEXT(""),TEXT("MSSCLK"),TEXT("MMCLK"),TEXT(""), },
287/*33*/	{ TEXT("GPIO<33>"),TEXT("FFRXD"),TEXT("FFDSR"),TEXT(""),TEXT("DVAL<1>"),TEXT("nCS<5>"),TEXT("MBGNT"), },
288/*34*/	{ TEXT("GPIO<34>"),TEXT("FFRXD"),TEXT("KP_MKIN<3>"),TEXT("SSPSCLK3"),TEXT("USB_P2_2"),TEXT(""),TEXT("SSPSCLK3"), },
289/*35*/	{ TEXT("GPIO<35>"),TEXT("FFCTS"),TEXT("USB_P2_1"),TEXT("SSPSFRM3"),TEXT(""),TEXT("KP_MKOUT<6>"),TEXT("SSPTXD3"), },
290/*36*/	{ TEXT("GPIO<36>"),TEXT("FFDCD"),TEXT("SSPSCLK2"),TEXT("KP_MKIN<7>"),TEXT("USB_P2_4"),TEXT("SSPSCLK2"),TEXT(""), },
291/*37*/	{ TEXT("GPIO<37>"),TEXT("FFDSR"),TEXT("SSPSFRM2"),TEXT("KP_MKIN<3>"),TEXT("USB_P2_8"),TEXT("SSPSFRM2"),TEXT("FFTXD"), },
292/*38*/	{ TEXT("GPIO<38>"),TEXT("FFRI"),TEXT("KP_MKIN<4>"),TEXT("USB_P2_3"),TEXT("SSPTXD3"),TEXT("SSPTXD2"),TEXT("PWM_OUT<1>"), },
293/*39*/	{ TEXT("GPIO<39>"),TEXT("KP_MKIN<4>"),TEXT(""),TEXT("SSPSFRM3"),TEXT("USB_P2_6"),TEXT("FFTXD"),TEXT("SSPSFRM3"), },
294/*40*/	{ TEXT("GPIO<40>"),TEXT("SSPRXD2"),TEXT(""),TEXT("USB_P2_5"),TEXT("KP_MKOUT<6>"),TEXT("FFDTR"),TEXT("SSPSCLK3"), },
295/*41*/	{ TEXT("GPIO<41>"),TEXT("FFRXD"),TEXT("USB_P2_7"),TEXT("SSPRXD3"),TEXT("KP_MKOUT<7>"),TEXT("FFRTS"),TEXT(""), },
296/*42*/	{ TEXT("GPIO<42>"),TEXT("BTRXD"),TEXT("ICP_RXD"),TEXT(""),TEXT(""),TEXT(""),TEXT("CIF_MCLK"), },
297/*43*/	{ TEXT("GPIO<43>"),TEXT(""),TEXT(""),TEXT("CIF_FV"),TEXT("ICP_TXD"),TEXT("BTTXD"),TEXT("CIF_FV"), },
298/*44*/	{ TEXT("GPIO<44>"),TEXT("BTCTS"),TEXT(""),TEXT("CIF_LV"),TEXT(""),TEXT(""),TEXT("CIF_LV"), },
299/*45*/	{ TEXT("GPIO<45>"),TEXT(""),TEXT(""),TEXT("CIF_PCLK"),TEXT("AC97_SYSCLK"),TEXT("BTRTS"),TEXT("SSPSYSCLK3"), },
300/*46*/	{ TEXT("GPIO<46>"),TEXT("ICP_RXD"),TEXT("STD_RXD"),TEXT(""),TEXT(""),TEXT("PWM_OUT<2>"),TEXT(""), },
301/*47*/	{ TEXT("GPIO<47>"),TEXT("CIF_DD<0>"),TEXT(""),TEXT(""),TEXT("STD_TXD"),TEXT("ICP_TXD"),TEXT("PWM_OUT<3>"), },
302/*48*/	{ TEXT("GPIO<48>"),TEXT("CIF_DD<5>"),TEXT(""),TEXT(""),TEXT("BB_OB_DAT<1>"),TEXT("nPOE"),TEXT(""), },
303/*49*/	{ TEXT("GPIO<49>"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT("nPWE"),TEXT(""), },
304/*50*/	{ TEXT("GPIO<50>"),TEXT("CIF_DD<3>"),TEXT(""),TEXT("SSPSCLK2"),TEXT("BB_OB_DAT<2>"),TEXT("nPIOR"),TEXT("SSPSCLK2"), },
305/*51*/	{ TEXT("GPIO<51>"),TEXT("CIF_DD<2>"),TEXT(""),TEXT(""),TEXT("BB_OB_DAT<3>"),TEXT("nPIOW"),TEXT(""), },
306/*52*/	{ TEXT("GPIO<52>"),TEXT("CIF_DD<4>"),TEXT("SSPSCLK3"),TEXT(""),TEXT("BB_OB_CLK"),TEXT("SSPSCLK3"),TEXT(""), },
307/*53*/	{ TEXT("GPIO<53>"),TEXT("FFRXD"),TEXT("USB_P2_3"),TEXT(""),TEXT("BB_OB_STB"),TEXT("CIF_MCLK"),TEXT("SSPSYSCLK"), },
308/*54*/	{ TEXT("GPIO<54>"),TEXT(""),TEXT("BB_OB_WAIT"),TEXT("CIF_PCLK"),TEXT(""),TEXT("nPCE<2>"),TEXT(""), },
309/*55*/	{ TEXT("GPIO<55>"),TEXT("CIF_DD<1>"),TEXT("BB_IB_DAT<1>"),TEXT(""),TEXT(""),TEXT("nPREG"),TEXT(""), },
310/*56*/	{ TEXT("GPIO<56>"),TEXT("nPWAIT"),TEXT("BB_IB_DAT<2>"),TEXT(""),TEXT("USB_P3_4"),TEXT(""),TEXT(""), },
311/*57*/	{ TEXT("GPIO<57>"),TEXT("nIOIS16"),TEXT("BB_IB_DAT<3>"),TEXT(""),TEXT(""),TEXT(""),TEXT("SSPTXD"), },
312/*58*/	{ TEXT("GPIO<58>"),TEXT(""),TEXT("LDD<0>"),TEXT(""),TEXT(""),TEXT("LDD<0>"),TEXT(""), },
313/*59*/	{ TEXT("GPIO<59>"),TEXT(""),TEXT("LDD<1>"),TEXT(""),TEXT(""),TEXT("LDD<1>"),TEXT(""), },
314/*60*/	{ TEXT("GPIO<60>"),TEXT(""),TEXT("LDD<2>"),TEXT(""),TEXT(""),TEXT("LDD<2>"),TEXT(""), },
315/*61*/	{ TEXT("GPIO<61>"),TEXT(""),TEXT("LDD<3>"),TEXT(""),TEXT(""),TEXT("LDD<3>"),TEXT(""), },
316/*62*/	{ TEXT("GPIO<62>"),TEXT(""),TEXT("LDD<4>"),TEXT(""),TEXT(""),TEXT("LDD<4>"),TEXT(""), },
317/*63*/	{ TEXT("GPIO<63>"),TEXT(""),TEXT("LDD<5>"),TEXT(""),TEXT(""),TEXT("LDD<5>"),TEXT(""), },
318/*64*/	{ TEXT("GPIO<64>"),TEXT(""),TEXT("LDD<6>"),TEXT(""),TEXT(""),TEXT("LDD<6>"),TEXT(""), },
319/*65*/	{ TEXT("GPIO<65>"),TEXT(""),TEXT("LDD<7>"),TEXT(""),TEXT(""),TEXT("LDD<7>"),TEXT(""), },
320/*66*/	{ TEXT("GPIO<66>"),TEXT(""),TEXT("LDD<8>"),TEXT(""),TEXT(""),TEXT("LDD<8>"),TEXT(""), },
321/*67*/	{ TEXT("GPIO<67>"),TEXT(""),TEXT("LDD<9>"),TEXT(""),TEXT(""),TEXT("LDD<9>"),TEXT(""), },
322/*68*/	{ TEXT("GPIO<68>"),TEXT(""),TEXT("LDD<10>"),TEXT(""),TEXT(""),TEXT("LDD<10>"),TEXT(""), },
323/*69*/	{ TEXT("GPIO<69>"),TEXT(""),TEXT("LDD<11>"),TEXT(""),TEXT(""),TEXT("LDD<11>"),TEXT(""), },
324/*70*/	{ TEXT("GPIO<70>"),TEXT(""),TEXT("LDD<12>"),TEXT(""),TEXT(""),TEXT("LDD<12>"),TEXT(""), },
325/*71*/	{ TEXT("GPIO<71>"),TEXT(""),TEXT("LDD<13>"),TEXT(""),TEXT(""),TEXT("LDD<13>"),TEXT(""), },
326/*72*/	{ TEXT("GPIO<72>"),TEXT(""),TEXT("LDD<14>"),TEXT(""),TEXT(""),TEXT("LDD<14>"),TEXT(""), },
327/*73*/	{ TEXT("GPIO<73>"),TEXT(""),TEXT("LDD<15>"),TEXT(""),TEXT(""),TEXT("LDD<15>"),TEXT(""), },
328/*74*/	{ TEXT("GPIO<74>"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT("L_FCLK_RD"),TEXT(""), },
329/*75*/	{ TEXT("GPIO<75>"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT("L_LCLK_A0"),TEXT(""), },
330/*76*/	{ TEXT("GPIO<76>"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT("L_PCLK_WR"),TEXT(""), },
331/*77*/	{ TEXT("GPIO<77>"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT("L_BIAS"),TEXT(""), },
332/*78*/	{ TEXT("GPIO<78>"),TEXT(""),TEXT(""),TEXT(""),TEXT("nPCE<2>"),TEXT("nCS<2>"),TEXT(""), },
333/*79*/	{ TEXT("GPIO<79>"),TEXT(""),TEXT(""),TEXT(""),TEXT("PSKTSEL"),TEXT("nCS<3>"),TEXT("PWM_OUT<2>"), },
334/*80*/	{ TEXT("GPIO<80>"),TEXT("DREQ<1>"),TEXT("MBREQ"),TEXT(""),TEXT(""),TEXT("nCS<4>"),TEXT("PWM_OUT<3>"), },
335/*81*/	{ TEXT("GPIO<81>"),TEXT(""),TEXT("CIF_DD<0>"),TEXT(""),TEXT("SSPTXD3"),TEXT("BB_OB_DAT<0>"),TEXT(""), },
336/*82*/	{ TEXT("GPIO<82>"),TEXT("SSPRXD3"),TEXT("BB_IB_DAT<0>"),TEXT("CIF_DD<5>"),TEXT(""),TEXT(""),TEXT("FFDTR"), },
337/*83*/	{ TEXT("GPIO<83>"),TEXT("SSPSFRM3"),TEXT("BB_IB_CLK"),TEXT("CIF_DD<4>"),TEXT("SSPSFRM3"),TEXT("FFTXD"),TEXT("FFRTS"), },
338/*84*/	{ TEXT("GPIO<84>"),TEXT("SSPCLK3"),TEXT("BB_IB_STB"),TEXT("CIF_FV"),TEXT("SSPCLK3"),TEXT(""),TEXT("CIF_FV"), },
339/*85*/	{ TEXT("GPIO<85>"),TEXT("FFRXD"),TEXT("DREQ<2>"),TEXT("CIF_LV"),TEXT("nPCE<1>"),TEXT("BB_IB_WAIT"),TEXT("CIF_LV"), },
340/*86*/	{ TEXT("GPIO<86>"),TEXT("SSPRXD2"),TEXT("LDD<16>"),TEXT("USB_P3_5"),TEXT("nPCE<1>"),TEXT("LDD<16>"),TEXT(""), },
341/*87*/	{ TEXT("GPIO<87>"),TEXT("nPCE<2>"),TEXT("LDD<17>"),TEXT("USB_P3_1"),TEXT("SSPTXD2"),TEXT("LDD<17>"),TEXT("SSPSFRM2"), },
342/*88*/	{ TEXT("GPIO<88>"),TEXT("USBHPWR<1>"),TEXT("SSPRXD2"),TEXT("SSPSFRM2"),TEXT(""),TEXT(""),TEXT("SSPSFRM2"), },
343/*89*/	{ TEXT("GPIO<89>"),TEXT("SSPRXD3"),TEXT(""),TEXT("FFRI"),TEXT("AC97_SYSCLK"),TEXT("USBHPEN<1>"),TEXT("SSPTXD2"), },
344/*90*/	{ TEXT("GPIO<90>"),TEXT("KP_MKIN<5>"),TEXT("USB_P3_5"),TEXT("CIF_DD<4>"),TEXT(""),TEXT("nURST"),TEXT(""), },
345/*91*/	{ TEXT("GPIO<91>"),TEXT("KP_MKIN<6>"),TEXT("USB_P3_1"),TEXT("CIF_DD<5>"),TEXT(""),TEXT("UCLK"),TEXT(""), },
346/*92*/	{ TEXT("GPIO<92>"),TEXT("MMDAT<0>"),TEXT(""),TEXT(""),TEXT("MMDAT<0>"),TEXT("MSBS"),TEXT(""), },
347/*93*/	{ TEXT("GPIO<93>"),TEXT("KP_DKIN<0>"),TEXT("CIF_DD<6>"),TEXT(""),TEXT("AC97_SDATA_OUT"),TEXT(""),TEXT(""), },
348/*94*/	{ TEXT("GPIO<94>"),TEXT("KP_DKIN<1>"),TEXT("CIF_DD<5>"),TEXT(""),TEXT("AC97_SYNC"),TEXT(""),TEXT(""), },
349/*95*/	{ TEXT("GPIO<95>"),TEXT("KP_DKIN<2>"),TEXT("CIF_DD<4>"),TEXT("KP_MKIN<6>"),TEXT("AC97_RESET_n"),TEXT(""),TEXT(""), },
350/*96*/	{ TEXT("GPIO<96>"),TEXT("KP_DKIN<3>"),TEXT("MBREQ"),TEXT("FFRXD"),TEXT(""),TEXT("DVAL<1>"),TEXT("KP_MKOUT<6>"), },
351/*97*/	{ TEXT("GPIO<97>"),TEXT("KP_DKIN<4>"),TEXT("DREQ<1>"),TEXT("KP_MKIN<3>"),TEXT(""),TEXT("MBGNT"),TEXT(""), },
352/*98*/	{ TEXT("GPIO<98>"),TEXT("KP_DKIN<5>"),TEXT("CIF_DD<0>"),TEXT("KP_MKIN<4>"),TEXT("AC97_SYSCLK"),TEXT(""),TEXT("FFRTS"), },
353/*99*/	{ TEXT("GPIO<99>"),TEXT("KP_DKIN<6>"),TEXT("AC97_SDATA_IN_1"),TEXT("KP_MKIN<5>"),TEXT(""),TEXT(""),TEXT("FFTXD"), },
354/*100*/	{ TEXT("GPIO<100>"),TEXT("KP_MKIN<0>"),TEXT("DREQ<2>"),TEXT("FFCTS"),TEXT(""),TEXT(""),TEXT(""), },
355/*101*/	{ TEXT("GPIO<101>"),TEXT("KP_MKIN<1>"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""), },
356/*102*/	{ TEXT("GPIO<102>"),TEXT("KP_MKIN<2>"),TEXT(""),TEXT("FFRXD"),TEXT("nPCE<1>"),TEXT(""),TEXT(""), },
357/*103*/	{ TEXT("GPIO<103>"),TEXT("CIF_DD<3>"),TEXT(""),TEXT(""),TEXT(""),TEXT("KP_MKOUT<0>"),TEXT(""), },
358/*104*/	{ TEXT("GPIO<104>"),TEXT("CIF_DD<2>"),TEXT(""),TEXT(""),TEXT("PSKTSEL"),TEXT("KP_MKOUT<1>"),TEXT(""), },
359/*105*/	{ TEXT("GPIO<105>"),TEXT("CIF_DD<1>"),TEXT(""),TEXT(""),TEXT("nPCE<2>"),TEXT("KP_MKOUT<2>"),TEXT(""), },
360/*106*/	{ TEXT("GPIO<106>"),TEXT("CIF_DD<9>"),TEXT(""),TEXT(""),TEXT(""),TEXT("KP_MKOUT<3>"),TEXT(""), },
361/*107*/	{ TEXT("GPIO<107>"),TEXT("CIF_DD<8>"),TEXT(""),TEXT(""),TEXT(""),TEXT("KP_MKOUT<4>"),TEXT(""), },
362/*108*/	{ TEXT("GPIO<108>"),TEXT("CIF_DD<7>"),TEXT(""),TEXT(""),TEXT("CHOUT<0>"),TEXT("KP_MKOUT<5>"),TEXT(""), },
363/*109*/	{ TEXT("GPIO<109>"),TEXT("MMDAT<1>"),TEXT("MSSDIO"),TEXT(""),TEXT("MMDAT<1>"),TEXT("MSSDIO"),TEXT(""), },
364/*110*/	{ TEXT("GPIO<110>"),TEXT("MMDAT<2>/MMCCS<0>"),TEXT(""),TEXT(""),TEXT("MMDAT<2>/MMCCS<0>"),TEXT(""),TEXT(""), },
365/*111*/	{ TEXT("GPIO<111>"),TEXT("MMDAT<3>/MMCCS<1>"),TEXT(""),TEXT(""),TEXT("MMDAT<3>/MMCCS<1>"),TEXT(""),TEXT(""), },
366/*112*/	{ TEXT("GPIO<112>"),TEXT("MMCMD"),TEXT("nMSINS"),TEXT(""),TEXT("MMCMD"),TEXT(""),TEXT(""), },
367/*113*/	{ TEXT("GPIO<113>"),TEXT(""),TEXT(""),TEXT("USB_P3_3"),TEXT("I2S_SYSCLK"),TEXT("AC97_RESET_n"),TEXT(""), },
368/*114*/	{ TEXT("GPIO<114>"),TEXT("CIF_DD<1>"),TEXT(""),TEXT(""),TEXT("UEN"),TEXT("UVS0"),TEXT(""), },
369/*115*/	{ TEXT("GPIO<115>"),TEXT("DREQ<0>"),TEXT("CIF_DD<3>"),TEXT("MBREQ"),TEXT("UEN"),TEXT("nUVS1"),TEXT("PWM_OUT<1>"), },
370/*116*/	{ TEXT("GPIO<116>"),TEXT("CIF_DD<2>"),TEXT("AC97_SDATA_IN_0"),TEXT("UDET"),TEXT("DVAL<0>"),TEXT("nUVS2"),TEXT("MBGNT"), },
371/*117*/	{ TEXT("GPIO<117>"),TEXT("SCL"),TEXT(""),TEXT(""),TEXT("SCL"),TEXT(""),TEXT(""), },
372/*118*/	{ TEXT("GPIO<118>"),TEXT("SDA"),TEXT(""),TEXT(""),TEXT("SDA"),TEXT(""),TEXT(""), },
373/*119*/	{ TEXT("GPIO<119>"),TEXT("USBHPWR<2>"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""), },
374/*120*/	{ TEXT("GPIO<120>"),TEXT("USBHPEN<2>"),TEXT(""),TEXT(""),TEXT(""),TEXT(""),TEXT(""), },
375};
376#endif
377
378void
379PXA2X0Architecture::dumpPeripheralRegs(void)
380{
381#ifdef REGDUMP
382	uint32_t reg;
383	bool first;
384	int i, n;
385
386#define	GPIO_OFFSET(r,o) ((r == 3) ? (o + 0x100) : (o + (r * 4)))
387	// GPIO
388	if (platid_match(&platid, &platid_mask_CPU_ARM_XSCALE_PXA270))
389		n = PXA270_GPIO_REG_NUM;
390	else
391		n = PXA250_GPIO_REG_NUM;
392
393	vaddr_t gpio =
394	    _mem->mapPhysicalPage(0x40e00000, 0x1000, PAGE_READWRITE);
395	DPRINTF((TEXT("Dump GPIO registers.\n")));
396	for (i = 0; i < n; i++) {
397		reg = VOLATILE_REF(gpio + GPIO_OFFSET(i, 0x00));
398		DPRINTF((TEXT("GPLR%d: 0x%08x\n"), i, reg));
399	}
400	for (i = 0; i < n; i++) {
401		reg = VOLATILE_REF(gpio + GPIO_OFFSET(i, 0x0c));
402		DPRINTF((TEXT("GPDR%d: 0x%08x\n"), i, reg));
403	}
404#if 0	/* write-only register */
405	for (i = 0; i < n; i++) {
406		reg = VOLATILE_REF(gpio + GPIO_OFFSET(i, 0x18));
407		DPRINTF((TEXT("GPSR%d: 0x%08x\n"), reg));
408	}
409	for (i = 0; i < n; i++) {
410		reg = VOLATILE_REF(gpio + GPIO_OFFSET(i, 0x24));
411		DPRINTF((TEXT("GPCR%d: 0x%08x\n"), reg));
412	}
413#endif
414	for (i = 0; i < n; i++) {
415		reg = VOLATILE_REF(gpio + GPIO_OFFSET(i, 0x30));
416		DPRINTF((TEXT("GRER%d: 0x%08x\n"), i, reg));
417	}
418	for (i = 0; i < n; i++) {
419		reg = VOLATILE_REF(gpio + GPIO_OFFSET(i, 0x3c));
420		DPRINTF((TEXT("GFER%d: 0x%08x\n"), i, reg));
421	}
422	for (i = 0; i < n; i++) {
423		reg = VOLATILE_REF(gpio + GPIO_OFFSET(i, 0x48));
424		DPRINTF((TEXT("GEDR%d: 0x%08x\n"), i, reg));
425	}
426	for (i = 0; i < n; i++) {
427		reg = VOLATILE_REF(gpio + 0x54 + (i * 8));
428		DPRINTF((TEXT("GAFR%d_L: 0x%08x\n"), i, reg));
429		reg = VOLATILE_REF(gpio + 0x58 + (i * 8));
430		DPRINTF((TEXT("GAFR%d_U: 0x%08x\n"), i, reg));
431	}
432
433	//
434	// display detail
435	//
436
437	if (!platid_match(&platid, &platid_mask_CPU_ARM_XSCALE_PXA270))
438		return;
439
440	// header
441	DPRINTF((TEXT("pin#,function,name,rising,falling,status\n")));
442
443	n = PXA270_GPIO_NUM;
444	for (i = 0; i < n; i++) {
445		const TCHAR *fn_name, *pin_name;
446		uint32_t dir, altfn, redge, fedge, status;
447
448		// pin function
449		dir = VOLATILE_REF(gpio + GPIO_OFFSET(i, 0x0c));
450		dir = (dir >> (i % 32)) & 1;
451		altfn = VOLATILE_REF(gpio + 0x54 + ((i / 16) * 4));
452		altfn = (altfn >> ((i % 16) * 2)) & 3;
453		if (altfn == 0) {
454			if (dir == 0) {
455				fn_name = TEXT("GPIO_IN");
456			} else {
457				fn_name = TEXT("GPIO_OUT");
458			}
459			DPRINTF((TEXT("%d,%s,%s,"), i, fn_name,
460			    pxa270_gpioName[i][0]));
461		} else {
462			if (dir == 0) {
463				fn_name = TEXT("IN");
464				pin_name = pxa270_gpioName[i][altfn];
465			} else {
466				fn_name = TEXT("OUT");
467				pin_name = pxa270_gpioName[i][altfn+3];
468			}
469			DPRINTF((TEXT("%d,ALT_FN_%d_%s,%s,"), i, altfn,
470			    fn_name, pin_name));
471		}
472
473		// edge detect
474		redge = VOLATILE_REF(gpio + GPIO_OFFSET(i, 0x30));
475		redge = (redge >> (i % 32)) & 1;
476		fedge = VOLATILE_REF(gpio + GPIO_OFFSET(i, 0x3c));
477		fedge = (fedge >> (i % 32)) & 1;
478		DPRINTF((TEXT("%s,%s,"),
479		    redge ? TEXT("enable") : TEXT("disable"),
480		    fedge ? TEXT("enable") : TEXT("disable")));
481
482		// status
483		status = VOLATILE_REF(gpio + GPIO_OFFSET(i, 0x00));
484		status = (status >> (i % 32)) & 1;
485		DPRINTF((TEXT("%s"), status ? TEXT("high") : TEXT("low")));
486
487		DPRINTF((TEXT("\n")));
488	}
489	_mem->unmapPhysicalPage(gpio);
490
491	// LCDC
492	DPRINTF((TEXT("Dump LCDC registers.\n")));
493	vaddr_t lcdc =
494	    _mem->mapPhysicalPage(0x44000000, 0x1000, PAGE_READWRITE);
495	reg = VOLATILE_REF(lcdc + 0x00);
496	DPRINTF((TEXT("LCCR0: 0x%08x\n"), reg));
497	DPRINTF((TEXT("-> ")));
498	first = true;
499	if (reg & (1U << 26)) {
500		DPRINTF((TEXT("%sLDDALT"), first ? TEXT("") : TEXT("/")));
501		first = false;
502	}
503	if (reg & (1U << 25)) {
504		DPRINTF((TEXT("%sOUC"), first ? TEXT("") : TEXT("/")));
505		first = false;
506	}
507	if (reg & (1U << 22)) {
508		DPRINTF((TEXT("%sLCDT"), first ? TEXT("") : TEXT("/")));
509		first = false;
510	}
511	if (reg & (1U << 9)) {
512		DPRINTF((TEXT("%sDPD"), first ? TEXT("") : TEXT("/")));
513		first = false;
514	}
515	if (reg & (1U << 7)) {
516		DPRINTF((TEXT("%sPAS"), first ? TEXT("") : TEXT("/")));
517		first = false;
518	}
519	if (reg & (1U << 2)) {
520		DPRINTF((TEXT("%sSDS"), first ? TEXT("") : TEXT("/")));
521		first = false;
522	}
523	if (reg & (1U << 1)) {
524		DPRINTF((TEXT("%sCMS"), first ? TEXT("") : TEXT("/")));
525		first = false;
526	}
527	if (reg & (1U << 0)) {
528		DPRINTF((TEXT("%sENB"), first ? TEXT("") : TEXT("/")));
529		first = false;
530	}
531	DPRINTF((TEXT("\n")));
532	DPRINTF((TEXT("-> PDD = 0x%02x\n"), (reg >> 12) & 0xff));
533	reg = VOLATILE_REF(lcdc + 0x04);
534	DPRINTF((TEXT("LCCR1: 0x%08x\n"), reg));
535	DPRINTF((TEXT("-> BLW = 0x%02x, ELW = 0x%02x, HSW = 0x%02x, PPL = 0x%03x\n"),
536	    (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 10) & 0x3f,
537	    reg & 0x3ff));
538	reg = VOLATILE_REF(lcdc + 0x08);
539	DPRINTF((TEXT("LCCR2: 0x%08x\n"), reg));
540	DPRINTF((TEXT("-> BFW = 0x%02x, EFW = 0x%02x, VSW = 0x%02x, LPP = 0x%03x\n"),
541	    (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 10) & 0x3f,
542	    reg & 0x3ff));
543	reg = VOLATILE_REF(lcdc + 0x0c);
544	DPRINTF((TEXT("LCCR3: 0x%08x\n"), reg));
545	DPRINTF((TEXT("-> ")));
546	first = true;
547	if (reg & (1U << 27)) {
548		DPRINTF((TEXT("%sDPC"), first ? TEXT("") : TEXT("/")));
549		first = false;
550	}
551	if (reg & (1U << 23)) {
552		DPRINTF((TEXT("%sOEP"), first ? TEXT("") : TEXT("/")));
553		first = false;
554	}
555	if (reg & (1U << 22)) {
556		DPRINTF((TEXT("%sPCP"), first ? TEXT("") : TEXT("/")));
557		first = false;
558	}
559	if (reg & (1U << 21)) {
560		DPRINTF((TEXT("%sHSP"), first ? TEXT("") : TEXT("/")));
561		first = false;
562	}
563	if (reg & (1U << 20)) {
564		DPRINTF((TEXT("%sVSP"), first ? TEXT("") : TEXT("/")));
565		first = false;
566	}
567	if (reg & (1U << 19)) {
568		DPRINTF((TEXT("%sVSP"), first ? TEXT("") : TEXT("/")));
569		first = false;
570	}
571	DPRINTF((TEXT("\n")));
572	DPRINTF((TEXT("-> PDFOR = %d\n"), (reg >> 30) & 3));
573	DPRINTF((TEXT("-> BPP = 0x%02x\n"), ((reg >> 29) & 1 << 3) | ((reg >> 24) & 7)));
574	DPRINTF((TEXT("-> API = 0x%x\n"), (reg >> 16) & 0xf));
575	DPRINTF((TEXT("-> ACB = 0x%02x\n"), (reg >> 8) & 0xff));
576	DPRINTF((TEXT("-> PCD = 0x%02x\n"), reg & 0xff));
577	reg = VOLATILE_REF(lcdc + 0x10);
578	DPRINTF((TEXT("LCCR4: 0x%08x\n"), reg));
579	DPRINTF((TEXT("-> PCDDIV = %d\n"), (reg >> 31) & 1));
580	DPRINTF((TEXT("-> PAL_FOR = %d\n"), (reg >> 15) & 3));
581	DPRINTF((TEXT("-> K3 = 0x%x, K2 = 0x%x, K1 = 0x%x\n"),
582	    (reg >> 6) & 7, (reg >> 3) & 7, reg & 7));
583	reg = VOLATILE_REF(lcdc + 0x14);
584	DPRINTF((TEXT("LCCR5: 0x%08x\n"), reg));
585	reg = VOLATILE_REF(lcdc + 0x54);
586	DPRINTF((TEXT("LCDBSCNTR: 0x%08x\n"), reg));
587	_mem->unmapPhysicalPage(lcdc);
588#endif
589}
590