2009-01-20 09:15:18 +03:00
/*
* linux / arch / arm / mach - mmp / pxa168 . c
*
* Code specific to PXA168
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/list.h>
2009-01-20 09:38:24 +03:00
# include <linux/io.h>
2009-01-20 09:15:18 +03:00
# include <linux/clk.h>
# include <asm/mach/time.h>
# include <mach/addr-map.h>
# include <mach/cputype.h>
# include <mach/regs-apbc.h>
# include <mach/irqs.h>
2009-01-20 09:38:24 +03:00
# include <mach/gpio.h>
2009-01-20 09:15:18 +03:00
# include <mach/dma.h>
# include <mach/devices.h>
2009-01-20 12:20:56 +03:00
# include <mach/mfp.h>
2009-01-20 09:15:18 +03:00
# include "common.h"
# include "clock.h"
2009-01-20 12:20:56 +03:00
# define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000)
static struct mfp_addr_map pxa168_mfp_addr_map [ ] __initdata =
{
MFP_ADDR_X ( GPIO0 , GPIO36 , 0x04c ) ,
MFP_ADDR_X ( GPIO37 , GPIO55 , 0x000 ) ,
MFP_ADDR_X ( GPIO56 , GPIO123 , 0x0e0 ) ,
MFP_ADDR_X ( GPIO124 , GPIO127 , 0x0f4 ) ,
MFP_ADDR_END ,
} ;
2009-01-20 09:38:24 +03:00
# define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c)
static void __init pxa168_init_gpio ( void )
{
int i ;
/* enable GPIO clock */
__raw_writel ( APBC_APBCLK | APBC_FNCLK , APBC_PXA168_GPIO ) ;
/* unmask GPIO edge detection for all 4 banks - APMASKx */
for ( i = 0 ; i < 4 ; i + + )
__raw_writel ( 0xffffffff , APMASK ( i ) ) ;
pxa_init_gpio ( IRQ_PXA168_GPIOX , 0 , 127 , NULL ) ;
}
2009-01-20 09:15:18 +03:00
void __init pxa168_init_irq ( void )
{
icu_init_irq ( ) ;
2009-01-20 09:38:24 +03:00
pxa168_init_gpio ( ) ;
2009-01-20 09:15:18 +03:00
}
/* APB peripheral clocks */
static APBC_CLK ( uart1 , PXA168_UART1 , 1 , 14745600 ) ;
static APBC_CLK ( uart2 , PXA168_UART2 , 1 , 14745600 ) ;
2009-04-13 11:34:54 +04:00
static APBC_CLK ( twsi0 , PXA168_TWSI0 , 1 , 33000000 ) ;
static APBC_CLK ( twsi1 , PXA168_TWSI1 , 1 , 33000000 ) ;
2009-01-20 09:15:18 +03:00
/* device and clock bindings */
static struct clk_lookup pxa168_clkregs [ ] = {
INIT_CLKREG ( & clk_uart1 , " pxa2xx-uart.0 " , NULL ) ,
INIT_CLKREG ( & clk_uart2 , " pxa2xx-uart.1 " , NULL ) ,
2009-04-13 11:34:54 +04:00
INIT_CLKREG ( & clk_twsi0 , " pxa2xx-i2c.0 " , NULL ) ,
INIT_CLKREG ( & clk_twsi1 , " pxa2xx-i2c.1 " , NULL ) ,
2009-01-20 09:15:18 +03:00
} ;
static int __init pxa168_init ( void )
{
if ( cpu_is_pxa168 ( ) ) {
2009-01-20 12:20:56 +03:00
mfp_init_base ( MFPR_VIRT_BASE ) ;
mfp_init_addr ( pxa168_mfp_addr_map ) ;
2009-01-20 09:15:18 +03:00
pxa_init_dma ( IRQ_PXA168_DMA_INT0 , 32 ) ;
clks_register ( ARRAY_AND_SIZE ( pxa168_clkregs ) ) ;
}
return 0 ;
}
postcore_initcall ( pxa168_init ) ;
/* system timer - clock enabled, 3.25MHz */
# define TIMER_CLK_RST (APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3))
static void __init pxa168_timer_init ( void )
{
/* this is early, we have to initialize the CCU registers by
* ourselves instead of using clk_ * API . Clock rate is defined
* by APBC_TIMERS_CLK_RST ( 3.25 MHz ) and enabled free - running
*/
__raw_writel ( APBC_APBCLK | APBC_RST , APBC_PXA168_TIMERS ) ;
/* 3.25MHz, bus/functional clock enabled, release reset */
__raw_writel ( TIMER_CLK_RST , APBC_PXA168_TIMERS ) ;
timer_init ( IRQ_PXA168_TIMER1 ) ;
}
struct sys_timer pxa168_timer = {
. init = pxa168_timer_init ,
} ;
/* on-chip devices */
PXA168_DEVICE ( uart1 , " pxa2xx-uart " , 0 , UART1 , 0xd4017000 , 0x30 , 21 , 22 ) ;
PXA168_DEVICE ( uart2 , " pxa2xx-uart " , 1 , UART2 , 0xd4018000 , 0x30 , 23 , 24 ) ;
2009-04-13 11:34:54 +04:00
PXA168_DEVICE ( twsi0 , " pxa2xx-i2c " , 0 , TWSI0 , 0xd4011000 , 0x28 ) ;
PXA168_DEVICE ( twsi1 , " pxa2xx-i2c " , 1 , TWSI1 , 0xd4025000 , 0x28 ) ;