xref: /netbsd/sys/arch/arm/xscale/pxa2x0.c (revision c4a72b64)
1 /*	$NetBSD: pxa2x0.c,v 1.1 2002/10/19 19:31:38 bsh Exp $ */
2 
3 /*
4  * Copyright (c) 2002  Genetec Corporation.  All rights reserved.
5  * Written by Hiroyuki Bessho for Genetec Corporation.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed for the NetBSD Project by
18  *	Genetec Corporation.
19  * 4. The name of Genetec Corporation may not be used to endorse or
20  *    promote products derived from this software without specific prior
21  *    written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
27  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  *
36  * Autoconfiguration support for the Intel PXA2[15]0 application
37  * processor. This code is derived from arm/sa11x0/sa11x0.c
38  */
39 
40 /*-
41  * Copyright (c) 2001, The NetBSD Foundation, Inc.  All rights reserved.
42  *
43  * This code is derived from software contributed to The NetBSD Foundation
44  * by IWAMOTO Toshihiro and Ichiro FUKUHARA.
45  *
46  * Redistribution and use in source and binary forms, with or without
47  * modification, are permitted provided that the following conditions
48  * are met:
49  * 1. Redistributions of source code must retain the above copyright
50  *    notice, this list of conditions and the following disclaimer.
51  * 2. Redistributions in binary form must reproduce the above copyright
52  *    notice, this list of conditions and the following disclaimer in the
53  *    documentation and/or other materials provided with the distribution.
54  * 3. All advertising materials mentioning features or use of this software
55  *    must display the following acknowledgement:
56  *      This product includes software developed by the NetBSD
57  *      Foundation, Inc. and its contributors.
58  * 4. Neither the name of The NetBSD Foundation nor the names of its
59  *    contributors may be used to endorse or promote products derived
60  *    from this software without specific prior written permission.
61  */
62 /*-
63  * Copyright (c) 1999
64  *         Shin Takemura and PocketBSD Project. All rights reserved.
65  *
66  * Redistribution and use in source and binary forms, with or without
67  * modification, are permitted provided that the following conditions
68  * are met:
69  * 1. Redistributions of source code must retain the above copyright
70  *    notice, this list of conditions and the following disclaimer.
71  * 2. Redistributions in binary form must reproduce the above copyright
72  *    notice, this list of conditions and the following disclaimer in the
73  *    documentation and/or other materials provided with the distribution.
74  * 3. All advertising materials mentioning features or use of this software
75  *    must display the following acknowledgement:
76  *	This product includes software developed by the PocketBSD project
77  *	and its contributors.
78  * 4. Neither the name of the project nor the names of its contributors
79  *    may be used to endorse or promote products derived from this software
80  *    without specific prior written permission.
81  *
82  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
83  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
84  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
85  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
86  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
87  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
88  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
89  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
90  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
91  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
92  * SUCH DAMAGE.
93  *
94  */
95 
96 #include <sys/param.h>
97 #include <sys/systm.h>
98 #include <sys/device.h>
99 #include <sys/kernel.h>
100 #include <sys/reboot.h>
101 
102 #include <machine/cpu.h>
103 #include <machine/bus.h>
104 
105 #include <arm/cpufunc.h>
106 #include <arm/mainbus/mainbus.h>
107 #include <arm/xscale/pxa2x0reg.h>
108 #include <arm/xscale/pxa2x0var.h>
109 
110 #include "locators.h"
111 
112 /* prototypes */
113 static int	pxa2x0_match(struct device *, struct cfdata *, void *);
114 static void	pxa2x0_attach(struct device *, struct device *, void *);
115 static int 	pxa2x0_search(struct device *, struct cfdata *, void *);
116 
117 /* attach structures */
118 CFATTACH_DECL(pxaip, sizeof(struct pxa2x0_softc), pxa2x0_match, pxa2x0_attach,
119     NULL, NULL);
120 
121 extern struct bus_space pxa2x0_bs_tag;
122 
123 struct pxa2x0_softc *pxa2x0_softc;
124 
125 static int
126 pxa2x0_print(void *aux, const char *name)
127 {
128 	struct pxa2x0_attach_args *sa = (struct pxa2x0_attach_args*)aux;
129 
130 	if (sa->pxa_size)
131                 printf(" addr 0x%lx", sa->pxa_addr);
132         if (sa->pxa_size > 1)
133                 printf("-0x%lx", sa->pxa_addr + sa->pxa_size - 1);
134         if (sa->pxa_intr > 1)
135                 printf(" intr %d", sa->pxa_intr);
136 	if (sa->pxa_gpio != -1)
137 		printf(" gpio %d", sa->pxa_gpio);
138 
139         return (UNCONF);
140 }
141 
142 int
143 pxa2x0_match(struct device *parent, struct cfdata *match, void *aux)
144 {
145 	return 1;
146 }
147 
148 void
149 pxa2x0_attach(struct device *parent, struct device *self, void *aux)
150 {
151 	struct pxa2x0_softc *sc = (struct pxa2x0_softc*)self;
152 	bus_space_tag_t iot;
153 	const char *which_registers; /* for panic message */
154 
155 #define FAIL(which)  do { \
156 	which_registers=(which); goto abort; }while(/*CONSTCOND*/0)
157 
158 	pxa2x0_softc = sc;
159 	sc->saip.sc_iot = iot = &pxa2x0_bs_tag;
160 
161 	if (bus_space_map(iot,
162 			  PXA2X0_INTCTL_BASE, PXA2X0_INTCTL_SIZE,
163 			0, &sc->saip.sc_ioh))
164 		FAIL("intc");
165 
166 	/* Map the GPIO registers */
167 	if (bus_space_map(iot, PXA2X0_GPIO_BASE, PXA2X0_GPIO_SIZE,
168 			  0, &sc->saip.sc_gpioh))
169 		FAIL("GPIO");
170 
171 	/* Map the DMA controller registers */
172 	if (bus_space_map(iot, PXA2X0_DMAC_BASE, PXA2X0_DMAC_SIZE,
173 			  0, &sc->saip.sc_dmach))
174 		FAIL("DMAC");
175 
176 	/* Memory controller */
177 	if( bus_space_map(iot, PXA2X0_MEMCTL_BASE,
178 			  PXA2X0_MEMCTL_SIZE, 0, &sc->sc_memctl_ioh) )
179 		FAIL("MEMC");
180 	/* Clock manager */
181 	if( bus_space_map(iot, PXA2X0_CLKMAN_BASE,
182 			  PXA2X0_CLKMAN_SIZE, 0, &sc->sc_clkman_ioh) )
183 		FAIL("CLK");
184 
185 	/* Real time clock */
186 	if( bus_space_map(iot, PXA2X0_RTC_BASE,
187 			  PXA2X0_RTC_SIZE, 0, &sc->sc_rtc_ioh) )
188 		FAIL("RTC");
189 
190 #if 1
191 	/* This takes 2 secs at most. */
192 	{
193 		int cpuclock;
194 
195 		cpuclock = pxa2x0_measure_cpuclock( sc ) / 1000;
196 		printf( " CPU clock = %d.%03d MHz", cpuclock/1000, cpuclock%1000 );
197 	}
198 #endif
199 	printf("\n");
200 
201 	pxa2x0_set_intcbase(sc->saip.sc_ioh);
202 	pxa2x0_intr_init();
203 
204 	/*
205 	 *  Attach devices.
206 	 */
207 	config_search(pxa2x0_search, self, NULL);
208 	return;
209 
210  abort:
211 	panic("%s: unable to map %s registers\n",
212 	      self->dv_xname, which_registers);
213 
214 #undef FAIL
215 }
216 
217 int
218 pxa2x0_search(struct device *parent, struct cfdata *cf, void *aux)
219 {
220 	struct pxa2x0_softc *sc = (struct pxa2x0_softc *)parent;
221 	struct pxa2x0_attach_args aa;
222 
223 	aa.pxa_sc = sc;
224         aa.pxa_iot = sc->saip.sc_iot;
225         aa.pxa_addr = cf->cf_loc[PXAIPCF_ADDR];
226         aa.pxa_size = cf->cf_loc[PXAIPCF_SIZE];
227 	aa.pxa_index = cf->cf_loc[PXAIPCF_INDEX];
228 	aa.pxa_sa.sa_membase = 0;
229         aa.pxa_sa.sa_memsize = 0;
230         aa.pxa_intr = cf->cf_loc[PXAIPCF_INTR];
231 	aa.pxa_gpio = cf->cf_loc[PXAIPCF_GPIO];
232 
233         if (config_match(parent, cf, &aa))
234                 config_attach(parent, cf, &aa, pxa2x0_print);
235 
236         return 0;
237 }
238 
239 static inline uint32_t
240 read_clock_counter(void)
241 {
242   uint32_t x;
243   __asm __volatile("mrc	p14, 0, %0, c1, c0, 0" : "=r" (x) );
244 
245   return x;
246 }
247 
248 int
249 pxa2x0_measure_cpuclock( struct pxa2x0_softc *sc )
250 {
251 	uint32_t rtc0, rtc1, start, end;
252 	uint32_t pmcr_save;
253 	bus_space_tag_t iot = sc->saip.sc_iot;
254 	bus_space_handle_t rtc_ioh = sc->sc_rtc_ioh;
255 	int irq = disable_interrupts(I32_bit|F32_bit);
256 
257 	__asm __volatile( "mrc p14, 0, %0, c0, c0, 0" : "=r" (pmcr_save) );
258 	/* Enable clock counter */
259 	__asm __volatile( "mcr p14, 0, %0, c0, c0, 0" : : "r" (0x0001) );
260 
261 	rtc0 = bus_space_read_4( iot, rtc_ioh, RTC_RCNR );
262 	/* Wait for next second starts */
263 	while( (rtc1 = bus_space_read_4( iot, rtc_ioh, RTC_RCNR )) == rtc0 )
264 		;
265 	start = read_clock_counter();
266 	while( rtc1 == bus_space_read_4( iot, rtc_ioh, RTC_RCNR ) )
267 		;		/* Wait for 1sec */
268 	end = read_clock_counter();
269 
270 	__asm __volatile( "mcr p14, 0, %0, c0, c0, 0" : : "r" (pmcr_save) );
271 	restore_interrupts(irq);
272 
273 	return end - start;
274 }
275 
276 void
277 pxa2x0_turbo_mode( int f )
278 {
279   __asm __volatile("mcr p14, 0, %0, c6, c0, 0" : : "r" (f));
280 }
281