1/* 2 * arch/arm/mach-imx/generic.c 3 * 4 * author: Sascha Hauer 5 * Created: april 20th, 2004 6 * Copyright: Synertronixx GmbH 7 * 8 * Common code for i.MX 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 as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * 24 */ 25#include <linux/platform_device.h> 26#include <linux/init.h> 27#include <linux/kernel.h> 28#include <linux/module.h> 29#include <linux/string.h> 30 31#include <asm/arch/imxfb.h> 32#include <asm/hardware.h> 33#include <asm/arch/imx-regs.h> 34 35#include <asm/mach/map.h> 36#include <asm/arch/mmc.h> 37 38void imx_gpio_mode(int gpio_mode) 39{ 40 unsigned int pin = gpio_mode & GPIO_PIN_MASK; 41 unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; 42 unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT; 43 unsigned int tmp; 44 45 /* Pullup enable */ 46 if(gpio_mode & GPIO_PUEN) 47 PUEN(port) |= (1<<pin); 48 else 49 PUEN(port) &= ~(1<<pin); 50 51 /* Data direction */ 52 if(gpio_mode & GPIO_OUT) 53 DDIR(port) |= 1<<pin; 54 else 55 DDIR(port) &= ~(1<<pin); 56 57 /* Primary / alternate function */ 58 if(gpio_mode & GPIO_AF) 59 GPR(port) |= (1<<pin); 60 else 61 GPR(port) &= ~(1<<pin); 62 63 /* use as gpio? */ 64 if(gpio_mode & GPIO_GIUS) 65 GIUS(port) |= (1<<pin); 66 else 67 GIUS(port) &= ~(1<<pin); 68 69 /* Output / input configuration */ 70 if(pin<16) { 71 tmp = OCR1(port); 72 tmp &= ~( 3<<(pin*2)); 73 tmp |= (ocr << (pin*2)); 74 OCR1(port) = tmp; 75 76 ICONFA1(port) &= ~( 3<<(pin*2)); 77 ICONFA1(port) |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); 78 ICONFB1(port) &= ~( 3<<(pin*2)); 79 ICONFB1(port) |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2); 80 } else { 81 tmp = OCR2(port); 82 tmp &= ~( 3<<((pin-16)*2)); 83 tmp |= (ocr << ((pin-16)*2)); 84 OCR2(port) = tmp; 85 86 ICONFA2(port) &= ~( 3<<((pin-16)*2)); 87 ICONFA2(port) |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << ((pin-16) * 2); 88 ICONFB2(port) &= ~( 3<<((pin-16)*2)); 89 ICONFB2(port) |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << ((pin-16) * 2); 90 } 91} 92 93EXPORT_SYMBOL(imx_gpio_mode); 94 95/* 96 * get the system pll clock in Hz 97 * 98 * mfi + mfn / (mfd +1) 99 * f = 2 * f_ref * -------------------- 100 * pd + 1 101 */ 102static unsigned int imx_decode_pll(unsigned int pll, u32 f_ref) 103{ 104 unsigned long long ll; 105 unsigned long quot; 106 107 u32 mfi = (pll >> 10) & 0xf; 108 u32 mfn = pll & 0x3ff; 109 u32 mfd = (pll >> 16) & 0x3ff; 110 u32 pd = (pll >> 26) & 0xf; 111 112 mfi = mfi <= 5 ? 5 : mfi; 113 114 ll = 2 * (unsigned long long)f_ref * ( (mfi<<16) + (mfn<<16) / (mfd+1) ); 115 quot = (pd+1) * (1<<16); 116 ll += quot / 2; 117 do_div(ll, quot); 118 return (unsigned int) ll; 119} 120 121unsigned int imx_get_system_clk(void) 122{ 123 u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512); 124 125 return imx_decode_pll(SPCTL0, f_ref); 126} 127EXPORT_SYMBOL(imx_get_system_clk); 128 129unsigned int imx_get_mcu_clk(void) 130{ 131 return imx_decode_pll(MPCTL0, CLK32 * 512); 132} 133EXPORT_SYMBOL(imx_get_mcu_clk); 134 135/* 136 * get peripheral clock 1 ( UART[12], Timer[12], PWM ) 137 */ 138unsigned int imx_get_perclk1(void) 139{ 140 return imx_get_system_clk() / (((PCDR) & 0xf)+1); 141} 142EXPORT_SYMBOL(imx_get_perclk1); 143 144/* 145 * get peripheral clock 2 ( LCD, SD, SPI[12] ) 146 */ 147unsigned int imx_get_perclk2(void) 148{ 149 return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1); 150} 151EXPORT_SYMBOL(imx_get_perclk2); 152 153/* 154 * get peripheral clock 3 ( SSI ) 155 */ 156unsigned int imx_get_perclk3(void) 157{ 158 return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1); 159} 160EXPORT_SYMBOL(imx_get_perclk3); 161 162/* 163 * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA ) 164 */ 165unsigned int imx_get_hclk(void) 166{ 167 return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1); 168} 169EXPORT_SYMBOL(imx_get_hclk); 170 171static struct resource imx_mmc_resources[] = { 172 [0] = { 173 .start = 0x00214000, 174 .end = 0x002140FF, 175 .flags = IORESOURCE_MEM, 176 }, 177 [1] = { 178 .start = (SDHC_INT), 179 .end = (SDHC_INT), 180 .flags = IORESOURCE_IRQ, 181 }, 182}; 183 184static u64 imxmmmc_dmamask = 0xffffffffUL; 185 186static struct platform_device imx_mmc_device = { 187 .name = "imx-mmc", 188 .id = 0, 189 .dev = { 190 .dma_mask = &imxmmmc_dmamask, 191 .coherent_dma_mask = 0xffffffff, 192 }, 193 .num_resources = ARRAY_SIZE(imx_mmc_resources), 194 .resource = imx_mmc_resources, 195}; 196 197void __init imx_set_mmc_info(struct imxmmc_platform_data *info) 198{ 199 imx_mmc_device.dev.platform_data = info; 200} 201 202static struct imxfb_mach_info imx_fb_info; 203 204void __init set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info) 205{ 206 memcpy(&imx_fb_info,hard_imx_fb_info,sizeof(struct imxfb_mach_info)); 207} 208EXPORT_SYMBOL(set_imx_fb_info); 209 210static struct resource imxfb_resources[] = { 211 [0] = { 212 .start = 0x00205000, 213 .end = 0x002050FF, 214 .flags = IORESOURCE_MEM, 215 }, 216 [1] = { 217 .start = LCDC_INT, 218 .end = LCDC_INT, 219 .flags = IORESOURCE_IRQ, 220 }, 221}; 222 223static u64 fb_dma_mask = ~(u64)0; 224 225static struct platform_device imxfb_device = { 226 .name = "imx-fb", 227 .id = 0, 228 .dev = { 229 .platform_data = &imx_fb_info, 230 .dma_mask = &fb_dma_mask, 231 .coherent_dma_mask = 0xffffffff, 232 }, 233 .num_resources = ARRAY_SIZE(imxfb_resources), 234 .resource = imxfb_resources, 235}; 236 237static struct platform_device *devices[] __initdata = { 238 &imx_mmc_device, 239 &imxfb_device, 240}; 241 242static struct map_desc imx_io_desc[] __initdata = { 243 { 244 .virtual = IMX_IO_BASE, 245 .pfn = __phys_to_pfn(IMX_IO_PHYS), 246 .length = IMX_IO_SIZE, 247 .type = MT_DEVICE 248 } 249}; 250 251void __init 252imx_map_io(void) 253{ 254 iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc)); 255} 256 257static int __init imx_init(void) 258{ 259 return platform_add_devices(devices, ARRAY_SIZE(devices)); 260} 261 262subsys_initcall(imx_init); 263