1 1.24 thorpej /* $NetBSD: pxa2x0.c,v 1.24 2021/08/07 16:18:46 thorpej Exp $ */ 2 1.1 bsh 3 1.1 bsh /* 4 1.7 bsh * Copyright (c) 2002, 2005 Genetec Corporation. All rights reserved. 5 1.1 bsh * Written by Hiroyuki Bessho for Genetec Corporation. 6 1.1 bsh * 7 1.1 bsh * Redistribution and use in source and binary forms, with or without 8 1.1 bsh * modification, are permitted provided that the following conditions 9 1.1 bsh * are met: 10 1.1 bsh * 1. Redistributions of source code must retain the above copyright 11 1.1 bsh * notice, this list of conditions and the following disclaimer. 12 1.1 bsh * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 bsh * notice, this list of conditions and the following disclaimer in the 14 1.1 bsh * documentation and/or other materials provided with the distribution. 15 1.1 bsh * 3. All advertising materials mentioning features or use of this software 16 1.1 bsh * must display the following acknowledgement: 17 1.1 bsh * This product includes software developed for the NetBSD Project by 18 1.1 bsh * Genetec Corporation. 19 1.1 bsh * 4. The name of Genetec Corporation may not be used to endorse or 20 1.1 bsh * promote products derived from this software without specific prior 21 1.1 bsh * written permission. 22 1.1 bsh * 23 1.1 bsh * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND 24 1.1 bsh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 1.1 bsh * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 1.1 bsh * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION 27 1.1 bsh * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 1.1 bsh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 1.1 bsh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 1.1 bsh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 1.1 bsh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 1.1 bsh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 1.1 bsh * POSSIBILITY OF SUCH DAMAGE. 34 1.1 bsh * 35 1.1 bsh * 36 1.1 bsh * Autoconfiguration support for the Intel PXA2[15]0 application 37 1.1 bsh * processor. This code is derived from arm/sa11x0/sa11x0.c 38 1.1 bsh */ 39 1.1 bsh 40 1.1 bsh /*- 41 1.1 bsh * Copyright (c) 2001, The NetBSD Foundation, Inc. All rights reserved. 42 1.1 bsh * 43 1.1 bsh * This code is derived from software contributed to The NetBSD Foundation 44 1.1 bsh * by IWAMOTO Toshihiro and Ichiro FUKUHARA. 45 1.1 bsh * 46 1.1 bsh * Redistribution and use in source and binary forms, with or without 47 1.1 bsh * modification, are permitted provided that the following conditions 48 1.1 bsh * are met: 49 1.1 bsh * 1. Redistributions of source code must retain the above copyright 50 1.1 bsh * notice, this list of conditions and the following disclaimer. 51 1.1 bsh * 2. Redistributions in binary form must reproduce the above copyright 52 1.1 bsh * notice, this list of conditions and the following disclaimer in the 53 1.1 bsh * documentation and/or other materials provided with the distribution. 54 1.17 martin * 55 1.17 martin * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 56 1.17 martin * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 57 1.17 martin * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 58 1.17 martin * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 59 1.17 martin * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 60 1.17 martin * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 61 1.17 martin * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 62 1.17 martin * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 63 1.17 martin * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 64 1.17 martin * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 65 1.17 martin * POSSIBILITY OF SUCH DAMAGE. 66 1.1 bsh */ 67 1.1 bsh /*- 68 1.1 bsh * Copyright (c) 1999 69 1.1 bsh * Shin Takemura and PocketBSD Project. All rights reserved. 70 1.1 bsh * 71 1.1 bsh * Redistribution and use in source and binary forms, with or without 72 1.1 bsh * modification, are permitted provided that the following conditions 73 1.1 bsh * are met: 74 1.1 bsh * 1. Redistributions of source code must retain the above copyright 75 1.1 bsh * notice, this list of conditions and the following disclaimer. 76 1.1 bsh * 2. Redistributions in binary form must reproduce the above copyright 77 1.1 bsh * notice, this list of conditions and the following disclaimer in the 78 1.1 bsh * documentation and/or other materials provided with the distribution. 79 1.1 bsh * 3. All advertising materials mentioning features or use of this software 80 1.1 bsh * must display the following acknowledgement: 81 1.1 bsh * This product includes software developed by the PocketBSD project 82 1.1 bsh * and its contributors. 83 1.1 bsh * 4. Neither the name of the project nor the names of its contributors 84 1.1 bsh * may be used to endorse or promote products derived from this software 85 1.1 bsh * without specific prior written permission. 86 1.1 bsh * 87 1.1 bsh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 88 1.1 bsh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 89 1.1 bsh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 90 1.1 bsh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 91 1.1 bsh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 92 1.1 bsh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 93 1.1 bsh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 94 1.1 bsh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 95 1.1 bsh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 96 1.1 bsh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 97 1.1 bsh * SUCH DAMAGE. 98 1.1 bsh * 99 1.1 bsh */ 100 1.4 lukem 101 1.4 lukem #include <sys/cdefs.h> 102 1.24 thorpej __KERNEL_RCSID(0, "$NetBSD: pxa2x0.c,v 1.24 2021/08/07 16:18:46 thorpej Exp $"); 103 1.1 bsh 104 1.3 scw #include "pxaintc.h" 105 1.3 scw #include "pxagpio.h" 106 1.3 scw #if 0 107 1.3 scw #include "pxadmac.h" /* Not yet */ 108 1.3 scw #endif 109 1.3 scw 110 1.3 scw #include "locators.h" 111 1.3 scw 112 1.1 bsh #include <sys/param.h> 113 1.1 bsh #include <sys/systm.h> 114 1.1 bsh #include <sys/device.h> 115 1.1 bsh #include <sys/kernel.h> 116 1.1 bsh #include <sys/reboot.h> 117 1.1 bsh 118 1.1 bsh #include <machine/cpu.h> 119 1.20 dyoung #include <sys/bus.h> 120 1.1 bsh 121 1.1 bsh #include <arm/cpufunc.h> 122 1.1 bsh #include <arm/mainbus/mainbus.h> 123 1.8 bsh #include <arm/xscale/pxa2x0cpu.h> 124 1.1 bsh #include <arm/xscale/pxa2x0reg.h> 125 1.1 bsh #include <arm/xscale/pxa2x0var.h> 126 1.7 bsh #include <arm/xscale/xscalereg.h> 127 1.1 bsh 128 1.3 scw struct pxaip_softc { 129 1.19 nonaka device_t sc_dev; 130 1.3 scw bus_space_tag_t sc_bust; 131 1.3 scw bus_dma_tag_t sc_dmat; 132 1.3 scw bus_space_handle_t sc_bush_clk; 133 1.15 peter bus_space_handle_t sc_bush_mem; 134 1.3 scw }; 135 1.1 bsh 136 1.1 bsh /* prototypes */ 137 1.19 nonaka static int pxaip_match(device_t, cfdata_t, void *); 138 1.19 nonaka static void pxaip_attach(device_t, device_t, void *); 139 1.19 nonaka static int pxaip_search(device_t, cfdata_t, const int *, void *); 140 1.3 scw static void pxaip_attach_critical(struct pxaip_softc *); 141 1.3 scw static int pxaip_print(void *, const char *); 142 1.3 scw 143 1.3 scw static int pxaip_measure_cpuclock(struct pxaip_softc *); 144 1.1 bsh 145 1.8 bsh #if defined(CPU_XSCALE_PXA250) && defined(CPU_XSCALE_PXA270) 146 1.8 bsh # define SUPPORTED_CPU "PXA250 and PXA270" 147 1.8 bsh #elif defined(CPU_XSCALE_PXA250) 148 1.8 bsh # define SUPPORTED_CPU "PXA250" 149 1.8 bsh #elif defined(CPU_XSCALE_PXA270) 150 1.8 bsh # define SUPPORTED_CPU "PXA270" 151 1.8 bsh #else 152 1.8 bsh # define SUPPORTED_CPU "none of PXA2xx" 153 1.8 bsh #endif 154 1.8 bsh 155 1.1 bsh /* attach structures */ 156 1.19 nonaka CFATTACH_DECL_NEW(pxaip, sizeof(struct pxaip_softc), 157 1.3 scw pxaip_match, pxaip_attach, NULL, NULL); 158 1.1 bsh 159 1.3 scw static struct pxaip_softc *pxaip_sc; 160 1.15 peter static vaddr_t pxamemctl_regs; 161 1.15 peter #define MEMCTL_BOOTSTRAP_REG(reg) \ 162 1.15 peter (*((volatile uint32_t *)(pxamemctl_regs + (reg)))) 163 1.14 ober static vaddr_t pxaclkman_regs; 164 1.14 ober #define CLKMAN_BOOTSTRAP_REG(reg) \ 165 1.14 ober (*((volatile uint32_t *)(pxaclkman_regs + (reg)))) 166 1.1 bsh 167 1.1 bsh static int 168 1.19 nonaka pxaip_match(device_t parent, cfdata_t match, void *aux) 169 1.1 bsh { 170 1.1 bsh 171 1.8 bsh #if !defined(CPU_XSCALE_PXA270) 172 1.8 bsh if (__CPU_IS_PXA270) 173 1.8 bsh goto bad_config; 174 1.8 bsh #endif 175 1.8 bsh 176 1.8 bsh #if !defined(CPU_XSCALE_PXA250) 177 1.8 bsh if (__CPU_IS_PXA250) 178 1.8 bsh goto bad_config; 179 1.8 bsh #endif 180 1.8 bsh 181 1.1 bsh return 1; 182 1.8 bsh 183 1.8 bsh #if defined(CPU_XSCALE_PXA250) + defined(CPU_XSCALE_PXA270) != 2 184 1.8 bsh bad_config: 185 1.8 bsh aprint_error("Kernel is configured for %s, but CPU is %s\n", 186 1.8 bsh SUPPORTED_CPU, __CPU_IS_PXA270 ? "PXA270" : "PXA250"); 187 1.8 bsh return 0; 188 1.8 bsh #endif 189 1.1 bsh } 190 1.1 bsh 191 1.3 scw static void 192 1.19 nonaka pxaip_attach(device_t parent, device_t self, void *aux) 193 1.1 bsh { 194 1.19 nonaka struct pxaip_softc *sc = device_private(self); 195 1.3 scw int cpuclock; 196 1.1 bsh 197 1.3 scw pxaip_sc = sc; 198 1.19 nonaka sc->sc_dev = self; 199 1.3 scw sc->sc_bust = &pxa2x0_bs_tag; 200 1.3 scw sc->sc_dmat = &pxa2x0_bus_dma_tag; 201 1.3 scw 202 1.19 nonaka aprint_normal(": Onchip Peripheral Bus\n"); 203 1.3 scw 204 1.3 scw if (bus_space_map(sc->sc_bust, PXA2X0_CLKMAN_BASE, PXA2X0_CLKMAN_SIZE, 205 1.3 scw 0, &sc->sc_bush_clk)) 206 1.3 scw panic("pxaip_attach: failed to map CLKMAN"); 207 1.1 bsh 208 1.15 peter if (bus_space_map(sc->sc_bust, PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE, 209 1.15 peter 0, &sc->sc_bush_mem)) 210 1.15 peter panic("pxaip_attach: failed to map MEMCTL"); 211 1.15 peter 212 1.3 scw /* 213 1.3 scw * Calculate clock speed 214 1.3 scw * This takes 2 secs at most. 215 1.3 scw */ 216 1.3 scw cpuclock = pxaip_measure_cpuclock(sc) / 1000; 217 1.21 chs printf("%s: CPU clock = %d.%03d MHz\n", device_xname(self), 218 1.3 scw cpuclock/1000, cpuclock%1000 ); 219 1.1 bsh 220 1.8 bsh aprint_normal("%s: kernel is configured for " SUPPORTED_CPU 221 1.8 bsh ", cpu type is %s\n", 222 1.21 chs device_xname(self), 223 1.8 bsh __CPU_IS_PXA270 ? "PXA270" : "PXA250"); 224 1.8 bsh 225 1.1 bsh /* 226 1.3 scw * Attach critical devices 227 1.1 bsh */ 228 1.3 scw pxaip_attach_critical(sc); 229 1.1 bsh 230 1.3 scw /* 231 1.3 scw * Attach all other devices 232 1.3 scw */ 233 1.23 thorpej config_search(self, NULL, 234 1.24 thorpej CFARGS(.search = pxaip_search)); 235 1.1 bsh } 236 1.1 bsh 237 1.3 scw static int 238 1.19 nonaka pxaip_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux) 239 1.1 bsh { 240 1.23 thorpej struct pxaip_softc *sc = device_private(parent); 241 1.3 scw struct pxaip_attach_args aa; 242 1.1 bsh 243 1.12 simonb aa.pxa_iot = sc->sc_bust; 244 1.12 simonb aa.pxa_dmat = sc->sc_dmat; 245 1.18 kiyohara aa.pxa_name = cf->cf_name; 246 1.12 simonb aa.pxa_addr = cf->cf_loc[PXAIPCF_ADDR]; 247 1.12 simonb aa.pxa_size = cf->cf_loc[PXAIPCF_SIZE]; 248 1.1 bsh aa.pxa_index = cf->cf_loc[PXAIPCF_INDEX]; 249 1.12 simonb aa.pxa_intr = cf->cf_loc[PXAIPCF_INTR]; 250 1.1 bsh 251 1.23 thorpej if (config_probe(parent, cf, &aa)) 252 1.24 thorpej config_attach(parent, cf, &aa, pxaip_print, CFARGS_NONE); 253 1.1 bsh 254 1.12 simonb return 0; 255 1.1 bsh } 256 1.1 bsh 257 1.3 scw static void 258 1.3 scw pxaip_attach_critical(struct pxaip_softc *sc) 259 1.3 scw { 260 1.3 scw struct pxaip_attach_args aa; 261 1.3 scw 262 1.12 simonb aa.pxa_iot = sc->sc_bust; 263 1.12 simonb aa.pxa_dmat = sc->sc_dmat; 264 1.18 kiyohara aa.pxa_name = "pxaintc"; 265 1.12 simonb aa.pxa_addr = PXA2X0_INTCTL_BASE; 266 1.12 simonb aa.pxa_size = PXA2X0_INTCTL_SIZE; 267 1.12 simonb aa.pxa_intr = PXAIPCF_INTR_DEFAULT; 268 1.24 thorpej if (config_found(sc->sc_dev, &aa, pxaip_print, CFARGS_NONE) == NULL) 269 1.3 scw panic("pxaip_attach_critical: failed to attach INTC!"); 270 1.3 scw 271 1.3 scw #if NPXAGPIO > 0 272 1.12 simonb aa.pxa_iot = sc->sc_bust; 273 1.12 simonb aa.pxa_dmat = sc->sc_dmat; 274 1.18 kiyohara aa.pxa_name = "pxagpio"; 275 1.12 simonb aa.pxa_addr = PXA2X0_GPIO_BASE; 276 1.12 simonb aa.pxa_size = PXA2X0_GPIO_SIZE; 277 1.12 simonb aa.pxa_intr = PXAIPCF_INTR_DEFAULT; 278 1.24 thorpej if (config_found(sc->sc_dev, &aa, pxaip_print, CFARGS_NONE) == NULL) 279 1.3 scw panic("pxaip_attach_critical: failed to attach GPIO!"); 280 1.3 scw #endif 281 1.3 scw 282 1.3 scw #if NPXADMAC > 0 283 1.12 simonb aa.pxa_iot = sc->sc_bust; 284 1.12 simonb aa.pxa_dmat = sc->sc_dmat; 285 1.18 kiyohara aa.pxa_name = "pxaidmac"; 286 1.12 simonb aa.pxa_addr = PXA2X0_DMAC_BASE; 287 1.12 simonb aa.pxa_size = PXA2X0_DMAC_SIZE; 288 1.12 simonb aa.pxa_intr = PXA2X0_INT_DMA; 289 1.24 thorpej if (config_found(sc->sc_dev, &aa, pxaip_print, CFARGS_NONE) == NULL) 290 1.3 scw panic("pxaip_attach_critical: failed to attach DMAC!"); 291 1.3 scw #endif 292 1.3 scw } 293 1.3 scw 294 1.3 scw static int 295 1.3 scw pxaip_print(void *aux, const char *name) 296 1.3 scw { 297 1.19 nonaka struct pxaip_attach_args *sa = (struct pxaip_attach_args *)aux; 298 1.3 scw 299 1.3 scw if (sa->pxa_addr != PXAIPCF_ADDR_DEFAULT) { 300 1.12 simonb aprint_normal(" addr 0x%lx", sa->pxa_addr); 301 1.12 simonb if (sa->pxa_size > PXAIPCF_SIZE_DEFAULT) 302 1.12 simonb aprint_normal("-0x%lx", sa->pxa_addr + sa->pxa_size-1); 303 1.3 scw } 304 1.12 simonb if (sa->pxa_intr != PXAIPCF_INTR_DEFAULT) 305 1.12 simonb aprint_normal(" intr %d", sa->pxa_intr); 306 1.3 scw 307 1.12 simonb return (UNCONF); 308 1.3 scw } 309 1.3 scw 310 1.1 bsh static inline uint32_t 311 1.8 bsh read_clock_counter_xsc1(void) 312 1.1 bsh { 313 1.12 simonb uint32_t x; 314 1.12 simonb __asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (x) ); 315 1.1 bsh 316 1.12 simonb return x; 317 1.1 bsh } 318 1.1 bsh 319 1.8 bsh static inline uint32_t 320 1.8 bsh read_clock_counter_xsc2(void) 321 1.8 bsh { 322 1.12 simonb uint32_t x; 323 1.12 simonb __asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (x) ); 324 1.8 bsh 325 1.12 simonb return x; 326 1.8 bsh } 327 1.8 bsh 328 1.3 scw static int 329 1.3 scw pxaip_measure_cpuclock(struct pxaip_softc *sc) 330 1.1 bsh { 331 1.1 bsh uint32_t rtc0, rtc1, start, end; 332 1.1 bsh uint32_t pmcr_save; 333 1.3 scw bus_space_handle_t ioh; 334 1.3 scw int irq; 335 1.8 bsh int is_xsc2 = CPU_IS_PXA270; 336 1.8 bsh #define read_clock_counter() (is_xsc2 ? read_clock_counter_xsc2() : \ 337 1.8 bsh read_clock_counter_xsc1()) 338 1.3 scw 339 1.3 scw if (bus_space_map(sc->sc_bust, PXA2X0_RTC_BASE, PXA2X0_RTC_SIZE, 0, 340 1.3 scw &ioh)) 341 1.3 scw panic("pxaip_measure_cpuclock: can't map RTC"); 342 1.3 scw 343 1.3 scw irq = disable_interrupts(I32_bit|F32_bit); 344 1.1 bsh 345 1.8 bsh if (is_xsc2) { 346 1.11 perry __asm volatile( 347 1.8 bsh "mrc p14, 0, %0, c0, c1, 0" : "=r" (pmcr_save)); 348 1.8 bsh /* Enable clock counter */ 349 1.11 perry __asm volatile( 350 1.8 bsh "mcr p14, 0, %0, c0, c1, 0" : : "r" (PMNC_E|PMNC_C)); 351 1.8 bsh } 352 1.8 bsh else { 353 1.11 perry __asm volatile( 354 1.8 bsh "mrc p14, 0, %0, c0, c0, 0" : "=r" (pmcr_save)); 355 1.8 bsh /* Enable clock counter */ 356 1.11 perry __asm volatile( 357 1.8 bsh "mcr p14, 0, %0, c0, c0, 0" : : "r" (PMNC_E|PMNC_C)); 358 1.8 bsh } 359 1.1 bsh 360 1.3 scw rtc0 = bus_space_read_4(sc->sc_bust, ioh, RTC_RCNR); 361 1.1 bsh /* Wait for next second starts */ 362 1.3 scw while ((rtc1 = bus_space_read_4(sc->sc_bust, ioh, RTC_RCNR)) == rtc0) 363 1.1 bsh ; 364 1.1 bsh start = read_clock_counter(); 365 1.3 scw while(rtc1 == bus_space_read_4(sc->sc_bust, ioh, RTC_RCNR)) 366 1.1 bsh ; /* Wait for 1sec */ 367 1.1 bsh end = read_clock_counter(); 368 1.1 bsh 369 1.8 bsh if (is_xsc2) 370 1.11 perry __asm volatile( 371 1.8 bsh "mcr p14, 0, %0, c0, c1, 0" : : "r" (pmcr_save)); 372 1.8 bsh else 373 1.11 perry __asm volatile( 374 1.8 bsh "mcr p14, 0, %0, c0, c0, 0" : : "r" (pmcr_save)); 375 1.1 bsh restore_interrupts(irq); 376 1.1 bsh 377 1.3 scw bus_space_unmap(sc->sc_bust, ioh, PXA2X0_RTC_SIZE); 378 1.3 scw 379 1.1 bsh return end - start; 380 1.1 bsh } 381 1.1 bsh 382 1.1 bsh void 383 1.7 bsh pxa2x0_turbo_mode(int f) 384 1.1 bsh { 385 1.12 simonb __asm volatile("mcr p14, 0, %0, c6, c0, 0" : : "r" (f)); 386 1.3 scw } 387 1.3 scw 388 1.3 scw void 389 1.3 scw pxa2x0_probe_sdram(vaddr_t memctl_va, paddr_t *start, paddr_t *size) 390 1.3 scw { 391 1.22 skrll uint32_t mdcnfg, dwid, dcac, drac, dnb; 392 1.3 scw int i; 393 1.3 scw 394 1.22 skrll mdcnfg = *((volatile uint32_t *)(memctl_va + MEMCTL_MDCNFG)); 395 1.3 scw 396 1.3 scw /* 397 1.3 scw * Scan all 4 SDRAM banks 398 1.3 scw */ 399 1.3 scw for (i = 0; i < PXA2X0_SDRAM_BANKS; i++) { 400 1.3 scw start[i] = 0; 401 1.3 scw size[i] = 0; 402 1.3 scw 403 1.3 scw switch (i) { 404 1.3 scw case 0: 405 1.3 scw case 1: 406 1.3 scw if ((i == 0 && (mdcnfg & MDCNFG_DE0) == 0) || 407 1.3 scw (i == 1 && (mdcnfg & MDCNFG_DE1) == 0)) 408 1.3 scw continue; 409 1.3 scw dwid = mdcnfg >> MDCNFD_DWID01_SHIFT; 410 1.3 scw dcac = mdcnfg >> MDCNFD_DCAC01_SHIFT; 411 1.3 scw drac = mdcnfg >> MDCNFD_DRAC01_SHIFT; 412 1.3 scw dnb = mdcnfg >> MDCNFD_DNB01_SHIFT; 413 1.3 scw break; 414 1.3 scw 415 1.3 scw case 2: 416 1.3 scw case 3: 417 1.3 scw if ((i == 2 && (mdcnfg & MDCNFG_DE2) == 0) || 418 1.3 scw (i == 3 && (mdcnfg & MDCNFG_DE3) == 0)) 419 1.3 scw continue; 420 1.3 scw dwid = mdcnfg >> MDCNFD_DWID23_SHIFT; 421 1.3 scw dcac = mdcnfg >> MDCNFD_DCAC23_SHIFT; 422 1.3 scw drac = mdcnfg >> MDCNFD_DRAC23_SHIFT; 423 1.3 scw dnb = mdcnfg >> MDCNFD_DNB23_SHIFT; 424 1.3 scw break; 425 1.5 thorpej default: 426 1.5 thorpej panic("pxa2x0_probe_sdram: impossible"); 427 1.3 scw } 428 1.3 scw 429 1.3 scw dwid = 2 << (1 - (dwid & MDCNFD_DWID_MASK)); /* 16/32 width */ 430 1.3 scw dcac = 1 << ((dcac & MDCNFD_DCAC_MASK) + 8); /* 8-11 columns */ 431 1.3 scw drac = 1 << ((drac & MDCNFD_DRAC_MASK) + 11); /* 11-13 rows */ 432 1.3 scw dnb = 2 << (dnb & MDCNFD_DNB_MASK); /* # of banks */ 433 1.3 scw 434 1.3 scw size[i] = (paddr_t)(dwid * dcac * drac * dnb); 435 1.3 scw start[i] = PXA2X0_SDRAM0_START + (i * PXA2X0_SDRAM_BANK_SIZE); 436 1.3 scw } 437 1.3 scw } 438 1.3 scw 439 1.3 scw void 440 1.15 peter pxa2x0_memctl_bootstrap(vaddr_t va) 441 1.15 peter { 442 1.15 peter 443 1.15 peter pxamemctl_regs = va; 444 1.15 peter } 445 1.15 peter 446 1.15 peter uint32_t 447 1.15 peter pxa2x0_memctl_read(int reg) 448 1.15 peter { 449 1.15 peter struct pxaip_softc *sc; 450 1.15 peter bus_space_tag_t iot; 451 1.15 peter bus_space_handle_t ioh; 452 1.15 peter 453 1.15 peter if (__predict_true(pxaip_sc != NULL)) { 454 1.15 peter sc = pxaip_sc; 455 1.15 peter iot = sc->sc_bust; 456 1.15 peter ioh = sc->sc_bush_mem; 457 1.15 peter return (bus_space_read_4(iot, ioh, reg)); 458 1.15 peter } else if (__predict_true(pxamemctl_regs != 0)) { 459 1.15 peter return (MEMCTL_BOOTSTRAP_REG(reg)); 460 1.15 peter } 461 1.15 peter panic("pxa2x0_memctl_read: not bootstrapped"); 462 1.15 peter /*NOTREACHED*/ 463 1.15 peter } 464 1.15 peter 465 1.15 peter void 466 1.15 peter pxa2x0_memctl_write(int reg, uint32_t val) 467 1.15 peter { 468 1.15 peter struct pxaip_softc *sc; 469 1.15 peter bus_space_tag_t iot; 470 1.15 peter bus_space_handle_t ioh; 471 1.15 peter 472 1.15 peter if (__predict_true(pxaip_sc != NULL)) { 473 1.15 peter sc = pxaip_sc; 474 1.15 peter iot = sc->sc_bust; 475 1.15 peter ioh = sc->sc_bush_mem; 476 1.15 peter bus_space_write_4(iot, ioh, reg, val); 477 1.15 peter } else if (__predict_true(pxamemctl_regs != 0)) { 478 1.15 peter MEMCTL_BOOTSTRAP_REG(reg) = val; 479 1.15 peter } else { 480 1.15 peter panic("pxa2x0_memctl_write: not bootstrapped"); 481 1.15 peter } 482 1.15 peter return; 483 1.15 peter } 484 1.15 peter 485 1.15 peter void 486 1.14 ober pxa2x0_clkman_bootstrap(vaddr_t va) 487 1.14 ober { 488 1.14 ober 489 1.14 ober pxaclkman_regs = va; 490 1.14 ober } 491 1.14 ober 492 1.14 ober void 493 1.16 thorpej pxa2x0_clkman_config(u_int clk, bool enable) 494 1.3 scw { 495 1.3 scw struct pxaip_softc *sc; 496 1.14 ober bus_space_tag_t iot; 497 1.14 ober bus_space_handle_t ioh; 498 1.14 ober uint32_t rv; 499 1.3 scw 500 1.14 ober if (__predict_true(pxaip_sc != NULL)) { 501 1.14 ober sc = pxaip_sc; 502 1.14 ober iot = sc->sc_bust; 503 1.14 ober ioh = sc->sc_bush_clk; 504 1.14 ober 505 1.14 ober rv = bus_space_read_4(iot, ioh, CLKMAN_CKEN); 506 1.14 ober rv &= ~clk; 507 1.14 ober if (enable) 508 1.14 ober rv |= clk; 509 1.14 ober bus_space_write_4(iot, ioh, CLKMAN_CKEN, rv); 510 1.14 ober return; 511 1.15 peter } else if (__predict_true(pxaclkman_regs != 0)) { 512 1.14 ober rv = CLKMAN_BOOTSTRAP_REG(CLKMAN_CKEN); 513 1.14 ober rv &= ~clk; 514 1.14 ober if (enable) 515 1.14 ober rv |= clk; 516 1.14 ober CLKMAN_BOOTSTRAP_REG(CLKMAN_CKEN) = rv; 517 1.14 ober return; 518 1.14 ober } 519 1.14 ober panic("pxa2x0_clkman_config: not bootstrapped"); 520 1.1 bsh } 521