1 /* 2 * linux/arch/arm/mach-pxa/generic.c 3 * 4 * Author: Nicolas Pitre 5 * Created: Jun 15, 2001 6 * Copyright: MontaVista Software Inc. 7 * 8 * Code common to all PXA machines. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 * 14 * Since this file should be linked before any other machine specific file, 15 * the __initcall() here will be executed first. This serves as default 16 * initialization stuff for PXA machines which can be overridden later if 17 * need be. 18 */ 19 #include <linux/module.h> 20 #include <linux/kernel.h> 21 #include <linux/init.h> 22 #include <linux/delay.h> 23 #include <linux/platform_device.h> 24 #include <linux/ioport.h> 25 #include <linux/pm.h> 26 #include <linux/string.h> 27 28 #include <asm/hardware.h> 29 #include <asm/irq.h> 30 #include <asm/system.h> 31 #include <asm/pgtable.h> 32 #include <asm/mach/map.h> 33 34 #include <asm/arch/pxa-regs.h> 35 #include <asm/arch/gpio.h> 36 #include <asm/arch/udc.h> 37 #include <asm/arch/pxafb.h> 38 #include <asm/arch/mmc.h> 39 #include <asm/arch/irda.h> 40 #include <asm/arch/i2c.h> 41 42 #include "devices.h" 43 #include "generic.h" 44 45 /* 46 * Get the clock frequency as reflected by CCCR and the turbo flag. 47 * We assume these values have been applied via a fcs. 48 * If info is not 0 we also display the current settings. 49 */ 50 unsigned int get_clk_frequency_khz(int info) 51 { 52 if (cpu_is_pxa21x() || cpu_is_pxa25x()) 53 return pxa25x_get_clk_frequency_khz(info); 54 else if (cpu_is_pxa27x()) 55 return pxa27x_get_clk_frequency_khz(info); 56 else 57 return pxa3xx_get_clk_frequency_khz(info); 58 } 59 EXPORT_SYMBOL(get_clk_frequency_khz); 60 61 /* 62 * Return the current memory clock frequency in units of 10kHz 63 */ 64 unsigned int get_memclk_frequency_10khz(void) 65 { 66 if (cpu_is_pxa21x() || cpu_is_pxa25x()) 67 return pxa25x_get_memclk_frequency_10khz(); 68 else if (cpu_is_pxa27x()) 69 return pxa27x_get_memclk_frequency_10khz(); 70 else 71 return pxa3xx_get_memclk_frequency_10khz(); 72 } 73 EXPORT_SYMBOL(get_memclk_frequency_10khz); 74 75 /* 76 * Handy function to set GPIO alternate functions 77 */ 78 int pxa_last_gpio; 79 80 int pxa_gpio_mode(int gpio_mode) 81 { 82 unsigned long flags; 83 int gpio = gpio_mode & GPIO_MD_MASK_NR; 84 int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; 85 int gafr; 86 87 if (gpio > pxa_last_gpio) 88 return -EINVAL; 89 90 local_irq_save(flags); 91 if (gpio_mode & GPIO_DFLT_LOW) 92 GPCR(gpio) = GPIO_bit(gpio); 93 else if (gpio_mode & GPIO_DFLT_HIGH) 94 GPSR(gpio) = GPIO_bit(gpio); 95 if (gpio_mode & GPIO_MD_MASK_DIR) 96 GPDR(gpio) |= GPIO_bit(gpio); 97 else 98 GPDR(gpio) &= ~GPIO_bit(gpio); 99 gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); 100 GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); 101 local_irq_restore(flags); 102 103 return 0; 104 } 105 106 EXPORT_SYMBOL(pxa_gpio_mode); 107 108 int gpio_direction_input(unsigned gpio) 109 { 110 unsigned long flags; 111 u32 mask; 112 113 if (gpio > pxa_last_gpio) 114 return -EINVAL; 115 116 mask = GPIO_bit(gpio); 117 local_irq_save(flags); 118 GPDR(gpio) &= ~mask; 119 local_irq_restore(flags); 120 121 return 0; 122 } 123 EXPORT_SYMBOL(gpio_direction_input); 124 125 int gpio_direction_output(unsigned gpio, int value) 126 { 127 unsigned long flags; 128 u32 mask; 129 130 if (gpio > pxa_last_gpio) 131 return -EINVAL; 132 133 mask = GPIO_bit(gpio); 134 local_irq_save(flags); 135 if (value) 136 GPSR(gpio) = mask; 137 else 138 GPCR(gpio) = mask; 139 GPDR(gpio) |= mask; 140 local_irq_restore(flags); 141 142 return 0; 143 } 144 EXPORT_SYMBOL(gpio_direction_output); 145 146 /* 147 * Return GPIO level 148 */ 149 int pxa_gpio_get_value(unsigned gpio) 150 { 151 return __gpio_get_value(gpio); 152 } 153 154 EXPORT_SYMBOL(pxa_gpio_get_value); 155 156 /* 157 * Set output GPIO level 158 */ 159 void pxa_gpio_set_value(unsigned gpio, int value) 160 { 161 __gpio_set_value(gpio, value); 162 } 163 164 EXPORT_SYMBOL(pxa_gpio_set_value); 165 166 /* 167 * Routine to safely enable or disable a clock in the CKEN 168 */ 169 void __pxa_set_cken(int clock, int enable) 170 { 171 unsigned long flags; 172 local_irq_save(flags); 173 174 if (enable) 175 CKEN |= (1 << clock); 176 else 177 CKEN &= ~(1 << clock); 178 179 local_irq_restore(flags); 180 } 181 182 EXPORT_SYMBOL(__pxa_set_cken); 183 184 /* 185 * Intel PXA2xx internal register mapping. 186 * 187 * Note 1: not all PXA2xx variants implement all those addresses. 188 * 189 * Note 2: virtual 0xfffe0000-0xffffffff is reserved for the vector table 190 * and cache flush area. 191 */ 192 static struct map_desc standard_io_desc[] __initdata = { 193 { /* Devs */ 194 .virtual = 0xf2000000, 195 .pfn = __phys_to_pfn(0x40000000), 196 .length = 0x02000000, 197 .type = MT_DEVICE 198 }, { /* LCD */ 199 .virtual = 0xf4000000, 200 .pfn = __phys_to_pfn(0x44000000), 201 .length = 0x00100000, 202 .type = MT_DEVICE 203 }, { /* Mem Ctl */ 204 .virtual = 0xf6000000, 205 .pfn = __phys_to_pfn(0x48000000), 206 .length = 0x00100000, 207 .type = MT_DEVICE 208 }, { /* USB host */ 209 .virtual = 0xf8000000, 210 .pfn = __phys_to_pfn(0x4c000000), 211 .length = 0x00100000, 212 .type = MT_DEVICE 213 }, { /* Camera */ 214 .virtual = 0xfa000000, 215 .pfn = __phys_to_pfn(0x50000000), 216 .length = 0x00100000, 217 .type = MT_DEVICE 218 }, { /* IMem ctl */ 219 .virtual = 0xfe000000, 220 .pfn = __phys_to_pfn(0x58000000), 221 .length = 0x00100000, 222 .type = MT_DEVICE 223 }, { /* UNCACHED_PHYS_0 */ 224 .virtual = 0xff000000, 225 .pfn = __phys_to_pfn(0x00000000), 226 .length = 0x00100000, 227 .type = MT_DEVICE 228 } 229 }; 230 231 void __init pxa_map_io(void) 232 { 233 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); 234 get_clk_frequency_khz(1); 235 } 236 237 238 static struct resource pxamci_resources[] = { 239 [0] = { 240 .start = 0x41100000, 241 .end = 0x41100fff, 242 .flags = IORESOURCE_MEM, 243 }, 244 [1] = { 245 .start = IRQ_MMC, 246 .end = IRQ_MMC, 247 .flags = IORESOURCE_IRQ, 248 }, 249 }; 250 251 static u64 pxamci_dmamask = 0xffffffffUL; 252 253 struct platform_device pxa_device_mci = { 254 .name = "pxa2xx-mci", 255 .id = -1, 256 .dev = { 257 .dma_mask = &pxamci_dmamask, 258 .coherent_dma_mask = 0xffffffff, 259 }, 260 .num_resources = ARRAY_SIZE(pxamci_resources), 261 .resource = pxamci_resources, 262 }; 263 264 void __init pxa_set_mci_info(struct pxamci_platform_data *info) 265 { 266 pxa_device_mci.dev.platform_data = info; 267 } 268 269 270 static struct pxa2xx_udc_mach_info pxa_udc_info; 271 272 void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info) 273 { 274 memcpy(&pxa_udc_info, info, sizeof *info); 275 } 276 277 static struct resource pxa2xx_udc_resources[] = { 278 [0] = { 279 .start = 0x40600000, 280 .end = 0x4060ffff, 281 .flags = IORESOURCE_MEM, 282 }, 283 [1] = { 284 .start = IRQ_USB, 285 .end = IRQ_USB, 286 .flags = IORESOURCE_IRQ, 287 }, 288 }; 289 290 static u64 udc_dma_mask = ~(u32)0; 291 292 struct platform_device pxa_device_udc = { 293 .name = "pxa2xx-udc", 294 .id = -1, 295 .resource = pxa2xx_udc_resources, 296 .num_resources = ARRAY_SIZE(pxa2xx_udc_resources), 297 .dev = { 298 .platform_data = &pxa_udc_info, 299 .dma_mask = &udc_dma_mask, 300 } 301 }; 302 303 static struct resource pxafb_resources[] = { 304 [0] = { 305 .start = 0x44000000, 306 .end = 0x4400ffff, 307 .flags = IORESOURCE_MEM, 308 }, 309 [1] = { 310 .start = IRQ_LCD, 311 .end = IRQ_LCD, 312 .flags = IORESOURCE_IRQ, 313 }, 314 }; 315 316 static u64 fb_dma_mask = ~(u64)0; 317 318 struct platform_device pxa_device_fb = { 319 .name = "pxa2xx-fb", 320 .id = -1, 321 .dev = { 322 .dma_mask = &fb_dma_mask, 323 .coherent_dma_mask = 0xffffffff, 324 }, 325 .num_resources = ARRAY_SIZE(pxafb_resources), 326 .resource = pxafb_resources, 327 }; 328 329 void __init set_pxa_fb_info(struct pxafb_mach_info *info) 330 { 331 pxa_device_fb.dev.platform_data = info; 332 } 333 334 void __init set_pxa_fb_parent(struct device *parent_dev) 335 { 336 pxa_device_fb.dev.parent = parent_dev; 337 } 338 339 static struct resource pxa_resource_ffuart[] = { 340 { 341 .start = __PREG(FFUART), 342 .end = __PREG(FFUART) + 35, 343 .flags = IORESOURCE_MEM, 344 }, { 345 .start = IRQ_FFUART, 346 .end = IRQ_FFUART, 347 .flags = IORESOURCE_IRQ, 348 } 349 }; 350 351 struct platform_device pxa_device_ffuart= { 352 .name = "pxa2xx-uart", 353 .id = 0, 354 .resource = pxa_resource_ffuart, 355 .num_resources = ARRAY_SIZE(pxa_resource_ffuart), 356 }; 357 358 static struct resource pxa_resource_btuart[] = { 359 { 360 .start = __PREG(BTUART), 361 .end = __PREG(BTUART) + 35, 362 .flags = IORESOURCE_MEM, 363 }, { 364 .start = IRQ_BTUART, 365 .end = IRQ_BTUART, 366 .flags = IORESOURCE_IRQ, 367 } 368 }; 369 370 struct platform_device pxa_device_btuart = { 371 .name = "pxa2xx-uart", 372 .id = 1, 373 .resource = pxa_resource_btuart, 374 .num_resources = ARRAY_SIZE(pxa_resource_btuart), 375 }; 376 377 static struct resource pxa_resource_stuart[] = { 378 { 379 .start = __PREG(STUART), 380 .end = __PREG(STUART) + 35, 381 .flags = IORESOURCE_MEM, 382 }, { 383 .start = IRQ_STUART, 384 .end = IRQ_STUART, 385 .flags = IORESOURCE_IRQ, 386 } 387 }; 388 389 struct platform_device pxa_device_stuart = { 390 .name = "pxa2xx-uart", 391 .id = 2, 392 .resource = pxa_resource_stuart, 393 .num_resources = ARRAY_SIZE(pxa_resource_stuart), 394 }; 395 396 static struct resource pxa_resource_hwuart[] = { 397 { 398 .start = __PREG(HWUART), 399 .end = __PREG(HWUART) + 47, 400 .flags = IORESOURCE_MEM, 401 }, { 402 .start = IRQ_HWUART, 403 .end = IRQ_HWUART, 404 .flags = IORESOURCE_IRQ, 405 } 406 }; 407 408 struct platform_device pxa_device_hwuart = { 409 .name = "pxa2xx-uart", 410 .id = 3, 411 .resource = pxa_resource_hwuart, 412 .num_resources = ARRAY_SIZE(pxa_resource_hwuart), 413 }; 414 415 static struct resource pxai2c_resources[] = { 416 { 417 .start = 0x40301680, 418 .end = 0x403016a3, 419 .flags = IORESOURCE_MEM, 420 }, { 421 .start = IRQ_I2C, 422 .end = IRQ_I2C, 423 .flags = IORESOURCE_IRQ, 424 }, 425 }; 426 427 struct platform_device pxa_device_i2c = { 428 .name = "pxa2xx-i2c", 429 .id = 0, 430 .resource = pxai2c_resources, 431 .num_resources = ARRAY_SIZE(pxai2c_resources), 432 }; 433 434 void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info) 435 { 436 pxa_device_i2c.dev.platform_data = info; 437 } 438 439 static struct resource pxai2s_resources[] = { 440 { 441 .start = 0x40400000, 442 .end = 0x40400083, 443 .flags = IORESOURCE_MEM, 444 }, { 445 .start = IRQ_I2S, 446 .end = IRQ_I2S, 447 .flags = IORESOURCE_IRQ, 448 }, 449 }; 450 451 struct platform_device pxa_device_i2s = { 452 .name = "pxa2xx-i2s", 453 .id = -1, 454 .resource = pxai2s_resources, 455 .num_resources = ARRAY_SIZE(pxai2s_resources), 456 }; 457 458 static u64 pxaficp_dmamask = ~(u32)0; 459 460 struct platform_device pxa_device_ficp = { 461 .name = "pxa2xx-ir", 462 .id = -1, 463 .dev = { 464 .dma_mask = &pxaficp_dmamask, 465 .coherent_dma_mask = 0xffffffff, 466 }, 467 }; 468 469 void __init pxa_set_ficp_info(struct pxaficp_platform_data *info) 470 { 471 pxa_device_ficp.dev.platform_data = info; 472 } 473 474 struct platform_device pxa_device_rtc = { 475 .name = "sa1100-rtc", 476 .id = -1, 477 }; 478