summaryrefslogtreecommitdiff
path: root/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci
diff options
context:
space:
mode:
authorlefranc2009-03-19 08:34:57 +0000
committerlefranc2009-03-19 08:34:57 +0000
commitade8df59a0d7d3ac394b61f3096b5963d18dcfcc (patch)
tree486cec51f00d138ab08352a6f5611f4a0323b1ca /cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci
parenta49226f2d9f26b70584f3bea9388e2d753663c91 (diff)
[kernel] changed linux-2.6.25.10 to linux-2.6.25.10-spc300
[bundle] add bundle creation functionnality git-svn-id: svn+ssh://pessac/svn/cesar/trunk@4255 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci')
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/Kconfig23
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/Makefile11
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/Makefile.boot3
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/board-evm.c133
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/clock.c323
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/clock.h33
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/gpio.c286
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/id.c94
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/io.c57
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/irq.c226
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/mux.c41
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/psc.c140
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/serial.c96
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/time.c374
14 files changed, 1840 insertions, 0 deletions
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/Kconfig b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/Kconfig
new file mode 100644
index 0000000000..bac988e7a4
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/Kconfig
@@ -0,0 +1,23 @@
+if ARCH_DAVINCI
+
+menu "TI DaVinci Implementations"
+
+comment "DaVinci Core Type"
+
+config ARCH_DAVINCI644x
+ default y
+ bool "DaVinci 644x based system"
+
+comment "DaVinci Board Type"
+
+config MACH_DAVINCI_EVM
+ bool "TI DaVinci EVM"
+ default y
+ depends on ARCH_DAVINCI644x
+ help
+ Configure this option to specify the whether the board used
+ for development is a DaVinci EVM
+
+endmenu
+
+endif
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/Makefile b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/Makefile
new file mode 100644
index 0000000000..99ac2e5577
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the linux kernel.
+#
+#
+
+# Common objects
+obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \
+ gpio.o mux.o
+
+# Board specific
+obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/Makefile.boot b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/Makefile.boot
new file mode 100644
index 0000000000..e1dd366f83
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x80008000
+params_phys-y := 0x80000100
+initrd_phys-y := 0x80800000
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/board-evm.c b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/board-evm.c
new file mode 100644
index 0000000000..9e4024c496
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/board-evm.c
@@ -0,0 +1,133 @@
+/*
+ * TI DaVinci EVM board support
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/setup.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <asm/arch/common.h>
+
+/* other misc. init functions */
+void __init davinci_psc_init(void);
+void __init davinci_irq_init(void);
+void __init davinci_map_common_io(void);
+void __init davinci_init_common_hw(void);
+
+/* NOR Flash base address set to CS0 by default */
+#define NOR_FLASH_PHYS 0x02000000
+
+static struct mtd_partition davinci_evm_partitions[] = {
+ /* bootloader (U-Boot, etc) in first 4 sectors */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 4 * SZ_64K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next 1 sectors */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_64K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data davinci_evm_flash_data = {
+ .width = 2,
+ .parts = davinci_evm_partitions,
+ .nr_parts = ARRAY_SIZE(davinci_evm_partitions),
+};
+
+/* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF
+ * limits addresses to 16M, so using addresses past 16M will wrap */
+static struct resource davinci_evm_flash_resource = {
+ .start = NOR_FLASH_PHYS,
+ .end = NOR_FLASH_PHYS + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device davinci_evm_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &davinci_evm_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &davinci_evm_flash_resource,
+};
+
+static struct platform_device *davinci_evm_devices[] __initdata = {
+ &davinci_evm_flash_device,
+};
+
+static void __init
+davinci_evm_map_io(void)
+{
+ davinci_map_common_io();
+}
+
+static __init void davinci_evm_init(void)
+{
+ davinci_psc_init();
+
+#if defined(CONFIG_BLK_DEV_DAVINCI) || defined(CONFIG_BLK_DEV_DAVINCI_MODULE)
+ printk(KERN_WARNING "WARNING: both IDE and NOR flash are enabled, "
+ "but share pins.\n\t Disable IDE for NOR support.\n");
+#endif
+
+ platform_add_devices(davinci_evm_devices,
+ ARRAY_SIZE(davinci_evm_devices));
+}
+
+static __init void davinci_evm_irq_init(void)
+{
+ davinci_init_common_hw();
+ davinci_irq_init();
+}
+
+MACHINE_START(DAVINCI_EVM, "DaVinci EVM")
+ /* Maintainer: MontaVista Software <source@mvista.com> */
+ .phys_io = IO_PHYS,
+ .io_pg_offst = (io_p2v(IO_PHYS) >> 18) & 0xfffc,
+ .boot_params = (DAVINCI_DDR_BASE + 0x100),
+ .map_io = davinci_evm_map_io,
+ .init_irq = davinci_evm_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = davinci_evm_init,
+MACHINE_END
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/clock.c b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/clock.c
new file mode 100644
index 0000000000..4143828a96
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/clock.c
@@ -0,0 +1,323 @@
+/*
+ * TI DaVinci clock config file
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/psc.h>
+#include "clock.h"
+
+/* PLL/Reset register offsets */
+#define PLLM 0x110
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+static DEFINE_SPINLOCK(clockfw_lock);
+
+static unsigned int commonrate;
+static unsigned int armrate;
+static unsigned int fixedrate = 27000000; /* 27 MHZ */
+
+extern void davinci_psc_config(unsigned int domain, unsigned int id, char enable);
+
+/*
+ * Returns a clock. Note that we first try to use device id on the bus
+ * and clock name. If this fails, we try to use clock name only.
+ */
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ struct clk *p, *clk = ERR_PTR(-ENOENT);
+ int idno;
+
+ if (dev == NULL || dev->bus != &platform_bus_type)
+ idno = -1;
+ else
+ idno = to_platform_device(dev)->id;
+
+ mutex_lock(&clocks_mutex);
+
+ list_for_each_entry(p, &clocks, node) {
+ if (p->id == idno &&
+ strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+ clk = p;
+ goto found;
+ }
+ }
+
+ list_for_each_entry(p, &clocks, node) {
+ if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+ clk = p;
+ break;
+ }
+ }
+
+found:
+ mutex_unlock(&clocks_mutex);
+
+ return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+ if (clk && !IS_ERR(clk))
+ module_put(clk->owner);
+}
+EXPORT_SYMBOL(clk_put);
+
+static int __clk_enable(struct clk *clk)
+{
+ if (clk->flags & ALWAYS_ENABLED)
+ return 0;
+
+ davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 1);
+ return 0;
+}
+
+static void __clk_disable(struct clk *clk)
+{
+ if (clk->usecount)
+ return;
+
+ davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 0);
+}
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if (clk->usecount++ == 0) {
+ spin_lock_irqsave(&clockfw_lock, flags);
+ ret = __clk_enable(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ if (clk->usecount > 0 && !(--clk->usecount)) {
+ spin_lock_irqsave(&clockfw_lock, flags);
+ __clk_disable(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+ }
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ return *(clk->rate);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ return *(clk->rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ /* changing the clk rate is not supported */
+ return -EINVAL;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_register(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ list_add(&clk->node, &clocks);
+ mutex_unlock(&clocks_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ mutex_lock(&clocks_mutex);
+ list_del(&clk->node);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+static struct clk davinci_clks[] = {
+ {
+ .name = "ARMCLK",
+ .rate = &armrate,
+ .lpsc = -1,
+ .flags = ALWAYS_ENABLED,
+ },
+ {
+ .name = "UART",
+ .rate = &fixedrate,
+ .lpsc = DAVINCI_LPSC_UART0,
+ },
+ {
+ .name = "EMACCLK",
+ .rate = &commonrate,
+ .lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
+ },
+ {
+ .name = "I2CCLK",
+ .rate = &fixedrate,
+ .lpsc = DAVINCI_LPSC_I2C,
+ },
+ {
+ .name = "IDECLK",
+ .rate = &commonrate,
+ .lpsc = DAVINCI_LPSC_ATA,
+ },
+ {
+ .name = "McBSPCLK",
+ .rate = &commonrate,
+ .lpsc = DAVINCI_LPSC_McBSP,
+ },
+ {
+ .name = "MMCSDCLK",
+ .rate = &commonrate,
+ .lpsc = DAVINCI_LPSC_MMC_SD,
+ },
+ {
+ .name = "SPICLK",
+ .rate = &commonrate,
+ .lpsc = DAVINCI_LPSC_SPI,
+ },
+ {
+ .name = "gpio",
+ .rate = &commonrate,
+ .lpsc = DAVINCI_LPSC_GPIO,
+ },
+ {
+ .name = "AEMIFCLK",
+ .rate = &commonrate,
+ .lpsc = DAVINCI_LPSC_AEMIF,
+ .usecount = 1,
+ }
+};
+
+int __init davinci_clk_init(void)
+{
+ struct clk *clkp;
+ int count = 0;
+ u32 pll_mult;
+
+ pll_mult = davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLM);
+ commonrate = ((pll_mult + 1) * 27000000) / 6;
+ armrate = ((pll_mult + 1) * 27000000) / 2;
+
+ for (clkp = davinci_clks; count < ARRAY_SIZE(davinci_clks);
+ count++, clkp++) {
+ clk_register(clkp);
+
+ /* Turn on clocks that have been enabled in the
+ * table above */
+ if (clkp->usecount)
+ clk_enable(clkp);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+static void *davinci_ck_start(struct seq_file *m, loff_t *pos)
+{
+ return *pos < 1 ? (void *)1 : NULL;
+}
+
+static void *davinci_ck_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return NULL;
+}
+
+static void davinci_ck_stop(struct seq_file *m, void *v)
+{
+}
+
+static int davinci_ck_show(struct seq_file *m, void *v)
+{
+ struct clk *cp;
+
+ list_for_each_entry(cp, &clocks, node)
+ seq_printf(m,"%s %d %d\n", cp->name, *(cp->rate), cp->usecount);
+
+ return 0;
+}
+
+static const struct seq_operations davinci_ck_op = {
+ .start = davinci_ck_start,
+ .next = davinci_ck_next,
+ .stop = davinci_ck_stop,
+ .show = davinci_ck_show
+};
+
+static int davinci_ck_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &davinci_ck_op);
+}
+
+static const struct file_operations proc_davinci_ck_operations = {
+ .open = davinci_ck_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static int __init davinci_ck_proc_init(void)
+{
+ struct proc_dir_entry *entry;
+
+ entry = create_proc_entry("davinci_clocks", 0, NULL);
+ if (entry)
+ entry->proc_fops = &proc_davinci_ck_operations;
+ return 0;
+
+}
+__initcall(davinci_ck_proc_init);
+#endif /* CONFIG_DEBUG_PROC_FS */
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/clock.h b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/clock.h
new file mode 100644
index 0000000000..ed47079a52
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/clock.h
@@ -0,0 +1,33 @@
+/*
+ * TI DaVinci clock definitions
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * 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 __ARCH_ARM_DAVINCI_CLOCK_H
+#define __ARCH_ARM_DAVINCI_CLOCK_H
+
+struct clk {
+ struct list_head node;
+ struct module *owner;
+ const char *name;
+ unsigned int *rate;
+ int id;
+ __s8 usecount;
+ __u8 flags;
+ __u8 lpsc;
+};
+
+/* Clock flags */
+#define RATE_CKCTL 1
+#define RATE_FIXED 2
+#define RATE_PROPAGATES 4
+#define VIRTUAL_CLOCK 8
+#define ALWAYS_ENABLED 16
+#define ENABLE_REG_32BIT 32
+
+#endif
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/gpio.c b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/gpio.c
new file mode 100644
index 0000000000..9c67886e71
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/gpio.c
@@ -0,0 +1,286 @@
+/*
+ * TI DaVinci GPIO Support
+ *
+ * Copyright (c) 2006 David Brownell
+ * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/bitops.h>
+
+#include <asm/arch/irqs.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/gpio.h>
+
+#include <asm/mach/irq.h>
+
+static DEFINE_SPINLOCK(gpio_lock);
+static DECLARE_BITMAP(gpio_in_use, DAVINCI_N_GPIO);
+
+int gpio_request(unsigned gpio, const char *tag)
+{
+ if (gpio >= DAVINCI_N_GPIO)
+ return -EINVAL;
+
+ if (test_and_set_bit(gpio, gpio_in_use))
+ return -EBUSY;
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_request);
+
+void gpio_free(unsigned gpio)
+{
+ if (gpio >= DAVINCI_N_GPIO)
+ return;
+
+ clear_bit(gpio, gpio_in_use);
+}
+EXPORT_SYMBOL(gpio_free);
+
+/* create a non-inlined version */
+static struct gpio_controller *__iomem gpio2controller(unsigned gpio)
+{
+ return __gpio_to_controller(gpio);
+}
+
+/*
+ * Assuming the pin is muxed as a gpio output, set its output value.
+ */
+void __gpio_set(unsigned gpio, int value)
+{
+ struct gpio_controller *__iomem g = gpio2controller(gpio);
+
+ __raw_writel(__gpio_mask(gpio), value ? &g->set_data : &g->clr_data);
+}
+EXPORT_SYMBOL(__gpio_set);
+
+
+/*
+ * Read the pin's value (works even if it's set up as output);
+ * returns zero/nonzero.
+ *
+ * Note that changes are synched to the GPIO clock, so reading values back
+ * right after you've set them may give old values.
+ */
+int __gpio_get(unsigned gpio)
+{
+ struct gpio_controller *__iomem g = gpio2controller(gpio);
+
+ return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data));
+}
+EXPORT_SYMBOL(__gpio_get);
+
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ * board setup code *MUST* set PINMUX0 and PINMUX1 as
+ * needed, and enable the GPIO clock.
+ */
+
+int gpio_direction_input(unsigned gpio)
+{
+ struct gpio_controller *__iomem g = gpio2controller(gpio);
+ u32 temp;
+ u32 mask;
+
+ if (!g)
+ return -EINVAL;
+
+ spin_lock(&gpio_lock);
+ mask = __gpio_mask(gpio);
+ temp = __raw_readl(&g->dir);
+ temp |= mask;
+ __raw_writel(temp, &g->dir);
+ spin_unlock(&gpio_lock);
+ return 0;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+ struct gpio_controller *__iomem g = gpio2controller(gpio);
+ u32 temp;
+ u32 mask;
+
+ if (!g)
+ return -EINVAL;
+
+ spin_lock(&gpio_lock);
+ mask = __gpio_mask(gpio);
+ temp = __raw_readl(&g->dir);
+ temp &= ~mask;
+ __raw_writel(mask, value ? &g->set_data : &g->clr_data);
+ __raw_writel(temp, &g->dir);
+ spin_unlock(&gpio_lock);
+ return 0;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+/*
+ * We expect irqs will normally be set up as input pins, but they can also be
+ * used as output pins ... which is convenient for testing.
+ *
+ * NOTE: GPIO0..GPIO7 also have direct INTC hookups, which work in addition
+ * to their GPIOBNK0 irq (but with a bit less overhead). But we don't have
+ * a good way to hook those up ...
+ *
+ * All those INTC hookups (GPIO0..GPIO7 plus five IRQ banks) can also
+ * serve as EDMA event triggers.
+ */
+
+static void gpio_irq_disable(unsigned irq)
+{
+ struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+ u32 mask = __gpio_mask(irq_to_gpio(irq));
+
+ __raw_writel(mask, &g->clr_falling);
+ __raw_writel(mask, &g->clr_rising);
+}
+
+static void gpio_irq_enable(unsigned irq)
+{
+ struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+ u32 mask = __gpio_mask(irq_to_gpio(irq));
+
+ if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING)
+ __raw_writel(mask, &g->set_falling);
+ if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING)
+ __raw_writel(mask, &g->set_rising);
+}
+
+static int gpio_irq_type(unsigned irq, unsigned trigger)
+{
+ struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+ u32 mask = __gpio_mask(irq_to_gpio(irq));
+
+ if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+ return -EINVAL;
+
+ irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
+ irq_desc[irq].status |= trigger;
+
+ __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
+ ? &g->set_falling : &g->clr_falling);
+ __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
+ ? &g->set_rising : &g->clr_rising);
+ return 0;
+}
+
+static struct irq_chip gpio_irqchip = {
+ .name = "GPIO",
+ .enable = gpio_irq_enable,
+ .disable = gpio_irq_disable,
+ .set_type = gpio_irq_type,
+};
+
+static void
+gpio_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+ struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+ u32 mask = 0xffff;
+
+ /* we only care about one bank */
+ if (irq & 1)
+ mask <<= 16;
+
+ /* temporarily mask (level sensitive) parent IRQ */
+ desc->chip->ack(irq);
+ while (1) {
+ u32 status;
+ struct irq_desc *gpio;
+ int n;
+ int res;
+
+ /* ack any irqs */
+ status = __raw_readl(&g->intstat) & mask;
+ if (!status)
+ break;
+ __raw_writel(status, &g->intstat);
+ if (irq & 1)
+ status >>= 16;
+
+ /* now demux them to the right lowlevel handler */
+ n = (int)get_irq_data(irq);
+ gpio = &irq_desc[n];
+ while (status) {
+ res = ffs(status);
+ n += res;
+ gpio += res;
+ desc_handle_irq(n - 1, gpio - 1);
+ status >>= res;
+ }
+ }
+ desc->chip->unmask(irq);
+ /* now it may re-trigger */
+}
+
+/*
+ * NOTE: for suspend/resume, probably best to make a sysdev (and class)
+ * with its suspend/resume calls hooking into the results of the set_wake()
+ * calls ... so if no gpios are wakeup events the clock can be disabled,
+ * with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0
+ * can be set appropriately for GPIOV33 pins.
+ */
+
+static int __init davinci_gpio_irq_setup(void)
+{
+ unsigned gpio, irq, bank;
+ struct clk *clk;
+
+ clk = clk_get(NULL, "gpio");
+ if (IS_ERR(clk)) {
+ printk(KERN_ERR "Error %ld getting gpio clock?\n",
+ PTR_ERR(clk));
+ return 0;
+ }
+
+ clk_enable(clk);
+
+ for (gpio = 0, irq = gpio_to_irq(0), bank = IRQ_GPIOBNK0;
+ gpio < DAVINCI_N_GPIO; bank++) {
+ struct gpio_controller *__iomem g = gpio2controller(gpio);
+ unsigned i;
+
+ __raw_writel(~0, &g->clr_falling);
+ __raw_writel(~0, &g->clr_rising);
+
+ /* set up all irqs in this bank */
+ set_irq_chained_handler(bank, gpio_irq_handler);
+ set_irq_chip_data(bank, g);
+ set_irq_data(bank, (void *)irq);
+
+ for (i = 0; i < 16 && gpio < DAVINCI_N_GPIO;
+ i++, irq++, gpio++) {
+ set_irq_chip(irq, &gpio_irqchip);
+ set_irq_chip_data(irq, g);
+ set_irq_handler(irq, handle_simple_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+ }
+
+ /* BINTEN -- per-bank interrupt enable. genirq would also let these
+ * bits be set/cleared dynamically.
+ */
+ __raw_writel(0x1f, (void *__iomem)
+ IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
+
+ printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
+
+ return 0;
+}
+
+arch_initcall(davinci_gpio_irq_setup);
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/id.c b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/id.c
new file mode 100644
index 0000000000..70608f76ae
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/id.c
@@ -0,0 +1,94 @@
+/*
+ * Davinci CPU identification code
+ *
+ * Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.com>
+ *
+ * Derived from OMAP1 CPU identification code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+
+#define JTAG_ID_BASE 0x01c40028
+
+struct davinci_id {
+ u8 variant; /* JTAG ID bits 31:28 */
+ u16 part_no; /* JTAG ID bits 27:12 */
+ u32 manufacturer; /* JTAG ID bits 11:1 */
+ u32 type; /* Cpu id bits [31:8], cpu class bits [7:0] */
+};
+
+/* Register values to detect the DaVinci version */
+static struct davinci_id davinci_ids[] __initdata = {
+ {
+ /* DM6446 */
+ .part_no = 0xb700,
+ .variant = 0x0,
+ .manufacturer = 0x017,
+ .type = 0x64460000,
+ },
+};
+
+/*
+ * Get Device Part No. from JTAG ID register
+ */
+static u16 __init davinci_get_part_no(void)
+{
+ u32 dev_id, part_no;
+
+ dev_id = davinci_readl(JTAG_ID_BASE);
+
+ part_no = ((dev_id >> 12) & 0xffff);
+
+ return part_no;
+}
+
+/*
+ * Get Device Revision from JTAG ID register
+ */
+static u8 __init davinci_get_variant(void)
+{
+ u32 variant;
+
+ variant = davinci_readl(JTAG_ID_BASE);
+
+ variant = (variant >> 28) & 0xf;
+
+ return variant;
+}
+
+void __init davinci_check_revision(void)
+{
+ int i;
+ u16 part_no;
+ u8 variant;
+
+ part_no = davinci_get_part_no();
+ variant = davinci_get_variant();
+
+ /* First check only the major version in a safe way */
+ for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
+ if (part_no == (davinci_ids[i].part_no)) {
+ system_rev = davinci_ids[i].type;
+ break;
+ }
+ }
+
+ /* Check if we can find the dev revision */
+ for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
+ if (part_no == davinci_ids[i].part_no &&
+ variant == davinci_ids[i].variant) {
+ system_rev = davinci_ids[i].type;
+ break;
+ }
+ }
+
+ printk("DaVinci DM%04x variant 0x%x\n", system_rev >> 16, variant);
+}
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/io.c b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/io.c
new file mode 100644
index 0000000000..47787ff84a
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/io.c
@@ -0,0 +1,57 @@
+/*
+ * DaVinci I/O mapping code
+ *
+ * Copyright (C) 2005-2006 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/tlb.h>
+#include <asm/io.h>
+#include <asm/memory.h>
+
+#include <asm/mach/map.h>
+#include <asm/arch/clock.h>
+
+extern void davinci_check_revision(void);
+
+/*
+ * The machine specific code may provide the extra mapping besides the
+ * default mapping provided here.
+ */
+static struct map_desc davinci_io_desc[] __initdata = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+void __init davinci_map_common_io(void)
+{
+ iotable_init(davinci_io_desc, ARRAY_SIZE(davinci_io_desc));
+
+ /* Normally devicemaps_init() would flush caches and tlb after
+ * mdesc->map_io(), but we must also do it here because of the CPU
+ * revision check below.
+ */
+ local_flush_tlb_all();
+ flush_cache_all();
+
+ /* We want to check CPU revision early for cpu_is_xxxx() macros.
+ * IO space mapping must be initialized before we can do that.
+ */
+ davinci_check_revision();
+}
+
+void __init davinci_init_common_hw(void)
+{
+ davinci_clk_init();
+}
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/irq.c b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/irq.c
new file mode 100644
index 0000000000..1333d84d2e
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/irq.c
@@ -0,0 +1,226 @@
+/*
+ * Interrupt handler for DaVinci boards.
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+
+#define IRQ_BIT(irq) ((irq) & 0x1f)
+
+#define FIQ_REG0_OFFSET 0x0000
+#define FIQ_REG1_OFFSET 0x0004
+#define IRQ_REG0_OFFSET 0x0008
+#define IRQ_REG1_OFFSET 0x000C
+#define IRQ_ENT_REG0_OFFSET 0x0018
+#define IRQ_ENT_REG1_OFFSET 0x001C
+#define IRQ_INCTL_REG_OFFSET 0x0020
+#define IRQ_EABASE_REG_OFFSET 0x0024
+#define IRQ_INTPRI0_REG_OFFSET 0x0030
+#define IRQ_INTPRI7_REG_OFFSET 0x004C
+
+static inline unsigned int davinci_irq_readl(int offset)
+{
+ return davinci_readl(DAVINCI_ARM_INTC_BASE + offset);
+}
+
+static inline void davinci_irq_writel(unsigned long value, int offset)
+{
+ davinci_writel(value, DAVINCI_ARM_INTC_BASE + offset);
+}
+
+/* Disable interrupt */
+static void davinci_mask_irq(unsigned int irq)
+{
+ unsigned int mask;
+ u32 l;
+
+ mask = 1 << IRQ_BIT(irq);
+
+ if (irq > 31) {
+ l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
+ l &= ~mask;
+ davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
+ } else {
+ l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
+ l &= ~mask;
+ davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
+ }
+}
+
+/* Enable interrupt */
+static void davinci_unmask_irq(unsigned int irq)
+{
+ unsigned int mask;
+ u32 l;
+
+ mask = 1 << IRQ_BIT(irq);
+
+ if (irq > 31) {
+ l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
+ l |= mask;
+ davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
+ } else {
+ l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
+ l |= mask;
+ davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
+ }
+}
+
+/* EOI interrupt */
+static void davinci_ack_irq(unsigned int irq)
+{
+ unsigned int mask;
+
+ mask = 1 << IRQ_BIT(irq);
+
+ if (irq > 31)
+ davinci_irq_writel(mask, IRQ_REG1_OFFSET);
+ else
+ davinci_irq_writel(mask, IRQ_REG0_OFFSET);
+}
+
+static struct irq_chip davinci_irq_chip_0 = {
+ .name = "AINTC",
+ .ack = davinci_ack_irq,
+ .mask = davinci_mask_irq,
+ .unmask = davinci_unmask_irq,
+};
+
+
+/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
+static const u8 default_priorities[DAVINCI_N_AINTC_IRQ] __initdata = {
+ [IRQ_VDINT0] = 2,
+ [IRQ_VDINT1] = 6,
+ [IRQ_VDINT2] = 6,
+ [IRQ_HISTINT] = 6,
+ [IRQ_H3AINT] = 6,
+ [IRQ_PRVUINT] = 6,
+ [IRQ_RSZINT] = 6,
+ [7] = 7,
+ [IRQ_VENCINT] = 6,
+ [IRQ_ASQINT] = 6,
+ [IRQ_IMXINT] = 6,
+ [IRQ_VLCDINT] = 6,
+ [IRQ_USBINT] = 4,
+ [IRQ_EMACINT] = 4,
+ [14] = 7,
+ [15] = 7,
+ [IRQ_CCINT0] = 5, /* dma */
+ [IRQ_CCERRINT] = 5, /* dma */
+ [IRQ_TCERRINT0] = 5, /* dma */
+ [IRQ_TCERRINT] = 5, /* dma */
+ [IRQ_PSCIN] = 7,
+ [21] = 7,
+ [IRQ_IDE] = 4,
+ [23] = 7,
+ [IRQ_MBXINT] = 7,
+ [IRQ_MBRINT] = 7,
+ [IRQ_MMCINT] = 7,
+ [IRQ_SDIOINT] = 7,
+ [28] = 7,
+ [IRQ_DDRINT] = 7,
+ [IRQ_AEMIFINT] = 7,
+ [IRQ_VLQINT] = 4,
+ [IRQ_TINT0_TINT12] = 2, /* clockevent */
+ [IRQ_TINT0_TINT34] = 2, /* clocksource */
+ [IRQ_TINT1_TINT12] = 7, /* DSP timer */
+ [IRQ_TINT1_TINT34] = 7, /* system tick */
+ [IRQ_PWMINT0] = 7,
+ [IRQ_PWMINT1] = 7,
+ [IRQ_PWMINT2] = 7,
+ [IRQ_I2C] = 3,
+ [IRQ_UARTINT0] = 3,
+ [IRQ_UARTINT1] = 3,
+ [IRQ_UARTINT2] = 3,
+ [IRQ_SPINT0] = 3,
+ [IRQ_SPINT1] = 3,
+ [45] = 7,
+ [IRQ_DSP2ARM0] = 4,
+ [IRQ_DSP2ARM1] = 4,
+ [IRQ_GPIO0] = 7,
+ [IRQ_GPIO1] = 7,
+ [IRQ_GPIO2] = 7,
+ [IRQ_GPIO3] = 7,
+ [IRQ_GPIO4] = 7,
+ [IRQ_GPIO5] = 7,
+ [IRQ_GPIO6] = 7,
+ [IRQ_GPIO7] = 7,
+ [IRQ_GPIOBNK0] = 7,
+ [IRQ_GPIOBNK1] = 7,
+ [IRQ_GPIOBNK2] = 7,
+ [IRQ_GPIOBNK3] = 7,
+ [IRQ_GPIOBNK4] = 7,
+ [IRQ_COMMTX] = 7,
+ [IRQ_COMMRX] = 7,
+ [IRQ_EMUINT] = 7,
+};
+
+/* ARM Interrupt Controller Initialization */
+void __init davinci_irq_init(void)
+{
+ unsigned i;
+ const u8 *priority = default_priorities;
+
+ /* Clear all interrupt requests */
+ davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
+ davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
+ davinci_irq_writel(~0x0, IRQ_REG0_OFFSET);
+ davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);
+
+ /* Disable all interrupts */
+ davinci_irq_writel(0x0, IRQ_ENT_REG0_OFFSET);
+ davinci_irq_writel(0x0, IRQ_ENT_REG1_OFFSET);
+
+ /* Interrupts disabled immediately, IRQ entry reflects all */
+ davinci_irq_writel(0x0, IRQ_INCTL_REG_OFFSET);
+
+ /* we don't use the hardware vector table, just its entry addresses */
+ davinci_irq_writel(0, IRQ_EABASE_REG_OFFSET);
+
+ /* Clear all interrupt requests */
+ davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
+ davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
+ davinci_irq_writel(~0x0, IRQ_REG0_OFFSET);
+ davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);
+
+ for (i = IRQ_INTPRI0_REG_OFFSET; i <= IRQ_INTPRI7_REG_OFFSET; i += 4) {
+ unsigned j;
+ u32 pri;
+
+ for (j = 0, pri = 0; j < 32; j += 4, priority++)
+ pri |= (*priority & 0x07) << j;
+ davinci_irq_writel(pri, i);
+ }
+
+ /* set up genirq dispatch for ARM INTC */
+ for (i = 0; i < DAVINCI_N_AINTC_IRQ; i++) {
+ set_irq_chip(i, &davinci_irq_chip_0);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ if (i != IRQ_TINT1_TINT34)
+ set_irq_handler(i, handle_edge_irq);
+ else
+ set_irq_handler(i, handle_level_irq);
+ }
+}
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/mux.c b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/mux.c
new file mode 100644
index 0000000000..92d26bd305
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/mux.c
@@ -0,0 +1,41 @@
+/*
+ * DaVinci pin multiplexing configurations
+ *
+ * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware.h>
+
+#include <asm/arch/mux.h>
+
+/* System control register offsets */
+#define PINMUX0 0x00
+#define PINMUX1 0x04
+
+static DEFINE_SPINLOCK(mux_lock);
+
+void davinci_mux_peripheral(unsigned int mux, unsigned int enable)
+{
+ u32 pinmux, muxreg = PINMUX0;
+
+ if (mux >= DAVINCI_MUX_LEVEL2) {
+ muxreg = PINMUX1;
+ mux -= DAVINCI_MUX_LEVEL2;
+ }
+
+ spin_lock(&mux_lock);
+ pinmux = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + muxreg);
+ if (enable)
+ pinmux |= (1 << mux);
+ else
+ pinmux &= ~(1 << mux);
+ davinci_writel(pinmux, DAVINCI_SYSTEM_MODULE_BASE + muxreg);
+ spin_unlock(&mux_lock);
+}
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/psc.c b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/psc.c
new file mode 100644
index 0000000000..1334416559
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/psc.c
@@ -0,0 +1,140 @@
+/*
+ * TI DaVinci Power and Sleep Controller (PSC)
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/psc.h>
+#include <asm/arch/mux.h>
+
+/* PSC register offsets */
+#define EPCPR 0x070
+#define PTCMD 0x120
+#define PTSTAT 0x128
+#define PDSTAT 0x200
+#define PDCTL1 0x304
+#define MDSTAT 0x800
+#define MDCTL 0xA00
+
+/* System control register offsets */
+#define VDD3P3V_PWDN 0x48
+
+static void davinci_psc_mux(unsigned int id)
+{
+ switch (id) {
+ case DAVINCI_LPSC_ATA:
+ davinci_mux_peripheral(DAVINCI_MUX_HDIREN, 1);
+ davinci_mux_peripheral(DAVINCI_MUX_ATAEN, 1);
+ break;
+ case DAVINCI_LPSC_MMC_SD:
+ /* VDD power manupulations are done in U-Boot for CPMAC
+ * so applies to MMC as well
+ */
+ /*Set up the pull regiter for MMC */
+ davinci_writel(0, DAVINCI_SYSTEM_MODULE_BASE + VDD3P3V_PWDN);
+ davinci_mux_peripheral(DAVINCI_MUX_MSTK, 0);
+ break;
+ case DAVINCI_LPSC_I2C:
+ davinci_mux_peripheral(DAVINCI_MUX_I2C, 1);
+ break;
+ case DAVINCI_LPSC_McBSP:
+ davinci_mux_peripheral(DAVINCI_MUX_ASP, 1);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Enable or disable a PSC domain */
+void davinci_psc_config(unsigned int domain, unsigned int id, char enable)
+{
+ u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl, mdstat_mask;
+
+ if (id < 0)
+ return;
+
+ mdctl = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
+ if (enable)
+ mdctl |= 0x00000003; /* Enable Module */
+ else
+ mdctl &= 0xFFFFFFF2; /* Disable Module */
+ davinci_writel(mdctl, DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
+
+ pdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDSTAT);
+ if ((pdstat & 0x00000001) == 0) {
+ pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+ pdctl1 |= 0x1;
+ davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+
+ ptcmd = 1 << domain;
+ davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
+
+ do {
+ epcpr = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
+ EPCPR);
+ } while ((((epcpr >> domain) & 1) == 0));
+
+ pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+ pdctl1 |= 0x100;
+ davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+
+ do {
+ ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
+ PTSTAT);
+ } while (!(((ptstat >> domain) & 1) == 0));
+ } else {
+ ptcmd = 1 << domain;
+ davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
+
+ do {
+ ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
+ PTSTAT);
+ } while (!(((ptstat >> domain) & 1) == 0));
+ }
+
+ if (enable)
+ mdstat_mask = 0x3;
+ else
+ mdstat_mask = 0x2;
+
+ do {
+ mdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
+ MDSTAT + 4 * id);
+ } while (!((mdstat & 0x0000001F) == mdstat_mask));
+
+ if (enable)
+ davinci_psc_mux(id);
+}
+
+void __init davinci_psc_init(void)
+{
+ davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSMSTR, 1);
+ davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSSLV, 1);
+ davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPCC, 1);
+ davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC0, 1);
+ davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC1, 1);
+ davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_GPIO, 1);
+
+ /* Turn on WatchDog timer LPSC. Needed for RESET to work */
+ davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TIMER2, 1);
+}
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/serial.c b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/serial.c
new file mode 100644
index 0000000000..8368c93c78
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/serial.c
@@ -0,0 +1,96 @@
+/*
+ * TI DaVinci serial driver
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/arch/serial.h>
+#include <asm/arch/irqs.h>
+
+#define UART_DAVINCI_PWREMU 0x0c
+
+static inline unsigned int davinci_serial_in(struct plat_serial8250_port *up,
+ int offset)
+{
+ offset <<= up->regshift;
+ return (unsigned int)__raw_readb(up->membase + offset);
+}
+
+static inline void davinci_serial_outp(struct plat_serial8250_port *p,
+ int offset, int value)
+{
+ offset <<= p->regshift;
+ __raw_writeb(value, p->membase + offset);
+}
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .membase = (char *)IO_ADDRESS(DAVINCI_UART0_BASE),
+ .mapbase = (unsigned long)DAVINCI_UART0_BASE,
+ .irq = IRQ_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 27000000,
+ },
+ {
+ .flags = 0
+ },
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+static void __init davinci_serial_reset(struct plat_serial8250_port *p)
+{
+ /* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */
+ unsigned int pwremu = 0;
+
+ davinci_serial_outp(p, UART_IER, 0); /* disable all interrupts */
+
+ davinci_serial_outp(p, UART_DAVINCI_PWREMU, pwremu);
+ mdelay(10);
+
+ pwremu |= (0x3 << 13);
+ pwremu |= 0x1;
+ davinci_serial_outp(p, UART_DAVINCI_PWREMU, pwremu);
+}
+
+static int __init davinci_init(void)
+{
+ davinci_serial_reset(&serial_platform_data[0]);
+ return platform_device_register(&serial_device);
+}
+
+arch_initcall(davinci_init);
diff --git a/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/time.c b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/time.c
new file mode 100644
index 0000000000..e96a3dcdc1
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/arch/arm/mach-davinci/time.c
@@ -0,0 +1,374 @@
+/*
+ * DaVinci timer subsystem
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/errno.h>
+#include <asm/arch/io.h>
+
+static struct clock_event_device clockevent_davinci;
+
+#define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400)
+#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800)
+#define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00)
+
+enum {
+ T0_BOT = 0, T0_TOP, T1_BOT, T1_TOP, NUM_TIMERS,
+};
+
+#define IS_TIMER1(id) (id & 0x2)
+#define IS_TIMER0(id) (!IS_TIMER1(id))
+#define IS_TIMER_TOP(id) ((id & 0x1))
+#define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id))
+
+static int timer_irqs[NUM_TIMERS] = {
+ IRQ_TINT0_TINT12,
+ IRQ_TINT0_TINT34,
+ IRQ_TINT1_TINT12,
+ IRQ_TINT1_TINT34,
+};
+
+/*
+ * This driver configures the 2 64-bit count-up timers as 4 independent
+ * 32-bit count-up timers used as follows:
+ *
+ * T0_BOT: Timer 0, bottom: clockevent source for hrtimers
+ * T0_TOP: Timer 0, top : clocksource for generic timekeeping
+ * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code)
+ * T1_TOP: Timer 1, top : <unused>
+ */
+#define TID_CLOCKEVENT T0_BOT
+#define TID_CLOCKSOURCE T0_TOP
+
+/* Timer register offsets */
+#define PID12 0x0
+#define TIM12 0x10
+#define TIM34 0x14
+#define PRD12 0x18
+#define PRD34 0x1c
+#define TCR 0x20
+#define TGCR 0x24
+#define WDTCR 0x28
+
+/* Timer register bitfields */
+#define TCR_ENAMODE_DISABLE 0x0
+#define TCR_ENAMODE_ONESHOT 0x1
+#define TCR_ENAMODE_PERIODIC 0x2
+#define TCR_ENAMODE_MASK 0x3
+
+#define TGCR_TIMMODE_SHIFT 2
+#define TGCR_TIMMODE_64BIT_GP 0x0
+#define TGCR_TIMMODE_32BIT_UNCHAINED 0x1
+#define TGCR_TIMMODE_64BIT_WDOG 0x2
+#define TGCR_TIMMODE_32BIT_CHAINED 0x3
+
+#define TGCR_TIM12RS_SHIFT 0
+#define TGCR_TIM34RS_SHIFT 1
+#define TGCR_RESET 0x0
+#define TGCR_UNRESET 0x1
+#define TGCR_RESET_MASK 0x3
+
+#define WDTCR_WDEN_SHIFT 14
+#define WDTCR_WDEN_DISABLE 0x0
+#define WDTCR_WDEN_ENABLE 0x1
+#define WDTCR_WDKEY_SHIFT 16
+#define WDTCR_WDKEY_SEQ0 0xa5c6
+#define WDTCR_WDKEY_SEQ1 0xda7e
+
+struct timer_s {
+ char *name;
+ unsigned int id;
+ unsigned long period;
+ unsigned long opts;
+ unsigned long reg_base;
+ unsigned long tim_reg;
+ unsigned long prd_reg;
+ unsigned long enamode_shift;
+ struct irqaction irqaction;
+};
+static struct timer_s timers[];
+
+/* values for 'opts' field of struct timer_s */
+#define TIMER_OPTS_DISABLED 0x00
+#define TIMER_OPTS_ONESHOT 0x01
+#define TIMER_OPTS_PERIODIC 0x02
+
+static int timer32_config(struct timer_s *t)
+{
+ u32 tcr = davinci_readl(t->reg_base + TCR);
+
+ /* disable timer */
+ tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift);
+ davinci_writel(tcr, t->reg_base + TCR);
+
+ /* reset counter to zero, set new period */
+ davinci_writel(0, t->tim_reg);
+ davinci_writel(t->period, t->prd_reg);
+
+ /* Set enable mode */
+ if (t->opts & TIMER_OPTS_ONESHOT) {
+ tcr |= TCR_ENAMODE_ONESHOT << t->enamode_shift;
+ } else if (t->opts & TIMER_OPTS_PERIODIC) {
+ tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift;
+ }
+
+ davinci_writel(tcr, t->reg_base + TCR);
+ return 0;
+}
+
+static inline u32 timer32_read(struct timer_s *t)
+{
+ return davinci_readl(t->tim_reg);
+}
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_davinci;
+
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+/* called when 32-bit counter wraps */
+static irqreturn_t freerun_interrupt(int irq, void *dev_id)
+{
+ return IRQ_HANDLED;
+}
+
+static struct timer_s timers[] = {
+ [TID_CLOCKEVENT] = {
+ .name = "clockevent",
+ .opts = TIMER_OPTS_DISABLED,
+ .irqaction = {
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = timer_interrupt,
+ }
+ },
+ [TID_CLOCKSOURCE] = {
+ .name = "free-run counter",
+ .period = ~0,
+ .opts = TIMER_OPTS_PERIODIC,
+ .irqaction = {
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = freerun_interrupt,
+ }
+ },
+};
+
+static void __init timer_init(void)
+{
+ u32 bases[] = {DAVINCI_TIMER0_BASE, DAVINCI_TIMER1_BASE};
+ int i;
+
+ /* Global init of each 64-bit timer as a whole */
+ for(i=0; i<2; i++) {
+ u32 tgcr, base = bases[i];
+
+ /* Disabled, Internal clock source */
+ davinci_writel(0, base + TCR);
+
+ /* reset both timers, no pre-scaler for timer34 */
+ tgcr = 0;
+ davinci_writel(tgcr, base + TGCR);
+
+ /* Set both timers to unchained 32-bit */
+ tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT;
+ davinci_writel(tgcr, base + TGCR);
+
+ /* Unreset timers */
+ tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
+ (TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
+ davinci_writel(tgcr, base + TGCR);
+
+ /* Init both counters to zero */
+ davinci_writel(0, base + TIM12);
+ davinci_writel(0, base + TIM34);
+ }
+
+ /* Init of each timer as a 32-bit timer */
+ for (i=0; i< ARRAY_SIZE(timers); i++) {
+ struct timer_s *t = &timers[i];
+
+ if (t->name) {
+ t->id = i;
+ t->reg_base = (IS_TIMER1(t->id) ?
+ DAVINCI_TIMER1_BASE : DAVINCI_TIMER0_BASE);
+
+ if (IS_TIMER_BOT(t->id)) {
+ t->enamode_shift = 6;
+ t->tim_reg = t->reg_base + TIM12;
+ t->prd_reg = t->reg_base + PRD12;
+ } else {
+ t->enamode_shift = 22;
+ t->tim_reg = t->reg_base + TIM34;
+ t->prd_reg = t->reg_base + PRD34;
+ }
+
+ /* Register interrupt */
+ t->irqaction.name = t->name;
+ t->irqaction.dev_id = (void *)t;
+ if (t->irqaction.handler != NULL) {
+ setup_irq(timer_irqs[t->id], &t->irqaction);
+ }
+
+ timer32_config(&timers[i]);
+ }
+ }
+}
+
+/*
+ * clocksource
+ */
+static cycle_t read_cycles(void)
+{
+ struct timer_s *t = &timers[TID_CLOCKSOURCE];
+
+ return (cycles_t)timer32_read(t);
+}
+
+static struct clocksource clocksource_davinci = {
+ .name = "timer0_1",
+ .rating = 300,
+ .read = read_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 24,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/*
+ * clockevent
+ */
+static int davinci_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ struct timer_s *t = &timers[TID_CLOCKEVENT];
+
+ t->period = cycles;
+ timer32_config(t);
+ return 0;
+}
+
+static void davinci_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ struct timer_s *t = &timers[TID_CLOCKEVENT];
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ t->period = CLOCK_TICK_RATE / (HZ);
+ t->opts = TIMER_OPTS_PERIODIC;
+ timer32_config(t);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ t->opts = TIMER_OPTS_ONESHOT;
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ t->opts = TIMER_OPTS_DISABLED;
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device clockevent_davinci = {
+ .name = "timer0_0",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_next_event = davinci_set_next_event,
+ .set_mode = davinci_set_mode,
+};
+
+
+static void __init davinci_timer_init(void)
+{
+ static char err[] __initdata = KERN_ERR
+ "%s: can't register clocksource!\n";
+
+ /* init timer hw */
+ timer_init();
+
+ /* setup clocksource */
+ clocksource_davinci.mult =
+ clocksource_khz2mult(CLOCK_TICK_RATE/1000,
+ clocksource_davinci.shift);
+ if (clocksource_register(&clocksource_davinci))
+ printk(err, clocksource_davinci.name);
+
+ /* setup clockevent */
+ clockevent_davinci.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
+ clockevent_davinci.shift);
+ clockevent_davinci.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_davinci);
+ clockevent_davinci.min_delta_ns =
+ clockevent_delta2ns(1, &clockevent_davinci);
+
+ clockevent_davinci.cpumask = cpumask_of_cpu(0);
+ clockevents_register_device(&clockevent_davinci);
+}
+
+struct sys_timer davinci_timer = {
+ .init = davinci_timer_init,
+};
+
+
+/* reset board using watchdog timer */
+void davinci_watchdog_reset(void) {
+ u32 tgcr, wdtcr, base = DAVINCI_WDOG_BASE;
+
+ /* disable, internal clock source */
+ davinci_writel(0, base + TCR);
+
+ /* reset timer, set mode to 64-bit watchdog, and unreset */
+ tgcr = 0;
+ davinci_writel(tgcr, base + TCR);
+ tgcr = TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT;
+ tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
+ (TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
+ davinci_writel(tgcr, base + TCR);
+
+ /* clear counter and period regs */
+ davinci_writel(0, base + TIM12);
+ davinci_writel(0, base + TIM34);
+ davinci_writel(0, base + PRD12);
+ davinci_writel(0, base + PRD34);
+
+ /* enable */
+ wdtcr = davinci_readl(base + WDTCR);
+ wdtcr |= WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT;
+ davinci_writel(wdtcr, base + WDTCR);
+
+ /* put watchdog in pre-active state */
+ wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) |
+ (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
+ davinci_writel(wdtcr, base + WDTCR);
+
+ /* put watchdog in active state */
+ wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) |
+ (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
+ davinci_writel(wdtcr, base + WDTCR);
+
+ /* write an invalid value to the WDKEY field to trigger
+ * a watchdog reset */
+ wdtcr = 0x00004000;
+ davinci_writel(wdtcr, base + WDTCR);
+}