提交 b7c11ec9 编写于 作者: R Russell King 提交者: Russell King

Merge branch 'u300' into devel

Conflicts:
	arch/arm/Makefile
Updates:
	arch/arm/mach-u300/core.c
	arch/arm/mach-u300/timer.c
......@@ -598,6 +598,20 @@ config ARCH_LH7A40X
core with a wide array of integrated devices for
hand-held and low-power applications.
config ARCH_U300
bool "ST-Ericsson U300 Series"
depends on MMU
select CPU_ARM926T
select ARM_AMBA
select ARM_VIC
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select HAVE_CLK
select COMMON_CLKDEV
select GENERIC_GPIO
help
Support for ST-Ericsson U300 series mobile platforms.
config ARCH_DAVINCI
bool "TI DaVinci"
select CPU_ARM926T
......@@ -712,6 +726,8 @@ source "arch/arm/mach-ks8695/Kconfig"
source "arch/arm/mach-msm/Kconfig"
source "arch/arm/mach-u300/Kconfig"
source "arch/arm/mach-w90x900/Kconfig"
# Definitions to make life easier
......
......@@ -154,6 +154,7 @@ machine-$(CONFIG_ARCH_SA1100) := sa1100
machine-$(CONFIG_ARCH_SHARK) := shark
machine-$(CONFIG_ARCH_STMP378X) := stmp378x
machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx
machine-$(CONFIG_ARCH_U300) := u300
machine-$(CONFIG_ARCH_VERSATILE) := versatile
machine-$(CONFIG_ARCH_W90X900) := w90x900
machine-$(CONFIG_FOOTBRIDGE) := footbridge
......
此差异已折叠。
if ARCH_U300
menu "ST-Ericsson AB U300/U330/U335/U365 Platform"
comment "ST-Ericsson Mobile Platform Products"
config MACH_U300
bool "U300"
comment "ST-Ericsson U300/U330/U335/U365 Feature Selections"
choice
prompt "U300/U330/U335/U365 system type"
default MACH_U300_BS2X
---help---
You need to select the target system, i.e. the
U300/U330/U335/U365 board that you want to compile your kernel
for.
config MACH_U300_BS2X
bool "S26/S26/B25/B26 Test Products"
depends on MACH_U300
help
Select this if you're developing on the
S26/S25 test products. (Also works on
B26/B25 big boards.)
config MACH_U300_BS330
bool "S330/B330 Test Products"
depends on MACH_U300
help
Select this if you're developing on the
S330/B330 test products.
config MACH_U300_BS335
bool "S335/B335 Test Products"
depends on MACH_U300
help
Select this if you're developing on the
S335/B335 test products.
config MACH_U300_BS365
bool "S365/B365 Test Products"
depends on MACH_U300
help
Select this if you're developing on the
S365/B365 test products.
endchoice
choice
prompt "Memory configuration"
default MACH_U300_SINGLE_RAM
---help---
You have to config the kernel according to the physical memory
configuration.
config MACH_U300_SINGLE_RAM
bool "Single RAM"
help
Select this if you want support for Single RAM phones.
config MACH_U300_DUAL_RAM
bool "Dual RAM"
help
Select this if you want support for Dual RAM phones.
This is two RAM memorys on different EMIFs.
endchoice
config U300_DEBUG
bool "Debug support for U300"
depends on PM
help
Debug support for U300 in sysfs, procfs etc.
config MACH_U300_SEMI_IS_SHARED
bool "The SEMI is used by both the access and application side"
depends on MACH_U300
help
This makes it possible to use the SEMI (Shared External
Memory Interface) from both from access and application
side.
comment "All the settings below must match the bootloader's settings"
config MACH_U300_ACCESS_MEM_SIZE
int "Access CPU memory allocation"
range 7 25
depends on MACH_U300_SINGLE_RAM
default 13
help
How much memory in MiB that the Access side CPU has allocated
config MACH_U300_2MB_ALIGNMENT_FIX
bool "2MiB alignment fix"
depends on MACH_U300_SINGLE_RAM
default y
help
If yes and the Access side CPU has allocated an odd size in
MiB, this fix gives you one MiB extra that would otherwise be
lost due to Linux 2 MiB alignment policy.
endmenu
endif
#
# Makefile for the linux kernel, U300 machine.
#
obj-y := core.o clock.o timer.o gpio.o padmux.o
obj-m :=
obj-n :=
obj- :=
obj-$(CONFIG_ARCH_U300) += u300.o
obj-$(CONFIG_MMC) += mmc.o
# Note: the following conditions must always be true:
# ZRELADDR == virt_to_phys(TEXTADDR)
# PARAMS_PHYS must be within 4MB of ZRELADDR
# INITRD_PHYS must be in RAM
ifdef CONFIG_MACH_U300_SINGLE_RAM
zreladdr-y := 0x28E08000
params_phys-y := 0x28E00100
else
zreladdr-y := 0x48008000
params_phys-y := 0x48000100
endif
# This isn't used.
#initrd_phys-y := 0x29800000
此差异已折叠。
/*
* arch/arm/mach-u300/include/mach/clock.h
*
* Copyright (C) 2004 - 2005 Nokia corporation
* Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
* Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
* Copyright (C) 2007-2009 ST-Ericsson AB
* Adopted to ST-Ericsson U300 platforms by
* Jonas Aaberg <jonas.aberg@stericsson.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.
*
*/
#ifndef __MACH_CLOCK_H
#define __MACH_CLOCK_H
#include <linux/clk.h>
struct clk {
struct list_head node;
struct module *owner;
struct device *dev;
const char *name;
struct clk *parent;
spinlock_t lock;
unsigned long rate;
bool reset;
__u16 clk_val;
__s8 usecount;
__u32 res_reg;
__u16 res_mask;
bool hw_ctrld;
void (*recalc) (struct clk *);
int (*set_rate) (struct clk *, unsigned long);
unsigned long (*get_rate) (struct clk *);
unsigned long (*round_rate) (struct clk *, unsigned long);
void (*init) (struct clk *);
void (*enable) (struct clk *);
void (*disable) (struct clk *);
};
void u300_clock_primecells(void);
void u300_unclock_primecells(void);
void u300_enable_intcon_clock(void);
void u300_enable_timer_clock(void);
#endif
/*
*
* arch/arm/mach-u300/core.c
*
*
* Copyright (C) 2007-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* Core platform support, IRQ handling and device definitions.
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <linux/termios.h>
#include <linux/amba/bus.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/hardware/vic.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <mach/hardware.h>
#include <mach/syscon.h>
#include "clock.h"
#include "mmc.h"
/*
* Static I/O mappings that are needed for booting the U300 platforms. The
* only things we need are the areas where we find the timer, syscon and
* intcon, since the remaining device drivers will map their own memory
* physical to virtual as the need arise.
*/
static struct map_desc u300_io_desc[] __initdata = {
{
.virtual = U300_SLOW_PER_VIRT_BASE,
.pfn = __phys_to_pfn(U300_SLOW_PER_PHYS_BASE),
.length = SZ_64K,
.type = MT_DEVICE,
},
{
.virtual = U300_AHB_PER_VIRT_BASE,
.pfn = __phys_to_pfn(U300_AHB_PER_PHYS_BASE),
.length = SZ_32K,
.type = MT_DEVICE,
},
{
.virtual = U300_FAST_PER_VIRT_BASE,
.pfn = __phys_to_pfn(U300_FAST_PER_PHYS_BASE),
.length = SZ_32K,
.type = MT_DEVICE,
},
{
.virtual = 0xffff2000, /* TCM memory */
.pfn = __phys_to_pfn(0xffff2000),
.length = SZ_16K,
.type = MT_DEVICE,
},
/*
* This overlaps with the IRQ vectors etc at 0xffff0000, so these
* may have to be moved to 0x00000000 in order to use the ROM.
*/
/*
{
.virtual = U300_BOOTROM_VIRT_BASE,
.pfn = __phys_to_pfn(U300_BOOTROM_PHYS_BASE),
.length = SZ_64K,
.type = MT_ROM,
},
*/
};
void __init u300_map_io(void)
{
iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc));
}
/*
* Declaration of devices found on the U300 board and
* their respective memory locations.
*/
static struct amba_device uart0_device = {
.dev = {
.init_name = "uart0", /* Slow device at 0x3000 offset */
.platform_data = NULL,
},
.res = {
.start = U300_UART0_BASE,
.end = U300_UART0_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
.irq = { IRQ_U300_UART0, NO_IRQ },
};
/* The U335 have an additional UART1 on the APP CPU */
#ifdef CONFIG_MACH_U300_BS335
static struct amba_device uart1_device = {
.dev = {
.init_name = "uart1", /* Fast device at 0x7000 offset */
.platform_data = NULL,
},
.res = {
.start = U300_UART1_BASE,
.end = U300_UART1_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
.irq = { IRQ_U300_UART1, NO_IRQ },
};
#endif
static struct amba_device pl172_device = {
.dev = {
.init_name = "pl172", /* AHB device at 0x4000 offset */
.platform_data = NULL,
},
.res = {
.start = U300_EMIF_CFG_BASE,
.end = U300_EMIF_CFG_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
};
/*
* Everything within this next ifdef deals with external devices connected to
* the APP SPI bus.
*/
static struct amba_device pl022_device = {
.dev = {
.coherent_dma_mask = ~0,
.init_name = "pl022", /* Fast device at 0x6000 offset */
},
.res = {
.start = U300_SPI_BASE,
.end = U300_SPI_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
.irq = {IRQ_U300_SPI, NO_IRQ },
/*
* This device has a DMA channel but the Linux driver does not use
* it currently.
*/
};
static struct amba_device mmcsd_device = {
.dev = {
.init_name = "mmci", /* Fast device at 0x1000 offset */
.platform_data = NULL, /* Added later */
},
.res = {
.start = U300_MMCSD_BASE,
.end = U300_MMCSD_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
.irq = {IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 },
/*
* This device has a DMA channel but the Linux driver does not use
* it currently.
*/
};
/*
* The order of device declaration may be important, since some devices
* have dependencies on other devices being initialized first.
*/
static struct amba_device *amba_devs[] __initdata = {
&uart0_device,
#ifdef CONFIG_MACH_U300_BS335
&uart1_device,
#endif
&pl022_device,
&pl172_device,
&mmcsd_device,
};
/* Here follows a list of all hw resources that the platform devices
* allocate. Note, clock dependencies are not included
*/
static struct resource gpio_resources[] = {
{
.start = U300_GPIO_BASE,
.end = (U300_GPIO_BASE + SZ_4K - 1),
.flags = IORESOURCE_MEM,
},
{
.name = "gpio0",
.start = IRQ_U300_GPIO_PORT0,
.end = IRQ_U300_GPIO_PORT0,
.flags = IORESOURCE_IRQ,
},
{
.name = "gpio1",
.start = IRQ_U300_GPIO_PORT1,
.end = IRQ_U300_GPIO_PORT1,
.flags = IORESOURCE_IRQ,
},
{
.name = "gpio2",
.start = IRQ_U300_GPIO_PORT2,
.end = IRQ_U300_GPIO_PORT2,
.flags = IORESOURCE_IRQ,
},
#ifdef U300_COH901571_3
{
.name = "gpio3",
.start = IRQ_U300_GPIO_PORT3,
.end = IRQ_U300_GPIO_PORT3,
.flags = IORESOURCE_IRQ,
},
{
.name = "gpio4",
.start = IRQ_U300_GPIO_PORT4,
.end = IRQ_U300_GPIO_PORT4,
.flags = IORESOURCE_IRQ,
},
#ifdef CONFIG_MACH_U300_BS335
{
.name = "gpio5",
.start = IRQ_U300_GPIO_PORT5,
.end = IRQ_U300_GPIO_PORT5,
.flags = IORESOURCE_IRQ,
},
{
.name = "gpio6",
.start = IRQ_U300_GPIO_PORT6,
.end = IRQ_U300_GPIO_PORT6,
.flags = IORESOURCE_IRQ,
},
#endif /* CONFIG_MACH_U300_BS335 */
#endif /* U300_COH901571_3 */
};
static struct resource keypad_resources[] = {
{
.start = U300_KEYPAD_BASE,
.end = U300_KEYPAD_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{
.name = "coh901461-press",
.start = IRQ_U300_KEYPAD_KEYBF,
.end = IRQ_U300_KEYPAD_KEYBF,
.flags = IORESOURCE_IRQ,
},
{
.name = "coh901461-release",
.start = IRQ_U300_KEYPAD_KEYBR,
.end = IRQ_U300_KEYPAD_KEYBR,
.flags = IORESOURCE_IRQ,
},
};
static struct resource rtc_resources[] = {
{
.start = U300_RTC_BASE,
.end = U300_RTC_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_U300_RTC,
.end = IRQ_U300_RTC,
.flags = IORESOURCE_IRQ,
},
};
/*
* Fsmc does have IRQs: #43 and #44 (NFIF and NFIF2)
* but these are not yet used by the driver.
*/
static struct resource fsmc_resources[] = {
{
.start = U300_NAND_IF_PHYS_BASE,
.end = U300_NAND_IF_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
};
static struct resource i2c0_resources[] = {
{
.start = U300_I2C0_BASE,
.end = U300_I2C0_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_U300_I2C0,
.end = IRQ_U300_I2C0,
.flags = IORESOURCE_IRQ,
},
};
static struct resource i2c1_resources[] = {
{
.start = U300_I2C1_BASE,
.end = U300_I2C1_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_U300_I2C1,
.end = IRQ_U300_I2C1,
.flags = IORESOURCE_IRQ,
},
};
static struct resource wdog_resources[] = {
{
.start = U300_WDOG_BASE,
.end = U300_WDOG_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_U300_WDOG,
.end = IRQ_U300_WDOG,
.flags = IORESOURCE_IRQ,
}
};
/* TODO: These should be protected by suitable #ifdef's */
static struct resource ave_resources[] = {
{
.name = "AVE3e I/O Area",
.start = U300_VIDEOENC_BASE,
.end = U300_VIDEOENC_BASE + SZ_512K - 1,
.flags = IORESOURCE_MEM,
},
{
.name = "AVE3e IRQ0",
.start = IRQ_U300_VIDEO_ENC_0,
.end = IRQ_U300_VIDEO_ENC_0,
.flags = IORESOURCE_IRQ,
},
{
.name = "AVE3e IRQ1",
.start = IRQ_U300_VIDEO_ENC_1,
.end = IRQ_U300_VIDEO_ENC_1,
.flags = IORESOURCE_IRQ,
},
{
.name = "AVE3e Physmem Area",
.start = 0, /* 0 will be remapped to reserved memory */
.end = SZ_1M - 1,
.flags = IORESOURCE_MEM,
},
/*
* The AVE3e requires two regions of 256MB that it considers
* "invisible". The hardware will not be able to access these
* adresses, so they should never point to system RAM.
*/
{
.name = "AVE3e Reserved 0",
.start = 0xd0000000,
.end = 0xd0000000 + SZ_256M - 1,
.flags = IORESOURCE_MEM,
},
{
.name = "AVE3e Reserved 1",
.start = 0xe0000000,
.end = 0xe0000000 + SZ_256M - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device wdog_device = {
.name = "wdog",
.id = -1,
.num_resources = ARRAY_SIZE(wdog_resources),
.resource = wdog_resources,
};
static struct platform_device i2c0_device = {
.name = "stddci2c",
.id = 0,
.num_resources = ARRAY_SIZE(i2c0_resources),
.resource = i2c0_resources,
};
static struct platform_device i2c1_device = {
.name = "stddci2c",
.id = 1,
.num_resources = ARRAY_SIZE(i2c1_resources),
.resource = i2c1_resources,
};
static struct platform_device gpio_device = {
.name = "u300-gpio",
.id = -1,
.num_resources = ARRAY_SIZE(gpio_resources),
.resource = gpio_resources,
};
static struct platform_device keypad_device = {
.name = "keypad",
.id = -1,
.num_resources = ARRAY_SIZE(keypad_resources),
.resource = keypad_resources,
};
static struct platform_device rtc_device = {
.name = "rtc0",
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
};
static struct platform_device fsmc_device = {
.name = "nandif",
.id = -1,
.num_resources = ARRAY_SIZE(fsmc_resources),
.resource = fsmc_resources,
};
static struct platform_device ave_device = {
.name = "video_enc",
.id = -1,
.num_resources = ARRAY_SIZE(ave_resources),
.resource = ave_resources,
};
/*
* Notice that AMBA devices are initialized before platform devices.
*
*/
static struct platform_device *platform_devs[] __initdata = {
&i2c0_device,
&i2c1_device,
&keypad_device,
&rtc_device,
&gpio_device,
&fsmc_device,
&wdog_device,
&ave_device
};
/*
* Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected
* together so some interrupts are connected to the first one and some
* to the second one.
*/
void __init u300_init_irq(void)
{
u32 mask[2] = {0, 0};
int i;
for (i = 0; i < NR_IRQS; i++)
set_bit(i, (unsigned long *) &mask[0]);
u300_enable_intcon_clock();
vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], 0);
vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], 0);
}
/*
* U300 platforms peripheral handling
*/
struct db_chip {
u16 chipid;
const char *name;
};
/*
* This is a list of the Digital Baseband chips used in the U300 platform.
*/
static struct db_chip db_chips[] __initdata = {
{
.chipid = 0xb800,
.name = "DB3000",
},
{
.chipid = 0xc000,
.name = "DB3100",
},
{
.chipid = 0xc800,
.name = "DB3150",
},
{
.chipid = 0xd800,
.name = "DB3200",
},
{
.chipid = 0xe000,
.name = "DB3250",
},
{
.chipid = 0xe800,
.name = "DB3210",
},
{
.chipid = 0xf000,
.name = "DB3350 P1x",
},
{
.chipid = 0xf100,
.name = "DB3350 P2x",
},
{
.chipid = 0x0000, /* List terminator */
.name = NULL,
}
};
static void u300_init_check_chip(void)
{
u16 val;
struct db_chip *chip;
const char *chipname;
const char unknown[] = "UNKNOWN";
/* Read out and print chip ID */
val = readw(U300_SYSCON_VBASE + U300_SYSCON_CIDR);
/* This is in funky bigendian order... */
val = (val & 0xFFU) << 8 | (val >> 8);
chip = db_chips;
chipname = unknown;
for ( ; chip->chipid; chip++) {
if (chip->chipid == (val & 0xFF00U)) {
chipname = chip->name;
break;
}
}
printk(KERN_INFO "Initializing U300 system on %s baseband chip " \
"(chip ID 0x%04x)\n", chipname, val);
#ifdef CONFIG_MACH_U300_BS26
if ((val & 0xFF00U) != 0xc800) {
printk(KERN_ERR "Platform configured for BS25/BS26 " \
"with DB3150 but %s detected, expect problems!",
chipname);
}
#endif
#ifdef CONFIG_MACH_U300_BS330
if ((val & 0xFF00U) != 0xd800) {
printk(KERN_ERR "Platform configured for BS330 " \
"with DB3200 but %s detected, expect problems!",
chipname);
}
#endif
#ifdef CONFIG_MACH_U300_BS335
if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) {
printk(KERN_ERR "Platform configured for BS365 " \
" with DB3350 but %s detected, expect problems!",
chipname);
}
#endif
#ifdef CONFIG_MACH_U300_BS365
if ((val & 0xFF00U) != 0xe800) {
printk(KERN_ERR "Platform configured for BS365 " \
"with DB3210 but %s detected, expect problems!",
chipname);
}
#endif
}
/*
* Some devices and their resources require reserved physical memory from
* the end of the available RAM. This function traverses the list of devices
* and assigns actual adresses to these.
*/
static void __init u300_assign_physmem(void)
{
unsigned long curr_start = __pa(high_memory);
int i, j;
for (i = 0; i < ARRAY_SIZE(platform_devs); i++) {
for (j = 0; j < platform_devs[i]->num_resources; j++) {
struct resource *const res =
&platform_devs[i]->resource[j];
if (IORESOURCE_MEM == res->flags &&
0 == res->start) {
res->start = curr_start;
res->end += curr_start;
curr_start += (res->end - res->start + 1);
printk(KERN_INFO "core.c: Mapping RAM " \
"%#x-%#x to device %s:%s\n",
res->start, res->end,
platform_devs[i]->name, res->name);
}
}
}
}
void __init u300_init_devices(void)
{
int i;
u16 val;
/* Check what platform we run and print some status information */
u300_init_check_chip();
/* Set system to run at PLL208, max performance, a known state. */
val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
/* Wait for the PLL208 to lock if not locked in yet */
while (!(readw(U300_SYSCON_VBASE + U300_SYSCON_CSR) &
U300_SYSCON_CSR_PLL208_LOCK_IND));
/* Register the AMBA devices in the AMBA bus abstraction layer */
u300_clock_primecells();
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
}
u300_unclock_primecells();
u300_assign_physmem();
/* Register the platform devices */
platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
#ifndef CONFIG_MACH_U300_SEMI_IS_SHARED
/*
* Enable SEMI self refresh. Self-refresh of the SDRAM is entered when
* both subsystems are requesting this mode.
* If we not share the Acc SDRAM, this is never the case. Therefore
* enable it here from the App side.
*/
val = readw(U300_SYSCON_VBASE + U300_SYSCON_SMCR) |
U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE;
writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR);
#endif /* CONFIG_MACH_U300_SEMI_IS_SHARED */
}
static int core_module_init(void)
{
/*
* This needs to be initialized later: it needs the input framework
* to be initialized first.
*/
return mmc_init(&mmcsd_device);
}
module_init(core_module_init);
/*
*
* arch/arm/mach-u300/gpio.c
*
*
* Copyright (C) 2007-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* U300 GPIO module.
* This can driver either of the two basic GPIO cores
* available in the U300 platforms:
* COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0)
* COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0)
* Notice that you also have inline macros in <asm-arch/gpio.h>
* Author: Linus Walleij <linus.walleij@stericsson.com>
* Author: Jonas Aaberg <jonas.aberg@stericsson.com>
*
*/
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
/* Need access to SYSCON registers for PADmuxing */
#include <mach/syscon.h>
#include "padmux.h"
/* Reference to GPIO block clock */
static struct clk *clk;
/* Memory resource */
static struct resource *memres;
static void __iomem *virtbase;
static struct device *gpiodev;
struct u300_gpio_port {
const char *name;
int irq;
int number;
};
static struct u300_gpio_port gpio_ports[] = {
{
.name = "gpio0",
.number = 0,
},
{
.name = "gpio1",
.number = 1,
},
{
.name = "gpio2",
.number = 2,
},
#ifdef U300_COH901571_3
{
.name = "gpio3",
.number = 3,
},
{
.name = "gpio4",
.number = 4,
},
#ifdef CONFIG_MACH_U300_BS335
{
.name = "gpio5",
.number = 5,
},
{
.name = "gpio6",
.number = 6,
},
#endif
#endif
};
#ifdef U300_COH901571_3
/* Default input value */
#define DEFAULT_OUTPUT_LOW 0
#define DEFAULT_OUTPUT_HIGH 1
/* GPIO Pull-Up status */
#define DISABLE_PULL_UP 0
#define ENABLE_PULL_UP 1
#define GPIO_NOT_USED 0
#define GPIO_IN 1
#define GPIO_OUT 2
struct u300_gpio_configuration_data {
unsigned char pin_usage;
unsigned char default_output_value;
unsigned char pull_up;
};
/* Initial configuration */
const struct u300_gpio_configuration_data
u300_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
#ifdef CONFIG_MACH_U300_BS335
/* Port 0, pins 0-7 */
{
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
},
/* Port 1, pins 0-7 */
{
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
},
/* Port 2, pins 0-7 */
{
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
},
/* Port 3, pins 0-7 */
{
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
},
/* Port 4, pins 0-7 */
{
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
},
/* Port 5, pins 0-7 */
{
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
},
/* Port 6, pind 0-7 */
{
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
}
#endif
#ifdef CONFIG_MACH_U300_BS365
/* Port 0, pins 0-7 */
{
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
},
/* Port 1, pins 0-7 */
{
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
},
/* Port 2, pins 0-7 */
{
{GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
},
/* Port 3, pins 0-7 */
{
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
},
/* Port 4, pins 0-7 */
{
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
/* These 4 pins doesn't exist on DB3210 */
{GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
{GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
}
#endif
};
#endif
/* No users == we can power down GPIO */
static int gpio_users;
struct gpio_struct {
int (*callback)(void *);
void *data;
int users;
};
static struct gpio_struct gpio_pin[U300_GPIO_MAX];
/*
* Let drivers register callback in order to get notified when there is
* an interrupt on the gpio pin
*/
int gpio_register_callback(unsigned gpio, int (*func)(void *arg), void *data)
{
if (gpio_pin[gpio].callback)
dev_warn(gpiodev, "%s: WARNING: callback already "
"registered for gpio pin#%d\n", __func__, gpio);
gpio_pin[gpio].callback = func;
gpio_pin[gpio].data = data;
return 0;
}
EXPORT_SYMBOL(gpio_register_callback);
int gpio_unregister_callback(unsigned gpio)
{
if (!gpio_pin[gpio].callback)
dev_warn(gpiodev, "%s: WARNING: callback already "
"unregistered for gpio pin#%d\n", __func__, gpio);
gpio_pin[gpio].callback = NULL;
gpio_pin[gpio].data = NULL;
return 0;
}
EXPORT_SYMBOL(gpio_unregister_callback);
int gpio_request(unsigned gpio, const char *label)
{
if (gpio_pin[gpio].users)
return -EINVAL;
else
gpio_pin[gpio].users++;
gpio_users++;
return 0;
}
EXPORT_SYMBOL(gpio_request);
void gpio_free(unsigned gpio)
{
gpio_users--;
gpio_pin[gpio].users--;
if (unlikely(gpio_pin[gpio].users < 0)) {
dev_warn(gpiodev, "warning: gpio#%d release mismatch\n",
gpio);
gpio_pin[gpio].users = 0;
}
return;
}
EXPORT_SYMBOL(gpio_free);
/* This returns zero or nonzero */
int gpio_get_value(unsigned gpio)
{
return readl(virtbase + U300_GPIO_PXPDIR +
PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) & (1 << (gpio & 0x07));
}
EXPORT_SYMBOL(gpio_get_value);
/*
* We hope that the compiler will optimize away the unused branch
* in case "value" is a constant
*/
void gpio_set_value(unsigned gpio, int value)
{
u32 val;
unsigned long flags;
local_irq_save(flags);
if (value) {
/* set */
val = readl(virtbase + U300_GPIO_PXPDOR +
PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
& (1 << (gpio & 0x07));
writel(val | (1 << (gpio & 0x07)), virtbase +
U300_GPIO_PXPDOR +
PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
} else {
/* clear */
val = readl(virtbase + U300_GPIO_PXPDOR +
PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
& (1 << (gpio & 0x07));
writel(val & ~(1 << (gpio & 0x07)), virtbase +
U300_GPIO_PXPDOR +
PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
}
local_irq_restore(flags);
}
EXPORT_SYMBOL(gpio_set_value);
int gpio_direction_input(unsigned gpio)
{
unsigned long flags;
u32 val;
if (gpio > U300_GPIO_MAX)
return -EINVAL;
local_irq_save(flags);
val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
U300_GPIO_PORTX_SPACING);
/* Mask out this pin*/
val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
/* This is not needed since it sets the bits to zero.*/
/* val |= (U300_GPIO_PXPCR_PIN_MODE_INPUT << (gpio*2)); */
writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
U300_GPIO_PORTX_SPACING);
local_irq_restore(flags);
return 0;
}
EXPORT_SYMBOL(gpio_direction_input);
int gpio_direction_output(unsigned gpio, int value)
{
unsigned long flags;
u32 val;
if (gpio > U300_GPIO_MAX)
return -EINVAL;
local_irq_save(flags);
val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
U300_GPIO_PORTX_SPACING);
/* Mask out this pin */
val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
/*
* FIXME: configure for push/pull, open drain or open source per pin
* in setup. The current driver will only support push/pull.
*/
val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL
<< ((gpio & 0x07) << 1));
writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
U300_GPIO_PORTX_SPACING);
gpio_set_value(gpio, value);
local_irq_restore(flags);
return 0;
}
EXPORT_SYMBOL(gpio_direction_output);
/*
* Enable an IRQ, edge is rising edge (!= 0) or falling edge (==0).
*/
void enable_irq_on_gpio_pin(unsigned gpio, int edge)
{
u32 val;
unsigned long flags;
local_irq_save(flags);
val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
U300_GPIO_PORTX_SPACING);
val |= (1 << (gpio & 0x07));
writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
U300_GPIO_PORTX_SPACING);
val = readl(virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
U300_GPIO_PORTX_SPACING);
if (edge)
val |= (1 << (gpio & 0x07));
else
val &= ~(1 << (gpio & 0x07));
writel(val, virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
U300_GPIO_PORTX_SPACING);
local_irq_restore(flags);
}
EXPORT_SYMBOL(enable_irq_on_gpio_pin);
void disable_irq_on_gpio_pin(unsigned gpio)
{
u32 val;
unsigned long flags;
local_irq_save(flags);
val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
U300_GPIO_PORTX_SPACING);
val &= ~(1 << (gpio & 0x07));
writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
U300_GPIO_PORTX_SPACING);
local_irq_restore(flags);
}
EXPORT_SYMBOL(disable_irq_on_gpio_pin);
/* Enable (value == 0) or disable (value == 1) internal pullup */
void gpio_pullup(unsigned gpio, int value)
{
u32 val;
unsigned long flags;
local_irq_save(flags);
if (value) {
val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
U300_GPIO_PORTX_SPACING);
writel(val | (1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
} else {
val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
U300_GPIO_PORTX_SPACING);
writel(val & ~(1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
}
local_irq_restore(flags);
}
EXPORT_SYMBOL(gpio_pullup);
static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
{
struct u300_gpio_port *port = dev_id;
u32 val;
int pin;
/* Read event register */
val = readl(virtbase + U300_GPIO_PXIEV + port->number *
U300_GPIO_PORTX_SPACING);
/* Mask with enable register */
val &= readl(virtbase + U300_GPIO_PXIEV + port->number *
U300_GPIO_PORTX_SPACING);
/* Mask relevant bits */
val &= U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK;
/* ACK IRQ (clear event) */
writel(val, virtbase + U300_GPIO_PXIEV + port->number *
U300_GPIO_PORTX_SPACING);
/* Print message */
while (val != 0) {
unsigned gpio;
pin = __ffs(val);
/* mask off this pin */
val &= ~(1 << pin);
gpio = (port->number << 3) + pin;
if (gpio_pin[gpio].callback)
(void)gpio_pin[gpio].callback(gpio_pin[gpio].data);
else
dev_dbg(gpiodev, "stray GPIO IRQ on line %d\n",
gpio);
}
return IRQ_HANDLED;
}
static void gpio_set_initial_values(void)
{
#ifdef U300_COH901571_3
int i, j;
unsigned long flags;
u32 val;
/* Write default values to all pins */
for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
val = 0;
for (j = 0; j < 8; j++)
val |= (u32) (u300_gpio_config[i][j].default_output_value != DEFAULT_OUTPUT_LOW) << j;
local_irq_save(flags);
writel(val, virtbase + U300_GPIO_PXPDOR + i * U300_GPIO_PORTX_SPACING);
local_irq_restore(flags);
}
/*
* Put all pins that are set to either 'GPIO_OUT' or 'GPIO_NOT_USED'
* to output and 'GPIO_IN' to input for each port. And initalize
* default value on outputs.
*/
for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
for (j = 0; j < U300_GPIO_PINS_PER_PORT; j++) {
local_irq_save(flags);
val = readl(virtbase + U300_GPIO_PXPCR +
i * U300_GPIO_PORTX_SPACING);
/* Mask out this pin */
val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << (j << 1));
if (u300_gpio_config[i][j].pin_usage != GPIO_IN)
val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL << (j << 1));
writel(val, virtbase + U300_GPIO_PXPCR +
i * U300_GPIO_PORTX_SPACING);
local_irq_restore(flags);
}
}
/* Enable or disable the internal pull-ups in the GPIO ASIC block */
for (i = 0; i < U300_GPIO_MAX; i++) {
val = 0;
for (j = 0; j < 8; j++)
val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP)) << j;
local_irq_save(flags);
writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING);
local_irq_restore(flags);
}
#endif
}
static int __init gpio_probe(struct platform_device *pdev)
{
u32 val;
int err = 0;
int i;
int num_irqs;
gpiodev = &pdev->dev;
memset(gpio_pin, 0, sizeof(gpio_pin));
/* Get GPIO clock */
clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(clk)) {
err = PTR_ERR(clk);
dev_err(gpiodev, "could not get GPIO clock\n");
goto err_no_clk;
}
err = clk_enable(clk);
if (err) {
dev_err(gpiodev, "could not enable GPIO clock\n");
goto err_no_clk_enable;
}
memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!memres)
goto err_no_resource;
if (request_mem_region(memres->start, memres->end - memres->start, "GPIO Controller")
== NULL) {
err = -ENODEV;
goto err_no_ioregion;
}
virtbase = ioremap(memres->start, resource_size(memres));
if (!virtbase) {
err = -ENOMEM;
goto err_no_ioremap;
}
dev_info(gpiodev, "remapped 0x%08x to %p\n",
memres->start, virtbase);
#ifdef U300_COH901335
dev_info(gpiodev, "initializing GPIO Controller COH 901 335\n");
/* Turn on the GPIO block */
writel(U300_GPIO_CR_BLOCK_CLOCK_ENABLE, virtbase + U300_GPIO_CR);
#endif
#ifdef U300_COH901571_3
dev_info(gpiodev, "initializing GPIO Controller COH 901 571/3\n");
val = readl(virtbase + U300_GPIO_CR);
dev_info(gpiodev, "COH901571/3 block version: %d, " \
"number of cores: %d\n",
((val & 0x0000FE00) >> 9),
((val & 0x000001FC) >> 2));
writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, virtbase + U300_GPIO_CR);
#endif
/* Set up some padmuxing here */
#ifdef CONFIG_MMC
pmx_set_mission_mode_mmc();
#endif
#ifdef CONFIG_SPI_PL022
pmx_set_mission_mode_spi();
#endif
gpio_set_initial_values();
for (num_irqs = 0 ; num_irqs < U300_GPIO_NUM_PORTS; num_irqs++) {
gpio_ports[num_irqs].irq =
platform_get_irq_byname(pdev,
gpio_ports[num_irqs].name);
err = request_irq(gpio_ports[num_irqs].irq,
gpio_irq_handler, IRQF_DISABLED,
gpio_ports[num_irqs].name,
&gpio_ports[num_irqs]);
if (err) {
dev_err(gpiodev, "cannot allocate IRQ for %s!\n",
gpio_ports[num_irqs].name);
goto err_no_irq;
}
/* Turns off PortX_irq_force */
writel(0x0, virtbase + U300_GPIO_PXIFR +
num_irqs * U300_GPIO_PORTX_SPACING);
}
return 0;
err_no_irq:
for (i = 0; i < num_irqs; i++)
free_irq(gpio_ports[i].irq, &gpio_ports[i]);
iounmap(virtbase);
err_no_ioremap:
release_mem_region(memres->start, memres->end - memres->start);
err_no_ioregion:
err_no_resource:
clk_disable(clk);
err_no_clk_enable:
clk_put(clk);
err_no_clk:
dev_info(gpiodev, "module ERROR:%d\n", err);
return err;
}
static int __exit gpio_remove(struct platform_device *pdev)
{
int i;
/* Turn off the GPIO block */
writel(0x00000000U, virtbase + U300_GPIO_CR);
for (i = 0 ; i < U300_GPIO_NUM_PORTS; i++)
free_irq(gpio_ports[i].irq, &gpio_ports[i]);
iounmap(virtbase);
release_mem_region(memres->start, memres->end - memres->start);
clk_disable(clk);
clk_put(clk);
return 0;
}
static struct platform_driver gpio_driver = {
.driver = {
.name = "u300-gpio",
},
.remove = __exit_p(gpio_remove),
};
static int __init u300_gpio_init(void)
{
return platform_driver_probe(&gpio_driver, gpio_probe);
}
static void __exit u300_gpio_exit(void)
{
platform_driver_unregister(&gpio_driver);
}
arch_initcall(u300_gpio_init);
module_exit(u300_gpio_exit);
MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
#ifdef U300_COH901571_3
MODULE_DESCRIPTION("ST-Ericsson AB COH 901 571/3 GPIO driver");
#endif
#ifdef U300_COH901335
MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335 GPIO driver");
#endif
MODULE_LICENSE("GPL");
#ifndef __MACH_CLKDEV_H
#define __MACH_CLKDEV_H
int __clk_get(struct clk *clk);
void __clk_put(struct clk *clk);
#endif
/*
*
* arch-arm/mach-u300/include/mach/debug-macro.S
*
*
* Copyright (C) 2006-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* Debugging macro include header.
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#include <mach/hardware.h>
.macro addruart,rx
/* If we move the adress using MMU, use this. */
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
ldreq \rx, = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address
ldrne \rx, = U300_SLOW_PER_VIRT_BASE @ MMU on, virtual address
orr \rx, \rx, #0x00003000
.endm
#include <asm/hardware/debug-pl01x.S>
/*
*
* arch-arm/mach-u300/include/mach/entry-macro.S
*
*
* Copyright (C) 2006-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* Low-level IRQ helper macros for ST-Ericsson U300
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#include <mach/hardware.h>
#include <asm/hardware/vic.h>
.macro disable_fiq
.endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON0_BASE
ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status
mov \irqnr, #0
teq \irqstat, #0
bne 1002f
1001: ldr \base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON1_BASE
ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status
mov \irqnr, #32
teq \irqstat, #0
beq 1003f
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
/*
*
* arch/arm/mach-u300/include/mach/gpio.h
*
*
* Copyright (C) 2007-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* GPIO block resgister definitions and inline macros for
* U300 GPIO COH 901 335 or COH 901 571/3
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#ifndef __MACH_U300_GPIO_H
#define __MACH_U300_GPIO_H
#include <linux/kernel.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/irq.h>
/* Switch type depending on platform/chip variant */
#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
#define U300_COH901335
#endif
#if defined(CONFIG_MACH_U300_BS365) || defined(CONFIG_MACH_U300_BS335)
#define U300_COH901571_3
#endif
/* Get base address for regs here */
#include "u300-regs.h"
/* IRQ numbers */
#include "irqs.h"
/*
* This is the GPIO block definitions. GPIO (General Purpose I/O) can be
* used for anything, and often is. The event/enable etc figures are for
* the lowermost pin (pin 0 on each port), shift this left to match your
* pin if you're gonna use these values.
*/
#ifdef U300_COH901335
#define U300_GPIO_PORTX_SPACING (0x1C)
/* Port X Pin Data Register 32bit, this is both input and output (R/W) */
#define U300_GPIO_PXPDIR (0x00)
#define U300_GPIO_PXPDOR (0x00)
/* Port X Pin Config Register 32bit (R/W) */
#define U300_GPIO_PXPCR (0x04)
#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL)
#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL)
#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL)
#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL)
#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL)
#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL)
#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL)
/* Port X Interrupt Event Register 32bit (R/W) */
#define U300_GPIO_PXIEV (0x08)
#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK (0x000000FFUL)
#define U300_GPIO_PXIEV_IRQ_EVENT (0x00000001UL)
/* Port X Interrupt Enable Register 32bit (R/W) */
#define U300_GPIO_PXIEN (0x0C)
#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK (0x000000FFUL)
#define U300_GPIO_PXIEN_IRQ_ENABLE (0x00000001UL)
/* Port X Interrupt Force Register 32bit (R/W) */
#define U300_GPIO_PXIFR (0x10)
#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK (0x000000FFUL)
#define U300_GPIO_PXIFR_IRQ_FORCE (0x00000001UL)
/* Port X Interrupt Config Register 32bit (R/W) */
#define U300_GPIO_PXICR (0x14)
#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL)
#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL)
#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL)
#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL)
/* Port X Pull-up Enable Register 32bit (R/W) */
#define U300_GPIO_PXPER (0x18)
#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL)
#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL)
/* Control Register 32bit (R/W) */
#define U300_GPIO_CR (0x54)
#define U300_GPIO_CR_BLOCK_CLOCK_ENABLE (0x00000001UL)
/* three ports of 8 bits each = GPIO pins 0..23 */
#define U300_GPIO_NUM_PORTS 3
#define U300_GPIO_PINS_PER_PORT 8
#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1)
#endif
#ifdef U300_COH901571_3
/*
* Control Register 32bit (R/W)
* bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores
* gives the number of GPIO pins.
* bit 8-2 (mask 0x000001FC) contains the core version ID.
*/
#define U300_GPIO_CR (0x00)
#define U300_GPIO_CR_SYNC_SEL_ENABLE (0x00000002UL)
#define U300_GPIO_CR_BLOCK_CLKRQ_ENABLE (0x00000001UL)
#define U300_GPIO_PORTX_SPACING (0x30)
/* Port X Pin Data INPUT Register 32bit (R/W) */
#define U300_GPIO_PXPDIR (0x04)
/* Port X Pin Data OUTPUT Register 32bit (R/W) */
#define U300_GPIO_PXPDOR (0x08)
/* Port X Pin Config Register 32bit (R/W) */
#define U300_GPIO_PXPCR (0x0C)
#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL)
#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL)
#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL)
#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL)
#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL)
#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL)
#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL)
/* Port X Pull-up Enable Register 32bit (R/W) */
#define U300_GPIO_PXPER (0x10)
#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL)
#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL)
/* Port X Interrupt Event Register 32bit (R/W) */
#define U300_GPIO_PXIEV (0x14)
#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK (0x000000FFUL)
#define U300_GPIO_PXIEV_IRQ_EVENT (0x00000001UL)
/* Port X Interrupt Enable Register 32bit (R/W) */
#define U300_GPIO_PXIEN (0x18)
#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK (0x000000FFUL)
#define U300_GPIO_PXIEN_IRQ_ENABLE (0x00000001UL)
/* Port X Interrupt Force Register 32bit (R/W) */
#define U300_GPIO_PXIFR (0x1C)
#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK (0x000000FFUL)
#define U300_GPIO_PXIFR_IRQ_FORCE (0x00000001UL)
/* Port X Interrupt Config Register 32bit (R/W) */
#define U300_GPIO_PXICR (0x20)
#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL)
#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL)
#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL)
#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL)
#ifdef CONFIG_MACH_U300_BS335
/* seven ports of 8 bits each = GPIO pins 0..55 */
#define U300_GPIO_NUM_PORTS 7
#else
/* five ports of 8 bits each = GPIO pins 0..39 */
#define U300_GPIO_NUM_PORTS 5
#endif
#define U300_GPIO_PINS_PER_PORT 8
#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1)
#endif
/*
* Individual pin assignments for the B26/S26. Notice that the
* actual usage of these pins depends on the PAD MUX settings, that
* is why the same number can potentially appear several times.
* In the reference design each pin is only used for one purpose.
* These were determined by inspecting the B26/S26 schematic:
* 2/1911-ROA 128 1603
*/
#ifdef CONFIG_MACH_U300_BS2X
#define U300_GPIO_PIN_UART_RX 0
#define U300_GPIO_PIN_UART_TX 1
#define U300_GPIO_PIN_GPIO02 2 /* Unrouted */
#define U300_GPIO_PIN_GPIO03 3 /* Unrouted */
#define U300_GPIO_PIN_CAM_SLEEP 4
#define U300_GPIO_PIN_CAM_REG_EN 5
#define U300_GPIO_PIN_GPIO06 6 /* Unrouted */
#define U300_GPIO_PIN_GPIO07 7 /* Unrouted */
#define U300_GPIO_PIN_GPIO08 8 /* Service point SP2321 */
#define U300_GPIO_PIN_GPIO09 9 /* Service point SP2322 */
#define U300_GPIO_PIN_PHFSENSE 10 /* Headphone jack sensing */
#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
#define U300_GPIO_PIN_FLIPSENSE 13 /* Mechanical flip sensing */
#define U300_GPIO_PIN_GPIO14 14 /* DSP JTAG Port RTCK */
#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
#define U300_GPIO_PIN_GPIO16 16 /* Unrouted */
#define U300_GPIO_PIN_GPIO17 17 /* Unrouted */
#define U300_GPIO_PIN_GPIO18 18 /* Unrouted */
#define U300_GPIO_PIN_GPIO19 19 /* Unrouted */
#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
#endif
/*
* Individual pin assignments for the B330/S330 and B365/S365.
* Notice that the actual usage of these pins depends on the
* PAD MUX settings, that is why the same number can potentially
* appear several times. In the reference design each pin is only
* used for one purpose. These were determined by inspecting the
* S365 schematic.
*/
#if defined(CONFIG_MACH_U300_BS330) || defined(CONFIG_MACH_U300_BS365) || \
defined(CONFIG_MACH_U300_BS335)
#define U300_GPIO_PIN_UART_RX 0
#define U300_GPIO_PIN_UART_TX 1
#define U300_GPIO_PIN_UART_CTS 2
#define U300_GPIO_PIN_UART_RTS 3
#define U300_GPIO_PIN_CAM_MAIN_STANDBY 4 /* Camera MAIN standby */
#define U300_GPIO_PIN_GPIO05 5 /* Unrouted */
#define U300_GPIO_PIN_MS_CD 6 /* Memory Stick Card insertion */
#define U300_GPIO_PIN_GPIO07 7 /* Test point TP2430 */
#define U300_GPIO_PIN_GPIO08 8 /* Test point TP2437 */
#define U300_GPIO_PIN_GPIO09 9 /* Test point TP2431 */
#define U300_GPIO_PIN_GPIO10 10 /* Test point TP2432 */
#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
#define U300_GPIO_PIN_CAM_SUB_STANDBY 13 /* Camera SUB standby */
#define U300_GPIO_PIN_GPIO14 14 /* Test point TP2436 */
#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
#define U300_GPIO_PIN_GPIO16 16 /* Test point TP2438 */
#define U300_GPIO_PIN_PHFSENSE 17 /* Headphone jack sensing */
#define U300_GPIO_PIN_GPIO18 18 /* Test point TP2439 */
#define U300_GPIO_PIN_GPIO19 19 /* Routed somewhere */
#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
#define U300_GPIO_PIN_GPIO24 24 /* Unrouted */
#define U300_GPIO_PIN_GPIO25 25 /* Unrouted */
#define U300_GPIO_PIN_GPIO26 26 /* Unrouted */
#define U300_GPIO_PIN_GPIO27 27 /* Unrouted */
#define U300_GPIO_PIN_GPIO28 28 /* Unrouted */
#define U300_GPIO_PIN_GPIO29 29 /* Unrouted */
#define U300_GPIO_PIN_GPIO30 30 /* Unrouted */
#define U300_GPIO_PIN_GPIO31 31 /* Unrouted */
#define U300_GPIO_PIN_GPIO32 32 /* Unrouted */
#define U300_GPIO_PIN_GPIO33 33 /* Unrouted */
#define U300_GPIO_PIN_GPIO34 34 /* Unrouted */
#define U300_GPIO_PIN_GPIO35 35 /* Unrouted */
#define U300_GPIO_PIN_GPIO36 36 /* Unrouted */
#define U300_GPIO_PIN_GPIO37 37 /* Unrouted */
#define U300_GPIO_PIN_GPIO38 38 /* Unrouted */
#define U300_GPIO_PIN_GPIO39 39 /* Unrouted */
#ifdef CONFIG_MACH_U300_BS335
#define U300_GPIO_PIN_GPIO40 40 /* Unrouted */
#define U300_GPIO_PIN_GPIO41 41 /* Unrouted */
#define U300_GPIO_PIN_GPIO42 42 /* Unrouted */
#define U300_GPIO_PIN_GPIO43 43 /* Unrouted */
#define U300_GPIO_PIN_GPIO44 44 /* Unrouted */
#define U300_GPIO_PIN_GPIO45 45 /* Unrouted */
#define U300_GPIO_PIN_GPIO46 46 /* Unrouted */
#define U300_GPIO_PIN_GPIO47 47 /* Unrouted */
#define U300_GPIO_PIN_GPIO48 48 /* Unrouted */
#define U300_GPIO_PIN_GPIO49 49 /* Unrouted */
#define U300_GPIO_PIN_GPIO50 50 /* Unrouted */
#define U300_GPIO_PIN_GPIO51 51 /* Unrouted */
#define U300_GPIO_PIN_GPIO52 52 /* Unrouted */
#define U300_GPIO_PIN_GPIO53 53 /* Unrouted */
#define U300_GPIO_PIN_GPIO54 54 /* Unrouted */
#define U300_GPIO_PIN_GPIO55 55 /* Unrouted */
#endif
#endif
/* translates a pin number to a port number */
#define PIN_TO_PORT(val) (val >> 3)
/* These can be found in arch/arm/mach-u300/gpio.c */
extern int gpio_request(unsigned gpio, const char *label);
extern void gpio_free(unsigned gpio);
extern int gpio_direction_input(unsigned gpio);
extern int gpio_direction_output(unsigned gpio, int value);
extern int gpio_register_callback(unsigned gpio,
int (*func)(void *arg),
void *);
extern int gpio_unregister_callback(unsigned gpio);
extern void enable_irq_on_gpio_pin(unsigned gpio, int edge);
extern void disable_irq_on_gpio_pin(unsigned gpio);
extern void gpio_pullup(unsigned gpio, int value);
extern int gpio_get_value(unsigned gpio);
extern void gpio_set_value(unsigned gpio, int value);
/* wrappers to sleep-enable the previous two functions */
static inline unsigned gpio_to_irq(unsigned gpio)
{
return PIN_TO_PORT(gpio) + IRQ_U300_GPIO_PORT0;
}
static inline unsigned irq_to_gpio(unsigned irq)
{
/*
* FIXME: This is no 1-1 mapping at all, it points to the
* whole block of 8 pins.
*/
return (irq - IRQ_U300_GPIO_PORT0) << 3;
}
#endif
/*
* arch/arm/mach-u300/include/mach/hardware.h
*/
#include <asm/sizes.h>
#include <mach/u300-regs.h>
/*
*
* arch/arm/mach-u300/include/mach/io.h
*
*
* Copyright (C) 2006-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* Dummy IO map for being able to use writew()/readw(),
* writel()/readw() and similar accessor functions.
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#ifndef __MACH_IO_H
#define __MACH_IO_H
#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) __typesafe_io(a)
#define __mem_pci(a) (a)
#endif
/*
*
* arch/arm/mach-u300/include/mach/irqs.h
*
*
* Copyright (C) 2006-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* IRQ channel definitions for the U300 platforms.
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#ifndef __MACH_IRQS_H
#define __MACH_IRQS_H
#define IRQ_U300_INTCON0_START 0
#define IRQ_U300_INTCON1_START 32
/* These are on INTCON0 - 30 lines */
#define IRQ_U300_IRQ0_EXT 0
#define IRQ_U300_IRQ1_EXT 1
#define IRQ_U300_DMA 2
#define IRQ_U300_VIDEO_ENC_0 3
#define IRQ_U300_VIDEO_ENC_1 4
#define IRQ_U300_AAIF_RX 5
#define IRQ_U300_AAIF_TX 6
#define IRQ_U300_AAIF_VGPIO 7
#define IRQ_U300_AAIF_WAKEUP 8
#define IRQ_U300_PCM_I2S0_FRAME 9
#define IRQ_U300_PCM_I2S0_FIFO 10
#define IRQ_U300_PCM_I2S1_FRAME 11
#define IRQ_U300_PCM_I2S1_FIFO 12
#define IRQ_U300_XGAM_GAMCON 13
#define IRQ_U300_XGAM_CDI 14
#define IRQ_U300_XGAM_CDICON 15
#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
/* MMIACC not used on the DB3210 or DB3350 chips */
#define IRQ_U300_XGAM_MMIACC 16
#endif
#define IRQ_U300_XGAM_PDI 17
#define IRQ_U300_XGAM_PDICON 18
#define IRQ_U300_XGAM_GAMEACC 19
#define IRQ_U300_XGAM_MCIDCT 20
#define IRQ_U300_APEX 21
#define IRQ_U300_UART0 22
#define IRQ_U300_SPI 23
#define IRQ_U300_TIMER_APP_OS 24
#define IRQ_U300_TIMER_APP_DD 25
#define IRQ_U300_TIMER_APP_GP1 26
#define IRQ_U300_TIMER_APP_GP2 27
#define IRQ_U300_TIMER_OS 28
#define IRQ_U300_TIMER_MS 29
#define IRQ_U300_KEYPAD_KEYBF 30
#define IRQ_U300_KEYPAD_KEYBR 31
/* These are on INTCON1 - 32 lines */
#define IRQ_U300_GPIO_PORT0 32
#define IRQ_U300_GPIO_PORT1 33
#define IRQ_U300_GPIO_PORT2 34
#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) || \
defined(CONFIG_MACH_U300_BS335)
/* These are for DB3150, DB3200 and DB3350 */
#define IRQ_U300_WDOG 35
#define IRQ_U300_EVHIST 36
#define IRQ_U300_MSPRO 37
#define IRQ_U300_MMCSD_MCIINTR0 38
#define IRQ_U300_MMCSD_MCIINTR1 39
#define IRQ_U300_I2C0 40
#define IRQ_U300_I2C1 41
#define IRQ_U300_RTC 42
#define IRQ_U300_NFIF 43
#define IRQ_U300_NFIF2 44
#endif
/* DB3150 and DB3200 have only 45 IRQs */
#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
#define U300_NR_IRQS 45
#endif
/* The DB3350-specific interrupt lines */
#ifdef CONFIG_MACH_U300_BS335
#define IRQ_U300_ISP_F0 45
#define IRQ_U300_ISP_F1 46
#define IRQ_U300_ISP_F2 47
#define IRQ_U300_ISP_F3 48
#define IRQ_U300_ISP_F4 49
#define IRQ_U300_GPIO_PORT3 50
#define IRQ_U300_SYSCON_PLL_LOCK 51
#define IRQ_U300_UART1 52
#define IRQ_U300_GPIO_PORT4 53
#define IRQ_U300_GPIO_PORT5 54
#define IRQ_U300_GPIO_PORT6 55
#define U300_NR_IRQS 56
#endif
/* The DB3210-specific interrupt lines */
#ifdef CONFIG_MACH_U300_BS365
#define IRQ_U300_GPIO_PORT3 35
#define IRQ_U300_GPIO_PORT4 36
#define IRQ_U300_WDOG 37
#define IRQ_U300_EVHIST 38
#define IRQ_U300_MSPRO 39
#define IRQ_U300_MMCSD_MCIINTR0 40
#define IRQ_U300_MMCSD_MCIINTR1 41
#define IRQ_U300_I2C0 42
#define IRQ_U300_I2C1 43
#define IRQ_U300_RTC 44
#define IRQ_U300_NFIF 45
#define IRQ_U300_NFIF2 46
#define IRQ_U300_SYSCON_PLL_LOCK 47
#define U300_NR_IRQS 48
#endif
#define NR_IRQS U300_NR_IRQS
#endif
/*
*
* arch/arm/mach-u300/include/mach/memory.h
*
*
* Copyright (C) 2007-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* Memory virtual/physical mapping constants.
* Author: Linus Walleij <linus.walleij@stericsson.com>
* Author: Jonas Aaberg <jonas.aberg@stericsson.com>
*/
#ifndef __MACH_MEMORY_H
#define __MACH_MEMORY_H
#ifdef CONFIG_MACH_U300_DUAL_RAM
#define PHYS_OFFSET UL(0x48000000)
#define BOOT_PARAMS_OFFSET (PHYS_OFFSET + 0x100)
#else
#ifdef CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
#define PHYS_OFFSET (0x28000000 + \
(CONFIG_MACH_U300_ACCESS_MEM_SIZE - \
(CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024)
#else
#define PHYS_OFFSET (0x28000000 + \
(CONFIG_MACH_U300_ACCESS_MEM_SIZE + \
(CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024)
#endif
#define BOOT_PARAMS_OFFSET (0x28000000 + \
(CONFIG_MACH_U300_ACCESS_MEM_SIZE + \
(CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024 + 0x100)
#endif
/*
* We enable a real big DMA buffer if need be.
*/
#define CONSISTENT_DMA_SIZE SZ_4M
#endif
/*
*
* arch/arm/mach-u300/include/mach/platform.h
*
*
* Copyright (C) 2006-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* Basic platform init and mapping functions.
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#ifndef __ASSEMBLY__
void u300_map_io(void);
void u300_init_irq(void);
void u300_init_devices(void);
extern struct sys_timer u300_timer;
#endif
此差异已折叠。
/*
*
* arch/arm/mach-u300/include/mach/system.h
*
*
* Copyright (C) 2007-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* System shutdown and reset functions.
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#include <mach/hardware.h>
#include <asm/io.h>
#include <asm/hardware/vic.h>
#include <asm/irq.h>
/* Forward declare this function from the watchdog */
void coh901327_watchdog_reset(void);
static inline void arch_idle(void)
{
cpu_do_idle();
}
static void arch_reset(char mode, const char *cmd)
{
switch (mode) {
case 's':
case 'h':
printk(KERN_CRIT "RESET: shutting down/rebooting system\n");
/* Disable interrupts */
local_irq_disable();
#ifdef CONFIG_COH901327_WATCHDOG
coh901327_watchdog_reset();
#endif
break;
default:
/* Do nothing */
break;
}
/* Wait for system do die/reset. */
while (1);
}
/*
*
* arch/arm/mach-u300/include/mach/timex.h
*
*
* Copyright (C) 2006-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* Platform tick rate definition.
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#ifndef __MACH_TIMEX_H
#define __MACH_TIMEX_H
/* This is for the APP OS GP1 (General Purpose 1) timer */
#define CLOCK_TICK_RATE 1000000
#endif
/*
*
* arch/arm/mach-u300/include/mach/u300-regs.h
*
*
* Copyright (C) 2006-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* Basic register address definitions in physical memory and
* some block defintions for core devices like the timer.
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#ifndef __MACH_U300_REGS_H
#define __MACH_U300_REGS_H
/*
* These are the large blocks of memory allocated for I/O.
* the defines are used for setting up the I/O memory mapping.
*/
/* NAND Flash CS0 */
#define U300_NAND_CS0_PHYS_BASE 0x80000000
#define U300_NAND_CS0_VIRT_BASE 0xff040000
/* NFIF */
#define U300_NAND_IF_PHYS_BASE 0x9f800000
#define U300_NAND_IF_VIRT_BASE 0xff030000
/* AHB Peripherals */
#define U300_AHB_PER_PHYS_BASE 0xa0000000
#define U300_AHB_PER_VIRT_BASE 0xff010000
/* FAST Peripherals */
#define U300_FAST_PER_PHYS_BASE 0xc0000000
#define U300_FAST_PER_VIRT_BASE 0xff020000
/* SLOW Peripherals */
#define U300_SLOW_PER_PHYS_BASE 0xc0010000
#define U300_SLOW_PER_VIRT_BASE 0xff000000
/* Boot ROM */
#define U300_BOOTROM_PHYS_BASE 0xffff0000
#define U300_BOOTROM_VIRT_BASE 0xffff0000
/* SEMI config base */
#ifdef CONFIG_MACH_U300_BS335
#define U300_SEMI_CONFIG_BASE 0x2FFE0000
#else
#define U300_SEMI_CONFIG_BASE 0x30000000
#endif
/*
* All the following peripherals are specified at their PHYSICAL address,
* so if you need to access them (in the kernel), you MUST use the macros
* defined in <asm/io.h> to map to the IO_ADDRESS_AHB() IO_ADDRESS_FAST()
* etc.
*/
/*
* AHB peripherals
*/
/* AHB Peripherals Bridge Controller */
#define U300_AHB_BRIDGE_BASE (U300_AHB_PER_PHYS_BASE+0x0000)
/* Vectored Interrupt Controller 0, servicing 32 interrupts */
#define U300_INTCON0_BASE (U300_AHB_PER_PHYS_BASE+0x1000)
#define U300_INTCON0_VBASE (U300_AHB_PER_VIRT_BASE+0x1000)
/* Vectored Interrupt Controller 1, servicing 32 interrupts */
#define U300_INTCON1_BASE (U300_AHB_PER_PHYS_BASE+0x2000)
#define U300_INTCON1_VBASE (U300_AHB_PER_VIRT_BASE+0x2000)
/* Memory Stick Pro (MSPRO) controller */
#define U300_MSPRO_BASE (U300_AHB_PER_PHYS_BASE+0x3000)
/* EMIF Configuration Area */
#define U300_EMIF_CFG_BASE (U300_AHB_PER_PHYS_BASE+0x4000)
/*
* FAST peripherals
*/
/* FAST bridge control */
#define U300_FAST_BRIDGE_BASE (U300_FAST_PER_PHYS_BASE+0x0000)
/* MMC/SD controller */
#define U300_MMCSD_BASE (U300_FAST_PER_PHYS_BASE+0x1000)
/* PCM I2S0 controller */
#define U300_PCM_I2S0_BASE (U300_FAST_PER_PHYS_BASE+0x2000)
/* PCM I2S1 controller */
#define U300_PCM_I2S1_BASE (U300_FAST_PER_PHYS_BASE+0x3000)
/* I2C0 controller */
#define U300_I2C0_BASE (U300_FAST_PER_PHYS_BASE+0x4000)
/* I2C1 controller */
#define U300_I2C1_BASE (U300_FAST_PER_PHYS_BASE+0x5000)
/* SPI controller */
#define U300_SPI_BASE (U300_FAST_PER_PHYS_BASE+0x6000)
#ifdef CONFIG_MACH_U300_BS335
/* Fast UART1 on U335 only */
#define U300_UART1_BASE (U300_SLOW_PER_PHYS_BASE+0x7000)
#endif
/*
* SLOW peripherals
*/
/* SLOW bridge control */
#define U300_SLOW_BRIDGE_BASE (U300_SLOW_PER_PHYS_BASE)
/* SYSCON */
#define U300_SYSCON_BASE (U300_SLOW_PER_PHYS_BASE+0x1000)
#define U300_SYSCON_VBASE (U300_SLOW_PER_VIRT_BASE+0x1000)
/* Watchdog */
#define U300_WDOG_BASE (U300_SLOW_PER_PHYS_BASE+0x2000)
/* UART0 */
#define U300_UART0_BASE (U300_SLOW_PER_PHYS_BASE+0x3000)
/* APP side special timer */
#define U300_TIMER_APP_BASE (U300_SLOW_PER_PHYS_BASE+0x4000)
#define U300_TIMER_APP_VBASE (U300_SLOW_PER_VIRT_BASE+0x4000)
/* Keypad */
#define U300_KEYPAD_BASE (U300_SLOW_PER_PHYS_BASE+0x5000)
/* GPIO */
#define U300_GPIO_BASE (U300_SLOW_PER_PHYS_BASE+0x6000)
/* RTC */
#define U300_RTC_BASE (U300_SLOW_PER_PHYS_BASE+0x7000)
/* Bus tracer */
#define U300_BUSTR_BASE (U300_SLOW_PER_PHYS_BASE+0x8000)
/* Event handler (hardware queue) */
#define U300_EVHIST_BASE (U300_SLOW_PER_PHYS_BASE+0x9000)
/* Genric Timer */
#define U300_TIMER_BASE (U300_SLOW_PER_PHYS_BASE+0xa000)
/* PPM */
#define U300_PPM_BASE (U300_SLOW_PER_PHYS_BASE+0xb000)
/*
* REST peripherals
*/
/* ISP (image signal processor) is only available in U335 */
#ifdef CONFIG_MACH_U300_BS335
#define U300_ISP_BASE (0xA0008000)
#endif
/* DMA Controller base */
#define U300_DMAC_BASE (0xC0020000)
/* MSL Base */
#define U300_MSL_BASE (0xc0022000)
/* APEX Base */
#define U300_APEX_BASE (0xc0030000)
/* Video Encoder Base */
#ifdef CONFIG_MACH_U300_BS335
#define U300_VIDEOENC_BASE (0xc0080000)
#else
#define U300_VIDEOENC_BASE (0xc0040000)
#endif
/* XGAM Base */
#define U300_XGAM_BASE (0xd0000000)
/*
* Virtual accessor macros for static devices
*/
#endif
此差异已折叠。
/*
*
* arch/arm/mach-u300/include/mach/vmalloc.h
*
*
* Copyright (C) 2006-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* Virtual memory allocations
* End must be above the I/O registers and on an even 2MiB boundary.
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#define VMALLOC_END 0xfe800000
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册