Merge branch 'nomadik' into devel-stable
This commit is contained in:
commit
7010381449
|
@ -338,6 +338,20 @@ config ARCH_H720X
|
|||
help
|
||||
This enables support for systems based on the Hynix HMS720x
|
||||
|
||||
config ARCH_NOMADIK
|
||||
bool "STMicroelectronics Nomadik"
|
||||
select ARM_AMBA
|
||||
select ARM_VIC
|
||||
select CPU_ARM926T
|
||||
select HAVE_CLK
|
||||
select COMMON_CLKDEV
|
||||
select GENERIC_TIME
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_GPIO
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
help
|
||||
Support for the Nomadik platform by ST-Ericsson
|
||||
|
||||
config ARCH_IOP13XX
|
||||
bool "IOP13xx-based"
|
||||
depends on MMU
|
||||
|
@ -745,6 +759,8 @@ source "arch/arm/mach-at91/Kconfig"
|
|||
|
||||
source "arch/arm/plat-mxc/Kconfig"
|
||||
|
||||
source "arch/arm/mach-nomadik/Kconfig"
|
||||
|
||||
source "arch/arm/mach-netx/Kconfig"
|
||||
|
||||
source "arch/arm/mach-ns9xxx/Kconfig"
|
||||
|
|
|
@ -145,6 +145,7 @@ machine-$(CONFIG_ARCH_MX2) := mx2
|
|||
machine-$(CONFIG_ARCH_MX25) := mx25
|
||||
machine-$(CONFIG_ARCH_MX3) := mx3
|
||||
machine-$(CONFIG_ARCH_NETX) := netx
|
||||
machine-$(CONFIG_ARCH_NOMADIK) := nomadik
|
||||
machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
|
||||
machine-$(CONFIG_ARCH_OMAP1) := omap1
|
||||
machine-$(CONFIG_ARCH_OMAP2) := omap2
|
||||
|
|
|
@ -26,6 +26,15 @@
|
|||
#include <asm/mach/irq.h>
|
||||
#include <asm/hardware/vic.h>
|
||||
|
||||
static void vic_ack_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *base = get_irq_chip_data(irq);
|
||||
irq &= 31;
|
||||
writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
|
||||
/* moreover, clear the soft-triggered, in case it was the reason */
|
||||
writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
|
||||
}
|
||||
|
||||
static void vic_mask_irq(unsigned int irq)
|
||||
{
|
||||
void __iomem *base = get_irq_chip_data(irq);
|
||||
|
@ -253,12 +262,21 @@ static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg
|
|||
|
||||
static struct irq_chip vic_chip = {
|
||||
.name = "VIC",
|
||||
.ack = vic_mask_irq,
|
||||
.ack = vic_ack_irq,
|
||||
.mask = vic_mask_irq,
|
||||
.unmask = vic_unmask_irq,
|
||||
.set_wake = vic_set_wake,
|
||||
};
|
||||
|
||||
/* The PL190 cell from ARM has been modified by ST, so handle both here */
|
||||
static void vik_init_st(void __iomem *base, unsigned int irq_start,
|
||||
u32 vic_sources);
|
||||
|
||||
enum vic_vendor {
|
||||
VENDOR_ARM = 0x41,
|
||||
VENDOR_ST = 0x80,
|
||||
};
|
||||
|
||||
/**
|
||||
* vic_init - initialise a vectored interrupt controller
|
||||
* @base: iomem base address
|
||||
|
@ -270,6 +288,28 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
|
|||
u32 vic_sources, u32 resume_sources)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 cellid = 0;
|
||||
enum vic_vendor vendor;
|
||||
|
||||
/* Identify which VIC cell this one is, by reading the ID */
|
||||
for (i = 0; i < 4; i++) {
|
||||
u32 addr = ((u32)base & PAGE_MASK) + 0xfe0 + (i * 4);
|
||||
cellid |= (readl(addr) & 0xff) << (8 * i);
|
||||
}
|
||||
vendor = (cellid >> 12) & 0xff;
|
||||
printk(KERN_INFO "VIC @%p: id 0x%08x, vendor 0x%02x\n",
|
||||
base, cellid, vendor);
|
||||
|
||||
switch(vendor) {
|
||||
case VENDOR_ST:
|
||||
vik_init_st(base, irq_start, vic_sources);
|
||||
return;
|
||||
default:
|
||||
printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
|
||||
/* fall through */
|
||||
case VENDOR_ARM:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Disable all interrupts initially. */
|
||||
|
||||
|
@ -306,3 +346,60 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
|
|||
|
||||
vic_pm_register(base, irq_start, resume_sources);
|
||||
}
|
||||
|
||||
/*
|
||||
* The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
|
||||
* The original cell has 32 interrupts, while the modified one has 64,
|
||||
* replocating two blocks 0x00..0x1f in 0x20..0x3f. In that case
|
||||
* the probe function is called twice, with base set to offset 000
|
||||
* and 020 within the page. We call this "second block".
|
||||
*/
|
||||
static void __init vik_init_st(void __iomem *base, unsigned int irq_start,
|
||||
u32 vic_sources)
|
||||
{
|
||||
unsigned int i;
|
||||
int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0;
|
||||
|
||||
/* Disable all interrupts initially. */
|
||||
|
||||
writel(0, base + VIC_INT_SELECT);
|
||||
writel(0, base + VIC_INT_ENABLE);
|
||||
writel(~0, base + VIC_INT_ENABLE_CLEAR);
|
||||
writel(0, base + VIC_IRQ_STATUS);
|
||||
writel(0, base + VIC_ITCR);
|
||||
writel(~0, base + VIC_INT_SOFT_CLEAR);
|
||||
|
||||
/*
|
||||
* Make sure we clear all existing interrupts. The vector registers
|
||||
* in this cell are after the second block of general registers,
|
||||
* so we can address them using standard offsets, but only from
|
||||
* the second base address, which is 0x20 in the page
|
||||
*/
|
||||
if (vic_2nd_block) {
|
||||
writel(0, base + VIC_PL190_VECT_ADDR);
|
||||
for (i = 0; i < 19; i++) {
|
||||
unsigned int value;
|
||||
|
||||
value = readl(base + VIC_PL190_VECT_ADDR);
|
||||
writel(value, base + VIC_PL190_VECT_ADDR);
|
||||
}
|
||||
/* ST has 16 vectors as well, but we don't enable them by now */
|
||||
for (i = 0; i < 16; i++) {
|
||||
void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
|
||||
writel(0, reg);
|
||||
}
|
||||
|
||||
writel(32, base + VIC_PL190_DEF_VECT_ADDR);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (vic_sources & (1 << i)) {
|
||||
unsigned int irq = irq_start + i;
|
||||
|
||||
set_irq_chip(irq, &vic_chip);
|
||||
set_irq_chip_data(irq, base);
|
||||
set_irq_handler(irq, handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
1316
arch/arm/configs/nhk8815_defconfig
Normal file
1316
arch/arm/configs/nhk8815_defconfig
Normal file
File diff suppressed because it is too large
Load diff
21
arch/arm/mach-nomadik/Kconfig
Normal file
21
arch/arm/mach-nomadik/Kconfig
Normal file
|
@ -0,0 +1,21 @@
|
|||
if ARCH_NOMADIK
|
||||
|
||||
menu "Nomadik boards"
|
||||
|
||||
config MACH_NOMADIK_8815NHK
|
||||
bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
|
||||
select NOMADIK_8815
|
||||
|
||||
endmenu
|
||||
|
||||
config NOMADIK_8815
|
||||
bool
|
||||
|
||||
|
||||
config I2C_BITBANG_8815NHK
|
||||
tristate "Driver for bit-bang busses found on the 8815 NHK"
|
||||
depends on I2C && MACH_NOMADIK_8815NHK
|
||||
select I2C_ALGOBIT
|
||||
default y
|
||||
|
||||
endif
|
19
arch/arm/mach-nomadik/Makefile
Normal file
19
arch/arm/mach-nomadik/Makefile
Normal file
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
# Note! Dependencies are done automagically by 'make dep', which also
|
||||
# removes any old dependencies. DON'T put your own dependencies here
|
||||
# unless it's something special (ie not a .c file).
|
||||
|
||||
# Object file lists.
|
||||
|
||||
obj-y += clock.o timer.o gpio.o
|
||||
|
||||
# Cpu revision
|
||||
obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o
|
||||
|
||||
# Specific board support
|
||||
obj-$(CONFIG_MACH_NOMADIK_8815NHK) += board-nhk8815.o
|
||||
|
||||
# Nomadik extra devices
|
||||
obj-$(CONFIG_I2C_BITBANG_8815NHK) += i2c-8815nhk.o
|
4
arch/arm/mach-nomadik/Makefile.boot
Normal file
4
arch/arm/mach-nomadik/Makefile.boot
Normal file
|
@ -0,0 +1,4 @@
|
|||
zreladdr-y := 0x00008000
|
||||
params_phys-y := 0x00000100
|
||||
initrd_phys-y := 0x00800000
|
||||
|
111
arch/arm/mach-nomadik/board-nhk8815.c
Normal file
111
arch/arm/mach-nomadik/board-nhk8815.c
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-nomadik/board-8815nhk.c
|
||||
*
|
||||
* Copyright (C) STMicroelectronics
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* NHK15 board specifc driver definition
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/amba/bus.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <mach/setup.h>
|
||||
#include "clock.h"
|
||||
|
||||
#define __MEM_4K_RESOURCE(x) \
|
||||
.res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
|
||||
|
||||
static struct amba_device uart0_device = {
|
||||
.dev = { .init_name = "uart0" },
|
||||
__MEM_4K_RESOURCE(NOMADIK_UART0_BASE),
|
||||
.irq = {IRQ_UART0, NO_IRQ},
|
||||
};
|
||||
|
||||
static struct amba_device uart1_device = {
|
||||
.dev = { .init_name = "uart1" },
|
||||
__MEM_4K_RESOURCE(NOMADIK_UART1_BASE),
|
||||
.irq = {IRQ_UART1, NO_IRQ},
|
||||
};
|
||||
|
||||
static struct amba_device *amba_devs[] __initdata = {
|
||||
&uart0_device,
|
||||
&uart1_device,
|
||||
};
|
||||
|
||||
/* We have a fixed clock alone, by now */
|
||||
static struct clk nhk8815_clk_48 = {
|
||||
.rate = 48*1000*1000,
|
||||
};
|
||||
|
||||
static struct resource nhk8815_eth_resources[] = {
|
||||
{
|
||||
.name = "smc91x-regs",
|
||||
.start = 0x34000000 + 0x300,
|
||||
.end = 0x34000000 + SZ_64K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.start = NOMADIK_GPIO_TO_IRQ(115),
|
||||
.end = NOMADIK_GPIO_TO_IRQ(115),
|
||||
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device nhk8815_eth_device = {
|
||||
.name = "smc91x",
|
||||
.resource = nhk8815_eth_resources,
|
||||
.num_resources = ARRAY_SIZE(nhk8815_eth_resources),
|
||||
};
|
||||
|
||||
static int __init nhk8815_eth_init(void)
|
||||
{
|
||||
int gpio_nr = 115; /* hardwired in the board */
|
||||
int err;
|
||||
|
||||
err = gpio_request(gpio_nr, "eth_irq");
|
||||
if (!err) err = nmk_gpio_set_mode(gpio_nr, NMK_GPIO_ALT_GPIO);
|
||||
if (!err) err = gpio_direction_input(gpio_nr);
|
||||
if (err)
|
||||
pr_err("Error %i in %s\n", err, __func__);
|
||||
return err;
|
||||
}
|
||||
device_initcall(nhk8815_eth_init);
|
||||
|
||||
static struct platform_device *nhk8815_platform_devices[] __initdata = {
|
||||
&nhk8815_eth_device,
|
||||
/* will add more devices */
|
||||
};
|
||||
|
||||
static void __init nhk8815_platform_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
cpu8815_platform_init();
|
||||
platform_add_devices(nhk8815_platform_devices,
|
||||
ARRAY_SIZE(nhk8815_platform_devices));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
||||
nmdk_clk_create(&nhk8815_clk_48, amba_devs[i]->dev.init_name);
|
||||
amba_device_register(amba_devs[i], &iomem_resource);
|
||||
}
|
||||
}
|
||||
|
||||
MACHINE_START(NOMADIK, "NHK8815")
|
||||
/* Maintainer: ST MicroElectronics */
|
||||
.phys_io = NOMADIK_UART0_BASE,
|
||||
.io_pg_offst = (IO_ADDRESS(NOMADIK_UART0_BASE) >> 18) & 0xfffc,
|
||||
.boot_params = 0x100,
|
||||
.map_io = cpu8815_map_io,
|
||||
.init_irq = cpu8815_init_irq,
|
||||
.timer = &nomadik_timer,
|
||||
.init_machine = nhk8815_platform_init,
|
||||
MACHINE_END
|
45
arch/arm/mach-nomadik/clock.c
Normal file
45
arch/arm/mach-nomadik/clock.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-nomadik/clock.c
|
||||
*
|
||||
* Copyright (C) 2009 Alessandro Rubini
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk.h>
|
||||
#include <asm/clkdev.h>
|
||||
#include "clock.h"
|
||||
|
||||
/*
|
||||
* The nomadik board uses generic clocks, but the serial pl011 file
|
||||
* calls clk_enable(), clk_disable(), clk_get_rate(), so we provide them
|
||||
*/
|
||||
unsigned long clk_get_rate(struct clk *clk)
|
||||
{
|
||||
return clk->rate;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get_rate);
|
||||
|
||||
/* enable and disable do nothing */
|
||||
int clk_enable(struct clk *clk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_enable);
|
||||
|
||||
void clk_disable(struct clk *clk)
|
||||
{
|
||||
}
|
||||
EXPORT_SYMBOL(clk_disable);
|
||||
|
||||
/* Create a clock structure with the given name */
|
||||
int nmdk_clk_create(struct clk *clk, const char *dev_id)
|
||||
{
|
||||
struct clk_lookup *clkdev;
|
||||
|
||||
clkdev = clkdev_alloc(clk, NULL, dev_id);
|
||||
if (!clkdev)
|
||||
return -ENOMEM;
|
||||
clkdev_add(clkdev);
|
||||
return 0;
|
||||
}
|
14
arch/arm/mach-nomadik/clock.h
Normal file
14
arch/arm/mach-nomadik/clock.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
/*
|
||||
* linux/arch/arm/mach-nomadik/clock.h
|
||||
*
|
||||
* Copyright (C) 2009 Alessandro Rubini
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
struct clk {
|
||||
unsigned long rate;
|
||||
};
|
||||
extern int nmdk_clk_create(struct clk *clk, const char *dev_id);
|
139
arch/arm/mach-nomadik/cpu-8815.c
Normal file
139
arch/arm/mach-nomadik/cpu-8815.c
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright STMicroelectronics, 2007.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/amba/bus.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/hardware/vic.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
|
||||
/* The 8815 has 4 GPIO blocks, let's register them immediately */
|
||||
static struct nmk_gpio_platform_data cpu8815_gpio[] = {
|
||||
{
|
||||
.name = "GPIO-0-31",
|
||||
.first_gpio = 0,
|
||||
.first_irq = NOMADIK_GPIO_TO_IRQ(0),
|
||||
.parent_irq = IRQ_GPIO0,
|
||||
}, {
|
||||
.name = "GPIO-32-63",
|
||||
.first_gpio = 32,
|
||||
.first_irq = NOMADIK_GPIO_TO_IRQ(32),
|
||||
.parent_irq = IRQ_GPIO1,
|
||||
}, {
|
||||
.name = "GPIO-64-95",
|
||||
.first_gpio = 64,
|
||||
.first_irq = NOMADIK_GPIO_TO_IRQ(64),
|
||||
.parent_irq = IRQ_GPIO2,
|
||||
}, {
|
||||
.name = "GPIO-96-127", /* 124..127 not routed to pin */
|
||||
.first_gpio = 96,
|
||||
.first_irq = NOMADIK_GPIO_TO_IRQ(96),
|
||||
.parent_irq = IRQ_GPIO3,
|
||||
}
|
||||
};
|
||||
|
||||
#define __MEM_4K_RESOURCE(x) \
|
||||
.res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
|
||||
|
||||
static struct amba_device cpu8815_amba_gpio[] = {
|
||||
{
|
||||
.dev = {
|
||||
.init_name = "gpio0",
|
||||
.platform_data = cpu8815_gpio + 0,
|
||||
},
|
||||
__MEM_4K_RESOURCE(NOMADIK_GPIO0_BASE),
|
||||
}, {
|
||||
.dev = {
|
||||
.init_name = "gpio1",
|
||||
.platform_data = cpu8815_gpio + 1,
|
||||
},
|
||||
__MEM_4K_RESOURCE(NOMADIK_GPIO1_BASE),
|
||||
}, {
|
||||
.dev = {
|
||||
.init_name = "gpio2",
|
||||
.platform_data = cpu8815_gpio + 2,
|
||||
},
|
||||
__MEM_4K_RESOURCE(NOMADIK_GPIO2_BASE),
|
||||
}, {
|
||||
.dev = {
|
||||
.init_name = "gpio3",
|
||||
.platform_data = cpu8815_gpio + 3,
|
||||
},
|
||||
__MEM_4K_RESOURCE(NOMADIK_GPIO3_BASE),
|
||||
},
|
||||
};
|
||||
|
||||
static struct amba_device *amba_devs[] __initdata = {
|
||||
cpu8815_amba_gpio + 0,
|
||||
cpu8815_amba_gpio + 1,
|
||||
cpu8815_amba_gpio + 2,
|
||||
cpu8815_amba_gpio + 3,
|
||||
};
|
||||
|
||||
static int __init cpu8815_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
|
||||
amba_device_register(amba_devs[i], &iomem_resource);
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(cpu8815_init);
|
||||
|
||||
/* All SoC devices live in the same area (see hardware.h) */
|
||||
static struct map_desc nomadik_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = NOMADIK_IO_VIRTUAL,
|
||||
.pfn = __phys_to_pfn(NOMADIK_IO_PHYSICAL),
|
||||
.length = NOMADIK_IO_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
}
|
||||
/* static ram and secured ram may be added later */
|
||||
};
|
||||
|
||||
void __init cpu8815_map_io(void)
|
||||
{
|
||||
iotable_init(nomadik_io_desc, ARRAY_SIZE(nomadik_io_desc));
|
||||
}
|
||||
|
||||
void __init cpu8815_init_irq(void)
|
||||
{
|
||||
/* This modified VIC cell has two register blocks, at 0 and 0x20 */
|
||||
vic_init(io_p2v(NOMADIK_IC_BASE + 0x00), IRQ_VIC_START + 0, ~0, 0);
|
||||
vic_init(io_p2v(NOMADIK_IC_BASE + 0x20), IRQ_VIC_START + 32, ~0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called from the board init ("init_machine").
|
||||
*/
|
||||
void __init cpu8815_platform_init(void)
|
||||
{
|
||||
#ifdef CONFIG_CACHE_L2X0
|
||||
/* At full speed latency must be >=2, so 0x249 in low bits */
|
||||
l2x0_init(io_p2v(NOMADIK_L2CC_BASE), 0x00730249, 0xfe000fff);
|
||||
#endif
|
||||
return;
|
||||
}
|
396
arch/arm/mach-nomadik/gpio.c
Normal file
396
arch/arm/mach-nomadik/gpio.c
Normal file
|
@ -0,0 +1,396 @@
|
|||
/*
|
||||
* Generic GPIO driver for logic cells found in the Nomadik SoC
|
||||
*
|
||||
* Copyright (C) 2008,2009 STMicroelectronics
|
||||
* Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
|
||||
* Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/amba/bus.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/gpio.h>
|
||||
|
||||
/*
|
||||
* The GPIO module in the Nomadik family of Systems-on-Chip is an
|
||||
* AMBA device, managing 32 pins and alternate functions. The logic block
|
||||
* is currently only used in the Nomadik.
|
||||
*
|
||||
* Symbols in this file are called "nmk_gpio" for "nomadik gpio"
|
||||
*/
|
||||
|
||||
#define NMK_GPIO_PER_CHIP 32
|
||||
struct nmk_gpio_chip {
|
||||
struct gpio_chip chip;
|
||||
void __iomem *addr;
|
||||
unsigned int parent_irq;
|
||||
spinlock_t *lock;
|
||||
/* Keep track of configured edges */
|
||||
u32 edge_rising;
|
||||
u32 edge_falling;
|
||||
};
|
||||
|
||||
/* Mode functions */
|
||||
int nmk_gpio_set_mode(int gpio, int gpio_mode)
|
||||
{
|
||||
struct nmk_gpio_chip *nmk_chip;
|
||||
unsigned long flags;
|
||||
u32 afunc, bfunc, bit;
|
||||
|
||||
nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
|
||||
if (!nmk_chip)
|
||||
return -EINVAL;
|
||||
|
||||
bit = 1 << (gpio - nmk_chip->chip.base);
|
||||
|
||||
spin_lock_irqsave(&nmk_chip->lock, flags);
|
||||
afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
|
||||
bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
|
||||
if (gpio_mode & NMK_GPIO_ALT_A)
|
||||
afunc |= bit;
|
||||
if (gpio_mode & NMK_GPIO_ALT_B)
|
||||
bfunc |= bit;
|
||||
writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
|
||||
writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
|
||||
spin_unlock_irqrestore(&nmk_chip->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(nmk_gpio_set_mode);
|
||||
|
||||
int nmk_gpio_get_mode(int gpio)
|
||||
{
|
||||
struct nmk_gpio_chip *nmk_chip;
|
||||
u32 afunc, bfunc, bit;
|
||||
|
||||
nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
|
||||
if (!nmk_chip)
|
||||
return -EINVAL;
|
||||
|
||||
bit = 1 << (gpio - nmk_chip->chip.base);
|
||||
|
||||
afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit;
|
||||
bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit;
|
||||
|
||||
return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
|
||||
}
|
||||
EXPORT_SYMBOL(nmk_gpio_get_mode);
|
||||
|
||||
|
||||
/* IRQ functions */
|
||||
static inline int nmk_gpio_get_bitmask(int gpio)
|
||||
{
|
||||
return 1 << (gpio % 32);
|
||||
}
|
||||
|
||||
static void nmk_gpio_irq_ack(unsigned int irq)
|
||||
{
|
||||
int gpio;
|
||||
struct nmk_gpio_chip *nmk_chip;
|
||||
|
||||
gpio = NOMADIK_IRQ_TO_GPIO(irq);
|
||||
nmk_chip = get_irq_chip_data(irq);
|
||||
if (!nmk_chip)
|
||||
return;
|
||||
writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
|
||||
}
|
||||
|
||||
static void nmk_gpio_irq_mask(unsigned int irq)
|
||||
{
|
||||
int gpio;
|
||||
struct nmk_gpio_chip *nmk_chip;
|
||||
unsigned long flags;
|
||||
u32 bitmask, reg;
|
||||
|
||||
gpio = NOMADIK_IRQ_TO_GPIO(irq);
|
||||
nmk_chip = get_irq_chip_data(irq);
|
||||
bitmask = nmk_gpio_get_bitmask(gpio);
|
||||
if (!nmk_chip)
|
||||
return;
|
||||
|
||||
/* we must individually clear the two edges */
|
||||
spin_lock_irqsave(&nmk_chip->lock, flags);
|
||||
if (nmk_chip->edge_rising & bitmask) {
|
||||
reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
|
||||
reg &= ~bitmask;
|
||||
writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC);
|
||||
}
|
||||
if (nmk_chip->edge_falling & bitmask) {
|
||||
reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
|
||||
reg &= ~bitmask;
|
||||
writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC);
|
||||
}
|
||||
spin_unlock_irqrestore(&nmk_chip->lock, flags);
|
||||
};
|
||||
|
||||
static void nmk_gpio_irq_unmask(unsigned int irq)
|
||||
{
|
||||
int gpio;
|
||||
struct nmk_gpio_chip *nmk_chip;
|
||||
unsigned long flags;
|
||||
u32 bitmask, reg;
|
||||
|
||||
gpio = NOMADIK_IRQ_TO_GPIO(irq);
|
||||
nmk_chip = get_irq_chip_data(irq);
|
||||
bitmask = nmk_gpio_get_bitmask(gpio);
|
||||
if (!nmk_chip)
|
||||
return;
|
||||
|
||||
/* we must individually set the two edges */
|
||||
spin_lock_irqsave(&nmk_chip->lock, flags);
|
||||
if (nmk_chip->edge_rising & bitmask) {
|
||||
reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
|
||||
reg |= bitmask;
|
||||
writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC);
|
||||
}
|
||||
if (nmk_chip->edge_falling & bitmask) {
|
||||
reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
|
||||
reg |= bitmask;
|
||||
writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC);
|
||||
}
|
||||
spin_unlock_irqrestore(&nmk_chip->lock, flags);
|
||||
}
|
||||
|
||||
static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
|
||||
{
|
||||
int gpio;
|
||||
struct nmk_gpio_chip *nmk_chip;
|
||||
unsigned long flags;
|
||||
u32 bitmask;
|
||||
|
||||
gpio = NOMADIK_IRQ_TO_GPIO(irq);
|
||||
nmk_chip = get_irq_chip_data(irq);
|
||||
bitmask = nmk_gpio_get_bitmask(gpio);
|
||||
if (!nmk_chip)
|
||||
return -EINVAL;
|
||||
|
||||
if (type & IRQ_TYPE_LEVEL_HIGH)
|
||||
return -EINVAL;
|
||||
if (type & IRQ_TYPE_LEVEL_LOW)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&nmk_chip->lock, flags);
|
||||
|
||||
nmk_chip->edge_rising &= ~bitmask;
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
nmk_chip->edge_rising |= bitmask;
|
||||
writel(nmk_chip->edge_rising, nmk_chip->addr + NMK_GPIO_RIMSC);
|
||||
|
||||
nmk_chip->edge_falling &= ~bitmask;
|
||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
nmk_chip->edge_falling |= bitmask;
|
||||
writel(nmk_chip->edge_falling, nmk_chip->addr + NMK_GPIO_FIMSC);
|
||||
|
||||
spin_unlock_irqrestore(&nmk_chip->lock, flags);
|
||||
|
||||
nmk_gpio_irq_unmask(irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip nmk_gpio_irq_chip = {
|
||||
.name = "Nomadik-GPIO",
|
||||
.ack = nmk_gpio_irq_ack,
|
||||
.mask = nmk_gpio_irq_mask,
|
||||
.unmask = nmk_gpio_irq_unmask,
|
||||
.set_type = nmk_gpio_irq_set_type,
|
||||
};
|
||||
|
||||
static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct nmk_gpio_chip *nmk_chip;
|
||||
struct irq_chip *host_chip;
|
||||
unsigned int gpio_irq;
|
||||
u32 pending;
|
||||
unsigned int first_irq;
|
||||
|
||||
nmk_chip = get_irq_data(irq);
|
||||
first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
|
||||
while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) {
|
||||
gpio_irq = first_irq + __ffs(pending);
|
||||
generic_handle_irq(gpio_irq);
|
||||
}
|
||||
if (0) {/* don't ack parent irq, as ack == disable */
|
||||
host_chip = get_irq_chip(irq);
|
||||
host_chip->ack(irq);
|
||||
}
|
||||
}
|
||||
|
||||
static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
|
||||
{
|
||||
unsigned int first_irq;
|
||||
int i;
|
||||
|
||||
first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
|
||||
for (i = first_irq; i < first_irq + NMK_GPIO_PER_CHIP; i++) {
|
||||
set_irq_chip(i, &nmk_gpio_irq_chip);
|
||||
set_irq_handler(i, handle_edge_irq);
|
||||
set_irq_flags(i, IRQF_VALID);
|
||||
set_irq_chip_data(i, nmk_chip);
|
||||
}
|
||||
set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
|
||||
set_irq_data(nmk_chip->parent_irq, nmk_chip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* I/O Functions */
|
||||
static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct nmk_gpio_chip *nmk_chip =
|
||||
container_of(chip, struct nmk_gpio_chip, chip);
|
||||
|
||||
writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
|
||||
int val)
|
||||
{
|
||||
struct nmk_gpio_chip *nmk_chip =
|
||||
container_of(chip, struct nmk_gpio_chip, chip);
|
||||
|
||||
writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct nmk_gpio_chip *nmk_chip =
|
||||
container_of(chip, struct nmk_gpio_chip, chip);
|
||||
u32 bit = 1 << offset;
|
||||
|
||||
return (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0;
|
||||
}
|
||||
|
||||
static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
|
||||
int val)
|
||||
{
|
||||
struct nmk_gpio_chip *nmk_chip =
|
||||
container_of(chip, struct nmk_gpio_chip, chip);
|
||||
u32 bit = 1 << offset;
|
||||
|
||||
if (val)
|
||||
writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
|
||||
else
|
||||
writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
|
||||
}
|
||||
|
||||
/* This structure is replicated for each GPIO block allocated at probe time */
|
||||
static struct gpio_chip nmk_gpio_template = {
|
||||
.direction_input = nmk_gpio_make_input,
|
||||
.get = nmk_gpio_get_input,
|
||||
.direction_output = nmk_gpio_make_output,
|
||||
.set = nmk_gpio_set_output,
|
||||
.ngpio = NMK_GPIO_PER_CHIP,
|
||||
.can_sleep = 0,
|
||||
};
|
||||
|
||||
static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id)
|
||||
{
|
||||
struct nmk_gpio_platform_data *pdata;
|
||||
struct nmk_gpio_chip *nmk_chip;
|
||||
struct gpio_chip *chip;
|
||||
int ret;
|
||||
|
||||
pdata = dev->dev.platform_data;
|
||||
ret = amba_request_regions(dev, pdata->name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
|
||||
if (!nmk_chip) {
|
||||
ret = -ENOMEM;
|
||||
goto out_amba;
|
||||
}
|
||||
/*
|
||||
* The virt address in nmk_chip->addr is in the nomadik register space,
|
||||
* so we can simply convert the resource address, without remapping
|
||||
*/
|
||||
nmk_chip->addr = io_p2v(dev->res.start);
|
||||
nmk_chip->chip = nmk_gpio_template;
|
||||
nmk_chip->parent_irq = pdata->parent_irq;
|
||||
|
||||
chip = &nmk_chip->chip;
|
||||
chip->base = pdata->first_gpio;
|
||||
chip->label = pdata->name;
|
||||
chip->dev = &dev->dev;
|
||||
chip->owner = THIS_MODULE;
|
||||
|
||||
ret = gpiochip_add(&nmk_chip->chip);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
|
||||
amba_set_drvdata(dev, nmk_chip);
|
||||
|
||||
nmk_gpio_init_irq(nmk_chip);
|
||||
|
||||
dev_info(&dev->dev, "Bits %i-%i at address %p\n",
|
||||
nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr);
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
kfree(nmk_chip);
|
||||
out_amba:
|
||||
amba_release_regions(dev);
|
||||
dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
|
||||
pdata->first_gpio, pdata->first_gpio+31);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nmk_gpio_remove(struct amba_device *dev)
|
||||
{
|
||||
struct nmk_gpio_chip *nmk_chip;
|
||||
|
||||
nmk_chip = amba_get_drvdata(dev);
|
||||
gpiochip_remove(&nmk_chip->chip);
|
||||
kfree(nmk_chip);
|
||||
amba_release_regions(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* We have 0x1f080060 and 0x1f180060, accept both using the mask */
|
||||
static struct amba_id nmk_gpio_ids[] = {
|
||||
{
|
||||
.id = 0x1f080060,
|
||||
.mask = 0xffefffff,
|
||||
},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static struct amba_driver nmk_gpio_driver = {
|
||||
.drv = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "gpio",
|
||||
},
|
||||
.probe = nmk_gpio_probe,
|
||||
.remove = nmk_gpio_remove,
|
||||
.suspend = NULL, /* to be done */
|
||||
.resume = NULL,
|
||||
.id_table = nmk_gpio_ids,
|
||||
};
|
||||
|
||||
static int __init nmk_gpio_init(void)
|
||||
{
|
||||
return amba_driver_register(&nmk_gpio_driver);
|
||||
}
|
||||
|
||||
arch_initcall(nmk_gpio_init);
|
||||
|
||||
MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
|
||||
MODULE_DESCRIPTION("Nomadik GPIO Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
65
arch/arm/mach-nomadik/i2c-8815nhk.c
Normal file
65
arch/arm/mach-nomadik/i2c-8815nhk.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-algo-bit.h>
|
||||
#include <linux/i2c-gpio.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
/*
|
||||
* There are two busses in the 8815NHK.
|
||||
* They could, in theory, be driven by the hardware component, but we
|
||||
* use bit-bang through GPIO by now, to keep things simple
|
||||
*/
|
||||
|
||||
static struct i2c_gpio_platform_data nhk8815_i2c_data0 = {
|
||||
/* keep defaults for timeouts; pins are push-pull bidirectional */
|
||||
.scl_pin = 62,
|
||||
.sda_pin = 63,
|
||||
};
|
||||
|
||||
static struct i2c_gpio_platform_data nhk8815_i2c_data1 = {
|
||||
/* keep defaults for timeouts; pins are push-pull bidirectional */
|
||||
.scl_pin = 53,
|
||||
.sda_pin = 54,
|
||||
};
|
||||
|
||||
/* first bus: GPIO XX and YY */
|
||||
static struct platform_device nhk8815_i2c_dev0 = {
|
||||
.name = "i2c-gpio",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &nhk8815_i2c_data0,
|
||||
},
|
||||
};
|
||||
/* second bus: GPIO XX and YY */
|
||||
static struct platform_device nhk8815_i2c_dev1 = {
|
||||
.name = "i2c-gpio",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &nhk8815_i2c_data1,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init nhk8815_i2c_init(void)
|
||||
{
|
||||
nmk_gpio_set_mode(nhk8815_i2c_data0.scl_pin, NMK_GPIO_ALT_GPIO);
|
||||
nmk_gpio_set_mode(nhk8815_i2c_data0.sda_pin, NMK_GPIO_ALT_GPIO);
|
||||
platform_device_register(&nhk8815_i2c_dev0);
|
||||
|
||||
nmk_gpio_set_mode(nhk8815_i2c_data1.scl_pin, NMK_GPIO_ALT_GPIO);
|
||||
nmk_gpio_set_mode(nhk8815_i2c_data1.sda_pin, NMK_GPIO_ALT_GPIO);
|
||||
platform_device_register(&nhk8815_i2c_dev1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit nhk8815_i2c_exit(void)
|
||||
{
|
||||
platform_device_unregister(&nhk8815_i2c_dev0);
|
||||
platform_device_unregister(&nhk8815_i2c_dev1);
|
||||
return;
|
||||
}
|
||||
|
||||
module_init(nhk8815_i2c_init);
|
||||
module_exit(nhk8815_i2c_exit);
|
7
arch/arm/mach-nomadik/include/mach/clkdev.h
Normal file
7
arch/arm/mach-nomadik/include/mach/clkdev.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef __ASM_MACH_CLKDEV_H
|
||||
#define __ASM_MACH_CLKDEV_H
|
||||
|
||||
#define __clk_get(clk) ({ 1; })
|
||||
#define __clk_put(clk) do { } while (0)
|
||||
|
||||
#endif
|
22
arch/arm/mach-nomadik/include/mach/debug-macro.S
Normal file
22
arch/arm/mach-nomadik/include/mach/debug-macro.S
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Debugging macro include header
|
||||
*
|
||||
* Copyright (C) 1994-1999 Russell King
|
||||
* Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
.macro addruart,rx
|
||||
mrc p15, 0, \rx, c1, c0
|
||||
tst \rx, #1 @ MMU enabled?
|
||||
moveq \rx, #0x10000000 @ physical base address
|
||||
movne \rx, #0xf0000000 @ virtual base
|
||||
add \rx, \rx, #0x00100000
|
||||
add \rx, \rx, #0x000fb000
|
||||
.endm
|
||||
|
||||
#include <asm/hardware/debug-pl01x.S>
|
43
arch/arm/mach-nomadik/include/mach/entry-macro.S
Normal file
43
arch/arm/mach-nomadik/include/mach/entry-macro.S
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Low-level IRQ helper macros for Nomadik platforms
|
||||
*
|
||||
* 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 <mach/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
.macro disable_fiq
|
||||
.endm
|
||||
|
||||
.macro get_irqnr_preamble, base, tmp
|
||||
ldr \base, =IO_ADDRESS(NOMADIK_IC_BASE)
|
||||
.endm
|
||||
|
||||
.macro arch_ret_to_user, tmp1, tmp2
|
||||
.endm
|
||||
|
||||
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
|
||||
|
||||
/* This stanza gets the irq mask from one of two status registers */
|
||||
mov \irqnr, #0
|
||||
ldr \irqstat, [\base, #VIC_REG_IRQSR0] @ get masked status
|
||||
cmp \irqstat, #0
|
||||
bne 1001f
|
||||
add \irqnr, \irqnr, #32
|
||||
ldr \irqstat, [\base, #VIC_REG_IRQSR1] @ get masked status
|
||||
|
||||
1001: tst \irqstat, #15
|
||||
bne 1002f
|
||||
add \irqnr, \irqnr, #4
|
||||
movs \irqstat, \irqstat, lsr #4
|
||||
bne 1001b
|
||||
1002: tst \irqstat, #1
|
||||
bne 1003f
|
||||
add \irqnr, \irqnr, #1
|
||||
movs \irqstat, \irqstat, lsr #1
|
||||
bne 1002b
|
||||
1003: /* EQ will be set if no irqs pending */
|
||||
.endm
|
71
arch/arm/mach-nomadik/include/mach/gpio.h
Normal file
71
arch/arm/mach-nomadik/include/mach/gpio.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Structures and registers for GPIO access in the Nomadik SoC
|
||||
*
|
||||
* Copyright (C) 2008 STMicroelectronics
|
||||
* Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
|
||||
* Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef __ASM_ARCH_GPIO_H
|
||||
#define __ASM_ARCH_GPIO_H
|
||||
|
||||
#include <asm-generic/gpio.h>
|
||||
|
||||
/*
|
||||
* These currently cause a function call to happen, they may be optimized
|
||||
* if needed by adding cpu-specific defines to identify blocks
|
||||
* (see mach-pxa/include/mach/gpio.h as an example using GPLR etc)
|
||||
*/
|
||||
#define gpio_get_value __gpio_get_value
|
||||
#define gpio_set_value __gpio_set_value
|
||||
#define gpio_cansleep __gpio_cansleep
|
||||
#define gpio_to_irq __gpio_to_irq
|
||||
|
||||
/*
|
||||
* "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
|
||||
* the "gpio" namespace for generic and cross-machine functions
|
||||
*/
|
||||
|
||||
/* Register in the logic block */
|
||||
#define NMK_GPIO_DAT 0x00
|
||||
#define NMK_GPIO_DATS 0x04
|
||||
#define NMK_GPIO_DATC 0x08
|
||||
#define NMK_GPIO_PDIS 0x0c
|
||||
#define NMK_GPIO_DIR 0x10
|
||||
#define NMK_GPIO_DIRS 0x14
|
||||
#define NMK_GPIO_DIRC 0x18
|
||||
#define NMK_GPIO_SLPC 0x1c
|
||||
#define NMK_GPIO_AFSLA 0x20
|
||||
#define NMK_GPIO_AFSLB 0x24
|
||||
|
||||
#define NMK_GPIO_RIMSC 0x40
|
||||
#define NMK_GPIO_FIMSC 0x44
|
||||
#define NMK_GPIO_IS 0x48
|
||||
#define NMK_GPIO_IC 0x4c
|
||||
#define NMK_GPIO_RWIMSC 0x50
|
||||
#define NMK_GPIO_FWIMSC 0x54
|
||||
#define NMK_GPIO_WKS 0x58
|
||||
|
||||
/* Alternate functions: function C is set in hw by setting both A and B */
|
||||
#define NMK_GPIO_ALT_GPIO 0
|
||||
#define NMK_GPIO_ALT_A 1
|
||||
#define NMK_GPIO_ALT_B 2
|
||||
#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
|
||||
|
||||
extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
|
||||
extern int nmk_gpio_get_mode(int gpio);
|
||||
|
||||
/*
|
||||
* Platform data to register a block: only the initial gpio/irq number.
|
||||
*/
|
||||
struct nmk_gpio_platform_data {
|
||||
char *name;
|
||||
int first_gpio;
|
||||
int first_irq;
|
||||
int parent_irq;
|
||||
};
|
||||
|
||||
#endif /* __ASM_ARCH_GPIO_H */
|
90
arch/arm/mach-nomadik/include/mach/hardware.h
Normal file
90
arch/arm/mach-nomadik/include/mach/hardware.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* This file contains the hardware definitions of the Nomadik.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* YOU should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __ASM_ARCH_HARDWARE_H
|
||||
#define __ASM_ARCH_HARDWARE_H
|
||||
|
||||
/* Nomadik registers live from 0x1000.0000 to 0x1023.0000 -- currently */
|
||||
#define NOMADIK_IO_VIRTUAL 0xF0000000 /* VA of IO */
|
||||
#define NOMADIK_IO_PHYSICAL 0x10000000 /* PA of IO */
|
||||
#define NOMADIK_IO_SIZE 0x00300000 /* 3MB for all regs */
|
||||
|
||||
/* used in C code, so cast to proper type */
|
||||
#define io_p2v(x) ((void __iomem *)(x) \
|
||||
- NOMADIK_IO_PHYSICAL + NOMADIK_IO_VIRTUAL)
|
||||
#define io_v2p(x) ((unsigned long)(x) \
|
||||
- NOMADIK_IO_VIRTUAL + NOMADIK_IO_PHYSICAL)
|
||||
|
||||
/* used in asm code, so no casts */
|
||||
#define IO_ADDRESS(x) ((x) - NOMADIK_IO_PHYSICAL + NOMADIK_IO_VIRTUAL)
|
||||
|
||||
/*
|
||||
* Base address defination for Nomadik Onchip Logic Block
|
||||
*/
|
||||
#define NOMADIK_FSMC_BASE 0x10100000 /* FSMC registers */
|
||||
#define NOMADIK_SDRAMC_BASE 0x10110000 /* SDRAM Controller */
|
||||
#define NOMADIK_CLCDC_BASE 0x10120000 /* CLCD Controller */
|
||||
#define NOMADIK_MDIF_BASE 0x10120000 /* MDIF */
|
||||
#define NOMADIK_DMA0_BASE 0x10130000 /* DMA0 Controller */
|
||||
#define NOMADIK_IC_BASE 0x10140000 /* Vectored Irq Controller */
|
||||
#define NOMADIK_DMA1_BASE 0x10150000 /* DMA1 Controller */
|
||||
#define NOMADIK_USB_BASE 0x10170000 /* USB-OTG conf reg base */
|
||||
#define NOMADIK_CRYP_BASE 0x10180000 /* Crypto processor */
|
||||
#define NOMADIK_SHA1_BASE 0x10190000 /* SHA-1 Processor */
|
||||
#define NOMADIK_XTI_BASE 0x101A0000 /* XTI */
|
||||
#define NOMADIK_RNG_BASE 0x101B0000 /* Random number generator */
|
||||
#define NOMADIK_SRC_BASE 0x101E0000 /* SRC base */
|
||||
#define NOMADIK_WDOG_BASE 0x101E1000 /* Watchdog */
|
||||
#define NOMADIK_MTU0_BASE 0x101E2000 /* Multiple Timer 0 */
|
||||
#define NOMADIK_MTU1_BASE 0x101E3000 /* Multiple Timer 1 */
|
||||
#define NOMADIK_GPIO0_BASE 0x101E4000 /* GPIO0 */
|
||||
#define NOMADIK_GPIO1_BASE 0x101E5000 /* GPIO1 */
|
||||
#define NOMADIK_GPIO2_BASE 0x101E6000 /* GPIO2 */
|
||||
#define NOMADIK_GPIO3_BASE 0x101E7000 /* GPIO3 */
|
||||
#define NOMADIK_RTC_BASE 0x101E8000 /* Real Time Clock base */
|
||||
#define NOMADIK_PMU_BASE 0x101E9000 /* Power Management Unit */
|
||||
#define NOMADIK_OWM_BASE 0x101EA000 /* One wire master */
|
||||
#define NOMADIK_SCR_BASE 0x101EF000 /* Secure Control registers */
|
||||
#define NOMADIK_MSP2_BASE 0x101F0000 /* MSP 2 interface */
|
||||
#define NOMADIK_MSP1_BASE 0x101F1000 /* MSP 1 interface */
|
||||
#define NOMADIK_UART2_BASE 0x101F2000 /* UART 2 interface */
|
||||
#define NOMADIK_SSIRx_BASE 0x101F3000 /* SSI 8-ch rx interface */
|
||||
#define NOMADIK_SSITx_BASE 0x101F4000 /* SSI 8-ch tx interface */
|
||||
#define NOMADIK_MSHC_BASE 0x101F5000 /* Memory Stick(Pro) Host */
|
||||
#define NOMADIK_SDI_BASE 0x101F6000 /* SD-card/MM-Card */
|
||||
#define NOMADIK_I2C1_BASE 0x101F7000 /* I2C1 interface */
|
||||
#define NOMADIK_I2C0_BASE 0x101F8000 /* I2C0 interface */
|
||||
#define NOMADIK_MSP0_BASE 0x101F9000 /* MSP 0 interface */
|
||||
#define NOMADIK_FIRDA_BASE 0x101FA000 /* FIrDA interface */
|
||||
#define NOMADIK_UART1_BASE 0x101FB000 /* UART 1 interface */
|
||||
#define NOMADIK_SSP_BASE 0x101FC000 /* SSP interface */
|
||||
#define NOMADIK_UART0_BASE 0x101FD000 /* UART 0 interface */
|
||||
#define NOMADIK_SGA_BASE 0x101FE000 /* SGA interface */
|
||||
#define NOMADIK_L2CC_BASE 0x10210000 /* L2 Cache controller */
|
||||
|
||||
/* Other ranges, not for p2v/v2p */
|
||||
#define NOMADIK_BACKUP_RAM 0x80010000
|
||||
#define NOMADIK_EBROM 0x80000000 /* Embedded boot ROM */
|
||||
#define NOMADIK_HAMACV_DMEM_BASE 0xA0100000 /* HAMACV Data Memory Start */
|
||||
#define NOMADIK_HAMACV_DMEM_END 0xA01FFFFF /* HAMACV Data Memory End */
|
||||
#define NOMADIK_HAMACA_DMEM 0xA0200000 /* HAMACA Data Memory Space */
|
||||
|
||||
#define NOMADIK_FSMC_VA IO_ADDRESS(NOMADIK_FSMC_BASE)
|
||||
#define NOMADIK_MTU0_VA IO_ADDRESS(NOMADIK_MTU0_BASE)
|
||||
#define NOMADIK_MTU1_VA IO_ADDRESS(NOMADIK_MTU1_BASE)
|
||||
|
||||
#endif /* __ASM_ARCH_HARDWARE_H */
|
22
arch/arm/mach-nomadik/include/mach/io.h
Normal file
22
arch/arm/mach-nomadik/include/mach/io.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* arch/arm/mach-nomadik/include/mach/io.h (copied from mach-sa1100)
|
||||
*
|
||||
* Copyright (C) 1997-1999 Russell King
|
||||
*
|
||||
* Modifications:
|
||||
* 06-12-1997 RMK Created.
|
||||
* 07-04-1999 RMK Major cleanup
|
||||
*/
|
||||
#ifndef __ASM_ARM_ARCH_IO_H
|
||||
#define __ASM_ARM_ARCH_IO_H
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffffffff
|
||||
|
||||
/*
|
||||
* We don't actually have real ISA nor PCI buses, but there is so many
|
||||
* drivers out there that might just work if we fake them...
|
||||
*/
|
||||
#define __io(a) __typesafe_io(a)
|
||||
#define __mem_pci(a) (a)
|
||||
|
||||
#endif
|
82
arch/arm/mach-nomadik/include/mach/irqs.h
Normal file
82
arch/arm/mach-nomadik/include/mach/irqs.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* mach-nomadik/include/mach/irqs.h
|
||||
*
|
||||
* Copyright (C) ST Microelectronics
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __ASM_ARCH_IRQS_H
|
||||
#define __ASM_ARCH_IRQS_H
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#define IRQ_VIC_START 0 /* first VIC interrupt is 0 */
|
||||
|
||||
/*
|
||||
* Interrupt numbers generic for all Nomadik Chip cuts
|
||||
*/
|
||||
#define IRQ_WATCHDOG 0
|
||||
#define IRQ_SOFTINT 1
|
||||
#define IRQ_CRYPTO 2
|
||||
#define IRQ_OWM 3
|
||||
#define IRQ_MTU0 4
|
||||
#define IRQ_MTU1 5
|
||||
#define IRQ_GPIO0 6
|
||||
#define IRQ_GPIO1 7
|
||||
#define IRQ_GPIO2 8
|
||||
#define IRQ_GPIO3 9
|
||||
#define IRQ_RTC_RTT 10
|
||||
#define IRQ_SSP 11
|
||||
#define IRQ_UART0 12
|
||||
#define IRQ_DMA1 13
|
||||
#define IRQ_CLCD_MDIF 14
|
||||
#define IRQ_DMA0 15
|
||||
#define IRQ_PWRFAIL 16
|
||||
#define IRQ_UART1 17
|
||||
#define IRQ_FIRDA 18
|
||||
#define IRQ_MSP0 19
|
||||
#define IRQ_I2C0 20
|
||||
#define IRQ_I2C1 21
|
||||
#define IRQ_SDMMC 22
|
||||
#define IRQ_USBOTG 23
|
||||
#define IRQ_SVA_IT0 24
|
||||
#define IRQ_SVA_IT1 25
|
||||
#define IRQ_SAA_IT0 26
|
||||
#define IRQ_SAA_IT1 27
|
||||
#define IRQ_UART2 28
|
||||
#define IRQ_MSP2 31
|
||||
#define IRQ_L2CC 48
|
||||
#define IRQ_HPI 49
|
||||
#define IRQ_SKE 50
|
||||
#define IRQ_KP 51
|
||||
#define IRQ_MEMST 54
|
||||
#define IRQ_SGA_IT 58
|
||||
#define IRQ_USBM 60
|
||||
#define IRQ_MSP1 62
|
||||
|
||||
#define NOMADIK_SOC_NR_IRQS 64
|
||||
|
||||
/* After chip-specific IRQ numbers we have the GPIO ones */
|
||||
#define NOMADIK_NR_GPIO 128 /* last 4 not wired to pins */
|
||||
#define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + NOMADIK_SOC_NR_IRQS)
|
||||
#define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - NOMADIK_SOC_NR_IRQS)
|
||||
#define NR_IRQS NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
|
||||
|
||||
/* Following two are used by entry_macro.S, to access our dual-vic */
|
||||
#define VIC_REG_IRQSR0 0
|
||||
#define VIC_REG_IRQSR1 0x20
|
||||
|
||||
#endif /* __ASM_ARCH_IRQS_H */
|
||||
|
28
arch/arm/mach-nomadik/include/mach/memory.h
Normal file
28
arch/arm/mach-nomadik/include/mach/memory.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* mach-nomadik/include/mach/memory.h
|
||||
*
|
||||
* Copyright (C) 1999 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __ASM_ARCH_MEMORY_H
|
||||
#define __ASM_ARCH_MEMORY_H
|
||||
|
||||
/*
|
||||
* Physical DRAM offset.
|
||||
*/
|
||||
#define PHYS_OFFSET UL(0x00000000)
|
||||
|
||||
#endif
|
45
arch/arm/mach-nomadik/include/mach/mtu.h
Normal file
45
arch/arm/mach-nomadik/include/mach/mtu.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef __ASM_ARCH_MTU_H
|
||||
#define __ASM_ARCH_MTU_H
|
||||
|
||||
/*
|
||||
* The MTU device hosts four different counters, with 4 set of
|
||||
* registers. These are register names.
|
||||
*/
|
||||
|
||||
#define MTU_IMSC 0x00 /* Interrupt mask set/clear */
|
||||
#define MTU_RIS 0x04 /* Raw interrupt status */
|
||||
#define MTU_MIS 0x08 /* Masked interrupt status */
|
||||
#define MTU_ICR 0x0C /* Interrupt clear register */
|
||||
|
||||
/* per-timer registers take 0..3 as argument */
|
||||
#define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */
|
||||
#define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */
|
||||
#define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */
|
||||
#define MTU_BGLR(x) (0x10 + 0x10 * (x) + 0x0c) /* At next overflow */
|
||||
|
||||
/* bits for the control register */
|
||||
#define MTU_CRn_ENA 0x80
|
||||
#define MTU_CRn_PERIODIC 0x40 /* if 0 = free-running */
|
||||
#define MTU_CRn_PRESCALE_MASK 0x0c
|
||||
#define MTU_CRn_PRESCALE_1 0x00
|
||||
#define MTU_CRn_PRESCALE_16 0x04
|
||||
#define MTU_CRn_PRESCALE_256 0x08
|
||||
#define MTU_CRn_32BITS 0x02
|
||||
#define MTU_CRn_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR*/
|
||||
|
||||
/* Other registers are usual amba/primecell registers, currently not used */
|
||||
#define MTU_ITCR 0xff0
|
||||
#define MTU_ITOP 0xff4
|
||||
|
||||
#define MTU_PERIPH_ID0 0xfe0
|
||||
#define MTU_PERIPH_ID1 0xfe4
|
||||
#define MTU_PERIPH_ID2 0xfe8
|
||||
#define MTU_PERIPH_ID3 0xfeC
|
||||
|
||||
#define MTU_PCELL0 0xff0
|
||||
#define MTU_PCELL1 0xff4
|
||||
#define MTU_PCELL2 0xff8
|
||||
#define MTU_PCELL3 0xffC
|
||||
|
||||
#endif /* __ASM_ARCH_MTU_H */
|
||||
|
22
arch/arm/mach-nomadik/include/mach/setup.h
Normal file
22
arch/arm/mach-nomadik/include/mach/setup.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
/*
|
||||
* These symbols are needed for board-specific files to call their
|
||||
* own cpu-specific files
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_SETUP_H
|
||||
#define __ASM_ARCH_SETUP_H
|
||||
|
||||
#include <asm/mach/time.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#ifdef CONFIG_NOMADIK_8815
|
||||
|
||||
extern void cpu8815_map_io(void);
|
||||
extern void cpu8815_platform_init(void);
|
||||
extern void cpu8815_init_irq(void);
|
||||
extern struct sys_timer nomadik_timer;
|
||||
|
||||
#endif /* NOMADIK_8815 */
|
||||
|
||||
#endif /* __ASM_ARCH_SETUP_H */
|
45
arch/arm/mach-nomadik/include/mach/system.h
Normal file
45
arch/arm/mach-nomadik/include/mach/system.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* mach-nomadik/include/mach/system.h
|
||||
*
|
||||
* Copyright (C) 2008 STMicroelectronics
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __ASM_ARCH_SYSTEM_H
|
||||
#define __ASM_ARCH_SYSTEM_H
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
static inline void arch_idle(void)
|
||||
{
|
||||
/*
|
||||
* This should do all the clock switching
|
||||
* and wait for interrupt tricks
|
||||
*/
|
||||
cpu_do_idle();
|
||||
}
|
||||
|
||||
static inline void arch_reset(char mode, const char *cmd)
|
||||
{
|
||||
void __iomem *src_rstsr = io_p2v(NOMADIK_SRC_BASE + 0x18);
|
||||
|
||||
/* FIXME: use egpio when implemented */
|
||||
|
||||
/* Write anything to Reset status register */
|
||||
writel(1, src_rstsr);
|
||||
}
|
||||
|
||||
#endif
|
6
arch/arm/mach-nomadik/include/mach/timex.h
Normal file
6
arch/arm/mach-nomadik/include/mach/timex.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef __ASM_ARCH_TIMEX_H
|
||||
#define __ASM_ARCH_TIMEX_H
|
||||
|
||||
#define CLOCK_TICK_RATE 2400000
|
||||
|
||||
#endif
|
63
arch/arm/mach-nomadik/include/mach/uncompress.h
Normal file
63
arch/arm/mach-nomadik/include/mach/uncompress.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) 2008 STMicroelectronics
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_UNCOMPRESS_H
|
||||
#define __ASM_ARCH_UNCOMPRESS_H
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/io.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
/* we need the constants in amba/serial.h, but it refers to amba_device */
|
||||
struct amba_device;
|
||||
#include <linux/amba/serial.h>
|
||||
|
||||
#define NOMADIK_UART_DR 0x101FB000
|
||||
#define NOMADIK_UART_LCRH 0x101FB02c
|
||||
#define NOMADIK_UART_CR 0x101FB030
|
||||
#define NOMADIK_UART_FR 0x101FB018
|
||||
|
||||
static void putc(const char c)
|
||||
{
|
||||
/* Do nothing if the UART is not enabled. */
|
||||
if (!(readb(NOMADIK_UART_CR) & UART01x_CR_UARTEN))
|
||||
return;
|
||||
|
||||
if (c == '\n')
|
||||
putc('\r');
|
||||
|
||||
while (readb(NOMADIK_UART_FR) & UART01x_FR_TXFF)
|
||||
barrier();
|
||||
writeb(c, NOMADIK_UART_DR);
|
||||
}
|
||||
|
||||
static void flush(void)
|
||||
{
|
||||
if (!(readb(NOMADIK_UART_CR) & UART01x_CR_UARTEN))
|
||||
return;
|
||||
while (readb(NOMADIK_UART_FR) & UART01x_FR_BUSY)
|
||||
barrier();
|
||||
}
|
||||
|
||||
static inline void arch_decomp_setup(void)
|
||||
{
|
||||
}
|
||||
|
||||
#define arch_decomp_wdog() /* nothing to do here */
|
||||
|
||||
#endif /* __ASM_ARCH_UNCOMPRESS_H */
|
2
arch/arm/mach-nomadik/include/mach/vmalloc.h
Normal file
2
arch/arm/mach-nomadik/include/mach/vmalloc.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
|
||||
#define VMALLOC_END 0xe8000000
|
164
arch/arm/mach-nomadik/timer.c
Normal file
164
arch/arm/mach-nomadik/timer.c
Normal file
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-nomadik/timer.c
|
||||
*
|
||||
* Copyright (C) 2008 STMicroelectronics
|
||||
* Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <mach/mtu.h>
|
||||
|
||||
#define TIMER_CTRL 0x80 /* No divisor */
|
||||
#define TIMER_PERIODIC 0x40
|
||||
#define TIMER_SZ32BIT 0x02
|
||||
|
||||
/* Initial value for SRC control register: all timers use MXTAL/8 source */
|
||||
#define SRC_CR_INIT_MASK 0x00007fff
|
||||
#define SRC_CR_INIT_VAL 0x2aaa8000
|
||||
|
||||
static u32 nmdk_count; /* accumulated count */
|
||||
static u32 nmdk_cycle; /* write-once */
|
||||
static __iomem void *mtu_base;
|
||||
|
||||
/*
|
||||
* clocksource: the MTU device is a decrementing counters, so we negate
|
||||
* the value being read.
|
||||
*/
|
||||
static cycle_t nmdk_read_timer(struct clocksource *cs)
|
||||
{
|
||||
u32 count = readl(mtu_base + MTU_VAL(0));
|
||||
return nmdk_count + nmdk_cycle - count;
|
||||
|
||||
}
|
||||
|
||||
static struct clocksource nmdk_clksrc = {
|
||||
.name = "mtu_0",
|
||||
.rating = 120,
|
||||
.read = nmdk_read_timer,
|
||||
.shift = 20,
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
/*
|
||||
* Clockevent device: currently only periodic mode is supported
|
||||
*/
|
||||
static void nmdk_clkevt_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *dev)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
/* enable interrupts -- and count current value? */
|
||||
raw_local_irq_save(flags);
|
||||
writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
|
||||
raw_local_irq_restore(flags);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
BUG(); /* Not supported, yet */
|
||||
/* FALLTHROUGH */
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
/* disable irq */
|
||||
raw_local_irq_save(flags);
|
||||
writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
|
||||
raw_local_irq_restore(flags);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct clock_event_device nmdk_clkevt = {
|
||||
.name = "mtu_0",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC,
|
||||
.shift = 32,
|
||||
.rating = 100,
|
||||
.set_mode = nmdk_clkevt_mode,
|
||||
};
|
||||
|
||||
/*
|
||||
* IRQ Handler for the timer 0 of the MTU block. The irq is not shared
|
||||
* as we are the only users of mtu0 by now.
|
||||
*/
|
||||
static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
/* ack: "interrupt clear register" */
|
||||
writel( 1 << 0, mtu_base + MTU_ICR);
|
||||
|
||||
/* we can't count lost ticks, unfortunately */
|
||||
nmdk_count += nmdk_cycle;
|
||||
nmdk_clkevt.event_handler(&nmdk_clkevt);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up timer interrupt, and return the current time in seconds.
|
||||
*/
|
||||
static struct irqaction nmdk_timer_irq = {
|
||||
.name = "Nomadik Timer Tick",
|
||||
.flags = IRQF_DISABLED | IRQF_TIMER,
|
||||
.handler = nmdk_timer_interrupt,
|
||||
};
|
||||
|
||||
static void nmdk_timer_reset(void)
|
||||
{
|
||||
u32 cr;
|
||||
|
||||
writel(0, mtu_base + MTU_CR(0)); /* off */
|
||||
|
||||
/* configure load and background-load, and fire it up */
|
||||
writel(nmdk_cycle, mtu_base + MTU_LR(0));
|
||||
writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
|
||||
cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS;
|
||||
writel(cr, mtu_base + MTU_CR(0));
|
||||
writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
|
||||
}
|
||||
|
||||
static void __init nmdk_timer_init(void)
|
||||
{
|
||||
u32 src_cr;
|
||||
unsigned long rate;
|
||||
int bits;
|
||||
|
||||
rate = CLOCK_TICK_RATE; /* 2.4MHz */
|
||||
nmdk_cycle = (rate + HZ/2) / HZ;
|
||||
|
||||
/* Configure timer sources in "system reset controller" ctrl reg */
|
||||
src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
|
||||
src_cr &= SRC_CR_INIT_MASK;
|
||||
src_cr |= SRC_CR_INIT_VAL;
|
||||
writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
|
||||
|
||||
/* Save global pointer to mtu, used by functions above */
|
||||
mtu_base = io_p2v(NOMADIK_MTU0_BASE);
|
||||
|
||||
/* Init the timer and register clocksource */
|
||||
nmdk_timer_reset();
|
||||
|
||||
nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
|
||||
bits = 8*sizeof(nmdk_count);
|
||||
nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits);
|
||||
|
||||
clocksource_register(&nmdk_clksrc);
|
||||
|
||||
/* Register irq and clockevents */
|
||||
setup_irq(IRQ_MTU0, &nmdk_timer_irq);
|
||||
nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
|
||||
nmdk_clkevt.cpumask = cpumask_of(0);
|
||||
clockevents_register_device(&nmdk_clkevt);
|
||||
}
|
||||
|
||||
struct sys_timer nomadik_timer = {
|
||||
.init = nmdk_timer_init,
|
||||
};
|
|
@ -758,7 +758,7 @@ config CACHE_FEROCEON_L2_WRITETHROUGH
|
|||
config CACHE_L2X0
|
||||
bool "Enable the L2x0 outer cache controller"
|
||||
depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
|
||||
REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX
|
||||
REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK
|
||||
default y
|
||||
select OUTER_CACHE
|
||||
help
|
||||
|
|
Loading…
Reference in a new issue