PageRenderTime 29ms CodeModel.GetById 12ms app.highlight 13ms RepoModel.GetById 2ms app.codeStats 0ms

/arch/arm/mach-imx/generic.c

https://bitbucket.org/evzijst/gittest
C | 274 lines | 190 code | 32 blank | 52 comment | 11 complexity | cafb8c5eb8eca4ad3ddc5de04a65c49f MD5 | raw file
  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/device.h>
 26#include <linux/init.h>
 27#include <linux/kernel.h>
 28#include <linux/module.h>
 29#include <asm/hardware.h>
 30
 31#include <asm/mach/map.h>
 32
 33void imx_gpio_mode(int gpio_mode)
 34{
 35	unsigned int pin = gpio_mode & GPIO_PIN_MASK;
 36	unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> 5;
 37	unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> 10;
 38	unsigned int tmp;
 39
 40	/* Pullup enable */
 41	if(gpio_mode & GPIO_PUEN)
 42		PUEN(port) |= (1<<pin);
 43	else
 44		PUEN(port) &= ~(1<<pin);
 45
 46	/* Data direction */
 47	if(gpio_mode & GPIO_OUT)
 48		DDIR(port) |= 1<<pin;
 49	else
 50		DDIR(port) &= ~(1<<pin);
 51
 52	/* Primary / alternate function */
 53	if(gpio_mode & GPIO_AF)
 54		GPR(port) |= (1<<pin);
 55	else
 56		GPR(port) &= ~(1<<pin);
 57
 58	/* use as gpio? */
 59	if( ocr == 3 )
 60		GIUS(port) |= (1<<pin);
 61	else
 62		GIUS(port) &= ~(1<<pin);
 63
 64	/* Output / input configuration */
 65	/* FIXME: I'm not very sure about OCR and ICONF, someone
 66	 * should have a look over it
 67	 */
 68	if(pin<16) {
 69		tmp = OCR1(port);
 70		tmp &= ~( 3<<(pin*2));
 71		tmp |= (ocr << (pin*2));
 72		OCR1(port) = tmp;
 73
 74		if( gpio_mode &	GPIO_AOUT )
 75			ICONFA1(port) &= ~( 3<<(pin*2));
 76		if( gpio_mode &	GPIO_BOUT )
 77			ICONFB1(port) &= ~( 3<<(pin*2));
 78	} else {
 79		tmp = OCR2(port);
 80		tmp &= ~( 3<<((pin-16)*2));
 81		tmp |= (ocr << ((pin-16)*2));
 82		OCR2(port) = tmp;
 83
 84		if( gpio_mode &	GPIO_AOUT )
 85			ICONFA2(port) &= ~( 3<<((pin-16)*2));
 86		if( gpio_mode &	GPIO_BOUT )
 87			ICONFB2(port) &= ~( 3<<((pin-16)*2));
 88	}
 89}
 90
 91EXPORT_SYMBOL(imx_gpio_mode);
 92
 93/*
 94 *  get the system pll clock in Hz
 95 *
 96 *                  mfi + mfn / (mfd +1)
 97 *  f = 2 * f_ref * --------------------
 98 *                        pd + 1
 99 */
