Merge branch 'test' of ../test/linux-2.6-lpc2 into wells/lpc32xx-arch_v2

This commit is contained in:
Kevin Wells 2010-07-28 03:38:52 -07:00
commit cccf59abea
30 changed files with 4827 additions and 0 deletions

View file

@ -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"

View file

@ -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

View file

@ -0,0 +1,33 @@
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

View file

@ -0,0 +1,8 @@
#
# 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

View file

@ -0,0 +1,4 @@
zreladdr-y := 0x80008000
params_phys-y := 0x80000100
initrd_phys-y := 0x82000000

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,38 @@
/*
* 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

View file

@ -0,0 +1,271 @@
/*
* 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));
}

View file

@ -0,0 +1,73 @@
/*
* 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

View file

@ -0,0 +1,446 @@
/*
* 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);
}

View file

@ -0,0 +1,25 @@
/*
* 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

View file

@ -0,0 +1,31 @@
/*
* 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>

View file

@ -0,0 +1,47 @@
/*
* 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

View file

@ -0,0 +1,74 @@
/*
* 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

View file

@ -0,0 +1,34 @@
/*
* 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

View file

@ -0,0 +1,63 @@
/*
* 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 */

View file

@ -0,0 +1,27 @@
/*
* 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

View file

@ -0,0 +1,117 @@
/*
* 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

View file

@ -0,0 +1,27 @@
/*
* 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

View file

@ -0,0 +1,694 @@
/*
* 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

View file

@ -0,0 +1,52 @@
/*
* 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

View file

@ -0,0 +1,28 @@
/*
* 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

View file

@ -0,0 +1,60 @@
/*
* 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

View file

@ -0,0 +1,24 @@
/*
* 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

432
arch/arm/mach-lpc32xx/irq.c Normal file
View file

@ -0,0 +1,432 @@
/*
* 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);
}

View file

@ -0,0 +1,397 @@
/*
* 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

146
arch/arm/mach-lpc32xx/pm.c Normal file
View file

@ -0,0 +1,146 @@
/*
* 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);

View file

@ -0,0 +1,190 @@
/*
* 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));
}

View file

@ -0,0 +1,151 @@
/*
* 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 1b @ 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 2b @ 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 3b @ 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 4b
@ 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 5b @ 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

View file

@ -0,0 +1,182 @@
/*
* 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,
};