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/ioport.h> 24 #include <linux/pm.h> 25 #include <linux/string.h> 26 #include <linux/sysdev.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 36 #include "generic.h" 37 38 /* 39 * Get the clock frequency as reflected by CCCR and the turbo flag. 40 * We assume these values have been applied via a fcs. 41 * If info is not 0 we also display the current settings. 42 */ 43 unsigned int get_clk_frequency_khz(int info) 44 { 45 if (cpu_is_pxa21x() || cpu_is_pxa25x()) 46 return pxa25x_get_clk_frequency_khz(info); 47 else if (cpu_is_pxa27x()) 48 return pxa27x_get_clk_frequency_khz(info); 49 else 50 return pxa3xx_get_clk_frequency_khz(info); 51 } 52 EXPORT_SYMBOL(get_clk_frequency_khz); 53 54 /* 55 * Return the current memory clock frequency in units of 10kHz 56 */ 57 unsigned int get_memclk_frequency_10khz(void) 58 { 59 if (cpu_is_pxa21x() || cpu_is_pxa25x()) 60 return pxa25x_get_memclk_frequency_10khz(); 61 else if (cpu_is_pxa27x()) 62 return pxa27x_get_memclk_frequency_10khz(); 63 else 64 return pxa3xx_get_memclk_frequency_10khz(); 65 } 66 EXPORT_SYMBOL(get_memclk_frequency_10khz); 67 68 /* 69 * Routine to safely enable or disable a clock in the CKEN 70 */ 71 void __pxa_set_cken(int clock, int enable) 72 { 73 unsigned long flags; 74 local_irq_save(flags); 75 76 if (enable) 77 CKEN |= (1 << clock); 78 else 79 CKEN &= ~(1 << clock); 80 81 local_irq_restore(flags); 82 } 83 EXPORT_SYMBOL(__pxa_set_cken); 84 85 /* 86 * Intel PXA2xx internal register mapping. 87 * 88 * Note 1: not all PXA2xx variants implement all those addresses. 89 * 90 * Note 2: virtual 0xfffe0000-0xffffffff is reserved for the vector table 91 * and cache flush area. 92 */ 93 static struct map_desc standard_io_desc[] __initdata = { 94 { /* Devs */ 95 .virtual = 0xf2000000, 96 .pfn = __phys_to_pfn(0x40000000), 97 .length = 0x02000000, 98 .type = MT_DEVICE 99 }, { /* LCD */ 100 .virtual = 0xf4000000, 101 .pfn = __phys_to_pfn(0x44000000), 102 .length = 0x00100000, 103 .type = MT_DEVICE 104 }, { /* Mem Ctl */ 105 .virtual = 0xf6000000, 106 .pfn = __phys_to_pfn(0x48000000), 107 .length = 0x00200000, 108 .type = MT_DEVICE 109 }, { /* USB host */ 110 .virtual = 0xf8000000, 111 .pfn = __phys_to_pfn(0x4c000000), 112 .length = 0x00100000, 113 .type = MT_DEVICE 114 }, { /* Camera */ 115 .virtual = 0xfa000000, 116 .pfn = __phys_to_pfn(0x50000000), 117 .length = 0x00100000, 118 .type = MT_DEVICE 119 }, { /* IMem ctl */ 120 .virtual = 0xfe000000, 121 .pfn = __phys_to_pfn(0x58000000), 122 .length = 0x00100000, 123 .type = MT_DEVICE 124 }, { /* UNCACHED_PHYS_0 */ 125 .virtual = 0xff000000, 126 .pfn = __phys_to_pfn(0x00000000), 127 .length = 0x00100000, 128 .type = MT_DEVICE 129 } 130 }; 131 132 void __init pxa_map_io(void) 133 { 134 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); 135 get_clk_frequency_khz(1); 136 } 137 138 #ifdef CONFIG_PM 139 140 static unsigned long saved_gplr[4]; 141 static unsigned long saved_gpdr[4]; 142 static unsigned long saved_grer[4]; 143 static unsigned long saved_gfer[4]; 144 145 static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state) 146 { 147 int i, gpio; 148 149 for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) { 150 saved_gplr[i] = GPLR(gpio); 151 saved_gpdr[i] = GPDR(gpio); 152 saved_grer[i] = GRER(gpio); 153 saved_gfer[i] = GFER(gpio); 154 155 /* Clear GPIO transition detect bits */ 156 GEDR(gpio) = GEDR(gpio); 157 } 158 return 0; 159 } 160 161 static int pxa_gpio_resume(struct sys_device *dev) 162 { 163 int i, gpio; 164 165 for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) { 166 /* restore level with set/clear */ 167 GPSR(gpio) = saved_gplr[i]; 168 GPCR(gpio) = ~saved_gplr[i]; 169 170 GRER(gpio) = saved_grer[i]; 171 GFER(gpio) = saved_gfer[i]; 172 GPDR(gpio) = saved_gpdr[i]; 173 } 174 return 0; 175 } 176 #else 177 #define pxa_gpio_suspend NULL 178 #define pxa_gpio_resume NULL 179 #endif 180 181 struct sysdev_class pxa_gpio_sysclass = { 182 .name = "gpio", 183 .suspend = pxa_gpio_suspend, 184 .resume = pxa_gpio_resume, 185 }; 186 187 static int __init pxa_gpio_init(void) 188 { 189 return sysdev_class_register(&pxa_gpio_sysclass); 190 } 191 192 core_initcall(pxa_gpio_init); 193