100static unsigned int imx_decode_pll(unsigned int pll)
101{
102	u32 mfi = (pll >> 10) & 0xf;
103	u32 mfn = pll & 0x3ff;
104	u32 mfd = (pll >> 16) & 0x3ff;
105	u32 pd =  (pll >> 26) & 0xf;
106	u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512);
107
108	mfi = mfi <= 5 ? 5 : mfi;
109
110	return (2 * (f_ref>>10) * ( (mfi<<10) + (mfn<<10) / (mfd+1) )) / (pd+1);
111}
112
113unsigned int imx_get_system_clk(void)
114{
115	return imx_decode_pll(SPCTL0);
116}
117EXPORT_SYMBOL(imx_get_system_clk);
118
119unsigned int imx_get_mcu_clk(void)
120{
121	return imx_decode_pll(MPCTL0);
122}
123EXPORT_SYMBOL(imx_get_mcu_clk);
124
125/*
126 *  get peripheral clock 1 ( UART[12], Timer[12], PWM )
127 */
128unsigned int imx_get_perclk1(void)
129{
130	return imx_get_system_clk() / (((PCDR) & 0xf)+1);
131}
132EXPORT_SYMBOL(imx_get_perclk1);
133
134/*
135 *  get peripheral clock 2 ( LCD, SD, SPI[12] )
136 */
137unsigned int imx_get_perclk2(void)
138{
139	return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1);
140}
141EXPORT_SYMBOL(imx_get_perclk2);
142
143/*
144 *  get peripheral clock 3 ( SSI )
145 */
146unsigned int imx_get_perclk3(void)
147{
148	return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1);
149}
150EXPORT_SYMBOL(imx_get_perclk3);
151
152/*
153 *  get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA )
154 */
155unsigned int imx_get_hclk(void)
156{
157	return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1);
158}
159EXPORT_SYMBOL(imx_get_hclk);
160
161static struct resource imx_mmc_resources[] = {
162	[0] = {
163		.start	= 0x00214000,
164		.end	= 0x002140FF,
165		.flags	= IORESOURCE_MEM,
166	},
167	[1] = {
168		.start	= (SDHC_INT),
169		.end	= (SDHC_INT),
170		.flags	= IORESOURCE_IRQ,
171	},
172};
173
174static struct platform_device imx_mmc_device = {
175	.name		= "imx-mmc",
176	.id		= 0,
177	.num_resources	= ARRAY_SIZE(imx_mmc_resources),
178	.resource	= imx_mmc_resources,
179};
180
181static struct resource imx_uart1_resources[] = {
182	[0] = {
183		.start	= 0x00206000,
184		.end	= 0x002060FF,
185		.flags	= IORESOURCE_MEM,
186	},
187	[1] = {
188		.start	= (UART1_MINT_RX),
189		.end	= (UART1_MINT_RX),
190		.flags	= IORESOURCE_IRQ,
191	},
192	[2] = {
193		.start	= (UART1_MINT_TX),
194		.end	= (UART1_MINT_TX),
195		.flags	= IORESOURCE_IRQ,
196	},
197};
198
199static struct platform_device imx_uart1_device = {
200	.name		= "imx-uart",
201	.id		= 0,
202	.num_resources	= ARRAY_SIZE(imx_uart1_resources),
203	.resource	= imx_uart1_resources,
204};
205
206static struct resource imx_uart2_resources[] = {
207	[0] = {
208		.start	= 0x00207000,
209		.end	= 0x002070FF,
210		.flags	= IORESOURCE_MEM,
211	},
212	[1] = {
213		.start	= (UART2_MINT_RX),
214		.end	= (UART2_MINT_RX),
215		.flags	= IORESOURCE_IRQ,
216	},
217	[2] = {
218		.start	= (UART2_MINT_TX),
219		.end	= (UART2_MINT_TX),
220		.flags	= IORESOURCE_IRQ,
221	},
222};
223
224static struct platform_device imx_uart2_device = {
225	.name		= "imx-uart",
226	.id		= 1,
227	.num_resources	= ARRAY_SIZE(imx_uart2_resources),
228	.resource	= imx_uart2_resources,
229};
230
231static struct resource imxfb_resources[] = {
232	[0] = {
233		.start	= 0x00205000,
234		.end	= 0x002050FF,
235		.flags	= IORESOURCE_MEM,
236	},
237	[1] = {
238		.start	= LCDC_INT,
239		.end	= LCDC_INT,
240		.flags	= IORESOURCE_IRQ,
241	},
242};
243
244static struct platform_device imxfb_device = {
245	.name		= "imx-fb",
246	.id		= 0,
247	.num_resources	= ARRAY_SIZE(imxfb_resources),
248	.resource	= imxfb_resources,
249};
250
251static struct platform_device *devices[] __initdata = {
252	&imx_mmc_device,
253	&imxfb_device,
254	&imx_uart1_device,
255	&imx_uart2_device,
256};
257
258static struct map_desc imx_io_desc[] __initdata = {
259	/* virtual     physical    length      type */
260	{IMX_IO_BASE, IMX_IO_PHYS, IMX_IO_SIZE, MT_DEVICE},
261};
262
263void __init
264imx_map_io(void)
265{
266	iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc));
267}
268
269static int __init imx_init(void)
270{
271	return platform_add_devices(devices, ARRAY_SIZE(devices));
272}
273
274subsys_initcall(imx_init);