Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
cccf59ab
Commit
cccf59ab
authored
Jul 28, 2010
by
Kevin Wells
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'test' of ../test/linux-2.6-lpc2 into wells/lpc32xx-arch_v2
parents
fc0f5ac8
40805949
Changes
30
Show whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
4827 additions
and
0 deletions
+4827
-0
arch/arm/Kconfig
arch/arm/Kconfig
+15
-0
arch/arm/Makefile
arch/arm/Makefile
+1
-0
arch/arm/mach-lpc32xx/Kconfig
arch/arm/mach-lpc32xx/Kconfig
+33
-0
arch/arm/mach-lpc32xx/Makefile
arch/arm/mach-lpc32xx/Makefile
+8
-0
arch/arm/mach-lpc32xx/Makefile.boot
arch/arm/mach-lpc32xx/Makefile.boot
+4
-0
arch/arm/mach-lpc32xx/clock.c
arch/arm/mach-lpc32xx/clock.c
+1137
-0
arch/arm/mach-lpc32xx/clock.h
arch/arm/mach-lpc32xx/clock.h
+38
-0
arch/arm/mach-lpc32xx/common.c
arch/arm/mach-lpc32xx/common.c
+271
-0
arch/arm/mach-lpc32xx/common.h
arch/arm/mach-lpc32xx/common.h
+73
-0
arch/arm/mach-lpc32xx/gpiolib.c
arch/arm/mach-lpc32xx/gpiolib.c
+446
-0
arch/arm/mach-lpc32xx/include/mach/clkdev.h
arch/arm/mach-lpc32xx/include/mach/clkdev.h
+25
-0
arch/arm/mach-lpc32xx/include/mach/debug-macro.S
arch/arm/mach-lpc32xx/include/mach/debug-macro.S
+31
-0
arch/arm/mach-lpc32xx/include/mach/entry-macro.S
arch/arm/mach-lpc32xx/include/mach/entry-macro.S
+47
-0
arch/arm/mach-lpc32xx/include/mach/gpio.h
arch/arm/mach-lpc32xx/include/mach/gpio.h
+74
-0
arch/arm/mach-lpc32xx/include/mach/hardware.h
arch/arm/mach-lpc32xx/include/mach/hardware.h
+34
-0
arch/arm/mach-lpc32xx/include/mach/i2c.h
arch/arm/mach-lpc32xx/include/mach/i2c.h
+63
-0
arch/arm/mach-lpc32xx/include/mach/io.h
arch/arm/mach-lpc32xx/include/mach/io.h
+27
-0
arch/arm/mach-lpc32xx/include/mach/irqs.h
arch/arm/mach-lpc32xx/include/mach/irqs.h
+117
-0
arch/arm/mach-lpc32xx/include/mach/memory.h
arch/arm/mach-lpc32xx/include/mach/memory.h
+27
-0
arch/arm/mach-lpc32xx/include/mach/platform.h
arch/arm/mach-lpc32xx/include/mach/platform.h
+694
-0
arch/arm/mach-lpc32xx/include/mach/system.h
arch/arm/mach-lpc32xx/include/mach/system.h
+52
-0
arch/arm/mach-lpc32xx/include/mach/timex.h
arch/arm/mach-lpc32xx/include/mach/timex.h
+28
-0
arch/arm/mach-lpc32xx/include/mach/uncompress.h
arch/arm/mach-lpc32xx/include/mach/uncompress.h
+60
-0
arch/arm/mach-lpc32xx/include/mach/vmalloc.h
arch/arm/mach-lpc32xx/include/mach/vmalloc.h
+24
-0
arch/arm/mach-lpc32xx/irq.c
arch/arm/mach-lpc32xx/irq.c
+432
-0
arch/arm/mach-lpc32xx/phy3250.c
arch/arm/mach-lpc32xx/phy3250.c
+397
-0
arch/arm/mach-lpc32xx/pm.c
arch/arm/mach-lpc32xx/pm.c
+146
-0
arch/arm/mach-lpc32xx/serial.c
arch/arm/mach-lpc32xx/serial.c
+190
-0
arch/arm/mach-lpc32xx/suspend.S
arch/arm/mach-lpc32xx/suspend.S
+151
-0
arch/arm/mach-lpc32xx/timer.c
arch/arm/mach-lpc32xx/timer.c
+182
-0
No files found.
arch/arm/Kconfig
View file @
cccf59ab
...
...
@@ -482,6 +482,19 @@ config ARCH_LOKI
help
Support for the Marvell Loki (88RC8480) SoC.
config ARCH_LPC32XX
bool "NXP LPC32XX"
select CPU_ARM926T
select ARCH_REQUIRE_GPIOLIB
select HAVE_IDE
select ARM_AMBA
select USB_ARCH_HAS_OHCI
select COMMON_CLKDEV
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
Support for the NXP LPC32XX family of processors
config ARCH_MV78XX0
bool "Marvell MV78xx0"
select CPU_FEROCEON
...
...
@@ -845,6 +858,8 @@ source "arch/arm/mach-lh7a40x/Kconfig"
source "arch/arm/mach-loki/Kconfig"
source "arch/arm/mach-lpc32xx/Kconfig"
source "arch/arm/mach-msm/Kconfig"
source "arch/arm/mach-mv78xx0/Kconfig"
...
...
arch/arm/Makefile
View file @
cccf59ab
...
...
@@ -142,6 +142,7 @@ machine-$(CONFIG_ARCH_KS8695) := ks8695
machine-$(CONFIG_ARCH_L7200)
:=
l7200
machine-$(CONFIG_ARCH_LH7A40X)
:=
lh7a40x
machine-$(CONFIG_ARCH_LOKI)
:=
loki
machine-$(CONFIG_ARCH_LPC32XX)
:=
lpc32xx
machine-$(CONFIG_ARCH_MMP)
:=
mmp
machine-$(CONFIG_ARCH_MSM)
:=
msm
machine-$(CONFIG_ARCH_MV78XX0)
:=
mv78xx0
...
...
arch/arm/mach-lpc32xx/Kconfig
0 → 100644
View file @
cccf59ab
if ARCH_LPC32XX
menu "Individual UART enable selections"
config ARCH_LPC32XX_UART3_SELECT
bool "Add support for standard UART3"
help
Adds support for standard UART 3 when the 8250 serial support
is enabled.
config ARCH_LPC32XX_UART4_SELECT
bool "Add support for standard UART4"
help
Adds support for standard UART 4 when the 8250 serial support
is enabled.
config ARCH_LPC32XX_UART5_SELECT
bool "Add support for standard UART5"
default y
help
Adds support for standard UART 5 when the 8250 serial support
is enabled.
config ARCH_LPC32XX_UART6_SELECT
bool "Add support for standard UART6"
help
Adds support for standard UART 6 when the 8250 serial support
is enabled.
endmenu
endif
arch/arm/mach-lpc32xx/Makefile
0 → 100644
View file @
cccf59ab
#
# Makefile for the linux kernel.
#
obj-y
:=
timer.o irq.o common.o serial.o clock.o
obj-y
+=
gpiolib.o pm.o suspend.o
obj-y
+=
phy3250.o
arch/arm/mach-lpc32xx/Makefile.boot
0 → 100644
View file @
cccf59ab
zreladdr-y
:=
0x80008000
params_phys-y
:=
0x80000100
initrd_phys-y
:=
0x82000000
arch/arm/mach-lpc32xx/clock.c
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/clock.c
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* LPC32xx clock management driver overview
*
* The LPC32XX contains a number of high level system clocks that can be
* generated from different sources. These system clocks are used to
* generate the CPU and bus rates and the individual peripheral clocks in
* the system. When Linux is started by the boot loader, the system
* clocks are already running. Stopping a system clock during normal
* Linux operation should never be attempted, as peripherals that require
* those clocks will quit working (ie, DRAM).
*
* The LPC32xx high level clock tree looks as follows. Clocks marked with
* an asterisk are always on and cannot be disabled. Clocks marked with
* an ampersand can only be disabled in CPU suspend mode. Clocks marked
* with a caret are always on if it is the selected clock for the SYSCLK
* source. The clock that isn't used for SYSCLK can be enabled and
* disabled normally.
* 32KHz oscillator*
* / | \
* RTC* PLL397^ TOUCH
* /
* Main oscillator^ /
* | \ /
* | SYSCLK&
* | \
* | \
* USB_PLL HCLK_PLL&
* | | |
* USB host/device PCLK& |
* | |
* Peripherals
*
* The CPU and chip bus rates are derived from the HCLK PLL, which can
* generate various clock rates up to 266MHz and beyond. The internal bus
* rates (PCLK and HCLK) are generated from dividers based on the HCLK
* PLL rate. HCLK can be a ratio of 1:1, 1:2, or 1:4 or HCLK PLL rate,
* while PCLK can be 1:1 to 1:32 of HCLK PLL rate. Most peripherals high
* level clocks are based on either HCLK or PCLK, but have their own
* dividers as part of the IP itself. Because of this, the system clock
* rates should not be changed.
*
* The HCLK PLL is clocked from SYSCLK, which can be derived from the
* main oscillator or PLL397. PLL397 generates a rate that is 397 times
* the 32KHz oscillator rate. The main oscillator runs at the selected
* oscillator/crystal rate on the mosc_in pin of the LPC32xx. This rate
* is normally 13MHz, but depends on the selection of external crystals
* or oscillators. If USB operation is required, the main oscillator must
* be used in the system.
*
* Switching SYSCLK between sources during normal Linux operation is not
* supported. SYSCLK is preset in the bootloader. Because of the
* complexities of clock management during clock frequency changes,
* there are some limitations to the clock driver explained below:
* - The PLL397 and main oscillator can be enabled and disabled by the
* clk_enable() and clk_disable() functions unless SYSCLK is based
* on that clock. This allows the other oscillator that isn't driving
* the HCLK PLL to be used as another system clock that can be routed
* to an external pin.
* - The muxed SYSCLK input and HCLK_PLL rate cannot be changed with
* this driver.
* - HCLK and PCLK rates cannot be changed as part of this driver.
* - Most peripherals have their own dividers are part of the peripheral
* block. Changing SYSCLK, HCLK PLL, HCLK, or PCLK sources or rates
* will also impact the individual peripheral rates.
*/
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <mach/hardware.h>
#include <asm/clkdev.h>
#include <mach/clkdev.h>
#include <mach/platform.h>
#include "clock.h"
#include "common.h"
static
struct
clk
clk_armpll
;
static
struct
clk
clk_usbpll
;
static
DEFINE_MUTEX
(
clkm_lock
);
/*
* Post divider values for PLLs based on selected register value
*/
static
const
u32
pll_postdivs
[
4
]
=
{
1
,
2
,
4
,
8
};
static
unsigned
long
local_return_parent_rate
(
struct
clk
*
clk
)
{
/*
* If a clock has a rate of 0, then it inherits it's parent
* clock rate
*/
while
(
clk
->
rate
==
0
)
clk
=
clk
->
parent
;
return
clk
->
rate
;
}
/* 32KHz clock has a fixed rate and is not stoppable */
static
struct
clk
osc_32KHz
=
{
.
rate
=
LPC32XX_CLOCK_OSC_FREQ
,
.
get_rate
=
local_return_parent_rate
,
};
static
int
local_pll397_enable
(
struct
clk
*
clk
,
int
enable
)
{
u32
reg
;
unsigned
long
timeout
=
1
+
msecs_to_jiffies
(
10
);
reg
=
__raw_readl
(
LPC32XX_CLKPWR_PLL397_CTRL
);
if
(
enable
==
0
)
{
reg
|=
LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS
;
__raw_writel
(
reg
,
LPC32XX_CLKPWR_PLL397_CTRL
);
}
else
{
/* Enable PLL397 */
reg
&=
~
LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS
;
__raw_writel
(
reg
,
LPC32XX_CLKPWR_PLL397_CTRL
);
/* Wait for PLL397 lock */
while
(((
__raw_readl
(
LPC32XX_CLKPWR_PLL397_CTRL
)
&
LPC32XX_CLKPWR_SYSCTRL_PLL397_STS
)
==
0
)
&&
(
timeout
>
jiffies
))
cpu_relax
();
if
((
__raw_readl
(
LPC32XX_CLKPWR_PLL397_CTRL
)
&
LPC32XX_CLKPWR_SYSCTRL_PLL397_STS
)
==
0
)
return
-
ENODEV
;
}
return
0
;
}
static
int
local_oscmain_enable
(
struct
clk
*
clk
,
int
enable
)
{
u32
reg
;
unsigned
long
timeout
=
1
+
msecs_to_jiffies
(
10
);
reg
=
__raw_readl
(
LPC32XX_CLKPWR_MAIN_OSC_CTRL
);
if
(
enable
==
0
)
{
reg
|=
LPC32XX_CLKPWR_MOSC_DISABLE
;
__raw_writel
(
reg
,
LPC32XX_CLKPWR_MAIN_OSC_CTRL
);
}
else
{
/* Enable main oscillator */
reg
&=
~
LPC32XX_CLKPWR_MOSC_DISABLE
;
__raw_writel
(
reg
,
LPC32XX_CLKPWR_MAIN_OSC_CTRL
);
/* Wait for main oscillator to start */
while
(((
__raw_readl
(
LPC32XX_CLKPWR_MAIN_OSC_CTRL
)
&
LPC32XX_CLKPWR_MOSC_DISABLE
)
!=
0
)
&&
(
timeout
>
jiffies
))
cpu_relax
();
if
((
__raw_readl
(
LPC32XX_CLKPWR_MAIN_OSC_CTRL
)
&
LPC32XX_CLKPWR_MOSC_DISABLE
)
!=
0
)
return
-
ENODEV
;
}
return
0
;
}
static
struct
clk
osc_pll397
=
{
.
parent
=
&
osc_32KHz
,
.
enable
=
local_pll397_enable
,
.
rate
=
LPC32XX_CLOCK_OSC_FREQ
*
397
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
osc_main
=
{
.
enable
=
local_oscmain_enable
,
.
rate
=
LPC32XX_MAIN_OSC_FREQ
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_sys
;
/*
* Convert a PLL register value to a PLL output frequency
*/
u32
clk_get_pllrate_from_reg
(
u32
inputclk
,
u32
regval
)
{
struct
clk_pll_setup
pllcfg
;
pllcfg
.
cco_bypass_b15
=
0
;
pllcfg
.
direct_output_b14
=
0
;
pllcfg
.
fdbk_div_ctrl_b13
=
0
;
if
((
regval
&
LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS
)
!=
0
)
pllcfg
.
cco_bypass_b15
=
1
;
if
((
regval
&
LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS
)
!=
0
)
pllcfg
.
direct_output_b14
=
1
;
if
((
regval
&
LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK
)
!=
0
)
pllcfg
.
fdbk_div_ctrl_b13
=
1
;
pllcfg
.
pll_m
=
1
+
((
regval
>>
1
)
&
0xFF
);
pllcfg
.
pll_n
=
1
+
((
regval
>>
9
)
&
0x3
);
pllcfg
.
pll_p
=
pll_postdivs
[((
regval
>>
11
)
&
0x3
)];
return
clk_check_pll_setup
(
inputclk
,
&
pllcfg
);
}
/*
* Setup the HCLK PLL with a PLL structure
*/
static
u32
local_clk_pll_setup
(
struct
clk_pll_setup
*
PllSetup
)
{
u32
tv
,
tmp
=
0
;
if
(
PllSetup
->
analog_on
!=
0
)
tmp
|=
LPC32XX_CLKPWR_HCLKPLL_POWER_UP
;
if
(
PllSetup
->
cco_bypass_b15
!=
0
)
tmp
|=
LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS
;
if
(
PllSetup
->
direct_output_b14
!=
0
)
tmp
|=
LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS
;
if
(
PllSetup
->
fdbk_div_ctrl_b13
!=
0
)
tmp
|=
LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK
;
tv
=
ffs
(
PllSetup
->
pll_p
)
-
1
;
if
((
!
is_power_of_2
(
PllSetup
->
pll_p
))
||
(
tv
>
3
))
return
0
;
tmp
|=
LPC32XX_CLKPWR_HCLKPLL_POSTDIV_2POW
(
tv
);
tmp
|=
LPC32XX_CLKPWR_HCLKPLL_PREDIV_PLUS1
(
PllSetup
->
pll_n
-
1
);
tmp
|=
LPC32XX_CLKPWR_HCLKPLL_PLLM
(
PllSetup
->
pll_m
-
1
);
return
tmp
;
}
/*
* Update the ARM core PLL frequency rate variable from the actual PLL setting
*/
static
void
local_update_armpll_rate
(
void
)
{
u32
clkin
,
pllreg
;
clkin
=
clk_armpll
.
parent
->
rate
;
pllreg
=
__raw_readl
(
LPC32XX_CLKPWR_HCLKPLL_CTRL
)
&
0x1FFFF
;
clk_armpll
.
rate
=
clk_get_pllrate_from_reg
(
clkin
,
pllreg
);
}
/*
* Find a PLL configuration for the selected input frequency
*/
static
u32
local_clk_find_pll_cfg
(
u32
pllin_freq
,
u32
target_freq
,
struct
clk_pll_setup
*
pllsetup
)
{
u32
ifreq
,
freqtol
,
m
,
n
,
p
,
fclkout
;
/* Determine frequency tolerance limits */
freqtol
=
target_freq
/
250
;
ifreq
=
pllin_freq
;
/* Is direct bypass mode possible? */
if
(
abs
(
pllin_freq
-
target_freq
)
<=
freqtol
)
{
pllsetup
->
analog_on
=
0
;
pllsetup
->
cco_bypass_b15
=
1
;
pllsetup
->
direct_output_b14
=
1
;
pllsetup
->
fdbk_div_ctrl_b13
=
1
;
pllsetup
->
pll_p
=
pll_postdivs
[
0
];
pllsetup
->
pll_n
=
1
;
pllsetup
->
pll_m
=
1
;
return
clk_check_pll_setup
(
ifreq
,
pllsetup
);
}
else
if
(
target_freq
<=
ifreq
)
{
pllsetup
->
analog_on
=
0
;
pllsetup
->
cco_bypass_b15
=
1
;
pllsetup
->
direct_output_b14
=
0
;
pllsetup
->
fdbk_div_ctrl_b13
=
1
;
pllsetup
->
pll_n
=
1
;
pllsetup
->
pll_m
=
1
;
for
(
p
=
0
;
p
<=
3
;
p
++
)
{
pllsetup
->
pll_p
=
pll_postdivs
[
p
];
fclkout
=
clk_check_pll_setup
(
ifreq
,
pllsetup
);
if
(
abs
(
target_freq
-
fclkout
)
<=
freqtol
)
return
fclkout
;
}
}
/* Is direct mode possible? */
pllsetup
->
analog_on
=
1
;
pllsetup
->
cco_bypass_b15
=
0
;
pllsetup
->
direct_output_b14
=
1
;
pllsetup
->
fdbk_div_ctrl_b13
=
0
;
pllsetup
->
pll_p
=
pll_postdivs
[
0
];
for
(
m
=
1
;
m
<=
256
;
m
++
)
{
for
(
n
=
1
;
n
<=
4
;
n
++
)
{
/* Compute output frequency for this value */
pllsetup
->
pll_n
=
n
;
pllsetup
->
pll_m
=
m
;
fclkout
=
clk_check_pll_setup
(
ifreq
,
pllsetup
);
if
(
abs
(
target_freq
-
fclkout
)
<=
freqtol
)
return
fclkout
;
}
}
/* Is integer mode possible? */
pllsetup
->
analog_on
=
1
;
pllsetup
->
cco_bypass_b15
=
0
;
pllsetup
->
direct_output_b14
=
0
;
pllsetup
->
fdbk_div_ctrl_b13
=
1
;
for
(
m
=
1
;
m
<=
256
;
m
++
)
{
for
(
n
=
1
;
n
<=
4
;
n
++
)
{
for
(
p
=
0
;
p
<
4
;
p
++
)
{
/* Compute output frequency */
pllsetup
->
pll_p
=
pll_postdivs
[
p
];
pllsetup
->
pll_n
=
n
;
pllsetup
->
pll_m
=
m
;
fclkout
=
clk_check_pll_setup
(
ifreq
,
pllsetup
);
if
(
abs
(
target_freq
-
fclkout
)
<=
freqtol
)
return
fclkout
;
}
}
}
/* Try non-integer mode */
pllsetup
->
analog_on
=
1
;
pllsetup
->
cco_bypass_b15
=
0
;
pllsetup
->
direct_output_b14
=
0
;
pllsetup
->
fdbk_div_ctrl_b13
=
0
;
for
(
m
=
1
;
m
<=
256
;
m
++
)
{
for
(
n
=
1
;
n
<=
4
;
n
++
)
{
for
(
p
=
0
;
p
<
4
;
p
++
)
{
/* Compute output frequency */
pllsetup
->
pll_p
=
pll_postdivs
[
p
];
pllsetup
->
pll_n
=
n
;
pllsetup
->
pll_m
=
m
;
fclkout
=
clk_check_pll_setup
(
ifreq
,
pllsetup
);
if
(
abs
(
target_freq
-
fclkout
)
<=
freqtol
)
return
fclkout
;
}
}
}
return
0
;
}
static
struct
clk
clk_armpll
=
{
.
parent
=
&
clk_sys
,
.
get_rate
=
local_return_parent_rate
,
};
/*
* Setup the USB PLL with a PLL structure
*/
static
u32
local_clk_usbpll_setup
(
struct
clk_pll_setup
*
pHCLKPllSetup
)
{
u32
reg
,
tmp
=
local_clk_pll_setup
(
pHCLKPllSetup
);
reg
=
__raw_readl
(
LPC32XX_CLKPWR_USB_CTRL
)
&
~
0x1FFFF
;
reg
|=
tmp
;
__raw_writel
(
reg
,
LPC32XX_CLKPWR_USB_CTRL
);
return
clk_check_pll_setup
(
clk_usbpll
.
parent
->
rate
,
pHCLKPllSetup
);
}
static
int
local_usbpll_enable
(
struct
clk
*
clk
,
int
enable
)
{
u32
reg
;
int
ret
=
-
ENODEV
;
unsigned
long
timeout
=
1
+
msecs_to_jiffies
(
10
);
reg
=
__raw_readl
(
LPC32XX_CLKPWR_USB_CTRL
);
if
(
enable
==
0
)
{
reg
&=
~
(
LPC32XX_CLKPWR_USBCTRL_CLK_EN1
|
LPC32XX_CLKPWR_USBCTRL_CLK_EN2
);
__raw_writel
(
reg
,
LPC32XX_CLKPWR_USB_CTRL
);
}
else
if
(
reg
&
LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP
)
{
reg
|=
LPC32XX_CLKPWR_USBCTRL_CLK_EN1
;
__raw_writel
(
reg
,
LPC32XX_CLKPWR_USB_CTRL
);
/* Wait for PLL lock */
while
((
timeout
>
jiffies
)
&
(
ret
==
-
ENODEV
))
{
reg
=
__raw_readl
(
LPC32XX_CLKPWR_USB_CTRL
);
if
(
reg
&
LPC32XX_CLKPWR_USBCTRL_PLL_STS
)
ret
=
0
;
}
if
(
ret
==
0
)
{
reg
|=
LPC32XX_CLKPWR_USBCTRL_CLK_EN2
;
__raw_writel
(
reg
,
LPC32XX_CLKPWR_USB_CTRL
);
}
}
return
ret
;
}
static
unsigned
long
local_usbpll_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
u32
clkin
,
usbdiv
;
struct
clk_pll_setup
pllsetup
;
/*
* Unlike other clocks, this clock has a KHz input rate, so bump
* it up to work with the PLL function
*/
rate
=
rate
*
1000
;
clkin
=
clk
->
parent
->
rate
;
usbdiv
=
(
__raw_readl
(
LPC32XX_CLKPWR_USBCLK_PDIV
)
&
LPC32XX_CLKPWR_USBPDIV_PLL_MASK
)
+
1
;
clkin
=
clkin
/
usbdiv
;
/* Try to find a good rate setup */
if
(
local_clk_find_pll_cfg
(
clkin
,
rate
,
&
pllsetup
)
==
0
)
return
0
;
return
clk_check_pll_setup
(
clkin
,
&
pllsetup
);
}
static
int
local_usbpll_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
u32
clkin
,
reg
,
usbdiv
;
struct
clk_pll_setup
pllsetup
;
/*
* Unlike other clocks, this clock has a KHz input rate, so bump
* it up to work with the PLL function
*/
rate
=
rate
*
1000
;
clkin
=
clk
->
get_rate
(
clk
);
usbdiv
=
(
__raw_readl
(
LPC32XX_CLKPWR_USBCLK_PDIV
)
&
LPC32XX_CLKPWR_USBPDIV_PLL_MASK
)
+
1
;
clkin
=
clkin
/
usbdiv
;
/* Try to find a good rate setup */
if
(
local_clk_find_pll_cfg
(
clkin
,
rate
,
&
pllsetup
)
==
0
)
return
-
EINVAL
;
local_usbpll_enable
(
clk
,
0
);
reg
=
__raw_readl
(
LPC32XX_CLKPWR_USB_CTRL
);
reg
|=
LPC32XX_CLKPWR_USBCTRL_CLK_EN1
;
__raw_writel
(
reg
,
LPC32XX_CLKPWR_USB_CTRL
);
pllsetup
.
analog_on
=
1
;
local_clk_usbpll_setup
(
&
pllsetup
);
clk
->
rate
=
clk_check_pll_setup
(
clkin
,
&
pllsetup
);
reg
=
__raw_readl
(
LPC32XX_CLKPWR_USB_CTRL
);
reg
|=
LPC32XX_CLKPWR_USBCTRL_CLK_EN2
;
__raw_writel
(
reg
,
LPC32XX_CLKPWR_USB_CTRL
);
return
0
;
}
static
struct
clk
clk_usbpll
=
{
.
parent
=
&
osc_main
,
.
set_rate
=
local_usbpll_set_rate
,
.
enable
=
local_usbpll_enable
,
.
rate
=
48000
,
/* In KHz */
.
get_rate
=
local_return_parent_rate
,
.
round_rate
=
local_usbpll_round_rate
,
};
static
u32
clk_get_hclk_div
(
void
)
{
static
const
u32
hclkdivs
[
4
]
=
{
1
,
2
,
4
,
4
};
return
hclkdivs
[
LPC32XX_CLKPWR_HCLKDIV_DIV_2POW
(
__raw_readl
(
LPC32XX_CLKPWR_HCLK_DIV
))];
}
static
struct
clk
clk_hclk
=
{
.
parent
=
&
clk_armpll
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_pclk
=
{
.
parent
=
&
clk_armpll
,
.
get_rate
=
local_return_parent_rate
,
};
static
int
local_onoff_enable
(
struct
clk
*
clk
,
int
enable
)
{
u32
tmp
;
tmp
=
__raw_readl
(
clk
->
enable_reg
);
if
(
enable
==
0
)
tmp
&=
~
clk
->
enable_mask
;
else
tmp
|=
clk
->
enable_mask
;
__raw_writel
(
tmp
,
clk
->
enable_reg
);
return
0
;
}
/* Peripheral clock sources */
static
struct
clk
clk_timer0
=
{
.
parent
=
&
clk_pclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1
,
.
enable_mask
=
LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_timer1
=
{
.
parent
=
&
clk_pclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1
,
.
enable_mask
=
LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_timer2
=
{
.
parent
=
&
clk_pclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1
,
.
enable_mask
=
LPC32XX_CLKPWR_TMRPWMCLK_TIMER2_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_timer3
=
{
.
parent
=
&
clk_pclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1
,
.
enable_mask
=
LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_wdt
=
{
.
parent
=
&
clk_pclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_TIMER_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_PWMCLK_WDOG_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_vfp9
=
{
.
parent
=
&
clk_pclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_DEBUG_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_VFP_CLOCK_ENABLE_BIT
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_dma
=
{
.
parent
=
&
clk_hclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_DMA_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_uart3
=
{
.
parent
=
&
clk_pclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_UART_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_UARTCLKCTRL_UART3_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_uart4
=
{
.
parent
=
&
clk_pclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_UART_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_UARTCLKCTRL_UART4_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_uart5
=
{
.
parent
=
&
clk_pclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_UART_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_UARTCLKCTRL_UART5_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_uart6
=
{
.
parent
=
&
clk_pclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_UART_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_UARTCLKCTRL_UART6_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_i2c0
=
{
.
parent
=
&
clk_hclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_I2C_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_I2CCLK_I2C1CLK_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_i2c1
=
{
.
parent
=
&
clk_hclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_I2C_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_I2CCLK_I2C2CLK_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_i2c2
=
{
.
parent
=
&
clk_pclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
io_p2v
(
LPC32XX_USB_BASE
+
0xFF4
),
.
enable_mask
=
0x4
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_ssp0
=
{
.
parent
=
&
clk_hclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_SSP_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_ssp1
=
{
.
parent
=
&
clk_hclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_SSP_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_SSPCTRL_SSPCLK1_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_kscan
=
{
.
parent
=
&
osc_32KHz
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_KEY_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_KEYCLKCTRL_CLK_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_nand
=
{
.
parent
=
&
clk_hclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_NAND_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_i2s0
=
{
.
parent
=
&
clk_hclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_I2S_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_I2SCTRL_I2SCLK0_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_i2s1
=
{
.
parent
=
&
clk_hclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_I2S_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_net
=
{
.
parent
=
&
clk_hclk
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_MACCLK_CTRL
,
.
enable_mask
=
(
LPC32XX_CLKPWR_MACCTRL_DMACLK_EN
|
LPC32XX_CLKPWR_MACCTRL_MMIOCLK_EN
|
LPC32XX_CLKPWR_MACCTRL_HRCCLK_EN
),
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_rtc
=
{
.
parent
=
&
osc_32KHz
,
.
rate
=
1
,
/* 1 Hz */
.
get_rate
=
local_return_parent_rate
,
};
static
struct
clk
clk_usbd
=
{
.
parent
=
&
clk_usbpll
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_USB_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_USBCTRL_HCLK_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
int
tsc_onoff_enable
(
struct
clk
*
clk
,
int
enable
)
{
u32
tmp
;
/* Make sure 32KHz clock is the selected clock */
tmp
=
__raw_readl
(
LPC32XX_CLKPWR_ADC_CLK_CTRL_1
);
tmp
&=
~
LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL
;
__raw_writel
(
tmp
,
LPC32XX_CLKPWR_ADC_CLK_CTRL_1
);
if
(
enable
==
0
)
__raw_writel
(
0
,
clk
->
enable_reg
);
else
__raw_writel
(
clk
->
enable_mask
,
clk
->
enable_reg
);
return
0
;
}
static
struct
clk
clk_tsc
=
{
.
parent
=
&
osc_32KHz
,
.
enable
=
tsc_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_ADC_CLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN
,
.
get_rate
=
local_return_parent_rate
,
};
static
int
mmc_onoff_enable
(
struct
clk
*
clk
,
int
enable
)
{
u32
tmp
;
tmp
=
__raw_readl
(
LPC32XX_CLKPWR_MS_CTRL
)
&
~
LPC32XX_CLKPWR_MSCARD_SDCARD_EN
;
/* If rate is 0, disable clock */
if
(
enable
!=
0
)
tmp
|=
LPC32XX_CLKPWR_MSCARD_SDCARD_EN
;
__raw_writel
(
tmp
,
LPC32XX_CLKPWR_MS_CTRL
);
return
0
;
}
static
unsigned
long
mmc_get_rate
(
struct
clk
*
clk
)
{
u32
div
,
rate
,
oldclk
;
/* The MMC clock must be on when accessing an MMC register */
oldclk
=
__raw_readl
(
LPC32XX_CLKPWR_MS_CTRL
);
__raw_writel
(
oldclk
|
LPC32XX_CLKPWR_MSCARD_SDCARD_EN
,
LPC32XX_CLKPWR_MS_CTRL
);
div
=
__raw_readl
(
LPC32XX_CLKPWR_MS_CTRL
);
__raw_writel
(
oldclk
,
LPC32XX_CLKPWR_MS_CTRL
);
/* Get the parent clock rate */
rate
=
clk
->
parent
->
get_rate
(
clk
->
parent
);
/* Get the MMC controller clock divider value */
div
=
div
&
LPC32XX_CLKPWR_MSCARD_SDCARD_DIV
(
0xf
);
if
(
!
div
)
div
=
1
;
return
rate
/
div
;
}
static
unsigned
long
mmc_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
long
div
,
prate
;
/* Get the parent clock rate */
prate
=
clk
->
parent
->
get_rate
(
clk
->
parent
);
if
(
rate
>=
prate
)
return
prate
;
div
=
prate
/
rate
;
if
(
div
>
0xf
)
div
=
0xf
;
return
prate
/
div
;
}
static
int
mmc_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
u32
oldclk
,
tmp
;
unsigned
long
prate
,
div
,
crate
=
mmc_round_rate
(
clk
,
rate
);
prate
=
clk
->
parent
->
get_rate
(
clk
->
parent
);
div
=
prate
/
crate
;
/* The MMC clock must be on when accessing an MMC register */
oldclk
=
__raw_readl
(
LPC32XX_CLKPWR_MS_CTRL
);
__raw_writel
(
oldclk
|
LPC32XX_CLKPWR_MSCARD_SDCARD_EN
,
LPC32XX_CLKPWR_MS_CTRL
);
tmp
=
__raw_readl
(
LPC32XX_CLKPWR_MS_CTRL
)
&
~
LPC32XX_CLKPWR_MSCARD_SDCARD_DIV
(
0xf
);
tmp
|=
LPC32XX_CLKPWR_MSCARD_SDCARD_DIV
(
div
);
__raw_writel
(
tmp
,
LPC32XX_CLKPWR_MS_CTRL
);
__raw_writel
(
oldclk
,
LPC32XX_CLKPWR_MS_CTRL
);
return
0
;
}
static
struct
clk
clk_mmc
=
{
.
parent
=
&
clk_armpll
,
.
set_rate
=
mmc_set_rate
,
.
get_rate
=
mmc_get_rate
,
.
round_rate
=
mmc_round_rate
,
.
enable
=
mmc_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_MS_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_MSCARD_SDCARD_EN
,
};
static
unsigned
long
clcd_get_rate
(
struct
clk
*
clk
)
{
u32
tmp
,
div
,
rate
,
oldclk
;
/* The LCD clock must be on when accessing an LCD register */
oldclk
=
__raw_readl
(
LPC32XX_CLKPWR_LCDCLK_CTRL
);
__raw_writel
(
oldclk
|
LPC32XX_CLKPWR_LCDCTRL_CLK_EN
,
LPC32XX_CLKPWR_LCDCLK_CTRL
);
tmp
=
__raw_readl
(
io_p2v
(
LPC32XX_LCD_BASE
+
CLCD_TIM2
));
__raw_writel
(
oldclk
,
LPC32XX_CLKPWR_LCDCLK_CTRL
);
rate
=
clk
->
parent
->
get_rate
(
clk
->
parent
);
/* Only supports internal clocking */
if
(
tmp
&
TIM2_BCD
)
return
rate
;
div
=
(
tmp
&
0x1F
)
|
((
tmp
&
0xF8
)
>>
22
);
tmp
=
rate
/
(
2
+
div
);
return
tmp
;
}
static
int
clcd_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
u32
tmp
,
prate
,
div
,
oldclk
;
/* The LCD clock must be on when accessing an LCD register */
oldclk
=
__raw_readl
(
LPC32XX_CLKPWR_LCDCLK_CTRL
);
__raw_writel
(
oldclk
|
LPC32XX_CLKPWR_LCDCTRL_CLK_EN
,
LPC32XX_CLKPWR_LCDCLK_CTRL
);
tmp
=
__raw_readl
(
io_p2v
(
LPC32XX_LCD_BASE
+
CLCD_TIM2
))
|
TIM2_BCD
;
prate
=
clk
->
parent
->
get_rate
(
clk
->
parent
);
if
(
rate
<
prate
)
{
/* Find closest divider */
div
=
prate
/
rate
;
if
(
div
>=
2
)
{
div
-=
2
;
tmp
&=
~
TIM2_BCD
;
}
tmp
&=
~
(
0xF800001F
);
tmp
|=
(
div
&
0x1F
);
tmp
|=
(((
div
>>
5
)
&
0x1F
)
<<
27
);
}
__raw_writel
(
tmp
,
io_p2v
(
LPC32XX_LCD_BASE
+
CLCD_TIM2
));
__raw_writel
(
oldclk
,
LPC32XX_CLKPWR_LCDCLK_CTRL
);
return
0
;
}
static
unsigned
long
clcd_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
u32
prate
,
div
;
prate
=
clk
->
parent
->
get_rate
(
clk
->
parent
);
if
(
rate
>=
prate
)
rate
=
prate
;
else
{
div
=
prate
/
rate
;
if
(
div
>
0x3ff
)
div
=
0x3ff
;
rate
=
prate
/
div
;
}
return
rate
;
}
static
struct
clk
clk_lcd
=
{
.
parent
=
&
clk_hclk
,
.
set_rate
=
clcd_set_rate
,
.
get_rate
=
clcd_get_rate
,
.
round_rate
=
clcd_round_rate
,
.
enable
=
local_onoff_enable
,
.
enable_reg
=
LPC32XX_CLKPWR_LCDCLK_CTRL
,
.
enable_mask
=
LPC32XX_CLKPWR_LCDCTRL_CLK_EN
,
};
static
inline
void
clk_lock
(
void
)
{
mutex_lock
(
&
clkm_lock
);
}
static
inline
void
clk_unlock
(
void
)
{
mutex_unlock
(
&
clkm_lock
);
}
static
void
local_clk_disable
(
struct
clk
*
clk
)
{
WARN_ON
(
clk
->
usecount
==
0
);
/* Don't attempt to disable clock if it has no users */
if
(
clk
->
usecount
>
0
)
{
clk
->
usecount
--
;
/* Only disable clock when it has no more users */
if
((
clk
->
usecount
==
0
)
&&
(
clk
->
enable
))
clk
->
enable
(
clk
,
0
);
/* Check parent clocks, they may need to be disabled too */
if
(
clk
->
parent
)
local_clk_disable
(
clk
->
parent
);
}
}
static
int
local_clk_enable
(
struct
clk
*
clk
)
{
int
ret
=
0
;
/* Enable parent clocks first and update use counts */
if
(
clk
->
parent
)
ret
=
local_clk_enable
(
clk
->
parent
);
if
(
!
ret
)
{
/* Only enable clock if it's currently disabled */
if
((
clk
->
usecount
==
0
)
&&
(
clk
->
enable
))
ret
=
clk
->
enable
(
clk
,
1
);
if
(
!
ret
)
clk
->
usecount
++
;
else
if
(
clk
->
parent
)
local_clk_disable
(
clk
->
parent
);
}
return
ret
;
}
/*
* clk_enable - inform the system when the clock source should be running.
*/
int
clk_enable
(
struct
clk
*
clk
)
{
int
ret
;
clk_lock
();
ret
=
local_clk_enable
(
clk
);
clk_unlock
();
return
ret
;
}
EXPORT_SYMBOL
(
clk_enable
);
/*
* clk_disable - inform the system when the clock source is no longer required
*/
void
clk_disable
(
struct
clk
*
clk
)
{
clk_lock
();
local_clk_disable
(
clk
);
clk_unlock
();
}
EXPORT_SYMBOL
(
clk_disable
);
/*
* clk_get_rate - obtain the current clock rate (in Hz) for a clock source
*/
unsigned
long
clk_get_rate
(
struct
clk
*
clk
)
{
unsigned
long
rate
;
clk_lock
();
rate
=
clk
->
get_rate
(
clk
);
clk_unlock
();
return
rate
;
}
EXPORT_SYMBOL
(
clk_get_rate
);
/*
* clk_set_rate - set the clock rate for a clock source
*/
int
clk_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
int
ret
=
-
EINVAL
;
/*
* Most system clocks can only be enabled or disabled, with
* the actual rate set as part of the peripheral dividers
* instead of high level clock control
*/
if
(
clk
->
set_rate
)
{
clk_lock
();
ret
=
clk
->
set_rate
(
clk
,
rate
);
clk_unlock
();
}
return
ret
;
}
EXPORT_SYMBOL
(
clk_set_rate
);
/*
* clk_round_rate - adjust a rate to the exact rate a clock can provide
*/
long
clk_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
clk_lock
();
if
(
clk
->
round_rate
)
rate
=
clk
->
round_rate
(
clk
,
rate
);
else
rate
=
clk
->
get_rate
(
clk
);
clk_unlock
();
return
rate
;
}
EXPORT_SYMBOL
(
clk_round_rate
);
/*
* clk_set_parent - set the parent clock source for this clock
*/
int
clk_set_parent
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
/* Clock re-parenting is not supported */
return
-
EINVAL
;
}
EXPORT_SYMBOL
(
clk_set_parent
);
/*
* clk_get_parent - get the parent clock source for this clock
*/
struct
clk
*
clk_get_parent
(
struct
clk
*
clk
)
{
return
clk
->
parent
;
}
EXPORT_SYMBOL
(
clk_get_parent
);
#define _REGISTER_CLOCK(d, n, c) \
{ \
.dev_id = (d), \
.con_id = (n), \
.clk = &(c), \
},
static
struct
clk_lookup
lookups
[]
=
{
_REGISTER_CLOCK
(
NULL
,
"osc_32KHz"
,
osc_32KHz
)
_REGISTER_CLOCK
(
NULL
,
"osc_pll397"
,
osc_pll397
)
_REGISTER_CLOCK
(
NULL
,
"osc_main"
,
osc_main
)
_REGISTER_CLOCK
(
NULL
,
"sys_ck"
,
clk_sys
)
_REGISTER_CLOCK
(
NULL
,
"arm_pll_ck"
,
clk_armpll
)
_REGISTER_CLOCK
(
NULL
,
"ck_pll5"
,
clk_usbpll
)
_REGISTER_CLOCK
(
NULL
,
"hclk_ck"
,
clk_hclk
)
_REGISTER_CLOCK
(
NULL
,
"pclk_ck"
,
clk_pclk
)
_REGISTER_CLOCK
(
NULL
,
"timer0_ck"
,
clk_timer0
)
_REGISTER_CLOCK
(
NULL
,
"timer1_ck"
,
clk_timer1
)
_REGISTER_CLOCK
(
NULL
,
"timer2_ck"
,
clk_timer2
)
_REGISTER_CLOCK
(
NULL
,
"timer3_ck"
,
clk_timer3
)
_REGISTER_CLOCK
(
NULL
,
"vfp9_ck"
,
clk_vfp9
)
_REGISTER_CLOCK
(
NULL
,
"clk_dmac"
,
clk_dma
)
_REGISTER_CLOCK
(
"pnx4008-watchdog"
,
NULL
,
clk_wdt
)
_REGISTER_CLOCK
(
NULL
,
"uart3_ck"
,
clk_uart3
)
_REGISTER_CLOCK
(
NULL
,
"uart4_ck"
,
clk_uart4
)
_REGISTER_CLOCK
(
NULL
,
"uart5_ck"
,
clk_uart5
)
_REGISTER_CLOCK
(
NULL
,
"uart6_ck"
,
clk_uart6
)
_REGISTER_CLOCK
(
"pnx-i2c.0"
,
NULL
,
clk_i2c0
)
_REGISTER_CLOCK
(
"pnx-i2c.1"
,
NULL
,
clk_i2c1
)
_REGISTER_CLOCK
(
"pnx-i2c.2"
,
NULL
,
clk_i2c2
)
_REGISTER_CLOCK
(
"dev:ssp0"
,
NULL
,
clk_ssp0
)
_REGISTER_CLOCK
(
"dev:ssp1"
,
NULL
,
clk_ssp1
)
_REGISTER_CLOCK
(
"lpc32xx_keys.0"
,
NULL
,
clk_kscan
)
_REGISTER_CLOCK
(
"lpc32xx-nand.0"
,
"nand_ck"
,
clk_nand
)
_REGISTER_CLOCK
(
"tbd"
,
"i2s0_ck"
,
clk_i2s0
)
_REGISTER_CLOCK
(
"tbd"
,
"i2s1_ck"
,
clk_i2s1
)
_REGISTER_CLOCK
(
"lpc32xx-ts"
,
NULL
,
clk_tsc
)
_REGISTER_CLOCK
(
"dev:mmc0"
,
"MCLK"
,
clk_mmc
)
_REGISTER_CLOCK
(
"lpc-net.0"
,
NULL
,
clk_net
)
_REGISTER_CLOCK
(
"dev:clcd"
,
NULL
,
clk_lcd
)
_REGISTER_CLOCK
(
"lpc32xx_udc"
,
"ck_usbd"
,
clk_usbd
)
_REGISTER_CLOCK
(
"lpc32xx_rtc"
,
NULL
,
clk_rtc
)
};
static
int
__init
clk_init
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
lookups
);
i
++
)
clkdev_add
(
&
lookups
[
i
]);
/*
* Setup muxed SYSCLK for HCLK PLL base -this selects the
* parent clock used for the ARM PLL and is used to derive
* the many system clock rates in the device.
*/
if
(
clk_is_sysclk_mainosc
()
!=
0
)
clk_sys
.
parent
=
&
osc_main
;
else
clk_sys
.
parent
=
&
osc_pll397
;
clk_sys
.
rate
=
clk_sys
.
parent
->
rate
;
/* Compute the current ARM PLL and USB PLL frequencies */
local_update_armpll_rate
();
/* Compute HCLK and PCLK bus rates */
clk_hclk
.
rate
=
clk_hclk
.
parent
->
rate
/
clk_get_hclk_div
();
clk_pclk
.
rate
=
clk_pclk
.
parent
->
rate
/
clk_get_pclk_div
();
/*
* Enable system clocks - this step is somewhat formal, as the
* clocks are already running, but it does get the clock data
* inline with the actual system state. Never disable these
* clocks as they will only stop if the system is going to sleep.
* In that case, the chip/system power management functions will
* handle clock gating.
*/
if
(
clk_enable
(
&
clk_hclk
)
||
clk_enable
(
&
clk_pclk
))
printk
(
KERN_ERR
"Error enabling system HCLK and PCLK
\n
"
);
/*
* Timers 0 and 1 were enabled and are being used by the high
* resolution tick function prior to this driver being initialized.
* Tag them now as used.
*/
if
(
clk_enable
(
&
clk_timer0
)
||
clk_enable
(
&
clk_timer1
))
printk
(
KERN_ERR
"Error enabling timer tick clocks
\n
"
);
return
0
;
}
core_initcall
(
clk_init
);
arch/arm/mach-lpc32xx/clock.h
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/clock.h
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __LPC32XX_CLOCK_H
#define __LPC32XX_CLOCK_H
struct
clk
{
struct
list_head
node
;
struct
clk
*
parent
;
u32
rate
;
u32
usecount
;
int
(
*
set_rate
)
(
struct
clk
*
,
unsigned
long
);
unsigned
long
(
*
round_rate
)
(
struct
clk
*
,
unsigned
long
);
unsigned
long
(
*
get_rate
)
(
struct
clk
*
clk
);
int
(
*
enable
)
(
struct
clk
*
,
int
);
/* Register address and bit mask for simple clocks */
void
__iomem
*
enable_reg
;
u32
enable_mask
;
};
#endif
arch/arm/mach-lpc32xx/common.c
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/common.c
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/i2c-pnx.h>
#include <linux/io.h>
#include <asm/mach/map.h>
#include <mach/i2c.h>
#include <mach/hardware.h>
#include <mach/platform.h>
#include "common.h"
/*
* Watchdog timer
*/
static
struct
resource
watchdog_resources
[]
=
{
[
0
]
=
{
.
start
=
LPC32XX_WDTIM_BASE
,
.
end
=
LPC32XX_WDTIM_BASE
+
SZ_4K
-
1
,
.
flags
=
IORESOURCE_MEM
,
},
};
struct
platform_device
lpc32xx_watchdog_device
=
{
.
name
=
"pnx4008-watchdog"
,
.
id
=
-
1
,
.
num_resources
=
ARRAY_SIZE
(
watchdog_resources
),
.
resource
=
watchdog_resources
,
};
/*
* I2C busses
*/
static
struct
i2c_pnx_data
i2c0_data
=
{
.
name
=
I2C_CHIP_NAME
"1"
,
.
base
=
LPC32XX_I2C1_BASE
,
.
irq
=
IRQ_LPC32XX_I2C_1
,
};
static
struct
i2c_pnx_data
i2c1_data
=
{
.
name
=
I2C_CHIP_NAME
"2"
,
.
base
=
LPC32XX_I2C2_BASE
,
.
irq
=
IRQ_LPC32XX_I2C_2
,
};
static
struct
i2c_pnx_data
i2c2_data
=
{
.
name
=
"USB-I2C"
,
.
base
=
LPC32XX_OTG_I2C_BASE
,
.
irq
=
IRQ_LPC32XX_USB_I2C
,
};
struct
platform_device
lpc32xx_i2c0_device
=
{
.
name
=
"pnx-i2c"
,
.
id
=
0
,
.
dev
=
{
.
platform_data
=
&
i2c0_data
,
},
};
struct
platform_device
lpc32xx_i2c1_device
=
{
.
name
=
"pnx-i2c"
,
.
id
=
1
,
.
dev
=
{
.
platform_data
=
&
i2c1_data
,
},
};
struct
platform_device
lpc32xx_i2c2_device
=
{
.
name
=
"pnx-i2c"
,
.
id
=
2
,
.
dev
=
{
.
platform_data
=
&
i2c2_data
,
},
};
/*
* Returns the unique ID for the device
*/
void
lpc32xx_get_uid
(
u32
devid
[
4
])
{
int
i
;
for
(
i
=
0
;
i
<
4
;
i
++
)
devid
[
i
]
=
__raw_readl
(
LPC32XX_CLKPWR_DEVID
(
i
<<
2
));
}
/*
* Returns SYSCLK source
* 0 = PLL397, 1 = main oscillator
*/
int
clk_is_sysclk_mainosc
(
void
)
{
if
((
__raw_readl
(
LPC32XX_CLKPWR_SYSCLK_CTRL
)
&
LPC32XX_CLKPWR_SYSCTRL_SYSCLKMUX
)
==
0
)
return
1
;
return
0
;
}
/*
* System reset via the watchdog timer
*/
void
lpc32xx_watchdog_reset
(
void
)
{
/* Make sure WDT clocks are enabled */
__raw_writel
(
LPC32XX_CLKPWR_PWMCLK_WDOG_EN
,
LPC32XX_CLKPWR_TIMER_CLK_CTRL
);
/* Instant assert of RESETOUT_N with pulse length 1mS */
__raw_writel
(
13000
,
io_p2v
(
LPC32XX_WDTIM_BASE
+
0x18
));
__raw_writel
(
0x70
,
io_p2v
(
LPC32XX_WDTIM_BASE
+
0xC
));
}
/*
* Detects and returns IRAM size for the device variation
*/
#define LPC32XX_IRAM_BANK_SIZE SZ_128K
static
u32
iram_size
;
u32
lpc32xx_return_iram_size
(
void
)
{
if
(
iram_size
==
0
)
{
u32
savedval1
,
savedval2
;
void
__iomem
*
iramptr1
,
*
iramptr2
;
iramptr1
=
io_p2v
(
LPC32XX_IRAM_BASE
);
iramptr2
=
io_p2v
(
LPC32XX_IRAM_BASE
+
LPC32XX_IRAM_BANK_SIZE
);
savedval1
=
__raw_readl
(
iramptr1
);
savedval2
=
__raw_readl
(
iramptr2
);
if
(
savedval1
==
savedval2
)
{
__raw_writel
(
savedval2
+
1
,
iramptr2
);
if
(
__raw_readl
(
iramptr1
)
==
savedval2
+
1
)
iram_size
=
LPC32XX_IRAM_BANK_SIZE
;
else
iram_size
=
LPC32XX_IRAM_BANK_SIZE
*
2
;
__raw_writel
(
savedval2
,
iramptr2
);
}
else
iram_size
=
LPC32XX_IRAM_BANK_SIZE
*
2
;
}
return
iram_size
;
}
/*
* Computes PLL rate from PLL register and input clock
*/
u32
clk_check_pll_setup
(
u32
ifreq
,
struct
clk_pll_setup
*
pllsetup
)
{
u32
ilfreq
,
p
,
m
,
n
,
fcco
,
fref
,
cfreq
;
int
mode
;
/*
* PLL requirements
* ifreq must be >= 1MHz and <= 20MHz
* FCCO must be >= 156MHz and <= 320MHz
* FREF must be >= 1MHz and <= 27MHz
* Assume the passed input data is not valid
*/
ilfreq
=
ifreq
;
m
=
pllsetup
->
pll_m
;
n
=
pllsetup
->
pll_n
;
p
=
pllsetup
->
pll_p
;
mode
=
(
pllsetup
->
cco_bypass_b15
<<
2
)
|
(
pllsetup
->
direct_output_b14
<<
1
)
|
pllsetup
->
fdbk_div_ctrl_b13
;
switch
(
mode
)
{
case
0x0
:
/* Non-integer mode */
cfreq
=
(
m
*
ilfreq
)
/
(
2
*
p
*
n
);
fcco
=
(
m
*
ilfreq
)
/
n
;
fref
=
ilfreq
/
n
;
break
;
case
0x1
:
/* integer mode */
cfreq
=
(
m
*
ilfreq
)
/
n
;
fcco
=
(
m
*
ilfreq
)
/
(
n
*
2
*
p
);
fref
=
ilfreq
/
n
;
break
;
case
0x2
:
case
0x3
:
/* Direct mode */
cfreq
=
(
m
*
ilfreq
)
/
n
;
fcco
=
cfreq
;
fref
=
ilfreq
/
n
;
break
;
case
0x4
:
case
0x5
:
/* Bypass mode */
cfreq
=
ilfreq
/
(
2
*
p
);
fcco
=
156000000
;
fref
=
1000000
;
break
;
case
0x6
:
case
0x7
:
/* Direct bypass mode */
default:
cfreq
=
ilfreq
;
fcco
=
156000000
;
fref
=
1000000
;
break
;
}
if
(
fcco
<
156000000
||
fcco
>
320000000
)
cfreq
=
0
;
if
(
fref
<
1000000
||
fref
>
27000000
)
cfreq
=
0
;
return
(
u32
)
cfreq
;
}
u32
clk_get_pclk_div
(
void
)
{
return
1
+
((
__raw_readl
(
LPC32XX_CLKPWR_HCLK_DIV
)
>>
2
)
&
0x1F
);
}
static
struct
map_desc
lpc32xx_io_desc
[]
__initdata
=
{
{
.
virtual
=
IO_ADDRESS
(
LPC32XX_AHB0_START
),
.
pfn
=
__phys_to_pfn
(
LPC32XX_AHB0_START
),
.
length
=
LPC32XX_AHB0_SIZE
,
.
type
=
MT_DEVICE
},
{
.
virtual
=
IO_ADDRESS
(
LPC32XX_AHB1_START
),
.
pfn
=
__phys_to_pfn
(
LPC32XX_AHB1_START
),
.
length
=
LPC32XX_AHB1_SIZE
,
.
type
=
MT_DEVICE
},
{
.
virtual
=
IO_ADDRESS
(
LPC32XX_FABAPB_START
),
.
pfn
=
__phys_to_pfn
(
LPC32XX_FABAPB_START
),
.
length
=
LPC32XX_FABAPB_SIZE
,
.
type
=
MT_DEVICE
},
{
.
virtual
=
IO_ADDRESS
(
LPC32XX_IRAM_BASE
),
.
pfn
=
__phys_to_pfn
(
LPC32XX_IRAM_BASE
),
.
length
=
(
LPC32XX_IRAM_BANK_SIZE
*
2
),
.
type
=
MT_DEVICE
},
};
void
__init
lpc32xx_map_io
(
void
)
{
iotable_init
(
lpc32xx_io_desc
,
ARRAY_SIZE
(
lpc32xx_io_desc
));
}
arch/arm/mach-lpc32xx/common.h
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/common.h
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2009-2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __LPC32XX_COMMON_H
#define __LPC32XX_COMMON_H
#include <linux/platform_device.h>
/*
* Arch specific platform device structures
*/
extern
struct
platform_device
lpc32xx_watchdog_device
;
extern
struct
platform_device
lpc32xx_i2c0_device
;
extern
struct
platform_device
lpc32xx_i2c1_device
;
extern
struct
platform_device
lpc32xx_i2c2_device
;
/*
* Other arch specific structures and functions
*/
extern
struct
sys_timer
lpc32xx_timer
;
extern
void
__init
lpc32xx_init_irq
(
void
);
extern
void
__init
lpc32xx_map_io
(
void
);
extern
void
__init
lpc32xx_serial_init
(
void
);
extern
void
__init
lpc32xx_gpio_init
(
void
);
/*
* Structure used for setting up and querying the PLLS
*/
struct
clk_pll_setup
{
int
analog_on
;
int
cco_bypass_b15
;
int
direct_output_b14
;
int
fdbk_div_ctrl_b13
;
int
pll_p
;
int
pll_n
;
u32
pll_m
;
};
extern
int
clk_is_sysclk_mainosc
(
void
);
extern
u32
clk_check_pll_setup
(
u32
ifreq
,
struct
clk_pll_setup
*
pllsetup
);
extern
u32
clk_get_pllrate_from_reg
(
u32
inputclk
,
u32
regval
);
extern
u32
clk_get_pclk_div
(
void
);
/*
* Returns the LPC32xx unique 128-bit chip ID
*/
extern
void
lpc32xx_get_uid
(
u32
devid
[
4
]);
extern
void
lpc32xx_watchdog_reset
(
void
);
extern
u32
lpc32xx_return_iram_size
(
void
);
/*
* Pointers used for sizing and copying suspend function data
*/
extern
int
lpc32xx_sys_suspend
(
void
);
extern
int
lpc32xx_sys_suspend_sz
;
#endif
arch/arm/mach-lpc32xx/gpiolib.c
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/gpiolib.c
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <mach/hardware.h>
#include <mach/platform.h>
#include "common.h"
#define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000)
#define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004)
#define LPC32XX_GPIO_P3_OUTP_CLR _GPREG(0x008)
#define LPC32XX_GPIO_P3_OUTP_STATE _GPREG(0x00C)
#define LPC32XX_GPIO_P2_DIR_SET _GPREG(0x010)
#define LPC32XX_GPIO_P2_DIR_CLR _GPREG(0x014)
#define LPC32XX_GPIO_P2_DIR_STATE _GPREG(0x018)
#define LPC32XX_GPIO_P2_INP_STATE _GPREG(0x01C)
#define LPC32XX_GPIO_P2_OUTP_SET _GPREG(0x020)
#define LPC32XX_GPIO_P2_OUTP_CLR _GPREG(0x024)
#define LPC32XX_GPIO_P2_MUX_SET _GPREG(0x028)
#define LPC32XX_GPIO_P2_MUX_CLR _GPREG(0x02C)
#define LPC32XX_GPIO_P2_MUX_STATE _GPREG(0x030)
#define LPC32XX_GPIO_P0_INP_STATE _GPREG(0x040)
#define LPC32XX_GPIO_P0_OUTP_SET _GPREG(0x044)
#define LPC32XX_GPIO_P0_OUTP_CLR _GPREG(0x048)
#define LPC32XX_GPIO_P0_OUTP_STATE _GPREG(0x04C)
#define LPC32XX_GPIO_P0_DIR_SET _GPREG(0x050)
#define LPC32XX_GPIO_P0_DIR_CLR _GPREG(0x054)
#define LPC32XX_GPIO_P0_DIR_STATE _GPREG(0x058)
#define LPC32XX_GPIO_P1_INP_STATE _GPREG(0x060)
#define LPC32XX_GPIO_P1_OUTP_SET _GPREG(0x064)
#define LPC32XX_GPIO_P1_OUTP_CLR _GPREG(0x068)
#define LPC32XX_GPIO_P1_OUTP_STATE _GPREG(0x06C)
#define LPC32XX_GPIO_P1_DIR_SET _GPREG(0x070)
#define LPC32XX_GPIO_P1_DIR_CLR _GPREG(0x074)
#define LPC32XX_GPIO_P1_DIR_STATE _GPREG(0x078)
#define GPIO012_PIN_TO_BIT(x) (1 << (x))
#define GPIO3_PIN_TO_BIT(x) (1 << ((x) + 25))
#define GPO3_PIN_TO_BIT(x) (1 << (x))
#define GPIO012_PIN_IN_SEL(x, y) (((x) >> (y)) & 1)
#define GPIO3_PIN_IN_SHIFT(x) ((x) == 5 ? 24 : 10 + (x))
#define GPIO3_PIN_IN_SEL(x, y) ((x) >> GPIO3_PIN_IN_SHIFT(y))
#define GPIO3_PIN5_IN_SEL(x) (((x) >> 24) & 1)
#define GPI3_PIN_IN_SEL(x, y) (((x) >> (y)) & 1)
struct
gpio_regs
{
void
__iomem
*
inp_state
;
void
__iomem
*
outp_set
;
void
__iomem
*
outp_clr
;
void
__iomem
*
dir_set
;
void
__iomem
*
dir_clr
;
};
/*
* GPIO names
*/
static
const
char
*
gpio_p0_names
[
LPC32XX_GPIO_P0_MAX
]
=
{
"p0.0"
,
"p0.1"
,
"p0.2"
,
"p0.3"
,
"p0.4"
,
"p0.5"
,
"p0.6"
,
"p0.7"
};
static
const
char
*
gpio_p1_names
[
LPC32XX_GPIO_P1_MAX
]
=
{
"p1.0"
,
"p1.1"
,
"p1.2"
,
"p1.3"
,
"p1.4"
,
"p1.5"
,
"p1.6"
,
"p1.7"
,
"p1.8"
,
"p1.9"
,
"p1.10"
,
"p1.11"
,
"p1.12"
,
"p1.13"
,
"p1.14"
,
"p1.15"
,
"p1.16"
,
"p1.17"
,
"p1.18"
,
"p1.19"
,
"p1.20"
,
"p1.21"
,
"p1.22"
,
"p1.23"
,
};
static
const
char
*
gpio_p2_names
[
LPC32XX_GPIO_P2_MAX
]
=
{
"p2.0"
,
"p2.1"
,
"p2.2"
,
"p2.3"
,
"p2.4"
,
"p2.5"
,
"p2.6"
,
"p2.7"
,
"p2.8"
,
"p2.9"
,
"p2.10"
,
"p2.11"
,
"p2.12"
};
static
const
char
*
gpio_p3_names
[
LPC32XX_GPIO_P3_MAX
]
=
{
"gpi000"
,
"gpio01"
,
"gpio02"
,
"gpio03"
,
"gpio04"
,
"gpio05"
};
static
const
char
*
gpi_p3_names
[
LPC32XX_GPI_P3_MAX
]
=
{
"gpi00"
,
"gpi01"
,
"gpi02"
,
"gpi03"
,
"gpi04"
,
"gpi05"
,
"gpi06"
,
"gpi07"
,
"gpi08"
,
"gpi09"
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
"gpi15"
,
"gpi16"
,
"gpi17"
,
"gpi18"
,
"gpi19"
,
"gpi20"
,
"gpi21"
,
"gpi22"
,
"gpi23"
,
"gpi24"
,
"gpi25"
,
"gpi26"
,
"gpi27"
};
static
const
char
*
gpo_p3_names
[
LPC32XX_GPO_P3_MAX
]
=
{
"gpo00"
,
"gpo01"
,
"gpo02"
,
"gpo03"
,
"gpo04"
,
"gpo05"
,
"gpo06"
,
"gpo07"
,
"gpo08"
,
"gpo09"
,
"gpo10"
,
"gpo11"
,
"gpo12"
,
"gpo13"
,
"gpo14"
,
"gpo15"
,
"gpo16"
,
"gpo17"
,
"gpo18"
,
"gpo19"
,
"gpo20"
,
"gpo21"
,
"gpo22"
,
"gpo23"
};
static
struct
gpio_regs
gpio_grp_regs_p0
=
{
.
inp_state
=
LPC32XX_GPIO_P0_INP_STATE
,
.
outp_set
=
LPC32XX_GPIO_P0_OUTP_SET
,
.
outp_clr
=
LPC32XX_GPIO_P0_OUTP_CLR
,
.
dir_set
=
LPC32XX_GPIO_P0_DIR_SET
,
.
dir_clr
=
LPC32XX_GPIO_P0_DIR_CLR
,
};
static
struct
gpio_regs
gpio_grp_regs_p1
=
{
.
inp_state
=
LPC32XX_GPIO_P1_INP_STATE
,
.
outp_set
=
LPC32XX_GPIO_P1_OUTP_SET
,
.
outp_clr
=
LPC32XX_GPIO_P1_OUTP_CLR
,
.
dir_set
=
LPC32XX_GPIO_P1_DIR_SET
,
.
dir_clr
=
LPC32XX_GPIO_P1_DIR_CLR
,
};
static
struct
gpio_regs
gpio_grp_regs_p2
=
{
.
inp_state
=
LPC32XX_GPIO_P2_INP_STATE
,
.
outp_set
=
LPC32XX_GPIO_P2_OUTP_SET
,
.
outp_clr
=
LPC32XX_GPIO_P2_OUTP_CLR
,
.
dir_set
=
LPC32XX_GPIO_P2_DIR_SET
,
.
dir_clr
=
LPC32XX_GPIO_P2_DIR_CLR
,
};
static
struct
gpio_regs
gpio_grp_regs_p3
=
{
.
inp_state
=
LPC32XX_GPIO_P3_INP_STATE
,
.
outp_set
=
LPC32XX_GPIO_P3_OUTP_SET
,
.
outp_clr
=
LPC32XX_GPIO_P3_OUTP_CLR
,
.
dir_set
=
LPC32XX_GPIO_P2_DIR_SET
,
.
dir_clr
=
LPC32XX_GPIO_P2_DIR_CLR
,
};
struct
lpc32xx_gpio_chip
{
struct
gpio_chip
chip
;
struct
gpio_regs
*
gpio_grp
;
};
static
inline
struct
lpc32xx_gpio_chip
*
to_lpc32xx_gpio
(
struct
gpio_chip
*
gpc
)
{
return
container_of
(
gpc
,
struct
lpc32xx_gpio_chip
,
chip
);
}
static
void
__set_gpio_dir_p012
(
struct
lpc32xx_gpio_chip
*
group
,
unsigned
pin
,
int
input
)
{
if
(
input
)
__raw_writel
(
GPIO012_PIN_TO_BIT
(
pin
),
group
->
gpio_grp
->
dir_clr
);
else
__raw_writel
(
GPIO012_PIN_TO_BIT
(
pin
),
group
->
gpio_grp
->
dir_set
);
}
static
void
__set_gpio_dir_p3
(
struct
lpc32xx_gpio_chip
*
group
,
unsigned
pin
,
int
input
)
{
u32
u
=
GPIO3_PIN_TO_BIT
(
pin
);
if
(
input
)
__raw_writel
(
u
,
group
->
gpio_grp
->
dir_clr
);
else
__raw_writel
(
u
,
group
->
gpio_grp
->
dir_set
);
}
static
void
__set_gpio_level_p012
(
struct
lpc32xx_gpio_chip
*
group
,
unsigned
pin
,
int
high
)
{
if
(
high
)
__raw_writel
(
GPIO012_PIN_TO_BIT
(
pin
),
group
->
gpio_grp
->
outp_set
);
else
__raw_writel
(
GPIO012_PIN_TO_BIT
(
pin
),
group
->
gpio_grp
->
outp_clr
);
}
static
void
__set_gpio_level_p3
(
struct
lpc32xx_gpio_chip
*
group
,
unsigned
pin
,
int
high
)
{
u32
u
=
GPIO3_PIN_TO_BIT
(
pin
);
if
(
high
)
__raw_writel
(
u
,
group
->
gpio_grp
->
outp_set
);
else
__raw_writel
(
u
,
group
->
gpio_grp
->
outp_clr
);
}
static
void
__set_gpo_level_p3
(
struct
lpc32xx_gpio_chip
*
group
,
unsigned
pin
,
int
high
)
{
if
(
high
)
__raw_writel
(
GPO3_PIN_TO_BIT
(
pin
),
group
->
gpio_grp
->
outp_set
);
else
__raw_writel
(
GPO3_PIN_TO_BIT
(
pin
),
group
->
gpio_grp
->
outp_clr
);
}
static
int
__get_gpio_state_p012
(
struct
lpc32xx_gpio_chip
*
group
,
unsigned
pin
)
{
return
GPIO012_PIN_IN_SEL
(
__raw_readl
(
group
->
gpio_grp
->
inp_state
),
pin
);
}
static
int
__get_gpio_state_p3
(
struct
lpc32xx_gpio_chip
*
group
,
unsigned
pin
)
{
int
state
=
__raw_readl
(
group
->
gpio_grp
->
inp_state
);
/*
* P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped
* to bits 10..14, while GPIOP3-5 is mapped to bit 24.
*/
return
GPIO3_PIN_IN_SEL
(
state
,
pin
);
}
static
int
__get_gpi_state_p3
(
struct
lpc32xx_gpio_chip
*
group
,
unsigned
pin
)
{
return
GPI3_PIN_IN_SEL
(
__raw_readl
(
group
->
gpio_grp
->
inp_state
),
pin
);
}
/*
* GENERIC_GPIO primitives.
*/
static
int
lpc32xx_gpio_dir_input_p012
(
struct
gpio_chip
*
chip
,
unsigned
pin
)
{
struct
lpc32xx_gpio_chip
*
group
=
to_lpc32xx_gpio
(
chip
);
__set_gpio_dir_p012
(
group
,
pin
,
1
);
return
0
;
}
static
int
lpc32xx_gpio_dir_input_p3
(
struct
gpio_chip
*
chip
,
unsigned
pin
)
{
struct
lpc32xx_gpio_chip
*
group
=
to_lpc32xx_gpio
(
chip
);
__set_gpio_dir_p3
(
group
,
pin
,
1
);
return
0
;
}
static
int
lpc32xx_gpio_dir_in_always
(
struct
gpio_chip
*
chip
,
unsigned
pin
)
{
return
0
;
}
static
int
lpc32xx_gpio_get_value_p012
(
struct
gpio_chip
*
chip
,
unsigned
pin
)
{
struct
lpc32xx_gpio_chip
*
group
=
to_lpc32xx_gpio
(
chip
);
return
__get_gpio_state_p012
(
group
,
pin
);
}
static
int
lpc32xx_gpio_get_value_p3
(
struct
gpio_chip
*
chip
,
unsigned
pin
)
{
struct
lpc32xx_gpio_chip
*
group
=
to_lpc32xx_gpio
(
chip
);
return
__get_gpio_state_p3
(
group
,
pin
);
}
static
int
lpc32xx_gpi_get_value
(
struct
gpio_chip
*
chip
,
unsigned
pin
)
{
struct
lpc32xx_gpio_chip
*
group
=
to_lpc32xx_gpio
(
chip
);
return
__get_gpi_state_p3
(
group
,
pin
);
}
static
int
lpc32xx_gpio_dir_output_p012
(
struct
gpio_chip
*
chip
,
unsigned
pin
,
int
value
)
{
struct
lpc32xx_gpio_chip
*
group
=
to_lpc32xx_gpio
(
chip
);
__set_gpio_dir_p012
(
group
,
pin
,
0
);
return
0
;
}
static
int
lpc32xx_gpio_dir_output_p3
(
struct
gpio_chip
*
chip
,
unsigned
pin
,
int
value
)
{
struct
lpc32xx_gpio_chip
*
group
=
to_lpc32xx_gpio
(
chip
);
__set_gpio_dir_p3
(
group
,
pin
,
0
);
return
0
;
}
static
int
lpc32xx_gpio_dir_out_always
(
struct
gpio_chip
*
chip
,
unsigned
pin
,
int
value
)
{
return
0
;
}
static
void
lpc32xx_gpio_set_value_p012
(
struct
gpio_chip
*
chip
,
unsigned
pin
,
int
value
)
{
struct
lpc32xx_gpio_chip
*
group
=
to_lpc32xx_gpio
(
chip
);
__set_gpio_level_p012
(
group
,
pin
,
value
);
}
static
void
lpc32xx_gpio_set_value_p3
(
struct
gpio_chip
*
chip
,
unsigned
pin
,
int
value
)
{
struct
lpc32xx_gpio_chip
*
group
=
to_lpc32xx_gpio
(
chip
);
__set_gpio_level_p3
(
group
,
pin
,
value
);
}
static
void
lpc32xx_gpo_set_value
(
struct
gpio_chip
*
chip
,
unsigned
pin
,
int
value
)
{
struct
lpc32xx_gpio_chip
*
group
=
to_lpc32xx_gpio
(
chip
);
__set_gpo_level_p3
(
group
,
pin
,
value
);
}
static
int
lpc32xx_gpio_request
(
struct
gpio_chip
*
chip
,
unsigned
pin
)
{
if
(
pin
<
chip
->
ngpio
)
return
0
;
return
-
EINVAL
;
}
static
struct
lpc32xx_gpio_chip
lpc32xx_gpiochip
[]
=
{
{
.
chip
=
{
.
label
=
"gpio_p0"
,
.
direction_input
=
lpc32xx_gpio_dir_input_p012
,
.
get
=
lpc32xx_gpio_get_value_p012
,
.
direction_output
=
lpc32xx_gpio_dir_output_p012
,
.
set
=
lpc32xx_gpio_set_value_p012
,
.
request
=
lpc32xx_gpio_request
,
.
base
=
LPC32XX_GPIO_P0_GRP
,
.
ngpio
=
LPC32XX_GPIO_P0_MAX
,
.
names
=
gpio_p0_names
,
.
can_sleep
=
0
,
},
.
gpio_grp
=
&
gpio_grp_regs_p0
,
},
{
.
chip
=
{
.
label
=
"gpio_p1"
,
.
direction_input
=
lpc32xx_gpio_dir_input_p012
,
.
get
=
lpc32xx_gpio_get_value_p012
,
.
direction_output
=
lpc32xx_gpio_dir_output_p012
,
.
set
=
lpc32xx_gpio_set_value_p012
,
.
request
=
lpc32xx_gpio_request
,
.
base
=
LPC32XX_GPIO_P1_GRP
,
.
ngpio
=
LPC32XX_GPIO_P1_MAX
,
.
names
=
gpio_p1_names
,
.
can_sleep
=
0
,
},
.
gpio_grp
=
&
gpio_grp_regs_p1
,
},
{
.
chip
=
{
.
label
=
"gpio_p2"
,
.
direction_input
=
lpc32xx_gpio_dir_input_p012
,
.
get
=
lpc32xx_gpio_get_value_p012
,
.
direction_output
=
lpc32xx_gpio_dir_output_p012
,
.
set
=
lpc32xx_gpio_set_value_p012
,
.
request
=
lpc32xx_gpio_request
,
.
base
=
LPC32XX_GPIO_P2_GRP
,
.
ngpio
=
LPC32XX_GPIO_P2_MAX
,
.
names
=
gpio_p2_names
,
.
can_sleep
=
0
,
},
.
gpio_grp
=
&
gpio_grp_regs_p2
,
},
{
.
chip
=
{
.
label
=
"gpio_p3"
,
.
direction_input
=
lpc32xx_gpio_dir_input_p3
,
.
get
=
lpc32xx_gpio_get_value_p3
,
.
direction_output
=
lpc32xx_gpio_dir_output_p3
,
.
set
=
lpc32xx_gpio_set_value_p3
,
.
request
=
lpc32xx_gpio_request
,
.
base
=
LPC32XX_GPIO_P3_GRP
,
.
ngpio
=
LPC32XX_GPIO_P3_MAX
,
.
names
=
gpio_p3_names
,
.
can_sleep
=
0
,
},
.
gpio_grp
=
&
gpio_grp_regs_p3
,
},
{
.
chip
=
{
.
label
=
"gpi_p3"
,
.
direction_input
=
lpc32xx_gpio_dir_in_always
,
.
get
=
lpc32xx_gpi_get_value
,
.
request
=
lpc32xx_gpio_request
,
.
base
=
LPC32XX_GPI_P3_GRP
,
.
ngpio
=
LPC32XX_GPI_P3_MAX
,
.
names
=
gpi_p3_names
,
.
can_sleep
=
0
,
},
.
gpio_grp
=
&
gpio_grp_regs_p3
,
},
{
.
chip
=
{
.
label
=
"gpo_p3"
,
.
direction_output
=
lpc32xx_gpio_dir_out_always
,
.
set
=
lpc32xx_gpo_set_value
,
.
request
=
lpc32xx_gpio_request
,
.
base
=
LPC32XX_GPO_P3_GRP
,
.
ngpio
=
LPC32XX_GPO_P3_MAX
,
.
names
=
gpo_p3_names
,
.
can_sleep
=
0
,
},
.
gpio_grp
=
&
gpio_grp_regs_p3
,
},
};
void
__init
lpc32xx_gpio_init
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
lpc32xx_gpiochip
);
i
++
)
gpiochip_add
(
&
lpc32xx_gpiochip
[
i
].
chip
);
}
arch/arm/mach-lpc32xx/include/mach/clkdev.h
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/include/mach/clkdev.h
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARCH_CLKDEV_H
#define __ASM_ARCH_CLKDEV_H
#define __clk_get(clk) ({ 1; })
#define __clk_put(clk) do { } while (0)
#endif
arch/arm/mach-lpc32xx/include/mach/debug-macro.S
0 → 100644
View file @
cccf59ab
/*
*
arch
/
arm
/
mach
-
lpc32xx
/
include
/
mach
/
debug
-
macro
.
S
*
*
Author
:
Kevin
Wells
<
kevin
.
wells
@
nxp
.
com
>
*
*
Copyright
(
C
)
2010
NXP
Semiconductors
*
*
This
program
is
free
software
; you can redistribute it and/or modify
*
it
under
the
terms
of
the
GNU
General
Public
License
as
published
by
*
the
Free
Software
Foundation
; either version 2 of the License, or
*
(
at
your
option
)
any
later
version
.
*
*
This
program
is
distributed
in
the
hope
that
it
will
be
useful
,
*
but
WITHOUT
ANY
WARRANTY
; without even the implied warranty of
*
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE
.
See
the
*
GNU
General
Public
License
for
more
details
.
*/
/*
*
Debug
output
is
hardcoded
to
standard
UART
5
*/
.
macro
addruart
,
rx
,
tmp
mrc
p15
,
0
,
\
rx
,
c1
,
c0
tst
\
rx
,
#
1
@
MMU
enabled
?
ldreq
\
rx
,
=
0x40090000
ldrne
\
rx
,
=
0xF4090000
.
endm
#define UART_SHIFT 2
#include <asm/hardware/debug-8250.S>
arch/arm/mach-lpc32xx/include/mach/entry-macro.S
0 → 100644
View file @
cccf59ab
/*
*
arch
/
arm
/
mach
-
lpc32xx
/
include
/
mach
/
entry
-
macro
.
S
*
*
Author
:
Kevin
Wells
<
kevin
.
wells
@
nxp
.
com
>
*
*
Copyright
(
C
)
2010
NXP
Semiconductors
*
*
This
program
is
free
software
; you can redistribute it and/or modify
*
it
under
the
terms
of
the
GNU
General
Public
License
as
published
by
*
the
Free
Software
Foundation
; either version 2 of the License, or
*
(
at
your
option
)
any
later
version
.
*
*
This
program
is
distributed
in
the
hope
that
it
will
be
useful
,
*
but
WITHOUT
ANY
WARRANTY
; without even the implied warranty of
*
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE
.
See
the
*
GNU
General
Public
License
for
more
details
.
*/
#include <mach/hardware.h>
#include <mach/platform.h>
#define LPC32XX_INTC_MASKED_STATUS_OFS 0x8
.
macro
disable_fiq
.
endm
.
macro
get_irqnr_preamble
,
base
,
tmp
ldr
\
base
,
=
IO_ADDRESS
(
LPC32XX_MIC_BASE
)
.
endm
.
macro
arch_ret_to_user
,
tmp1
,
tmp2
.
endm
/*
*
Return
IRQ
number
in
irqnr
.
Also
return
processor
Z
flag
status
in
CPSR
*
as
set
if
an
interrupt
is
pending
.
*/
.
macro
get_irqnr_and_base
,
irqnr
,
irqstat
,
base
,
tmp
ldr
\
irqstat
,
[
\
base
,
#
LPC32XX_INTC_MASKED_STATUS_OFS
]
clz
\
irqnr
,
\
irqstat
rsb
\
irqnr
,
\
irqnr
,
#
31
teq
\
irqstat
,
#
0
.
endm
.
macro
irq_prio_table
.
endm
arch/arm/mach-lpc32xx/include/mach/gpio.h
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/include/mach/gpio.h
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARCH_GPIO_H
#define __ASM_ARCH_GPIO_H
#include <asm-generic/gpio.h>
/*
* Note!
* Muxed GP pins need to be setup to the GP state in the board level
* code prior to using this driver.
* GPI pins : 28xP3 group
* GPO pins : 24xP3 group
* GPIO pins: 8xP0 group, 24xP1 group, 13xP2 group, 6xP3 group
*/
#define LPC32XX_GPIO_P0_MAX 8
#define LPC32XX_GPIO_P1_MAX 24
#define LPC32XX_GPIO_P2_MAX 13
#define LPC32XX_GPIO_P3_MAX 6
#define LPC32XX_GPI_P3_MAX 28
#define LPC32XX_GPO_P3_MAX 24
#define LPC32XX_GPIO_P0_GRP 0
#define LPC32XX_GPIO_P1_GRP (LPC32XX_GPIO_P0_GRP + LPC32XX_GPIO_P0_MAX)
#define LPC32XX_GPIO_P2_GRP (LPC32XX_GPIO_P1_GRP + LPC32XX_GPIO_P1_MAX)
#define LPC32XX_GPIO_P3_GRP (LPC32XX_GPIO_P2_GRP + LPC32XX_GPIO_P2_MAX)
#define LPC32XX_GPI_P3_GRP (LPC32XX_GPIO_P3_GRP + LPC32XX_GPIO_P3_MAX)
#define LPC32XX_GPO_P3_GRP (LPC32XX_GPI_P3_GRP + LPC32XX_GPI_P3_MAX)
/*
* A specific GPIO can be selected with this macro
* ie, GPIO_05 can be selected with LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5)
* See the LPC32x0 User's guide for GPIO group numbers
*/
#define LPC32XX_GPIO(x, y) ((x) + (y))
static
inline
int
gpio_get_value
(
unsigned
gpio
)
{
return
__gpio_get_value
(
gpio
);
}
static
inline
void
gpio_set_value
(
unsigned
gpio
,
int
value
)
{
__gpio_set_value
(
gpio
,
value
);
}
static
inline
int
gpio_cansleep
(
unsigned
gpio
)
{
return
__gpio_cansleep
(
gpio
);
}
static
inline
int
gpio_to_irq
(
unsigned
gpio
)
{
return
__gpio_to_irq
(
gpio
);
}
#endif
arch/arm/mach-lpc32xx/include/mach/hardware.h
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/include/mach/hardware.h
*
* Copyright (c) 2005 MontaVista Software, Inc. <source@mvista.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
/*
* Start of virtual addresses for IO devices
*/
#define IO_BASE 0xF0000000
/*
* This macro relies on fact that for all HW i/o addresses bits 20-23 are 0
*/
#define IO_ADDRESS(x) (((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) |\
IO_BASE)
#define io_p2v(x) ((void __iomem *) (unsigned long) IO_ADDRESS(x))
#define io_v2p(x) ((((x) & 0x0ff00000) << 4) | ((x) & 0x000fffff))
#endif
arch/arm/mach-lpc32xx/include/mach/i2c.h
0 → 100644
View file @
cccf59ab
/*
* PNX4008-specific tweaks for I2C IP3204 block
*
* Author: Vitaly Wool <vwool@ru.mvista.com>
*
* 2005 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef __ASM_ARCH_I2C_H
#define __ASM_ARCH_I2C_H
enum
{
mstatus_tdi
=
0x00000001
,
mstatus_afi
=
0x00000002
,
mstatus_nai
=
0x00000004
,
mstatus_drmi
=
0x00000008
,
mstatus_active
=
0x00000020
,
mstatus_scl
=
0x00000040
,
mstatus_sda
=
0x00000080
,
mstatus_rff
=
0x00000100
,
mstatus_rfe
=
0x00000200
,
mstatus_tff
=
0x00000400
,
mstatus_tfe
=
0x00000800
,
};
enum
{
mcntrl_tdie
=
0x00000001
,
mcntrl_afie
=
0x00000002
,
mcntrl_naie
=
0x00000004
,
mcntrl_drmie
=
0x00000008
,
mcntrl_daie
=
0x00000020
,
mcntrl_rffie
=
0x00000040
,
mcntrl_tffie
=
0x00000080
,
mcntrl_reset
=
0x00000100
,
mcntrl_cdbmode
=
0x00000400
,
};
enum
{
rw_bit
=
1
<<
0
,
start_bit
=
1
<<
8
,
stop_bit
=
1
<<
9
,
};
#define I2C_REG_RX(a) ((a)->ioaddr)
/* Rx FIFO reg (RO) */
#define I2C_REG_TX(a) ((a)->ioaddr)
/* Tx FIFO reg (WO) */
#define I2C_REG_STS(a) ((a)->ioaddr + 0x04)
/* Status reg (RO) */
#define I2C_REG_CTL(a) ((a)->ioaddr + 0x08)
/* Ctl reg */
#define I2C_REG_CKL(a) ((a)->ioaddr + 0x0c)
/* Clock divider low */
#define I2C_REG_CKH(a) ((a)->ioaddr + 0x10)
/* Clock divider high */
#define I2C_REG_ADR(a) ((a)->ioaddr + 0x14)
/* I2C address */
#define I2C_REG_RFL(a) ((a)->ioaddr + 0x18)
/* Rx FIFO level (RO) */
#define I2C_REG_TFL(a) ((a)->ioaddr + 0x1c)
/* Tx FIFO level (RO) */
#define I2C_REG_RXB(a) ((a)->ioaddr + 0x20)
/* Num of bytes Rx-ed (RO) */
#define I2C_REG_TXB(a) ((a)->ioaddr + 0x24)
/* Num of bytes Tx-ed (RO) */
#define I2C_REG_TXS(a) ((a)->ioaddr + 0x28)
/* Tx slave FIFO (RO) */
#define I2C_REG_STFL(a) ((a)->ioaddr + 0x2c)
/* Tx slave FIFO level (RO) */
#define I2C_CHIP_NAME "PNX4008-I2C"
#endif
/* __ASM_ARCH_I2C_H */
arch/arm/mach-lpc32xx/include/mach/io.h
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/include/mach/io.h
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) __typesafe_io(a)
#define __mem_pci(a) (a)
#endif
arch/arm/mach-lpc32xx/include/mach/irqs.h
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/include/mach/irqs.h
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARM_ARCH_IRQS_H
#define __ASM_ARM_ARCH_IRQS_H
#define LPC32XX_SIC1_IRQ(n) (32 + (n))
#define LPC32XX_SIC2_IRQ(n) (64 + (n))
/*
* MIC interrupts
*/
#define IRQ_LPC32XX_SUB1IRQ 0
#define IRQ_LPC32XX_SUB2IRQ 1
#define IRQ_LPC32XX_PWM3 3
#define IRQ_LPC32XX_PWM4 4
#define IRQ_LPC32XX_HSTIMER 5
#define IRQ_LPC32XX_WATCH 6
#define IRQ_LPC32XX_UART_IIR3 7
#define IRQ_LPC32XX_UART_IIR4 8
#define IRQ_LPC32XX_UART_IIR5 9
#define IRQ_LPC32XX_UART_IIR6 10
#define IRQ_LPC32XX_FLASH 11
#define IRQ_LPC32XX_SD1 13
#define IRQ_LPC32XX_LCD 14
#define IRQ_LPC32XX_SD0 15
#define IRQ_LPC32XX_TIMER0 16
#define IRQ_LPC32XX_TIMER1 17
#define IRQ_LPC32XX_TIMER2 18
#define IRQ_LPC32XX_TIMER3 19
#define IRQ_LPC32XX_SSP0 20
#define IRQ_LPC32XX_SSP1 21
#define IRQ_LPC32XX_I2S0 22
#define IRQ_LPC32XX_I2S1 23
#define IRQ_LPC32XX_UART_IIR7 24
#define IRQ_LPC32XX_UART_IIR2 25
#define IRQ_LPC32XX_UART_IIR1 26
#define IRQ_LPC32XX_MSTIMER 27
#define IRQ_LPC32XX_DMA 28
#define IRQ_LPC32XX_ETHERNET 29
#define IRQ_LPC32XX_SUB1FIQ 30
#define IRQ_LPC32XX_SUB2FIQ 31
/*
* SIC1 interrupts start at offset 32
*/
#define IRQ_LPC32XX_JTAG_COMM_TX LPC32XX_SIC1_IRQ(1)
#define IRQ_LPC32XX_JTAG_COMM_RX LPC32XX_SIC1_IRQ(2)
#define IRQ_LPC32XX_GPI_11 LPC32XX_SIC1_IRQ(4)
#define IRQ_LPC32XX_TS_P LPC32XX_SIC1_IRQ(6)
#define IRQ_LPC32XX_TS_IRQ LPC32XX_SIC1_IRQ(7)
#define IRQ_LPC32XX_TS_AUX LPC32XX_SIC1_IRQ(8)
#define IRQ_LPC32XX_SPI2 LPC32XX_SIC1_IRQ(12)
#define IRQ_LPC32XX_PLLUSB LPC32XX_SIC1_IRQ(13)
#define IRQ_LPC32XX_PLLHCLK LPC32XX_SIC1_IRQ(14)
#define IRQ_LPC32XX_PLL397 LPC32XX_SIC1_IRQ(17)
#define IRQ_LPC32XX_I2C_2 LPC32XX_SIC1_IRQ(18)
#define IRQ_LPC32XX_I2C_1 LPC32XX_SIC1_IRQ(19)
#define IRQ_LPC32XX_RTC LPC32XX_SIC1_IRQ(20)
#define IRQ_LPC32XX_KEY LPC32XX_SIC1_IRQ(22)
#define IRQ_LPC32XX_SPI1 LPC32XX_SIC1_IRQ(23)
#define IRQ_LPC32XX_SW LPC32XX_SIC1_IRQ(24)
#define IRQ_LPC32XX_USB_OTG_TIMER LPC32XX_SIC1_IRQ(25)
#define IRQ_LPC32XX_USB_OTG_ATX LPC32XX_SIC1_IRQ(26)
#define IRQ_LPC32XX_USB_HOST LPC32XX_SIC1_IRQ(27)
#define IRQ_LPC32XX_USB_DEV_DMA LPC32XX_SIC1_IRQ(28)
#define IRQ_LPC32XX_USB_DEV_LP LPC32XX_SIC1_IRQ(29)
#define IRQ_LPC32XX_USB_DEV_HP LPC32XX_SIC1_IRQ(30)
#define IRQ_LPC32XX_USB_I2C LPC32XX_SIC1_IRQ(31)
/*
* SIC2 interrupts start at offset 64
*/
#define IRQ_LPC32XX_GPIO_00 LPC32XX_SIC2_IRQ(0)
#define IRQ_LPC32XX_GPIO_01 LPC32XX_SIC2_IRQ(1)
#define IRQ_LPC32XX_GPIO_02 LPC32XX_SIC2_IRQ(2)
#define IRQ_LPC32XX_GPIO_03 LPC32XX_SIC2_IRQ(3)
#define IRQ_LPC32XX_GPIO_04 LPC32XX_SIC2_IRQ(4)
#define IRQ_LPC32XX_GPIO_05 LPC32XX_SIC2_IRQ(5)
#define IRQ_LPC32XX_SPI2_DATAIN LPC32XX_SIC2_IRQ(6)
#define IRQ_LPC32XX_U2_HCTS LPC32XX_SIC2_IRQ(7)
#define IRQ_LPC32XX_P0_P1_IRQ LPC32XX_SIC2_IRQ(8)
#define IRQ_LPC32XX_GPI_08 LPC32XX_SIC2_IRQ(9)
#define IRQ_LPC32XX_GPI_09 LPC32XX_SIC2_IRQ(10)
#define IRQ_LPC32XX_GPI_19 LPC32XX_SIC2_IRQ(11)
#define IRQ_LPC32XX_U7_HCTS LPC32XX_SIC2_IRQ(12)
#define IRQ_LPC32XX_GPI_07 LPC32XX_SIC2_IRQ(15)
#define IRQ_LPC32XX_SDIO LPC32XX_SIC2_IRQ(18)
#define IRQ_LPC32XX_U5_RX LPC32XX_SIC2_IRQ(19)
#define IRQ_LPC32XX_SPI1_DATAIN LPC32XX_SIC2_IRQ(20)
#define IRQ_LPC32XX_GPI_00 LPC32XX_SIC2_IRQ(22)
#define IRQ_LPC32XX_GPI_01 LPC32XX_SIC2_IRQ(23)
#define IRQ_LPC32XX_GPI_02 LPC32XX_SIC2_IRQ(24)
#define IRQ_LPC32XX_GPI_03 LPC32XX_SIC2_IRQ(25)
#define IRQ_LPC32XX_GPI_04 LPC32XX_SIC2_IRQ(26)
#define IRQ_LPC32XX_GPI_05 LPC32XX_SIC2_IRQ(27)
#define IRQ_LPC32XX_GPI_06 LPC32XX_SIC2_IRQ(28)
#define IRQ_LPC32XX_SYSCLK LPC32XX_SIC2_IRQ(31)
#define NR_IRQS 96
#endif
arch/arm/mach-lpc32xx/include/mach/memory.h
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/include/mach/memory.h
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
/*
* Physical DRAM offset of bank 0
*/
#define PHYS_OFFSET UL(0x80000000)
#endif
arch/arm/mach-lpc32xx/include/mach/platform.h
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/include/mach/platform.h
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARCH_PLATFORM_H
#define __ASM_ARCH_PLATFORM_H
#define _SBF(f, v) ((v) << (f))
#define _BIT(n) _SBF(n, 1)
/*
* AHB 0 physical base addresses
*/
#define LPC32XX_SLC_BASE 0x20020000
#define LPC32XX_SSP0_BASE 0x20084000
#define LPC32XX_SPI1_BASE 0x20088000
#define LPC32XX_SSP1_BASE 0x2008C000
#define LPC32XX_SPI2_BASE 0x20090000
#define LPC32XX_I2S0_BASE 0x20094000
#define LPC32XX_SD_BASE 0x20098000
#define LPC32XX_I2S1_BASE 0x2009C000
#define LPC32XX_MLC_BASE 0x200A8000
#define LPC32XX_AHB0_START LPC32XX_SLC_BASE
#define LPC32XX_AHB0_SIZE 0x00089000
/*
* AHB 1 physical base addresses
*/
#define LPC32XX_DMA_BASE 0x31000000
#define LPC32XX_USB_BASE 0x31020000
#define LPC32XX_USBH_BASE 0x31020000
#define LPC32XX_USB_OTG_BASE 0x31020000
#define LPC32XX_OTG_I2C_BASE 0x31020300
#define LPC32XX_LCD_BASE 0x31040000
#define LPC32XX_ETHERNET_BASE 0x31060000
#define LPC32XX_EMC_BASE 0x31080000
#define LPC32XX_ETB_CFG_BASE 0x310C0000
#define LPC32XX_ETB_DATA_BASE 0x310E0000
#define LPC32XX_AHB1_START LPC32XX_DMA_BASE
#define LPC32XX_AHB1_SIZE 0x000E1000
/*
* FAB physical base addresses
*/
#define LPC32XX_CLK_PM_BASE 0x40004000
#define LPC32XX_MIC_BASE 0x40008000
#define LPC32XX_SIC1_BASE 0x4000C000
#define LPC32XX_SIC2_BASE 0x40010000
#define LPC32XX_HS_UART1_BASE 0x40014000
#define LPC32XX_HS_UART2_BASE 0x40018000
#define LPC32XX_HS_UART7_BASE 0x4001C000
#define LPC32XX_RTC_BASE 0x40024000
#define LPC32XX_RTC_RAM_BASE 0x40024080
#define LPC32XX_GPIO_BASE 0x40028000
#define LPC32XX_PWM3_BASE 0x4002C000
#define LPC32XX_PWM4_BASE 0x40030000
#define LPC32XX_MSTIM_BASE 0x40034000
#define LPC32XX_HSTIM_BASE 0x40038000
#define LPC32XX_WDTIM_BASE 0x4003C000
#define LPC32XX_DEBUG_CTRL_BASE 0x40040000
#define LPC32XX_TIMER0_BASE 0x40044000
#define LPC32XX_ADC_BASE 0x40048000
#define LPC32XX_TIMER1_BASE 0x4004C000
#define LPC32XX_KSCAN_BASE 0x40050000
#define LPC32XX_UART_CTRL_BASE 0x40054000
#define LPC32XX_TIMER2_BASE 0x40058000
#define LPC32XX_PWM1_BASE 0x4005C000
#define LPC32XX_PWM2_BASE 0x4005C004
#define LPC32XX_TIMER3_BASE 0x40060000
/*
* APB physical base addresses
*/
#define LPC32XX_UART3_BASE 0x40080000
#define LPC32XX_UART4_BASE 0x40088000
#define LPC32XX_UART5_BASE 0x40090000
#define LPC32XX_UART6_BASE 0x40098000
#define LPC32XX_I2C1_BASE 0x400A0000
#define LPC32XX_I2C2_BASE 0x400A8000
/*
* FAB and APB base and sizing
*/
#define LPC32XX_FABAPB_START LPC32XX_CLK_PM_BASE
#define LPC32XX_FABAPB_SIZE 0x000A5000
/*
* Internal memory bases and sizes
*/
#define LPC32XX_IRAM_BASE 0x08000000
#define LPC32XX_IROM_BASE 0x0C000000
/*
* External Static Memory Bank Address Space Bases
*/
#define LPC32XX_EMC_CS0_BASE 0xE0000000
#define LPC32XX_EMC_CS1_BASE 0xE1000000
#define LPC32XX_EMC_CS2_BASE 0xE2000000
#define LPC32XX_EMC_CS3_BASE 0xE3000000
/*
* External SDRAM Memory Bank Address Space Bases
*/
#define LPC32XX_EMC_DYCS0_BASE 0x80000000
#define LPC32XX_EMC_DYCS1_BASE 0xA0000000
/*
* Clock and crystal information
*/
#define LPC32XX_MAIN_OSC_FREQ 13000000
#define LPC32XX_CLOCK_OSC_FREQ 32768
/*
* Clock and Power control register offsets
*/
#define _PMREG(x) io_p2v(LPC32XX_CLK_PM_BASE +\
(x))
#define LPC32XX_CLKPWR_DEBUG_CTRL _PMREG(0x000)
#define LPC32XX_CLKPWR_BOOTMAP _PMREG(0x014)
#define LPC32XX_CLKPWR_P01_ER _PMREG(0x018)
#define LPC32XX_CLKPWR_USBCLK_PDIV _PMREG(0x01C)
#define LPC32XX_CLKPWR_INT_ER _PMREG(0x020)
#define LPC32XX_CLKPWR_INT_RS _PMREG(0x024)
#define LPC32XX_CLKPWR_INT_SR _PMREG(0x028)
#define LPC32XX_CLKPWR_INT_AP _PMREG(0x02C)
#define LPC32XX_CLKPWR_PIN_ER _PMREG(0x030)
#define LPC32XX_CLKPWR_PIN_RS _PMREG(0x034)
#define LPC32XX_CLKPWR_PIN_SR _PMREG(0x038)
#define LPC32XX_CLKPWR_PIN_AP _PMREG(0x03C)
#define LPC32XX_CLKPWR_HCLK_DIV _PMREG(0x040)
#define LPC32XX_CLKPWR_PWR_CTRL _PMREG(0x044)
#define LPC32XX_CLKPWR_PLL397_CTRL _PMREG(0x048)
#define LPC32XX_CLKPWR_MAIN_OSC_CTRL _PMREG(0x04C)
#define LPC32XX_CLKPWR_SYSCLK_CTRL _PMREG(0x050)
#define LPC32XX_CLKPWR_LCDCLK_CTRL _PMREG(0x054)
#define LPC32XX_CLKPWR_HCLKPLL_CTRL _PMREG(0x058)
#define LPC32XX_CLKPWR_ADC_CLK_CTRL_1 _PMREG(0x060)
#define LPC32XX_CLKPWR_USB_CTRL _PMREG(0x064)
#define LPC32XX_CLKPWR_SDRAMCLK_CTRL _PMREG(0x068)
#define LPC32XX_CLKPWR_DDR_LAP_NOM _PMREG(0x06C)
#define LPC32XX_CLKPWR_DDR_LAP_COUNT _PMREG(0x070)
#define LPC32XX_CLKPWR_DDR_LAP_DELAY _PMREG(0x074)
#define LPC32XX_CLKPWR_SSP_CLK_CTRL _PMREG(0x078)
#define LPC32XX_CLKPWR_I2S_CLK_CTRL _PMREG(0x07C)
#define LPC32XX_CLKPWR_MS_CTRL _PMREG(0x080)
#define LPC32XX_CLKPWR_MACCLK_CTRL _PMREG(0x090)
#define LPC32XX_CLKPWR_TEST_CLK_SEL _PMREG(0x0A4)
#define LPC32XX_CLKPWR_SFW_INT _PMREG(0x0A8)
#define LPC32XX_CLKPWR_I2C_CLK_CTRL _PMREG(0x0AC)
#define LPC32XX_CLKPWR_KEY_CLK_CTRL _PMREG(0x0B0)
#define LPC32XX_CLKPWR_ADC_CLK_CTRL _PMREG(0x0B4)
#define LPC32XX_CLKPWR_PWM_CLK_CTRL _PMREG(0x0B8)
#define LPC32XX_CLKPWR_TIMER_CLK_CTRL _PMREG(0x0BC)
#define LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1 _PMREG(0x0C0)
#define LPC32XX_CLKPWR_SPI_CLK_CTRL _PMREG(0x0C4)
#define LPC32XX_CLKPWR_NAND_CLK_CTRL _PMREG(0x0C8)
#define LPC32XX_CLKPWR_UART3_CLK_CTRL _PMREG(0x0D0)
#define LPC32XX_CLKPWR_UART4_CLK_CTRL _PMREG(0x0D4)
#define LPC32XX_CLKPWR_UART5_CLK_CTRL _PMREG(0x0D8)
#define LPC32XX_CLKPWR_UART6_CLK_CTRL _PMREG(0x0DC)
#define LPC32XX_CLKPWR_IRDA_CLK_CTRL _PMREG(0x0E0)
#define LPC32XX_CLKPWR_UART_CLK_CTRL _PMREG(0x0E4)
#define LPC32XX_CLKPWR_DMA_CLK_CTRL _PMREG(0x0E8)
#define LPC32XX_CLKPWR_AUTOCLOCK _PMREG(0x0EC)
#define LPC32XX_CLKPWR_DEVID(x) _PMREG(0x130 + (x))
/*
* clkpwr_debug_ctrl register definitions
*/
#define LPC32XX_CLKPWR_VFP_CLOCK_ENABLE_BIT _BIT(4)
/*
* clkpwr_bootmap register definitions
*/
#define LPC32XX_CLKPWR_BOOTMAP_SEL_BIT _BIT(1)
/*
* clkpwr_start_gpio register bit definitions
*/
#define LPC32XX_CLKPWR_GPIOSRC_P1IO23_BIT _BIT(31)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO22_BIT _BIT(30)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO21_BIT _BIT(29)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO20_BIT _BIT(28)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO19_BIT _BIT(27)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO18_BIT _BIT(26)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO17_BIT _BIT(25)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO16_BIT _BIT(24)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO15_BIT _BIT(23)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO14_BIT _BIT(22)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO13_BIT _BIT(21)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO12_BIT _BIT(20)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO11_BIT _BIT(19)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO10_BIT _BIT(18)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO9_BIT _BIT(17)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO8_BIT _BIT(16)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO7_BIT _BIT(15)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO6_BIT _BIT(14)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO5_BIT _BIT(13)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO4_BIT _BIT(12)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO3_BIT _BIT(11)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO2_BIT _BIT(10)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO1_BIT _BIT(9)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO0_BIT _BIT(8)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO7_BIT _BIT(7)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO6_BIT _BIT(6)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO5_BIT _BIT(5)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO4_BIT _BIT(4)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO3_BIT _BIT(3)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO2_BIT _BIT(2)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO1_BIT _BIT(1)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO0_BIT _BIT(0)
/*
* clkpwr_usbclk_pdiv register definitions
*/
#define LPC32XX_CLKPWR_USBPDIV_PLL_MASK 0xF
/*
* clkpwr_start_int, clkpwr_start_raw_sts_int, clkpwr_start_sts_int,
* clkpwr_start_pol_int, register bit definitions
*/
#define LPC32XX_CLKPWR_INTSRC_ADC_BIT _BIT(31)
#define LPC32XX_CLKPWR_INTSRC_TS_P_BIT _BIT(30)
#define LPC32XX_CLKPWR_INTSRC_TS_AUX_BIT _BIT(29)
#define LPC32XX_CLKPWR_INTSRC_USBAHNEEDCLK_BIT _BIT(26)
#define LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT _BIT(25)
#define LPC32XX_CLKPWR_INTSRC_RTC_BIT _BIT(24)
#define LPC32XX_CLKPWR_INTSRC_USBNEEDCLK_BIT _BIT(23)
#define LPC32XX_CLKPWR_INTSRC_USB_BIT _BIT(22)
#define LPC32XX_CLKPWR_INTSRC_I2C_BIT _BIT(21)
#define LPC32XX_CLKPWR_INTSRC_USBOTGTIMER_BIT _BIT(20)
#define LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT _BIT(19)
#define LPC32XX_CLKPWR_INTSRC_KEY_BIT _BIT(16)
#define LPC32XX_CLKPWR_INTSRC_MAC_BIT _BIT(7)
#define LPC32XX_CLKPWR_INTSRC_P0P1_BIT _BIT(6)
#define LPC32XX_CLKPWR_INTSRC_GPIO_05_BIT _BIT(5)
#define LPC32XX_CLKPWR_INTSRC_GPIO_04_BIT _BIT(4)
#define LPC32XX_CLKPWR_INTSRC_GPIO_03_BIT _BIT(3)
#define LPC32XX_CLKPWR_INTSRC_GPIO_02_BIT _BIT(2)
#define LPC32XX_CLKPWR_INTSRC_GPIO_01_BIT _BIT(1)
#define LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT _BIT(0)
/*
* clkpwr_start_pin, clkpwr_start_raw_sts_pin, clkpwr_start_sts_pin,
* clkpwr_start_pol_pin register bit definitions
*/
#define LPC32XX_CLKPWR_EXTSRC_U7_RX_BIT _BIT(31)
#define LPC32XX_CLKPWR_EXTSRC_U7_HCTS_BIT _BIT(30)
#define LPC32XX_CLKPWR_EXTSRC_U6_IRRX_BIT _BIT(28)
#define LPC32XX_CLKPWR_EXTSRC_U5_RX_BIT _BIT(26)
#define LPC32XX_CLKPWR_EXTSRC_GPI_28_BIT _BIT(25)
#define LPC32XX_CLKPWR_EXTSRC_U3_RX_BIT _BIT(24)
#define LPC32XX_CLKPWR_EXTSRC_U2_HCTS_BIT _BIT(23)
#define LPC32XX_CLKPWR_EXTSRC_U2_RX_BIT _BIT(22)
#define LPC32XX_CLKPWR_EXTSRC_U1_RX_BIT _BIT(21)
#define LPC32XX_CLKPWR_EXTSRC_MSDIO_INT_BIT _BIT(18)
#define LPC32XX_CLKPWR_EXTSRC_MSDIO_SRT_BIT _BIT(17)
#define LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT _BIT(16)
#define LPC32XX_CLKPWR_EXTSRC_GPI_05_BIT _BIT(15)
#define LPC32XX_CLKPWR_EXTSRC_GPI_04_BIT _BIT(14)
#define LPC32XX_CLKPWR_EXTSRC_GPI_03_BIT _BIT(13)
#define LPC32XX_CLKPWR_EXTSRC_GPI_02_BIT _BIT(12)
#define LPC32XX_CLKPWR_EXTSRC_GPI_01_BIT _BIT(11)
#define LPC32XX_CLKPWR_EXTSRC_GPI_00_BIT _BIT(10)
#define LPC32XX_CLKPWR_EXTSRC_SYSCLKEN_BIT _BIT(9)
#define LPC32XX_CLKPWR_EXTSRC_SPI1_DATIN_BIT _BIT(8)
#define LPC32XX_CLKPWR_EXTSRC_GPI_07_BIT _BIT(7)
#define LPC32XX_CLKPWR_EXTSRC_SPI2_DATIN_BIT _BIT(6)
#define LPC32XX_CLKPWR_EXTSRC_GPI_19_BIT _BIT(5)
#define LPC32XX_CLKPWR_EXTSRC_GPI_09_BIT _BIT(4)
#define LPC32XX_CLKPWR_EXTSRC_GPI_08_BIT _BIT(3)
/*
* clkpwr_hclk_div register definitions
*/
#define LPC32XX_CLKPWR_HCLKDIV_DDRCLK_STOP (0x0 << 7)
#define LPC32XX_CLKPWR_HCLKDIV_DDRCLK_NORM (0x1 << 7)
#define LPC32XX_CLKPWR_HCLKDIV_DDRCLK_HALF (0x2 << 7)
#define LPC32XX_CLKPWR_HCLKDIV_PCLK_DIV(n) (((n) & 0x1F) << 2)
#define LPC32XX_CLKPWR_HCLKDIV_DIV_2POW(n) ((n) & 0x3)
/*
* clkpwr_pwr_ctrl register definitions
*/
#define LPC32XX_CLKPWR_CTRL_FORCE_PCLK _BIT(10)
#define LPC32XX_CLKPWR_SDRAM_SELF_RFSH _BIT(9)
#define LPC32XX_CLKPWR_UPD_SDRAM_SELF_RFSH _BIT(8)
#define LPC32XX_CLKPWR_AUTO_SDRAM_SELF_RFSH _BIT(7)
#define LPC32XX_CLKPWR_HIGHCORE_STATE_BIT _BIT(5)
#define LPC32XX_CLKPWR_SYSCLKEN_STATE_BIT _BIT(4)
#define LPC32XX_CLKPWR_SYSCLKEN_GPIO_EN _BIT(3)
#define LPC32XX_CLKPWR_SELECT_RUN_MODE _BIT(2)
#define LPC32XX_CLKPWR_HIGHCORE_GPIO_EN _BIT(1)
#define LPC32XX_CLKPWR_STOP_MODE_CTRL _BIT(0)
/*
* clkpwr_pll397_ctrl register definitions
*/
#define LPC32XX_CLKPWR_PLL397_MSLOCK_STS _BIT(10)
#define LPC32XX_CLKPWR_PLL397_BYPASS _BIT(9)
#define LPC32XX_CLKPWR_PLL397_BIAS_NORM 0x000
#define LPC32XX_CLKPWR_PLL397_BIAS_N12_5 0x040
#define LPC32XX_CLKPWR_PLL397_BIAS_N25 0x080
#define LPC32XX_CLKPWR_PLL397_BIAS_N37_5 0x0C0
#define LPC32XX_CLKPWR_PLL397_BIAS_P12_5 0x100
#define LPC32XX_CLKPWR_PLL397_BIAS_P25 0x140
#define LPC32XX_CLKPWR_PLL397_BIAS_P37_5 0x180
#define LPC32XX_CLKPWR_PLL397_BIAS_P50 0x1C0
#define LPC32XX_CLKPWR_PLL397_BIAS_MASK 0x1C0
#define LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS _BIT(1)
#define LPC32XX_CLKPWR_SYSCTRL_PLL397_STS _BIT(0)
/*
* clkpwr_main_osc_ctrl register definitions
*/
#define LPC32XX_CLKPWR_MOSC_ADD_CAP(n) (((n) & 0x7F) << 2)
#define LPC32XX_CLKPWR_MOSC_CAP_MASK (0x7F << 2)
#define LPC32XX_CLKPWR_TEST_MODE _BIT(1)
#define LPC32XX_CLKPWR_MOSC_DISABLE _BIT(0)
/*
* clkpwr_sysclk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_SYSCTRL_BP_TRIG(n) (((n) & 0x3FF) << 2)
#define LPC32XX_CLKPWR_SYSCTRL_BP_MASK (0x3FF << 2)
#define LPC32XX_CLKPWR_SYSCTRL_USEPLL397 _BIT(1)
#define LPC32XX_CLKPWR_SYSCTRL_SYSCLKMUX _BIT(0)
/*
* clkpwr_lcdclk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT12 0x000
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16 0x040
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT15 0x080
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT24 0x0C0
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_STN4M 0x100
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_STN8C 0x140
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_DSTN4M 0x180
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_DSTN8C 0x1C0
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_MSK 0x01C0
#define LPC32XX_CLKPWR_LCDCTRL_CLK_EN 0x020
#define LPC32XX_CLKPWR_LCDCTRL_SET_PSCALE(n) ((n - 1) & 0x1F)
#define LPC32XX_CLKPWR_LCDCTRL_PSCALE_MSK 0x001F
/*
* clkpwr_hclkpll_ctrl register definitions
*/
#define LPC32XX_CLKPWR_HCLKPLL_POWER_UP _BIT(16)
#define LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS _BIT(15)
#define LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS _BIT(14)
#define LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK _BIT(13)
#define LPC32XX_CLKPWR_HCLKPLL_POSTDIV_2POW(n) (((n) & 0x3) << 11)
#define LPC32XX_CLKPWR_HCLKPLL_PREDIV_PLUS1(n) (((n) & 0x3) << 9)
#define LPC32XX_CLKPWR_HCLKPLL_PLLM(n) (((n) & 0xFF) << 1)
#define LPC32XX_CLKPWR_HCLKPLL_PLL_STS _BIT(0)
/*
* clkpwr_adc_clk_ctrl_1 register definitions
*/
#define LPC32XX_CLKPWR_ADCCTRL1_RTDIV(n) (((n) & 0xFF) << 0)
#define LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL _BIT(8)
/*
* clkpwr_usb_ctrl register definitions
*/
#define LPC32XX_CLKPWR_USBCTRL_HCLK_EN _BIT(24)
#define LPC32XX_CLKPWR_USBCTRL_USBI2C_EN _BIT(23)
#define LPC32XX_CLKPWR_USBCTRL_USBDVND_EN _BIT(22)
#define LPC32XX_CLKPWR_USBCTRL_USBHSTND_EN _BIT(21)
#define LPC32XX_CLKPWR_USBCTRL_PU_ADD (0x0 << 19)
#define LPC32XX_CLKPWR_USBCTRL_BUS_KEEPER (0x1 << 19)
#define LPC32XX_CLKPWR_USBCTRL_PD_ADD (0x3 << 19)
#define LPC32XX_CLKPWR_USBCTRL_CLK_EN2 _BIT(18)
#define LPC32XX_CLKPWR_USBCTRL_CLK_EN1 _BIT(17)
#define LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP _BIT(16)
#define LPC32XX_CLKPWR_USBCTRL_CCO_BYPASS _BIT(15)
#define LPC32XX_CLKPWR_USBCTRL_POSTDIV_BYPASS _BIT(14)
#define LPC32XX_CLKPWR_USBCTRL_FDBK_SEL_FCLK _BIT(13)
#define LPC32XX_CLKPWR_USBCTRL_POSTDIV_2POW(n) (((n) & 0x3) << 11)
#define LPC32XX_CLKPWR_USBCTRL_PREDIV_PLUS1(n) (((n) & 0x3) << 9)
#define LPC32XX_CLKPWR_USBCTRL_FDBK_PLUS1(n) (((n) & 0xFF) << 1)
#define LPC32XX_CLKPWR_USBCTRL_PLL_STS _BIT(0)
/*
* clkpwr_sdramclk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_SDRCLK_FASTSLEW_CLK _BIT(22)
#define LPC32XX_CLKPWR_SDRCLK_FASTSLEW _BIT(21)
#define LPC32XX_CLKPWR_SDRCLK_FASTSLEW_DAT _BIT(20)
#define LPC32XX_CLKPWR_SDRCLK_SW_DDR_RESET _BIT(19)
#define LPC32XX_CLKPWR_SDRCLK_HCLK_DLY(n) (((n) & 0x1F) << 14)
#define LPC32XX_CLKPWR_SDRCLK_DLY_ADDR_STS _BIT(13)
#define LPC32XX_CLKPWR_SDRCLK_SENS_FACT(n) (((n) & 0x7) << 10)
#define LPC32XX_CLKPWR_SDRCLK_USE_CAL _BIT(9)
#define LPC32XX_CLKPWR_SDRCLK_DO_CAL _BIT(8)
#define LPC32XX_CLKPWR_SDRCLK_CAL_ON_RTC _BIT(7)
#define LPC32XX_CLKPWR_SDRCLK_DQS_DLY(n) (((n) & 0x1F) << 2)
#define LPC32XX_CLKPWR_SDRCLK_USE_DDR _BIT(1)
#define LPC32XX_CLKPWR_SDRCLK_CLK_DIS _BIT(0)
/*
* clkpwr_ssp_blk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP1RX _BIT(5)
#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP1TX _BIT(4)
#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP0RX _BIT(3)
#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP0TX _BIT(2)
#define LPC32XX_CLKPWR_SSPCTRL_SSPCLK1_EN _BIT(1)
#define LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN _BIT(0)
/*
* clkpwr_i2s_clk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_I2SCTRL_I2S1_RX_FOR_TX _BIT(6)
#define LPC32XX_CLKPWR_I2SCTRL_I2S1_TX_FOR_RX _BIT(5)
#define LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA _BIT(4)
#define LPC32XX_CLKPWR_I2SCTRL_I2S0_RX_FOR_TX _BIT(3)
#define LPC32XX_CLKPWR_I2SCTRL_I2S0_TX_FOR_RX _BIT(2)
#define LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN _BIT(1)
#define LPC32XX_CLKPWR_I2SCTRL_I2SCLK0_EN _BIT(0)
/*
* clkpwr_ms_ctrl register definitions
*/
#define LPC32XX_CLKPWR_MSCARD_MSDIO_PIN_DIS _BIT(10)
#define LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN _BIT(9)
#define LPC32XX_CLKPWR_MSCARD_MSDIO23_DIS _BIT(8)
#define LPC32XX_CLKPWR_MSCARD_MSDIO1_DIS _BIT(7)
#define LPC32XX_CLKPWR_MSCARD_MSDIO0_DIS _BIT(6)
#define LPC32XX_CLKPWR_MSCARD_SDCARD_EN _BIT(5)
#define LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(n) ((n) & 0xF)
/*
* clkpwr_macclk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_MACCTRL_NO_ENET_PIS 0x00
#define LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS 0x08
#define LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS 0x18
#define LPC32XX_CLKPWR_MACCTRL_PINS_MSK 0x18
#define LPC32XX_CLKPWR_MACCTRL_DMACLK_EN _BIT(2)
#define LPC32XX_CLKPWR_MACCTRL_MMIOCLK_EN _BIT(1)
#define LPC32XX_CLKPWR_MACCTRL_HRCCLK_EN _BIT(0)
/*
* clkpwr_test_clk_sel register definitions
*/
#define LPC32XX_CLKPWR_TESTCLK1_SEL_PERCLK (0x0 << 5)
#define LPC32XX_CLKPWR_TESTCLK1_SEL_RTC (0x1 << 5)
#define LPC32XX_CLKPWR_TESTCLK1_SEL_MOSC (0x2 << 5)
#define LPC32XX_CLKPWR_TESTCLK1_SEL_MASK (0x3 << 5)
#define LPC32XX_CLKPWR_TESTCLK_TESTCLK1_EN _BIT(4)
#define LPC32XX_CLKPWR_TESTCLK2_SEL_HCLK (0x0 << 1)
#define LPC32XX_CLKPWR_TESTCLK2_SEL_PERCLK (0x1 << 1)
#define LPC32XX_CLKPWR_TESTCLK2_SEL_USBCLK (0x2 << 1)
#define LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC (0x5 << 1)
#define LPC32XX_CLKPWR_TESTCLK2_SEL_PLL397 (0x7 << 1)
#define LPC32XX_CLKPWR_TESTCLK2_SEL_MASK (0x7 << 1)
#define LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN _BIT(0)
/*
* clkpwr_sw_int register definitions
*/
#define LPC32XX_CLKPWR_SW_INT(n) (_BIT(0) | (((n) & 0x7F) << 1))
#define LPC32XX_CLKPWR_SW_GET_ARG(n) (((n) & 0xFE) >> 1)
/*
* clkpwr_i2c_clk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE _BIT(4)
#define LPC32XX_CLKPWR_I2CCLK_I2C2HI_DRIVE _BIT(3)
#define LPC32XX_CLKPWR_I2CCLK_I2C1HI_DRIVE _BIT(2)
#define LPC32XX_CLKPWR_I2CCLK_I2C2CLK_EN _BIT(1)
#define LPC32XX_CLKPWR_I2CCLK_I2C1CLK_EN _BIT(0)
/*
* clkpwr_key_clk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_KEYCLKCTRL_CLK_EN 0x1
/*
* clkpwr_adc_clk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN 0x1
/*
* clkpwr_pwm_clk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_PWMCLK_PWM2_DIV(n) (((n) & 0xF) << 8)
#define LPC32XX_CLKPWR_PWMCLK_PWM1_DIV(n) (((n) & 0xF) << 4)
#define LPC32XX_CLKPWR_PWMCLK_PWM2SEL_PCLK 0x8
#define LPC32XX_CLKPWR_PWMCLK_PWM2CLK_EN 0x4
#define LPC32XX_CLKPWR_PWMCLK_PWM1SEL_PCLK 0x2
#define LPC32XX_CLKPWR_PWMCLK_PWM1CLK_EN 0x1
/*
* clkpwr_timer_clk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_PWMCLK_HSTIMER_EN 0x2
#define LPC32XX_CLKPWR_PWMCLK_WDOG_EN 0x1
/*
* clkpwr_timers_pwms_clk_ctrl_1 register definitions
*/
#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN 0x20
#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER2_EN 0x10
#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN 0x08
#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN 0x04
#define LPC32XX_CLKPWR_TMRPWMCLK_PWM4_EN 0x02
#define LPC32XX_CLKPWR_TMRPWMCLK_PWM3_EN 0x01
/*
* clkpwr_spi_clk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_SPICLK_SET_SPI2DATIO 0x80
#define LPC32XX_CLKPWR_SPICLK_SET_SPI2CLK 0x40
#define LPC32XX_CLKPWR_SPICLK_USE_SPI2 0x20
#define LPC32XX_CLKPWR_SPICLK_SPI2CLK_EN 0x10
#define LPC32XX_CLKPWR_SPICLK_SET_SPI1DATIO 0x08
#define LPC32XX_CLKPWR_SPICLK_SET_SPI1CLK 0x04
#define LPC32XX_CLKPWR_SPICLK_USE_SPI1 0x02
#define LPC32XX_CLKPWR_SPICLK_SPI1CLK_EN 0x01
/*
* clkpwr_nand_clk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_NANDCLK_INTSEL_MLC 0x20
#define LPC32XX_CLKPWR_NANDCLK_DMA_RNB 0x10
#define LPC32XX_CLKPWR_NANDCLK_DMA_INT 0x08
#define LPC32XX_CLKPWR_NANDCLK_SEL_SLC 0x04
#define LPC32XX_CLKPWR_NANDCLK_MLCCLK_EN 0x02
#define LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN 0x01
/*
* clkpwr_uart3_clk_ctrl, clkpwr_uart4_clk_ctrl, clkpwr_uart5_clk_ctrl
* and clkpwr_uart6_clk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_UART_Y_DIV(y) ((y) & 0xFF)
#define LPC32XX_CLKPWR_UART_X_DIV(x) (((x) & 0xFF) << 8)
#define LPC32XX_CLKPWR_UART_USE_HCLK _BIT(16)
/*
* clkpwr_irda_clk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_IRDA_Y_DIV(y) ((y) & 0xFF)
#define LPC32XX_CLKPWR_IRDA_X_DIV(x) (((x) & 0xFF) << 8)
/*
* clkpwr_uart_clk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_UARTCLKCTRL_UART6_EN _BIT(3)
#define LPC32XX_CLKPWR_UARTCLKCTRL_UART5_EN _BIT(2)
#define LPC32XX_CLKPWR_UARTCLKCTRL_UART4_EN _BIT(1)
#define LPC32XX_CLKPWR_UARTCLKCTRL_UART3_EN _BIT(0)
/*
* clkpwr_dmaclk_ctrl register definitions
*/
#define LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN 0x1
/*
* clkpwr_autoclock register definitions
*/
#define LPC32XX_CLKPWR_AUTOCLK_USB_EN 0x40
#define LPC32XX_CLKPWR_AUTOCLK_IRAM_EN 0x02
#define LPC32XX_CLKPWR_AUTOCLK_IROM_EN 0x01
/*
* Interrupt controller register offsets
*/
#define LPC32XX_INTC_MASK(x) io_p2v((x) + 0x00)
#define LPC32XX_INTC_RAW_STAT(x) io_p2v((x) + 0x04)
#define LPC32XX_INTC_STAT(x) io_p2v((x) + 0x08)
#define LPC32XX_INTC_POLAR(x) io_p2v((x) + 0x0C)
#define LPC32XX_INTC_ACT_TYPE(x) io_p2v((x) + 0x10)
#define LPC32XX_INTC_TYPE(x) io_p2v((x) + 0x14)
/*
* Timer/counter register offsets
*/
#define LCP32XX_TIMER_IR(x) io_p2v((x) + 0x00)
#define LCP32XX_TIMER_TCR(x) io_p2v((x) + 0x04)
#define LCP32XX_TIMER_TC(x) io_p2v((x) + 0x08)
#define LCP32XX_TIMER_PR(x) io_p2v((x) + 0x0C)
#define LCP32XX_TIMER_PC(x) io_p2v((x) + 0x10)
#define LCP32XX_TIMER_MCR(x) io_p2v((x) + 0x14)
#define LCP32XX_TIMER_MR0(x) io_p2v((x) + 0x18)
#define LCP32XX_TIMER_MR1(x) io_p2v((x) + 0x1C)
#define LCP32XX_TIMER_MR2(x) io_p2v((x) + 0x20)
#define LCP32XX_TIMER_MR3(x) io_p2v((x) + 0x24)
#define LCP32XX_TIMER_CCR(x) io_p2v((x) + 0x28)
#define LCP32XX_TIMER_CR0(x) io_p2v((x) + 0x2C)
#define LCP32XX_TIMER_CR1(x) io_p2v((x) + 0x30)
#define LCP32XX_TIMER_CR2(x) io_p2v((x) + 0x34)
#define LCP32XX_TIMER_CR3(x) io_p2v((x) + 0x38)
#define LCP32XX_TIMER_EMR(x) io_p2v((x) + 0x3C)
#define LCP32XX_TIMER_CTCR(x) io_p2v((x) + 0x70)
/*
* ir register definitions
*/
#define LCP32XX_TIMER_CNTR_MTCH_BIT(n) (1 << ((n) & 0x3))
#define LCP32XX_TIMER_CNTR_CAPT_BIT(n) (1 << (4 + ((n) & 0x3)))
/*
* tcr register definitions
*/
#define LCP32XX_TIMER_CNTR_TCR_EN 0x1
#define LCP32XX_TIMER_CNTR_TCR_RESET 0x2
/*
* mcr register definitions
*/
#define LCP32XX_TIMER_CNTR_MCR_MTCH(n) (0x1 << ((n) * 3))
#define LCP32XX_TIMER_CNTR_MCR_RESET(n) (0x1 << (((n) * 3) + 1))
#define LCP32XX_TIMER_CNTR_MCR_STOP(n) (0x1 << (((n) * 3) + 2))
/*
* Standard UART register offsets
*/
#define LPC32XX_UART_DLL_FIFO(x) io_p2v((x) + 0x00)
#define LPC32XX_UART_DLM_IER(x) io_p2v((x) + 0x04)
#define LPC32XX_UART_IIR_FCR(x) io_p2v((x) + 0x08)
#define LPC32XX_UART_LCR(x) io_p2v((x) + 0x0C)
#define LPC32XX_UART_MODEM_CTRL(x) io_p2v((x) + 0x10)
#define LPC32XX_UART_LSR(x) io_p2v((x) + 0x14)
#define LPC32XX_UART_MODEM_STATUS(x) io_p2v((x) + 0x18)
#define LPC32XX_UART_RXLEV(x) io_p2v((x) + 0x1C)
/*
* UART control structure offsets
*/
#define _UCREG(x) io_p2v(\
LPC32XX_UART_CTRL_BASE + (x))
#define LPC32XX_UARTCTL_CTRL _UCREG(0x00)
#define LPC32XX_UARTCTL_CLKMODE _UCREG(0x04)
#define LPC32XX_UARTCTL_CLOOP _UCREG(0x08)
/*
* ctrl register definitions
*/
#define LPC32XX_UART_U3_MD_CTRL_EN _BIT(11)
#define LPC32XX_UART_IRRX6_INV_EN _BIT(10)
#define LPC32XX_UART_HDPX_EN _BIT(9)
#define LPC32XX_UART_UART6_IRDAMOD_BYPASS _BIT(5)
#define LPC32XX_RT_IRTX6_INV_EN _BIT(4)
#define LPC32XX_RT_IRTX6_INV_MIR_EN _BIT(3)
#define LPC32XX_RT_RX_IRPULSE_3_16_115K _BIT(2)
#define LPC32XX_RT_TX_IRPULSE_3_16_115K _BIT(1)
#define LPC32XX_UART_U5_ROUTE_TO_USB _BIT(0)
/*
* clkmode register definitions
*/
#define LPC32XX_UART_ENABLED_CLOCKS(n) (((n) >> 16) & 0x7F)
#define LPC32XX_UART_ENABLED_CLOCK(n, u) (((n) >> (16 + (u))) & 0x1)
#define LPC32XX_UART_ENABLED_CLKS_ANY _BIT(14)
#define LPC32XX_UART_CLKMODE_OFF 0x0
#define LPC32XX_UART_CLKMODE_ON 0x1
#define LPC32XX_UART_CLKMODE_AUTO 0x2
#define LPC32XX_UART_CLKMODE_MASK(u) (0x3 << ((((u) - 3) * 2) + 4))
#define LPC32XX_UART_CLKMODE_LOAD(m, u) ((m) << ((((u) - 3) * 2) + 4))
/*
* GPIO Module Register offsets
*/
#define _GPREG(x) io_p2v(LPC32XX_GPIO_BASE + (x))
#define LPC32XX_GPIO_P_MUX_SET _GPREG(0x100)
#define LPC32XX_GPIO_P_MUX_CLR _GPREG(0x104)
#define LPC32XX_GPIO_P_MUX_STATE _GPREG(0x108)
#define LPC32XX_GPIO_P3_MUX_SET _GPREG(0x110)
#define LPC32XX_GPIO_P3_MUX_CLR _GPREG(0x114)
#define LPC32XX_GPIO_P3_MUX_STATE _GPREG(0x118)
#define LPC32XX_GPIO_P0_MUX_SET _GPREG(0x120)
#define LPC32XX_GPIO_P0_MUX_CLR _GPREG(0x124)
#define LPC32XX_GPIO_P0_MUX_STATE _GPREG(0x128)
#define LPC32XX_GPIO_P1_MUX_SET _GPREG(0x130)
#define LPC32XX_GPIO_P1_MUX_CLR _GPREG(0x134)
#define LPC32XX_GPIO_P1_MUX_STATE _GPREG(0x138)
#endif
arch/arm/mach-lpc32xx/include/mach/system.h
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/include/mach/system.h
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARCH_SYSTEM_H
#define __ASM_ARCH_SYSTEM_H
static
void
arch_idle
(
void
)
{
cpu_do_idle
();
}
static
inline
void
arch_reset
(
char
mode
,
const
char
*
cmd
)
{
extern
void
lpc32xx_watchdog_reset
(
void
);
switch
(
mode
)
{
case
's'
:
case
'h'
:
printk
(
KERN_CRIT
"RESET: Rebooting system
\n
"
);
/* Disable interrupts */
local_irq_disable
();
lpc32xx_watchdog_reset
();
break
;
default:
/* Do nothing */
break
;
}
/* Wait for watchdog to reset system */
while
(
1
)
;
}
#endif
arch/arm/mach-lpc32xx/include/mach/timex.h
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/include/mach/timex.h
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARCH_TIMEX_H
#define __ASM_ARCH_TIMEX_H
/*
* Rate in Hz of the main system oscillator. This value should match
* the value 'MAIN_OSC_FREQ' in platform.h
*/
#define CLOCK_TICK_RATE 13000000
#endif
arch/arm/mach-lpc32xx/include/mach/uncompress.h
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/include/mach/uncompress.h
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARM_ARCH_UNCOMPRESS_H
#define __ASM_ARM_ARCH_UNCOMPRESS_H
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/platform.h>
/*
* Uncompress output is hardcoded to standard UART 5
*/
#define UART_FIFO_CTL_TX_RESET (1 << 2)
#define UART_STATUS_TX_MT (1 << 6)
#define _UARTREG(x) (void __iomem *)(LPC32XX_UART5_BASE + (x))
#define LPC32XX_UART_DLLFIFO_O 0x00
#define LPC32XX_UART_IIRFCR_O 0x08
#define LPC32XX_UART_LSR_O 0x14
static
inline
void
putc
(
int
ch
)
{
/* Wait for transmit FIFO to empty */
while
((
__raw_readl
(
_UARTREG
(
LPC32XX_UART_LSR_O
))
&
UART_STATUS_TX_MT
)
==
0
)
;
__raw_writel
((
u32
)
ch
,
_UARTREG
(
LPC32XX_UART_DLLFIFO_O
));
}
static
inline
void
flush
(
void
)
{
__raw_writel
(
__raw_readl
(
_UARTREG
(
LPC32XX_UART_IIRFCR_O
))
|
UART_FIFO_CTL_TX_RESET
,
_UARTREG
(
LPC32XX_UART_IIRFCR_O
));
}
/* NULL functions; we don't presently need them */
#define arch_decomp_setup()
#define arch_decomp_wdog()
#endif
arch/arm/mach-lpc32xx/include/mach/vmalloc.h
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/include/mach/vmalloc.h
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END 0xF0000000
#endif
arch/arm/mach-lpc32xx/irq.c
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/irq.c
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/err.h>
#include <linux/io.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/platform.h>
#include "common.h"
/*
* Default value representing the Activation polarity of all internal
* interrupt sources
*/
#define MIC_APR_DEFAULT 0x3FF0EFE0
#define SIC1_APR_DEFAULT 0xFBD27186
#define SIC2_APR_DEFAULT 0x801810C0
/*
* Default value representing the Activation Type of all internal
* interrupt sources. All are level sensitive.
*/
#define MIC_ATR_DEFAULT 0x00000000
#define SIC1_ATR_DEFAULT 0x00026000
#define SIC2_ATR_DEFAULT 0x00000000
struct
lpc32xx_event_group_regs
{
void
__iomem
*
enab_reg
;
void
__iomem
*
edge_reg
;
void
__iomem
*
maskstat_reg
;
void
__iomem
*
rawstat_reg
;
};
static
const
struct
lpc32xx_event_group_regs
lpc32xx_event_int_regs
=
{
.
enab_reg
=
LPC32XX_CLKPWR_INT_ER
,
.
edge_reg
=
LPC32XX_CLKPWR_INT_AP
,
.
maskstat_reg
=
LPC32XX_CLKPWR_INT_SR
,
.
rawstat_reg
=
LPC32XX_CLKPWR_INT_RS
,
};
static
const
struct
lpc32xx_event_group_regs
lpc32xx_event_pin_regs
=
{
.
enab_reg
=
LPC32XX_CLKPWR_PIN_ER
,
.
edge_reg
=
LPC32XX_CLKPWR_PIN_AP
,
.
maskstat_reg
=
LPC32XX_CLKPWR_PIN_SR
,
.
rawstat_reg
=
LPC32XX_CLKPWR_PIN_RS
,
};
struct
lpc32xx_event_info
{
const
struct
lpc32xx_event_group_regs
*
event_group
;
u32
mask
;
};
/*
* Maps an IRQ number to and event mask and register
*/
static
const
struct
lpc32xx_event_info
lpc32xx_events
[
NR_IRQS
]
=
{
[
IRQ_LPC32XX_GPI_08
]
=
{
.
event_group
=
&
lpc32xx_event_pin_regs
,
.
mask
=
LPC32XX_CLKPWR_EXTSRC_GPI_08_BIT
,
},
[
IRQ_LPC32XX_GPI_09
]
=
{
.
event_group
=
&
lpc32xx_event_pin_regs
,
.
mask
=
LPC32XX_CLKPWR_EXTSRC_GPI_09_BIT
,
},
[
IRQ_LPC32XX_GPI_19
]
=
{
.
event_group
=
&
lpc32xx_event_pin_regs
,
.
mask
=
LPC32XX_CLKPWR_EXTSRC_GPI_19_BIT
,
},
[
IRQ_LPC32XX_GPI_07
]
=
{
.
event_group
=
&
lpc32xx_event_pin_regs
,
.
mask
=
LPC32XX_CLKPWR_EXTSRC_GPI_07_BIT
,
},
[
IRQ_LPC32XX_GPI_00
]
=
{
.
event_group
=
&
lpc32xx_event_pin_regs
,
.
mask
=
LPC32XX_CLKPWR_EXTSRC_GPI_00_BIT
,
},
[
IRQ_LPC32XX_GPI_01
]
=
{
.
event_group
=
&
lpc32xx_event_pin_regs
,
.
mask
=
LPC32XX_CLKPWR_EXTSRC_GPI_01_BIT
,
},
[
IRQ_LPC32XX_GPI_02
]
=
{
.
event_group
=
&
lpc32xx_event_pin_regs
,
.
mask
=
LPC32XX_CLKPWR_EXTSRC_GPI_02_BIT
,
},
[
IRQ_LPC32XX_GPI_03
]
=
{
.
event_group
=
&
lpc32xx_event_pin_regs
,
.
mask
=
LPC32XX_CLKPWR_EXTSRC_GPI_03_BIT
,
},
[
IRQ_LPC32XX_GPI_04
]
=
{
.
event_group
=
&
lpc32xx_event_pin_regs
,
.
mask
=
LPC32XX_CLKPWR_EXTSRC_GPI_04_BIT
,
},
[
IRQ_LPC32XX_GPI_05
]
=
{
.
event_group
=
&
lpc32xx_event_pin_regs
,
.
mask
=
LPC32XX_CLKPWR_EXTSRC_GPI_05_BIT
,
},
[
IRQ_LPC32XX_GPI_06
]
=
{
.
event_group
=
&
lpc32xx_event_pin_regs
,
.
mask
=
LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT
,
},
[
IRQ_LPC32XX_GPIO_00
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT
,
},
[
IRQ_LPC32XX_GPIO_01
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_GPIO_01_BIT
,
},
[
IRQ_LPC32XX_GPIO_02
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_GPIO_02_BIT
,
},
[
IRQ_LPC32XX_GPIO_03
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_GPIO_03_BIT
,
},
[
IRQ_LPC32XX_GPIO_04
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_GPIO_04_BIT
,
},
[
IRQ_LPC32XX_GPIO_05
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_GPIO_05_BIT
,
},
[
IRQ_LPC32XX_KEY
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_KEY_BIT
,
},
[
IRQ_LPC32XX_USB_OTG_ATX
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT
,
},
[
IRQ_LPC32XX_USB_HOST
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_USB_BIT
,
},
[
IRQ_LPC32XX_RTC
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_RTC_BIT
,
},
[
IRQ_LPC32XX_MSTIMER
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT
,
},
[
IRQ_LPC32XX_TS_AUX
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_TS_AUX_BIT
,
},
[
IRQ_LPC32XX_TS_P
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_TS_P_BIT
,
},
[
IRQ_LPC32XX_TS_IRQ
]
=
{
.
event_group
=
&
lpc32xx_event_int_regs
,
.
mask
=
LPC32XX_CLKPWR_INTSRC_ADC_BIT
,
},
};
static
void
get_controller
(
unsigned
int
irq
,
unsigned
int
*
base
,
unsigned
int
*
irqbit
)
{
if
(
irq
<
32
)
{
*
base
=
LPC32XX_MIC_BASE
;
*
irqbit
=
1
<<
irq
;
}
else
if
(
irq
<
64
)
{
*
base
=
LPC32XX_SIC1_BASE
;
*
irqbit
=
1
<<
(
irq
-
32
);
}
else
{
*
base
=
LPC32XX_SIC2_BASE
;
*
irqbit
=
1
<<
(
irq
-
64
);
}
}
static
void
lpc32xx_mask_irq
(
unsigned
int
irq
)
{
unsigned
int
reg
,
ctrl
,
mask
;
get_controller
(
irq
,
&
ctrl
,
&
mask
);
reg
=
__raw_readl
(
LPC32XX_INTC_MASK
(
ctrl
))
&
~
mask
;
__raw_writel
(
reg
,
LPC32XX_INTC_MASK
(
ctrl
));
}
static
void
lpc32xx_unmask_irq
(
unsigned
int
irq
)
{
unsigned
int
reg
,
ctrl
,
mask
;
get_controller
(
irq
,
&
ctrl
,
&
mask
);
reg
=
__raw_readl
(
LPC32XX_INTC_MASK
(
ctrl
))
|
mask
;
__raw_writel
(
reg
,
LPC32XX_INTC_MASK
(
ctrl
));
}
static
void
lpc32xx_ack_irq
(
unsigned
int
irq
)
{
unsigned
int
ctrl
,
mask
;
get_controller
(
irq
,
&
ctrl
,
&
mask
);
__raw_writel
(
mask
,
LPC32XX_INTC_RAW_STAT
(
ctrl
));
/* Also need to clear pending wake event */
if
(
lpc32xx_events
[
irq
].
mask
!=
0
)
__raw_writel
(
lpc32xx_events
[
irq
].
mask
,
lpc32xx_events
[
irq
].
event_group
->
rawstat_reg
);
}
static
void
__lpc32xx_set_irq_type
(
unsigned
int
irq
,
int
use_high_level
,
int
use_edge
)
{
unsigned
int
reg
,
ctrl
,
mask
;
get_controller
(
irq
,
&
ctrl
,
&
mask
);
/* Activation level, high or low */
reg
=
__raw_readl
(
LPC32XX_INTC_POLAR
(
ctrl
));
if
(
use_high_level
)
reg
|=
mask
;
else
reg
&=
~
mask
;
__raw_writel
(
reg
,
LPC32XX_INTC_POLAR
(
ctrl
));
/* Activation type, edge or level */
reg
=
__raw_readl
(
LPC32XX_INTC_ACT_TYPE
(
ctrl
));
if
(
use_edge
)
reg
|=
mask
;
else
reg
&=
~
mask
;
__raw_writel
(
reg
,
LPC32XX_INTC_ACT_TYPE
(
ctrl
));
/* Use same polarity for the wake events */
if
(
lpc32xx_events
[
irq
].
mask
!=
0
)
{
reg
=
__raw_readl
(
lpc32xx_events
[
irq
].
event_group
->
edge_reg
);
if
(
use_high_level
)
reg
|=
lpc32xx_events
[
irq
].
mask
;
else
reg
&=
~
lpc32xx_events
[
irq
].
mask
;
__raw_writel
(
reg
,
lpc32xx_events
[
irq
].
event_group
->
edge_reg
);
}
}
static
int
lpc32xx_set_irq_type
(
unsigned
int
irq
,
unsigned
int
type
)
{
switch
(
type
)
{
case
IRQ_TYPE_EDGE_RISING
:
/* Rising edge sensitive */
__lpc32xx_set_irq_type
(
irq
,
1
,
1
);
break
;
case
IRQ_TYPE_EDGE_FALLING
:
/* Falling edge sensitive */
__lpc32xx_set_irq_type
(
irq
,
0
,
1
);
break
;
case
IRQ_TYPE_LEVEL_LOW
:
/* Low level sensitive */
__lpc32xx_set_irq_type
(
irq
,
0
,
0
);
break
;
case
IRQ_TYPE_LEVEL_HIGH
:
/* High level sensitive */
__lpc32xx_set_irq_type
(
irq
,
1
,
0
);
break
;
/* Other modes are not supported */
default:
return
-
EINVAL
;
}
/* Ok to use the level handler for all types */
set_irq_handler
(
irq
,
handle_level_irq
);
return
0
;
}
static
int
lpc32xx_irq_wake
(
unsigned
int
irqno
,
unsigned
int
state
)
{
unsigned
long
eventreg
;
if
(
lpc32xx_events
[
irqno
].
mask
!=
0
)
{
eventreg
=
__raw_readl
(
lpc32xx_events
[
irqno
].
event_group
->
enab_reg
);
if
(
state
)
eventreg
|=
lpc32xx_events
[
irqno
].
mask
;
else
eventreg
&=
~
lpc32xx_events
[
irqno
].
mask
;
__raw_writel
(
eventreg
,
lpc32xx_events
[
irqno
].
event_group
->
enab_reg
);
return
0
;
}
/* Clear event */
__raw_writel
(
lpc32xx_events
[
irqno
].
mask
,
lpc32xx_events
[
irqno
].
event_group
->
rawstat_reg
);
return
-
ENODEV
;
}
static
void
__init
lpc32xx_set_default_mappings
(
unsigned
int
apr
,
unsigned
int
atr
,
unsigned
int
offset
)
{
unsigned
int
i
;
/* Set activation levels for each interrupt */
i
=
0
;
while
(
i
<
32
)
{
__lpc32xx_set_irq_type
(
offset
+
i
,
((
apr
>>
i
)
&
0x1
),
((
atr
>>
i
)
&
0x1
));
i
++
;
}
}
static
struct
irq_chip
lpc32xx_irq_chip
=
{
.
ack
=
lpc32xx_ack_irq
,
.
mask
=
lpc32xx_mask_irq
,
.
unmask
=
lpc32xx_unmask_irq
,
.
set_type
=
lpc32xx_set_irq_type
,
.
set_wake
=
lpc32xx_irq_wake
};
static
void
lpc32xx_sic1_handler
(
unsigned
int
irq
,
struct
irq_desc
*
desc
)
{
unsigned
long
ints
=
__raw_readl
(
LPC32XX_INTC_STAT
(
LPC32XX_SIC1_BASE
));
while
(
ints
!=
0
)
{
int
irqno
=
fls
(
ints
)
-
1
;
ints
&=
~
(
1
<<
irqno
);
generic_handle_irq
(
LPC32XX_SIC1_IRQ
(
irqno
));
}
}
static
void
lpc32xx_sic2_handler
(
unsigned
int
irq
,
struct
irq_desc
*
desc
)
{
unsigned
long
ints
=
__raw_readl
(
LPC32XX_INTC_STAT
(
LPC32XX_SIC2_BASE
));
while
(
ints
!=
0
)
{
int
irqno
=
fls
(
ints
)
-
1
;
ints
&=
~
(
1
<<
irqno
);
generic_handle_irq
(
LPC32XX_SIC2_IRQ
(
irqno
));
}
}
void
__init
lpc32xx_init_irq
(
void
)
{
unsigned
int
i
;
/* Setup MIC */
__raw_writel
(
0
,
LPC32XX_INTC_MASK
(
LPC32XX_MIC_BASE
));
__raw_writel
(
MIC_APR_DEFAULT
,
LPC32XX_INTC_POLAR
(
LPC32XX_MIC_BASE
));
__raw_writel
(
MIC_ATR_DEFAULT
,
LPC32XX_INTC_ACT_TYPE
(
LPC32XX_MIC_BASE
));
/* Setup SIC1 */
__raw_writel
(
0
,
LPC32XX_INTC_MASK
(
LPC32XX_SIC1_BASE
));
__raw_writel
(
MIC_APR_DEFAULT
,
LPC32XX_INTC_POLAR
(
LPC32XX_SIC1_BASE
));
__raw_writel
(
MIC_ATR_DEFAULT
,
LPC32XX_INTC_ACT_TYPE
(
LPC32XX_SIC1_BASE
));
/* Setup SIC2 */
__raw_writel
(
0
,
LPC32XX_INTC_MASK
(
LPC32XX_SIC2_BASE
));
__raw_writel
(
MIC_APR_DEFAULT
,
LPC32XX_INTC_POLAR
(
LPC32XX_SIC2_BASE
));
__raw_writel
(
MIC_ATR_DEFAULT
,
LPC32XX_INTC_ACT_TYPE
(
LPC32XX_SIC2_BASE
));
/* Configure supported IRQ's */
for
(
i
=
0
;
i
<
NR_IRQS
;
i
++
)
{
set_irq_chip
(
i
,
&
lpc32xx_irq_chip
);
set_irq_handler
(
i
,
handle_level_irq
);
set_irq_flags
(
i
,
IRQF_VALID
);
}
/* Set default mappings */
lpc32xx_set_default_mappings
(
MIC_APR_DEFAULT
,
MIC_ATR_DEFAULT
,
0
);
lpc32xx_set_default_mappings
(
SIC1_APR_DEFAULT
,
SIC1_ATR_DEFAULT
,
32
);
lpc32xx_set_default_mappings
(
SIC2_APR_DEFAULT
,
SIC2_ATR_DEFAULT
,
64
);
/* mask all interrupts except SUBIRQ */
__raw_writel
(
0
,
LPC32XX_INTC_MASK
(
LPC32XX_MIC_BASE
));
__raw_writel
(
0
,
LPC32XX_INTC_MASK
(
LPC32XX_SIC1_BASE
));
__raw_writel
(
0
,
LPC32XX_INTC_MASK
(
LPC32XX_SIC2_BASE
));
/* MIC SUBIRQx interrupts will route handling to the chain handlers */
set_irq_chained_handler
(
IRQ_LPC32XX_SUB1IRQ
,
lpc32xx_sic1_handler
);
set_irq_chained_handler
(
IRQ_LPC32XX_SUB2IRQ
,
lpc32xx_sic2_handler
);
/* Initially disable all wake events */
__raw_writel
(
0
,
LPC32XX_CLKPWR_P01_ER
);
__raw_writel
(
0
,
LPC32XX_CLKPWR_INT_ER
);
__raw_writel
(
0
,
LPC32XX_CLKPWR_PIN_ER
);
/*
* Default wake activation polarities, all pin sources are low edge
* triggered
*/
__raw_writel
(
LPC32XX_CLKPWR_INTSRC_TS_P_BIT
|
LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT
|
LPC32XX_CLKPWR_INTSRC_RTC_BIT
,
LPC32XX_CLKPWR_INT_AP
);
__raw_writel
(
0
,
LPC32XX_CLKPWR_PIN_AP
);
/* Clear latched wake event states */
__raw_writel
(
__raw_readl
(
LPC32XX_CLKPWR_PIN_RS
),
LPC32XX_CLKPWR_PIN_RS
);
__raw_writel
(
__raw_readl
(
LPC32XX_CLKPWR_INT_RS
),
LPC32XX_CLKPWR_INT_RS
);
}
arch/arm/mach-lpc32xx/phy3250.c
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/phy3250.c
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/sysdev.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <linux/amba/pl022.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/hardware.h>
#include <mach/platform.h>
#include "common.h"
/*
* Mapped GPIOLIB GPIOs
*/
#define SPI0_CS_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5)
#define LCD_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 0)
#define BKL_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4)
#define LED_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 1)
/*
* AMBA LCD controller
*/
static
struct
clcd_panel
conn_lcd_panel
=
{
.
mode
=
{
.
name
=
"QVGA portrait"
,
.
refresh
=
60
,
.
xres
=
240
,
.
yres
=
320
,
.
pixclock
=
191828
,
.
left_margin
=
22
,
.
right_margin
=
11
,
.
upper_margin
=
2
,
.
lower_margin
=
1
,
.
hsync_len
=
5
,
.
vsync_len
=
2
,
.
sync
=
0
,
.
vmode
=
FB_VMODE_NONINTERLACED
,
},
.
width
=
-
1
,
.
height
=
-
1
,
.
tim2
=
(
TIM2_IVS
|
TIM2_IHS
),
.
cntl
=
(
CNTL_BGR
|
CNTL_LCDTFT
|
CNTL_LCDVCOMP
(
1
)
|
CNTL_LCDBPP16_565
),
.
bpp
=
16
,
};
#define PANEL_SIZE (3 * SZ_64K)
static
int
lpc32xx_clcd_setup
(
struct
clcd_fb
*
fb
)
{
dma_addr_t
dma
;
fb
->
fb
.
screen_base
=
dma_alloc_writecombine
(
&
fb
->
dev
->
dev
,
PANEL_SIZE
,
&
dma
,
GFP_KERNEL
);
if
(
!
fb
->
fb
.
screen_base
)
{
printk
(
KERN_ERR
"CLCD: unable to map framebuffer
\n
"
);
return
-
ENOMEM
;
}
fb
->
fb
.
fix
.
smem_start
=
dma
;
fb
->
fb
.
fix
.
smem_len
=
PANEL_SIZE
;
fb
->
panel
=
&
conn_lcd_panel
;
if
(
gpio_request
(
LCD_POWER_GPIO
,
"LCD power"
))
printk
(
KERN_ERR
"Error requesting gpio %u"
,
LCD_POWER_GPIO
);
else
if
(
gpio_direction_output
(
LCD_POWER_GPIO
,
1
))
printk
(
KERN_ERR
"Error setting gpio %u to output"
,
LCD_POWER_GPIO
);
if
(
gpio_request
(
BKL_POWER_GPIO
,
"LCD backlight power"
))
printk
(
KERN_ERR
"Error requesting gpio %u"
,
BKL_POWER_GPIO
);
else
if
(
gpio_direction_output
(
BKL_POWER_GPIO
,
1
))
printk
(
KERN_ERR
"Error setting gpio %u to output"
,
BKL_POWER_GPIO
);
return
0
;
}
static
int
lpc32xx_clcd_mmap
(
struct
clcd_fb
*
fb
,
struct
vm_area_struct
*
vma
)
{
return
dma_mmap_writecombine
(
&
fb
->
dev
->
dev
,
vma
,
fb
->
fb
.
screen_base
,
fb
->
fb
.
fix
.
smem_start
,
fb
->
fb
.
fix
.
smem_len
);
}
static
void
lpc32xx_clcd_remove
(
struct
clcd_fb
*
fb
)
{
dma_free_writecombine
(
&
fb
->
dev
->
dev
,
fb
->
fb
.
fix
.
smem_len
,
fb
->
fb
.
screen_base
,
fb
->
fb
.
fix
.
smem_start
);
}
/*
* On some early LCD modules (1307.0), the backlight logic is inverted.
* For those board variants, swap the disable and enable states for
* BKL_POWER_GPIO.
*/
static
void
clcd_disable
(
struct
clcd_fb
*
fb
)
{
gpio_set_value
(
BKL_POWER_GPIO
,
0
);
gpio_set_value
(
LCD_POWER_GPIO
,
0
);
}
static
void
clcd_enable
(
struct
clcd_fb
*
fb
)
{
gpio_set_value
(
BKL_POWER_GPIO
,
1
);
gpio_set_value
(
LCD_POWER_GPIO
,
1
);
}
static
struct
clcd_board
lpc32xx_clcd_data
=
{
.
name
=
"Phytec LCD"
,
.
check
=
clcdfb_check
,
.
decode
=
clcdfb_decode
,
.
disable
=
clcd_disable
,
.
enable
=
clcd_enable
,
.
setup
=
lpc32xx_clcd_setup
,
.
mmap
=
lpc32xx_clcd_mmap
,
.
remove
=
lpc32xx_clcd_remove
,
};
static
struct
amba_device
lpc32xx_clcd_device
=
{
.
dev
=
{
.
coherent_dma_mask
=
~
0
,
.
init_name
=
"dev:clcd"
,
.
platform_data
=
&
lpc32xx_clcd_data
,
},
.
res
=
{
.
start
=
LPC32XX_LCD_BASE
,
.
end
=
(
LPC32XX_LCD_BASE
+
SZ_4K
-
1
),
.
flags
=
IORESOURCE_MEM
,
},
.
dma_mask
=
~
0
,
.
irq
=
{
IRQ_LPC32XX_LCD
,
NO_IRQ
},
};
/*
* AMBA SSP (SPI)
*/
static
void
phy3250_spi_cs_set
(
u32
control
)
{
gpio_set_value
(
SPI0_CS_GPIO
,
(
int
)
control
);
}
static
struct
pl022_config_chip
spi0_chip_info
=
{
.
lbm
=
LOOPBACK_DISABLED
,
.
com_mode
=
INTERRUPT_TRANSFER
,
.
iface
=
SSP_INTERFACE_MOTOROLA_SPI
,
.
hierarchy
=
SSP_MASTER
,
.
slave_tx_disable
=
0
,
.
endian_tx
=
SSP_TX_LSB
,
.
endian_rx
=
SSP_RX_LSB
,
.
data_size
=
SSP_DATA_BITS_8
,
.
rx_lev_trig
=
SSP_RX_4_OR_MORE_ELEM
,
.
tx_lev_trig
=
SSP_TX_4_OR_MORE_EMPTY_LOC
,
.
clk_phase
=
SSP_CLK_FIRST_EDGE
,
.
clk_pol
=
SSP_CLK_POL_IDLE_LOW
,
.
ctrl_len
=
SSP_BITS_8
,
.
wait_state
=
SSP_MWIRE_WAIT_ZERO
,
.
duplex
=
SSP_MICROWIRE_CHANNEL_FULL_DUPLEX
,
.
cs_control
=
phy3250_spi_cs_set
,
};
static
struct
pl022_ssp_controller
lpc32xx_ssp0_data
=
{
.
bus_id
=
0
,
.
num_chipselect
=
1
,
.
enable_dma
=
0
,
};
static
struct
amba_device
lpc32xx_ssp0_device
=
{
.
dev
=
{
.
coherent_dma_mask
=
~
0
,
.
init_name
=
"dev:ssp0"
,
.
platform_data
=
&
lpc32xx_ssp0_data
,
},
.
res
=
{
.
start
=
LPC32XX_SSP0_BASE
,
.
end
=
(
LPC32XX_SSP0_BASE
+
SZ_4K
-
1
),
.
flags
=
IORESOURCE_MEM
,
},
.
dma_mask
=
~
0
,
.
irq
=
{
IRQ_LPC32XX_SSP0
,
NO_IRQ
},
};
/* AT25 driver registration */
static
int
__init
phy3250_spi_board_register
(
void
)
{
#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
static
struct
spi_board_info
info
[]
=
{
{
.
modalias
=
"spidev"
,
.
max_speed_hz
=
5000000
,
.
bus_num
=
0
,
.
chip_select
=
0
,
.
controller_data
=
&
spi0_chip_info
,
},
};
#else
static
struct
spi_eeprom
eeprom
=
{
.
name
=
"at25256a"
,
.
byte_len
=
0x8000
,
.
page_size
=
64
,
.
flags
=
EE_ADDR2
,
};
static
struct
spi_board_info
info
[]
=
{
{
.
modalias
=
"at25"
,
.
max_speed_hz
=
5000000
,
.
bus_num
=
0
,
.
chip_select
=
0
,
.
platform_data
=
&
eeprom
,
.
controller_data
=
&
spi0_chip_info
,
},
};
#endif
return
spi_register_board_info
(
info
,
ARRAY_SIZE
(
info
));
}
arch_initcall
(
phy3250_spi_board_register
);
static
struct
i2c_board_info
__initdata
phy3250_i2c_board_info
[]
=
{
{
I2C_BOARD_INFO
(
"pcf8563"
,
0x51
),
},
};
static
struct
gpio_led
phy_leds
[]
=
{
{
.
name
=
"led0"
,
.
gpio
=
LED_GPIO
,
.
active_low
=
1
,
.
default_trigger
=
"heartbeat"
,
},
};
static
struct
gpio_led_platform_data
led_data
=
{
.
leds
=
phy_leds
,
.
num_leds
=
ARRAY_SIZE
(
phy_leds
),
};
static
struct
platform_device
lpc32xx_gpio_led_device
=
{
.
name
=
"leds-gpio"
,
.
id
=
-
1
,
.
dev
.
platform_data
=
&
led_data
,
};
static
struct
platform_device
*
phy3250_devs
[]
__initdata
=
{
&
lpc32xx_i2c0_device
,
&
lpc32xx_i2c1_device
,
&
lpc32xx_i2c2_device
,
&
lpc32xx_watchdog_device
,
&
lpc32xx_gpio_led_device
,
};
static
struct
amba_device
*
amba_devs
[]
__initdata
=
{
&
lpc32xx_clcd_device
,
&
lpc32xx_ssp0_device
,
};
/*
* Board specific functions
*/
static
void
__init
phy3250_board_init
(
void
)
{
u32
tmp
;
int
i
;
lpc32xx_gpio_init
();
/* Register GPIOs used on this board */
if
(
gpio_request
(
SPI0_CS_GPIO
,
"spi0 cs"
))
printk
(
KERN_ERR
"Error requesting gpio %u"
,
SPI0_CS_GPIO
);
else
if
(
gpio_direction_output
(
SPI0_CS_GPIO
,
1
))
printk
(
KERN_ERR
"Error setting gpio %u to output"
,
SPI0_CS_GPIO
);
/* Setup network interface for RMII mode */
tmp
=
__raw_readl
(
LPC32XX_CLKPWR_MACCLK_CTRL
);
tmp
&=
~
LPC32XX_CLKPWR_MACCTRL_PINS_MSK
;
tmp
|=
LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS
;
__raw_writel
(
tmp
,
LPC32XX_CLKPWR_MACCLK_CTRL
);
/* Setup SLC NAND controller muxing */
__raw_writel
(
LPC32XX_CLKPWR_NANDCLK_SEL_SLC
,
LPC32XX_CLKPWR_NAND_CLK_CTRL
);
/* Setup LCD muxing to RGB565 */
tmp
=
__raw_readl
(
LPC32XX_CLKPWR_LCDCLK_CTRL
)
&
~
(
LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_MSK
|
LPC32XX_CLKPWR_LCDCTRL_PSCALE_MSK
);
tmp
|=
LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16
;
__raw_writel
(
tmp
,
LPC32XX_CLKPWR_LCDCLK_CTRL
);
/* Set up I2C pull levels */
tmp
=
__raw_readl
(
LPC32XX_CLKPWR_I2C_CLK_CTRL
);
tmp
|=
LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE
|
LPC32XX_CLKPWR_I2CCLK_I2C2HI_DRIVE
;
__raw_writel
(
tmp
,
LPC32XX_CLKPWR_I2C_CLK_CTRL
);
/* Disable IrDA pulsing support on UART6 */
tmp
=
__raw_readl
(
LPC32XX_UARTCTL_CTRL
);
tmp
|=
LPC32XX_UART_UART6_IRDAMOD_BYPASS
;
__raw_writel
(
tmp
,
LPC32XX_UARTCTL_CTRL
);
/* Enable DMA for I2S1 channel */
tmp
=
__raw_readl
(
LPC32XX_CLKPWR_I2S_CLK_CTRL
);
tmp
=
LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA
;
__raw_writel
(
tmp
,
LPC32XX_CLKPWR_I2S_CLK_CTRL
);
lpc32xx_serial_init
();
/*
* AMBA peripheral clocks need to be enabled prior to AMBA device
* detection or a data fault will occur, so enable the clocks
* here. However, we don't want to enable them if the peripheral
* isn't included in the image
*/
#ifdef CONFIG_FB_ARMCLCD
tmp
=
__raw_readl
(
LPC32XX_CLKPWR_LCDCLK_CTRL
);
__raw_writel
((
tmp
|
LPC32XX_CLKPWR_LCDCTRL_CLK_EN
),
LPC32XX_CLKPWR_LCDCLK_CTRL
);
#endif
#ifdef CONFIG_SPI_PL022
tmp
=
__raw_readl
(
LPC32XX_CLKPWR_SSP_CLK_CTRL
);
__raw_writel
((
tmp
|
LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN
),
LPC32XX_CLKPWR_SSP_CLK_CTRL
);
#endif
platform_add_devices
(
phy3250_devs
,
ARRAY_SIZE
(
phy3250_devs
));
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
amba_devs
);
i
++
)
{
struct
amba_device
*
d
=
amba_devs
[
i
];
amba_device_register
(
d
,
&
iomem_resource
);
}
/* Test clock needed for UDA1380 initial init */
__raw_writel
(
LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC
|
LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN
,
LPC32XX_CLKPWR_TEST_CLK_SEL
);
i2c_register_board_info
(
0
,
phy3250_i2c_board_info
,
ARRAY_SIZE
(
phy3250_i2c_board_info
));
}
static
int
__init
lpc32xx_display_uid
(
void
)
{
u32
uid
[
4
];
lpc32xx_get_uid
(
uid
);
printk
(
KERN_INFO
"LPC32XX unique ID: %08x%08x%08x%08x
\n
"
,
uid
[
3
],
uid
[
2
],
uid
[
1
],
uid
[
0
]);
return
1
;
}
arch_initcall
(
lpc32xx_display_uid
);
MACHINE_START
(
PHY3250
,
"Phytec 3250 board with the LPC3250 Microcontroller"
)
/* Maintainer: Kevin Wells, NXP Semiconductors */
.
phys_io
=
LPC32XX_UART5_BASE
,
.
io_pg_offst
=
((
IO_ADDRESS
(
LPC32XX_UART5_BASE
))
>>
18
)
&
0xfffc
,
.
boot_params
=
0x80000100
,
.
map_io
=
lpc32xx_map_io
,
.
init_irq
=
lpc32xx_init_irq
,
.
timer
=
&
lpc32xx_timer
,
.
init_machine
=
phy3250_board_init
,
MACHINE_END
arch/arm/mach-lpc32xx/pm.c
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/pm.c
*
* Original authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
* Modified by Kevin Wells <kevin.wells@nxp.com>
*
* 2005 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
/*
* LPC32XX CPU and system power management
*
* The LCP32XX has three CPU modes for controlling system power: run,
* direct-run, and halt modes. When switching between halt and run modes,
* the CPU transistions through direct-run mode. For Linux, direct-run
* mode is not used in normal operation. Halt mode is used when the
* system is fully suspended.
*
* Run mode:
* The ARM CPU clock (HCLK_PLL), HCLK bus clock, and PCLK bus clocks are
* derived from the HCLK PLL. The HCLK and PCLK bus rates are divided from
* the HCLK_PLL rate. Linux runs in this mode.
*
* Direct-run mode:
* The ARM CPU clock, HCLK bus clock, and PCLK bus clocks are driven from
* SYSCLK. SYSCLK is usually around 13MHz, but may vary based on SYSCLK
* source or the frequency of the main oscillator. In this mode, the
* HCLK_PLL can be safely enabled, changed, or disabled.
*
* Halt mode:
* SYSCLK is gated off and the CPU and system clocks are halted.
* Peripherals based on the 32KHz oscillator clock (ie, RTC, touch,
* key scanner, etc.) still operate if enabled. In this state, an enabled
* system event (ie, GPIO state change, RTC match, key press, etc.) will
* wake the system up back into direct-run mode.
*
* DRAM refresh
* DRAM clocking and refresh are slightly different for systems with DDR
* DRAM or regular SDRAM devices. If SDRAM is used in the system, the
* SDRAM will still be accessible in direct-run mode. In DDR based systems,
* a transistion to direct-run mode will stop all DDR accesses (no clocks).
* Because of this, the code to switch power modes and the code to enter
* and exit DRAM self-refresh modes must not be executed in DRAM. A small
* section of IRAM is used instead for this.
*
* Suspend is handled with the following logic:
* Backup a small area of IRAM used for the suspend code
* Copy suspend code to IRAM
* Transfer control to code in IRAM
* Places DRAMs in self-refresh mode
* Enter direct-run mode
* Save state of HCLK_PLL PLL
* Disable HCLK_PLL PLL
* Enter halt mode - CPU and buses will stop
* System enters direct-run mode when an enabled event occurs
* HCLK PLL state is restored
* Run mode is entered
* DRAMS are placed back into normal mode
* Code execution returns from IRAM
* IRAM code are used for suspend is restored
* Suspend mode is exited
*/
#include <linux/suspend.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <asm/cacheflush.h>
#include <mach/hardware.h>
#include <mach/platform.h>
#include "common.h"
#include "clock.h"
#define TEMP_IRAM_AREA IO_ADDRESS(LPC32XX_IRAM_BASE)
/*
* Both STANDBY and MEM suspend states are handled the same with no
* loss of CPU or memory state
*/
static
int
lpc32xx_pm_enter
(
suspend_state_t
state
)
{
int
(
*
lpc32xx_suspend_ptr
)
(
void
);
void
*
iram_swap_area
;
/* Allocate some space for temporary IRAM storage */
iram_swap_area
=
kmalloc
(
lpc32xx_sys_suspend_sz
,
GFP_KERNEL
);
if
(
!
iram_swap_area
)
{
printk
(
KERN_ERR
"PM Suspend: cannot allocate memory to save portion "
"of SRAM
\n
"
);
return
-
ENOMEM
;
}
/* Backup a small area of IRAM used for the suspend code */
memcpy
(
iram_swap_area
,
(
void
*
)
TEMP_IRAM_AREA
,
lpc32xx_sys_suspend_sz
);
/*
* Copy code to suspend system into IRAM. The suspend code
* needs to run from IRAM as DRAM may no longer be available
* when the PLL is stopped.
*/
memcpy
((
void
*
)
TEMP_IRAM_AREA
,
&
lpc32xx_sys_suspend
,
lpc32xx_sys_suspend_sz
);
flush_icache_range
((
unsigned
long
)
TEMP_IRAM_AREA
,
(
unsigned
long
)(
TEMP_IRAM_AREA
)
+
lpc32xx_sys_suspend_sz
);
/* Transfer to suspend code in IRAM */
lpc32xx_suspend_ptr
=
(
void
*
)
TEMP_IRAM_AREA
;
flush_cache_all
();
(
void
)
lpc32xx_suspend_ptr
();
/* Restore original IRAM contents */
memcpy
((
void
*
)
TEMP_IRAM_AREA
,
iram_swap_area
,
lpc32xx_sys_suspend_sz
);
kfree
(
iram_swap_area
);
return
0
;
}
static
struct
platform_suspend_ops
lpc32xx_pm_ops
=
{
.
valid
=
suspend_valid_only_mem
,
.
enter
=
lpc32xx_pm_enter
,
};
#define EMC_DYN_MEM_CTRL_OFS 0x20
#define EMC_SRMMC (1 << 3)
#define EMC_CTRL_REG io_p2v(LPC32XX_EMC_BASE + EMC_DYN_MEM_CTRL_OFS)
static
int
__init
lpc32xx_pm_init
(
void
)
{
/*
* Setup SDRAM self-refresh clock to automatically disable o
* start of self-refresh. This only needs to be done once.
*/
__raw_writel
(
__raw_readl
(
EMC_CTRL_REG
)
|
EMC_SRMMC
,
EMC_CTRL_REG
);
suspend_set_ops
(
&
lpc32xx_pm_ops
);
return
0
;
}
arch_initcall
(
lpc32xx_pm_init
);
arch/arm/mach-lpc32xx/serial.c
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/serial.c
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <linux/serial_8250.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/platform.h>
#include "common.h"
#define LPC32XX_SUART_FIFO_SIZE 64
/* Standard 8250/16550 compatible serial ports */
static
struct
plat_serial8250_port
serial_std_platform_data
[]
=
{
#ifdef CONFIG_ARCH_LPC32XX_UART5_SELECT
{
.
membase
=
io_p2v
(
LPC32XX_UART5_BASE
),
.
mapbase
=
LPC32XX_UART5_BASE
,
.
irq
=
IRQ_LPC32XX_UART_IIR5
,
.
uartclk
=
LPC32XX_MAIN_OSC_FREQ
,
.
regshift
=
2
,
.
iotype
=
UPIO_MEM32
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_BUGGY_UART
|
UPF_SKIP_TEST
,
},
#endif
#ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT
{
.
membase
=
io_p2v
(
LPC32XX_UART3_BASE
),
.
mapbase
=
LPC32XX_UART3_BASE
,
.
irq
=
IRQ_LPC32XX_UART_IIR3
,
.
uartclk
=
LPC32XX_MAIN_OSC_FREQ
,
.
regshift
=
2
,
.
iotype
=
UPIO_MEM32
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_BUGGY_UART
|
UPF_SKIP_TEST
,
},
#endif
#ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT
{
.
membase
=
io_p2v
(
LPC32XX_UART4_BASE
),
.
mapbase
=
LPC32XX_UART4_BASE
,
.
irq
=
IRQ_LPC32XX_UART_IIR4
,
.
uartclk
=
LPC32XX_MAIN_OSC_FREQ
,
.
regshift
=
2
,
.
iotype
=
UPIO_MEM32
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_BUGGY_UART
|
UPF_SKIP_TEST
,
},
#endif
#ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT
{
.
membase
=
io_p2v
(
LPC32XX_UART6_BASE
),
.
mapbase
=
LPC32XX_UART6_BASE
,
.
irq
=
IRQ_LPC32XX_UART_IIR6
,
.
uartclk
=
LPC32XX_MAIN_OSC_FREQ
,
.
regshift
=
2
,
.
iotype
=
UPIO_MEM32
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_BUGGY_UART
|
UPF_SKIP_TEST
,
},
#endif
{
},
};
struct
uartinit
{
char
*
uart_ck_name
;
u32
ck_mode_mask
;
void
__iomem
*
pdiv_clk_reg
;
};
static
struct
uartinit
uartinit_data
[]
__initdata
=
{
#ifdef CONFIG_ARCH_LPC32XX_UART5_SELECT
{
.
uart_ck_name
=
"uart5_ck"
,
.
ck_mode_mask
=
LPC32XX_UART_CLKMODE_LOAD
(
LPC32XX_UART_CLKMODE_ON
,
5
),
.
pdiv_clk_reg
=
LPC32XX_CLKPWR_UART5_CLK_CTRL
,
},
#endif
#ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT
{
.
uart_ck_name
=
"uart3_ck"
,
.
ck_mode_mask
=
LPC32XX_UART_CLKMODE_LOAD
(
LPC32XX_UART_CLKMODE_ON
,
3
),
.
pdiv_clk_reg
=
LPC32XX_CLKPWR_UART3_CLK_CTRL
,
},
#endif
#ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT
{
.
uart_ck_name
=
"uart4_ck"
,
.
ck_mode_mask
=
LPC32XX_UART_CLKMODE_LOAD
(
LPC32XX_UART_CLKMODE_ON
,
4
),
.
pdiv_clk_reg
=
LPC32XX_CLKPWR_UART4_CLK_CTRL
,
},
#endif
#ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT
{
.
uart_ck_name
=
"uart6_ck"
,
.
ck_mode_mask
=
LPC32XX_UART_CLKMODE_LOAD
(
LPC32XX_UART_CLKMODE_ON
,
6
),
.
pdiv_clk_reg
=
LPC32XX_CLKPWR_UART6_CLK_CTRL
,
},
#endif
};
static
struct
platform_device
serial_std_platform_device
=
{
.
name
=
"serial8250"
,
.
id
=
0
,
.
dev
=
{
.
platform_data
=
serial_std_platform_data
,
},
};
static
struct
platform_device
*
lpc32xx_serial_devs
[]
__initdata
=
{
&
serial_std_platform_device
,
};
void
__init
lpc32xx_serial_init
(
void
)
{
u32
tmp
,
clkmodes
=
0
;
struct
clk
*
clk
;
unsigned
int
puart
;
int
i
,
j
;
/* UART clocks are off, let clock driver manage them */
__raw_writel
(
0
,
LPC32XX_CLKPWR_UART_CLK_CTRL
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
uartinit_data
);
i
++
)
{
clk
=
clk_get
(
NULL
,
uartinit_data
[
i
].
uart_ck_name
);
if
(
!
IS_ERR
(
clk
))
{
clk_enable
(
clk
);
serial_std_platform_data
[
i
].
uartclk
=
clk_get_rate
(
clk
);
}
/* Fall back on main osc rate if clock rate return fails */
if
(
serial_std_platform_data
[
i
].
uartclk
==
0
)
serial_std_platform_data
[
i
].
uartclk
=
LPC32XX_MAIN_OSC_FREQ
;
/* Setup UART clock modes for all UARTs, disable autoclock */
clkmodes
|=
uartinit_data
[
i
].
ck_mode_mask
;
/* pre-UART clock divider set to 1 */
__raw_writel
(
0x0101
,
uartinit_data
[
i
].
pdiv_clk_reg
);
}
/* This needs to be done after all UART clocks are setup */
__raw_writel
(
clkmodes
,
LPC32XX_UARTCTL_CLKMODE
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
uartinit_data
)
-
1
;
i
++
)
{
/* Force a flush of the RX FIFOs to work around a HW bug */
puart
=
serial_std_platform_data
[
i
].
mapbase
;
__raw_writel
(
0xC1
,
LPC32XX_UART_IIR_FCR
(
puart
));
__raw_writel
(
0x00
,
LPC32XX_UART_DLL_FIFO
(
puart
));
j
=
LPC32XX_SUART_FIFO_SIZE
;
while
(
j
--
)
tmp
=
__raw_readl
(
LPC32XX_UART_DLL_FIFO
(
puart
));
__raw_writel
(
0
,
LPC32XX_UART_IIR_FCR
(
puart
));
}
/* Disable UART5->USB transparent mode or USB won't work */
tmp
=
__raw_readl
(
LPC32XX_UARTCTL_CTRL
);
tmp
&=
~
LPC32XX_UART_U5_ROUTE_TO_USB
;
__raw_writel
(
tmp
,
LPC32XX_UARTCTL_CTRL
);
platform_add_devices
(
lpc32xx_serial_devs
,
ARRAY_SIZE
(
lpc32xx_serial_devs
));
}
arch/arm/mach-lpc32xx/suspend.S
0 → 100644
View file @
cccf59ab
/*
*
arch
/
arm
/
mach
-
lpc32xx
/
suspend
.
S
*
*
Original
authors
:
Dmitry
Chigirev
,
Vitaly
Wool
<
source
@
mvista
.
com
>
*
Modified
by
Kevin
Wells
<
kevin
.
wells
@
nxp
.
com
>
*
*
2005
(
c
)
MontaVista
Software
,
Inc
.
This
file
is
licensed
under
*
the
terms
of
the
GNU
General
Public
License
version
2
.
This
program
*
is
licensed
"as is"
without
any
warranty
of
any
kind
,
whether
express
*
or
implied
.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <mach/platform.h>
#include <mach/hardware.h>
/*
Using
named
register
defines
makes
the
code
easier
to
follow
*/
#define WORK1_REG r0
#define WORK2_REG r1
#define SAVED_HCLK_DIV_REG r2
#define SAVED_HCLK_PLL_REG r3
#define SAVED_DRAM_CLKCTRL_REG r4
#define SAVED_PWR_CTRL_REG r5
#define CLKPWRBASE_REG r6
#define EMCBASE_REG r7
#define LPC32XX_EMC_STATUS_OFFS 0x04
#define LPC32XX_EMC_STATUS_BUSY 0x1
#define LPC32XX_EMC_STATUS_SELF_RFSH 0x4
#define LPC32XX_CLKPWR_PWR_CTRL_OFFS 0x44
#define LPC32XX_CLKPWR_HCLK_DIV_OFFS 0x40
#define LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS 0x58
#define CLKPWR_PCLK_DIV_MASK 0xFFFFFE7F
.
text
ENTRY
(
lpc32xx_sys_suspend
)
@
Save
a
copy
of
the
used
registers
in
IRAM
,
r0
is
corrupted
adr
r0
,
tmp_stack_end
stmfd
r0
!,
{
r3
-
r7
,
sp
,
lr
}
@
Load
a
few
common
register
addresses
adr
WORK1_REG
,
reg_bases
ldr
CLKPWRBASE_REG
,
[
WORK1_REG
,
#
0
]
ldr
EMCBASE_REG
,
[
WORK1_REG
,
#
4
]
ldr
SAVED_PWR_CTRL_REG
,
[
CLKPWRBASE_REG
,
\
#
LPC32XX_CLKPWR_PWR_CTRL_OFFS
]
orr
WORK1_REG
,
SAVED_PWR_CTRL_REG
,
#
LPC32XX_CLKPWR_SDRAM_SELF_RFSH
@
Wait
for
SDRAM
busy
status
to
go
busy
and
then
idle
@
This
guarantees
a
small
windows
where
DRAM
isn
't busy
1
:
ldr
WORK2_REG
,
[
EMCBASE_REG
,
#
LPC32XX_EMC_STATUS_OFFS
]
and
WORK2_REG
,
WORK2_REG
,
#
LPC32XX_EMC_STATUS_BUSY
cmp
WORK2_REG
,
#
LPC32XX_EMC_STATUS_BUSY
bne
1
b
@
Branch
while
idle
2
:
ldr
WORK2_REG
,
[
EMCBASE_REG
,
#
LPC32XX_EMC_STATUS_OFFS
]
and
WORK2_REG
,
WORK2_REG
,
#
LPC32XX_EMC_STATUS_BUSY
cmp
WORK2_REG
,
#
LPC32XX_EMC_STATUS_BUSY
beq
2
b
@
Branch
until
idle
@
Setup
self
-
refresh
with
support
for
manual
exit
of
@
self
-
refresh
mode
str
WORK1_REG
,
[
CLKPWRBASE_REG
,
#
LPC32XX_CLKPWR_PWR_CTRL_OFFS
]
orr
WORK2_REG
,
WORK1_REG
,
#
LPC32XX_CLKPWR_UPD_SDRAM_SELF_RFSH
str
WORK2_REG
,
[
CLKPWRBASE_REG
,
#
LPC32XX_CLKPWR_PWR_CTRL_OFFS
]
str
WORK1_REG
,
[
CLKPWRBASE_REG
,
#
LPC32XX_CLKPWR_PWR_CTRL_OFFS
]
@
Wait
for
self
-
refresh
acknowledge
,
clocks
to
the
DRAM
device
@
will
automatically
stop
on
start
of
self
-
refresh
3
:
ldr
WORK2_REG
,
[
EMCBASE_REG
,
#
LPC32XX_EMC_STATUS_OFFS
]
and
WORK2_REG
,
WORK2_REG
,
#
LPC32XX_EMC_STATUS_SELF_RFSH
cmp
WORK2_REG
,
#
LPC32XX_EMC_STATUS_SELF_RFSH
bne
3
b
@
Branch
until
self
-
refresh
mode
starts
@
Enter
direct
-
run
mode
from
run
mode
bic
WORK1_REG
,
WORK1_REG
,
#
LPC32XX_CLKPWR_SELECT_RUN_MODE
str
WORK1_REG
,
[
CLKPWRBASE_REG
,
#
LPC32XX_CLKPWR_PWR_CTRL_OFFS
]
@
Safe
disable
of
DRAM
clock
in
EMC
block
,
prevents
DDR
sync
@
issues
on
restart
ldr
SAVED_HCLK_DIV_REG
,
[
CLKPWRBASE_REG
,
\
#
LPC32XX_CLKPWR_HCLK_DIV_OFFS
]
and
WORK2_REG
,
SAVED_HCLK_DIV_REG
,
#
CLKPWR_PCLK_DIV_MASK
str
WORK2_REG
,
[
CLKPWRBASE_REG
,
#
LPC32XX_CLKPWR_HCLK_DIV_OFFS
]
@
Save
HCLK
PLL
state
and
disable
HCLK
PLL
ldr
SAVED_HCLK_PLL_REG
,
[
CLKPWRBASE_REG
,
\
#
LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS
]
bic
WORK2_REG
,
SAVED_HCLK_PLL_REG
,
#
LPC32XX_CLKPWR_HCLKPLL_POWER_UP
str
WORK2_REG
,
[
CLKPWRBASE_REG
,
#
LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS
]
@
Enter
stop
mode
until
an
enabled
event
occurs
orr
WORK1_REG
,
WORK1_REG
,
#
LPC32XX_CLKPWR_STOP_MODE_CTRL
str
WORK1_REG
,
[
CLKPWRBASE_REG
,
#
LPC32XX_CLKPWR_PWR_CTRL_OFFS
]
.
rept
9
nop
.
endr
@
Clear
stop
status
bic
WORK1_REG
,
WORK1_REG
,
#
LPC32XX_CLKPWR_STOP_MODE_CTRL
@
Restore
original
HCLK
PLL
value
and
wait
for
PLL
lock
str
SAVED_HCLK_PLL_REG
,
[
CLKPWRBASE_REG
,
\
#
LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS
]
4
:
ldr
WORK2_REG
,
[
CLKPWRBASE_REG
,
#
LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS
]
and
WORK2_REG
,
WORK2_REG
,
#
LPC32XX_CLKPWR_HCLKPLL_PLL_STS
bne
4
b
@
Re
-
enter
run
mode
with
self
-
refresh
flag
cleared
,
but
no
DRAM
@
update
yet
.
DRAM
is
still
in
self
-
refresh
str
SAVED_PWR_CTRL_REG
,
[
CLKPWRBASE_REG
,
\
#
LPC32XX_CLKPWR_PWR_CTRL_OFFS
]
@
Restore
original
DRAM
clock
mode
to
restore
DRAM
clocks
str
SAVED_HCLK_DIV_REG
,
[
CLKPWRBASE_REG
,
\
#
LPC32XX_CLKPWR_HCLK_DIV_OFFS
]
@
Clear
self
-
refresh
mode
orr
WORK1_REG
,
SAVED_PWR_CTRL_REG
,
\
#
LPC32XX_CLKPWR_UPD_SDRAM_SELF_RFSH
str
WORK1_REG
,
[
CLKPWRBASE_REG
,
#
LPC32XX_CLKPWR_PWR_CTRL_OFFS
]
str
SAVED_PWR_CTRL_REG
,
[
CLKPWRBASE_REG
,
\
#
LPC32XX_CLKPWR_PWR_CTRL_OFFS
]
@
Wait
for
EMC
to
clear
self
-
refresh
mode
5
:
ldr
WORK2_REG
,
[
EMCBASE_REG
,
#
LPC32XX_EMC_STATUS_OFFS
]
and
WORK2_REG
,
WORK2_REG
,
#
LPC32XX_EMC_STATUS_SELF_RFSH
bne
5
b
@
Branch
until
self
-
refresh
has
exited
@
restore
regs
and
return
adr
r0
,
tmp_stack
ldmfd
r0
!,
{
r3
-
r7
,
sp
,
pc
}
reg_bases
:
.
long
IO_ADDRESS
(
LPC32XX_CLK_PM_BASE
)
.
long
IO_ADDRESS
(
LPC32XX_EMC_BASE
)
tmp_stack
:
.
long
0
,
0
,
0
,
0
,
0
,
0
,
0
tmp_stack_end
:
ENTRY
(
lpc32xx_sys_suspend_sz
)
.
word
.
-
lpc32xx_sys_suspend
arch/arm/mach-lpc32xx/timer.c
0 → 100644
View file @
cccf59ab
/*
* arch/arm/mach-lpc32xx/timer.c
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2009 - 2010 NXP Semiconductors
* Copyright (C) 2009 Fontys University of Applied Sciences, Eindhoven
* Ed Schouten <e.schouten@fontys.nl>
* Laurens Timmermans <l.timmermans@fontys.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/time.h>
#include <linux/err.h>
#include <linux/clockchips.h>
#include <asm/mach/time.h>
#include <mach/hardware.h>
#include <mach/platform.h>
#include "common.h"
static
cycle_t
lpc32xx_clksrc_read
(
struct
clocksource
*
cs
)
{
return
(
cycle_t
)
__raw_readl
(
LCP32XX_TIMER_TC
(
LPC32XX_TIMER1_BASE
));
}
static
struct
clocksource
lpc32xx_clksrc
=
{
.
name
=
"lpc32xx_clksrc"
,
.
shift
=
24
,
.
rating
=
300
,
.
read
=
lpc32xx_clksrc_read
,
.
mask
=
CLOCKSOURCE_MASK
(
32
),
.
flags
=
CLOCK_SOURCE_IS_CONTINUOUS
,
};
static
int
lpc32xx_clkevt_next_event
(
unsigned
long
delta
,
struct
clock_event_device
*
dev
)
{
__raw_writel
(
LCP32XX_TIMER_CNTR_TCR_RESET
,
LCP32XX_TIMER_TCR
(
LPC32XX_TIMER0_BASE
));
__raw_writel
(
delta
,
LCP32XX_TIMER_PR
(
LPC32XX_TIMER0_BASE
));
__raw_writel
(
LCP32XX_TIMER_CNTR_TCR_EN
,
LCP32XX_TIMER_TCR
(
LPC32XX_TIMER0_BASE
));
return
0
;
}
static
void
lpc32xx_clkevt_mode
(
enum
clock_event_mode
mode
,
struct
clock_event_device
*
dev
)
{
switch
(
mode
)
{
case
CLOCK_EVT_MODE_PERIODIC
:
WARN_ON
(
1
);
break
;
case
CLOCK_EVT_MODE_ONESHOT
:
case
CLOCK_EVT_MODE_SHUTDOWN
:
/*
* Disable the timer. When using oneshot, we must also
* disable the timer to wait for the first call to
* set_next_event().
*/
__raw_writel
(
0
,
LCP32XX_TIMER_TCR
(
LPC32XX_TIMER0_BASE
));
break
;
case
CLOCK_EVT_MODE_UNUSED
:
case
CLOCK_EVT_MODE_RESUME
:
break
;
}
}
static
struct
clock_event_device
lpc32xx_clkevt
=
{
.
name
=
"lpc32xx_clkevt"
,
.
features
=
CLOCK_EVT_FEAT_ONESHOT
,
.
shift
=
32
,
.
rating
=
300
,
.
set_next_event
=
lpc32xx_clkevt_next_event
,
.
set_mode
=
lpc32xx_clkevt_mode
,
};
static
irqreturn_t
lpc32xx_timer_interrupt
(
int
irq
,
void
*
dev_id
)
{
struct
clock_event_device
*
evt
=
&
lpc32xx_clkevt
;
/* Clear match */
__raw_writel
(
LCP32XX_TIMER_CNTR_MTCH_BIT
(
0
),
LCP32XX_TIMER_IR
(
LPC32XX_TIMER0_BASE
));
evt
->
event_handler
(
evt
);
return
IRQ_HANDLED
;
}
static
struct
irqaction
lpc32xx_timer_irq
=
{
.
name
=
"LPC32XX Timer Tick"
,
.
flags
=
IRQF_DISABLED
|
IRQF_TIMER
|
IRQF_IRQPOLL
,
.
handler
=
lpc32xx_timer_interrupt
,
};
/*
* The clock management driver isn't initialized at this point, so the
* clocks need to be enabled here manually and then tagged as used in
* the clock driver initialization
*/
static
void
__init
lpc32xx_timer_init
(
void
)
{
u32
clkrate
,
pllreg
;
/* Enable timer clock */
__raw_writel
(
LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN
|
LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN
,
LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1
);
/*
* The clock driver isn't initialized at this point. So determine if
* the SYSCLK is driven from the PLL397 or main oscillator and then use
* it to compute the PLL frequency and the PCLK divider to get the base
* timer rates. This rate is needed to compute the tick rate.
*/
if
(
clk_is_sysclk_mainosc
()
!=
0
)
clkrate
=
LPC32XX_MAIN_OSC_FREQ
;
else
clkrate
=
397
*
LPC32XX_CLOCK_OSC_FREQ
;
/* Get ARM HCLKPLL register and convert it into a frequency */
pllreg
=
__raw_readl
(
LPC32XX_CLKPWR_HCLKPLL_CTRL
)
&
0x1FFFF
;
clkrate
=
clk_get_pllrate_from_reg
(
clkrate
,
pllreg
);
/* Get PCLK divider and divide ARM PLL clock by it to get timer rate */
clkrate
=
clkrate
/
clk_get_pclk_div
();
/* Initial timer setup */
__raw_writel
(
0
,
LCP32XX_TIMER_TCR
(
LPC32XX_TIMER0_BASE
));
__raw_writel
(
LCP32XX_TIMER_CNTR_MTCH_BIT
(
0
),
LCP32XX_TIMER_IR
(
LPC32XX_TIMER0_BASE
));
__raw_writel
(
1
,
LCP32XX_TIMER_MR0
(
LPC32XX_TIMER0_BASE
));
__raw_writel
(
LCP32XX_TIMER_CNTR_MCR_MTCH
(
0
)
|
LCP32XX_TIMER_CNTR_MCR_STOP
(
0
)
|
LCP32XX_TIMER_CNTR_MCR_RESET
(
0
),
LCP32XX_TIMER_MCR
(
LPC32XX_TIMER0_BASE
));
/* Setup tick interrupt */
setup_irq
(
IRQ_LPC32XX_TIMER0
,
&
lpc32xx_timer_irq
);
/* Setup the clockevent structure. */
lpc32xx_clkevt
.
mult
=
div_sc
(
clkrate
,
NSEC_PER_SEC
,
lpc32xx_clkevt
.
shift
);
lpc32xx_clkevt
.
max_delta_ns
=
clockevent_delta2ns
(
-
1
,
&
lpc32xx_clkevt
);
lpc32xx_clkevt
.
min_delta_ns
=
clockevent_delta2ns
(
1
,
&
lpc32xx_clkevt
)
+
1
;
lpc32xx_clkevt
.
cpumask
=
cpumask_of
(
0
);
clockevents_register_device
(
&
lpc32xx_clkevt
);
/* Use timer1 as clock source. */
__raw_writel
(
LCP32XX_TIMER_CNTR_TCR_RESET
,
LCP32XX_TIMER_TCR
(
LPC32XX_TIMER1_BASE
));
__raw_writel
(
0
,
LCP32XX_TIMER_PR
(
LPC32XX_TIMER1_BASE
));
__raw_writel
(
0
,
LCP32XX_TIMER_MCR
(
LPC32XX_TIMER1_BASE
));
__raw_writel
(
LCP32XX_TIMER_CNTR_TCR_EN
,
LCP32XX_TIMER_TCR
(
LPC32XX_TIMER1_BASE
));
lpc32xx_clksrc
.
mult
=
clocksource_hz2mult
(
clkrate
,
lpc32xx_clksrc
.
shift
);
clocksource_register
(
&
lpc32xx_clksrc
);
}
struct
sys_timer
lpc32xx_timer
=
{
.
init
=
&
lpc32xx_timer_init
,
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment