1 /* 2 * linux/arch/arm/mach-sa1100/generic.c 3 * 4 * Author: Nicolas Pitre 5 * 6 * Code common to all SA11x0 machines. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 #include <linux/config.h> 13 #include <linux/module.h> 14 #include <linux/kernel.h> 15 #include <linux/init.h> 16 #include <linux/delay.h> 17 #include <linux/pm.h> 18 #include <linux/cpufreq.h> 19 #include <linux/ioport.h> 20 21 #include <asm/div64.h> 22 #include <asm/hardware.h> 23 #include <asm/system.h> 24 #include <asm/pgtable.h> 25 #include <asm/mach/map.h> 26 #include <asm/irq.h> 27 28 #include "generic.h" 29 30 #define NR_FREQS 16 31 32 /* 33 * This table is setup for a 3.6864MHz Crystal. 34 */ 35 static const unsigned short cclk_frequency_100khz[NR_FREQS] = { 36 590, /* 59.0 MHz */ 37 737, /* 73.7 MHz */ 38 885, /* 88.5 MHz */ 39 1032, /* 103.2 MHz */ 40 1180, /* 118.0 MHz */ 41 1327, /* 132.7 MHz */ 42 1475, /* 147.5 MHz */ 43 1622, /* 162.2 MHz */ 44 1769, /* 176.9 MHz */ 45 1917, /* 191.7 MHz */ 46 2064, /* 206.4 MHz */ 47 2212, /* 221.2 MHz */ 48 2359, /* 235.9 MHz */ 49 2507, /* 250.7 MHz */ 50 2654, /* 265.4 MHz */ 51 2802 /* 280.2 MHz */ 52 }; 53 54 #if defined(CONFIG_CPU_FREQ_SA1100) || defined(CONFIG_CPU_FREQ_SA1110) 55 /* rounds up(!) */ 56 unsigned int sa11x0_freq_to_ppcr(unsigned int khz) 57 { 58 int i; 59 60 khz /= 100; 61 62 for (i = 0; i < NR_FREQS; i++) 63 if (cclk_frequency_100khz[i] >= khz) 64 break; 65 66 return i; 67 } 68 69 unsigned int sa11x0_ppcr_to_freq(unsigned int idx) 70 { 71 unsigned int freq = 0; 72 if (idx < NR_FREQS) 73 freq = cclk_frequency_100khz[idx] * 100; 74 return freq; 75 } 76 77 78 /* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on 79 * this platform, anyway. 80 */ 81 int sa11x0_verify_speed(struct cpufreq_policy *policy) 82 { 83 unsigned int tmp; 84 if (policy->cpu) 85 return -EINVAL; 86 87 cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); 88 89 /* make sure that at least one frequency is within the policy */ 90 tmp = cclk_frequency_100khz[sa11x0_freq_to_ppcr(policy->min)] * 100; 91 if (tmp > policy->max) 92 policy->max = tmp; 93 94 cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); 95 96 return 0; 97 } 98 99 unsigned int sa11x0_getspeed(unsigned int cpu) 100 { 101 if (cpu) 102 return 0; 103 return cclk_frequency_100khz[PPCR & 0xf] * 100; 104 } 105 106 #else 107 /* 108 * We still need to provide this so building without cpufreq works. 109 */ 110 unsigned int cpufreq_get(unsigned int cpu) 111 { 112 return cclk_frequency_100khz[PPCR & 0xf] * 100; 113 } 114 EXPORT_SYMBOL(cpufreq_get); 115 #endif 116 117 /* 118 * This is the SA11x0 sched_clock implementation. This has 119 * a resolution of 271ns, and a maximum value of 1165s. 120 * ( * 1E9 / 3686400 => * 78125 / 288) 121 */ 122 unsigned long long sched_clock(void) 123 { 124 unsigned long long v; 125 126 v = (unsigned long long)OSCR * 78125; 127 do_div(v, 288); 128 129 return v; 130 } 131 132 /* 133 * Default power-off for SA1100 134 */ 135 static void sa1100_power_off(void) 136 { 137 mdelay(100); 138 local_irq_disable(); 139 /* disable internal oscillator, float CS lines */ 140 PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS); 141 /* enable wake-up on GPIO0 (Assabet...) */ 142 PWER = GFER = GRER = 1; 143 /* 144 * set scratchpad to zero, just in case it is used as a 145 * restart address by the bootloader. 146 */ 147 PSPR = 0; 148 /* enter sleep mode */ 149 PMCR = PMCR_SF; 150 } 151 152 static struct resource sa11x0udc_resources[] = { 153 [0] = { 154 .start = 0x80000000, 155 .end = 0x8000ffff, 156 .flags = IORESOURCE_MEM, 157 }, 158 }; 159 160 static u64 sa11x0udc_dma_mask = 0xffffffffUL; 161 162 static struct platform_device sa11x0udc_device = { 163 .name = "sa11x0-udc", 164 .id = -1, 165 .dev = { 166 .dma_mask = &sa11x0udc_dma_mask, 167 .coherent_dma_mask = 0xffffffff, 168 }, 169 .num_resources = ARRAY_SIZE(sa11x0udc_resources), 170 .resource = sa11x0udc_resources, 171 }; 172 173 static struct resource sa11x0uart1_resources[] = { 174 [0] = { 175 .start = 0x80010000, 176 .end = 0x8001ffff, 177 .flags = IORESOURCE_MEM, 178 }, 179 }; 180 181 static struct platform_device sa11x0uart1_device = { 182 .name = "sa11x0-uart", 183 .id = 1, 184 .num_resources = ARRAY_SIZE(sa11x0uart1_resources), 185 .resource = sa11x0uart1_resources, 186 }; 187 188 static struct resource sa11x0uart3_resources[] = { 189 [0] = { 190 .start = 0x80050000, 191 .end = 0x8005ffff, 192 .flags = IORESOURCE_MEM, 193 }, 194 }; 195 196 static struct platform_device sa11x0uart3_device = { 197 .name = "sa11x0-uart", 198 .id = 3, 199 .num_resources = ARRAY_SIZE(sa11x0uart3_resources), 200 .resource = sa11x0uart3_resources, 201 }; 202 203 static struct resource sa11x0mcp_resources[] = { 204 [0] = { 205 .start = 0x80060000, 206 .end = 0x8006ffff, 207 .flags = IORESOURCE_MEM, 208 }, 209 }; 210 211 static u64 sa11x0mcp_dma_mask = 0xffffffffUL; 212 213 static struct platform_device sa11x0mcp_device = { 214 .name = "sa11x0-mcp", 215 .id = -1, 216 .dev = { 217 .dma_mask = &sa11x0mcp_dma_mask, 218 .coherent_dma_mask = 0xffffffff, 219 }, 220 .num_resources = ARRAY_SIZE(sa11x0mcp_resources), 221 .resource = sa11x0mcp_resources, 222 }; 223 224 void sa11x0_set_mcp_data(struct mcp_plat_data *data) 225 { 226 sa11x0mcp_device.dev.platform_data = data; 227 } 228 229 static struct resource sa11x0ssp_resources[] = { 230 [0] = { 231 .start = 0x80070000, 232 .end = 0x8007ffff, 233 .flags = IORESOURCE_MEM, 234 }, 235 }; 236 237 static u64 sa11x0ssp_dma_mask = 0xffffffffUL; 238 239 static struct platform_device sa11x0ssp_device = { 240 .name = "sa11x0-ssp", 241 .id = -1, 242 .dev = { 243 .dma_mask = &sa11x0ssp_dma_mask, 244 .coherent_dma_mask = 0xffffffff, 245 }, 246 .num_resources = ARRAY_SIZE(sa11x0ssp_resources), 247 .resource = sa11x0ssp_resources, 248 }; 249 250 static struct resource sa11x0fb_resources[] = { 251 [0] = { 252 .start = 0xb0100000, 253 .end = 0xb010ffff, 254 .flags = IORESOURCE_MEM, 255 }, 256 [1] = { 257 .start = IRQ_LCD, 258 .end = IRQ_LCD, 259 .flags = IORESOURCE_IRQ, 260 }, 261 }; 262 263 static struct platform_device sa11x0fb_device = { 264 .name = "sa11x0-fb", 265 .id = -1, 266 .dev = { 267 .coherent_dma_mask = 0xffffffff, 268 }, 269 .num_resources = ARRAY_SIZE(sa11x0fb_resources), 270 .resource = sa11x0fb_resources, 271 }; 272 273 static struct platform_device sa11x0pcmcia_device = { 274 .name = "sa11x0-pcmcia", 275 .id = -1, 276 }; 277 278 static struct platform_device sa11x0mtd_device = { 279 .name = "flash", 280 .id = -1, 281 }; 282 283 void sa11x0_set_flash_data(struct flash_platform_data *flash, 284 struct resource *res, int nr) 285 { 286 sa11x0mtd_device.dev.platform_data = flash; 287 sa11x0mtd_device.resource = res; 288 sa11x0mtd_device.num_resources = nr; 289 } 290 291 static struct resource sa11x0ir_resources[] = { 292 { 293 .start = __PREG(Ser2UTCR0), 294 .end = __PREG(Ser2UTCR0) + 0x24 - 1, 295 .flags = IORESOURCE_MEM, 296 }, { 297 .start = __PREG(Ser2HSCR0), 298 .end = __PREG(Ser2HSCR0) + 0x1c - 1, 299 .flags = IORESOURCE_MEM, 300 }, { 301 .start = __PREG(Ser2HSCR2), 302 .end = __PREG(Ser2HSCR2) + 0x04 - 1, 303 .flags = IORESOURCE_MEM, 304 }, { 305 .start = IRQ_Ser2ICP, 306 .end = IRQ_Ser2ICP, 307 .flags = IORESOURCE_IRQ, 308 } 309 }; 310 311 static struct platform_device sa11x0ir_device = { 312 .name = "sa11x0-ir", 313 .id = -1, 314 .num_resources = ARRAY_SIZE(sa11x0ir_resources), 315 .resource = sa11x0ir_resources, 316 }; 317 318 void sa11x0_set_irda_data(struct irda_platform_data *irda) 319 { 320 sa11x0ir_device.dev.platform_data = irda; 321 } 322 323 static struct platform_device *sa11x0_devices[] __initdata = { 324 &sa11x0udc_device, 325 &sa11x0uart1_device, 326 &sa11x0uart3_device, 327 &sa11x0mcp_device, 328 &sa11x0ssp_device, 329 &sa11x0pcmcia_device, 330 &sa11x0fb_device, 331 &sa11x0mtd_device, 332 }; 333 334 static int __init sa1100_init(void) 335 { 336 pm_power_off = sa1100_power_off; 337 338 if (sa11x0ir_device.dev.platform_data) 339 platform_device_register(&sa11x0ir_device); 340 341 return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices)); 342 } 343 344 arch_initcall(sa1100_init); 345 346 void (*sa1100fb_backlight_power)(int on); 347 void (*sa1100fb_lcd_power)(int on); 348 349 EXPORT_SYMBOL(sa1100fb_backlight_power); 350 EXPORT_SYMBOL(sa1100fb_lcd_power); 351 352 353 /* 354 * Common I/O mapping: 355 * 356 * Typically, static virtual address mappings are as follow: 357 * 358 * 0xf0000000-0xf3ffffff: miscellaneous stuff (CPLDs, etc.) 359 * 0xf4000000-0xf4ffffff: SA-1111 360 * 0xf5000000-0xf5ffffff: reserved (used by cache flushing area) 361 * 0xf6000000-0xfffeffff: reserved (internal SA1100 IO defined above) 362 * 0xffff0000-0xffff0fff: SA1100 exception vectors 363 * 0xffff2000-0xffff2fff: Minicache copy_user_page area 364 * 365 * Below 0xe8000000 is reserved for vm allocation. 366 * 367 * The machine specific code must provide the extra mapping beside the 368 * default mapping provided here. 369 */ 370 371 static struct map_desc standard_io_desc[] __initdata = { 372 /* virtual physical length type */ 373 { 0xf8000000, 0x80000000, 0x00100000, MT_DEVICE }, /* PCM */ 374 { 0xfa000000, 0x90000000, 0x00100000, MT_DEVICE }, /* SCM */ 375 { 0xfc000000, 0xa0000000, 0x00100000, MT_DEVICE }, /* MER */ 376 { 0xfe000000, 0xb0000000, 0x00200000, MT_DEVICE } /* LCD + DMA */ 377 }; 378 379 void __init sa1100_map_io(void) 380 { 381 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); 382 } 383 384 /* 385 * Disable the memory bus request/grant signals on the SA1110 to 386 * ensure that we don't receive spurious memory requests. We set 387 * the MBGNT signal false to ensure the SA1111 doesn't own the 388 * SDRAM bus. 389 */ 390 void __init sa1110_mb_disable(void) 391 { 392 unsigned long flags; 393 394 local_irq_save(flags); 395 396 PGSR &= ~GPIO_MBGNT; 397 GPCR = GPIO_MBGNT; 398 GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT; 399 400 GAFR &= ~(GPIO_MBGNT | GPIO_MBREQ); 401 402 local_irq_restore(flags); 403 } 404 405 /* 406 * If the system is going to use the SA-1111 DMA engines, set up 407 * the memory bus request/grant pins. 408 */ 409 void __init sa1110_mb_enable(void) 410 { 411 unsigned long flags; 412 413 local_irq_save(flags); 414 415 PGSR &= ~GPIO_MBGNT; 416 GPCR = GPIO_MBGNT; 417 GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT; 418 419 GAFR |= (GPIO_MBGNT | GPIO_MBREQ); 420 TUCR |= TUCR_MR; 421 422 local_irq_restore(flags); 423 } 424 425