aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-davinci')
-rw-r--r--arch/arm/mach-davinci/Kconfig266
-rw-r--r--arch/arm/mach-davinci/Makefile42
-rw-r--r--arch/arm/mach-davinci/Makefile.boot13
-rw-r--r--arch/arm/mach-davinci/aemif.c133
-rw-r--r--arch/arm/mach-davinci/board-da830-evm.c684
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c1292
-rw-r--r--arch/arm/mach-davinci/board-dm355-evm.c359
-rw-r--r--arch/arm/mach-davinci/board-dm355-leopard.c278
-rw-r--r--arch/arm/mach-davinci/board-dm365-evm.c621
-rw-r--r--arch/arm/mach-davinci/board-dm644x-evm.c720
-rw-r--r--arch/arm/mach-davinci/board-dm646x-evm.c814
-rw-r--r--arch/arm/mach-davinci/board-mityomapl138.c574
-rw-r--r--arch/arm/mach-davinci/board-neuros-osd2.c280
-rw-r--r--arch/arm/mach-davinci/board-omapl138-hawk.c346
-rw-r--r--arch/arm/mach-davinci/board-sffsdr.c159
-rw-r--r--arch/arm/mach-davinci/board-tnetv107x-evm.c285
-rw-r--r--arch/arm/mach-davinci/cdce949.c294
-rw-r--r--arch/arm/mach-davinci/clock.c641
-rw-r--r--arch/arm/mach-davinci/clock.h132
-rw-r--r--arch/arm/mach-davinci/common.c119
-rw-r--r--arch/arm/mach-davinci/cp_intc.c177
-rw-r--r--arch/arm/mach-davinci/cpufreq.c248
-rw-r--r--arch/arm/mach-davinci/cpuidle.c169
-rw-r--r--arch/arm/mach-davinci/da830.c1212
-rw-r--r--arch/arm/mach-davinci/da850.c1139
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c844
-rw-r--r--arch/arm/mach-davinci/devices-tnetv107x.c408
-rw-r--r--arch/arm/mach-davinci/devices.c339
-rw-r--r--arch/arm/mach-davinci/dm355.c892
-rw-r--r--arch/arm/mach-davinci/dm365.c1245
-rw-r--r--arch/arm/mach-davinci/dm644x.c805
-rw-r--r--arch/arm/mach-davinci/dm646x.c921
-rw-r--r--arch/arm/mach-davinci/dma.c1596
-rw-r--r--arch/arm/mach-davinci/gpio-tnetv107x.c205
-rw-r--r--arch/arm/mach-davinci/gpio.c460
-rw-r--r--arch/arm/mach-davinci/include/mach/aemif.h36
-rw-r--r--arch/arm/mach-davinci/include/mach/asp.h137
-rw-r--r--arch/arm/mach-davinci/include/mach/cdce949.h19
-rw-r--r--arch/arm/mach-davinci/include/mach/clkdev.h15
-rw-r--r--arch/arm/mach-davinci/include/mach/clock.h21
-rw-r--r--arch/arm/mach-davinci/include/mach/common.h93
-rw-r--r--arch/arm/mach-davinci/include/mach/cp_intc.h56
-rw-r--r--arch/arm/mach-davinci/include/mach/cpufreq.h26
-rw-r--r--arch/arm/mach-davinci/include/mach/cpuidle.h18
-rw-r--r--arch/arm/mach-davinci/include/mach/cputype.h94
-rw-r--r--arch/arm/mach-davinci/include/mach/da8xx.h130
-rw-r--r--arch/arm/mach-davinci/include/mach/debug-macro.S91
-rw-r--r--arch/arm/mach-davinci/include/mach/dm355.h32
-rw-r--r--arch/arm/mach-davinci/include/mach/dm365.h52
-rw-r--r--arch/arm/mach-davinci/include/mach/dm644x.h47
-rw-r--r--arch/arm/mach-davinci/include/mach/dm646x.h94
-rw-r--r--arch/arm/mach-davinci/include/mach/edma.h262
-rw-r--r--arch/arm/mach-davinci/include/mach/entry-macro.S51
-rw-r--r--arch/arm/mach-davinci/include/mach/gpio.h161
-rw-r--r--arch/arm/mach-davinci/include/mach/hardware.h41
-rw-r--r--arch/arm/mach-davinci/include/mach/i2c.h26
-rw-r--r--arch/arm/mach-davinci/include/mach/io.h32
-rw-r--r--arch/arm/mach-davinci/include/mach/irqs.h506
-rw-r--r--arch/arm/mach-davinci/include/mach/keyscan.h42
-rw-r--r--arch/arm/mach-davinci/include/mach/memory.h51
-rw-r--r--arch/arm/mach-davinci/include/mach/mmc.h36
-rw-r--r--arch/arm/mach-davinci/include/mach/mux.h1207
-rw-r--r--arch/arm/mach-davinci/include/mach/nand.h88
-rw-r--r--arch/arm/mach-davinci/include/mach/pm.h54
-rw-r--r--arch/arm/mach-davinci/include/mach/psc.h256
-rw-r--r--arch/arm/mach-davinci/include/mach/serial.h57
-rw-r--r--arch/arm/mach-davinci/include/mach/spi.h89
-rw-r--r--arch/arm/mach-davinci/include/mach/sram.h27
-rw-r--r--arch/arm/mach-davinci/include/mach/system.h27
-rw-r--r--arch/arm/mach-davinci/include/mach/time.h35
-rw-r--r--arch/arm/mach-davinci/include/mach/timex.h22
-rw-r--r--arch/arm/mach-davinci/include/mach/tnetv107x.h60
-rw-r--r--arch/arm/mach-davinci/include/mach/uncompress.h101
-rw-r--r--arch/arm/mach-davinci/include/mach/usb.h59
-rw-r--r--arch/arm/mach-davinci/include/mach/vmalloc.h14
-rw-r--r--arch/arm/mach-davinci/io.c48
-rw-r--r--arch/arm/mach-davinci/irq.c117
-rw-r--r--arch/arm/mach-davinci/mux.c113
-rw-r--r--arch/arm/mach-davinci/mux.h51
-rw-r--r--arch/arm/mach-davinci/pm.c159
-rw-r--r--arch/arm/mach-davinci/psc.c100
-rw-r--r--arch/arm/mach-davinci/serial.c115
-rw-r--r--arch/arm/mach-davinci/sleep.S228
-rw-r--r--arch/arm/mach-davinci/sram.c71
-rw-r--r--arch/arm/mach-davinci/time.c474
-rw-r--r--arch/arm/mach-davinci/tnetv107x.c761
-rw-r--r--arch/arm/mach-davinci/usb.c180
87 files changed, 25394 insertions, 0 deletions
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
new file mode 100644
index 00000000..c0deacae
--- /dev/null
+++ b/arch/arm/mach-davinci/Kconfig
@@ -0,0 +1,266 @@
+if ARCH_DAVINCI
+
+config AINTC
+ bool
+
+config CP_INTC
+ bool
+
+config ARCH_DAVINCI_DMx
+ select CPU_ARM926T
+ bool
+
+menu "TI DaVinci Implementations"
+
+comment "DaVinci Core Type"
+
+config ARCH_DAVINCI_DM644x
+ bool "DaVinci 644x based system"
+ select AINTC
+ select ARCH_DAVINCI_DMx
+
+config ARCH_DAVINCI_DM355
+ bool "DaVinci 355 based system"
+ select AINTC
+ select ARCH_DAVINCI_DMx
+
+config ARCH_DAVINCI_DM646x
+ bool "DaVinci 646x based system"
+ select AINTC
+ select ARCH_DAVINCI_DMx
+
+config ARCH_DAVINCI_DA830
+ bool "DA830/OMAP-L137/AM17x based system"
+ select CP_INTC
+ select ARCH_DAVINCI_DA8XX
+ select CPU_DCACHE_WRITETHROUGH # needed on silicon revs 1.0, 1.1
+
+config ARCH_DAVINCI_DA850
+ bool "DA850/OMAP-L138/AM18x based system"
+ select CP_INTC
+ select ARCH_DAVINCI_DA8XX
+ select ARCH_HAS_CPUFREQ
+
+config ARCH_DAVINCI_DA8XX
+ select CPU_ARM926T
+ bool
+
+config ARCH_DAVINCI_DM365
+ bool "DaVinci 365 based system"
+ select AINTC
+ select ARCH_DAVINCI_DMx
+
+config ARCH_DAVINCI_TNETV107X
+ select CPU_V6
+ select CP_INTC
+ bool "TNETV107X based system"
+
+comment "DaVinci Board Type"
+
+config MACH_DAVINCI_EVM
+ bool "TI DM644x EVM"
+ default ARCH_DAVINCI_DM644x
+ depends on ARCH_DAVINCI_DM644x
+ select MISC_DEVICES
+ select EEPROM_AT24
+ select I2C
+ help
+ Configure this option to specify the whether the board used
+ for development is a DM644x EVM
+
+config MACH_SFFSDR
+ bool "Lyrtech SFFSDR"
+ depends on ARCH_DAVINCI_DM644x
+ select MISC_DEVICES
+ select EEPROM_AT24
+ select I2C
+ help
+ Say Y here to select the Lyrtech Small Form Factor
+ Software Defined Radio (SFFSDR) board.
+
+config MACH_NEUROS_OSD2
+ bool "Neuros OSD2 Open Television Set Top Box"
+ depends on ARCH_DAVINCI_DM644x
+ help
+ Configure this option to specify the whether the board used
+ for development is a Neuros OSD2 Open Set Top Box.
+
+config MACH_DAVINCI_DM355_EVM
+ bool "TI DM355 EVM"
+ default ARCH_DAVINCI_DM355
+ depends on ARCH_DAVINCI_DM355
+ help
+ Configure this option to specify the whether the board used
+ for development is a DM355 EVM
+
+config MACH_DM355_LEOPARD
+ bool "DM355 Leopard board"
+ depends on ARCH_DAVINCI_DM355
+ help
+ Configure this option to specify the whether the board used
+ for development is a DM355 Leopard board.
+
+config MACH_DAVINCI_DM6467_EVM
+ bool "TI DM6467 EVM"
+ default ARCH_DAVINCI_DM646x
+ depends on ARCH_DAVINCI_DM646x
+ select MACH_DAVINCI_DM6467TEVM
+ select MISC_DEVICES
+ select EEPROM_AT24
+ select I2C
+ help
+ Configure this option to specify the whether the board used
+ for development is a DM6467 EVM
+
+config MACH_DAVINCI_DM6467TEVM
+ bool
+
+config MACH_DAVINCI_DM365_EVM
+ bool "TI DM365 EVM"
+ default ARCH_DAVINCI_DM365
+ depends on ARCH_DAVINCI_DM365
+ select MISC_DEVICES
+ select EEPROM_AT24
+ select I2C
+ help
+ Configure this option to specify whether the board used
+ for development is a DM365 EVM
+
+config MACH_DAVINCI_DA830_EVM
+ bool "TI DA830/OMAP-L137/AM17x Reference Platform"
+ default ARCH_DAVINCI_DA830
+ depends on ARCH_DAVINCI_DA830
+ select GPIO_PCF857X
+ select MISC_DEVICES
+ select EEPROM_AT24
+ select I2C
+ help
+ Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module.
+
+choice
+ prompt "Select DA830/OMAP-L137/AM17x UI board peripheral"
+ depends on MACH_DAVINCI_DA830_EVM
+ help
+ The presence of UI card on the DA830/OMAP-L137/AM17x EVM is
+ detected automatically based on successful probe of the I2C
+ based GPIO expander on that board. This option selected in this
+ menu has an effect only in case of a successful UI card detection.
+
+config DA830_UI_LCD
+ bool "LCD"
+ help
+ Say Y here to use the LCD as a framebuffer or simple character
+ display.
+
+config DA830_UI_NAND
+ bool "NAND flash"
+ help
+ Say Y here to use the NAND flash. Do not forget to setup
+ the switch correctly.
+endchoice
+
+config MACH_DAVINCI_DA850_EVM
+ bool "TI DA850/OMAP-L138/AM18x Reference Platform"
+ default ARCH_DAVINCI_DA850
+ depends on ARCH_DAVINCI_DA850
+ help
+ Say Y here to select the TI DA850/OMAP-L138/AM18x Evaluation Module.
+
+choice
+ prompt "Select peripherals connected to expander on UI board"
+ depends on MACH_DAVINCI_DA850_EVM
+ help
+ The presence of User Interface (UI) card on the DA850/OMAP-L138/AM18x
+ EVM is detected automatically based on successful probe of the I2C
+ based GPIO expander on that card. This option selected in this
+ menu has an effect only in case of a successful UI card detection.
+
+config DA850_UI_NONE
+ bool "No peripheral is enabled"
+ help
+ Say Y if you do not want to enable any of the peripherals connected
+ to TCA6416 expander on DA850/OMAP-L138/AM18x EVM UI card
+
+config DA850_UI_RMII
+ bool "RMII Ethernet PHY"
+ help
+ Say Y if you want to use the RMII PHY on the DA850/OMAP-L138/AM18x
+ EVM. This PHY is found on the UI daughter card that is supplied with
+ the EVM.
+ NOTE: Please take care while choosing this option, MII PHY will
+ not be functional if RMII mode is selected.
+
+endchoice
+
+config GPIO_PCA953X
+ default MACH_DAVINCI_DA850_EVM
+
+config KEYBOARD_GPIO_POLLED
+ default MACH_DAVINCI_DA850_EVM
+
+config MACH_TNETV107X
+ bool "TI TNETV107X Reference Platform"
+ default ARCH_DAVINCI_TNETV107X
+ depends on ARCH_DAVINCI_TNETV107X
+ help
+ Say Y here to select the TI TNETV107X Evaluation Module.
+
+config MACH_MITYOMAPL138
+ bool "Critical Link MityDSP-L138/MityARM-1808 SoM"
+ depends on ARCH_DAVINCI_DA850
+ select MISC_DEVICES
+ select EEPROM_AT24
+ select I2C
+ help
+ Say Y here to select the Critical Link MityDSP-L138/MityARM-1808
+ System on Module. Information on this SoM may be found at
+ http://www.mitydsp.com
+
+config MACH_OMAPL138_HAWKBOARD
+ bool "TI AM1808 / OMAPL-138 Hawkboard platform"
+ depends on ARCH_DAVINCI_DA850
+ help
+ Say Y here to select the TI AM1808 / OMAPL-138 Hawkboard platform .
+ Information of this board may be found at
+ http://www.hawkboard.org/
+
+config DAVINCI_MUX
+ bool "DAVINCI multiplexing support"
+ depends on ARCH_DAVINCI
+ default y
+ help
+ Pin multiplexing support for DAVINCI boards. If your bootloader
+ sets the multiplexing correctly, say N. Otherwise, or if unsure,
+ say Y.
+
+config DAVINCI_MUX_DEBUG
+ bool "Multiplexing debug output"
+ depends on DAVINCI_MUX
+ help
+ Makes the multiplexing functions print out a lot of debug info.
+ This is useful if you want to find out the correct values of the
+ multiplexing registers.
+
+config DAVINCI_MUX_WARNINGS
+ bool "Warn about pins the bootloader didn't set up"
+ depends on DAVINCI_MUX
+ help
+ Choose Y here to warn whenever driver initialization logic needs
+ to change the pin multiplexing setup. When there are no warnings
+ printed, it's safe to deselect DAVINCI_MUX for your product.
+
+config DAVINCI_RESET_CLOCKS
+ bool "Reset unused clocks during boot"
+ depends on ARCH_DAVINCI
+ help
+ Say Y if you want to reset unused clocks during boot.
+ This option saves power, but assumes all drivers are
+ using the clock framework. Broken drivers that do not
+ yet use clock framework may not work with this option.
+ If you are booting from another operating system, you
+ probably do not want this option enabled until your
+ device drivers work properly.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
new file mode 100644
index 00000000..0b87a1ca
--- /dev/null
+++ b/arch/arm/mach-davinci/Makefile
@@ -0,0 +1,42 @@
+#
+# Makefile for the linux kernel.
+#
+#
+
+# Common objects
+obj-y := time.o clock.o serial.o io.o psc.o \
+ gpio.o dma.o usb.o common.o sram.o aemif.o
+
+obj-$(CONFIG_DAVINCI_MUX) += mux.o
+
+# Chip specific
+obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o devices.o
+obj-$(CONFIG_ARCH_DAVINCI_DM355) += dm355.o devices.o
+obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o
+obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o
+obj-$(CONFIG_ARCH_DAVINCI_DA830) += da830.o devices-da8xx.o
+obj-$(CONFIG_ARCH_DAVINCI_DA850) += da850.o devices-da8xx.o
+obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += tnetv107x.o devices-tnetv107x.o
+obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o
+
+obj-$(CONFIG_AINTC) += irq.o
+obj-$(CONFIG_CP_INTC) += cp_intc.o
+
+# Board specific
+obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o
+obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o
+obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o
+obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o
+obj-$(CONFIG_MACH_DM355_LEOPARD) += board-dm355-leopard.o
+obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o
+obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o
+obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o
+obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o
+obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o
+obj-$(CONFIG_MACH_MITYOMAPL138) += board-mityomapl138.o
+obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o
+
+# Power Management
+obj-$(CONFIG_CPU_FREQ) += cpufreq.o
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+obj-$(CONFIG_SUSPEND) += pm.o sleep.o
diff --git a/arch/arm/mach-davinci/Makefile.boot b/arch/arm/mach-davinci/Makefile.boot
new file mode 100644
index 00000000..db97ef2c
--- /dev/null
+++ b/arch/arm/mach-davinci/Makefile.boot
@@ -0,0 +1,13 @@
+ifeq ($(CONFIG_ARCH_DAVINCI_DA8XX),y)
+ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y)
+$(error Cannot enable DaVinci and DA8XX platforms concurrently)
+else
+ zreladdr-y := 0xc0008000
+params_phys-y := 0xc0000100
+initrd_phys-y := 0xc0800000
+endif
+else
+ zreladdr-y := 0x80008000
+params_phys-y := 0x80000100
+initrd_phys-y := 0x80800000
+endif
diff --git a/arch/arm/mach-davinci/aemif.c b/arch/arm/mach-davinci/aemif.c
new file mode 100644
index 00000000..1ce70a91
--- /dev/null
+++ b/arch/arm/mach-davinci/aemif.c
@@ -0,0 +1,133 @@
+/*
+ * AEMIF support for DaVinci SoCs
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated. http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/time.h>
+
+#include <mach/aemif.h>
+
+/* Timing value configuration */
+
+#define TA(x) ((x) << 2)
+#define RHOLD(x) ((x) << 4)
+#define RSTROBE(x) ((x) << 7)
+#define RSETUP(x) ((x) << 13)
+#define WHOLD(x) ((x) << 17)
+#define WSTROBE(x) ((x) << 20)
+#define WSETUP(x) ((x) << 26)
+
+#define TA_MAX 0x3
+#define RHOLD_MAX 0x7
+#define RSTROBE_MAX 0x3f
+#define RSETUP_MAX 0xf
+#define WHOLD_MAX 0x7
+#define WSTROBE_MAX 0x3f
+#define WSETUP_MAX 0xf
+
+#define TIMING_MASK (TA(TA_MAX) | \
+ RHOLD(RHOLD_MAX) | \
+ RSTROBE(RSTROBE_MAX) | \
+ RSETUP(RSETUP_MAX) | \
+ WHOLD(WHOLD_MAX) | \
+ WSTROBE(WSTROBE_MAX) | \
+ WSETUP(WSETUP_MAX))
+
+/*
+ * aemif_calc_rate - calculate timing data.
+ * @wanted: The cycle time needed in nanoseconds.
+ * @clk: The input clock rate in kHz.
+ * @max: The maximum divider value that can be programmed.
+ *
+ * On success, returns the calculated timing value minus 1 for easy
+ * programming into AEMIF timing registers, else negative errno.
+ */
+static int aemif_calc_rate(int wanted, unsigned long clk, int max)
+{
+ int result;
+
+ result = DIV_ROUND_UP((wanted * clk), NSEC_PER_MSEC) - 1;
+
+ pr_debug("%s: result %d from %ld, %d\n", __func__, result, clk, wanted);
+
+ /* It is generally OK to have a more relaxed timing than requested... */
+ if (result < 0)
+ result = 0;
+
+ /* ... But configuring tighter timings is not an option. */
+ else if (result > max)
+ result = -EINVAL;
+
+ return result;
+}
+
+/**
+ * davinci_aemif_setup_timing - setup timing values for a given AEMIF interface
+ * @t: timing values to be progammed
+ * @base: The virtual base address of the AEMIF interface
+ * @cs: chip-select to program the timing values for
+ *
+ * This function programs the given timing values (in real clock) into the
+ * AEMIF registers taking the AEMIF clock into account.
+ *
+ * This function does not use any locking while programming the AEMIF
+ * because it is expected that there is only one user of a given
+ * chip-select.
+ *
+ * Returns 0 on success, else negative errno.
+ */
+int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
+ void __iomem *base, unsigned cs)
+{
+ unsigned set, val;
+ int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
+ unsigned offset = A1CR_OFFSET + cs * 4;
+ struct clk *aemif_clk;
+ unsigned long clkrate;
+
+ if (!t)
+ return 0; /* Nothing to do */
+
+ aemif_clk = clk_get(NULL, "aemif");
+ if (IS_ERR(aemif_clk))
+ return PTR_ERR(aemif_clk);
+
+ clkrate = clk_get_rate(aemif_clk);
+
+ clkrate /= 1000; /* turn clock into kHz for ease of use */
+
+ ta = aemif_calc_rate(t->ta, clkrate, TA_MAX);
+ rhold = aemif_calc_rate(t->rhold, clkrate, RHOLD_MAX);
+ rstrobe = aemif_calc_rate(t->rstrobe, clkrate, RSTROBE_MAX);
+ rsetup = aemif_calc_rate(t->rsetup, clkrate, RSETUP_MAX);
+ whold = aemif_calc_rate(t->whold, clkrate, WHOLD_MAX);
+ wstrobe = aemif_calc_rate(t->wstrobe, clkrate, WSTROBE_MAX);
+ wsetup = aemif_calc_rate(t->wsetup, clkrate, WSETUP_MAX);
+
+ if (ta < 0 || rhold < 0 || rstrobe < 0 || rsetup < 0 ||
+ whold < 0 || wstrobe < 0 || wsetup < 0) {
+ pr_err("%s: cannot get suitable timings\n", __func__);
+ return -EINVAL;
+ }
+
+ set = TA(ta) | RHOLD(rhold) | RSTROBE(rstrobe) | RSETUP(rsetup) |
+ WHOLD(whold) | WSTROBE(wstrobe) | WSETUP(wsetup);
+
+ val = __raw_readl(base + offset);
+ val &= ~TIMING_MASK;
+ val |= set;
+ __raw_writel(val, base + offset);
+
+ return 0;
+}
+EXPORT_SYMBOL(davinci_aemif_setup_timing);
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
new file mode 100644
index 00000000..8bc3701a
--- /dev/null
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -0,0 +1,684 @@
+/*
+ * TI DA830/OMAP L137 EVM board
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ * Derived from: arch/arm/mach-davinci/board-dm644x-evm.c
+ *
+ * 2007, 2009 (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/console.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/i2c/at24.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/cp_intc.h>
+#include <mach/mux.h>
+#include <mach/nand.h>
+#include <mach/da8xx.h>
+#include <mach/usb.h>
+#include <mach/aemif.h>
+#include <mach/spi.h>
+
+#define DA830_EVM_PHY_ID ""
+/*
+ * USB1 VBUS is controlled by GPIO1[15], over-current is reported on GPIO2[4].
+ */
+#define ON_BD_USB_DRV GPIO_TO_PIN(1, 15)
+#define ON_BD_USB_OVC GPIO_TO_PIN(2, 4)
+
+static const short da830_evm_usb11_pins[] = {
+ DA830_GPIO1_15, DA830_GPIO2_4,
+ -1
+};
+
+static da8xx_ocic_handler_t da830_evm_usb_ocic_handler;
+
+static int da830_evm_usb_set_power(unsigned port, int on)
+{
+ gpio_set_value(ON_BD_USB_DRV, on);
+ return 0;
+}
+
+static int da830_evm_usb_get_power(unsigned port)
+{
+ return gpio_get_value(ON_BD_USB_DRV);
+}
+
+static int da830_evm_usb_get_oci(unsigned port)
+{
+ return !gpio_get_value(ON_BD_USB_OVC);
+}
+
+static irqreturn_t da830_evm_usb_ocic_irq(int, void *);
+
+static int da830_evm_usb_ocic_notify(da8xx_ocic_handler_t handler)
+{
+ int irq = gpio_to_irq(ON_BD_USB_OVC);
+ int error = 0;
+
+ if (handler != NULL) {
+ da830_evm_usb_ocic_handler = handler;
+
+ error = request_irq(irq, da830_evm_usb_ocic_irq, IRQF_DISABLED |
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "OHCI over-current indicator", NULL);
+ if (error)
+ printk(KERN_ERR "%s: could not request IRQ to watch "
+ "over-current indicator changes\n", __func__);
+ } else
+ free_irq(irq, NULL);
+
+ return error;
+}
+
+static struct da8xx_ohci_root_hub da830_evm_usb11_pdata = {
+ .set_power = da830_evm_usb_set_power,
+ .get_power = da830_evm_usb_get_power,
+ .get_oci = da830_evm_usb_get_oci,
+ .ocic_notify = da830_evm_usb_ocic_notify,
+
+ /* TPS2065 switch @ 5V */
+ .potpgt = (3 + 1) / 2, /* 3 ms max */
+};
+
+static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *dev_id)
+{
+ da830_evm_usb_ocic_handler(&da830_evm_usb11_pdata, 1);
+ return IRQ_HANDLED;
+}
+
+static __init void da830_evm_usb_init(void)
+{
+ u32 cfgchip2;
+ int ret;
+
+ /*
+ * Set up USB clock/mode in the CFGCHIP2 register.
+ * FYI: CFGCHIP2 is 0x0000ef00 initially.
+ */
+ cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ /* USB2.0 PHY reference clock is 24 MHz */
+ cfgchip2 &= ~CFGCHIP2_REFFREQ;
+ cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ;
+
+ /*
+ * Select internal reference clock for USB 2.0 PHY
+ * and use it as a clock source for USB 1.1 PHY
+ * (this is the default setting anyway).
+ */
+ cfgchip2 &= ~CFGCHIP2_USB1PHYCLKMUX;
+ cfgchip2 |= CFGCHIP2_USB2PHYCLKMUX;
+
+ /*
+ * We have to override VBUS/ID signals when MUSB is configured into the
+ * host-only mode -- ID pin will float if no cable is connected, so the
+ * controller won't be able to drive VBUS thinking that it's a B-device.
+ * Otherwise, we want to use the OTG mode and enable VBUS comparators.
+ */
+ cfgchip2 &= ~CFGCHIP2_OTGMODE;
+#ifdef CONFIG_USB_MUSB_HOST
+ cfgchip2 |= CFGCHIP2_FORCE_HOST;
+#else
+ cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN;
+#endif
+
+ __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ /* USB_REFCLKIN is not used. */
+ ret = davinci_cfg_reg(DA830_USB0_DRVVBUS);
+ if (ret)
+ pr_warning("%s: USB 2.0 PinMux setup failed: %d\n",
+ __func__, ret);
+ else {
+ /*
+ * TPS2065 switch @ 5V supplies 1 A (sustains 1.5 A),
+ * with the power on to power good time of 3 ms.
+ */
+ ret = da8xx_register_usb20(1000, 3);
+ if (ret)
+ pr_warning("%s: USB 2.0 registration failed: %d\n",
+ __func__, ret);
+ }
+
+ ret = davinci_cfg_reg_list(da830_evm_usb11_pins);
+ if (ret) {
+ pr_warning("%s: USB 1.1 PinMux setup failed: %d\n",
+ __func__, ret);
+ return;
+ }
+
+ ret = gpio_request(ON_BD_USB_DRV, "ON_BD_USB_DRV");
+ if (ret) {
+ printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port "
+ "power control: %d\n", __func__, ret);
+ return;
+ }
+ gpio_direction_output(ON_BD_USB_DRV, 0);
+
+ ret = gpio_request(ON_BD_USB_OVC, "ON_BD_USB_OVC");
+ if (ret) {
+ printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port "
+ "over-current indicator: %d\n", __func__, ret);
+ return;
+ }
+ gpio_direction_input(ON_BD_USB_OVC);
+
+ ret = da8xx_register_usb11(&da830_evm_usb11_pdata);
+ if (ret)
+ pr_warning("%s: USB 1.1 registration failed: %d\n",
+ __func__, ret);
+}
+
+static struct davinci_uart_config da830_evm_uart_config __initdata = {
+ .enabled_uarts = 0x7,
+};
+
+static const short da830_evm_mcasp1_pins[] = {
+ DA830_AHCLKX1, DA830_ACLKX1, DA830_AFSX1, DA830_AHCLKR1, DA830_AFSR1,
+ DA830_AMUTE1, DA830_AXR1_0, DA830_AXR1_1, DA830_AXR1_2, DA830_AXR1_5,
+ DA830_ACLKR1, DA830_AXR1_6, DA830_AXR1_7, DA830_AXR1_8, DA830_AXR1_10,
+ DA830_AXR1_11,
+ -1
+};
+
+static u8 da830_iis_serializer_direction[] = {
+ RX_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
+ INACTIVE_MODE, TX_MODE, INACTIVE_MODE, INACTIVE_MODE,
+ INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
+};
+
+static struct snd_platform_data da830_evm_snd_data = {
+ .tx_dma_offset = 0x2000,
+ .rx_dma_offset = 0x2000,
+ .op_mode = DAVINCI_MCASP_IIS_MODE,
+ .num_serializer = ARRAY_SIZE(da830_iis_serializer_direction),
+ .tdm_slots = 2,
+ .serial_dir = da830_iis_serializer_direction,
+ .asp_chan_q = EVENTQ_0,
+ .version = MCASP_VERSION_2,
+ .txnumevt = 1,
+ .rxnumevt = 1,
+};
+
+/*
+ * GPIO2[1] is used as MMC_SD_WP and GPIO2[2] as MMC_SD_INS.
+ */
+static const short da830_evm_mmc_sd_pins[] = {
+ DA830_MMCSD_DAT_0, DA830_MMCSD_DAT_1, DA830_MMCSD_DAT_2,
+ DA830_MMCSD_DAT_3, DA830_MMCSD_DAT_4, DA830_MMCSD_DAT_5,
+ DA830_MMCSD_DAT_6, DA830_MMCSD_DAT_7, DA830_MMCSD_CLK,
+ DA830_MMCSD_CMD, DA830_GPIO2_1, DA830_GPIO2_2,
+ -1
+};
+
+#define DA830_MMCSD_WP_PIN GPIO_TO_PIN(2, 1)
+#define DA830_MMCSD_CD_PIN GPIO_TO_PIN(2, 2)
+
+static int da830_evm_mmc_get_ro(int index)
+{
+ return gpio_get_value(DA830_MMCSD_WP_PIN);
+}
+
+static int da830_evm_mmc_get_cd(int index)
+{
+ return !gpio_get_value(DA830_MMCSD_CD_PIN);
+}
+
+static struct davinci_mmc_config da830_evm_mmc_config = {
+ .get_ro = da830_evm_mmc_get_ro,
+ .get_cd = da830_evm_mmc_get_cd,
+ .wires = 8,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .version = MMC_CTLR_VERSION_2,
+};
+
+static inline void da830_evm_init_mmc(void)
+{
+ int ret;
+
+ ret = davinci_cfg_reg_list(da830_evm_mmc_sd_pins);
+ if (ret) {
+ pr_warning("da830_evm_init: mmc/sd mux setup failed: %d\n",
+ ret);
+ return;
+ }
+
+ ret = gpio_request(DA830_MMCSD_WP_PIN, "MMC WP");
+ if (ret) {
+ pr_warning("da830_evm_init: can not open GPIO %d\n",
+ DA830_MMCSD_WP_PIN);
+ return;
+ }
+ gpio_direction_input(DA830_MMCSD_WP_PIN);
+
+ ret = gpio_request(DA830_MMCSD_CD_PIN, "MMC CD\n");
+ if (ret) {
+ pr_warning("da830_evm_init: can not open GPIO %d\n",
+ DA830_MMCSD_CD_PIN);
+ return;
+ }
+ gpio_direction_input(DA830_MMCSD_CD_PIN);
+
+ ret = da8xx_register_mmcsd0(&da830_evm_mmc_config);
+ if (ret) {
+ pr_warning("da830_evm_init: mmc/sd registration failed: %d\n",
+ ret);
+ gpio_free(DA830_MMCSD_WP_PIN);
+ }
+}
+
+/*
+ * UI board NAND/NOR flashes only use 8-bit data bus.
+ */
+static const short da830_evm_emif25_pins[] = {
+ DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3,
+ DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7,
+ DA830_EMA_A_0, DA830_EMA_A_1, DA830_EMA_A_2, DA830_EMA_A_3,
+ DA830_EMA_A_4, DA830_EMA_A_5, DA830_EMA_A_6, DA830_EMA_A_7,
+ DA830_EMA_A_8, DA830_EMA_A_9, DA830_EMA_A_10, DA830_EMA_A_11,
+ DA830_EMA_A_12, DA830_EMA_BA_0, DA830_EMA_BA_1, DA830_NEMA_WE,
+ DA830_NEMA_CS_2, DA830_NEMA_CS_3, DA830_NEMA_OE, DA830_EMA_WAIT_0,
+ -1
+};
+
+#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
+#define HAS_MMC 1
+#else
+#define HAS_MMC 0
+#endif
+
+#ifdef CONFIG_DA830_UI_NAND
+static struct mtd_partition da830_evm_nand_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ [0] = {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ [1] = {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* kernel */
+ [2] = {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0,
+ },
+ /* file system */
+ [3] = {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+};
+
+/* flash bbt decriptors */
+static uint8_t da830_evm_nand_bbt_pattern[] = { 'B', 'b', 't', '0' };
+static uint8_t da830_evm_nand_mirror_pattern[] = { '1', 't', 'b', 'B' };
+
+static struct nand_bbt_descr da830_evm_nand_bbt_main_descr = {
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE |
+ NAND_BBT_WRITE | NAND_BBT_2BIT |
+ NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+ .offs = 2,
+ .len = 4,
+ .veroffs = 16,
+ .maxblocks = 4,
+ .pattern = da830_evm_nand_bbt_pattern
+};
+
+static struct nand_bbt_descr da830_evm_nand_bbt_mirror_descr = {
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE |
+ NAND_BBT_WRITE | NAND_BBT_2BIT |
+ NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+ .offs = 2,
+ .len = 4,
+ .veroffs = 16,
+ .maxblocks = 4,
+ .pattern = da830_evm_nand_mirror_pattern
+};
+
+static struct davinci_aemif_timing da830_evm_nandflash_timing = {
+ .wsetup = 24,
+ .wstrobe = 21,
+ .whold = 14,
+ .rsetup = 19,
+ .rstrobe = 50,
+ .rhold = 0,
+ .ta = 20,
+};
+
+static struct davinci_nand_pdata da830_evm_nand_pdata = {
+ .parts = da830_evm_nand_partitions,
+ .nr_parts = ARRAY_SIZE(da830_evm_nand_partitions),
+ .ecc_mode = NAND_ECC_HW,
+ .ecc_bits = 4,
+ .options = NAND_USE_FLASH_BBT,
+ .bbt_td = &da830_evm_nand_bbt_main_descr,
+ .bbt_md = &da830_evm_nand_bbt_mirror_descr,
+ .timing = &da830_evm_nandflash_timing,
+};
+
+static struct resource da830_evm_nand_resources[] = {
+ [0] = { /* First memory resource is NAND I/O window */
+ .start = DA8XX_AEMIF_CS3_BASE,
+ .end = DA8XX_AEMIF_CS3_BASE + PAGE_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* Second memory resource is AEMIF control registers */
+ .start = DA8XX_AEMIF_CTL_BASE,
+ .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da830_evm_nand_device = {
+ .name = "davinci_nand",
+ .id = 1,
+ .dev = {
+ .platform_data = &da830_evm_nand_pdata,
+ },
+ .num_resources = ARRAY_SIZE(da830_evm_nand_resources),
+ .resource = da830_evm_nand_resources,
+};
+
+static inline void da830_evm_init_nand(int mux_mode)
+{
+ int ret;
+
+ if (HAS_MMC) {
+ pr_warning("WARNING: both MMC/SD and NAND are "
+ "enabled, but they share AEMIF pins.\n"
+ "\tDisable MMC/SD for NAND support.\n");
+ return;
+ }
+
+ ret = davinci_cfg_reg_list(da830_evm_emif25_pins);
+ if (ret)
+ pr_warning("da830_evm_init: emif25 mux setup failed: %d\n",
+ ret);
+
+ ret = platform_device_register(&da830_evm_nand_device);
+ if (ret)
+ pr_warning("da830_evm_init: NAND device not registered.\n");
+
+ gpio_direction_output(mux_mode, 1);
+}
+#else
+static inline void da830_evm_init_nand(int mux_mode) { }
+#endif
+
+#ifdef CONFIG_DA830_UI_LCD
+static inline void da830_evm_init_lcdc(int mux_mode)
+{
+ int ret;
+
+ ret = davinci_cfg_reg_list(da830_lcdcntl_pins);
+ if (ret)
+ pr_warning("da830_evm_init: lcdcntl mux setup failed: %d\n",
+ ret);
+
+ ret = da8xx_register_lcdc(&sharp_lcd035q3dg01_pdata);
+ if (ret)
+ pr_warning("da830_evm_init: lcd setup failed: %d\n", ret);
+
+ gpio_direction_output(mux_mode, 0);
+}
+#else
+static inline void da830_evm_init_lcdc(int mux_mode) { }
+#endif
+
+static struct at24_platform_data da830_evm_i2c_eeprom_info = {
+ .byte_len = SZ_256K / 8,
+ .page_size = 64,
+ .flags = AT24_FLAG_ADDR16,
+ .setup = davinci_get_mac_addr,
+ .context = (void *)0x7f00,
+};
+
+static int __init da830_evm_ui_expander_setup(struct i2c_client *client,
+ int gpio, unsigned ngpio, void *context)
+{
+ gpio_request(gpio + 6, "UI MUX_MODE");
+
+ /* Drive mux mode low to match the default without UI card */
+ gpio_direction_output(gpio + 6, 0);
+
+ da830_evm_init_lcdc(gpio + 6);
+
+ da830_evm_init_nand(gpio + 6);
+
+ return 0;
+}
+
+static int da830_evm_ui_expander_teardown(struct i2c_client *client, int gpio,
+ unsigned ngpio, void *context)
+{
+ gpio_free(gpio + 6);
+ return 0;
+}
+
+static struct pcf857x_platform_data __initdata da830_evm_ui_expander_info = {
+ .gpio_base = DAVINCI_N_GPIO,
+ .setup = da830_evm_ui_expander_setup,
+ .teardown = da830_evm_ui_expander_teardown,
+};
+
+static struct i2c_board_info __initdata da830_evm_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("24c256", 0x50),
+ .platform_data = &da830_evm_i2c_eeprom_info,
+ },
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x18),
+ },
+ {
+ I2C_BOARD_INFO("pcf8574", 0x3f),
+ .platform_data = &da830_evm_ui_expander_info,
+ },
+};
+
+static struct davinci_i2c_platform_data da830_evm_i2c_0_pdata = {
+ .bus_freq = 100, /* kHz */
+ .bus_delay = 0, /* usec */
+};
+
+/*
+ * The following EDMA channels/slots are not being used by drivers (for
+ * example: Timer, GPIO, UART events etc) on da830/omap-l137 EVM, hence
+ * they are being reserved for codecs on the DSP side.
+ */
+static const s16 da830_dma_rsv_chans[][2] = {
+ /* (offset, number) */
+ { 8, 2},
+ {12, 2},
+ {24, 4},
+ {30, 2},
+ {-1, -1}
+};
+
+static const s16 da830_dma_rsv_slots[][2] = {
+ /* (offset, number) */
+ { 8, 2},
+ {12, 2},
+ {24, 4},
+ {30, 26},
+ {-1, -1}
+};
+
+static struct edma_rsv_info da830_edma_rsv[] = {
+ {
+ .rsv_chans = da830_dma_rsv_chans,
+ .rsv_slots = da830_dma_rsv_slots,
+ },
+};
+
+static struct mtd_partition da830evm_spiflash_part[] = {
+ [0] = {
+ .name = "DSP-UBL",
+ .offset = 0,
+ .size = SZ_8K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [1] = {
+ .name = "ARM-UBL",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_16K + SZ_8K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [2] = {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K - SZ_32K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [3] = {
+ .name = "U-Boot-Environment",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_16K,
+ .mask_flags = 0,
+ },
+ [4] = {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct flash_platform_data da830evm_spiflash_data = {
+ .name = "m25p80",
+ .parts = da830evm_spiflash_part,
+ .nr_parts = ARRAY_SIZE(da830evm_spiflash_part),
+ .type = "w25x32",
+};
+
+static struct davinci_spi_config da830evm_spiflash_cfg = {
+ .io_type = SPI_IO_TYPE_DMA,
+ .c2tdelay = 8,
+ .t2cdelay = 8,
+};
+
+static struct spi_board_info da830evm_spi_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &da830evm_spiflash_data,
+ .controller_data = &da830evm_spiflash_cfg,
+ .mode = SPI_MODE_0,
+ .max_speed_hz = 30000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+static __init void da830_evm_init(void)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ int ret;
+
+ ret = da830_register_edma(da830_edma_rsv);
+ if (ret)
+ pr_warning("da830_evm_init: edma registration failed: %d\n",
+ ret);
+
+ ret = davinci_cfg_reg_list(da830_i2c0_pins);
+ if (ret)
+ pr_warning("da830_evm_init: i2c0 mux setup failed: %d\n",
+ ret);
+
+ ret = da8xx_register_i2c(0, &da830_evm_i2c_0_pdata);
+ if (ret)
+ pr_warning("da830_evm_init: i2c0 registration failed: %d\n",
+ ret);
+
+ da830_evm_usb_init();
+
+ soc_info->emac_pdata->rmii_en = 1;
+ soc_info->emac_pdata->phy_id = DA830_EVM_PHY_ID;
+
+ ret = davinci_cfg_reg_list(da830_cpgmac_pins);
+ if (ret)
+ pr_warning("da830_evm_init: cpgmac mux setup failed: %d\n",
+ ret);
+
+ ret = da8xx_register_emac();
+ if (ret)
+ pr_warning("da830_evm_init: emac registration failed: %d\n",
+ ret);
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warning("da830_evm_init: watchdog registration failed: %d\n",
+ ret);
+
+ davinci_serial_init(&da830_evm_uart_config);
+ i2c_register_board_info(1, da830_evm_i2c_devices,
+ ARRAY_SIZE(da830_evm_i2c_devices));
+
+ ret = davinci_cfg_reg_list(da830_evm_mcasp1_pins);
+ if (ret)
+ pr_warning("da830_evm_init: mcasp1 mux setup failed: %d\n",
+ ret);
+
+ da8xx_register_mcasp(1, &da830_evm_snd_data);
+
+ da830_evm_init_mmc();
+
+ ret = da8xx_register_rtc();
+ if (ret)
+ pr_warning("da830_evm_init: rtc setup failed: %d\n", ret);
+
+ ret = da8xx_register_spi(0, da830evm_spi_info,
+ ARRAY_SIZE(da830evm_spi_info));
+ if (ret)
+ pr_warning("da830_evm_init: spi 0 registration failed: %d\n",
+ ret);
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init da830_evm_console_init(void)
+{
+ if (!machine_is_davinci_da830_evm())
+ return 0;
+
+ return add_preferred_console("ttyS", 2, "115200");
+}
+console_initcall(da830_evm_console_init);
+#endif
+
+static void __init da830_evm_map_io(void)
+{
+ da830_init();
+}
+
+MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM")
+ .boot_params = (DA8XX_DDR_BASE + 0x100),
+ .map_io = da830_evm_map_io,
+ .init_irq = cp_intc_init,
+ .timer = &davinci_timer,
+ .init_machine = da830_evm_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
new file mode 100644
index 00000000..f8936174
--- /dev/null
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -0,0 +1,1292 @@
+/*
+ * TI DA850/OMAP-L138 EVM board
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Derived from: arch/arm/mach-davinci/board-da830-evm.c
+ * Original Copyrights follow:
+ *
+ * 2007, 2009 (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/console.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/input.h>
+#include <linux/mfd/tps6507x.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/tps6507x.h>
+#include <linux/input/tps6507x-ts.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/cp_intc.h>
+#include <mach/da8xx.h>
+#include <mach/nand.h>
+#include <mach/mux.h>
+#include <mach/aemif.h>
+#include <mach/spi.h>
+
+#define DA850_EVM_PHY_ID "0:00"
+#define DA850_LCD_PWR_PIN GPIO_TO_PIN(2, 8)
+#define DA850_LCD_BL_PIN GPIO_TO_PIN(2, 15)
+
+#define DA850_MMCSD_CD_PIN GPIO_TO_PIN(4, 0)
+#define DA850_MMCSD_WP_PIN GPIO_TO_PIN(4, 1)
+
+#define DA850_MII_MDIO_CLKEN_PIN GPIO_TO_PIN(2, 6)
+
+static struct mtd_partition da850evm_spiflash_part[] = {
+ [0] = {
+ .name = "UBL",
+ .offset = 0,
+ .size = SZ_64K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [1] = {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_512K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [2] = {
+ .name = "U-Boot-Env",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_64K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [3] = {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M + SZ_512K,
+ .mask_flags = 0,
+ },
+ [4] = {
+ .name = "Filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ },
+ [5] = {
+ .name = "MAC-Address",
+ .offset = SZ_8M - SZ_64K,
+ .size = SZ_64K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct flash_platform_data da850evm_spiflash_data = {
+ .name = "m25p80",
+ .parts = da850evm_spiflash_part,
+ .nr_parts = ARRAY_SIZE(da850evm_spiflash_part),
+ .type = "m25p64",
+};
+
+static struct davinci_spi_config da850evm_spiflash_cfg = {
+ .io_type = SPI_IO_TYPE_DMA,
+ .c2tdelay = 8,
+ .t2cdelay = 8,
+};
+
+static struct spi_board_info da850evm_spi_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &da850evm_spiflash_data,
+ .controller_data = &da850evm_spiflash_cfg,
+ .mode = SPI_MODE_0,
+ .max_speed_hz = 30000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ },
+};
+
+#ifdef CONFIG_MTD
+static void da850_evm_m25p80_notify_add(struct mtd_info *mtd)
+{
+ char *mac_addr = davinci_soc_info.emac_pdata->mac_addr;
+ size_t retlen;
+
+ if (!strcmp(mtd->name, "MAC-Address")) {
+ mtd->read(mtd, 0, ETH_ALEN, &retlen, mac_addr);
+ if (retlen == ETH_ALEN)
+ pr_info("Read MAC addr from SPI Flash: %pM\n",
+ mac_addr);
+ }
+}
+
+static struct mtd_notifier da850evm_spi_notifier = {
+ .add = da850_evm_m25p80_notify_add,
+};
+
+static void da850_evm_setup_mac_addr(void)
+{
+ register_mtd_user(&da850evm_spi_notifier);
+}
+#else
+static void da850_evm_setup_mac_addr(void) { }
+#endif
+
+static struct mtd_partition da850_evm_norflash_partition[] = {
+ {
+ .name = "bootloaders + env",
+ .offset = 0,
+ .size = SZ_512K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0,
+ },
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct physmap_flash_data da850_evm_norflash_data = {
+ .width = 2,
+ .parts = da850_evm_norflash_partition,
+ .nr_parts = ARRAY_SIZE(da850_evm_norflash_partition),
+};
+
+static struct resource da850_evm_norflash_resource[] = {
+ {
+ .start = DA8XX_AEMIF_CS2_BASE,
+ .end = DA8XX_AEMIF_CS2_BASE + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da850_evm_norflash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &da850_evm_norflash_data,
+ },
+ .num_resources = 1,
+ .resource = da850_evm_norflash_resource,
+};
+
+static struct davinci_pm_config da850_pm_pdata = {
+ .sleepcount = 128,
+};
+
+static struct platform_device da850_pm_device = {
+ .name = "pm-davinci",
+ .dev = {
+ .platform_data = &da850_pm_pdata,
+ },
+ .id = -1,
+};
+
+/* DA850/OMAP-L138 EVM includes a 512 MByte large-page NAND flash
+ * (128K blocks). It may be used instead of the (default) SPI flash
+ * to boot, using TI's tools to install the secondary boot loader
+ * (UBL) and U-Boot.
+ */
+static struct mtd_partition da850_evm_nandflash_partition[] = {
+ {
+ .name = "u-boot env",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "UBL",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "u-boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 4 * SZ_128K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel",
+ .offset = 0x200000,
+ .size = SZ_2M,
+ .mask_flags = 0,
+ },
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct davinci_aemif_timing da850_evm_nandflash_timing = {
+ .wsetup = 24,
+ .wstrobe = 21,
+ .whold = 14,
+ .rsetup = 19,
+ .rstrobe = 50,
+ .rhold = 0,
+ .ta = 20,
+};
+
+static struct davinci_nand_pdata da850_evm_nandflash_data = {
+ .parts = da850_evm_nandflash_partition,
+ .nr_parts = ARRAY_SIZE(da850_evm_nandflash_partition),
+ .ecc_mode = NAND_ECC_HW,
+ .ecc_bits = 4,
+ .options = NAND_USE_FLASH_BBT,
+ .timing = &da850_evm_nandflash_timing,
+};
+
+static struct resource da850_evm_nandflash_resource[] = {
+ {
+ .start = DA8XX_AEMIF_CS3_BASE,
+ .end = DA8XX_AEMIF_CS3_BASE + SZ_512K + 2 * SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DA8XX_AEMIF_CTL_BASE,
+ .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da850_evm_nandflash_device = {
+ .name = "davinci_nand",
+ .id = 1,
+ .dev = {
+ .platform_data = &da850_evm_nandflash_data,
+ },
+ .num_resources = ARRAY_SIZE(da850_evm_nandflash_resource),
+ .resource = da850_evm_nandflash_resource,
+};
+
+static struct platform_device *da850_evm_devices[] __initdata = {
+ &da850_evm_nandflash_device,
+ &da850_evm_norflash_device,
+};
+
+#define DA8XX_AEMIF_CE2CFG_OFFSET 0x10
+#define DA8XX_AEMIF_ASIZE_16BIT 0x1
+
+static void __init da850_evm_init_nor(void)
+{
+ void __iomem *aemif_addr;
+
+ aemif_addr = ioremap(DA8XX_AEMIF_CTL_BASE, SZ_32K);
+
+ /* Configure data bus width of CS2 to 16 bit */
+ writel(readl(aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET) |
+ DA8XX_AEMIF_ASIZE_16BIT,
+ aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET);
+
+ iounmap(aemif_addr);
+}
+
+static const short da850_evm_nand_pins[] = {
+ DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3,
+ DA850_EMA_D_4, DA850_EMA_D_5, DA850_EMA_D_6, DA850_EMA_D_7,
+ DA850_EMA_A_1, DA850_EMA_A_2, DA850_NEMA_CS_3, DA850_NEMA_CS_4,
+ DA850_NEMA_WE, DA850_NEMA_OE,
+ -1
+};
+
+static const short da850_evm_nor_pins[] = {
+ DA850_EMA_BA_1, DA850_EMA_CLK, DA850_EMA_WAIT_1, DA850_NEMA_CS_2,
+ DA850_NEMA_WE, DA850_NEMA_OE, DA850_EMA_D_0, DA850_EMA_D_1,
+ DA850_EMA_D_2, DA850_EMA_D_3, DA850_EMA_D_4, DA850_EMA_D_5,
+ DA850_EMA_D_6, DA850_EMA_D_7, DA850_EMA_D_8, DA850_EMA_D_9,
+ DA850_EMA_D_10, DA850_EMA_D_11, DA850_EMA_D_12, DA850_EMA_D_13,
+ DA850_EMA_D_14, DA850_EMA_D_15, DA850_EMA_A_0, DA850_EMA_A_1,
+ DA850_EMA_A_2, DA850_EMA_A_3, DA850_EMA_A_4, DA850_EMA_A_5,
+ DA850_EMA_A_6, DA850_EMA_A_7, DA850_EMA_A_8, DA850_EMA_A_9,
+ DA850_EMA_A_10, DA850_EMA_A_11, DA850_EMA_A_12, DA850_EMA_A_13,
+ DA850_EMA_A_14, DA850_EMA_A_15, DA850_EMA_A_16, DA850_EMA_A_17,
+ DA850_EMA_A_18, DA850_EMA_A_19, DA850_EMA_A_20, DA850_EMA_A_21,
+ DA850_EMA_A_22, DA850_EMA_A_23,
+ -1
+};
+
+#if defined(CONFIG_MMC_DAVINCI) || \
+ defined(CONFIG_MMC_DAVINCI_MODULE)
+#define HAS_MMC 1
+#else
+#define HAS_MMC 0
+#endif
+
+static inline void da850_evm_setup_nor_nand(void)
+{
+ int ret = 0;
+
+ if (!HAS_MMC) {
+ ret = davinci_cfg_reg_list(da850_evm_nand_pins);
+ if (ret)
+ pr_warning("da850_evm_init: nand mux setup failed: "
+ "%d\n", ret);
+
+ ret = davinci_cfg_reg_list(da850_evm_nor_pins);
+ if (ret)
+ pr_warning("da850_evm_init: nor mux setup failed: %d\n",
+ ret);
+
+ da850_evm_init_nor();
+
+ platform_add_devices(da850_evm_devices,
+ ARRAY_SIZE(da850_evm_devices));
+ }
+}
+
+#ifdef CONFIG_DA850_UI_RMII
+static inline void da850_evm_setup_emac_rmii(int rmii_sel)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ soc_info->emac_pdata->rmii_en = 1;
+ gpio_set_value_cansleep(rmii_sel, 0);
+}
+#else
+static inline void da850_evm_setup_emac_rmii(int rmii_sel) { }
+#endif
+
+
+#define DA850_KEYS_DEBOUNCE_MS 10
+/*
+ * At 200ms polling interval it is possible to miss an
+ * event by tapping very lightly on the push button but most
+ * pushes do result in an event; longer intervals require the
+ * user to hold the button whereas shorter intervals require
+ * more CPU time for polling.
+ */
+#define DA850_GPIO_KEYS_POLL_MS 200
+
+enum da850_evm_ui_exp_pins {
+ DA850_EVM_UI_EXP_SEL_C = 5,
+ DA850_EVM_UI_EXP_SEL_B,
+ DA850_EVM_UI_EXP_SEL_A,
+ DA850_EVM_UI_EXP_PB8,
+ DA850_EVM_UI_EXP_PB7,
+ DA850_EVM_UI_EXP_PB6,
+ DA850_EVM_UI_EXP_PB5,
+ DA850_EVM_UI_EXP_PB4,
+ DA850_EVM_UI_EXP_PB3,
+ DA850_EVM_UI_EXP_PB2,
+ DA850_EVM_UI_EXP_PB1,
+};
+
+static const char const *da850_evm_ui_exp[] = {
+ [DA850_EVM_UI_EXP_SEL_C] = "sel_c",
+ [DA850_EVM_UI_EXP_SEL_B] = "sel_b",
+ [DA850_EVM_UI_EXP_SEL_A] = "sel_a",
+ [DA850_EVM_UI_EXP_PB8] = "pb8",
+ [DA850_EVM_UI_EXP_PB7] = "pb7",
+ [DA850_EVM_UI_EXP_PB6] = "pb6",
+ [DA850_EVM_UI_EXP_PB5] = "pb5",
+ [DA850_EVM_UI_EXP_PB4] = "pb4",
+ [DA850_EVM_UI_EXP_PB3] = "pb3",
+ [DA850_EVM_UI_EXP_PB2] = "pb2",
+ [DA850_EVM_UI_EXP_PB1] = "pb1",
+};
+
+#define DA850_N_UI_PB 8
+
+static struct gpio_keys_button da850_evm_ui_keys[] = {
+ [0 ... DA850_N_UI_PB - 1] = {
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = DA850_KEYS_DEBOUNCE_MS,
+ .code = -1, /* assigned at runtime */
+ .gpio = -1, /* assigned at runtime */
+ .desc = NULL, /* assigned at runtime */
+ },
+};
+
+static struct gpio_keys_platform_data da850_evm_ui_keys_pdata = {
+ .buttons = da850_evm_ui_keys,
+ .nbuttons = ARRAY_SIZE(da850_evm_ui_keys),
+ .poll_interval = DA850_GPIO_KEYS_POLL_MS,
+};
+
+static struct platform_device da850_evm_ui_keys_device = {
+ .name = "gpio-keys-polled",
+ .id = 0,
+ .dev = {
+ .platform_data = &da850_evm_ui_keys_pdata
+ },
+};
+
+static void da850_evm_ui_keys_init(unsigned gpio)
+{
+ int i;
+ struct gpio_keys_button *button;
+
+ for (i = 0; i < DA850_N_UI_PB; i++) {
+ button = &da850_evm_ui_keys[i];
+ button->code = KEY_F8 - i;
+ button->desc = (char *)
+ da850_evm_ui_exp[DA850_EVM_UI_EXP_PB8 + i];
+ button->gpio = gpio + DA850_EVM_UI_EXP_PB8 + i;
+ }
+}
+
+static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
+ unsigned ngpio, void *c)
+{
+ int sel_a, sel_b, sel_c, ret;
+
+ sel_a = gpio + DA850_EVM_UI_EXP_SEL_A;
+ sel_b = gpio + DA850_EVM_UI_EXP_SEL_B;
+ sel_c = gpio + DA850_EVM_UI_EXP_SEL_C;
+
+ ret = gpio_request(sel_a, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_A]);
+ if (ret) {
+ pr_warning("Cannot open UI expander pin %d\n", sel_a);
+ goto exp_setup_sela_fail;
+ }
+
+ ret = gpio_request(sel_b, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_B]);
+ if (ret) {
+ pr_warning("Cannot open UI expander pin %d\n", sel_b);
+ goto exp_setup_selb_fail;
+ }
+
+ ret = gpio_request(sel_c, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_C]);
+ if (ret) {
+ pr_warning("Cannot open UI expander pin %d\n", sel_c);
+ goto exp_setup_selc_fail;
+ }
+
+ /* deselect all functionalities */
+ gpio_direction_output(sel_a, 1);
+ gpio_direction_output(sel_b, 1);
+ gpio_direction_output(sel_c, 1);
+
+ da850_evm_ui_keys_init(gpio);
+ ret = platform_device_register(&da850_evm_ui_keys_device);
+ if (ret) {
+ pr_warning("Could not register UI GPIO expander push-buttons");
+ goto exp_setup_keys_fail;
+ }
+
+ pr_info("DA850/OMAP-L138 EVM UI card detected\n");
+
+ da850_evm_setup_nor_nand();
+
+ da850_evm_setup_emac_rmii(sel_a);
+
+ return 0;
+
+exp_setup_keys_fail:
+ gpio_free(sel_c);
+exp_setup_selc_fail:
+ gpio_free(sel_b);
+exp_setup_selb_fail:
+ gpio_free(sel_a);
+exp_setup_sela_fail:
+ return ret;
+}
+
+static int da850_evm_ui_expander_teardown(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio, void *c)
+{
+ platform_device_unregister(&da850_evm_ui_keys_device);
+
+ /* deselect all functionalities */
+ gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_C, 1);
+ gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_B, 1);
+ gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_A, 1);
+
+ gpio_free(gpio + DA850_EVM_UI_EXP_SEL_C);
+ gpio_free(gpio + DA850_EVM_UI_EXP_SEL_B);
+ gpio_free(gpio + DA850_EVM_UI_EXP_SEL_A);
+
+ return 0;
+}
+
+/* assign the baseboard expander's GPIOs after the UI board's */
+#define DA850_UI_EXPANDER_N_GPIOS ARRAY_SIZE(da850_evm_ui_exp)
+#define DA850_BB_EXPANDER_GPIO_BASE (DAVINCI_N_GPIO + DA850_UI_EXPANDER_N_GPIOS)
+
+enum da850_evm_bb_exp_pins {
+ DA850_EVM_BB_EXP_DEEP_SLEEP_EN = 0,
+ DA850_EVM_BB_EXP_SW_RST,
+ DA850_EVM_BB_EXP_TP_23,
+ DA850_EVM_BB_EXP_TP_22,
+ DA850_EVM_BB_EXP_TP_21,
+ DA850_EVM_BB_EXP_USER_PB1,
+ DA850_EVM_BB_EXP_USER_LED2,
+ DA850_EVM_BB_EXP_USER_LED1,
+ DA850_EVM_BB_EXP_USER_SW1,
+ DA850_EVM_BB_EXP_USER_SW2,
+ DA850_EVM_BB_EXP_USER_SW3,
+ DA850_EVM_BB_EXP_USER_SW4,
+ DA850_EVM_BB_EXP_USER_SW5,
+ DA850_EVM_BB_EXP_USER_SW6,
+ DA850_EVM_BB_EXP_USER_SW7,
+ DA850_EVM_BB_EXP_USER_SW8
+};
+
+static const char const *da850_evm_bb_exp[] = {
+ [DA850_EVM_BB_EXP_DEEP_SLEEP_EN] = "deep_sleep_en",
+ [DA850_EVM_BB_EXP_SW_RST] = "sw_rst",
+ [DA850_EVM_BB_EXP_TP_23] = "tp_23",
+ [DA850_EVM_BB_EXP_TP_22] = "tp_22",
+ [DA850_EVM_BB_EXP_TP_21] = "tp_21",
+ [DA850_EVM_BB_EXP_USER_PB1] = "user_pb1",
+ [DA850_EVM_BB_EXP_USER_LED2] = "user_led2",
+ [DA850_EVM_BB_EXP_USER_LED1] = "user_led1",
+ [DA850_EVM_BB_EXP_USER_SW1] = "user_sw1",
+ [DA850_EVM_BB_EXP_USER_SW2] = "user_sw2",
+ [DA850_EVM_BB_EXP_USER_SW3] = "user_sw3",
+ [DA850_EVM_BB_EXP_USER_SW4] = "user_sw4",
+ [DA850_EVM_BB_EXP_USER_SW5] = "user_sw5",
+ [DA850_EVM_BB_EXP_USER_SW6] = "user_sw6",
+ [DA850_EVM_BB_EXP_USER_SW7] = "user_sw7",
+ [DA850_EVM_BB_EXP_USER_SW8] = "user_sw8",
+};
+
+#define DA850_N_BB_USER_SW 8
+
+static struct gpio_keys_button da850_evm_bb_keys[] = {
+ [0] = {
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = DA850_KEYS_DEBOUNCE_MS,
+ .code = KEY_PROG1,
+ .desc = NULL, /* assigned at runtime */
+ .gpio = -1, /* assigned at runtime */
+ },
+ [1 ... DA850_N_BB_USER_SW] = {
+ .type = EV_SW,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = DA850_KEYS_DEBOUNCE_MS,
+ .code = -1, /* assigned at runtime */
+ .desc = NULL, /* assigned at runtime */
+ .gpio = -1, /* assigned at runtime */
+ },
+};
+
+static struct gpio_keys_platform_data da850_evm_bb_keys_pdata = {
+ .buttons = da850_evm_bb_keys,
+ .nbuttons = ARRAY_SIZE(da850_evm_bb_keys),
+ .poll_interval = DA850_GPIO_KEYS_POLL_MS,
+};
+
+static struct platform_device da850_evm_bb_keys_device = {
+ .name = "gpio-keys-polled",
+ .id = 1,
+ .dev = {
+ .platform_data = &da850_evm_bb_keys_pdata
+ },
+};
+
+static void da850_evm_bb_keys_init(unsigned gpio)
+{
+ int i;
+ struct gpio_keys_button *button;
+
+ button = &da850_evm_bb_keys[0];
+ button->desc = (char *)
+ da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_PB1];
+ button->gpio = gpio + DA850_EVM_BB_EXP_USER_PB1;
+
+ for (i = 0; i < DA850_N_BB_USER_SW; i++) {
+ button = &da850_evm_bb_keys[i + 1];
+ button->code = SW_LID + i;
+ button->desc = (char *)
+ da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_SW1 + i];
+ button->gpio = gpio + DA850_EVM_BB_EXP_USER_SW1 + i;
+ }
+}
+
+#define DA850_N_BB_USER_LED 2
+
+static struct gpio_led da850_evm_bb_leds[] = {
+ [0 ... DA850_N_BB_USER_LED - 1] = {
+ .active_low = 1,
+ .gpio = -1, /* assigned at runtime */
+ .name = NULL, /* assigned at runtime */
+ },
+};
+
+static struct gpio_led_platform_data da850_evm_bb_leds_pdata = {
+ .leds = da850_evm_bb_leds,
+ .num_leds = ARRAY_SIZE(da850_evm_bb_leds),
+};
+
+static struct platform_device da850_evm_bb_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &da850_evm_bb_leds_pdata
+ }
+};
+
+static void da850_evm_bb_leds_init(unsigned gpio)
+{
+ int i;
+ struct gpio_led *led;
+
+ for (i = 0; i < DA850_N_BB_USER_LED; i++) {
+ led = &da850_evm_bb_leds[i];
+
+ led->gpio = gpio + DA850_EVM_BB_EXP_USER_LED2 + i;
+ led->name =
+ da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_LED2 + i];
+ }
+}
+
+static int da850_evm_bb_expander_setup(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio,
+ void *c)
+{
+ int ret;
+
+ /*
+ * Register the switches and pushbutton on the baseboard as a gpio-keys
+ * device.
+ */
+ da850_evm_bb_keys_init(gpio);
+ ret = platform_device_register(&da850_evm_bb_keys_device);
+ if (ret) {
+ pr_warning("Could not register baseboard GPIO expander keys");
+ goto io_exp_setup_sw_fail;
+ }
+
+ da850_evm_bb_leds_init(gpio);
+ ret = platform_device_register(&da850_evm_bb_leds_device);
+ if (ret) {
+ pr_warning("Could not register baseboard GPIO expander LEDS");
+ goto io_exp_setup_leds_fail;
+ }
+
+ return 0;
+
+io_exp_setup_leds_fail:
+ platform_device_unregister(&da850_evm_bb_keys_device);
+io_exp_setup_sw_fail:
+ return ret;
+}
+
+static int da850_evm_bb_expander_teardown(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio, void *c)
+{
+ platform_device_unregister(&da850_evm_bb_leds_device);
+ platform_device_unregister(&da850_evm_bb_keys_device);
+
+ return 0;
+}
+
+static struct pca953x_platform_data da850_evm_ui_expander_info = {
+ .gpio_base = DAVINCI_N_GPIO,
+ .setup = da850_evm_ui_expander_setup,
+ .teardown = da850_evm_ui_expander_teardown,
+ .names = da850_evm_ui_exp,
+};
+
+static struct pca953x_platform_data da850_evm_bb_expander_info = {
+ .gpio_base = DA850_BB_EXPANDER_GPIO_BASE,
+ .setup = da850_evm_bb_expander_setup,
+ .teardown = da850_evm_bb_expander_teardown,
+ .names = da850_evm_bb_exp,
+};
+
+static struct i2c_board_info __initdata da850_evm_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x18),
+ },
+ {
+ I2C_BOARD_INFO("tca6416", 0x20),
+ .platform_data = &da850_evm_ui_expander_info,
+ },
+ {
+ I2C_BOARD_INFO("tca6416", 0x21),
+ .platform_data = &da850_evm_bb_expander_info,
+ },
+};
+
+static struct davinci_i2c_platform_data da850_evm_i2c_0_pdata = {
+ .bus_freq = 100, /* kHz */
+ .bus_delay = 0, /* usec */
+};
+
+static struct davinci_uart_config da850_evm_uart_config __initdata = {
+ .enabled_uarts = 0x7,
+};
+
+/* davinci da850 evm audio machine driver */
+static u8 da850_iis_serializer_direction[] = {
+ INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
+ INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
+ INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, TX_MODE,
+ RX_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
+};
+
+static struct snd_platform_data da850_evm_snd_data = {
+ .tx_dma_offset = 0x2000,
+ .rx_dma_offset = 0x2000,
+ .op_mode = DAVINCI_MCASP_IIS_MODE,
+ .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction),
+ .tdm_slots = 2,
+ .serial_dir = da850_iis_serializer_direction,
+ .asp_chan_q = EVENTQ_0,
+ .version = MCASP_VERSION_2,
+ .txnumevt = 1,
+ .rxnumevt = 1,
+};
+
+static const short da850_evm_mcasp_pins[] __initconst = {
+ DA850_AHCLKX, DA850_ACLKX, DA850_AFSX,
+ DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE,
+ DA850_AXR_11, DA850_AXR_12,
+ -1
+};
+
+static int da850_evm_mmc_get_ro(int index)
+{
+ return gpio_get_value(DA850_MMCSD_WP_PIN);
+}
+
+static int da850_evm_mmc_get_cd(int index)
+{
+ return !gpio_get_value(DA850_MMCSD_CD_PIN);
+}
+
+static struct davinci_mmc_config da850_mmc_config = {
+ .get_ro = da850_evm_mmc_get_ro,
+ .get_cd = da850_evm_mmc_get_cd,
+ .wires = 4,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .version = MMC_CTLR_VERSION_2,
+};
+
+static const short da850_evm_mmcsd0_pins[] __initconst = {
+ DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2,
+ DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD,
+ DA850_GPIO4_0, DA850_GPIO4_1,
+ -1
+};
+
+static void da850_panel_power_ctrl(int val)
+{
+ /* lcd backlight */
+ gpio_set_value(DA850_LCD_BL_PIN, val);
+
+ /* lcd power */
+ gpio_set_value(DA850_LCD_PWR_PIN, val);
+}
+
+static int da850_lcd_hw_init(void)
+{
+ int status;
+
+ status = gpio_request(DA850_LCD_BL_PIN, "lcd bl\n");
+ if (status < 0)
+ return status;
+
+ status = gpio_request(DA850_LCD_PWR_PIN, "lcd pwr\n");
+ if (status < 0) {
+ gpio_free(DA850_LCD_BL_PIN);
+ return status;
+ }
+
+ gpio_direction_output(DA850_LCD_BL_PIN, 0);
+ gpio_direction_output(DA850_LCD_PWR_PIN, 0);
+
+ /* Switch off panel power and backlight */
+ da850_panel_power_ctrl(0);
+
+ /* Switch on panel power and backlight */
+ da850_panel_power_ctrl(1);
+
+ return 0;
+}
+
+/* TPS65070 voltage regulator support */
+
+/* 3.3V */
+static struct regulator_consumer_supply tps65070_dcdc1_consumers[] = {
+ {
+ .supply = "usb0_vdda33",
+ },
+ {
+ .supply = "usb1_vdda33",
+ },
+};
+
+/* 3.3V or 1.8V */
+static struct regulator_consumer_supply tps65070_dcdc2_consumers[] = {
+ {
+ .supply = "dvdd3318_a",
+ },
+ {
+ .supply = "dvdd3318_b",
+ },
+ {
+ .supply = "dvdd3318_c",
+ },
+};
+
+/* 1.2V */
+static struct regulator_consumer_supply tps65070_dcdc3_consumers[] = {
+ {
+ .supply = "cvdd",
+ },
+};
+
+/* 1.8V LDO */
+static struct regulator_consumer_supply tps65070_ldo1_consumers[] = {
+ {
+ .supply = "sata_vddr",
+ },
+ {
+ .supply = "usb0_vdda18",
+ },
+ {
+ .supply = "usb1_vdda18",
+ },
+ {
+ .supply = "ddr_dvdd18",
+ },
+};
+
+/* 1.2V LDO */
+static struct regulator_consumer_supply tps65070_ldo2_consumers[] = {
+ {
+ .supply = "sata_vdd",
+ },
+ {
+ .supply = "pll0_vdda",
+ },
+ {
+ .supply = "pll1_vdda",
+ },
+ {
+ .supply = "usbs_cvdd",
+ },
+ {
+ .supply = "vddarnwa1",
+ },
+};
+
+/* We take advantage of the fact that both defdcdc{2,3} are tied high */
+static struct tps6507x_reg_platform_data tps6507x_platform_data = {
+ .defdcdc_default = true,
+};
+
+static struct regulator_init_data tps65070_regulator_data[] = {
+ /* dcdc1 */
+ {
+ .constraints = {
+ .min_uV = 3150000,
+ .max_uV = 3450000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc1_consumers),
+ .consumer_supplies = tps65070_dcdc1_consumers,
+ },
+
+ /* dcdc2 */
+ {
+ .constraints = {
+ .min_uV = 1710000,
+ .max_uV = 3450000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc2_consumers),
+ .consumer_supplies = tps65070_dcdc2_consumers,
+ .driver_data = &tps6507x_platform_data,
+ },
+
+ /* dcdc3 */
+ {
+ .constraints = {
+ .min_uV = 950000,
+ .max_uV = 1350000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc3_consumers),
+ .consumer_supplies = tps65070_dcdc3_consumers,
+ .driver_data = &tps6507x_platform_data,
+ },
+
+ /* ldo1 */
+ {
+ .constraints = {
+ .min_uV = 1710000,
+ .max_uV = 1890000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65070_ldo1_consumers),
+ .consumer_supplies = tps65070_ldo1_consumers,
+ },
+
+ /* ldo2 */
+ {
+ .constraints = {
+ .min_uV = 1140000,
+ .max_uV = 1320000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65070_ldo2_consumers),
+ .consumer_supplies = tps65070_ldo2_consumers,
+ },
+};
+
+static struct touchscreen_init_data tps6507x_touchscreen_data = {
+ .poll_period = 30, /* ms between touch samples */
+ .min_pressure = 0x30, /* minimum pressure to trigger touch */
+ .vref = 0, /* turn off vref when not using A/D */
+ .vendor = 0, /* /sys/class/input/input?/id/vendor */
+ .product = 65070, /* /sys/class/input/input?/id/product */
+ .version = 0x100, /* /sys/class/input/input?/id/version */
+};
+
+static struct tps6507x_board tps_board = {
+ .tps6507x_pmic_init_data = &tps65070_regulator_data[0],
+ .tps6507x_ts_init_data = &tps6507x_touchscreen_data,
+};
+
+static struct i2c_board_info __initdata da850_evm_tps65070_info[] = {
+ {
+ I2C_BOARD_INFO("tps6507x", 0x48),
+ .platform_data = &tps_board,
+ },
+};
+
+static int __init pmic_tps65070_init(void)
+{
+ return i2c_register_board_info(1, da850_evm_tps65070_info,
+ ARRAY_SIZE(da850_evm_tps65070_info));
+}
+
+static const short da850_evm_lcdc_pins[] = {
+ DA850_GPIO2_8, DA850_GPIO2_15,
+ -1
+};
+
+static const short da850_evm_mii_pins[] = {
+ DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
+ DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
+ DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
+ DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
+static const short da850_evm_rmii_pins[] = {
+ DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN,
+ DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1,
+ DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
+static int __init da850_evm_config_emac(void)
+{
+ void __iomem *cfg_chip3_base;
+ int ret;
+ u32 val;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ u8 rmii_en = soc_info->emac_pdata->rmii_en;
+
+ if (!machine_is_davinci_da850_evm())
+ return 0;
+
+ cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
+
+ val = __raw_readl(cfg_chip3_base);
+
+ if (rmii_en) {
+ val |= BIT(8);
+ ret = davinci_cfg_reg_list(da850_evm_rmii_pins);
+ pr_info("EMAC: RMII PHY configured, MII PHY will not be"
+ " functional\n");
+ } else {
+ val &= ~BIT(8);
+ ret = davinci_cfg_reg_list(da850_evm_mii_pins);
+ pr_info("EMAC: MII PHY configured, RMII PHY will not be"
+ " functional\n");
+ }
+
+ if (ret)
+ pr_warning("da850_evm_init: cpgmac/rmii mux setup failed: %d\n",
+ ret);
+
+ /* configure the CFGCHIP3 register for RMII or MII */
+ __raw_writel(val, cfg_chip3_base);
+
+ ret = davinci_cfg_reg(DA850_GPIO2_6);
+ if (ret)
+ pr_warning("da850_evm_init:GPIO(2,6) mux setup "
+ "failed\n");
+
+ ret = gpio_request(DA850_MII_MDIO_CLKEN_PIN, "mdio_clk_en");
+ if (ret) {
+ pr_warning("Cannot open GPIO %d\n",
+ DA850_MII_MDIO_CLKEN_PIN);
+ return ret;
+ }
+
+ /* Enable/Disable MII MDIO clock */
+ gpio_direction_output(DA850_MII_MDIO_CLKEN_PIN, rmii_en);
+
+ soc_info->emac_pdata->phy_id = DA850_EVM_PHY_ID;
+
+ ret = da8xx_register_emac();
+ if (ret)
+ pr_warning("da850_evm_init: emac registration failed: %d\n",
+ ret);
+
+ return 0;
+}
+device_initcall(da850_evm_config_emac);
+
+/*
+ * The following EDMA channels/slots are not being used by drivers (for
+ * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM, hence
+ * they are being reserved for codecs on the DSP side.
+ */
+static const s16 da850_dma0_rsv_chans[][2] = {
+ /* (offset, number) */
+ { 8, 6},
+ {24, 4},
+ {30, 2},
+ {-1, -1}
+};
+
+static const s16 da850_dma0_rsv_slots[][2] = {
+ /* (offset, number) */
+ { 8, 6},
+ {24, 4},
+ {30, 50},
+ {-1, -1}
+};
+
+static const s16 da850_dma1_rsv_chans[][2] = {
+ /* (offset, number) */
+ { 0, 28},
+ {30, 2},
+ {-1, -1}
+};
+
+static const s16 da850_dma1_rsv_slots[][2] = {
+ /* (offset, number) */
+ { 0, 28},
+ {30, 90},
+ {-1, -1}
+};
+
+static struct edma_rsv_info da850_edma_cc0_rsv = {
+ .rsv_chans = da850_dma0_rsv_chans,
+ .rsv_slots = da850_dma0_rsv_slots,
+};
+
+static struct edma_rsv_info da850_edma_cc1_rsv = {
+ .rsv_chans = da850_dma1_rsv_chans,
+ .rsv_slots = da850_dma1_rsv_slots,
+};
+
+static struct edma_rsv_info *da850_edma_rsv[2] = {
+ &da850_edma_cc0_rsv,
+ &da850_edma_cc1_rsv,
+};
+
+#ifdef CONFIG_CPU_FREQ
+static __init int da850_evm_init_cpufreq(void)
+{
+ switch (system_rev & 0xF) {
+ case 3:
+ da850_max_speed = 456000;
+ break;
+ case 2:
+ da850_max_speed = 408000;
+ break;
+ case 1:
+ da850_max_speed = 372000;
+ break;
+ }
+
+ return da850_register_cpufreq("pll0_sysclk3");
+}
+#else
+static __init int da850_evm_init_cpufreq(void) { return 0; }
+#endif
+
+static __init void da850_evm_init(void)
+{
+ int ret;
+
+ ret = pmic_tps65070_init();
+ if (ret)
+ pr_warning("da850_evm_init: TPS65070 PMIC init failed: %d\n",
+ ret);
+
+ ret = da850_register_edma(da850_edma_rsv);
+ if (ret)
+ pr_warning("da850_evm_init: edma registration failed: %d\n",
+ ret);
+
+ ret = davinci_cfg_reg_list(da850_i2c0_pins);
+ if (ret)
+ pr_warning("da850_evm_init: i2c0 mux setup failed: %d\n",
+ ret);
+
+ ret = da8xx_register_i2c(0, &da850_evm_i2c_0_pdata);
+ if (ret)
+ pr_warning("da850_evm_init: i2c0 registration failed: %d\n",
+ ret);
+
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warning("da830_evm_init: watchdog registration failed: %d\n",
+ ret);
+
+ if (HAS_MMC) {
+ ret = davinci_cfg_reg_list(da850_evm_mmcsd0_pins);
+ if (ret)
+ pr_warning("da850_evm_init: mmcsd0 mux setup failed:"
+ " %d\n", ret);
+
+ ret = gpio_request(DA850_MMCSD_CD_PIN, "MMC CD\n");
+ if (ret)
+ pr_warning("da850_evm_init: can not open GPIO %d\n",
+ DA850_MMCSD_CD_PIN);
+ gpio_direction_input(DA850_MMCSD_CD_PIN);
+
+ ret = gpio_request(DA850_MMCSD_WP_PIN, "MMC WP\n");
+ if (ret)
+ pr_warning("da850_evm_init: can not open GPIO %d\n",
+ DA850_MMCSD_WP_PIN);
+ gpio_direction_input(DA850_MMCSD_WP_PIN);
+
+ ret = da8xx_register_mmcsd0(&da850_mmc_config);
+ if (ret)
+ pr_warning("da850_evm_init: mmcsd0 registration failed:"
+ " %d\n", ret);
+ }
+
+ davinci_serial_init(&da850_evm_uart_config);
+
+ i2c_register_board_info(1, da850_evm_i2c_devices,
+ ARRAY_SIZE(da850_evm_i2c_devices));
+
+ /*
+ * shut down uart 0 and 1; they are not used on the board and
+ * accessing them causes endless "too much work in irq53" messages
+ * with arago fs
+ */
+ __raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30);
+ __raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30);
+
+ ret = davinci_cfg_reg_list(da850_evm_mcasp_pins);
+ if (ret)
+ pr_warning("da850_evm_init: mcasp mux setup failed: %d\n",
+ ret);
+
+ da8xx_register_mcasp(0, &da850_evm_snd_data);
+
+ ret = davinci_cfg_reg_list(da850_lcdcntl_pins);
+ if (ret)
+ pr_warning("da850_evm_init: lcdcntl mux setup failed: %d\n",
+ ret);
+
+ /* Handle board specific muxing for LCD here */
+ ret = davinci_cfg_reg_list(da850_evm_lcdc_pins);
+ if (ret)
+ pr_warning("da850_evm_init: evm specific lcd mux setup "
+ "failed: %d\n", ret);
+
+ ret = da850_lcd_hw_init();
+ if (ret)
+ pr_warning("da850_evm_init: lcd initialization failed: %d\n",
+ ret);
+
+ sharp_lk043t1dg01_pdata.panel_power_ctrl = da850_panel_power_ctrl,
+ ret = da8xx_register_lcdc(&sharp_lk043t1dg01_pdata);
+ if (ret)
+ pr_warning("da850_evm_init: lcdc registration failed: %d\n",
+ ret);
+
+ ret = da8xx_register_rtc();
+ if (ret)
+ pr_warning("da850_evm_init: rtc setup failed: %d\n", ret);
+
+ ret = da850_evm_init_cpufreq();
+ if (ret)
+ pr_warning("da850_evm_init: cpufreq registration failed: %d\n",
+ ret);
+
+ ret = da8xx_register_cpuidle();
+ if (ret)
+ pr_warning("da850_evm_init: cpuidle registration failed: %d\n",
+ ret);
+
+ ret = da850_register_pm(&da850_pm_device);
+ if (ret)
+ pr_warning("da850_evm_init: suspend registration failed: %d\n",
+ ret);
+
+ ret = da8xx_register_spi(1, da850evm_spi_info,
+ ARRAY_SIZE(da850evm_spi_info));
+ if (ret)
+ pr_warning("da850_evm_init: spi 1 registration failed: %d\n",
+ ret);
+
+ da850_evm_setup_mac_addr();
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init da850_evm_console_init(void)
+{
+ if (!machine_is_davinci_da850_evm())
+ return 0;
+
+ return add_preferred_console("ttyS", 2, "115200");
+}
+console_initcall(da850_evm_console_init);
+#endif
+
+static void __init da850_evm_map_io(void)
+{
+ da850_init();
+}
+
+MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM")
+ .boot_params = (DA8XX_DDR_BASE + 0x100),
+ .map_io = da850_evm_map_io,
+ .init_irq = cp_intc_init,
+ .timer = &davinci_timer,
+ .init_machine = da850_evm_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
new file mode 100644
index 00000000..6e7cad13
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -0,0 +1,359 @@
+/*
+ * TI DaVinci EVM board support
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 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/err.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/videodev2.h>
+#include <media/tvp514x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dm355.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/nand.h>
+#include <mach/mmc.h>
+#include <mach/usb.h>
+
+/* NOTE: this is geared for the standard config, with a socketed
+ * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you
+ * swap chips, maybe with a different block size, partitioning may
+ * need to be changed.
+ */
+#define NAND_BLOCK_SIZE SZ_128K
+
+static struct mtd_partition davinci_nand_partitions[] = {
+ {
+ /* UBL (a few copies) plus U-Boot */
+ .name = "bootloader",
+ .offset = 0,
+ .size = 15 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ /* U-Boot environment */
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1 * NAND_BLOCK_SIZE,
+ .mask_flags = 0,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_512M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+ /* two blocks with bad block table (and mirror) at the end */
+};
+
+static struct davinci_nand_pdata davinci_nand_data = {
+ .mask_chipsel = BIT(14),
+ .parts = davinci_nand_partitions,
+ .nr_parts = ARRAY_SIZE(davinci_nand_partitions),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT,
+ .ecc_bits = 4,
+};
+
+static struct resource davinci_nand_resources[] = {
+ {
+ .start = DM355_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM355_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM355_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM355_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_nand_device = {
+ .name = "davinci_nand",
+ .id = 0,
+
+ .num_resources = ARRAY_SIZE(davinci_nand_resources),
+ .resource = davinci_nand_resources,
+
+ .dev = {
+ .platform_data = &davinci_nand_data,
+ },
+};
+
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 400 /* kHz */,
+ .bus_delay = 0 /* usec */,
+ .sda_pin = 15,
+ .scl_pin = 14,
+};
+
+static struct snd_platform_data dm355_evm_snd_data;
+
+static int dm355evm_mmc_gpios = -EINVAL;
+
+static void dm355evm_mmcsd_gpios(unsigned gpio)
+{
+ gpio_request(gpio + 0, "mmc0_ro");
+ gpio_request(gpio + 1, "mmc0_cd");
+ gpio_request(gpio + 2, "mmc1_ro");
+ gpio_request(gpio + 3, "mmc1_cd");
+
+ /* we "know" these are input-only so we don't
+ * need to call gpio_direction_input()
+ */
+
+ dm355evm_mmc_gpios = gpio;
+}
+
+static struct i2c_board_info dm355evm_i2c_info[] = {
+ { I2C_BOARD_INFO("dm355evm_msp", 0x25),
+ .platform_data = dm355evm_mmcsd_gpios,
+ },
+ /* { plus irq }, */
+ { I2C_BOARD_INFO("tlv320aic33", 0x1b), },
+};
+
+static void __init evm_init_i2c(void)
+{
+ davinci_init_i2c(&i2c_pdata);
+
+ gpio_request(5, "dm355evm_msp");
+ gpio_direction_input(5);
+ dm355evm_i2c_info[0].irq = gpio_to_irq(5);
+
+ i2c_register_board_info(1, dm355evm_i2c_info,
+ ARRAY_SIZE(dm355evm_i2c_info));
+}
+
+static struct resource dm355evm_dm9000_rsrc[] = {
+ {
+ /* addr */
+ .start = 0x04014000,
+ .end = 0x04014001,
+ .flags = IORESOURCE_MEM,
+ }, {
+ /* data */
+ .start = 0x04014002,
+ .end = 0x04014003,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .flags = IORESOURCE_IRQ
+ | IORESOURCE_IRQ_HIGHEDGE /* rising (active high) */,
+ },
+};
+
+static struct platform_device dm355evm_dm9000 = {
+ .name = "dm9000",
+ .id = -1,
+ .resource = dm355evm_dm9000_rsrc,
+ .num_resources = ARRAY_SIZE(dm355evm_dm9000_rsrc),
+};
+
+static struct tvp514x_platform_data tvp5146_pdata = {
+ .clk_polarity = 0,
+ .hs_polarity = 1,
+ .vs_polarity = 1
+};
+
+#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+/* Inputs available at the TVP5146 */
+static struct v4l2_input tvp5146_inputs[] = {
+ {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+ {
+ .index = 1,
+ .name = "S-Video",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+};
+
+/*
+ * this is the route info for connecting each input to decoder
+ * ouput that goes to vpfe. There is a one to one correspondence
+ * with tvp5146_inputs
+ */
+static struct vpfe_route tvp5146_routes[] = {
+ {
+ .input = INPUT_CVBS_VI2B,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+ {
+ .input = INPUT_SVIDEO_VI2C_VI1C,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+};
+
+static struct vpfe_subdev_info vpfe_sub_devs[] = {
+ {
+ .name = "tvp5146",
+ .grp_id = 0,
+ .num_inputs = ARRAY_SIZE(tvp5146_inputs),
+ .inputs = tvp5146_inputs,
+ .routes = tvp5146_routes,
+ .can_route = 1,
+ .ccdc_if_params = {
+ .if_type = VPFE_BT656,
+ .hdpol = VPFE_PINPOL_POSITIVE,
+ .vdpol = VPFE_PINPOL_POSITIVE,
+ },
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5d),
+ .platform_data = &tvp5146_pdata,
+ },
+ }
+};
+
+static struct vpfe_config vpfe_cfg = {
+ .num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
+ .i2c_adapter_id = 1,
+ .sub_devs = vpfe_sub_devs,
+ .card_name = "DM355 EVM",
+ .ccdc = "DM355 CCDC",
+};
+
+static struct platform_device *davinci_evm_devices[] __initdata = {
+ &dm355evm_dm9000,
+ &davinci_nand_device,
+};
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+static void __init dm355_evm_map_io(void)
+{
+ /* setup input configuration for VPFE input devices */
+ dm355_set_vpfe_config(&vpfe_cfg);
+ dm355_init();
+}
+
+static int dm355evm_mmc_get_cd(int module)
+{
+ if (!gpio_is_valid(dm355evm_mmc_gpios))
+ return -ENXIO;
+ /* low == card present */
+ return !gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 1);
+}
+
+static int dm355evm_mmc_get_ro(int module)
+{
+ if (!gpio_is_valid(dm355evm_mmc_gpios))
+ return -ENXIO;
+ /* high == card's write protect switch active */
+ return gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 0);
+}
+
+static struct davinci_mmc_config dm355evm_mmc_config = {
+ .get_cd = dm355evm_mmc_get_cd,
+ .get_ro = dm355evm_mmc_get_ro,
+ .wires = 4,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .version = MMC_CTLR_VERSION_1,
+};
+
+/* Don't connect anything to J10 unless you're only using USB host
+ * mode *and* have to do so with some kind of gender-bender. If
+ * you have proper Mini-B or Mini-A cables (or Mini-A adapters)
+ * the ID pin won't need any help.
+ */
+#ifdef CONFIG_USB_MUSB_PERIPHERAL
+#define USB_ID_VALUE 0 /* ID pulled high; *should* float */
+#else
+#define USB_ID_VALUE 1 /* ID pulled low */
+#endif
+
+static struct spi_eeprom at25640a = {
+ .byte_len = SZ_64K / 8,
+ .name = "at25640a",
+ .page_size = 32,
+ .flags = EE_ADDR2,
+};
+
+static struct spi_board_info dm355_evm_spi_info[] __initconst = {
+ {
+ .modalias = "at25",
+ .platform_data = &at25640a,
+ .max_speed_hz = 10 * 1000 * 1000, /* at 3v3 */
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ },
+};
+
+static __init void dm355_evm_init(void)
+{
+ struct clk *aemif;
+
+ gpio_request(1, "dm9000");
+ gpio_direction_input(1);
+ dm355evm_dm9000_rsrc[2].start = gpio_to_irq(1);
+
+ aemif = clk_get(&dm355evm_dm9000.dev, "aemif");
+ if (IS_ERR(aemif))
+ WARN("%s: unable to get AEMIF clock\n", __func__);
+ else
+ clk_enable(aemif);
+
+ platform_add_devices(davinci_evm_devices,
+ ARRAY_SIZE(davinci_evm_devices));
+ evm_init_i2c();
+ davinci_serial_init(&uart_config);
+
+ /* NOTE: NAND flash timings set by the UBL are slower than
+ * needed by MT29F16G08FAA chips ... EMIF.A1CR is 0x40400204
+ * but could be 0x0400008c for about 25% faster page reads.
+ */
+
+ gpio_request(2, "usb_id_toggle");
+ gpio_direction_output(2, USB_ID_VALUE);
+ /* irlml6401 switches over 1A in under 8 msec */
+ davinci_setup_usb(1000, 8);
+
+ davinci_setup_mmc(0, &dm355evm_mmc_config);
+ davinci_setup_mmc(1, &dm355evm_mmc_config);
+
+ dm355_init_spi0(BIT(0), dm355_evm_spi_info,
+ ARRAY_SIZE(dm355_evm_spi_info));
+
+ /* DM335 EVM uses ASP1; line-out is a stereo mini-jack */
+ dm355_init_asp1(ASP1_TX_EVT_EN | ASP1_RX_EVT_EN, &dm355_evm_snd_data);
+}
+
+MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
+ .boot_params = (0x80000100),
+ .map_io = dm355_evm_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = dm355_evm_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
new file mode 100644
index 00000000..543f9911
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -0,0 +1,278 @@
+/*
+ * DM355 leopard board support
+ *
+ * Based on board-dm355-evm.c
+ *
+ * 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/err.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dm355.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/nand.h>
+#include <mach/mmc.h>
+#include <mach/usb.h>
+
+/* NOTE: this is geared for the standard config, with a socketed
+ * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you
+ * swap chips, maybe with a different block size, partitioning may
+ * need to be changed.
+ */
+#define NAND_BLOCK_SIZE SZ_128K
+
+static struct mtd_partition davinci_nand_partitions[] = {
+ {
+ /* UBL (a few copies) plus U-Boot */
+ .name = "bootloader",
+ .offset = 0,
+ .size = 15 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ /* U-Boot environment */
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1 * NAND_BLOCK_SIZE,
+ .mask_flags = 0,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_512M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+ /* two blocks with bad block table (and mirror) at the end */
+};
+
+static struct davinci_nand_pdata davinci_nand_data = {
+ .mask_chipsel = BIT(14),
+ .parts = davinci_nand_partitions,
+ .nr_parts = ARRAY_SIZE(davinci_nand_partitions),
+ .ecc_mode = NAND_ECC_HW_SYNDROME,
+ .options = NAND_USE_FLASH_BBT,
+};
+
+static struct resource davinci_nand_resources[] = {
+ {
+ .start = DM355_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM355_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM355_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM355_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_nand_device = {
+ .name = "davinci_nand",
+ .id = 0,
+
+ .num_resources = ARRAY_SIZE(davinci_nand_resources),
+ .resource = davinci_nand_resources,
+
+ .dev = {
+ .platform_data = &davinci_nand_data,
+ },
+};
+
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 400 /* kHz */,
+ .bus_delay = 0 /* usec */,
+};
+
+static int leopard_mmc_gpio = -EINVAL;
+
+static void dm355leopard_mmcsd_gpios(unsigned gpio)
+{
+ gpio_request(gpio + 0, "mmc0_ro");
+ gpio_request(gpio + 1, "mmc0_cd");
+ gpio_request(gpio + 2, "mmc1_ro");
+ gpio_request(gpio + 3, "mmc1_cd");
+
+ /* we "know" these are input-only so we don't
+ * need to call gpio_direction_input()
+ */
+
+ leopard_mmc_gpio = gpio;
+}
+
+static struct i2c_board_info dm355leopard_i2c_info[] = {
+ { I2C_BOARD_INFO("dm355leopard_msp", 0x25),
+ .platform_data = dm355leopard_mmcsd_gpios,
+ /* plus irq */ },
+ /* { I2C_BOARD_INFO("tlv320aic3x", 0x1b), }, */
+ /* { I2C_BOARD_INFO("tvp5146", 0x5d), }, */
+};
+
+static void __init leopard_init_i2c(void)
+{
+ davinci_init_i2c(&i2c_pdata);
+
+ gpio_request(5, "dm355leopard_msp");
+ gpio_direction_input(5);
+ dm355leopard_i2c_info[0].irq = gpio_to_irq(5);
+
+ i2c_register_board_info(1, dm355leopard_i2c_info,
+ ARRAY_SIZE(dm355leopard_i2c_info));
+}
+
+static struct resource dm355leopard_dm9000_rsrc[] = {
+ {
+ /* addr */
+ .start = 0x04000000,
+ .end = 0x04000001,
+ .flags = IORESOURCE_MEM,
+ }, {
+ /* data */
+ .start = 0x04000016,
+ .end = 0x04000017,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .flags = IORESOURCE_IRQ
+ | IORESOURCE_IRQ_HIGHEDGE /* rising (active high) */,
+ },
+};
+
+static struct platform_device dm355leopard_dm9000 = {
+ .name = "dm9000",
+ .id = -1,
+ .resource = dm355leopard_dm9000_rsrc,
+ .num_resources = ARRAY_SIZE(dm355leopard_dm9000_rsrc),
+};
+
+static struct platform_device *davinci_leopard_devices[] __initdata = {
+ &dm355leopard_dm9000,
+ &davinci_nand_device,
+};
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+static void __init dm355_leopard_map_io(void)
+{
+ dm355_init();
+}
+
+static int dm355leopard_mmc_get_cd(int module)
+{
+ if (!gpio_is_valid(leopard_mmc_gpio))
+ return -ENXIO;
+ /* low == card present */
+ return !gpio_get_value_cansleep(leopard_mmc_gpio + 2 * module + 1);
+}
+
+static int dm355leopard_mmc_get_ro(int module)
+{
+ if (!gpio_is_valid(leopard_mmc_gpio))
+ return -ENXIO;
+ /* high == card's write protect switch active */
+ return gpio_get_value_cansleep(leopard_mmc_gpio + 2 * module + 0);
+}
+
+static struct davinci_mmc_config dm355leopard_mmc_config = {
+ .get_cd = dm355leopard_mmc_get_cd,
+ .get_ro = dm355leopard_mmc_get_ro,
+ .wires = 4,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+};
+
+/* Don't connect anything to J10 unless you're only using USB host
+ * mode *and* have to do so with some kind of gender-bender. If
+ * you have proper Mini-B or Mini-A cables (or Mini-A adapters)
+ * the ID pin won't need any help.
+ */
+#ifdef CONFIG_USB_MUSB_PERIPHERAL
+#define USB_ID_VALUE 0 /* ID pulled high; *should* float */
+#else
+#define USB_ID_VALUE 1 /* ID pulled low */
+#endif
+
+static struct spi_eeprom at25640a = {
+ .byte_len = SZ_64K / 8,
+ .name = "at25640a",
+ .page_size = 32,
+ .flags = EE_ADDR2,
+};
+
+static struct spi_board_info dm355_leopard_spi_info[] __initconst = {
+ {
+ .modalias = "at25",
+ .platform_data = &at25640a,
+ .max_speed_hz = 10 * 1000 * 1000, /* at 3v3 */
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ },
+};
+
+static __init void dm355_leopard_init(void)
+{
+ struct clk *aemif;
+
+ gpio_request(9, "dm9000");
+ gpio_direction_input(9);
+ dm355leopard_dm9000_rsrc[2].start = gpio_to_irq(9);
+
+ aemif = clk_get(&dm355leopard_dm9000.dev, "aemif");
+ if (IS_ERR(aemif))
+ WARN("%s: unable to get AEMIF clock\n", __func__);
+ else
+ clk_enable(aemif);
+
+ platform_add_devices(davinci_leopard_devices,
+ ARRAY_SIZE(davinci_leopard_devices));
+ leopard_init_i2c();
+ davinci_serial_init(&uart_config);
+
+ /* NOTE: NAND flash timings set by the UBL are slower than
+ * needed by MT29F16G08FAA chips ... EMIF.A1CR is 0x40400204
+ * but could be 0x0400008c for about 25% faster page reads.
+ */
+
+ gpio_request(2, "usb_id_toggle");
+ gpio_direction_output(2, USB_ID_VALUE);
+ /* irlml6401 switches over 1A in under 8 msec */
+ davinci_setup_usb(1000, 8);
+
+ davinci_setup_mmc(0, &dm355leopard_mmc_config);
+ davinci_setup_mmc(1, &dm355leopard_mmc_config);
+
+ dm355_init_spi0(BIT(0), dm355_leopard_spi_info,
+ ARRAY_SIZE(dm355_leopard_spi_info));
+}
+
+MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard")
+ .boot_params = (0x80000100),
+ .map_io = dm355_leopard_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = dm355_leopard_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
new file mode 100644
index 00000000..09a87e61
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -0,0 +1,621 @@
+/*
+ * TI DaVinci DM365 EVM board support
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated
+ *
+ * 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/i2c/at24.h>
+#include <linux/leds.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/slab.h>
+#include <linux/mtd/nand.h>
+#include <linux/input.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/mux.h>
+#include <mach/dm365.h>
+#include <mach/common.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/mmc.h>
+#include <mach/nand.h>
+#include <mach/keyscan.h>
+
+#include <media/tvp514x.h>
+
+static inline int have_imager(void)
+{
+ /* REVISIT when it's supported, trigger via Kconfig */
+ return 0;
+}
+
+static inline int have_tvp7002(void)
+{
+ /* REVISIT when it's supported, trigger via Kconfig */
+ return 0;
+}
+
+#define DM365_EVM_PHY_ID "0:01"
+/*
+ * A MAX-II CPLD is used for various board control functions.
+ */
+#define CPLD_OFFSET(a13a8,a2a1) (((a13a8) << 10) + ((a2a1) << 3))
+
+#define CPLD_VERSION CPLD_OFFSET(0,0) /* r/o */
+#define CPLD_TEST CPLD_OFFSET(0,1)
+#define CPLD_LEDS CPLD_OFFSET(0,2)
+#define CPLD_MUX CPLD_OFFSET(0,3)
+#define CPLD_SWITCH CPLD_OFFSET(1,0) /* r/o */
+#define CPLD_POWER CPLD_OFFSET(1,1)
+#define CPLD_VIDEO CPLD_OFFSET(1,2)
+#define CPLD_CARDSTAT CPLD_OFFSET(1,3) /* r/o */
+
+#define CPLD_DILC_OUT CPLD_OFFSET(2,0)
+#define CPLD_DILC_IN CPLD_OFFSET(2,1) /* r/o */
+
+#define CPLD_IMG_DIR0 CPLD_OFFSET(2,2)
+#define CPLD_IMG_MUX0 CPLD_OFFSET(2,3)
+#define CPLD_IMG_MUX1 CPLD_OFFSET(3,0)
+#define CPLD_IMG_DIR1 CPLD_OFFSET(3,1)
+#define CPLD_IMG_MUX2 CPLD_OFFSET(3,2)
+#define CPLD_IMG_MUX3 CPLD_OFFSET(3,3)
+#define CPLD_IMG_DIR2 CPLD_OFFSET(4,0)
+#define CPLD_IMG_MUX4 CPLD_OFFSET(4,1)
+#define CPLD_IMG_MUX5 CPLD_OFFSET(4,2)
+
+#define CPLD_RESETS CPLD_OFFSET(4,3)
+
+#define CPLD_CCD_DIR1 CPLD_OFFSET(0x3e,0)
+#define CPLD_CCD_IO1 CPLD_OFFSET(0x3e,1)
+#define CPLD_CCD_DIR2 CPLD_OFFSET(0x3e,2)
+#define CPLD_CCD_IO2 CPLD_OFFSET(0x3e,3)
+#define CPLD_CCD_DIR3 CPLD_OFFSET(0x3f,0)
+#define CPLD_CCD_IO3 CPLD_OFFSET(0x3f,1)
+
+static void __iomem *cpld;
+
+
+/* NOTE: this is geared for the standard config, with a socketed
+ * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you
+ * swap chips with a different block size, partitioning will
+ * need to be changed. This NAND chip MT29F16G08FAA is the default
+ * NAND shipped with the Spectrum Digital DM365 EVM
+ */
+#define NAND_BLOCK_SIZE SZ_128K
+
+static struct mtd_partition davinci_nand_partitions[] = {
+ {
+ /* UBL (a few copies) plus U-Boot */
+ .name = "bootloader",
+ .offset = 0,
+ .size = 28 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ /* U-Boot environment */
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2 * NAND_BLOCK_SIZE,
+ .mask_flags = 0,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_512M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+ /* two blocks with bad block table (and mirror) at the end */
+};
+
+static struct davinci_nand_pdata davinci_nand_data = {
+ .mask_chipsel = BIT(14),
+ .parts = davinci_nand_partitions,
+ .nr_parts = ARRAY_SIZE(davinci_nand_partitions),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT,
+ .ecc_bits = 4,
+};
+
+static struct resource davinci_nand_resources[] = {
+ {
+ .start = DM365_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM365_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM365_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM365_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_nand_device = {
+ .name = "davinci_nand",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(davinci_nand_resources),
+ .resource = davinci_nand_resources,
+ .dev = {
+ .platform_data = &davinci_nand_data,
+ },
+};
+
+static struct at24_platform_data eeprom_info = {
+ .byte_len = (256*1024) / 8,
+ .page_size = 64,
+ .flags = AT24_FLAG_ADDR16,
+ .setup = davinci_get_mac_addr,
+ .context = (void *)0x7f00,
+};
+
+static struct snd_platform_data dm365_evm_snd_data = {
+ .asp_chan_q = EVENTQ_3,
+};
+
+static struct i2c_board_info i2c_info[] = {
+ {
+ I2C_BOARD_INFO("24c256", 0x50),
+ .platform_data = &eeprom_info,
+ },
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x18),
+ },
+};
+
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 400 /* kHz */,
+ .bus_delay = 0 /* usec */,
+};
+
+static int dm365evm_keyscan_enable(struct device *dev)
+{
+ return davinci_cfg_reg(DM365_KEYSCAN);
+}
+
+static unsigned short dm365evm_keymap[] = {
+ KEY_KP2,
+ KEY_LEFT,
+ KEY_EXIT,
+ KEY_DOWN,
+ KEY_ENTER,
+ KEY_UP,
+ KEY_KP1,
+ KEY_RIGHT,
+ KEY_MENU,
+ KEY_RECORD,
+ KEY_REWIND,
+ KEY_KPMINUS,
+ KEY_STOP,
+ KEY_FASTFORWARD,
+ KEY_KPPLUS,
+ KEY_PLAYPAUSE,
+ 0
+};
+
+static struct davinci_ks_platform_data dm365evm_ks_data = {
+ .device_enable = dm365evm_keyscan_enable,
+ .keymap = dm365evm_keymap,
+ .keymapsize = ARRAY_SIZE(dm365evm_keymap),
+ .rep = 1,
+ /* Scan period = strobe + interval */
+ .strobe = 0x5,
+ .interval = 0x2,
+ .matrix_type = DAVINCI_KEYSCAN_MATRIX_4X4,
+};
+
+static int cpld_mmc_get_cd(int module)
+{
+ if (!cpld)
+ return -ENXIO;
+
+ /* low == card present */
+ return !(__raw_readb(cpld + CPLD_CARDSTAT) & BIT(module ? 4 : 0));
+}
+
+static int cpld_mmc_get_ro(int module)
+{
+ if (!cpld)
+ return -ENXIO;
+
+ /* high == card's write protect switch active */
+ return !!(__raw_readb(cpld + CPLD_CARDSTAT) & BIT(module ? 5 : 1));
+}
+
+static struct davinci_mmc_config dm365evm_mmc_config = {
+ .get_cd = cpld_mmc_get_cd,
+ .get_ro = cpld_mmc_get_ro,
+ .wires = 4,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .version = MMC_CTLR_VERSION_2,
+};
+
+static void dm365evm_emac_configure(void)
+{
+ /*
+ * EMAC pins are multiplexed with GPIO and UART
+ * Further details are available at the DM365 ARM
+ * Subsystem Users Guide(sprufg5.pdf) pages 125 - 127
+ */
+ davinci_cfg_reg(DM365_EMAC_TX_EN);
+ davinci_cfg_reg(DM365_EMAC_TX_CLK);
+ davinci_cfg_reg(DM365_EMAC_COL);
+ davinci_cfg_reg(DM365_EMAC_TXD3);
+ davinci_cfg_reg(DM365_EMAC_TXD2);
+ davinci_cfg_reg(DM365_EMAC_TXD1);
+ davinci_cfg_reg(DM365_EMAC_TXD0);
+ davinci_cfg_reg(DM365_EMAC_RXD3);
+ davinci_cfg_reg(DM365_EMAC_RXD2);
+ davinci_cfg_reg(DM365_EMAC_RXD1);
+ davinci_cfg_reg(DM365_EMAC_RXD0);
+ davinci_cfg_reg(DM365_EMAC_RX_CLK);
+ davinci_cfg_reg(DM365_EMAC_RX_DV);
+ davinci_cfg_reg(DM365_EMAC_RX_ER);
+ davinci_cfg_reg(DM365_EMAC_CRS);
+ davinci_cfg_reg(DM365_EMAC_MDIO);
+ davinci_cfg_reg(DM365_EMAC_MDCLK);
+
+ /*
+ * EMAC interrupts are multiplexed with GPIO interrupts
+ * Details are available at the DM365 ARM
+ * Subsystem Users Guide(sprufg5.pdf) pages 133 - 134
+ */
+ davinci_cfg_reg(DM365_INT_EMAC_RXTHRESH);
+ davinci_cfg_reg(DM365_INT_EMAC_RXPULSE);
+ davinci_cfg_reg(DM365_INT_EMAC_TXPULSE);
+ davinci_cfg_reg(DM365_INT_EMAC_MISCPULSE);
+}
+
+static void dm365evm_mmc_configure(void)
+{
+ /*
+ * MMC/SD pins are multiplexed with GPIO and EMIF
+ * Further details are available at the DM365 ARM
+ * Subsystem Users Guide(sprufg5.pdf) pages 118, 128 - 131
+ */
+ davinci_cfg_reg(DM365_SD1_CLK);
+ davinci_cfg_reg(DM365_SD1_CMD);
+ davinci_cfg_reg(DM365_SD1_DATA3);
+ davinci_cfg_reg(DM365_SD1_DATA2);
+ davinci_cfg_reg(DM365_SD1_DATA1);
+ davinci_cfg_reg(DM365_SD1_DATA0);
+}
+
+static struct tvp514x_platform_data tvp5146_pdata = {
+ .clk_polarity = 0,
+ .hs_polarity = 1,
+ .vs_polarity = 1
+};
+
+#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+/* Inputs available at the TVP5146 */
+static struct v4l2_input tvp5146_inputs[] = {
+ {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+ {
+ .index = 1,
+ .name = "S-Video",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+};
+
+/*
+ * this is the route info for connecting each input to decoder
+ * ouput that goes to vpfe. There is a one to one correspondence
+ * with tvp5146_inputs
+ */
+static struct vpfe_route tvp5146_routes[] = {
+ {
+ .input = INPUT_CVBS_VI2B,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+{
+ .input = INPUT_SVIDEO_VI2C_VI1C,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+};
+
+static struct vpfe_subdev_info vpfe_sub_devs[] = {
+ {
+ .name = "tvp5146",
+ .grp_id = 0,
+ .num_inputs = ARRAY_SIZE(tvp5146_inputs),
+ .inputs = tvp5146_inputs,
+ .routes = tvp5146_routes,
+ .can_route = 1,
+ .ccdc_if_params = {
+ .if_type = VPFE_BT656,
+ .hdpol = VPFE_PINPOL_POSITIVE,
+ .vdpol = VPFE_PINPOL_POSITIVE,
+ },
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5d),
+ .platform_data = &tvp5146_pdata,
+ },
+ },
+};
+
+static struct vpfe_config vpfe_cfg = {
+ .num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
+ .sub_devs = vpfe_sub_devs,
+ .i2c_adapter_id = 1,
+ .card_name = "DM365 EVM",
+ .ccdc = "ISIF",
+};
+
+static void __init evm_init_i2c(void)
+{
+ davinci_init_i2c(&i2c_pdata);
+ i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+}
+
+static struct platform_device *dm365_evm_nand_devices[] __initdata = {
+ &davinci_nand_device,
+};
+
+static inline int have_leds(void)
+{
+#ifdef CONFIG_LEDS_CLASS
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+struct cpld_led {
+ struct led_classdev cdev;
+ u8 mask;
+};
+
+static const struct {
+ const char *name;
+ const char *trigger;
+} cpld_leds[] = {
+ { "dm365evm::ds2", },
+ { "dm365evm::ds3", },
+ { "dm365evm::ds4", },
+ { "dm365evm::ds5", },
+ { "dm365evm::ds6", "nand-disk", },
+ { "dm365evm::ds7", "mmc1", },
+ { "dm365evm::ds8", "mmc0", },
+ { "dm365evm::ds9", "heartbeat", },
+};
+
+static void cpld_led_set(struct led_classdev *cdev, enum led_brightness b)
+{
+ struct cpld_led *led = container_of(cdev, struct cpld_led, cdev);
+ u8 reg = __raw_readb(cpld + CPLD_LEDS);
+
+ if (b != LED_OFF)
+ reg &= ~led->mask;
+ else
+ reg |= led->mask;
+ __raw_writeb(reg, cpld + CPLD_LEDS);
+}
+
+static enum led_brightness cpld_led_get(struct led_classdev *cdev)
+{
+ struct cpld_led *led = container_of(cdev, struct cpld_led, cdev);
+ u8 reg = __raw_readb(cpld + CPLD_LEDS);
+
+ return (reg & led->mask) ? LED_OFF : LED_FULL;
+}
+
+static int __init cpld_leds_init(void)
+{
+ int i;
+
+ if (!have_leds() || !cpld)
+ return 0;
+
+ /* setup LEDs */
+ __raw_writeb(0xff, cpld + CPLD_LEDS);
+ for (i = 0; i < ARRAY_SIZE(cpld_leds); i++) {
+ struct cpld_led *led;
+
+ led = kzalloc(sizeof(*led), GFP_KERNEL);
+ if (!led)
+ break;
+
+ led->cdev.name = cpld_leds[i].name;
+ led->cdev.brightness_set = cpld_led_set;
+ led->cdev.brightness_get = cpld_led_get;
+ led->cdev.default_trigger = cpld_leds[i].trigger;
+ led->mask = BIT(i);
+
+ if (led_classdev_register(NULL, &led->cdev) < 0) {
+ kfree(led);
+ break;
+ }
+ }
+
+ return 0;
+}
+/* run after subsys_initcall() for LEDs */
+fs_initcall(cpld_leds_init);
+
+
+static void __init evm_init_cpld(void)
+{
+ u8 mux, resets;
+ const char *label;
+ struct clk *aemif_clk;
+
+ /* Make sure we can configure the CPLD through CS1. Then
+ * leave it on for later access to MMC and LED registers.
+ */
+ aemif_clk = clk_get(NULL, "aemif");
+ if (IS_ERR(aemif_clk))
+ return;
+ clk_enable(aemif_clk);
+
+ if (request_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE,
+ "cpld") == NULL)
+ goto fail;
+ cpld = ioremap(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE);
+ if (!cpld) {
+ release_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE,
+ SECTION_SIZE);
+fail:
+ pr_err("ERROR: can't map CPLD\n");
+ clk_disable(aemif_clk);
+ return;
+ }
+
+ /* External muxing for some signals */
+ mux = 0;
+
+ /* Read SW5 to set up NAND + keypad _or_ OneNAND (sync read).
+ * NOTE: SW4 bus width setting must match!
+ */
+ if ((__raw_readb(cpld + CPLD_SWITCH) & BIT(5)) == 0) {
+ /* external keypad mux */
+ mux |= BIT(7);
+
+ platform_add_devices(dm365_evm_nand_devices,
+ ARRAY_SIZE(dm365_evm_nand_devices));
+ } else {
+ /* no OneNAND support yet */
+ }
+
+ /* Leave external chips in reset when unused. */
+ resets = BIT(3) | BIT(2) | BIT(1) | BIT(0);
+
+ /* Static video input config with SN74CBT16214 1-of-3 mux:
+ * - port b1 == tvp7002 (mux lowbits == 1 or 6)
+ * - port b2 == imager (mux lowbits == 2 or 7)
+ * - port b3 == tvp5146 (mux lowbits == 5)
+ *
+ * Runtime switching could work too, with limitations.
+ */
+ if (have_imager()) {
+ label = "HD imager";
+ mux |= 2;
+
+ /* externally mux MMC1/ENET/AIC33 to imager */
+ mux |= BIT(6) | BIT(5) | BIT(3);
+ } else {
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ /* we can use MMC1 ... */
+ dm365evm_mmc_configure();
+ davinci_setup_mmc(1, &dm365evm_mmc_config);
+
+ /* ... and ENET ... */
+ dm365evm_emac_configure();
+ soc_info->emac_pdata->phy_id = DM365_EVM_PHY_ID;
+ resets &= ~BIT(3);
+
+ /* ... and AIC33 */
+ resets &= ~BIT(1);
+
+ if (have_tvp7002()) {
+ mux |= 1;
+ resets &= ~BIT(2);
+ label = "tvp7002 HD";
+ } else {
+ /* default to tvp5146 */
+ mux |= 5;
+ resets &= ~BIT(0);
+ label = "tvp5146 SD";
+ }
+ }
+ __raw_writeb(mux, cpld + CPLD_MUX);
+ __raw_writeb(resets, cpld + CPLD_RESETS);
+ pr_info("EVM: %s video input\n", label);
+
+ /* REVISIT export switches: NTSC/PAL (SW5.6), EXTRA1 (SW5.2), etc */
+}
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+static void __init dm365_evm_map_io(void)
+{
+ /* setup input configuration for VPFE input devices */
+ dm365_set_vpfe_config(&vpfe_cfg);
+ dm365_init();
+}
+
+static struct spi_eeprom at25640 = {
+ .byte_len = SZ_64K / 8,
+ .name = "at25640",
+ .page_size = 32,
+ .flags = EE_ADDR2,
+};
+
+static struct spi_board_info dm365_evm_spi_info[] __initconst = {
+ {
+ .modalias = "at25",
+ .platform_data = &at25640,
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ },
+};
+
+static __init void dm365_evm_init(void)
+{
+ evm_init_i2c();
+ davinci_serial_init(&uart_config);
+
+ dm365evm_emac_configure();
+ dm365evm_mmc_configure();
+
+ davinci_setup_mmc(0, &dm365evm_mmc_config);
+
+ /* maybe setup mmc1/etc ... _after_ mmc0 */
+ evm_init_cpld();
+
+#ifdef CONFIG_SND_DM365_AIC3X_CODEC
+ dm365_init_asp(&dm365_evm_snd_data);
+#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
+ dm365_init_vc(&dm365_evm_snd_data);
+#endif
+ dm365_init_rtc();
+ dm365_init_ks(&dm365evm_ks_data);
+
+ dm365_init_spi0(BIT(0), dm365_evm_spi_info,
+ ARRAY_SIZE(dm365_evm_spi_info));
+}
+
+MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
+ .boot_params = (0x80000100),
+ .map_io = dm365_evm_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = dm365_evm_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
new file mode 100644
index 00000000..556bbd46
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -0,0 +1,720 @@
+/*
+ * 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/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/i2c/at24.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/phy.h>
+#include <linux/clk.h>
+#include <linux/videodev2.h>
+
+#include <media/tvp514x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dm644x.h>
+#include <mach/common.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/mux.h>
+#include <mach/nand.h>
+#include <mach/mmc.h>
+#include <mach/usb.h>
+#include <mach/aemif.h>
+
+#define DM644X_EVM_PHY_ID "0:01"
+#define LXT971_PHY_ID (0x001378e2)
+#define LXT971_PHY_MASK (0xfffffff0)
+
+static struct mtd_partition davinci_evm_norflash_partitions[] = {
+ /* bootloader (UBL, U-Boot, etc) in first 5 sectors */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 5 * 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_norflash_data = {
+ .width = 2,
+ .parts = davinci_evm_norflash_partitions,
+ .nr_parts = ARRAY_SIZE(davinci_evm_norflash_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_norflash_resource = {
+ .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device davinci_evm_norflash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &davinci_evm_norflash_data,
+ },
+ .num_resources = 1,
+ .resource = &davinci_evm_norflash_resource,
+};
+
+/* DM644x EVM includes a 64 MByte small-page NAND flash (16K blocks).
+ * It may used instead of the (default) NOR chip to boot, using TI's
+ * tools to install the secondary boot loader (UBL) and U-Boot.
+ */
+static struct mtd_partition davinci_evm_nandflash_partition[] = {
+ /* Bootloader layout depends on whose u-boot is installed, but we
+ * can hide all the details.
+ * - block 0 for u-boot environment ... in mainline u-boot
+ * - block 1 for UBL (plus up to four backup copies in blocks 2..5)
+ * - blocks 6...? for u-boot
+ * - blocks 16..23 for u-boot environment ... in TI's u-boot
+ */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_256K + SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* Kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ },
+ /* File system (older GIT kernels started this on the 5MB mark) */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+ /* A few blocks at end hold a flash BBT ... created by TI's CCS
+ * using flashwriter_nand.out, but ignored by TI's versions of
+ * Linux and u-boot. We boot faster by using them.
+ */
+};
+
+static struct davinci_aemif_timing davinci_evm_nandflash_timing = {
+ .wsetup = 20,
+ .wstrobe = 40,
+ .whold = 20,
+ .rsetup = 10,
+ .rstrobe = 40,
+ .rhold = 10,
+ .ta = 40,
+};
+
+static struct davinci_nand_pdata davinci_evm_nandflash_data = {
+ .parts = davinci_evm_nandflash_partition,
+ .nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT,
+ .timing = &davinci_evm_nandflash_timing,
+};
+
+static struct resource davinci_evm_nandflash_resource[] = {
+ {
+ .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM644X_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_evm_nandflash_device = {
+ .name = "davinci_nand",
+ .id = 0,
+ .dev = {
+ .platform_data = &davinci_evm_nandflash_data,
+ },
+ .num_resources = ARRAY_SIZE(davinci_evm_nandflash_resource),
+ .resource = davinci_evm_nandflash_resource,
+};
+
+static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device davinci_fb_device = {
+ .name = "davincifb",
+ .id = -1,
+ .dev = {
+ .dma_mask = &davinci_fb_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = 0,
+};
+
+static struct tvp514x_platform_data tvp5146_pdata = {
+ .clk_polarity = 0,
+ .hs_polarity = 1,
+ .vs_polarity = 1
+};
+
+#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+/* Inputs available at the TVP5146 */
+static struct v4l2_input tvp5146_inputs[] = {
+ {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+ {
+ .index = 1,
+ .name = "S-Video",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+};
+
+/*
+ * this is the route info for connecting each input to decoder
+ * ouput that goes to vpfe. There is a one to one correspondence
+ * with tvp5146_inputs
+ */
+static struct vpfe_route tvp5146_routes[] = {
+ {
+ .input = INPUT_CVBS_VI2B,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+ {
+ .input = INPUT_SVIDEO_VI2C_VI1C,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+};
+
+static struct vpfe_subdev_info vpfe_sub_devs[] = {
+ {
+ .name = "tvp5146",
+ .grp_id = 0,
+ .num_inputs = ARRAY_SIZE(tvp5146_inputs),
+ .inputs = tvp5146_inputs,
+ .routes = tvp5146_routes,
+ .can_route = 1,
+ .ccdc_if_params = {
+ .if_type = VPFE_BT656,
+ .hdpol = VPFE_PINPOL_POSITIVE,
+ .vdpol = VPFE_PINPOL_POSITIVE,
+ },
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5d),
+ .platform_data = &tvp5146_pdata,
+ },
+ },
+};
+
+static struct vpfe_config vpfe_cfg = {
+ .num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
+ .i2c_adapter_id = 1,
+ .sub_devs = vpfe_sub_devs,
+ .card_name = "DM6446 EVM",
+ .ccdc = "DM6446 CCDC",
+};
+
+static struct platform_device rtc_dev = {
+ .name = "rtc_davinci_evm",
+ .id = -1,
+};
+
+static struct snd_platform_data dm644x_evm_snd_data;
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * I2C GPIO expanders
+ */
+
+#define PCF_Uxx_BASE(x) (DAVINCI_N_GPIO + ((x) * 8))
+
+
+/* U2 -- LEDs */
+
+static struct gpio_led evm_leds[] = {
+ { .name = "DS8", .active_low = 1,
+ .default_trigger = "heartbeat", },
+ { .name = "DS7", .active_low = 1, },
+ { .name = "DS6", .active_low = 1, },
+ { .name = "DS5", .active_low = 1, },
+ { .name = "DS4", .active_low = 1, },
+ { .name = "DS3", .active_low = 1, },
+ { .name = "DS2", .active_low = 1,
+ .default_trigger = "mmc0", },
+ { .name = "DS1", .active_low = 1,
+ .default_trigger = "ide-disk", },
+};
+
+static const struct gpio_led_platform_data evm_led_data = {
+ .num_leds = ARRAY_SIZE(evm_leds),
+ .leds = evm_leds,
+};
+
+static struct platform_device *evm_led_dev;
+
+static int
+evm_led_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+ struct gpio_led *leds = evm_leds;
+ int status;
+
+ while (ngpio--) {
+ leds->gpio = gpio++;
+ leds++;
+ }
+
+ /* what an extremely annoying way to be forced to handle
+ * device unregistration ...
+ */
+ evm_led_dev = platform_device_alloc("leds-gpio", 0);
+ platform_device_add_data(evm_led_dev,
+ &evm_led_data, sizeof evm_led_data);
+
+ evm_led_dev->dev.parent = &client->dev;
+ status = platform_device_add(evm_led_dev);
+ if (status < 0) {
+ platform_device_put(evm_led_dev);
+ evm_led_dev = NULL;
+ }
+ return status;
+}
+
+static int
+evm_led_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+ if (evm_led_dev) {
+ platform_device_unregister(evm_led_dev);
+ evm_led_dev = NULL;
+ }
+ return 0;
+}
+
+static struct pcf857x_platform_data pcf_data_u2 = {
+ .gpio_base = PCF_Uxx_BASE(0),
+ .setup = evm_led_setup,
+ .teardown = evm_led_teardown,
+};
+
+
+/* U18 - A/V clock generator and user switch */
+
+static int sw_gpio;
+
+static ssize_t
+sw_show(struct device *d, struct device_attribute *a, char *buf)
+{
+ char *s = gpio_get_value_cansleep(sw_gpio) ? "on\n" : "off\n";
+
+ strcpy(buf, s);
+ return strlen(s);
+}
+
+static DEVICE_ATTR(user_sw, S_IRUGO, sw_show, NULL);
+
+static int
+evm_u18_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+ int status;
+
+ /* export dip switch option */
+ sw_gpio = gpio + 7;
+ status = gpio_request(sw_gpio, "user_sw");
+ if (status == 0)
+ status = gpio_direction_input(sw_gpio);
+ if (status == 0)
+ status = device_create_file(&client->dev, &dev_attr_user_sw);
+ else
+ gpio_free(sw_gpio);
+ if (status != 0)
+ sw_gpio = -EINVAL;
+
+ /* audio PLL: 48 kHz (vs 44.1 or 32), single rate (vs double) */
+ gpio_request(gpio + 3, "pll_fs2");
+ gpio_direction_output(gpio + 3, 0);
+
+ gpio_request(gpio + 2, "pll_fs1");
+ gpio_direction_output(gpio + 2, 0);
+
+ gpio_request(gpio + 1, "pll_sr");
+ gpio_direction_output(gpio + 1, 0);
+
+ return 0;
+}
+
+static int
+evm_u18_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+ gpio_free(gpio + 1);
+ gpio_free(gpio + 2);
+ gpio_free(gpio + 3);
+
+ if (sw_gpio > 0) {
+ device_remove_file(&client->dev, &dev_attr_user_sw);
+ gpio_free(sw_gpio);
+ }
+ return 0;
+}
+
+static struct pcf857x_platform_data pcf_data_u18 = {
+ .gpio_base = PCF_Uxx_BASE(1),
+ .n_latch = (1 << 3) | (1 << 2) | (1 << 1),
+ .setup = evm_u18_setup,
+ .teardown = evm_u18_teardown,
+};
+
+
+/* U35 - various I/O signals used to manage USB, CF, ATA, etc */
+
+static int
+evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+ /* p0 = nDRV_VBUS (initial: don't supply it) */
+ gpio_request(gpio + 0, "nDRV_VBUS");
+ gpio_direction_output(gpio + 0, 1);
+
+ /* p1 = VDDIMX_EN */
+ gpio_request(gpio + 1, "VDDIMX_EN");
+ gpio_direction_output(gpio + 1, 1);
+
+ /* p2 = VLYNQ_EN */
+ gpio_request(gpio + 2, "VLYNQ_EN");
+ gpio_direction_output(gpio + 2, 1);
+
+ /* p3 = n3V3_CF_RESET (initial: stay in reset) */
+ gpio_request(gpio + 3, "nCF_RESET");
+ gpio_direction_output(gpio + 3, 0);
+
+ /* (p4 unused) */
+
+ /* p5 = 1V8_WLAN_RESET (initial: stay in reset) */
+ gpio_request(gpio + 5, "WLAN_RESET");
+ gpio_direction_output(gpio + 5, 1);
+
+ /* p6 = nATA_SEL (initial: select) */
+ gpio_request(gpio + 6, "nATA_SEL");
+ gpio_direction_output(gpio + 6, 0);
+
+ /* p7 = nCF_SEL (initial: deselect) */
+ gpio_request(gpio + 7, "nCF_SEL");
+ gpio_direction_output(gpio + 7, 1);
+
+ return 0;
+}
+
+static int
+evm_u35_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+ gpio_free(gpio + 7);
+ gpio_free(gpio + 6);
+ gpio_free(gpio + 5);
+ gpio_free(gpio + 3);
+ gpio_free(gpio + 2);
+ gpio_free(gpio + 1);
+ gpio_free(gpio + 0);
+ return 0;
+}
+
+static struct pcf857x_platform_data pcf_data_u35 = {
+ .gpio_base = PCF_Uxx_BASE(2),
+ .setup = evm_u35_setup,
+ .teardown = evm_u35_teardown,
+};
+
+/*----------------------------------------------------------------------*/
+
+/* Most of this EEPROM is unused, but U-Boot uses some data:
+ * - 0x7f00, 6 bytes Ethernet Address
+ * - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL)
+ * - ... newer boards may have more
+ */
+
+static struct at24_platform_data eeprom_info = {
+ .byte_len = (256*1024) / 8,
+ .page_size = 64,
+ .flags = AT24_FLAG_ADDR16,
+ .setup = davinci_get_mac_addr,
+ .context = (void *)0x7f00,
+};
+
+/*
+ * MSP430 supports RTC, card detection, input from IR remote, and
+ * a bit more. It triggers interrupts on GPIO(7) from pressing
+ * buttons on the IR remote, and for card detect switches.
+ */
+static struct i2c_client *dm6446evm_msp;
+
+static int dm6446evm_msp_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ dm6446evm_msp = client;
+ return 0;
+}
+
+static int dm6446evm_msp_remove(struct i2c_client *client)
+{
+ dm6446evm_msp = NULL;
+ return 0;
+}
+
+static const struct i2c_device_id dm6446evm_msp_ids[] = {
+ { "dm6446evm_msp", 0, },
+ { /* end of list */ },
+};
+
+static struct i2c_driver dm6446evm_msp_driver = {
+ .driver.name = "dm6446evm_msp",
+ .id_table = dm6446evm_msp_ids,
+ .probe = dm6446evm_msp_probe,
+ .remove = dm6446evm_msp_remove,
+};
+
+static int dm6444evm_msp430_get_pins(void)
+{
+ static const char txbuf[2] = { 2, 4, };
+ char buf[4];
+ struct i2c_msg msg[2] = {
+ {
+ .addr = dm6446evm_msp->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = (void __force *)txbuf,
+ },
+ {
+ .addr = dm6446evm_msp->addr,
+ .flags = I2C_M_RD,
+ .len = 4,
+ .buf = buf,
+ },
+ };
+ int status;
+
+ if (!dm6446evm_msp)
+ return -ENXIO;
+
+ /* Command 4 == get input state, returns port 2 and port3 data
+ * S Addr W [A] len=2 [A] cmd=4 [A]
+ * RS Addr R [A] [len=4] A [cmd=4] A [port2] A [port3] N P
+ */
+ status = i2c_transfer(dm6446evm_msp->adapter, msg, 2);
+ if (status < 0)
+ return status;
+
+ dev_dbg(&dm6446evm_msp->dev,
+ "PINS: %02x %02x %02x %02x\n",
+ buf[0], buf[1], buf[2], buf[3]);
+
+ return (buf[3] << 8) | buf[2];
+}
+
+static int dm6444evm_mmc_get_cd(int module)
+{
+ int status = dm6444evm_msp430_get_pins();
+
+ return (status < 0) ? status : !(status & BIT(1));
+}
+
+static int dm6444evm_mmc_get_ro(int module)
+{
+ int status = dm6444evm_msp430_get_pins();
+
+ return (status < 0) ? status : status & BIT(6 + 8);
+}
+
+static struct davinci_mmc_config dm6446evm_mmc_config = {
+ .get_cd = dm6444evm_mmc_get_cd,
+ .get_ro = dm6444evm_mmc_get_ro,
+ .wires = 4,
+ .version = MMC_CTLR_VERSION_1
+};
+
+static struct i2c_board_info __initdata i2c_info[] = {
+ {
+ I2C_BOARD_INFO("dm6446evm_msp", 0x23),
+ },
+ {
+ I2C_BOARD_INFO("pcf8574", 0x38),
+ .platform_data = &pcf_data_u2,
+ },
+ {
+ I2C_BOARD_INFO("pcf8574", 0x39),
+ .platform_data = &pcf_data_u18,
+ },
+ {
+ I2C_BOARD_INFO("pcf8574", 0x3a),
+ .platform_data = &pcf_data_u35,
+ },
+ {
+ I2C_BOARD_INFO("24c256", 0x50),
+ .platform_data = &eeprom_info,
+ },
+ {
+ I2C_BOARD_INFO("tlv320aic33", 0x1b),
+ },
+};
+
+/* The msp430 uses a slow bitbanged I2C implementation (ergo 20 KHz),
+ * which requires 100 usec of idle bus after i2c writes sent to it.
+ */
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 20 /* kHz */,
+ .bus_delay = 100 /* usec */,
+ .sda_pin = 44,
+ .scl_pin = 43,
+};
+
+static void __init evm_init_i2c(void)
+{
+ davinci_init_i2c(&i2c_pdata);
+ i2c_add_driver(&dm6446evm_msp_driver);
+ i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+}
+
+static struct platform_device *davinci_evm_devices[] __initdata = {
+ &davinci_fb_device,
+ &rtc_dev,
+};
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+static void __init
+davinci_evm_map_io(void)
+{
+ /* setup input configuration for VPFE input devices */
+ dm644x_set_vpfe_config(&vpfe_cfg);
+ dm644x_init();
+}
+
+static int davinci_phy_fixup(struct phy_device *phydev)
+{
+ unsigned int control;
+ /* CRITICAL: Fix for increasing PHY signal drive strength for
+ * TX lockup issue. On DaVinci EVM, the Intel LXT971 PHY
+ * signal strength was low causing TX to fail randomly. The
+ * fix is to Set bit 11 (Increased MII drive strength) of PHY
+ * register 26 (Digital Config register) on this phy. */
+ control = phy_read(phydev, 26);
+ phy_write(phydev, 26, (control | 0x800));
+ return 0;
+}
+
+#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+ defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+#define HAS_ATA 1
+#else
+#define HAS_ATA 0
+#endif
+
+#if defined(CONFIG_MTD_PHYSMAP) || \
+ defined(CONFIG_MTD_PHYSMAP_MODULE)
+#define HAS_NOR 1
+#else
+#define HAS_NOR 0
+#endif
+
+#if defined(CONFIG_MTD_NAND_DAVINCI) || \
+ defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
+#define HAS_NAND 1
+#else
+#define HAS_NAND 0
+#endif
+
+static __init void davinci_evm_init(void)
+{
+ struct clk *aemif_clk;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ aemif_clk = clk_get(NULL, "aemif");
+ clk_enable(aemif_clk);
+
+ if (HAS_ATA) {
+ if (HAS_NAND || HAS_NOR)
+ pr_warning("WARNING: both IDE and Flash are "
+ "enabled, but they share AEMIF pins.\n"
+ "\tDisable IDE for NAND/NOR support.\n");
+ davinci_init_ide();
+ } else if (HAS_NAND || HAS_NOR) {
+ davinci_cfg_reg(DM644X_HPIEN_DISABLE);
+ davinci_cfg_reg(DM644X_ATAEN_DISABLE);
+
+ /* only one device will be jumpered and detected */
+ if (HAS_NAND) {
+ platform_device_register(&davinci_evm_nandflash_device);
+ evm_leds[7].default_trigger = "nand-disk";
+ if (HAS_NOR)
+ pr_warning("WARNING: both NAND and NOR flash "
+ "are enabled; disable one of them.\n");
+ } else if (HAS_NOR)
+ platform_device_register(&davinci_evm_norflash_device);
+ }
+
+ platform_add_devices(davinci_evm_devices,
+ ARRAY_SIZE(davinci_evm_devices));
+ evm_init_i2c();
+
+ davinci_setup_mmc(0, &dm6446evm_mmc_config);
+
+ davinci_serial_init(&uart_config);
+ dm644x_init_asp(&dm644x_evm_snd_data);
+
+ /* irlml6401 switches over 1A, in under 8 msec */
+ davinci_setup_usb(1000, 8);
+
+ soc_info->emac_pdata->phy_id = DM644X_EVM_PHY_ID;
+ /* Register the fixup for PHY on DaVinci */
+ phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK,
+ davinci_phy_fixup);
+
+}
+
+MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
+ /* Maintainer: MontaVista Software <source@mvista.com> */
+ .boot_params = (DAVINCI_DDR_BASE + 0x100),
+ .map_io = davinci_evm_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = davinci_evm_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
new file mode 100644
index 00000000..3cdd2378
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -0,0 +1,814 @@
+/*
+ * TI DaVinci DM646X EVM board
+ *
+ * Derived from: arch/arm/mach-davinci/board-evm.c
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * (C) 2007-2008, 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.
+ *
+ */
+
+/**************************************************************************
+ * Included Files
+ **************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/i2c/pcf857x.h>
+
+#include <media/tvp514x.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dm646x.h>
+#include <mach/common.h>
+#include <mach/serial.h>
+#include <mach/i2c.h>
+#include <mach/nand.h>
+#include <mach/clock.h>
+#include <mach/cdce949.h>
+#include <mach/aemif.h>
+
+#include "clock.h"
+
+#define NAND_BLOCK_SIZE SZ_128K
+
+/* Note: We are setting first partition as 'bootloader' constituting UBL, U-Boot
+ * and U-Boot environment this avoids dependency on any particular combination
+ * of UBL, U-Boot or flashing tools etc.
+ */
+static struct mtd_partition davinci_nand_partitions[] = {
+ {
+ /* UBL, U-Boot with environment */
+ .name = "bootloader",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 16 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+};
+
+static struct davinci_aemif_timing dm6467tevm_nandflash_timing = {
+ .wsetup = 29,
+ .wstrobe = 24,
+ .whold = 14,
+ .rsetup = 19,
+ .rstrobe = 33,
+ .rhold = 0,
+ .ta = 29,
+};
+
+static struct davinci_nand_pdata davinci_nand_data = {
+ .mask_cle = 0x80000,
+ .mask_ale = 0x40000,
+ .parts = davinci_nand_partitions,
+ .nr_parts = ARRAY_SIZE(davinci_nand_partitions),
+ .ecc_mode = NAND_ECC_HW,
+ .options = 0,
+};
+
+static struct resource davinci_nand_resources[] = {
+ {
+ .start = DM646X_ASYNC_EMIF_CS2_SPACE_BASE,
+ .end = DM646X_ASYNC_EMIF_CS2_SPACE_BASE + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM646X_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM646X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_nand_device = {
+ .name = "davinci_nand",
+ .id = 0,
+
+ .num_resources = ARRAY_SIZE(davinci_nand_resources),
+ .resource = davinci_nand_resources,
+
+ .dev = {
+ .platform_data = &davinci_nand_data,
+ },
+};
+
+#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+ defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+#define HAS_ATA 1
+#else
+#define HAS_ATA 0
+#endif
+
+/* CPLD Register 0 bits to control ATA */
+#define DM646X_EVM_ATA_RST BIT(0)
+#define DM646X_EVM_ATA_PWD BIT(1)
+
+/* CPLD Register 0 Client: used for I/O Control */
+static int cpld_reg0_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ if (HAS_ATA) {
+ u8 data;
+ struct i2c_msg msg[2] = {
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = &data,
+ },
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = &data,
+ },
+ };
+
+ /* Clear ATA_RSTn and ATA_PWD bits to enable ATA operation. */
+ i2c_transfer(client->adapter, msg, 1);
+ data &= ~(DM646X_EVM_ATA_RST | DM646X_EVM_ATA_PWD);
+ i2c_transfer(client->adapter, msg + 1, 1);
+ }
+
+ return 0;
+}
+
+static const struct i2c_device_id cpld_reg_ids[] = {
+ { "cpld_reg0", 0, },
+ { },
+};
+
+static struct i2c_driver dm6467evm_cpld_driver = {
+ .driver.name = "cpld_reg0",
+ .id_table = cpld_reg_ids,
+ .probe = cpld_reg0_probe,
+};
+
+/* LEDS */
+
+static struct gpio_led evm_leds[] = {
+ { .name = "DS1", .active_low = 1, },
+ { .name = "DS2", .active_low = 1, },
+ { .name = "DS3", .active_low = 1, },
+ { .name = "DS4", .active_low = 1, },
+};
+
+static const struct gpio_led_platform_data evm_led_data = {
+ .num_leds = ARRAY_SIZE(evm_leds),
+ .leds = evm_leds,
+};
+
+static struct platform_device *evm_led_dev;
+
+static int evm_led_setup(struct i2c_client *client, int gpio,
+ unsigned int ngpio, void *c)
+{
+ struct gpio_led *leds = evm_leds;
+ int status;
+
+ while (ngpio--) {
+ leds->gpio = gpio++;
+ leds++;
+ };
+
+ evm_led_dev = platform_device_alloc("leds-gpio", 0);
+ platform_device_add_data(evm_led_dev, &evm_led_data,
+ sizeof(evm_led_data));
+
+ evm_led_dev->dev.parent = &client->dev;
+ status = platform_device_add(evm_led_dev);
+ if (status < 0) {
+ platform_device_put(evm_led_dev);
+ evm_led_dev = NULL;
+ }
+ return status;
+}
+
+static int evm_led_teardown(struct i2c_client *client, int gpio,
+ unsigned ngpio, void *c)
+{
+ if (evm_led_dev) {
+ platform_device_unregister(evm_led_dev);
+ evm_led_dev = NULL;
+ }
+ return 0;
+}
+
+static int evm_sw_gpio[4] = { -EINVAL, -EINVAL, -EINVAL, -EINVAL };
+
+static int evm_sw_setup(struct i2c_client *client, int gpio,
+ unsigned ngpio, void *c)
+{
+ int status;
+ int i;
+ char label[10];
+
+ for (i = 0; i < 4; ++i) {
+ snprintf(label, 10, "user_sw%d", i);
+ status = gpio_request(gpio, label);
+ if (status)
+ goto out_free;
+ evm_sw_gpio[i] = gpio++;
+
+ status = gpio_direction_input(evm_sw_gpio[i]);
+ if (status) {
+ gpio_free(evm_sw_gpio[i]);
+ evm_sw_gpio[i] = -EINVAL;
+ goto out_free;
+ }
+
+ status = gpio_export(evm_sw_gpio[i], 0);
+ if (status) {
+ gpio_free(evm_sw_gpio[i]);
+ evm_sw_gpio[i] = -EINVAL;
+ goto out_free;
+ }
+ }
+ return status;
+out_free:
+ for (i = 0; i < 4; ++i) {
+ if (evm_sw_gpio[i] != -EINVAL) {
+ gpio_free(evm_sw_gpio[i]);
+ evm_sw_gpio[i] = -EINVAL;
+ }
+ }
+ return status;
+}
+
+static int evm_sw_teardown(struct i2c_client *client, int gpio,
+ unsigned ngpio, void *c)
+{
+ int i;
+
+ for (i = 0; i < 4; ++i) {
+ if (evm_sw_gpio[i] != -EINVAL) {
+ gpio_unexport(evm_sw_gpio[i]);
+ gpio_free(evm_sw_gpio[i]);
+ evm_sw_gpio[i] = -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int evm_pcf_setup(struct i2c_client *client, int gpio,
+ unsigned int ngpio, void *c)
+{
+ int status;
+
+ if (ngpio < 8)
+ return -EINVAL;
+
+ status = evm_sw_setup(client, gpio, 4, c);
+ if (status)
+ return status;
+
+ return evm_led_setup(client, gpio+4, 4, c);
+}
+
+static int evm_pcf_teardown(struct i2c_client *client, int gpio,
+ unsigned int ngpio, void *c)
+{
+ BUG_ON(ngpio < 8);
+
+ evm_sw_teardown(client, gpio, 4, c);
+ evm_led_teardown(client, gpio+4, 4, c);
+
+ return 0;
+}
+
+static struct pcf857x_platform_data pcf_data = {
+ .gpio_base = DAVINCI_N_GPIO+1,
+ .setup = evm_pcf_setup,
+ .teardown = evm_pcf_teardown,
+};
+
+/* Most of this EEPROM is unused, but U-Boot uses some data:
+ * - 0x7f00, 6 bytes Ethernet Address
+ * - ... newer boards may have more
+ */
+
+static struct at24_platform_data eeprom_info = {
+ .byte_len = (256*1024) / 8,
+ .page_size = 64,
+ .flags = AT24_FLAG_ADDR16,
+ .setup = davinci_get_mac_addr,
+ .context = (void *)0x7f00,
+};
+
+static u8 dm646x_iis_serializer_direction[] = {
+ TX_MODE, RX_MODE, INACTIVE_MODE, INACTIVE_MODE,
+};
+
+static u8 dm646x_dit_serializer_direction[] = {
+ TX_MODE,
+};
+
+static struct snd_platform_data dm646x_evm_snd_data[] = {
+ {
+ .tx_dma_offset = 0x400,
+ .rx_dma_offset = 0x400,
+ .op_mode = DAVINCI_MCASP_IIS_MODE,
+ .num_serializer = ARRAY_SIZE(dm646x_iis_serializer_direction),
+ .tdm_slots = 2,
+ .serial_dir = dm646x_iis_serializer_direction,
+ .asp_chan_q = EVENTQ_0,
+ },
+ {
+ .tx_dma_offset = 0x400,
+ .rx_dma_offset = 0,
+ .op_mode = DAVINCI_MCASP_DIT_MODE,
+ .num_serializer = ARRAY_SIZE(dm646x_dit_serializer_direction),
+ .tdm_slots = 32,
+ .serial_dir = dm646x_dit_serializer_direction,
+ .asp_chan_q = EVENTQ_0,
+ },
+};
+
+static struct i2c_client *cpld_client;
+
+static int cpld_video_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ cpld_client = client;
+ return 0;
+}
+
+static int __devexit cpld_video_remove(struct i2c_client *client)
+{
+ cpld_client = NULL;
+ return 0;
+}
+
+static const struct i2c_device_id cpld_video_id[] = {
+ { "cpld_video", 0 },
+ { }
+};
+
+static struct i2c_driver cpld_video_driver = {
+ .driver = {
+ .name = "cpld_video",
+ },
+ .probe = cpld_video_probe,
+ .remove = cpld_video_remove,
+ .id_table = cpld_video_id,
+};
+
+static void evm_init_cpld(void)
+{
+ i2c_add_driver(&cpld_video_driver);
+}
+
+static struct i2c_board_info __initdata i2c_info[] = {
+ {
+ I2C_BOARD_INFO("24c256", 0x50),
+ .platform_data = &eeprom_info,
+ },
+ {
+ I2C_BOARD_INFO("pcf8574a", 0x38),
+ .platform_data = &pcf_data,
+ },
+ {
+ I2C_BOARD_INFO("cpld_reg0", 0x3a),
+ },
+ {
+ I2C_BOARD_INFO("tlv320aic33", 0x18),
+ },
+ {
+ I2C_BOARD_INFO("cpld_video", 0x3b),
+ },
+ {
+ I2C_BOARD_INFO("cdce949", 0x6c),
+ },
+};
+
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 100 /* kHz */,
+ .bus_delay = 0 /* usec */,
+};
+
+#define VIDCLKCTL_OFFSET (DAVINCI_SYSTEM_MODULE_BASE + 0x38)
+#define VSCLKDIS_OFFSET (DAVINCI_SYSTEM_MODULE_BASE + 0x6c)
+#define VCH2CLK_MASK (BIT_MASK(10) | BIT_MASK(9) | BIT_MASK(8))
+#define VCH2CLK_SYSCLK8 (BIT(9))
+#define VCH2CLK_AUXCLK (BIT(9) | BIT(8))
+#define VCH3CLK_MASK (BIT_MASK(14) | BIT_MASK(13) | BIT_MASK(12))
+#define VCH3CLK_SYSCLK8 (BIT(13))
+#define VCH3CLK_AUXCLK (BIT(14) | BIT(13))
+
+#define VIDCH2CLK (BIT(10))
+#define VIDCH3CLK (BIT(11))
+#define VIDCH1CLK (BIT(4))
+#define TVP7002_INPUT (BIT(4))
+#define TVP5147_INPUT (~BIT(4))
+#define VPIF_INPUT_ONE_CHANNEL (BIT(5))
+#define VPIF_INPUT_TWO_CHANNEL (~BIT(5))
+#define TVP5147_CH0 "tvp514x-0"
+#define TVP5147_CH1 "tvp514x-1"
+
+static void __iomem *vpif_vidclkctl_reg;
+static void __iomem *vpif_vsclkdis_reg;
+/* spin lock for updating above registers */
+static spinlock_t vpif_reg_lock;
+
+static int set_vpif_clock(int mux_mode, int hd)
+{
+ unsigned long flags;
+ unsigned int value;
+ int val = 0;
+ int err = 0;
+
+ if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg || !cpld_client)
+ return -ENXIO;
+
+ /* disable the clock */
+ spin_lock_irqsave(&vpif_reg_lock, flags);
+ value = __raw_readl(vpif_vsclkdis_reg);
+ value |= (VIDCH3CLK | VIDCH2CLK);
+ __raw_writel(value, vpif_vsclkdis_reg);
+ spin_unlock_irqrestore(&vpif_reg_lock, flags);
+
+ val = i2c_smbus_read_byte(cpld_client);
+ if (val < 0)
+ return val;
+
+ if (mux_mode == 1)
+ val &= ~0x40;
+ else
+ val |= 0x40;
+
+ err = i2c_smbus_write_byte(cpld_client, val);
+ if (err)
+ return err;
+
+ value = __raw_readl(vpif_vidclkctl_reg);
+ value &= ~(VCH2CLK_MASK);
+ value &= ~(VCH3CLK_MASK);
+
+ if (hd >= 1)
+ value |= (VCH2CLK_SYSCLK8 | VCH3CLK_SYSCLK8);
+ else
+ value |= (VCH2CLK_AUXCLK | VCH3CLK_AUXCLK);
+
+ __raw_writel(value, vpif_vidclkctl_reg);
+
+ spin_lock_irqsave(&vpif_reg_lock, flags);
+ value = __raw_readl(vpif_vsclkdis_reg);
+ /* enable the clock */
+ value &= ~(VIDCH3CLK | VIDCH2CLK);
+ __raw_writel(value, vpif_vsclkdis_reg);
+ spin_unlock_irqrestore(&vpif_reg_lock, flags);
+
+ return 0;
+}
+
+static struct vpif_subdev_info dm646x_vpif_subdev[] = {
+ {
+ .name = "adv7343",
+ .board_info = {
+ I2C_BOARD_INFO("adv7343", 0x2a),
+ },
+ },
+ {
+ .name = "ths7303",
+ .board_info = {
+ I2C_BOARD_INFO("ths7303", 0x2c),
+ },
+ },
+};
+
+static const char *output[] = {
+ "Composite",
+ "Component",
+ "S-Video",
+};
+
+static struct vpif_display_config dm646x_vpif_display_config = {
+ .set_clock = set_vpif_clock,
+ .subdevinfo = dm646x_vpif_subdev,
+ .subdev_count = ARRAY_SIZE(dm646x_vpif_subdev),
+ .output = output,
+ .output_count = ARRAY_SIZE(output),
+ .card_name = "DM646x EVM",
+};
+
+/**
+ * setup_vpif_input_path()
+ * @channel: channel id (0 - CH0, 1 - CH1)
+ * @sub_dev_name: ptr sub device name
+ *
+ * This will set vpif input to capture data from tvp514x or
+ * tvp7002.
+ */
+static int setup_vpif_input_path(int channel, const char *sub_dev_name)
+{
+ int err = 0;
+ int val;
+
+ /* for channel 1, we don't do anything */
+ if (channel != 0)
+ return 0;
+
+ if (!cpld_client)
+ return -ENXIO;
+
+ val = i2c_smbus_read_byte(cpld_client);
+ if (val < 0)
+ return val;
+
+ if (!strcmp(sub_dev_name, TVP5147_CH0) ||
+ !strcmp(sub_dev_name, TVP5147_CH1))
+ val &= TVP5147_INPUT;
+ else
+ val |= TVP7002_INPUT;
+
+ err = i2c_smbus_write_byte(cpld_client, val);
+ if (err)
+ return err;
+ return 0;
+}
+
+/**
+ * setup_vpif_input_channel_mode()
+ * @mux_mode: mux mode. 0 - 1 channel or (1) - 2 channel
+ *
+ * This will setup input mode to one channel (TVP7002) or 2 channel (TVP5147)
+ */
+static int setup_vpif_input_channel_mode(int mux_mode)
+{
+ unsigned long flags;
+ int err = 0;
+ int val;
+ u32 value;
+
+ if (!vpif_vidclkctl_reg || !cpld_client)
+ return -ENXIO;
+
+ val = i2c_smbus_read_byte(cpld_client);
+ if (val < 0)
+ return val;
+
+ spin_lock_irqsave(&vpif_reg_lock, flags);
+ value = __raw_readl(vpif_vidclkctl_reg);
+ if (mux_mode) {
+ val &= VPIF_INPUT_TWO_CHANNEL;
+ value |= VIDCH1CLK;
+ } else {
+ val |= VPIF_INPUT_ONE_CHANNEL;
+ value &= ~VIDCH1CLK;
+ }
+ __raw_writel(value, vpif_vidclkctl_reg);
+ spin_unlock_irqrestore(&vpif_reg_lock, flags);
+
+ err = i2c_smbus_write_byte(cpld_client, val);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static struct tvp514x_platform_data tvp5146_pdata = {
+ .clk_polarity = 0,
+ .hs_polarity = 1,
+ .vs_polarity = 1
+};
+
+#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+
+static struct vpif_subdev_info vpif_capture_sdev_info[] = {
+ {
+ .name = TVP5147_CH0,
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5d),
+ .platform_data = &tvp5146_pdata,
+ },
+ .input = INPUT_CVBS_VI2B,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ .can_route = 1,
+ .vpif_if = {
+ .if_type = VPIF_IF_BT656,
+ .hd_pol = 1,
+ .vd_pol = 1,
+ .fid_pol = 0,
+ },
+ },
+ {
+ .name = TVP5147_CH1,
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5c),
+ .platform_data = &tvp5146_pdata,
+ },
+ .input = INPUT_SVIDEO_VI2C_VI1C,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ .can_route = 1,
+ .vpif_if = {
+ .if_type = VPIF_IF_BT656,
+ .hd_pol = 1,
+ .vd_pol = 1,
+ .fid_pol = 0,
+ },
+ },
+};
+
+static const struct vpif_input dm6467_ch0_inputs[] = {
+ {
+ .input = {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+ .subdev_name = TVP5147_CH0,
+ },
+};
+
+static const struct vpif_input dm6467_ch1_inputs[] = {
+ {
+ .input = {
+ .index = 0,
+ .name = "S-Video",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+ .subdev_name = TVP5147_CH1,
+ },
+};
+
+static struct vpif_capture_config dm646x_vpif_capture_cfg = {
+ .setup_input_path = setup_vpif_input_path,
+ .setup_input_channel_mode = setup_vpif_input_channel_mode,
+ .subdev_info = vpif_capture_sdev_info,
+ .subdev_count = ARRAY_SIZE(vpif_capture_sdev_info),
+ .chan_config[0] = {
+ .inputs = dm6467_ch0_inputs,
+ .input_count = ARRAY_SIZE(dm6467_ch0_inputs),
+ },
+ .chan_config[1] = {
+ .inputs = dm6467_ch1_inputs,
+ .input_count = ARRAY_SIZE(dm6467_ch1_inputs),
+ },
+};
+
+static void __init evm_init_video(void)
+{
+ vpif_vidclkctl_reg = ioremap(VIDCLKCTL_OFFSET, 4);
+ vpif_vsclkdis_reg = ioremap(VSCLKDIS_OFFSET, 4);
+ if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg) {
+ pr_err("Can't map VPIF VIDCLKCTL or VSCLKDIS registers\n");
+ return;
+ }
+ spin_lock_init(&vpif_reg_lock);
+
+ dm646x_setup_vpif(&dm646x_vpif_display_config,
+ &dm646x_vpif_capture_cfg);
+}
+
+static void __init evm_init_i2c(void)
+{
+ davinci_init_i2c(&i2c_pdata);
+ i2c_add_driver(&dm6467evm_cpld_driver);
+ i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+ evm_init_cpld();
+ evm_init_video();
+}
+
+#define CDCE949_XIN_RATE 27000000
+
+/* CDCE949 support - "lpsc" field is overridden to work as clock number */
+static struct clk cdce_clk_in = {
+ .name = "cdce_xin",
+ .rate = CDCE949_XIN_RATE,
+};
+
+static struct clk_lookup cdce_clks[] = {
+ CLK(NULL, "xin", &cdce_clk_in),
+ CLK(NULL, NULL, NULL),
+};
+
+static void __init cdce_clk_init(void)
+{
+ struct clk_lookup *c;
+ struct clk *clk;
+
+ for (c = cdce_clks; c->clk; c++) {
+ clk = c->clk;
+ clkdev_add(c);
+ clk_register(clk);
+ }
+}
+
+static void __init davinci_map_io(void)
+{
+ dm646x_init();
+ cdce_clk_init();
+}
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+#define DM646X_EVM_PHY_ID "0:01"
+/*
+ * The following EDMA channels/slots are not being used by drivers (for
+ * example: Timer, GPIO, UART events etc) on dm646x, hence they are being
+ * reserved for codecs on the DSP side.
+ */
+static const s16 dm646x_dma_rsv_chans[][2] = {
+ /* (offset, number) */
+ { 0, 4},
+ {13, 3},
+ {24, 4},
+ {30, 2},
+ {54, 3},
+ {-1, -1}
+};
+
+static const s16 dm646x_dma_rsv_slots[][2] = {
+ /* (offset, number) */
+ { 0, 4},
+ {13, 3},
+ {24, 4},
+ {30, 2},
+ {54, 3},
+ {128, 384},
+ {-1, -1}
+};
+
+static struct edma_rsv_info dm646x_edma_rsv[] = {
+ {
+ .rsv_chans = dm646x_dma_rsv_chans,
+ .rsv_slots = dm646x_dma_rsv_slots,
+ },
+};
+
+static __init void evm_init(void)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ evm_init_i2c();
+ davinci_serial_init(&uart_config);
+ dm646x_init_mcasp0(&dm646x_evm_snd_data[0]);
+ dm646x_init_mcasp1(&dm646x_evm_snd_data[1]);
+
+ if (machine_is_davinci_dm6467tevm())
+ davinci_nand_data.timing = &dm6467tevm_nandflash_timing;
+
+ platform_device_register(&davinci_nand_device);
+
+ dm646x_init_edma(dm646x_edma_rsv);
+
+ if (HAS_ATA)
+ davinci_init_ide();
+
+ soc_info->emac_pdata->phy_id = DM646X_EVM_PHY_ID;
+}
+
+#define DM646X_EVM_REF_FREQ 27000000
+#define DM6467T_EVM_REF_FREQ 33000000
+
+void __init dm646x_board_setup_refclk(struct clk *clk)
+{
+ if (machine_is_davinci_dm6467tevm())
+ clk->rate = DM6467T_EVM_REF_FREQ;
+ else
+ clk->rate = DM646X_EVM_REF_FREQ;
+}
+
+MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
+ .boot_params = (0x80000100),
+ .map_io = davinci_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = evm_init,
+MACHINE_END
+
+MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
+ .boot_params = (0x80000100),
+ .map_io = davinci_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = evm_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
new file mode 100644
index 00000000..5f5d7830
--- /dev/null
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -0,0 +1,574 @@
+/*
+ * Critical Link MityOMAP-L138 SoM
+ *
+ * Copyright (C) 2010 Critical Link LLC - http://www.criticallink.com
+ *
+ * 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/console.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/etherdevice.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/common.h>
+#include <mach/cp_intc.h>
+#include <mach/da8xx.h>
+#include <mach/nand.h>
+#include <mach/mux.h>
+#include <mach/spi.h>
+
+#define MITYOMAPL138_PHY_ID ""
+
+#define FACTORY_CONFIG_MAGIC 0x012C0138
+#define FACTORY_CONFIG_VERSION 0x00010001
+
+/* Data Held in On-Board I2C device */
+struct factory_config {
+ u32 magic;
+ u32 version;
+ u8 mac[6];
+ u32 fpga_type;
+ u32 spare;
+ u32 serialnumber;
+ char partnum[32];
+};
+
+static struct factory_config factory_config;
+
+struct part_no_info {
+ const char *part_no; /* part number string of interest */
+ int max_freq; /* khz */
+};
+
+static struct part_no_info mityomapl138_pn_info[] = {
+ {
+ .part_no = "L138-C",
+ .max_freq = 300000,
+ },
+ {
+ .part_no = "L138-D",
+ .max_freq = 375000,
+ },
+ {
+ .part_no = "L138-F",
+ .max_freq = 456000,
+ },
+ {
+ .part_no = "1808-C",
+ .max_freq = 300000,
+ },
+ {
+ .part_no = "1808-D",
+ .max_freq = 375000,
+ },
+ {
+ .part_no = "1808-F",
+ .max_freq = 456000,
+ },
+ {
+ .part_no = "1810-D",
+ .max_freq = 375000,
+ },
+};
+
+#ifdef CONFIG_CPU_FREQ
+static void mityomapl138_cpufreq_init(const char *partnum)
+{
+ int i, ret;
+
+ for (i = 0; partnum && i < ARRAY_SIZE(mityomapl138_pn_info); i++) {
+ /*
+ * the part number has additional characters beyond what is
+ * stored in the table. This information is not needed for
+ * determining the speed grade, and would require several
+ * more table entries. Only check the first N characters
+ * for a match.
+ */
+ if (!strncmp(partnum, mityomapl138_pn_info[i].part_no,
+ strlen(mityomapl138_pn_info[i].part_no))) {
+ da850_max_speed = mityomapl138_pn_info[i].max_freq;
+ break;
+ }
+ }
+
+ ret = da850_register_cpufreq("pll0_sysclk3");
+ if (ret)
+ pr_warning("cpufreq registration failed: %d\n", ret);
+}
+#else
+static void mityomapl138_cpufreq_init(const char *partnum) { }
+#endif
+
+static void read_factory_config(struct memory_accessor *a, void *context)
+{
+ int ret;
+ const char *partnum = NULL;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ ret = a->read(a, (char *)&factory_config, 0, sizeof(factory_config));
+ if (ret != sizeof(struct factory_config)) {
+ pr_warning("MityOMAPL138: Read Factory Config Failed: %d\n",
+ ret);
+ goto bad_config;
+ }
+
+ if (factory_config.magic != FACTORY_CONFIG_MAGIC) {
+ pr_warning("MityOMAPL138: Factory Config Magic Wrong (%X)\n",
+ factory_config.magic);
+ goto bad_config;
+ }
+
+ if (factory_config.version != FACTORY_CONFIG_VERSION) {
+ pr_warning("MityOMAPL138: Factory Config Version Wrong (%X)\n",
+ factory_config.version);
+ goto bad_config;
+ }
+
+ pr_info("MityOMAPL138: Found MAC = %pM\n", factory_config.mac);
+ if (is_valid_ether_addr(factory_config.mac))
+ memcpy(soc_info->emac_pdata->mac_addr,
+ factory_config.mac, ETH_ALEN);
+ else
+ pr_warning("MityOMAPL138: Invalid MAC found "
+ "in factory config block\n");
+
+ partnum = factory_config.partnum;
+ pr_info("MityOMAPL138: Part Number = %s\n", partnum);
+
+bad_config:
+ /* default maximum speed is valid for all platforms */
+ mityomapl138_cpufreq_init(partnum);
+}
+
+static struct at24_platform_data mityomapl138_fd_chip = {
+ .byte_len = 256,
+ .page_size = 8,
+ .flags = AT24_FLAG_READONLY | AT24_FLAG_IRUGO,
+ .setup = read_factory_config,
+ .context = NULL,
+};
+
+static struct davinci_i2c_platform_data mityomap_i2c_0_pdata = {
+ .bus_freq = 100, /* kHz */
+ .bus_delay = 0, /* usec */
+};
+
+/* TPS65023 voltage regulator support */
+/* 1.2V Core */
+static struct regulator_consumer_supply tps65023_dcdc1_consumers[] = {
+ {
+ .supply = "cvdd",
+ },
+};
+
+/* 1.8V */
+static struct regulator_consumer_supply tps65023_dcdc2_consumers[] = {
+ {
+ .supply = "usb0_vdda18",
+ },
+ {
+ .supply = "usb1_vdda18",
+ },
+ {
+ .supply = "ddr_dvdd18",
+ },
+ {
+ .supply = "sata_vddr",
+ },
+};
+
+/* 1.2V */
+static struct regulator_consumer_supply tps65023_dcdc3_consumers[] = {
+ {
+ .supply = "sata_vdd",
+ },
+ {
+ .supply = "usb_cvdd",
+ },
+ {
+ .supply = "pll0_vdda",
+ },
+ {
+ .supply = "pll1_vdda",
+ },
+};
+
+/* 1.8V Aux LDO, not used */
+static struct regulator_consumer_supply tps65023_ldo1_consumers[] = {
+ {
+ .supply = "1.8v_aux",
+ },
+};
+
+/* FPGA VCC Aux (2.5 or 3.3) LDO */
+static struct regulator_consumer_supply tps65023_ldo2_consumers[] = {
+ {
+ .supply = "vccaux",
+ },
+};
+
+static struct regulator_init_data tps65023_regulator_data[] = {
+ /* dcdc1 */
+ {
+ .constraints = {
+ .min_uV = 1150000,
+ .max_uV = 1350000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc1_consumers),
+ .consumer_supplies = tps65023_dcdc1_consumers,
+ },
+ /* dcdc2 */
+ {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc2_consumers),
+ .consumer_supplies = tps65023_dcdc2_consumers,
+ },
+ /* dcdc3 */
+ {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc3_consumers),
+ .consumer_supplies = tps65023_dcdc3_consumers,
+ },
+ /* ldo1 */
+ {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_ldo1_consumers),
+ .consumer_supplies = tps65023_ldo1_consumers,
+ },
+ /* ldo2 */
+ {
+ .constraints = {
+ .min_uV = 2500000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_ldo2_consumers),
+ .consumer_supplies = tps65023_ldo2_consumers,
+ },
+};
+
+static struct i2c_board_info __initdata mityomap_tps65023_info[] = {
+ {
+ I2C_BOARD_INFO("tps65023", 0x48),
+ .platform_data = &tps65023_regulator_data[0],
+ },
+ {
+ I2C_BOARD_INFO("24c02", 0x50),
+ .platform_data = &mityomapl138_fd_chip,
+ },
+};
+
+static int __init pmic_tps65023_init(void)
+{
+ return i2c_register_board_info(1, mityomap_tps65023_info,
+ ARRAY_SIZE(mityomap_tps65023_info));
+}
+
+/*
+ * SPI Devices:
+ * SPI1_CS0: 8M Flash ST-M25P64-VME6G
+ */
+static struct mtd_partition spi_flash_partitions[] = {
+ [0] = {
+ .name = "ubl",
+ .offset = 0,
+ .size = SZ_64K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [1] = {
+ .name = "u-boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_512K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [2] = {
+ .name = "u-boot-env",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_64K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [3] = {
+ .name = "periph-config",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_64K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [4] = {
+ .name = "reserved",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K + SZ_64K,
+ },
+ [5] = {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M + SZ_1M,
+ },
+ [6] = {
+ .name = "fpga",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ },
+ [7] = {
+ .name = "spare",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data mityomapl138_spi_flash_data = {
+ .name = "m25p80",
+ .parts = spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(spi_flash_partitions),
+ .type = "m24p64",
+};
+
+static struct davinci_spi_config spi_eprom_config = {
+ .io_type = SPI_IO_TYPE_DMA,
+ .c2tdelay = 8,
+ .t2cdelay = 8,
+};
+
+static struct spi_board_info mityomapl138_spi_flash_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &mityomapl138_spi_flash_data,
+ .controller_data = &spi_eprom_config,
+ .mode = SPI_MODE_0,
+ .max_speed_hz = 30000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ },
+};
+
+/*
+ * MityDSP-L138 includes a 256 MByte large-page NAND flash
+ * (128K blocks).
+ */
+static struct mtd_partition mityomapl138_nandflash_partition[] = {
+ {
+ .name = "rootfs",
+ .offset = 0,
+ .size = SZ_128M,
+ .mask_flags = 0, /* MTD_WRITEABLE, */
+ },
+ {
+ .name = "homefs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct davinci_nand_pdata mityomapl138_nandflash_data = {
+ .parts = mityomapl138_nandflash_partition,
+ .nr_parts = ARRAY_SIZE(mityomapl138_nandflash_partition),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT | NAND_BUSWIDTH_16,
+ .ecc_bits = 1, /* 4 bit mode is not supported with 16 bit NAND */
+};
+
+static struct resource mityomapl138_nandflash_resource[] = {
+ {
+ .start = DA8XX_AEMIF_CS3_BASE,
+ .end = DA8XX_AEMIF_CS3_BASE + SZ_512K + 2 * SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DA8XX_AEMIF_CTL_BASE,
+ .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device mityomapl138_nandflash_device = {
+ .name = "davinci_nand",
+ .id = 1,
+ .dev = {
+ .platform_data = &mityomapl138_nandflash_data,
+ },
+ .num_resources = ARRAY_SIZE(mityomapl138_nandflash_resource),
+ .resource = mityomapl138_nandflash_resource,
+};
+
+static struct platform_device *mityomapl138_devices[] __initdata = {
+ &mityomapl138_nandflash_device,
+};
+
+static void __init mityomapl138_setup_nand(void)
+{
+ platform_add_devices(mityomapl138_devices,
+ ARRAY_SIZE(mityomapl138_devices));
+}
+
+static struct davinci_uart_config mityomapl138_uart_config __initdata = {
+ .enabled_uarts = 0x7,
+};
+
+static const short mityomap_mii_pins[] = {
+ DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
+ DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
+ DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
+ DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
+static const short mityomap_rmii_pins[] = {
+ DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN,
+ DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1,
+ DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
+static void __init mityomapl138_config_emac(void)
+{
+ void __iomem *cfg_chip3_base;
+ int ret;
+ u32 val;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ soc_info->emac_pdata->rmii_en = 0; /* hardcoded for now */
+
+ cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
+ val = __raw_readl(cfg_chip3_base);
+
+ if (soc_info->emac_pdata->rmii_en) {
+ val |= BIT(8);
+ ret = davinci_cfg_reg_list(mityomap_rmii_pins);
+ pr_info("RMII PHY configured\n");
+ } else {
+ val &= ~BIT(8);
+ ret = davinci_cfg_reg_list(mityomap_mii_pins);
+ pr_info("MII PHY configured\n");
+ }
+
+ if (ret) {
+ pr_warning("mii/rmii mux setup failed: %d\n", ret);
+ return;
+ }
+
+ /* configure the CFGCHIP3 register for RMII or MII */
+ __raw_writel(val, cfg_chip3_base);
+
+ soc_info->emac_pdata->phy_id = MITYOMAPL138_PHY_ID;
+
+ ret = da8xx_register_emac();
+ if (ret)
+ pr_warning("emac registration failed: %d\n", ret);
+}
+
+static struct davinci_pm_config da850_pm_pdata = {
+ .sleepcount = 128,
+};
+
+static struct platform_device da850_pm_device = {
+ .name = "pm-davinci",
+ .dev = {
+ .platform_data = &da850_pm_pdata,
+ },
+ .id = -1,
+};
+
+static void __init mityomapl138_init(void)
+{
+ int ret;
+
+ /* for now, no special EDMA channels are reserved */
+ ret = da850_register_edma(NULL);
+ if (ret)
+ pr_warning("edma registration failed: %d\n", ret);
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warning("watchdog registration failed: %d\n", ret);
+
+ davinci_serial_init(&mityomapl138_uart_config);
+
+ ret = da8xx_register_i2c(0, &mityomap_i2c_0_pdata);
+ if (ret)
+ pr_warning("i2c0 registration failed: %d\n", ret);
+
+ ret = pmic_tps65023_init();
+ if (ret)
+ pr_warning("TPS65023 PMIC init failed: %d\n", ret);
+
+ mityomapl138_setup_nand();
+
+ ret = da8xx_register_spi(1, mityomapl138_spi_flash_info,
+ ARRAY_SIZE(mityomapl138_spi_flash_info));
+ if (ret)
+ pr_warning("spi 1 registration failed: %d\n", ret);
+
+ mityomapl138_config_emac();
+
+ ret = da8xx_register_rtc();
+ if (ret)
+ pr_warning("rtc setup failed: %d\n", ret);
+
+ ret = da8xx_register_cpuidle();
+ if (ret)
+ pr_warning("cpuidle registration failed: %d\n", ret);
+
+ ret = da850_register_pm(&da850_pm_device);
+ if (ret)
+ pr_warning("da850_evm_init: suspend registration failed: %d\n",
+ ret);
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init mityomapl138_console_init(void)
+{
+ if (!machine_is_mityomapl138())
+ return 0;
+
+ return add_preferred_console("ttyS", 1, "115200");
+}
+console_initcall(mityomapl138_console_init);
+#endif
+
+static void __init mityomapl138_map_io(void)
+{
+ da850_init();
+}
+
+MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808")
+ .boot_params = (DA8XX_DDR_BASE + 0x100),
+ .map_io = mityomapl138_map_io,
+ .init_irq = cp_intc_init,
+ .timer = &davinci_timer,
+ .init_machine = mityomapl138_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
new file mode 100644
index 00000000..3e7be2de
--- /dev/null
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -0,0 +1,280 @@
+/*
+ * Neuros Technologies OSD2 board support
+ *
+ * Modified from original 644X-EVM board support.
+ * 2008 (c) Neuros Technology, LLC.
+ * 2009 (c) Jorge Luis Zapata Muga <jorgeluis.zapata@gmail.com>
+ * 2009 (c) Andrey A. Porodko <Andrey.Porodko@gmail.com>
+ *
+ * The Neuros OSD 2.0 is the hardware component of the Neuros Open
+ * Internet Television Platform. Hardware is very close to TI
+ * DM644X-EVM board. It has:
+ * DM6446M02 module with 256MB NAND, 256MB RAM, TLV320AIC32 AIC,
+ * USB, Ethernet, SD/MMC, UART, THS8200, TVP7000 for video.
+ * Additionally realtime clock, IR remote control receiver,
+ * IR Blaster based on MSP430 (firmware although is different
+ * from used in DM644X-EVM), internal ATA-6 3.5” HDD drive
+ * with PATA interface, two muxed red-green leds.
+ *
+ * For more information please refer to
+ * http://wiki.neurostechnology.com/index.php/OSD_2.0_HD
+ *
+ * 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/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dm644x.h>
+#include <mach/common.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/mux.h>
+#include <mach/nand.h>
+#include <mach/mmc.h>
+#include <mach/usb.h>
+
+#define NEUROS_OSD2_PHY_ID "0:01"
+#define LXT971_PHY_ID 0x001378e2
+#define LXT971_PHY_MASK 0xfffffff0
+
+#define NTOSD2_AUDIOSOC_I2C_ADDR 0x18
+#define NTOSD2_MSP430_I2C_ADDR 0x59
+#define NTOSD2_MSP430_IRQ 2
+
+/* Neuros OSD2 has a Samsung 256 MByte NAND flash (Dev ID of 0xAA,
+ * 2048 blocks in the device, 64 pages per block, 2048 bytes per
+ * page.
+ */
+
+#define NAND_BLOCK_SIZE SZ_128K
+
+static struct mtd_partition davinci_ntosd2_nandflash_partition[] = {
+ {
+ /* UBL (a few copies) plus U-Boot */
+ .name = "bootloader",
+ .offset = 0,
+ .size = 15 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ /* U-Boot environment */
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1 * NAND_BLOCK_SIZE,
+ .mask_flags = 0,
+ }, {
+ /* Kernel */
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ }, {
+ /* File System */
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+ /* A few blocks at end hold a flash Bad Block Table. */
+};
+
+static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = {
+ .parts = davinci_ntosd2_nandflash_partition,
+ .nr_parts = ARRAY_SIZE(davinci_ntosd2_nandflash_partition),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT,
+};
+
+static struct resource davinci_ntosd2_nandflash_resource[] = {
+ {
+ .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM644X_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_ntosd2_nandflash_device = {
+ .name = "davinci_nand",
+ .id = 0,
+ .dev = {
+ .platform_data = &davinci_ntosd2_nandflash_data,
+ },
+ .num_resources = ARRAY_SIZE(davinci_ntosd2_nandflash_resource),
+ .resource = davinci_ntosd2_nandflash_resource,
+};
+
+static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device davinci_fb_device = {
+ .name = "davincifb",
+ .id = -1,
+ .dev = {
+ .dma_mask = &davinci_fb_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = 0,
+};
+
+static struct snd_platform_data dm644x_ntosd2_snd_data;
+
+static struct gpio_led ntosd2_leds[] = {
+ { .name = "led1_green", .gpio = GPIO(10), },
+ { .name = "led1_red", .gpio = GPIO(11), },
+ { .name = "led2_green", .gpio = GPIO(12), },
+ { .name = "led2_red", .gpio = GPIO(13), },
+};
+
+static struct gpio_led_platform_data ntosd2_leds_data = {
+ .num_leds = ARRAY_SIZE(ntosd2_leds),
+ .leds = ntosd2_leds,
+};
+
+static struct platform_device ntosd2_leds_dev = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &ntosd2_leds_data,
+ },
+};
+
+
+static struct platform_device *davinci_ntosd2_devices[] __initdata = {
+ &davinci_fb_device,
+ &ntosd2_leds_dev,
+};
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+static void __init davinci_ntosd2_map_io(void)
+{
+ dm644x_init();
+}
+
+/*
+ I2C initialization
+*/
+static struct davinci_i2c_platform_data ntosd2_i2c_pdata = {
+ .bus_freq = 20 /* kHz */,
+ .bus_delay = 100 /* usec */,
+};
+
+static struct i2c_board_info __initdata ntosd2_i2c_info[] = {
+};
+
+static int ntosd2_init_i2c(void)
+{
+ int status;
+
+ davinci_init_i2c(&ntosd2_i2c_pdata);
+ status = gpio_request(NTOSD2_MSP430_IRQ, ntosd2_i2c_info[0].type);
+ if (status == 0) {
+ status = gpio_direction_input(NTOSD2_MSP430_IRQ);
+ if (status == 0) {
+ status = gpio_to_irq(NTOSD2_MSP430_IRQ);
+ if (status > 0) {
+ ntosd2_i2c_info[0].irq = status;
+ i2c_register_board_info(1,
+ ntosd2_i2c_info,
+ ARRAY_SIZE(ntosd2_i2c_info));
+ }
+ }
+ }
+ return status;
+}
+
+static struct davinci_mmc_config davinci_ntosd2_mmc_config = {
+ .wires = 4,
+ .version = MMC_CTLR_VERSION_1
+};
+
+
+#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+ defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+#define HAS_ATA 1
+#else
+#define HAS_ATA 0
+#endif
+
+#if defined(CONFIG_MTD_NAND_DAVINCI) || \
+ defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
+#define HAS_NAND 1
+#else
+#define HAS_NAND 0
+#endif
+
+static __init void davinci_ntosd2_init(void)
+{
+ struct clk *aemif_clk;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ int status;
+
+ aemif_clk = clk_get(NULL, "aemif");
+ clk_enable(aemif_clk);
+
+ if (HAS_ATA) {
+ if (HAS_NAND)
+ pr_warning("WARNING: both IDE and Flash are "
+ "enabled, but they share AEMIF pins.\n"
+ "\tDisable IDE for NAND/NOR support.\n");
+ davinci_init_ide();
+ } else if (HAS_NAND) {
+ davinci_cfg_reg(DM644X_HPIEN_DISABLE);
+ davinci_cfg_reg(DM644X_ATAEN_DISABLE);
+
+ /* only one device will be jumpered and detected */
+ if (HAS_NAND)
+ platform_device_register(
+ &davinci_ntosd2_nandflash_device);
+ }
+
+ platform_add_devices(davinci_ntosd2_devices,
+ ARRAY_SIZE(davinci_ntosd2_devices));
+
+ /* Initialize I2C interface specific for this board */
+ status = ntosd2_init_i2c();
+ if (status < 0)
+ pr_warning("davinci_ntosd2_init: msp430 irq setup failed:"
+ " %d\n", status);
+
+ davinci_serial_init(&uart_config);
+ dm644x_init_asp(&dm644x_ntosd2_snd_data);
+
+ soc_info->emac_pdata->phy_id = NEUROS_OSD2_PHY_ID;
+
+ davinci_setup_usb(1000, 8);
+ /*
+ * Mux the pins to be GPIOs, VLYNQEN is already done at startup.
+ * The AEAWx are five new AEAW pins that can be muxed by separately.
+ * They are a bitmask for GPIO management. According TI
+ * documentation (http://www.ti.com/lit/gpn/tms320dm6446) to employ
+ * gpio(10,11,12,13) for leds any combination of bits works except
+ * four last. So we are to reset all five.
+ */
+ davinci_cfg_reg(DM644X_AEAW0);
+ davinci_cfg_reg(DM644X_AEAW1);
+ davinci_cfg_reg(DM644X_AEAW2);
+ davinci_cfg_reg(DM644X_AEAW3);
+ davinci_cfg_reg(DM644X_AEAW4);
+
+ davinci_setup_mmc(0, &davinci_ntosd2_mmc_config);
+}
+
+MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
+ /* Maintainer: Neuros Technologies <neuros@groups.google.com> */
+ .boot_params = (DAVINCI_DDR_BASE + 0x100),
+ .map_io = davinci_ntosd2_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = davinci_ntosd2_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
new file mode 100644
index 00000000..67c38d0e
--- /dev/null
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -0,0 +1,346 @@
+/*
+ * Hawkboard.org based on TI's OMAP-L138 Platform
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * 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/console.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/cp_intc.h>
+#include <mach/da8xx.h>
+#include <mach/mux.h>
+
+#define HAWKBOARD_PHY_ID "0:07"
+#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12)
+#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13)
+
+#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4)
+#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13)
+
+static short omapl138_hawk_mii_pins[] __initdata = {
+ DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
+ DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
+ DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
+ DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
+static __init void omapl138_hawk_config_emac(void)
+{
+ void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
+ int ret;
+ u32 val;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ val = __raw_readl(cfgchip3);
+ val &= ~BIT(8);
+ ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins);
+ if (ret) {
+ pr_warning("%s: cpgmac/mii mux setup failed: %d\n",
+ __func__, ret);
+ return;
+ }
+
+ /* configure the CFGCHIP3 register for MII */
+ __raw_writel(val, cfgchip3);
+ pr_info("EMAC: MII PHY configured\n");
+
+ soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID;
+
+ ret = da8xx_register_emac();
+ if (ret)
+ pr_warning("%s: emac registration failed: %d\n",
+ __func__, ret);
+}
+
+/*
+ * The following EDMA channels/slots are not being used by drivers (for
+ * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM/Hawkboard,
+ * hence they are being reserved for codecs on the DSP side.
+ */
+static const s16 da850_dma0_rsv_chans[][2] = {
+ /* (offset, number) */
+ { 8, 6},
+ {24, 4},
+ {30, 2},
+ {-1, -1}
+};
+
+static const s16 da850_dma0_rsv_slots[][2] = {
+ /* (offset, number) */
+ { 8, 6},
+ {24, 4},
+ {30, 50},
+ {-1, -1}
+};
+
+static const s16 da850_dma1_rsv_chans[][2] = {
+ /* (offset, number) */
+ { 0, 28},
+ {30, 2},
+ {-1, -1}
+};
+
+static const s16 da850_dma1_rsv_slots[][2] = {
+ /* (offset, number) */
+ { 0, 28},
+ {30, 90},
+ {-1, -1}
+};
+
+static struct edma_rsv_info da850_edma_cc0_rsv = {
+ .rsv_chans = da850_dma0_rsv_chans,
+ .rsv_slots = da850_dma0_rsv_slots,
+};
+
+static struct edma_rsv_info da850_edma_cc1_rsv = {
+ .rsv_chans = da850_dma1_rsv_chans,
+ .rsv_slots = da850_dma1_rsv_slots,
+};
+
+static struct edma_rsv_info *da850_edma_rsv[2] = {
+ &da850_edma_cc0_rsv,
+ &da850_edma_cc1_rsv,
+};
+
+static const short hawk_mmcsd0_pins[] = {
+ DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2,
+ DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD,
+ DA850_GPIO3_12, DA850_GPIO3_13,
+ -1
+};
+
+static int da850_hawk_mmc_get_ro(int index)
+{
+ return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN);
+}
+
+static int da850_hawk_mmc_get_cd(int index)
+{
+ return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN);
+}
+
+static struct davinci_mmc_config da850_mmc_config = {
+ .get_ro = da850_hawk_mmc_get_ro,
+ .get_cd = da850_hawk_mmc_get_cd,
+ .wires = 4,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .version = MMC_CTLR_VERSION_2,
+};
+
+static __init void omapl138_hawk_mmc_init(void)
+{
+ int ret;
+
+ ret = davinci_cfg_reg_list(hawk_mmcsd0_pins);
+ if (ret) {
+ pr_warning("%s: MMC/SD0 mux setup failed: %d\n",
+ __func__, ret);
+ return;
+ }
+
+ ret = gpio_request_one(DA850_HAWK_MMCSD_CD_PIN,
+ GPIOF_DIR_IN, "MMC CD");
+ if (ret < 0) {
+ pr_warning("%s: can not open GPIO %d\n",
+ __func__, DA850_HAWK_MMCSD_CD_PIN);
+ return;
+ }
+
+ ret = gpio_request_one(DA850_HAWK_MMCSD_WP_PIN,
+ GPIOF_DIR_IN, "MMC WP");
+ if (ret < 0) {
+ pr_warning("%s: can not open GPIO %d\n",
+ __func__, DA850_HAWK_MMCSD_WP_PIN);
+ goto mmc_setup_wp_fail;
+ }
+
+ ret = da8xx_register_mmcsd0(&da850_mmc_config);
+ if (ret) {
+ pr_warning("%s: MMC/SD0 registration failed: %d\n",
+ __func__, ret);
+ goto mmc_setup_mmcsd_fail;
+ }
+
+ return;
+
+mmc_setup_mmcsd_fail:
+ gpio_free(DA850_HAWK_MMCSD_WP_PIN);
+mmc_setup_wp_fail:
+ gpio_free(DA850_HAWK_MMCSD_CD_PIN);
+}
+
+static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id);
+static da8xx_ocic_handler_t hawk_usb_ocic_handler;
+
+static const short da850_hawk_usb11_pins[] = {
+ DA850_GPIO2_4, DA850_GPIO6_13,
+ -1
+};
+
+static int hawk_usb_set_power(unsigned port, int on)
+{
+ gpio_set_value(DA850_USB1_VBUS_PIN, on);
+ return 0;
+}
+
+static int hawk_usb_get_power(unsigned port)
+{
+ return gpio_get_value(DA850_USB1_VBUS_PIN);
+}
+
+static int hawk_usb_get_oci(unsigned port)
+{
+ return !gpio_get_value(DA850_USB1_OC_PIN);
+}
+
+static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler)
+{
+ int irq = gpio_to_irq(DA850_USB1_OC_PIN);
+ int error = 0;
+
+ if (handler != NULL) {
+ hawk_usb_ocic_handler = handler;
+
+ error = request_irq(irq, omapl138_hawk_usb_ocic_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING,
+ "OHCI over-current indicator", NULL);
+ if (error)
+ pr_err("%s: could not request IRQ to watch "
+ "over-current indicator changes\n", __func__);
+ } else {
+ free_irq(irq, NULL);
+ }
+ return error;
+}
+
+static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = {
+ .set_power = hawk_usb_set_power,
+ .get_power = hawk_usb_get_power,
+ .get_oci = hawk_usb_get_oci,
+ .ocic_notify = hawk_usb_ocic_notify,
+ /* TPS2087 switch @ 5V */
+ .potpgt = (3 + 1) / 2, /* 3 ms max */
+};
+
+static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id)
+{
+ hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1);
+ return IRQ_HANDLED;
+}
+
+static __init void omapl138_hawk_usb_init(void)
+{
+ int ret;
+ u32 cfgchip2;
+
+ ret = davinci_cfg_reg_list(da850_hawk_usb11_pins);
+ if (ret) {
+ pr_warning("%s: USB 1.1 PinMux setup failed: %d\n",
+ __func__, ret);
+ return;
+ }
+
+ /* Setup the Ref. clock frequency for the HAWK at 24 MHz. */
+
+ cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+ cfgchip2 &= ~CFGCHIP2_REFFREQ;
+ cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ;
+ __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ ret = gpio_request_one(DA850_USB1_VBUS_PIN,
+ GPIOF_DIR_OUT, "USB1 VBUS");
+ if (ret < 0) {
+ pr_err("%s: failed to request GPIO for USB 1.1 port "
+ "power control: %d\n", __func__, ret);
+ return;
+ }
+
+ ret = gpio_request_one(DA850_USB1_OC_PIN,
+ GPIOF_DIR_IN, "USB1 OC");
+ if (ret < 0) {
+ pr_err("%s: failed to request GPIO for USB 1.1 port "
+ "over-current indicator: %d\n", __func__, ret);
+ goto usb11_setup_oc_fail;
+ }
+
+ ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata);
+ if (ret) {
+ pr_warning("%s: USB 1.1 registration failed: %d\n",
+ __func__, ret);
+ goto usb11_setup_fail;
+ }
+
+ return;
+
+usb11_setup_fail:
+ gpio_free(DA850_USB1_OC_PIN);
+usb11_setup_oc_fail:
+ gpio_free(DA850_USB1_VBUS_PIN);
+}
+
+static struct davinci_uart_config omapl138_hawk_uart_config __initdata = {
+ .enabled_uarts = 0x7,
+};
+
+static __init void omapl138_hawk_init(void)
+{
+ int ret;
+
+ davinci_serial_init(&omapl138_hawk_uart_config);
+
+ omapl138_hawk_config_emac();
+
+ ret = da850_register_edma(da850_edma_rsv);
+ if (ret)
+ pr_warning("%s: EDMA registration failed: %d\n",
+ __func__, ret);
+
+ omapl138_hawk_mmc_init();
+
+ omapl138_hawk_usb_init();
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warning("omapl138_hawk_init: "
+ "watchdog registration failed: %d\n",
+ ret);
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init omapl138_hawk_console_init(void)
+{
+ if (!machine_is_omapl138_hawkboard())
+ return 0;
+
+ return add_preferred_console("ttyS", 2, "115200");
+}
+console_initcall(omapl138_hawk_console_init);
+#endif
+
+static void __init omapl138_hawk_map_io(void)
+{
+ da850_init();
+}
+
+MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
+ .boot_params = (DA8XX_DDR_BASE + 0x100),
+ .map_io = omapl138_hawk_map_io,
+ .init_irq = cp_intc_init,
+ .timer = &davinci_timer,
+ .init_machine = omapl138_hawk_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
new file mode 100644
index 00000000..61ac96d8
--- /dev/null
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -0,0 +1,159 @@
+/*
+ * Lyrtech SFFSDR board support.
+ *
+ * Copyright (C) 2008 Philip Balister, OpenSDR <philip@opensdr.com>
+ * Copyright (C) 2008 Lyrtech <www.lyrtech.com>
+ *
+ * Based on DV-EVM platform, original copyright follows:
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *
+ * 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+#include <mach/dm644x.h>
+#include <mach/common.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/mux.h>
+#include <mach/usb.h>
+
+#define SFFSDR_PHY_ID "0:01"
+static struct mtd_partition davinci_sffsdr_nandflash_partition[] = {
+ /* U-Boot Environment: Block 0
+ * UBL: Block 1
+ * U-Boot: Blocks 6-7 (256 kb)
+ * Integrity Kernel: Blocks 8-31 (3 Mb)
+ * Integrity Data: Blocks 100-END
+ */
+ {
+ .name = "Linux Kernel",
+ .offset = 32 * SZ_128K,
+ .size = 16 * SZ_128K, /* 2 Mb */
+ .mask_flags = MTD_WRITEABLE, /* Force read-only */
+ },
+ {
+ .name = "Linux ROOT",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 256 * SZ_128K, /* 32 Mb */
+ .mask_flags = 0, /* R/W */
+ },
+};
+
+static struct flash_platform_data davinci_sffsdr_nandflash_data = {
+ .parts = davinci_sffsdr_nandflash_partition,
+ .nr_parts = ARRAY_SIZE(davinci_sffsdr_nandflash_partition),
+};
+
+static struct resource davinci_sffsdr_nandflash_resource[] = {
+ {
+ .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM644X_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_sffsdr_nandflash_device = {
+ .name = "davinci_nand", /* Name of driver */
+ .id = 0,
+ .dev = {
+ .platform_data = &davinci_sffsdr_nandflash_data,
+ },
+ .num_resources = ARRAY_SIZE(davinci_sffsdr_nandflash_resource),
+ .resource = davinci_sffsdr_nandflash_resource,
+};
+
+static struct at24_platform_data eeprom_info = {
+ .byte_len = (64*1024) / 8,
+ .page_size = 32,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info __initdata i2c_info[] = {
+ {
+ I2C_BOARD_INFO("24lc64", 0x50),
+ .platform_data = &eeprom_info,
+ },
+ /* Other I2C devices:
+ * MSP430, addr 0x23 (not used)
+ * PCA9543, addr 0x70 (setup done by U-Boot)
+ * ADS7828, addr 0x48 (ADC for voltage monitoring.)
+ */
+};
+
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 20 /* kHz */,
+ .bus_delay = 100 /* usec */,
+};
+
+static void __init sffsdr_init_i2c(void)
+{
+ davinci_init_i2c(&i2c_pdata);
+ i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+}
+
+static struct platform_device *davinci_sffsdr_devices[] __initdata = {
+ &davinci_sffsdr_nandflash_device,
+};
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+static void __init davinci_sffsdr_map_io(void)
+{
+ dm644x_init();
+}
+
+static __init void davinci_sffsdr_init(void)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ platform_add_devices(davinci_sffsdr_devices,
+ ARRAY_SIZE(davinci_sffsdr_devices));
+ sffsdr_init_i2c();
+ davinci_serial_init(&uart_config);
+ soc_info->emac_pdata->phy_id = SFFSDR_PHY_ID;
+ davinci_setup_usb(0, 0); /* We support only peripheral mode. */
+
+ /* mux VLYNQ pins */
+ davinci_cfg_reg(DM644X_VLYNQEN);
+ davinci_cfg_reg(DM644X_VLYNQWD);
+}
+
+MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
+ /* Maintainer: Hugo Villeneuve hugo.villeneuve@lyrtech.com */
+ .boot_params = (DAVINCI_DDR_BASE + 0x100),
+ .map_io = davinci_sffsdr_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = davinci_sffsdr_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c
new file mode 100644
index 00000000..1a656e88
--- /dev/null
+++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c
@@ -0,0 +1,285 @@
+/*
+ * Texas Instruments TNETV107X EVM Board Support
+ *
+ * Copyright (C) 2010 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/ratelimit.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/irqs.h>
+#include <mach/edma.h>
+#include <mach/mux.h>
+#include <mach/cp_intc.h>
+#include <mach/tnetv107x.h>
+
+#define EVM_MMC_WP_GPIO 21
+#define EVM_MMC_CD_GPIO 24
+#define EVM_SPI_CS_GPIO 54
+
+static int initialize_gpio(int gpio, char *desc)
+{
+ int ret;
+
+ ret = gpio_request(gpio, desc);
+ if (ret < 0) {
+ pr_err_ratelimited("cannot open %s gpio\n", desc);
+ return -ENOSYS;
+ }
+ gpio_direction_input(gpio);
+ return gpio;
+}
+
+static int mmc_get_cd(int index)
+{
+ static int gpio;
+
+ if (!gpio)
+ gpio = initialize_gpio(EVM_MMC_CD_GPIO, "mmc card detect");
+
+ if (gpio < 0)
+ return gpio;
+
+ return gpio_get_value(gpio) ? 0 : 1;
+}
+
+static int mmc_get_ro(int index)
+{
+ static int gpio;
+
+ if (!gpio)
+ gpio = initialize_gpio(EVM_MMC_WP_GPIO, "mmc write protect");
+
+ if (gpio < 0)
+ return gpio;
+
+ return gpio_get_value(gpio) ? 1 : 0;
+}
+
+static struct davinci_mmc_config mmc_config = {
+ .get_cd = mmc_get_cd,
+ .get_ro = mmc_get_ro,
+ .wires = 4,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .version = MMC_CTLR_VERSION_1,
+};
+
+static const short sdio1_pins[] __initdata = {
+ TNETV107X_SDIO1_CLK_1, TNETV107X_SDIO1_CMD_1,
+ TNETV107X_SDIO1_DATA0_1, TNETV107X_SDIO1_DATA1_1,
+ TNETV107X_SDIO1_DATA2_1, TNETV107X_SDIO1_DATA3_1,
+ TNETV107X_GPIO21, TNETV107X_GPIO24,
+ -1
+};
+
+static const short uart1_pins[] __initdata = {
+ TNETV107X_UART1_RD, TNETV107X_UART1_TD,
+ -1
+};
+
+static const short ssp_pins[] __initdata = {
+ TNETV107X_SSP0_0, TNETV107X_SSP0_1, TNETV107X_SSP0_2,
+ TNETV107X_SSP1_0, TNETV107X_SSP1_1, TNETV107X_SSP1_2,
+ TNETV107X_SSP1_3, -1
+};
+
+static struct mtd_partition nand_partitions[] = {
+ /* bootloader (U-Boot, etc) in first 12 sectors */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = (12*SZ_128K),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+};
+
+static struct davinci_nand_pdata nand_config = {
+ .mask_cle = 0x4000,
+ .mask_ale = 0x2000,
+ .parts = nand_partitions,
+ .nr_parts = ARRAY_SIZE(nand_partitions),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT,
+ .ecc_bits = 1,
+};
+
+static struct davinci_uart_config serial_config __initconst = {
+ .enabled_uarts = BIT(1),
+};
+
+static const uint32_t keymap[] = {
+ KEY(0, 0, KEY_NUMERIC_1),
+ KEY(0, 1, KEY_NUMERIC_2),
+ KEY(0, 2, KEY_NUMERIC_3),
+ KEY(0, 3, KEY_FN_F1),
+ KEY(0, 4, KEY_MENU),
+
+ KEY(1, 0, KEY_NUMERIC_4),
+ KEY(1, 1, KEY_NUMERIC_5),
+ KEY(1, 2, KEY_NUMERIC_6),
+ KEY(1, 3, KEY_UP),
+ KEY(1, 4, KEY_FN_F2),
+
+ KEY(2, 0, KEY_NUMERIC_7),
+ KEY(2, 1, KEY_NUMERIC_8),
+ KEY(2, 2, KEY_NUMERIC_9),
+ KEY(2, 3, KEY_LEFT),
+ KEY(2, 4, KEY_ENTER),
+
+ KEY(3, 0, KEY_NUMERIC_STAR),
+ KEY(3, 1, KEY_NUMERIC_0),
+ KEY(3, 2, KEY_NUMERIC_POUND),
+ KEY(3, 3, KEY_DOWN),
+ KEY(3, 4, KEY_RIGHT),
+
+ KEY(4, 0, KEY_FN_F3),
+ KEY(4, 1, KEY_FN_F4),
+ KEY(4, 2, KEY_MUTE),
+ KEY(4, 3, KEY_HOME),
+ KEY(4, 4, KEY_BACK),
+
+ KEY(5, 0, KEY_VOLUMEDOWN),
+ KEY(5, 1, KEY_VOLUMEUP),
+ KEY(5, 2, KEY_F1),
+ KEY(5, 3, KEY_F2),
+ KEY(5, 4, KEY_F3),
+};
+
+static const struct matrix_keymap_data keymap_data = {
+ .keymap = keymap,
+ .keymap_size = ARRAY_SIZE(keymap),
+};
+
+static struct matrix_keypad_platform_data keypad_config = {
+ .keymap_data = &keymap_data,
+ .num_row_gpios = 6,
+ .num_col_gpios = 5,
+ .debounce_ms = 0, /* minimum */
+ .active_low = 0, /* pull up realization */
+ .no_autorepeat = 0,
+};
+
+static void spi_select_device(int cs)
+{
+ static int gpio;
+
+ if (!gpio) {
+ int ret;
+ ret = gpio_request(EVM_SPI_CS_GPIO, "spi chipsel");
+ if (ret < 0) {
+ pr_err("cannot open spi chipsel gpio\n");
+ gpio = -ENOSYS;
+ return;
+ } else {
+ gpio = EVM_SPI_CS_GPIO;
+ gpio_direction_output(gpio, 0);
+ }
+ }
+
+ if (gpio < 0)
+ return;
+
+ return gpio_set_value(gpio, cs ? 1 : 0);
+}
+
+static struct ti_ssp_spi_data spi_master_data = {
+ .num_cs = 2,
+ .select = spi_select_device,
+ .iosel = SSP_PIN_SEL(0, SSP_CLOCK) | SSP_PIN_SEL(1, SSP_DATA) |
+ SSP_PIN_SEL(2, SSP_CHIPSEL) | SSP_PIN_SEL(3, SSP_IN) |
+ SSP_INPUT_SEL(3),
+};
+
+static struct ti_ssp_data ssp_config = {
+ .out_clock = 250 * 1000,
+ .dev_data = {
+ [1] = {
+ .dev_name = "ti-ssp-spi",
+ .pdata = &spi_master_data,
+ .pdata_size = sizeof(spi_master_data),
+ },
+ },
+};
+
+static struct tnetv107x_device_info evm_device_info __initconst = {
+ .serial_config = &serial_config,
+ .mmc_config[1] = &mmc_config, /* controller 1 */
+ .nand_config[0] = &nand_config, /* chip select 0 */
+ .keypad_config = &keypad_config,
+ .ssp_config = &ssp_config,
+};
+
+static struct spi_board_info spi_info[] __initconst = {
+};
+
+static __init void tnetv107x_evm_board_init(void)
+{
+ davinci_cfg_reg_list(sdio1_pins);
+ davinci_cfg_reg_list(uart1_pins);
+ davinci_cfg_reg_list(ssp_pins);
+
+ tnetv107x_devices_init(&evm_device_info);
+
+ spi_register_board_info(spi_info, ARRAY_SIZE(spi_info));
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init tnetv107x_evm_console_init(void)
+{
+ return add_preferred_console("ttyS", 0, "115200");
+}
+console_initcall(tnetv107x_evm_console_init);
+#endif
+
+MACHINE_START(TNETV107X, "TNETV107X EVM")
+ .boot_params = (TNETV107X_DDR_BASE + 0x100),
+ .map_io = tnetv107x_init,
+ .init_irq = cp_intc_init,
+ .timer = &davinci_timer,
+ .init_machine = tnetv107x_evm_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/cdce949.c b/arch/arm/mach-davinci/cdce949.c
new file mode 100644
index 00000000..ba8b12b2
--- /dev/null
+++ b/arch/arm/mach-davinci/cdce949.c
@@ -0,0 +1,294 @@
+/*
+ * TI CDCE949 clock synthesizer driver
+ *
+ * Note: This implementation assumes an input of 27MHz to the CDCE.
+ * This is by no means constrained by CDCE hardware although the datasheet
+ * does use this as an example for all illustrations and more importantly:
+ * that is the crystal input on boards it is currently used on.
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated. http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+
+#include <mach/clock.h>
+#include <mach/cdce949.h>
+
+#include "clock.h"
+
+static struct i2c_client *cdce_i2c_client;
+static DEFINE_MUTEX(cdce_mutex);
+
+/* CDCE register descriptor */
+struct cdce_reg {
+ u8 addr;
+ u8 val;
+};
+
+/* Per-Output (Y1, Y2 etc.) frequency descriptor */
+struct cdce_freq {
+ /* Frequency in KHz */
+ unsigned long frequency;
+ /*
+ * List of registers to program to obtain a particular frequency.
+ * 0x0 in register address and value is the end of list marker.
+ */
+ struct cdce_reg *reglist;
+};
+
+#define CDCE_FREQ_TABLE_ENTRY(line, out) \
+{ \
+ .reglist = cdce_y ##line## _ ##out, \
+ .frequency = out, \
+}
+
+/* List of CDCE outputs */
+struct cdce_output {
+ /* List of frequencies on this output */
+ struct cdce_freq *freq_table;
+ /* Number of possible frequencies */
+ int size;
+};
+
+/*
+ * Finding out the values to program into CDCE949 registers for a particular
+ * frequency output is not a simple calculation. Have a look at the datasheet
+ * for the details. There is desktop software available to help users with
+ * the calculations. Here, we just depend on the output of that software
+ * (or hand calculations) instead trying to runtime calculate the register
+ * values and inflicting misery on ourselves.
+ */
+static struct cdce_reg cdce_y1_148500[] = {
+ { 0x13, 0x00 },
+ /* program PLL1_0 multiplier */
+ { 0x18, 0xaf },
+ { 0x19, 0x50 },
+ { 0x1a, 0x02 },
+ { 0x1b, 0xc9 },
+ /* program PLL1_11 multiplier */
+ { 0x1c, 0x00 },
+ { 0x1d, 0x40 },
+ { 0x1e, 0x02 },
+ { 0x1f, 0xc9 },
+ /* output state selection */
+ { 0x15, 0x00 },
+ { 0x14, 0xef },
+ /* switch MUX to PLL1 output */
+ { 0x14, 0x6f },
+ { 0x16, 0x06 },
+ /* set P2DIV divider, P3DIV and input crystal */
+ { 0x17, 0x06 },
+ { 0x01, 0x00 },
+ { 0x05, 0x48 },
+ { 0x02, 0x80 },
+ /* enable and disable PLL */
+ { 0x02, 0xbc },
+ { 0x03, 0x01 },
+ { },
+};
+
+static struct cdce_reg cdce_y1_74250[] = {
+ { 0x13, 0x00 },
+ { 0x18, 0xaf },
+ { 0x19, 0x50 },
+ { 0x1a, 0x02 },
+ { 0x1b, 0xc9 },
+ { 0x1c, 0x00 },
+ { 0x1d, 0x40 },
+ { 0x1e, 0x02 },
+ { 0x1f, 0xc9 },
+ /* output state selection */
+ { 0x15, 0x00 },
+ { 0x14, 0xef },
+ /* switch MUX to PLL1 output */
+ { 0x14, 0x6f },
+ { 0x16, 0x06 },
+ /* set P2DIV divider, P3DIV and input crystal */
+ { 0x17, 0x06 },
+ { 0x01, 0x00 },
+ { 0x05, 0x48 },
+ { 0x02, 0x80 },
+ /* enable and disable PLL */
+ { 0x02, 0xbc },
+ { 0x03, 0x02 },
+ { },
+};
+
+static struct cdce_reg cdce_y1_27000[] = {
+ { 0x13, 0x00 },
+ { 0x18, 0x00 },
+ { 0x19, 0x40 },
+ { 0x1a, 0x02 },
+ { 0x1b, 0x08 },
+ { 0x1c, 0x00 },
+ { 0x1d, 0x40 },
+ { 0x1e, 0x02 },
+ { 0x1f, 0x08 },
+ { 0x15, 0x02 },
+ { 0x14, 0xed },
+ { 0x16, 0x01 },
+ { 0x17, 0x01 },
+ { 0x01, 0x00 },
+ { 0x05, 0x50 },
+ { 0x02, 0xb4 },
+ { 0x03, 0x01 },
+ { },
+};
+
+static struct cdce_freq cdce_y1_freqs[] = {
+ CDCE_FREQ_TABLE_ENTRY(1, 148500),
+ CDCE_FREQ_TABLE_ENTRY(1, 74250),
+ CDCE_FREQ_TABLE_ENTRY(1, 27000),
+};
+
+static struct cdce_reg cdce_y5_13500[] = {
+ { 0x27, 0x08 },
+ { 0x28, 0x00 },
+ { 0x29, 0x40 },
+ { 0x2a, 0x02 },
+ { 0x2b, 0x08 },
+ { 0x24, 0x6f },
+ { },
+};
+
+static struct cdce_reg cdce_y5_16875[] = {
+ { 0x27, 0x08 },
+ { 0x28, 0x9f },
+ { 0x29, 0xb0 },
+ { 0x2a, 0x02 },
+ { 0x2b, 0x89 },
+ { 0x24, 0x6f },
+ { },
+};
+
+static struct cdce_reg cdce_y5_27000[] = {
+ { 0x27, 0x04 },
+ { 0x28, 0x00 },
+ { 0x29, 0x40 },
+ { 0x2a, 0x02 },
+ { 0x2b, 0x08 },
+ { 0x24, 0x6f },
+ { },
+};
+static struct cdce_reg cdce_y5_54000[] = {
+ { 0x27, 0x04 },
+ { 0x28, 0xff },
+ { 0x29, 0x80 },
+ { 0x2a, 0x02 },
+ { 0x2b, 0x07 },
+ { 0x24, 0x6f },
+ { },
+};
+
+static struct cdce_reg cdce_y5_81000[] = {
+ { 0x27, 0x02 },
+ { 0x28, 0xbf },
+ { 0x29, 0xa0 },
+ { 0x2a, 0x03 },
+ { 0x2b, 0x0a },
+ { 0x24, 0x6f },
+ { },
+};
+
+static struct cdce_freq cdce_y5_freqs[] = {
+ CDCE_FREQ_TABLE_ENTRY(5, 13500),
+ CDCE_FREQ_TABLE_ENTRY(5, 16875),
+ CDCE_FREQ_TABLE_ENTRY(5, 27000),
+ CDCE_FREQ_TABLE_ENTRY(5, 54000),
+ CDCE_FREQ_TABLE_ENTRY(5, 81000),
+};
+
+
+static struct cdce_output output_list[] = {
+ [1] = { cdce_y1_freqs, ARRAY_SIZE(cdce_y1_freqs) },
+ [5] = { cdce_y5_freqs, ARRAY_SIZE(cdce_y5_freqs) },
+};
+
+int cdce_set_rate(struct clk *clk, unsigned long rate)
+{
+ int i, ret = 0;
+ struct cdce_freq *freq_table = output_list[clk->lpsc].freq_table;
+ struct cdce_reg *regs = NULL;
+
+ if (!cdce_i2c_client)
+ return -ENODEV;
+
+ if (!freq_table)
+ return -EINVAL;
+
+ for (i = 0; i < output_list[clk->lpsc].size; i++) {
+ if (freq_table[i].frequency == rate / 1000) {
+ regs = freq_table[i].reglist;
+ break;
+ }
+ }
+
+ if (!regs)
+ return -EINVAL;
+
+ mutex_lock(&cdce_mutex);
+ for (i = 0; regs[i].addr; i++) {
+ ret = i2c_smbus_write_byte_data(cdce_i2c_client,
+ regs[i].addr | 0x80, regs[i].val);
+ if (ret)
+ break;
+ }
+ mutex_unlock(&cdce_mutex);
+
+ if (!ret)
+ clk->rate = rate;
+
+ return ret;
+}
+
+static int cdce_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ cdce_i2c_client = client;
+ return 0;
+}
+
+static int __devexit cdce_remove(struct i2c_client *client)
+{
+ cdce_i2c_client = NULL;
+ return 0;
+}
+
+static const struct i2c_device_id cdce_id[] = {
+ {"cdce949", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, cdce_id);
+
+static struct i2c_driver cdce_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "cdce949",
+ },
+ .probe = cdce_probe,
+ .remove = __devexit_p(cdce_remove),
+ .id_table = cdce_id,
+};
+
+static int __init cdce_init(void)
+{
+ return i2c_add_driver(&cdce_driver);
+}
+subsys_initcall(cdce_init);
+
+static void __exit cdce_exit(void)
+{
+ i2c_del_driver(&cdce_driver);
+}
+module_exit(cdce_exit);
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("CDCE949 clock synthesizer driver");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
new file mode 100644
index 00000000..e4e3af17
--- /dev/null
+++ b/arch/arm/mach-davinci/clock.c
@@ -0,0 +1,641 @@
+/*
+ * Clock and PLL control for DaVinci devices
+ *
+ * Copyright (C) 2006-2007 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * 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/clk.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+
+#include <mach/clock.h>
+#include <mach/psc.h>
+#include <mach/cputype.h>
+#include "clock.h"
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+static DEFINE_SPINLOCK(clockfw_lock);
+
+static unsigned psc_domain(struct clk *clk)
+{
+ return (clk->flags & PSC_DSP)
+ ? DAVINCI_GPSC_DSPDOMAIN
+ : DAVINCI_GPSC_ARMDOMAIN;
+}
+
+static void __clk_enable(struct clk *clk)
+{
+ if (clk->parent)
+ __clk_enable(clk->parent);
+ if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
+ davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc,
+ PSC_STATE_ENABLE);
+}
+
+static void __clk_disable(struct clk *clk)
+{
+ if (WARN_ON(clk->usecount == 0))
+ return;
+ if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) &&
+ (clk->flags & CLK_PSC))
+ davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc,
+ (clk->flags & PSC_SWRSTDISABLE) ?
+ PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE);
+ if (clk->parent)
+ __clk_disable(clk->parent);
+}
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ __clk_enable(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ 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;
+
+ if (clk->round_rate)
+ return clk->round_rate(clk, rate);
+
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/* Propagate rate to children */
+static void propagate_rate(struct clk *root)
+{
+ struct clk *clk;
+
+ list_for_each_entry(clk, &root->children, childnode) {
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+ propagate_rate(clk);
+ }
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (clk == NULL || IS_ERR(clk))
+ return ret;
+
+ if (clk->set_rate)
+ ret = clk->set_rate(clk, rate);
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (ret == 0) {
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+ propagate_rate(clk);
+ }
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ unsigned long flags;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ /* Cannot change parent on enabled clock */
+ if (WARN_ON(clk->usecount))
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ clk->parent = parent;
+ list_del_init(&clk->childnode);
+ list_add(&clk->childnode, &clk->parent->children);
+ mutex_unlock(&clocks_mutex);
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+ propagate_rate(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+int clk_register(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if (WARN(clk->parent && !clk->parent->rate,
+ "CLK: %s parent %s has no rate!\n",
+ clk->name, clk->parent->name))
+ return -EINVAL;
+
+ INIT_LIST_HEAD(&clk->children);
+
+ mutex_lock(&clocks_mutex);
+ list_add_tail(&clk->node, &clocks);
+ if (clk->parent)
+ list_add_tail(&clk->childnode, &clk->parent->children);
+ mutex_unlock(&clocks_mutex);
+
+ /* If rate is already set, use it */
+ if (clk->rate)
+ return 0;
+
+ /* Else, see if there is a way to calculate it */
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+
+ /* Otherwise, default to parent rate */
+ else if (clk->parent)
+ clk->rate = clk->parent->rate;
+
+ 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);
+ list_del(&clk->childnode);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+#ifdef CONFIG_DAVINCI_RESET_CLOCKS
+/*
+ * Disable any unused clocks left on by the bootloader
+ */
+static int __init clk_disable_unused(void)
+{
+ struct clk *ck;
+
+ spin_lock_irq(&clockfw_lock);
+ list_for_each_entry(ck, &clocks, node) {
+ if (ck->usecount > 0)
+ continue;
+ if (!(ck->flags & CLK_PSC))
+ continue;
+
+ /* ignore if in Disabled or SwRstDisable states */
+ if (!davinci_psc_is_clk_active(ck->gpsc, ck->lpsc))
+ continue;
+
+ pr_debug("Clocks: disable unused %s\n", ck->name);
+
+ davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc,
+ (ck->flags & PSC_SWRSTDISABLE) ?
+ PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE);
+ }
+ spin_unlock_irq(&clockfw_lock);
+
+ return 0;
+}
+late_initcall(clk_disable_unused);
+#endif
+
+static unsigned long clk_sysclk_recalc(struct clk *clk)
+{
+ u32 v, plldiv;
+ struct pll_data *pll;
+ unsigned long rate = clk->rate;
+
+ /* If this is the PLL base clock, no more calculations needed */
+ if (clk->pll_data)
+ return rate;
+
+ if (WARN_ON(!clk->parent))
+ return rate;
+
+ rate = clk->parent->rate;
+
+ /* Otherwise, the parent must be a PLL */
+ if (WARN_ON(!clk->parent->pll_data))
+ return rate;
+
+ pll = clk->parent->pll_data;
+
+ /* If pre-PLL, source clock is before the multiplier and divider(s) */
+ if (clk->flags & PRE_PLL)
+ rate = pll->input_rate;
+
+ if (!clk->div_reg)
+ return rate;
+
+ v = __raw_readl(pll->base + clk->div_reg);
+ if (v & PLLDIV_EN) {
+ plldiv = (v & pll->div_ratio_mask) + 1;
+ if (plldiv)
+ rate /= plldiv;
+ }
+
+ return rate;
+}
+
+int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned v;
+ struct pll_data *pll;
+ unsigned long input;
+ unsigned ratio = 0;
+
+ /* If this is the PLL base clock, wrong function to call */
+ if (clk->pll_data)
+ return -EINVAL;
+
+ /* There must be a parent... */
+ if (WARN_ON(!clk->parent))
+ return -EINVAL;
+
+ /* ... the parent must be a PLL... */
+ if (WARN_ON(!clk->parent->pll_data))
+ return -EINVAL;
+
+ /* ... and this clock must have a divider. */
+ if (WARN_ON(!clk->div_reg))
+ return -EINVAL;
+
+ pll = clk->parent->pll_data;
+
+ input = clk->parent->rate;
+
+ /* If pre-PLL, source clock is before the multiplier and divider(s) */
+ if (clk->flags & PRE_PLL)
+ input = pll->input_rate;
+
+ if (input > rate) {
+ /*
+ * Can afford to provide an output little higher than requested
+ * only if maximum rate supported by hardware on this sysclk
+ * is known.
+ */
+ if (clk->maxrate) {
+ ratio = DIV_ROUND_CLOSEST(input, rate);
+ if (input / ratio > clk->maxrate)
+ ratio = 0;
+ }
+
+ if (ratio == 0)
+ ratio = DIV_ROUND_UP(input, rate);
+
+ ratio--;
+ }
+
+ if (ratio > pll->div_ratio_mask)
+ return -EINVAL;
+
+ do {
+ v = __raw_readl(pll->base + PLLSTAT);
+ } while (v & PLLSTAT_GOSTAT);
+
+ v = __raw_readl(pll->base + clk->div_reg);
+ v &= ~pll->div_ratio_mask;
+ v |= ratio | PLLDIV_EN;
+ __raw_writel(v, pll->base + clk->div_reg);
+
+ v = __raw_readl(pll->base + PLLCMD);
+ v |= PLLCMD_GOSET;
+ __raw_writel(v, pll->base + PLLCMD);
+
+ do {
+ v = __raw_readl(pll->base + PLLSTAT);
+ } while (v & PLLSTAT_GOSTAT);
+
+ return 0;
+}
+EXPORT_SYMBOL(davinci_set_sysclk_rate);
+
+static unsigned long clk_leafclk_recalc(struct clk *clk)
+{
+ if (WARN_ON(!clk->parent))
+ return clk->rate;
+
+ return clk->parent->rate;
+}
+
+static unsigned long clk_pllclk_recalc(struct clk *clk)
+{
+ u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
+ u8 bypass;
+ struct pll_data *pll = clk->pll_data;
+ unsigned long rate = clk->rate;
+
+ ctrl = __raw_readl(pll->base + PLLCTL);
+ rate = pll->input_rate = clk->parent->rate;
+
+ if (ctrl & PLLCTL_PLLEN) {
+ bypass = 0;
+ mult = __raw_readl(pll->base + PLLM);
+ if (cpu_is_davinci_dm365())
+ mult = 2 * (mult & PLLM_PLLM_MASK);
+ else
+ mult = (mult & PLLM_PLLM_MASK) + 1;
+ } else
+ bypass = 1;
+
+ if (pll->flags & PLL_HAS_PREDIV) {
+ prediv = __raw_readl(pll->base + PREDIV);
+ if (prediv & PLLDIV_EN)
+ prediv = (prediv & pll->div_ratio_mask) + 1;
+ else
+ prediv = 1;
+ }
+
+ /* pre-divider is fixed, but (some?) chips won't report that */
+ if (cpu_is_davinci_dm355() && pll->num == 1)
+ prediv = 8;
+
+ if (pll->flags & PLL_HAS_POSTDIV) {
+ postdiv = __raw_readl(pll->base + POSTDIV);
+ if (postdiv & PLLDIV_EN)
+ postdiv = (postdiv & pll->div_ratio_mask) + 1;
+ else
+ postdiv = 1;
+ }
+
+ if (!bypass) {
+ rate /= prediv;
+ rate *= mult;
+ rate /= postdiv;
+ }
+
+ pr_debug("PLL%d: input = %lu MHz [ ",
+ pll->num, clk->parent->rate / 1000000);
+ if (bypass)
+ pr_debug("bypass ");
+ if (prediv > 1)
+ pr_debug("/ %d ", prediv);
+ if (mult > 1)
+ pr_debug("* %d ", mult);
+ if (postdiv > 1)
+ pr_debug("/ %d ", postdiv);
+ pr_debug("] --> %lu MHz output.\n", rate / 1000000);
+
+ return rate;
+}
+
+/**
+ * davinci_set_pllrate - set the output rate of a given PLL.
+ *
+ * Note: Currently tested to work with OMAP-L138 only.
+ *
+ * @pll: pll whose rate needs to be changed.
+ * @prediv: The pre divider value. Passing 0 disables the pre-divider.
+ * @pllm: The multiplier value. Passing 0 leads to multiply-by-one.
+ * @postdiv: The post divider value. Passing 0 disables the post-divider.
+ */
+int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
+ unsigned int mult, unsigned int postdiv)
+{
+ u32 ctrl;
+ unsigned int locktime;
+ unsigned long flags;
+
+ if (pll->base == NULL)
+ return -EINVAL;
+
+ /*
+ * PLL lock time required per OMAP-L138 datasheet is
+ * (2000 * prediv)/sqrt(pllm) OSCIN cycles. We approximate sqrt(pllm)
+ * as 4 and OSCIN cycle as 25 MHz.
+ */
+ if (prediv) {
+ locktime = ((2000 * prediv) / 100);
+ prediv = (prediv - 1) | PLLDIV_EN;
+ } else {
+ locktime = PLL_LOCK_TIME;
+ }
+ if (postdiv)
+ postdiv = (postdiv - 1) | PLLDIV_EN;
+ if (mult)
+ mult = mult - 1;
+
+ /* Protect against simultaneous calls to PLL setting seqeunce */
+ spin_lock_irqsave(&clockfw_lock, flags);
+
+ ctrl = __raw_readl(pll->base + PLLCTL);
+
+ /* Switch the PLL to bypass mode */
+ ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
+ __raw_writel(ctrl, pll->base + PLLCTL);
+
+ udelay(PLL_BYPASS_TIME);
+
+ /* Reset and enable PLL */
+ ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
+ __raw_writel(ctrl, pll->base + PLLCTL);
+
+ if (pll->flags & PLL_HAS_PREDIV)
+ __raw_writel(prediv, pll->base + PREDIV);
+
+ __raw_writel(mult, pll->base + PLLM);
+
+ if (pll->flags & PLL_HAS_POSTDIV)
+ __raw_writel(postdiv, pll->base + POSTDIV);
+
+ udelay(PLL_RESET_TIME);
+
+ /* Bring PLL out of reset */
+ ctrl |= PLLCTL_PLLRST;
+ __raw_writel(ctrl, pll->base + PLLCTL);
+
+ udelay(locktime);
+
+ /* Remove PLL from bypass mode */
+ ctrl |= PLLCTL_PLLEN;
+ __raw_writel(ctrl, pll->base + PLLCTL);
+
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(davinci_set_pllrate);
+
+int __init davinci_clk_init(struct clk_lookup *clocks)
+ {
+ struct clk_lookup *c;
+ struct clk *clk;
+ size_t num_clocks = 0;
+
+ for (c = clocks; c->clk; c++) {
+ clk = c->clk;
+
+ if (!clk->recalc) {
+
+ /* Check if clock is a PLL */
+ if (clk->pll_data)
+ clk->recalc = clk_pllclk_recalc;
+
+ /* Else, if it is a PLL-derived clock */
+ else if (clk->flags & CLK_PLL)
+ clk->recalc = clk_sysclk_recalc;
+
+ /* Otherwise, it is a leaf clock (PSC clock) */
+ else if (clk->parent)
+ clk->recalc = clk_leafclk_recalc;
+ }
+
+ if (clk->pll_data) {
+ struct pll_data *pll = clk->pll_data;
+
+ if (!pll->div_ratio_mask)
+ pll->div_ratio_mask = PLLDIV_RATIO_MASK;
+
+ if (pll->phys_base && !pll->base) {
+ pll->base = ioremap(pll->phys_base, SZ_4K);
+ WARN_ON(!pll->base);
+ }
+ }
+
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+
+ if (clk->lpsc)
+ clk->flags |= CLK_PSC;
+
+ clk_register(clk);
+ num_clocks++;
+
+ /* Turn on clocks that Linux doesn't otherwise manage */
+ if (clk->flags & ALWAYS_ENABLED)
+ clk_enable(clk);
+ }
+
+ clkdev_add_table(clocks, num_clocks);
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#define CLKNAME_MAX 10 /* longest clock name */
+#define NEST_DELTA 2
+#define NEST_MAX 4
+
+static void
+dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
+{
+ char *state;
+ char buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX];
+ struct clk *clk;
+ unsigned i;
+
+ if (parent->flags & CLK_PLL)
+ state = "pll";
+ else if (parent->flags & CLK_PSC)
+ state = "psc";
+ else
+ state = "";
+
+ /* <nest spaces> name <pad to end> */
+ memset(buf, ' ', sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = 0;
+ i = strlen(parent->name);
+ memcpy(buf + nest, parent->name,
+ min(i, (unsigned)(sizeof(buf) - 1 - nest)));
+
+ seq_printf(s, "%s users=%2d %-3s %9ld Hz\n",
+ buf, parent->usecount, state, clk_get_rate(parent));
+ /* REVISIT show device associations too */
+
+ /* cost is now small, but not linear... */
+ list_for_each_entry(clk, &parent->children, childnode) {
+ dump_clock(s, nest + NEST_DELTA, clk);
+ }
+}
+
+static int davinci_ck_show(struct seq_file *m, void *v)
+{
+ struct clk *clk;
+
+ /*
+ * Show clock tree; We trust nonzero usecounts equate to PSC enables...
+ */
+ mutex_lock(&clocks_mutex);
+ list_for_each_entry(clk, &clocks, node)
+ if (!clk->parent)
+ dump_clock(m, 0, clk);
+ mutex_unlock(&clocks_mutex);
+
+ return 0;
+}
+
+static int davinci_ck_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, davinci_ck_show, NULL);
+}
+
+static const struct file_operations davinci_ck_operations = {
+ .open = davinci_ck_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init davinci_clk_debugfs_init(void)
+{
+ debugfs_create_file("davinci_clocks", S_IFREG | S_IRUGO, NULL, NULL,
+ &davinci_ck_operations);
+ return 0;
+
+}
+device_initcall(davinci_clk_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
new file mode 100644
index 00000000..0dd22031
--- /dev/null
+++ b/arch/arm/mach-davinci/clock.h
@@ -0,0 +1,132 @@
+/*
+ * TI DaVinci clock definitions
+ *
+ * Copyright (C) 2006-2007 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * 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
+
+#define DAVINCI_PLL1_BASE 0x01c40800
+#define DAVINCI_PLL2_BASE 0x01c40c00
+#define MAX_PLL 2
+
+/* PLL/Reset register offsets */
+#define PLLCTL 0x100
+#define PLLCTL_PLLEN BIT(0)
+#define PLLCTL_PLLPWRDN BIT(1)
+#define PLLCTL_PLLRST BIT(3)
+#define PLLCTL_PLLDIS BIT(4)
+#define PLLCTL_PLLENSRC BIT(5)
+#define PLLCTL_CLKMODE BIT(8)
+
+#define PLLM 0x110
+#define PLLM_PLLM_MASK 0xff
+
+#define PREDIV 0x114
+#define PLLDIV1 0x118
+#define PLLDIV2 0x11c
+#define PLLDIV3 0x120
+#define POSTDIV 0x128
+#define BPDIV 0x12c
+#define PLLCMD 0x138
+#define PLLSTAT 0x13c
+#define PLLALNCTL 0x140
+#define PLLDCHANGE 0x144
+#define PLLCKEN 0x148
+#define PLLCKSTAT 0x14c
+#define PLLSYSTAT 0x150
+#define PLLDIV4 0x160
+#define PLLDIV5 0x164
+#define PLLDIV6 0x168
+#define PLLDIV7 0x16c
+#define PLLDIV8 0x170
+#define PLLDIV9 0x174
+#define PLLDIV_EN BIT(15)
+#define PLLDIV_RATIO_MASK 0x1f
+
+/*
+ * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN
+ * cycles to ensure that the PLLC has switched to bypass mode. Delay of 1us
+ * ensures we are good for all > 4MHz OSCIN/CLKIN inputs. Typically the input
+ * is ~25MHz. Units are micro seconds.
+ */
+#define PLL_BYPASS_TIME 1
+/* From OMAP-L138 datasheet table 6-4. Units are micro seconds */
+#define PLL_RESET_TIME 1
+/*
+ * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4
+ * Units are micro seconds.
+ */
+#define PLL_LOCK_TIME 20
+
+#ifndef __ASSEMBLER__
+
+#include <linux/list.h>
+#include <linux/clkdev.h>
+
+#define PLLSTAT_GOSTAT BIT(0)
+#define PLLCMD_GOSET BIT(0)
+
+struct pll_data {
+ u32 phys_base;
+ void __iomem *base;
+ u32 num;
+ u32 flags;
+ u32 input_rate;
+ u32 div_ratio_mask;
+};
+#define PLL_HAS_PREDIV 0x01
+#define PLL_HAS_POSTDIV 0x02
+
+struct clk {
+ struct list_head node;
+ struct module *owner;
+ const char *name;
+ unsigned long rate;
+ unsigned long maxrate; /* H/W supported max rate */
+ u8 usecount;
+ u8 lpsc;
+ u8 gpsc;
+ u32 flags;
+ struct clk *parent;
+ struct list_head children; /* list of children */
+ struct list_head childnode; /* parent's child list node */
+ struct pll_data *pll_data;
+ u32 div_reg;
+ unsigned long (*recalc) (struct clk *);
+ int (*set_rate) (struct clk *clk, unsigned long rate);
+ int (*round_rate) (struct clk *clk, unsigned long rate);
+};
+
+/* Clock flags: SoC-specific flags start at BIT(16) */
+#define ALWAYS_ENABLED BIT(1)
+#define CLK_PSC BIT(2)
+#define PSC_DSP BIT(3) /* PSC uses DSP domain, not ARM */
+#define CLK_PLL BIT(4) /* PLL-derived clock */
+#define PRE_PLL BIT(5) /* source is before PLL mult/div */
+#define PSC_SWRSTDISABLE BIT(6) /* Disable state is SwRstDisable */
+
+#define CLK(dev, con, ck) \
+ { \
+ .dev_id = dev, \
+ .con_id = con, \
+ .clk = ck, \
+ } \
+
+int davinci_clk_init(struct clk_lookup *clocks);
+int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
+ unsigned int mult, unsigned int postdiv);
+int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate);
+
+extern struct platform_device davinci_wdt_device;
+extern void davinci_watchdog_reset(struct platform_device *);
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
new file mode 100644
index 00000000..1d255739
--- /dev/null
+++ b/arch/arm/mach-davinci/common.c
@@ -0,0 +1,119 @@
+/*
+ * Code commons to all DaVinci SoCs.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2009 (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/module.h>
+#include <linux/io.h>
+#include <linux/etherdevice.h>
+#include <linux/davinci_emac.h>
+
+#include <asm/tlb.h>
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/cputype.h>
+
+#include "clock.h"
+
+struct davinci_soc_info davinci_soc_info;
+EXPORT_SYMBOL(davinci_soc_info);
+
+void __iomem *davinci_intc_base;
+int davinci_intc_type;
+
+void davinci_get_mac_addr(struct memory_accessor *mem_acc, void *context)
+{
+ char *mac_addr = davinci_soc_info.emac_pdata->mac_addr;
+ off_t offset = (off_t)context;
+
+ /* Read MAC addr from EEPROM */
+ if (mem_acc->read(mem_acc, mac_addr, offset, ETH_ALEN) == ETH_ALEN)
+ pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr);
+}
+
+static int __init davinci_init_id(struct davinci_soc_info *soc_info)
+{
+ int i;
+ struct davinci_id *dip;
+ u8 variant;
+ u16 part_no;
+ void __iomem *base;
+
+ base = ioremap(soc_info->jtag_id_reg, SZ_4K);
+ if (!base) {
+ pr_err("Unable to map JTAG ID register\n");
+ return -ENOMEM;
+ }
+
+ soc_info->jtag_id = __raw_readl(base);
+ iounmap(base);
+
+ variant = (soc_info->jtag_id & 0xf0000000) >> 28;
+ part_no = (soc_info->jtag_id & 0x0ffff000) >> 12;
+
+ for (i = 0, dip = soc_info->ids; i < soc_info->ids_num;
+ i++, dip++)
+ /* Don't care about the manufacturer right now */
+ if ((dip->part_no == part_no) && (dip->variant == variant)) {
+ soc_info->cpu_id = dip->cpu_id;
+ pr_info("DaVinci %s variant 0x%x\n", dip->name,
+ dip->variant);
+ return 0;
+ }
+
+ pr_err("Unknown DaVinci JTAG ID 0x%x\n", soc_info->jtag_id);
+ return -EINVAL;
+}
+
+void __init davinci_common_init(struct davinci_soc_info *soc_info)
+{
+ int ret;
+
+ if (!soc_info) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ memcpy(&davinci_soc_info, soc_info, sizeof(struct davinci_soc_info));
+
+ if (davinci_soc_info.io_desc && (davinci_soc_info.io_desc_num > 0))
+ iotable_init(davinci_soc_info.io_desc,
+ davinci_soc_info.io_desc_num);
+
+ /*
+ * 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();
+
+ if (!davinci_soc_info.reset)
+ davinci_soc_info.reset = davinci_watchdog_reset;
+
+ /*
+ * We want to check CPU revision early for cpu_is_xxxx() macros.
+ * IO space mapping must be initialized before we can do that.
+ */
+ ret = davinci_init_id(&davinci_soc_info);
+ if (ret < 0)
+ goto err;
+
+ if (davinci_soc_info.cpu_clks) {
+ ret = davinci_clk_init(davinci_soc_info.cpu_clks);
+
+ if (ret != 0)
+ goto err;
+ }
+
+ return;
+
+err:
+ panic("davinci_common_init: SoC Initialization failed\n");
+}
diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c
new file mode 100644
index 00000000..f83152d6
--- /dev/null
+++ b/arch/arm/mach-davinci/cp_intc.c
@@ -0,0 +1,177 @@
+/*
+ * TI Common Platform Interrupt Controller (cp_intc) driver
+ *
+ * Author: Steve Chen <schen@mvista.com>
+ * Copyright (C) 2008-2009, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 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/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/common.h>
+#include <mach/cp_intc.h>
+
+static inline unsigned int cp_intc_read(unsigned offset)
+{
+ return __raw_readl(davinci_intc_base + offset);
+}
+
+static inline void cp_intc_write(unsigned long value, unsigned offset)
+{
+ __raw_writel(value, davinci_intc_base + offset);
+}
+
+static void cp_intc_ack_irq(struct irq_data *d)
+{
+ cp_intc_write(d->irq, CP_INTC_SYS_STAT_IDX_CLR);
+}
+
+/* Disable interrupt */
+static void cp_intc_mask_irq(struct irq_data *d)
+{
+ /* XXX don't know why we need to disable nIRQ here... */
+ cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_CLR);
+ cp_intc_write(d->irq, CP_INTC_SYS_ENABLE_IDX_CLR);
+ cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_SET);
+}
+
+/* Enable interrupt */
+static void cp_intc_unmask_irq(struct irq_data *d)
+{
+ cp_intc_write(d->irq, CP_INTC_SYS_ENABLE_IDX_SET);
+}
+
+static int cp_intc_set_irq_type(struct irq_data *d, unsigned int flow_type)
+{
+ unsigned reg = BIT_WORD(d->irq);
+ unsigned mask = BIT_MASK(d->irq);
+ unsigned polarity = cp_intc_read(CP_INTC_SYS_POLARITY(reg));
+ unsigned type = cp_intc_read(CP_INTC_SYS_TYPE(reg));
+
+ switch (flow_type) {
+ case IRQ_TYPE_EDGE_RISING:
+ polarity |= mask;
+ type |= mask;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ polarity &= ~mask;
+ type |= mask;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ polarity |= mask;
+ type &= ~mask;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ polarity &= ~mask;
+ type &= ~mask;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ cp_intc_write(polarity, CP_INTC_SYS_POLARITY(reg));
+ cp_intc_write(type, CP_INTC_SYS_TYPE(reg));
+
+ return 0;
+}
+
+/*
+ * Faking this allows us to to work with suspend functions of
+ * generic drivers which call {enable|disable}_irq_wake for
+ * wake up interrupt sources (eg RTC on DA850).
+ */
+static int cp_intc_set_wake(struct irq_data *d, unsigned int on)
+{
+ return 0;
+}
+
+static struct irq_chip cp_intc_irq_chip = {
+ .name = "cp_intc",
+ .irq_ack = cp_intc_ack_irq,
+ .irq_mask = cp_intc_mask_irq,
+ .irq_unmask = cp_intc_unmask_irq,
+ .irq_set_type = cp_intc_set_irq_type,
+ .irq_set_wake = cp_intc_set_wake,
+};
+
+void __init cp_intc_init(void)
+{
+ unsigned long num_irq = davinci_soc_info.intc_irq_num;
+ u8 *irq_prio = davinci_soc_info.intc_irq_prios;
+ u32 *host_map = davinci_soc_info.intc_host_map;
+ unsigned num_reg = BITS_TO_LONGS(num_irq);
+ int i;
+
+ davinci_intc_type = DAVINCI_INTC_TYPE_CP_INTC;
+ davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_8K);
+ if (WARN_ON(!davinci_intc_base))
+ return;
+
+ cp_intc_write(0, CP_INTC_GLOBAL_ENABLE);
+
+ /* Disable all host interrupts */
+ cp_intc_write(0, CP_INTC_HOST_ENABLE(0));
+
+ /* Disable system interrupts */
+ for (i = 0; i < num_reg; i++)
+ cp_intc_write(~0, CP_INTC_SYS_ENABLE_CLR(i));
+
+ /* Set to normal mode, no nesting, no priority hold */
+ cp_intc_write(0, CP_INTC_CTRL);
+ cp_intc_write(0, CP_INTC_HOST_CTRL);
+
+ /* Clear system interrupt status */
+ for (i = 0; i < num_reg; i++)
+ cp_intc_write(~0, CP_INTC_SYS_STAT_CLR(i));
+
+ /* Enable nIRQ (what about nFIQ?) */
+ cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_SET);
+
+ /*
+ * Priority is determined by host channel: lower channel number has
+ * higher priority i.e. channel 0 has highest priority and channel 31
+ * had the lowest priority.
+ */
+ num_reg = (num_irq + 3) >> 2; /* 4 channels per register */
+ if (irq_prio) {
+ unsigned j, k;
+ u32 val;
+
+ for (k = i = 0; i < num_reg; i++) {
+ for (val = j = 0; j < 4; j++, k++) {
+ val >>= 8;
+ if (k < num_irq)
+ val |= irq_prio[k] << 24;
+ }
+
+ cp_intc_write(val, CP_INTC_CHAN_MAP(i));
+ }
+ } else {
+ /*
+ * Default everything to channel 15 if priority not specified.
+ * Note that channel 0-1 are mapped to nFIQ and channels 2-31
+ * are mapped to nIRQ.
+ */
+ for (i = 0; i < num_reg; i++)
+ cp_intc_write(0x0f0f0f0f, CP_INTC_CHAN_MAP(i));
+ }
+
+ if (host_map)
+ for (i = 0; host_map[i] != -1; i++)
+ cp_intc_write(host_map[i], CP_INTC_HOST_MAP(i));
+
+ /* Set up genirq dispatching for cp_intc */
+ for (i = 0; i < num_irq; i++) {
+ irq_set_chip(i, &cp_intc_irq_chip);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ irq_set_handler(i, handle_edge_irq);
+ }
+
+ /* Enable global interrupt */
+ cp_intc_write(1, CP_INTC_GLOBAL_ENABLE);
+}
diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c
new file mode 100644
index 00000000..41669ecc
--- /dev/null
+++ b/arch/arm/mach-davinci/cpufreq.c
@@ -0,0 +1,248 @@
+/*
+ * CPU frequency scaling for DaVinci
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Based on linux/arch/arm/plat-omap/cpu-omap.c. Original Copyright follows:
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Updated to support OMAP3
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <mach/cpufreq.h>
+#include <mach/common.h>
+
+#include "clock.h"
+
+struct davinci_cpufreq {
+ struct device *dev;
+ struct clk *armclk;
+ struct clk *asyncclk;
+ unsigned long asyncrate;
+};
+static struct davinci_cpufreq cpufreq;
+
+static int davinci_verify_speed(struct cpufreq_policy *policy)
+{
+ struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
+ struct cpufreq_frequency_table *freq_table = pdata->freq_table;
+ struct clk *armclk = cpufreq.armclk;
+
+ if (freq_table)
+ return cpufreq_frequency_table_verify(policy, freq_table);
+
+ if (policy->cpu)
+ return -EINVAL;
+
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+
+ policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000;
+ policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000;
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+ return 0;
+}
+
+static unsigned int davinci_getspeed(unsigned int cpu)
+{
+ if (cpu)
+ return 0;
+
+ return clk_get_rate(cpufreq.armclk) / 1000;
+}
+
+static int davinci_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ int ret = 0;
+ unsigned int idx;
+ struct cpufreq_freqs freqs;
+ struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
+ struct clk *armclk = cpufreq.armclk;
+
+ /*
+ * Ensure desired rate is within allowed range. Some govenors
+ * (ondemand) will just pass target_freq=0 to get the minimum.
+ */
+ if (target_freq < policy->cpuinfo.min_freq)
+ target_freq = policy->cpuinfo.min_freq;
+ if (target_freq > policy->cpuinfo.max_freq)
+ target_freq = policy->cpuinfo.max_freq;
+
+ freqs.old = davinci_getspeed(0);
+ freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000;
+ freqs.cpu = 0;
+
+ if (freqs.old == freqs.new)
+ return ret;
+
+ dev_dbg(&cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new);
+
+ ret = cpufreq_frequency_table_target(policy, pdata->freq_table,
+ freqs.new, relation, &idx);
+ if (ret)
+ return -EINVAL;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ /* if moving to higher frequency, up the voltage beforehand */
+ if (pdata->set_voltage && freqs.new > freqs.old) {
+ ret = pdata->set_voltage(idx);
+ if (ret)
+ goto out;
+ }
+
+ ret = clk_set_rate(armclk, idx);
+ if (ret)
+ goto out;
+
+ if (cpufreq.asyncclk) {
+ ret = clk_set_rate(cpufreq.asyncclk, cpufreq.asyncrate);
+ if (ret)
+ goto out;
+ }
+
+ /* if moving to lower freq, lower the voltage after lowering freq */
+ if (pdata->set_voltage && freqs.new < freqs.old)
+ pdata->set_voltage(idx);
+
+out:
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return ret;
+}
+
+static int davinci_cpu_init(struct cpufreq_policy *policy)
+{
+ int result = 0;
+ struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
+ struct cpufreq_frequency_table *freq_table = pdata->freq_table;
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ /* Finish platform specific initialization */
+ if (pdata->init) {
+ result = pdata->init();
+ if (result)
+ return result;
+ }
+
+ policy->cur = policy->min = policy->max = davinci_getspeed(0);
+
+ if (freq_table) {
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (!result)
+ cpufreq_frequency_table_get_attr(freq_table,
+ policy->cpu);
+ } else {
+ policy->cpuinfo.min_freq = policy->min;
+ policy->cpuinfo.max_freq = policy->max;
+ }
+
+ policy->min = policy->cpuinfo.min_freq;
+ policy->max = policy->cpuinfo.max_freq;
+ policy->cur = davinci_getspeed(0);
+
+ /*
+ * Time measurement across the target() function yields ~1500-1800us
+ * time taken with no drivers on notification list.
+ * Setting the latency to 2000 us to accommodate addition of drivers
+ * to pre/post change notification list.
+ */
+ policy->cpuinfo.transition_latency = 2000 * 1000;
+ return 0;
+}
+
+static int davinci_cpu_exit(struct cpufreq_policy *policy)
+{
+ cpufreq_frequency_table_put_attr(policy->cpu);
+ return 0;
+}
+
+static struct freq_attr *davinci_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver davinci_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = davinci_verify_speed,
+ .target = davinci_target,
+ .get = davinci_getspeed,
+ .init = davinci_cpu_init,
+ .exit = davinci_cpu_exit,
+ .name = "davinci",
+ .attr = davinci_cpufreq_attr,
+};
+
+static int __init davinci_cpufreq_probe(struct platform_device *pdev)
+{
+ struct davinci_cpufreq_config *pdata = pdev->dev.platform_data;
+ struct clk *asyncclk;
+
+ if (!pdata)
+ return -EINVAL;
+ if (!pdata->freq_table)
+ return -EINVAL;
+
+ cpufreq.dev = &pdev->dev;
+
+ cpufreq.armclk = clk_get(NULL, "arm");
+ if (IS_ERR(cpufreq.armclk)) {
+ dev_err(cpufreq.dev, "Unable to get ARM clock\n");
+ return PTR_ERR(cpufreq.armclk);
+ }
+
+ asyncclk = clk_get(cpufreq.dev, "async");
+ if (!IS_ERR(asyncclk)) {
+ cpufreq.asyncclk = asyncclk;
+ cpufreq.asyncrate = clk_get_rate(asyncclk);
+ }
+
+ return cpufreq_register_driver(&davinci_driver);
+}
+
+static int __exit davinci_cpufreq_remove(struct platform_device *pdev)
+{
+ clk_put(cpufreq.armclk);
+
+ if (cpufreq.asyncclk)
+ clk_put(cpufreq.asyncclk);
+
+ return cpufreq_unregister_driver(&davinci_driver);
+}
+
+static struct platform_driver davinci_cpufreq_driver = {
+ .driver = {
+ .name = "cpufreq-davinci",
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(davinci_cpufreq_remove),
+};
+
+static int __init davinci_cpufreq_init(void)
+{
+ return platform_driver_probe(&davinci_cpufreq_driver,
+ davinci_cpufreq_probe);
+}
+late_initcall(davinci_cpufreq_init);
+
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
new file mode 100644
index 00000000..bd59f31b
--- /dev/null
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -0,0 +1,169 @@
+/*
+ * CPU idle for DaVinci SoCs
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated. http://www.ti.com/
+ *
+ * Derived from Marvell Kirkwood CPU idle code
+ * (arch/arm/mach-kirkwood/cpuidle.c)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+
+#include <mach/cpuidle.h>
+#include <mach/memory.h>
+
+#define DAVINCI_CPUIDLE_MAX_STATES 2
+
+struct davinci_ops {
+ void (*enter) (u32 flags);
+ void (*exit) (u32 flags);
+ u32 flags;
+};
+
+/* fields in davinci_ops.flags */
+#define DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN BIT(0)
+
+static struct cpuidle_driver davinci_idle_driver = {
+ .name = "cpuidle-davinci",
+ .owner = THIS_MODULE,
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device);
+static void __iomem *ddr2_reg_base;
+
+static void davinci_save_ddr_power(int enter, bool pdown)
+{
+ u32 val;
+
+ val = __raw_readl(ddr2_reg_base + DDR2_SDRCR_OFFSET);
+
+ if (enter) {
+ if (pdown)
+ val |= DDR2_SRPD_BIT;
+ else
+ val &= ~DDR2_SRPD_BIT;
+ val |= DDR2_LPMODEN_BIT;
+ } else {
+ val &= ~(DDR2_SRPD_BIT | DDR2_LPMODEN_BIT);
+ }
+
+ __raw_writel(val, ddr2_reg_base + DDR2_SDRCR_OFFSET);
+}
+
+static void davinci_c2state_enter(u32 flags)
+{
+ davinci_save_ddr_power(1, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN));
+}
+
+static void davinci_c2state_exit(u32 flags)
+{
+ davinci_save_ddr_power(0, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN));
+}
+
+static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
+ [1] = {
+ .enter = davinci_c2state_enter,
+ .exit = davinci_c2state_exit,
+ },
+};
+
+/* Actual code that puts the SoC in different idle states */
+static int davinci_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct davinci_ops *ops = cpuidle_get_statedata(state);
+ struct timeval before, after;
+ int idle_time;
+
+ local_irq_disable();
+ do_gettimeofday(&before);
+
+ if (ops && ops->enter)
+ ops->enter(ops->flags);
+ /* Wait for interrupt state */
+ cpu_do_idle();
+ if (ops && ops->exit)
+ ops->exit(ops->flags);
+
+ do_gettimeofday(&after);
+ local_irq_enable();
+ idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+ (after.tv_usec - before.tv_usec);
+ return idle_time;
+}
+
+static int __init davinci_cpuidle_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct cpuidle_device *device;
+ struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
+
+ device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "cannot get platform data\n");
+ return -ENOENT;
+ }
+
+ ddr2_reg_base = pdata->ddr2_ctlr_base;
+
+ ret = cpuidle_register_driver(&davinci_idle_driver);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register driver\n");
+ return ret;
+ }
+
+ /* Wait for interrupt state */
+ device->states[0].enter = davinci_enter_idle;
+ device->states[0].exit_latency = 1;
+ device->states[0].target_residency = 10000;
+ device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+ strcpy(device->states[0].name, "WFI");
+ strcpy(device->states[0].desc, "Wait for interrupt");
+
+ /* Wait for interrupt and DDR self refresh state */
+ device->states[1].enter = davinci_enter_idle;
+ device->states[1].exit_latency = 10;
+ device->states[1].target_residency = 10000;
+ device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+ strcpy(device->states[1].name, "DDR SR");
+ strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
+ if (pdata->ddr2_pdown)
+ davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
+ cpuidle_set_statedata(&device->states[1], &davinci_states[1]);
+
+ device->state_count = DAVINCI_CPUIDLE_MAX_STATES;
+
+ ret = cpuidle_register_device(device);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register device\n");
+ cpuidle_unregister_driver(&davinci_idle_driver);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct platform_driver davinci_cpuidle_driver = {
+ .driver = {
+ .name = "cpuidle-davinci",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init davinci_cpuidle_init(void)
+{
+ return platform_driver_probe(&davinci_cpuidle_driver,
+ davinci_cpuidle_probe);
+}
+device_initcall(davinci_cpuidle_init);
+
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
new file mode 100644
index 00000000..2ed2f822
--- /dev/null
+++ b/arch/arm/mach-davinci/da830.c
@@ -0,0 +1,1212 @@
+/*
+ * TI DA830/OMAP L137 chip specific setup
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2009 (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/init.h>
+#include <linux/clk.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/psc.h>
+#include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <mach/common.h>
+#include <mach/time.h>
+#include <mach/da8xx.h>
+#include <mach/gpio.h>
+
+#include "clock.h"
+#include "mux.h"
+
+/* Offsets of the 8 compare registers on the da830 */
+#define DA830_CMP12_0 0x60
+#define DA830_CMP12_1 0x64
+#define DA830_CMP12_2 0x68
+#define DA830_CMP12_3 0x6c
+#define DA830_CMP12_4 0x70
+#define DA830_CMP12_5 0x74
+#define DA830_CMP12_6 0x78
+#define DA830_CMP12_7 0x7c
+
+#define DA830_REF_FREQ 24000000
+
+static struct pll_data pll0_data = {
+ .num = 1,
+ .phys_base = DA8XX_PLL0_BASE,
+ .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
+};
+
+static struct clk ref_clk = {
+ .name = "ref_clk",
+ .rate = DA830_REF_FREQ,
+};
+
+static struct clk pll0_clk = {
+ .name = "pll0",
+ .parent = &ref_clk,
+ .pll_data = &pll0_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll0_aux_clk = {
+ .name = "pll0_aux_clk",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll0_sysclk2 = {
+ .name = "pll0_sysclk2",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll0_sysclk3 = {
+ .name = "pll0_sysclk3",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll0_sysclk4 = {
+ .name = "pll0_sysclk4",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll0_sysclk5 = {
+ .name = "pll0_sysclk5",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll0_sysclk6 = {
+ .name = "pll0_sysclk6",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV6,
+};
+
+static struct clk pll0_sysclk7 = {
+ .name = "pll0_sysclk7",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV7,
+};
+
+static struct clk i2c0_clk = {
+ .name = "i2c0",
+ .parent = &pll0_aux_clk,
+};
+
+static struct clk timerp64_0_clk = {
+ .name = "timer0",
+ .parent = &pll0_aux_clk,
+};
+
+static struct clk timerp64_1_clk = {
+ .name = "timer1",
+ .parent = &pll0_aux_clk,
+};
+
+static struct clk arm_rom_clk = {
+ .name = "arm_rom",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_ARM_RAM_ROM,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk scr0_ss_clk = {
+ .name = "scr0_ss",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_SCR0_SS,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk scr1_ss_clk = {
+ .name = "scr1_ss",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_SCR1_SS,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk scr2_ss_clk = {
+ .name = "scr2_ss",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_SCR2_SS,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk dmax_clk = {
+ .name = "dmax",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_PRUSS,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk tpcc_clk = {
+ .name = "tpcc",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_TPCC,
+ .flags = ALWAYS_ENABLED | CLK_PSC,
+};
+
+static struct clk tptc0_clk = {
+ .name = "tptc0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_TPTC0,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk tptc1_clk = {
+ .name = "tptc1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_TPTC1,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk mmcsd_clk = {
+ .name = "mmcsd",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_MMC_SD,
+};
+
+static struct clk uart0_clk = {
+ .name = "uart0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_UART0,
+};
+
+static struct clk uart1_clk = {
+ .name = "uart1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_UART1,
+ .gpsc = 1,
+};
+
+static struct clk uart2_clk = {
+ .name = "uart2",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_UART2,
+ .gpsc = 1,
+};
+
+static struct clk spi0_clk = {
+ .name = "spi0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_SPI0,
+};
+
+static struct clk spi1_clk = {
+ .name = "spi1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_SPI1,
+ .gpsc = 1,
+};
+
+static struct clk ecap0_clk = {
+ .name = "ecap0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_ECAP,
+ .gpsc = 1,
+};
+
+static struct clk ecap1_clk = {
+ .name = "ecap1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_ECAP,
+ .gpsc = 1,
+};
+
+static struct clk ecap2_clk = {
+ .name = "ecap2",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_ECAP,
+ .gpsc = 1,
+};
+
+static struct clk pwm0_clk = {
+ .name = "pwm0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_PWM,
+ .gpsc = 1,
+};
+
+static struct clk pwm1_clk = {
+ .name = "pwm1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_PWM,
+ .gpsc = 1,
+};
+
+static struct clk pwm2_clk = {
+ .name = "pwm2",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_PWM,
+ .gpsc = 1,
+};
+
+static struct clk eqep0_clk = {
+ .name = "eqep0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA830_LPSC1_EQEP,
+ .gpsc = 1,
+};
+
+static struct clk eqep1_clk = {
+ .name = "eqep1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA830_LPSC1_EQEP,
+ .gpsc = 1,
+};
+
+static struct clk lcdc_clk = {
+ .name = "lcdc",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_LCDC,
+ .gpsc = 1,
+};
+
+static struct clk mcasp0_clk = {
+ .name = "mcasp0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_McASP0,
+ .gpsc = 1,
+};
+
+static struct clk mcasp1_clk = {
+ .name = "mcasp1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA830_LPSC1_McASP1,
+ .gpsc = 1,
+};
+
+static struct clk mcasp2_clk = {
+ .name = "mcasp2",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA830_LPSC1_McASP2,
+ .gpsc = 1,
+};
+
+static struct clk usb20_clk = {
+ .name = "usb20",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_USB20,
+ .gpsc = 1,
+};
+
+static struct clk aemif_clk = {
+ .name = "aemif",
+ .parent = &pll0_sysclk3,
+ .lpsc = DA8XX_LPSC0_EMIF25,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk aintc_clk = {
+ .name = "aintc",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC0_AINTC,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk secu_mgr_clk = {
+ .name = "secu_mgr",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC0_SECU_MGR,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk emac_clk = {
+ .name = "emac",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_CPGMAC,
+ .gpsc = 1,
+};
+
+static struct clk gpio_clk = {
+ .name = "gpio",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_GPIO,
+ .gpsc = 1,
+};
+
+static struct clk i2c1_clk = {
+ .name = "i2c1",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_I2C,
+ .gpsc = 1,
+};
+
+static struct clk usb11_clk = {
+ .name = "usb11",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_USB11,
+ .gpsc = 1,
+};
+
+static struct clk emif3_clk = {
+ .name = "emif3",
+ .parent = &pll0_sysclk5,
+ .lpsc = DA8XX_LPSC1_EMIF3C,
+ .gpsc = 1,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk arm_clk = {
+ .name = "arm",
+ .parent = &pll0_sysclk6,
+ .lpsc = DA8XX_LPSC0_ARM,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk rmii_clk = {
+ .name = "rmii",
+ .parent = &pll0_sysclk7,
+};
+
+static struct clk_lookup da830_clks[] = {
+ CLK(NULL, "ref", &ref_clk),
+ CLK(NULL, "pll0", &pll0_clk),
+ CLK(NULL, "pll0_aux", &pll0_aux_clk),
+ CLK(NULL, "pll0_sysclk2", &pll0_sysclk2),
+ CLK(NULL, "pll0_sysclk3", &pll0_sysclk3),
+ CLK(NULL, "pll0_sysclk4", &pll0_sysclk4),
+ CLK(NULL, "pll0_sysclk5", &pll0_sysclk5),
+ CLK(NULL, "pll0_sysclk6", &pll0_sysclk6),
+ CLK(NULL, "pll0_sysclk7", &pll0_sysclk7),
+ CLK("i2c_davinci.1", NULL, &i2c0_clk),
+ CLK(NULL, "timer0", &timerp64_0_clk),
+ CLK("watchdog", NULL, &timerp64_1_clk),
+ CLK(NULL, "arm_rom", &arm_rom_clk),
+ CLK(NULL, "scr0_ss", &scr0_ss_clk),
+ CLK(NULL, "scr1_ss", &scr1_ss_clk),
+ CLK(NULL, "scr2_ss", &scr2_ss_clk),
+ CLK(NULL, "dmax", &dmax_clk),
+ CLK(NULL, "tpcc", &tpcc_clk),
+ CLK(NULL, "tptc0", &tptc0_clk),
+ CLK(NULL, "tptc1", &tptc1_clk),
+ CLK("davinci_mmc.0", NULL, &mmcsd_clk),
+ CLK(NULL, "uart0", &uart0_clk),
+ CLK(NULL, "uart1", &uart1_clk),
+ CLK(NULL, "uart2", &uart2_clk),
+ CLK("spi_davinci.0", NULL, &spi0_clk),
+ CLK("spi_davinci.1", NULL, &spi1_clk),
+ CLK(NULL, "ecap0", &ecap0_clk),
+ CLK(NULL, "ecap1", &ecap1_clk),
+ CLK(NULL, "ecap2", &ecap2_clk),
+ CLK(NULL, "pwm0", &pwm0_clk),
+ CLK(NULL, "pwm1", &pwm1_clk),
+ CLK(NULL, "pwm2", &pwm2_clk),
+ CLK("eqep.0", NULL, &eqep0_clk),
+ CLK("eqep.1", NULL, &eqep1_clk),
+ CLK("da8xx_lcdc.0", NULL, &lcdc_clk),
+ CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
+ CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
+ CLK("davinci-mcasp.2", NULL, &mcasp2_clk),
+ CLK(NULL, "usb20", &usb20_clk),
+ CLK(NULL, "aemif", &aemif_clk),
+ CLK(NULL, "aintc", &aintc_clk),
+ CLK(NULL, "secu_mgr", &secu_mgr_clk),
+ CLK("davinci_emac.1", NULL, &emac_clk),
+ CLK(NULL, "gpio", &gpio_clk),
+ CLK("i2c_davinci.2", NULL, &i2c1_clk),
+ CLK(NULL, "usb11", &usb11_clk),
+ CLK(NULL, "emif3", &emif3_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "rmii", &rmii_clk),
+ CLK(NULL, NULL, NULL),
+};
+
+/*
+ * Device specific mux setup
+ *
+ * soc description mux mode mode mux dbg
+ * reg offset mask mode
+ */
+static const struct mux_config da830_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+ MUX_CFG(DA830, GPIO7_14, 0, 0, 0xf, 1, false)
+ MUX_CFG(DA830, RTCK, 0, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_15, 0, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMU_0, 0, 4, 0xf, 8, false)
+ MUX_CFG(DA830, EMB_SDCKE, 0, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_CLK_GLUE, 0, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_CLK, 0, 12, 0xf, 2, false)
+ MUX_CFG(DA830, NEMB_CS_0, 0, 16, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_CAS, 0, 20, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_RAS, 0, 24, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_WE, 0, 28, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_BA_1, 1, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_BA_0, 1, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_0, 1, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_1, 1, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_2, 1, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_3, 1, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_4, 1, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_5, 1, 28, 0xf, 1, false)
+ MUX_CFG(DA830, GPIO7_0, 1, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_1, 1, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_2, 1, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_3, 1, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_4, 1, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_5, 1, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_6, 1, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_7, 1, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMB_A_6, 2, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_7, 2, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_8, 2, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_9, 2, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_10, 2, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_11, 2, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_12, 2, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_31, 2, 28, 0xf, 1, false)
+ MUX_CFG(DA830, GPIO7_8, 2, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_9, 2, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_10, 2, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_11, 2, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_12, 2, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_13, 2, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_13, 2, 24, 0xf, 8, false)
+ MUX_CFG(DA830, EMB_D_30, 3, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_29, 3, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_28, 3, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_27, 3, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_26, 3, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_25, 3, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_24, 3, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_23, 3, 28, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_22, 4, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_21, 4, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_20, 4, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_19, 4, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_18, 4, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_17, 4, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_16, 4, 24, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_WE_DQM_3, 4, 28, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_WE_DQM_2, 5, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_0, 5, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_1, 5, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_2, 5, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_3, 5, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_4, 5, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_5, 5, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_6, 5, 28, 0xf, 1, false)
+ MUX_CFG(DA830, GPIO6_0, 5, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_1, 5, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_2, 5, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_3, 5, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_4, 5, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_5, 5, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_6, 5, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMB_D_7, 6, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_8, 6, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_9, 6, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_10, 6, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_11, 6, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_12, 6, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_13, 6, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_14, 6, 28, 0xf, 1, false)
+ MUX_CFG(DA830, GPIO6_7, 6, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_8, 6, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_9, 6, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_10, 6, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_11, 6, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_12, 6, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_13, 6, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_14, 6, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMB_D_15, 7, 0, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_WE_DQM_1, 7, 4, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_WE_DQM_0, 7, 8, 0xf, 1, false)
+ MUX_CFG(DA830, SPI0_SOMI_0, 7, 12, 0xf, 1, false)
+ MUX_CFG(DA830, SPI0_SIMO_0, 7, 16, 0xf, 1, false)
+ MUX_CFG(DA830, SPI0_CLK, 7, 20, 0xf, 1, false)
+ MUX_CFG(DA830, NSPI0_ENA, 7, 24, 0xf, 1, false)
+ MUX_CFG(DA830, NSPI0_SCS_0, 7, 28, 0xf, 1, false)
+ MUX_CFG(DA830, EQEP0I, 7, 12, 0xf, 2, false)
+ MUX_CFG(DA830, EQEP0S, 7, 16, 0xf, 2, false)
+ MUX_CFG(DA830, EQEP1I, 7, 20, 0xf, 2, false)
+ MUX_CFG(DA830, NUART0_CTS, 7, 24, 0xf, 2, false)
+ MUX_CFG(DA830, NUART0_RTS, 7, 28, 0xf, 2, false)
+ MUX_CFG(DA830, EQEP0A, 7, 24, 0xf, 4, false)
+ MUX_CFG(DA830, EQEP0B, 7, 28, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO6_15, 7, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_14, 7, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_15, 7, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_0, 7, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_1, 7, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_2, 7, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_3, 7, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_4, 7, 28, 0xf, 8, false)
+ MUX_CFG(DA830, SPI1_SOMI_0, 8, 0, 0xf, 1, false)
+ MUX_CFG(DA830, SPI1_SIMO_0, 8, 4, 0xf, 1, false)
+ MUX_CFG(DA830, SPI1_CLK, 8, 8, 0xf, 1, false)
+ MUX_CFG(DA830, UART0_RXD, 8, 12, 0xf, 1, false)
+ MUX_CFG(DA830, UART0_TXD, 8, 16, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_10, 8, 20, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_11, 8, 24, 0xf, 1, false)
+ MUX_CFG(DA830, NSPI1_ENA, 8, 28, 0xf, 1, false)
+ MUX_CFG(DA830, I2C1_SCL, 8, 0, 0xf, 2, false)
+ MUX_CFG(DA830, I2C1_SDA, 8, 4, 0xf, 2, false)
+ MUX_CFG(DA830, EQEP1S, 8, 8, 0xf, 2, false)
+ MUX_CFG(DA830, I2C0_SDA, 8, 12, 0xf, 2, false)
+ MUX_CFG(DA830, I2C0_SCL, 8, 16, 0xf, 2, false)
+ MUX_CFG(DA830, UART2_RXD, 8, 28, 0xf, 2, false)
+ MUX_CFG(DA830, TM64P0_IN12, 8, 12, 0xf, 4, false)
+ MUX_CFG(DA830, TM64P0_OUT12, 8, 16, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO5_5, 8, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_6, 8, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_7, 8, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_8, 8, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_9, 8, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_10, 8, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_11, 8, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_12, 8, 28, 0xf, 8, false)
+ MUX_CFG(DA830, NSPI1_SCS_0, 9, 0, 0xf, 1, false)
+ MUX_CFG(DA830, USB0_DRVVBUS, 9, 4, 0xf, 1, false)
+ MUX_CFG(DA830, AHCLKX0, 9, 8, 0xf, 1, false)
+ MUX_CFG(DA830, ACLKX0, 9, 12, 0xf, 1, false)
+ MUX_CFG(DA830, AFSX0, 9, 16, 0xf, 1, false)
+ MUX_CFG(DA830, AHCLKR0, 9, 20, 0xf, 1, false)
+ MUX_CFG(DA830, ACLKR0, 9, 24, 0xf, 1, false)
+ MUX_CFG(DA830, AFSR0, 9, 28, 0xf, 1, false)
+ MUX_CFG(DA830, UART2_TXD, 9, 0, 0xf, 2, false)
+ MUX_CFG(DA830, AHCLKX2, 9, 8, 0xf, 2, false)
+ MUX_CFG(DA830, ECAP0_APWM0, 9, 12, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_MHZ_50_CLK, 9, 20, 0xf, 2, false)
+ MUX_CFG(DA830, ECAP1_APWM1, 9, 24, 0xf, 2, false)
+ MUX_CFG(DA830, USB_REFCLKIN, 9, 8, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO5_13, 9, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_15, 9, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_11, 9, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_12, 9, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_13, 9, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_14, 9, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_15, 9, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_12, 9, 28, 0xf, 8, false)
+ MUX_CFG(DA830, AMUTE0, 10, 0, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_0, 10, 4, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_1, 10, 8, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_2, 10, 12, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_3, 10, 16, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_4, 10, 20, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_5, 10, 24, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_6, 10, 28, 0xf, 1, false)
+ MUX_CFG(DA830, RMII_TXD_0, 10, 4, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_TXD_1, 10, 8, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_TXEN, 10, 12, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_CRS_DV, 10, 16, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_RXD_0, 10, 20, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_RXD_1, 10, 24, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_RXER, 10, 28, 0xf, 2, false)
+ MUX_CFG(DA830, AFSR2, 10, 4, 0xf, 4, false)
+ MUX_CFG(DA830, ACLKX2, 10, 8, 0xf, 4, false)
+ MUX_CFG(DA830, AXR2_3, 10, 12, 0xf, 4, false)
+ MUX_CFG(DA830, AXR2_2, 10, 16, 0xf, 4, false)
+ MUX_CFG(DA830, AXR2_1, 10, 20, 0xf, 4, false)
+ MUX_CFG(DA830, AFSX2, 10, 24, 0xf, 4, false)
+ MUX_CFG(DA830, ACLKR2, 10, 28, 0xf, 4, false)
+ MUX_CFG(DA830, NRESETOUT, 10, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_0, 10, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_1, 10, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_2, 10, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_3, 10, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_4, 10, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_5, 10, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_6, 10, 28, 0xf, 8, false)
+ MUX_CFG(DA830, AXR0_7, 11, 0, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_8, 11, 4, 0xf, 1, false)
+ MUX_CFG(DA830, UART1_RXD, 11, 8, 0xf, 1, false)
+ MUX_CFG(DA830, UART1_TXD, 11, 12, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_11, 11, 16, 0xf, 1, false)
+ MUX_CFG(DA830, AHCLKX1, 11, 20, 0xf, 1, false)
+ MUX_CFG(DA830, ACLKX1, 11, 24, 0xf, 1, false)
+ MUX_CFG(DA830, AFSX1, 11, 28, 0xf, 1, false)
+ MUX_CFG(DA830, MDIO_CLK, 11, 0, 0xf, 2, false)
+ MUX_CFG(DA830, MDIO_D, 11, 4, 0xf, 2, false)
+ MUX_CFG(DA830, AXR0_9, 11, 8, 0xf, 2, false)
+ MUX_CFG(DA830, AXR0_10, 11, 12, 0xf, 2, false)
+ MUX_CFG(DA830, EPWM0B, 11, 20, 0xf, 2, false)
+ MUX_CFG(DA830, EPWM0A, 11, 24, 0xf, 2, false)
+ MUX_CFG(DA830, EPWMSYNCI, 11, 28, 0xf, 2, false)
+ MUX_CFG(DA830, AXR2_0, 11, 16, 0xf, 4, false)
+ MUX_CFG(DA830, EPWMSYNC0, 11, 28, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO3_7, 11, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_8, 11, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_9, 11, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_10, 11, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_11, 11, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_14, 11, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_15, 11, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_10, 11, 28, 0xf, 8, false)
+ MUX_CFG(DA830, AHCLKR1, 12, 0, 0xf, 1, false)
+ MUX_CFG(DA830, ACLKR1, 12, 4, 0xf, 1, false)
+ MUX_CFG(DA830, AFSR1, 12, 8, 0xf, 1, false)
+ MUX_CFG(DA830, AMUTE1, 12, 12, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_0, 12, 16, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_1, 12, 20, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_2, 12, 24, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_3, 12, 28, 0xf, 1, false)
+ MUX_CFG(DA830, ECAP2_APWM2, 12, 4, 0xf, 2, false)
+ MUX_CFG(DA830, EHRPWMGLUETZ, 12, 12, 0xf, 2, false)
+ MUX_CFG(DA830, EQEP1A, 12, 28, 0xf, 2, false)
+ MUX_CFG(DA830, GPIO4_11, 12, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_12, 12, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_13, 12, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_14, 12, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_0, 12, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_1, 12, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_2, 12, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_3, 12, 28, 0xf, 8, false)
+ MUX_CFG(DA830, AXR1_4, 13, 0, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_5, 13, 4, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_6, 13, 8, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_7, 13, 12, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_8, 13, 16, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_9, 13, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_0, 13, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_1, 13, 28, 0xf, 1, false)
+ MUX_CFG(DA830, EQEP1B, 13, 0, 0xf, 2, false)
+ MUX_CFG(DA830, EPWM2B, 13, 4, 0xf, 2, false)
+ MUX_CFG(DA830, EPWM2A, 13, 8, 0xf, 2, false)
+ MUX_CFG(DA830, EPWM1B, 13, 12, 0xf, 2, false)
+ MUX_CFG(DA830, EPWM1A, 13, 16, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_0, 13, 24, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_1, 13, 28, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_0, 13, 24, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HD_1, 13, 28, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO4_4, 13, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_5, 13, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_6, 13, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_7, 13, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_8, 13, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_9, 13, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_0, 13, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_1, 13, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMA_D_2, 14, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_3, 14, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_4, 14, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_5, 14, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_6, 14, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_7, 14, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_8, 14, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_9, 14, 28, 0xf, 1, false)
+ MUX_CFG(DA830, MMCSD_DAT_2, 14, 0, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_3, 14, 4, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_4, 14, 8, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_5, 14, 12, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_6, 14, 16, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_7, 14, 20, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_8, 14, 24, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_9, 14, 28, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_2, 14, 0, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HD_3, 14, 4, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HD_4, 14, 8, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HD_5, 14, 12, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HD_6, 14, 16, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HD_7, 14, 20, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_8, 14, 24, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_9, 14, 28, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO0_2, 14, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_3, 14, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_4, 14, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_5, 14, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_6, 14, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_7, 14, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_8, 14, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_9, 14, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMA_D_10, 15, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_11, 15, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_12, 15, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_13, 15, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_14, 15, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_15, 15, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_0, 15, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_1, 15, 28, 0xf, 1, false)
+ MUX_CFG(DA830, UHPI_HD_10, 15, 0, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_11, 15, 4, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_12, 15, 8, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_13, 15, 12, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_14, 15, 16, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_15, 15, 20, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_7, 15, 24, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_CLK, 15, 28, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_10, 15, 0, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_11, 15, 4, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_12, 15, 8, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_13, 15, 12, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_14, 15, 16, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_15, 15, 20, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HCNTL0, 15, 28, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO0_10, 15, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_11, 15, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_12, 15, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_13, 15, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_14, 15, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_15, 15, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_0, 15, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_1, 15, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMA_A_2, 16, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_3, 16, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_4, 16, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_5, 16, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_6, 16, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_7, 16, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_8, 16, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_9, 16, 28, 0xf, 1, false)
+ MUX_CFG(DA830, MMCSD_CMD, 16, 0, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_6, 16, 4, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_3, 16, 8, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_2, 16, 12, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_1, 16, 16, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_0, 16, 20, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_PCLK, 16, 24, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_HSYNC, 16, 28, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HCNTL1, 16, 0, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO1_2, 16, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_3, 16, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_4, 16, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_5, 16, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_6, 16, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_7, 16, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_8, 16, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_9, 16, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMA_A_10, 17, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_11, 17, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_12, 17, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_BA_1, 17, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_BA_0, 17, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_CLK, 17, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_SDCKE, 17, 24, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_CAS, 17, 28, 0xf, 1, false)
+ MUX_CFG(DA830, LCD_VSYNC, 17, 0, 0xf, 2, false)
+ MUX_CFG(DA830, NLCD_AC_ENB_CS, 17, 4, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_MCLK, 17, 8, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_5, 17, 12, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_4, 17, 16, 0xf, 2, false)
+ MUX_CFG(DA830, OBSCLK, 17, 20, 0xf, 2, false)
+ MUX_CFG(DA830, NEMA_CS_4, 17, 28, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HHWIL, 17, 12, 0xf, 4, false)
+ MUX_CFG(DA830, AHCLKR2, 17, 20, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO1_10, 17, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_11, 17, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_12, 17, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_13, 17, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_14, 17, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_15, 17, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_0, 17, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_1, 17, 28, 0xf, 8, false)
+ MUX_CFG(DA830, NEMA_RAS, 18, 0, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_WE, 18, 4, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_CS_0, 18, 8, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_CS_2, 18, 12, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_CS_3, 18, 16, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_OE, 18, 20, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_WE_DQM_1, 18, 24, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_WE_DQM_0, 18, 28, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_CS_5, 18, 0, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HRNW, 18, 4, 0xf, 2, false)
+ MUX_CFG(DA830, NUHPI_HAS, 18, 8, 0xf, 2, false)
+ MUX_CFG(DA830, NUHPI_HCS, 18, 12, 0xf, 2, false)
+ MUX_CFG(DA830, NUHPI_HDS1, 18, 20, 0xf, 2, false)
+ MUX_CFG(DA830, NUHPI_HDS2, 18, 24, 0xf, 2, false)
+ MUX_CFG(DA830, NUHPI_HINT, 18, 28, 0xf, 2, false)
+ MUX_CFG(DA830, AXR0_12, 18, 4, 0xf, 4, false)
+ MUX_CFG(DA830, AMUTE2, 18, 16, 0xf, 4, false)
+ MUX_CFG(DA830, AXR0_13, 18, 20, 0xf, 4, false)
+ MUX_CFG(DA830, AXR0_14, 18, 24, 0xf, 4, false)
+ MUX_CFG(DA830, AXR0_15, 18, 28, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO2_2, 18, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_3, 18, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_4, 18, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_5, 18, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_6, 18, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_7, 18, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_8, 18, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_9, 18, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMA_WAIT_0, 19, 0, 0xf, 1, false)
+ MUX_CFG(DA830, NUHPI_HRDY, 19, 0, 0xf, 2, false)
+ MUX_CFG(DA830, GPIO2_10, 19, 0, 0xf, 8, false)
+#endif
+};
+
+const short da830_emif25_pins[] __initdata = {
+ DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3,
+ DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7,
+ DA830_EMA_D_8, DA830_EMA_D_9, DA830_EMA_D_10, DA830_EMA_D_11,
+ DA830_EMA_D_12, DA830_EMA_D_13, DA830_EMA_D_14, DA830_EMA_D_15,
+ DA830_EMA_A_0, DA830_EMA_A_1, DA830_EMA_A_2, DA830_EMA_A_3,
+ DA830_EMA_A_4, DA830_EMA_A_5, DA830_EMA_A_6, DA830_EMA_A_7,
+ DA830_EMA_A_8, DA830_EMA_A_9, DA830_EMA_A_10, DA830_EMA_A_11,
+ DA830_EMA_A_12, DA830_EMA_BA_0, DA830_EMA_BA_1, DA830_EMA_CLK,
+ DA830_EMA_SDCKE, DA830_NEMA_CS_4, DA830_NEMA_CS_5, DA830_NEMA_WE,
+ DA830_NEMA_CS_0, DA830_NEMA_CS_2, DA830_NEMA_CS_3, DA830_NEMA_OE,
+ DA830_NEMA_WE_DQM_1, DA830_NEMA_WE_DQM_0, DA830_EMA_WAIT_0,
+ -1
+};
+
+const short da830_spi0_pins[] __initdata = {
+ DA830_SPI0_SOMI_0, DA830_SPI0_SIMO_0, DA830_SPI0_CLK, DA830_NSPI0_ENA,
+ DA830_NSPI0_SCS_0,
+ -1
+};
+
+const short da830_spi1_pins[] __initdata = {
+ DA830_SPI1_SOMI_0, DA830_SPI1_SIMO_0, DA830_SPI1_CLK, DA830_NSPI1_ENA,
+ DA830_NSPI1_SCS_0,
+ -1
+};
+
+const short da830_mmc_sd_pins[] __initdata = {
+ DA830_MMCSD_DAT_0, DA830_MMCSD_DAT_1, DA830_MMCSD_DAT_2,
+ DA830_MMCSD_DAT_3, DA830_MMCSD_DAT_4, DA830_MMCSD_DAT_5,
+ DA830_MMCSD_DAT_6, DA830_MMCSD_DAT_7, DA830_MMCSD_CLK,
+ DA830_MMCSD_CMD,
+ -1
+};
+
+const short da830_uart0_pins[] __initdata = {
+ DA830_NUART0_CTS, DA830_NUART0_RTS, DA830_UART0_RXD, DA830_UART0_TXD,
+ -1
+};
+
+const short da830_uart1_pins[] __initdata = {
+ DA830_UART1_RXD, DA830_UART1_TXD,
+ -1
+};
+
+const short da830_uart2_pins[] __initdata = {
+ DA830_UART2_RXD, DA830_UART2_TXD,
+ -1
+};
+
+const short da830_usb20_pins[] __initdata = {
+ DA830_USB0_DRVVBUS, DA830_USB_REFCLKIN,
+ -1
+};
+
+const short da830_usb11_pins[] __initdata = {
+ DA830_USB_REFCLKIN,
+ -1
+};
+
+const short da830_uhpi_pins[] __initdata = {
+ DA830_UHPI_HD_0, DA830_UHPI_HD_1, DA830_UHPI_HD_2, DA830_UHPI_HD_3,
+ DA830_UHPI_HD_4, DA830_UHPI_HD_5, DA830_UHPI_HD_6, DA830_UHPI_HD_7,
+ DA830_UHPI_HD_8, DA830_UHPI_HD_9, DA830_UHPI_HD_10, DA830_UHPI_HD_11,
+ DA830_UHPI_HD_12, DA830_UHPI_HD_13, DA830_UHPI_HD_14, DA830_UHPI_HD_15,
+ DA830_UHPI_HCNTL0, DA830_UHPI_HCNTL1, DA830_UHPI_HHWIL, DA830_UHPI_HRNW,
+ DA830_NUHPI_HAS, DA830_NUHPI_HCS, DA830_NUHPI_HDS1, DA830_NUHPI_HDS2,
+ DA830_NUHPI_HINT, DA830_NUHPI_HRDY,
+ -1
+};
+
+const short da830_cpgmac_pins[] __initdata = {
+ DA830_RMII_TXD_0, DA830_RMII_TXD_1, DA830_RMII_TXEN, DA830_RMII_CRS_DV,
+ DA830_RMII_RXD_0, DA830_RMII_RXD_1, DA830_RMII_RXER, DA830_MDIO_CLK,
+ DA830_MDIO_D,
+ -1
+};
+
+const short da830_emif3c_pins[] __initdata = {
+ DA830_EMB_SDCKE, DA830_EMB_CLK_GLUE, DA830_EMB_CLK, DA830_NEMB_CS_0,
+ DA830_NEMB_CAS, DA830_NEMB_RAS, DA830_NEMB_WE, DA830_EMB_BA_1,
+ DA830_EMB_BA_0, DA830_EMB_A_0, DA830_EMB_A_1, DA830_EMB_A_2,
+ DA830_EMB_A_3, DA830_EMB_A_4, DA830_EMB_A_5, DA830_EMB_A_6,
+ DA830_EMB_A_7, DA830_EMB_A_8, DA830_EMB_A_9, DA830_EMB_A_10,
+ DA830_EMB_A_11, DA830_EMB_A_12, DA830_NEMB_WE_DQM_3,
+ DA830_NEMB_WE_DQM_2, DA830_EMB_D_0, DA830_EMB_D_1, DA830_EMB_D_2,
+ DA830_EMB_D_3, DA830_EMB_D_4, DA830_EMB_D_5, DA830_EMB_D_6,
+ DA830_EMB_D_7, DA830_EMB_D_8, DA830_EMB_D_9, DA830_EMB_D_10,
+ DA830_EMB_D_11, DA830_EMB_D_12, DA830_EMB_D_13, DA830_EMB_D_14,
+ DA830_EMB_D_15, DA830_EMB_D_16, DA830_EMB_D_17, DA830_EMB_D_18,
+ DA830_EMB_D_19, DA830_EMB_D_20, DA830_EMB_D_21, DA830_EMB_D_22,
+ DA830_EMB_D_23, DA830_EMB_D_24, DA830_EMB_D_25, DA830_EMB_D_26,
+ DA830_EMB_D_27, DA830_EMB_D_28, DA830_EMB_D_29, DA830_EMB_D_30,
+ DA830_EMB_D_31, DA830_NEMB_WE_DQM_1, DA830_NEMB_WE_DQM_0,
+ -1
+};
+
+const short da830_mcasp0_pins[] __initdata = {
+ DA830_AHCLKX0, DA830_ACLKX0, DA830_AFSX0,
+ DA830_AHCLKR0, DA830_ACLKR0, DA830_AFSR0, DA830_AMUTE0,
+ DA830_AXR0_0, DA830_AXR0_1, DA830_AXR0_2, DA830_AXR0_3,
+ DA830_AXR0_4, DA830_AXR0_5, DA830_AXR0_6, DA830_AXR0_7,
+ DA830_AXR0_8, DA830_AXR0_9, DA830_AXR0_10, DA830_AXR0_11,
+ DA830_AXR0_12, DA830_AXR0_13, DA830_AXR0_14, DA830_AXR0_15,
+ -1
+};
+
+const short da830_mcasp1_pins[] __initdata = {
+ DA830_AHCLKX1, DA830_ACLKX1, DA830_AFSX1,
+ DA830_AHCLKR1, DA830_ACLKR1, DA830_AFSR1, DA830_AMUTE1,
+ DA830_AXR1_0, DA830_AXR1_1, DA830_AXR1_2, DA830_AXR1_3,
+ DA830_AXR1_4, DA830_AXR1_5, DA830_AXR1_6, DA830_AXR1_7,
+ DA830_AXR1_8, DA830_AXR1_9, DA830_AXR1_10, DA830_AXR1_11,
+ -1
+};
+
+const short da830_mcasp2_pins[] __initdata = {
+ DA830_AHCLKX2, DA830_ACLKX2, DA830_AFSX2,
+ DA830_AHCLKR2, DA830_ACLKR2, DA830_AFSR2, DA830_AMUTE2,
+ DA830_AXR2_0, DA830_AXR2_1, DA830_AXR2_2, DA830_AXR2_3,
+ -1
+};
+
+const short da830_i2c0_pins[] __initdata = {
+ DA830_I2C0_SDA, DA830_I2C0_SCL,
+ -1
+};
+
+const short da830_i2c1_pins[] __initdata = {
+ DA830_I2C1_SCL, DA830_I2C1_SDA,
+ -1
+};
+
+const short da830_lcdcntl_pins[] __initdata = {
+ DA830_LCD_D_0, DA830_LCD_D_1, DA830_LCD_D_2, DA830_LCD_D_3,
+ DA830_LCD_D_4, DA830_LCD_D_5, DA830_LCD_D_6, DA830_LCD_D_7,
+ DA830_LCD_D_8, DA830_LCD_D_9, DA830_LCD_D_10, DA830_LCD_D_11,
+ DA830_LCD_D_12, DA830_LCD_D_13, DA830_LCD_D_14, DA830_LCD_D_15,
+ DA830_LCD_PCLK, DA830_LCD_HSYNC, DA830_LCD_VSYNC, DA830_NLCD_AC_ENB_CS,
+ DA830_LCD_MCLK,
+ -1
+};
+
+const short da830_pwm_pins[] __initdata = {
+ DA830_ECAP0_APWM0, DA830_ECAP1_APWM1, DA830_EPWM0B, DA830_EPWM0A,
+ DA830_EPWMSYNCI, DA830_EPWMSYNC0, DA830_ECAP2_APWM2, DA830_EHRPWMGLUETZ,
+ DA830_EPWM2B, DA830_EPWM2A, DA830_EPWM1B, DA830_EPWM1A,
+ -1
+};
+
+const short da830_ecap0_pins[] __initdata = {
+ DA830_ECAP0_APWM0,
+ -1
+};
+
+const short da830_ecap1_pins[] __initdata = {
+ DA830_ECAP1_APWM1,
+ -1
+};
+
+const short da830_ecap2_pins[] __initdata = {
+ DA830_ECAP2_APWM2,
+ -1
+};
+
+const short da830_eqep0_pins[] __initdata = {
+ DA830_EQEP0I, DA830_EQEP0S, DA830_EQEP0A, DA830_EQEP0B,
+ -1
+};
+
+const short da830_eqep1_pins[] __initdata = {
+ DA830_EQEP1I, DA830_EQEP1S, DA830_EQEP1A, DA830_EQEP1B,
+ -1
+};
+
+/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
+static u8 da830_default_priorities[DA830_N_CP_INTC_IRQ] = {
+ [IRQ_DA8XX_COMMTX] = 7,
+ [IRQ_DA8XX_COMMRX] = 7,
+ [IRQ_DA8XX_NINT] = 7,
+ [IRQ_DA8XX_EVTOUT0] = 7,
+ [IRQ_DA8XX_EVTOUT1] = 7,
+ [IRQ_DA8XX_EVTOUT2] = 7,
+ [IRQ_DA8XX_EVTOUT3] = 7,
+ [IRQ_DA8XX_EVTOUT4] = 7,
+ [IRQ_DA8XX_EVTOUT5] = 7,
+ [IRQ_DA8XX_EVTOUT6] = 7,
+ [IRQ_DA8XX_EVTOUT7] = 7,
+ [IRQ_DA8XX_CCINT0] = 7,
+ [IRQ_DA8XX_CCERRINT] = 7,
+ [IRQ_DA8XX_TCERRINT0] = 7,
+ [IRQ_DA8XX_AEMIFINT] = 7,
+ [IRQ_DA8XX_I2CINT0] = 7,
+ [IRQ_DA8XX_MMCSDINT0] = 7,
+ [IRQ_DA8XX_MMCSDINT1] = 7,
+ [IRQ_DA8XX_ALLINT0] = 7,
+ [IRQ_DA8XX_RTC] = 7,
+ [IRQ_DA8XX_SPINT0] = 7,
+ [IRQ_DA8XX_TINT12_0] = 7,
+ [IRQ_DA8XX_TINT34_0] = 7,
+ [IRQ_DA8XX_TINT12_1] = 7,
+ [IRQ_DA8XX_TINT34_1] = 7,
+ [IRQ_DA8XX_UARTINT0] = 7,
+ [IRQ_DA8XX_KEYMGRINT] = 7,
+ [IRQ_DA830_MPUERR] = 7,
+ [IRQ_DA8XX_CHIPINT0] = 7,
+ [IRQ_DA8XX_CHIPINT1] = 7,
+ [IRQ_DA8XX_CHIPINT2] = 7,
+ [IRQ_DA8XX_CHIPINT3] = 7,
+ [IRQ_DA8XX_TCERRINT1] = 7,
+ [IRQ_DA8XX_C0_RX_THRESH_PULSE] = 7,
+ [IRQ_DA8XX_C0_RX_PULSE] = 7,
+ [IRQ_DA8XX_C0_TX_PULSE] = 7,
+ [IRQ_DA8XX_C0_MISC_PULSE] = 7,
+ [IRQ_DA8XX_C1_RX_THRESH_PULSE] = 7,
+ [IRQ_DA8XX_C1_RX_PULSE] = 7,
+ [IRQ_DA8XX_C1_TX_PULSE] = 7,
+ [IRQ_DA8XX_C1_MISC_PULSE] = 7,
+ [IRQ_DA8XX_MEMERR] = 7,
+ [IRQ_DA8XX_GPIO0] = 7,
+ [IRQ_DA8XX_GPIO1] = 7,
+ [IRQ_DA8XX_GPIO2] = 7,
+ [IRQ_DA8XX_GPIO3] = 7,
+ [IRQ_DA8XX_GPIO4] = 7,
+ [IRQ_DA8XX_GPIO5] = 7,
+ [IRQ_DA8XX_GPIO6] = 7,
+ [IRQ_DA8XX_GPIO7] = 7,
+ [IRQ_DA8XX_GPIO8] = 7,
+ [IRQ_DA8XX_I2CINT1] = 7,
+ [IRQ_DA8XX_LCDINT] = 7,
+ [IRQ_DA8XX_UARTINT1] = 7,
+ [IRQ_DA8XX_MCASPINT] = 7,
+ [IRQ_DA8XX_ALLINT1] = 7,
+ [IRQ_DA8XX_SPINT1] = 7,
+ [IRQ_DA8XX_UHPI_INT1] = 7,
+ [IRQ_DA8XX_USB_INT] = 7,
+ [IRQ_DA8XX_IRQN] = 7,
+ [IRQ_DA8XX_RWAKEUP] = 7,
+ [IRQ_DA8XX_UARTINT2] = 7,
+ [IRQ_DA8XX_DFTSSINT] = 7,
+ [IRQ_DA8XX_EHRPWM0] = 7,
+ [IRQ_DA8XX_EHRPWM0TZ] = 7,
+ [IRQ_DA8XX_EHRPWM1] = 7,
+ [IRQ_DA8XX_EHRPWM1TZ] = 7,
+ [IRQ_DA830_EHRPWM2] = 7,
+ [IRQ_DA830_EHRPWM2TZ] = 7,
+ [IRQ_DA8XX_ECAP0] = 7,
+ [IRQ_DA8XX_ECAP1] = 7,
+ [IRQ_DA8XX_ECAP2] = 7,
+ [IRQ_DA830_EQEP0] = 7,
+ [IRQ_DA830_EQEP1] = 7,
+ [IRQ_DA830_T12CMPINT0_0] = 7,
+ [IRQ_DA830_T12CMPINT1_0] = 7,
+ [IRQ_DA830_T12CMPINT2_0] = 7,
+ [IRQ_DA830_T12CMPINT3_0] = 7,
+ [IRQ_DA830_T12CMPINT4_0] = 7,
+ [IRQ_DA830_T12CMPINT5_0] = 7,
+ [IRQ_DA830_T12CMPINT6_0] = 7,
+ [IRQ_DA830_T12CMPINT7_0] = 7,
+ [IRQ_DA830_T12CMPINT0_1] = 7,
+ [IRQ_DA830_T12CMPINT1_1] = 7,
+ [IRQ_DA830_T12CMPINT2_1] = 7,
+ [IRQ_DA830_T12CMPINT3_1] = 7,
+ [IRQ_DA830_T12CMPINT4_1] = 7,
+ [IRQ_DA830_T12CMPINT5_1] = 7,
+ [IRQ_DA830_T12CMPINT6_1] = 7,
+ [IRQ_DA830_T12CMPINT7_1] = 7,
+ [IRQ_DA8XX_ARMCLKSTOPREQ] = 7,
+};
+
+static struct map_desc da830_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = DA8XX_CP_INTC_VIRT,
+ .pfn = __phys_to_pfn(DA8XX_CP_INTC_BASE),
+ .length = DA8XX_CP_INTC_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+static u32 da830_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id da830_ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb7df,
+ .manufacturer = 0x017, /* 0x02f >> 1 */
+ .cpu_id = DAVINCI_CPU_ID_DA830,
+ .name = "da830/omap-l137 rev1.0",
+ },
+ {
+ .variant = 0x8,
+ .part_no = 0xb7df,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DA830,
+ .name = "da830/omap-l137 rev1.1",
+ },
+ {
+ .variant = 0x9,
+ .part_no = 0xb7df,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DA830,
+ .name = "da830/omap-l137 rev2.0",
+ },
+};
+
+static struct davinci_timer_instance da830_timer_instance[2] = {
+ {
+ .base = DA8XX_TIMER64P0_BASE,
+ .bottom_irq = IRQ_DA8XX_TINT12_0,
+ .top_irq = IRQ_DA8XX_TINT34_0,
+ .cmp_off = DA830_CMP12_0,
+ .cmp_irq = IRQ_DA830_T12CMPINT0_0,
+ },
+ {
+ .base = DA8XX_TIMER64P1_BASE,
+ .bottom_irq = IRQ_DA8XX_TINT12_1,
+ .top_irq = IRQ_DA8XX_TINT34_1,
+ .cmp_off = DA830_CMP12_0,
+ .cmp_irq = IRQ_DA830_T12CMPINT0_1,
+ },
+};
+
+/*
+ * T0_BOT: Timer 0, bottom : Used for clock_event & clocksource
+ * T0_TOP: Timer 0, top : Used by DSP
+ * T1_BOT, T1_TOP: Timer 1, bottom & top: Used for watchdog timer
+ */
+static struct davinci_timer_info da830_timer_info = {
+ .timers = da830_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_BOT,
+};
+
+static struct davinci_soc_info davinci_soc_info_da830 = {
+ .io_desc = da830_io_desc,
+ .io_desc_num = ARRAY_SIZE(da830_io_desc),
+ .jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
+ .ids = da830_ids,
+ .ids_num = ARRAY_SIZE(da830_ids),
+ .cpu_clks = da830_clks,
+ .psc_bases = da830_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(da830_psc_bases),
+ .pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
+ .pinmux_pins = da830_pins,
+ .pinmux_pins_num = ARRAY_SIZE(da830_pins),
+ .intc_base = DA8XX_CP_INTC_BASE,
+ .intc_type = DAVINCI_INTC_TYPE_CP_INTC,
+ .intc_irq_prios = da830_default_priorities,
+ .intc_irq_num = DA830_N_CP_INTC_IRQ,
+ .timer_info = &da830_timer_info,
+ .gpio_type = GPIO_TYPE_DAVINCI,
+ .gpio_base = DA8XX_GPIO_BASE,
+ .gpio_num = 128,
+ .gpio_irq = IRQ_DA8XX_GPIO0,
+ .serial_dev = &da8xx_serial_device,
+ .emac_pdata = &da8xx_emac_pdata,
+ .reset_device = &da8xx_wdt_device,
+};
+
+void __init da830_init(void)
+{
+ davinci_common_init(&davinci_soc_info_da830);
+
+ da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
+ WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module");
+}
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
new file mode 100644
index 00000000..133aac40
--- /dev/null
+++ b/arch/arm/mach-davinci/da850.c
@@ -0,0 +1,1139 @@
+/*
+ * TI DA850/OMAP-L138 chip specific setup
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Derived from: arch/arm/mach-davinci/da830.c
+ * Original Copyrights follow:
+ *
+ * 2009 (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/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/cpufreq.h>
+#include <linux/regulator/consumer.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/psc.h>
+#include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <mach/common.h>
+#include <mach/time.h>
+#include <mach/da8xx.h>
+#include <mach/cpufreq.h>
+#include <mach/pm.h>
+#include <mach/gpio.h>
+
+#include "clock.h"
+#include "mux.h"
+
+/* SoC specific clock flags */
+#define DA850_CLK_ASYNC3 BIT(16)
+
+#define DA850_PLL1_BASE 0x01e1a000
+#define DA850_TIMER64P2_BASE 0x01f0c000
+#define DA850_TIMER64P3_BASE 0x01f0d000
+
+#define DA850_REF_FREQ 24000000
+
+#define CFGCHIP3_ASYNC3_CLKSRC BIT(4)
+#define CFGCHIP3_PLL1_MASTER_LOCK BIT(5)
+#define CFGCHIP0_PLL_MASTER_LOCK BIT(4)
+
+static int da850_set_armrate(struct clk *clk, unsigned long rate);
+static int da850_round_armrate(struct clk *clk, unsigned long rate);
+static int da850_set_pll0rate(struct clk *clk, unsigned long armrate);
+
+static struct pll_data pll0_data = {
+ .num = 1,
+ .phys_base = DA8XX_PLL0_BASE,
+ .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
+};
+
+static struct clk ref_clk = {
+ .name = "ref_clk",
+ .rate = DA850_REF_FREQ,
+};
+
+static struct clk pll0_clk = {
+ .name = "pll0",
+ .parent = &ref_clk,
+ .pll_data = &pll0_data,
+ .flags = CLK_PLL,
+ .set_rate = da850_set_pll0rate,
+};
+
+static struct clk pll0_aux_clk = {
+ .name = "pll0_aux_clk",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll0_sysclk2 = {
+ .name = "pll0_sysclk2",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll0_sysclk3 = {
+ .name = "pll0_sysclk3",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+ .set_rate = davinci_set_sysclk_rate,
+ .maxrate = 100000000,
+};
+
+static struct clk pll0_sysclk4 = {
+ .name = "pll0_sysclk4",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll0_sysclk5 = {
+ .name = "pll0_sysclk5",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll0_sysclk6 = {
+ .name = "pll0_sysclk6",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV6,
+};
+
+static struct clk pll0_sysclk7 = {
+ .name = "pll0_sysclk7",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV7,
+};
+
+static struct pll_data pll1_data = {
+ .num = 2,
+ .phys_base = DA850_PLL1_BASE,
+ .flags = PLL_HAS_POSTDIV,
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &ref_clk,
+ .pll_data = &pll1_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll1_aux_clk = {
+ .name = "pll1_aux_clk",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclk2 = {
+ .name = "pll1_sysclk2",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll1_sysclk3 = {
+ .name = "pll1_sysclk3",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll1_sysclk4 = {
+ .name = "pll1_sysclk4",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll1_sysclk5 = {
+ .name = "pll1_sysclk5",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll1_sysclk6 = {
+ .name = "pll0_sysclk6",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV6,
+};
+
+static struct clk pll1_sysclk7 = {
+ .name = "pll1_sysclk7",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV7,
+};
+
+static struct clk i2c0_clk = {
+ .name = "i2c0",
+ .parent = &pll0_aux_clk,
+};
+
+static struct clk timerp64_0_clk = {
+ .name = "timer0",
+ .parent = &pll0_aux_clk,
+};
+
+static struct clk timerp64_1_clk = {
+ .name = "timer1",
+ .parent = &pll0_aux_clk,
+};
+
+static struct clk arm_rom_clk = {
+ .name = "arm_rom",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_ARM_RAM_ROM,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk tpcc0_clk = {
+ .name = "tpcc0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_TPCC,
+ .flags = ALWAYS_ENABLED | CLK_PSC,
+};
+
+static struct clk tptc0_clk = {
+ .name = "tptc0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_TPTC0,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk tptc1_clk = {
+ .name = "tptc1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_TPTC1,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk tpcc1_clk = {
+ .name = "tpcc1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA850_LPSC1_TPCC1,
+ .gpsc = 1,
+ .flags = CLK_PSC | ALWAYS_ENABLED,
+};
+
+static struct clk tptc2_clk = {
+ .name = "tptc2",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA850_LPSC1_TPTC2,
+ .gpsc = 1,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk uart0_clk = {
+ .name = "uart0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_UART0,
+};
+
+static struct clk uart1_clk = {
+ .name = "uart1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_UART1,
+ .gpsc = 1,
+ .flags = DA850_CLK_ASYNC3,
+};
+
+static struct clk uart2_clk = {
+ .name = "uart2",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_UART2,
+ .gpsc = 1,
+ .flags = DA850_CLK_ASYNC3,
+};
+
+static struct clk aintc_clk = {
+ .name = "aintc",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC0_AINTC,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk gpio_clk = {
+ .name = "gpio",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_GPIO,
+ .gpsc = 1,
+};
+
+static struct clk i2c1_clk = {
+ .name = "i2c1",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_I2C,
+ .gpsc = 1,
+};
+
+static struct clk emif3_clk = {
+ .name = "emif3",
+ .parent = &pll0_sysclk5,
+ .lpsc = DA8XX_LPSC1_EMIF3C,
+ .gpsc = 1,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk arm_clk = {
+ .name = "arm",
+ .parent = &pll0_sysclk6,
+ .lpsc = DA8XX_LPSC0_ARM,
+ .flags = ALWAYS_ENABLED,
+ .set_rate = da850_set_armrate,
+ .round_rate = da850_round_armrate,
+};
+
+static struct clk rmii_clk = {
+ .name = "rmii",
+ .parent = &pll0_sysclk7,
+};
+
+static struct clk emac_clk = {
+ .name = "emac",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_CPGMAC,
+ .gpsc = 1,
+};
+
+static struct clk mcasp_clk = {
+ .name = "mcasp",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_McASP0,
+ .gpsc = 1,
+ .flags = DA850_CLK_ASYNC3,
+};
+
+static struct clk lcdc_clk = {
+ .name = "lcdc",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_LCDC,
+ .gpsc = 1,
+};
+
+static struct clk mmcsd0_clk = {
+ .name = "mmcsd0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_MMC_SD,
+};
+
+static struct clk mmcsd1_clk = {
+ .name = "mmcsd1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA850_LPSC1_MMC_SD1,
+ .gpsc = 1,
+};
+
+static struct clk aemif_clk = {
+ .name = "aemif",
+ .parent = &pll0_sysclk3,
+ .lpsc = DA8XX_LPSC0_EMIF25,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk usb11_clk = {
+ .name = "usb11",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_USB11,
+ .gpsc = 1,
+};
+
+static struct clk usb20_clk = {
+ .name = "usb20",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_USB20,
+ .gpsc = 1,
+};
+
+static struct clk spi0_clk = {
+ .name = "spi0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_SPI0,
+};
+
+static struct clk spi1_clk = {
+ .name = "spi1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_SPI1,
+ .gpsc = 1,
+ .flags = DA850_CLK_ASYNC3,
+};
+
+static struct clk_lookup da850_clks[] = {
+ CLK(NULL, "ref", &ref_clk),
+ CLK(NULL, "pll0", &pll0_clk),
+ CLK(NULL, "pll0_aux", &pll0_aux_clk),
+ CLK(NULL, "pll0_sysclk2", &pll0_sysclk2),
+ CLK(NULL, "pll0_sysclk3", &pll0_sysclk3),
+ CLK(NULL, "pll0_sysclk4", &pll0_sysclk4),
+ CLK(NULL, "pll0_sysclk5", &pll0_sysclk5),
+ CLK(NULL, "pll0_sysclk6", &pll0_sysclk6),
+ CLK(NULL, "pll0_sysclk7", &pll0_sysclk7),
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_aux", &pll1_aux_clk),
+ CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+ CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+ CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
+ CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
+ CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
+ CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
+ CLK("i2c_davinci.1", NULL, &i2c0_clk),
+ CLK(NULL, "timer0", &timerp64_0_clk),
+ CLK("watchdog", NULL, &timerp64_1_clk),
+ CLK(NULL, "arm_rom", &arm_rom_clk),
+ CLK(NULL, "tpcc0", &tpcc0_clk),
+ CLK(NULL, "tptc0", &tptc0_clk),
+ CLK(NULL, "tptc1", &tptc1_clk),
+ CLK(NULL, "tpcc1", &tpcc1_clk),
+ CLK(NULL, "tptc2", &tptc2_clk),
+ CLK(NULL, "uart0", &uart0_clk),
+ CLK(NULL, "uart1", &uart1_clk),
+ CLK(NULL, "uart2", &uart2_clk),
+ CLK(NULL, "aintc", &aintc_clk),
+ CLK(NULL, "gpio", &gpio_clk),
+ CLK("i2c_davinci.2", NULL, &i2c1_clk),
+ CLK(NULL, "emif3", &emif3_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "rmii", &rmii_clk),
+ CLK("davinci_emac.1", NULL, &emac_clk),
+ CLK("davinci-mcasp.0", NULL, &mcasp_clk),
+ CLK("da8xx_lcdc.0", NULL, &lcdc_clk),
+ CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
+ CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
+ CLK(NULL, "aemif", &aemif_clk),
+ CLK(NULL, "usb11", &usb11_clk),
+ CLK(NULL, "usb20", &usb20_clk),
+ CLK("spi_davinci.0", NULL, &spi0_clk),
+ CLK("spi_davinci.1", NULL, &spi1_clk),
+ CLK(NULL, NULL, NULL),
+};
+
+/*
+ * Device specific mux setup
+ *
+ * soc description mux mode mode mux dbg
+ * reg offset mask mode
+ */
+static const struct mux_config da850_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+ /* UART0 function */
+ MUX_CFG(DA850, NUART0_CTS, 3, 24, 15, 2, false)
+ MUX_CFG(DA850, NUART0_RTS, 3, 28, 15, 2, false)
+ MUX_CFG(DA850, UART0_RXD, 3, 16, 15, 2, false)
+ MUX_CFG(DA850, UART0_TXD, 3, 20, 15, 2, false)
+ /* UART1 function */
+ MUX_CFG(DA850, UART1_RXD, 4, 24, 15, 2, false)
+ MUX_CFG(DA850, UART1_TXD, 4, 28, 15, 2, false)
+ /* UART2 function */
+ MUX_CFG(DA850, UART2_RXD, 4, 16, 15, 2, false)
+ MUX_CFG(DA850, UART2_TXD, 4, 20, 15, 2, false)
+ /* I2C1 function */
+ MUX_CFG(DA850, I2C1_SCL, 4, 16, 15, 4, false)
+ MUX_CFG(DA850, I2C1_SDA, 4, 20, 15, 4, false)
+ /* I2C0 function */
+ MUX_CFG(DA850, I2C0_SDA, 4, 12, 15, 2, false)
+ MUX_CFG(DA850, I2C0_SCL, 4, 8, 15, 2, false)
+ /* EMAC function */
+ MUX_CFG(DA850, MII_TXEN, 2, 4, 15, 8, false)
+ MUX_CFG(DA850, MII_TXCLK, 2, 8, 15, 8, false)
+ MUX_CFG(DA850, MII_COL, 2, 12, 15, 8, false)
+ MUX_CFG(DA850, MII_TXD_3, 2, 16, 15, 8, false)
+ MUX_CFG(DA850, MII_TXD_2, 2, 20, 15, 8, false)
+ MUX_CFG(DA850, MII_TXD_1, 2, 24, 15, 8, false)
+ MUX_CFG(DA850, MII_TXD_0, 2, 28, 15, 8, false)
+ MUX_CFG(DA850, MII_RXCLK, 3, 0, 15, 8, false)
+ MUX_CFG(DA850, MII_RXDV, 3, 4, 15, 8, false)
+ MUX_CFG(DA850, MII_RXER, 3, 8, 15, 8, false)
+ MUX_CFG(DA850, MII_CRS, 3, 12, 15, 8, false)
+ MUX_CFG(DA850, MII_RXD_3, 3, 16, 15, 8, false)
+ MUX_CFG(DA850, MII_RXD_2, 3, 20, 15, 8, false)
+ MUX_CFG(DA850, MII_RXD_1, 3, 24, 15, 8, false)
+ MUX_CFG(DA850, MII_RXD_0, 3, 28, 15, 8, false)
+ MUX_CFG(DA850, MDIO_CLK, 4, 0, 15, 8, false)
+ MUX_CFG(DA850, MDIO_D, 4, 4, 15, 8, false)
+ MUX_CFG(DA850, RMII_TXD_0, 14, 12, 15, 8, false)
+ MUX_CFG(DA850, RMII_TXD_1, 14, 8, 15, 8, false)
+ MUX_CFG(DA850, RMII_TXEN, 14, 16, 15, 8, false)
+ MUX_CFG(DA850, RMII_CRS_DV, 15, 4, 15, 8, false)
+ MUX_CFG(DA850, RMII_RXD_0, 14, 24, 15, 8, false)
+ MUX_CFG(DA850, RMII_RXD_1, 14, 20, 15, 8, false)
+ MUX_CFG(DA850, RMII_RXER, 14, 28, 15, 8, false)
+ MUX_CFG(DA850, RMII_MHZ_50_CLK, 15, 0, 15, 0, false)
+ /* McASP function */
+ MUX_CFG(DA850, ACLKR, 0, 0, 15, 1, false)
+ MUX_CFG(DA850, ACLKX, 0, 4, 15, 1, false)
+ MUX_CFG(DA850, AFSR, 0, 8, 15, 1, false)
+ MUX_CFG(DA850, AFSX, 0, 12, 15, 1, false)
+ MUX_CFG(DA850, AHCLKR, 0, 16, 15, 1, false)
+ MUX_CFG(DA850, AHCLKX, 0, 20, 15, 1, false)
+ MUX_CFG(DA850, AMUTE, 0, 24, 15, 1, false)
+ MUX_CFG(DA850, AXR_15, 1, 0, 15, 1, false)
+ MUX_CFG(DA850, AXR_14, 1, 4, 15, 1, false)
+ MUX_CFG(DA850, AXR_13, 1, 8, 15, 1, false)
+ MUX_CFG(DA850, AXR_12, 1, 12, 15, 1, false)
+ MUX_CFG(DA850, AXR_11, 1, 16, 15, 1, false)
+ MUX_CFG(DA850, AXR_10, 1, 20, 15, 1, false)
+ MUX_CFG(DA850, AXR_9, 1, 24, 15, 1, false)
+ MUX_CFG(DA850, AXR_8, 1, 28, 15, 1, false)
+ MUX_CFG(DA850, AXR_7, 2, 0, 15, 1, false)
+ MUX_CFG(DA850, AXR_6, 2, 4, 15, 1, false)
+ MUX_CFG(DA850, AXR_5, 2, 8, 15, 1, false)
+ MUX_CFG(DA850, AXR_4, 2, 12, 15, 1, false)
+ MUX_CFG(DA850, AXR_3, 2, 16, 15, 1, false)
+ MUX_CFG(DA850, AXR_2, 2, 20, 15, 1, false)
+ MUX_CFG(DA850, AXR_1, 2, 24, 15, 1, false)
+ MUX_CFG(DA850, AXR_0, 2, 28, 15, 1, false)
+ /* LCD function */
+ MUX_CFG(DA850, LCD_D_7, 16, 8, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_6, 16, 12, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_5, 16, 16, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_4, 16, 20, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_3, 16, 24, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_2, 16, 28, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_1, 17, 0, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_0, 17, 4, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_15, 17, 8, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_14, 17, 12, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_13, 17, 16, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_12, 17, 20, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_11, 17, 24, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_10, 17, 28, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_9, 18, 0, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_8, 18, 4, 15, 2, false)
+ MUX_CFG(DA850, LCD_PCLK, 18, 24, 15, 2, false)
+ MUX_CFG(DA850, LCD_HSYNC, 19, 0, 15, 2, false)
+ MUX_CFG(DA850, LCD_VSYNC, 19, 4, 15, 2, false)
+ MUX_CFG(DA850, NLCD_AC_ENB_CS, 19, 24, 15, 2, false)
+ /* MMC/SD0 function */
+ MUX_CFG(DA850, MMCSD0_DAT_0, 10, 8, 15, 2, false)
+ MUX_CFG(DA850, MMCSD0_DAT_1, 10, 12, 15, 2, false)
+ MUX_CFG(DA850, MMCSD0_DAT_2, 10, 16, 15, 2, false)
+ MUX_CFG(DA850, MMCSD0_DAT_3, 10, 20, 15, 2, false)
+ MUX_CFG(DA850, MMCSD0_CLK, 10, 0, 15, 2, false)
+ MUX_CFG(DA850, MMCSD0_CMD, 10, 4, 15, 2, false)
+ /* EMIF2.5/EMIFA function */
+ MUX_CFG(DA850, EMA_D_7, 9, 0, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_6, 9, 4, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_5, 9, 8, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_4, 9, 12, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_3, 9, 16, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_2, 9, 20, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_1, 9, 24, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_0, 9, 28, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_1, 12, 24, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_2, 12, 20, 15, 1, false)
+ MUX_CFG(DA850, NEMA_CS_3, 7, 4, 15, 1, false)
+ MUX_CFG(DA850, NEMA_CS_4, 7, 8, 15, 1, false)
+ MUX_CFG(DA850, NEMA_WE, 7, 16, 15, 1, false)
+ MUX_CFG(DA850, NEMA_OE, 7, 20, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_0, 12, 28, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_3, 12, 16, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_4, 12, 12, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_5, 12, 8, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_6, 12, 4, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_7, 12, 0, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_8, 11, 28, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_9, 11, 24, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_10, 11, 20, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_11, 11, 16, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_12, 11, 12, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_13, 11, 8, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_14, 11, 4, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_15, 11, 0, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_16, 10, 28, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_17, 10, 24, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_18, 10, 20, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_19, 10, 16, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_20, 10, 12, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_21, 10, 8, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_22, 10, 4, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_23, 10, 0, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_8, 8, 28, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_9, 8, 24, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_10, 8, 20, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_11, 8, 16, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_12, 8, 12, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_13, 8, 8, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_14, 8, 4, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_15, 8, 0, 15, 1, false)
+ MUX_CFG(DA850, EMA_BA_1, 5, 24, 15, 1, false)
+ MUX_CFG(DA850, EMA_CLK, 6, 0, 15, 1, false)
+ MUX_CFG(DA850, EMA_WAIT_1, 6, 24, 15, 1, false)
+ MUX_CFG(DA850, NEMA_CS_2, 7, 0, 15, 1, false)
+ /* GPIO function */
+ MUX_CFG(DA850, GPIO2_4, 6, 12, 15, 8, false)
+ MUX_CFG(DA850, GPIO2_6, 6, 4, 15, 8, false)
+ MUX_CFG(DA850, GPIO2_8, 5, 28, 15, 8, false)
+ MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false)
+ MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, false)
+ MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false)
+ MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false)
+ MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false)
+ MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false)
+ MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false)
+#endif
+};
+
+const short da850_i2c0_pins[] __initdata = {
+ DA850_I2C0_SDA, DA850_I2C0_SCL,
+ -1
+};
+
+const short da850_i2c1_pins[] __initdata = {
+ DA850_I2C1_SCL, DA850_I2C1_SDA,
+ -1
+};
+
+const short da850_lcdcntl_pins[] __initdata = {
+ DA850_LCD_D_0, DA850_LCD_D_1, DA850_LCD_D_2, DA850_LCD_D_3,
+ DA850_LCD_D_4, DA850_LCD_D_5, DA850_LCD_D_6, DA850_LCD_D_7,
+ DA850_LCD_D_8, DA850_LCD_D_9, DA850_LCD_D_10, DA850_LCD_D_11,
+ DA850_LCD_D_12, DA850_LCD_D_13, DA850_LCD_D_14, DA850_LCD_D_15,
+ DA850_LCD_PCLK, DA850_LCD_HSYNC, DA850_LCD_VSYNC, DA850_NLCD_AC_ENB_CS,
+ -1
+};
+
+/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
+static u8 da850_default_priorities[DA850_N_CP_INTC_IRQ] = {
+ [IRQ_DA8XX_COMMTX] = 7,
+ [IRQ_DA8XX_COMMRX] = 7,
+ [IRQ_DA8XX_NINT] = 7,
+ [IRQ_DA8XX_EVTOUT0] = 7,
+ [IRQ_DA8XX_EVTOUT1] = 7,
+ [IRQ_DA8XX_EVTOUT2] = 7,
+ [IRQ_DA8XX_EVTOUT3] = 7,
+ [IRQ_DA8XX_EVTOUT4] = 7,
+ [IRQ_DA8XX_EVTOUT5] = 7,
+ [IRQ_DA8XX_EVTOUT6] = 7,
+ [IRQ_DA8XX_EVTOUT7] = 7,
+ [IRQ_DA8XX_CCINT0] = 7,
+ [IRQ_DA8XX_CCERRINT] = 7,
+ [IRQ_DA8XX_TCERRINT0] = 7,
+ [IRQ_DA8XX_AEMIFINT] = 7,
+ [IRQ_DA8XX_I2CINT0] = 7,
+ [IRQ_DA8XX_MMCSDINT0] = 7,
+ [IRQ_DA8XX_MMCSDINT1] = 7,
+ [IRQ_DA8XX_ALLINT0] = 7,
+ [IRQ_DA8XX_RTC] = 7,
+ [IRQ_DA8XX_SPINT0] = 7,
+ [IRQ_DA8XX_TINT12_0] = 7,
+ [IRQ_DA8XX_TINT34_0] = 7,
+ [IRQ_DA8XX_TINT12_1] = 7,
+ [IRQ_DA8XX_TINT34_1] = 7,
+ [IRQ_DA8XX_UARTINT0] = 7,
+ [IRQ_DA8XX_KEYMGRINT] = 7,
+ [IRQ_DA850_MPUADDRERR0] = 7,
+ [IRQ_DA8XX_CHIPINT0] = 7,
+ [IRQ_DA8XX_CHIPINT1] = 7,
+ [IRQ_DA8XX_CHIPINT2] = 7,
+ [IRQ_DA8XX_CHIPINT3] = 7,
+ [IRQ_DA8XX_TCERRINT1] = 7,
+ [IRQ_DA8XX_C0_RX_THRESH_PULSE] = 7,
+ [IRQ_DA8XX_C0_RX_PULSE] = 7,
+ [IRQ_DA8XX_C0_TX_PULSE] = 7,
+ [IRQ_DA8XX_C0_MISC_PULSE] = 7,
+ [IRQ_DA8XX_C1_RX_THRESH_PULSE] = 7,
+ [IRQ_DA8XX_C1_RX_PULSE] = 7,
+ [IRQ_DA8XX_C1_TX_PULSE] = 7,
+ [IRQ_DA8XX_C1_MISC_PULSE] = 7,
+ [IRQ_DA8XX_MEMERR] = 7,
+ [IRQ_DA8XX_GPIO0] = 7,
+ [IRQ_DA8XX_GPIO1] = 7,
+ [IRQ_DA8XX_GPIO2] = 7,
+ [IRQ_DA8XX_GPIO3] = 7,
+ [IRQ_DA8XX_GPIO4] = 7,
+ [IRQ_DA8XX_GPIO5] = 7,
+ [IRQ_DA8XX_GPIO6] = 7,
+ [IRQ_DA8XX_GPIO7] = 7,
+ [IRQ_DA8XX_GPIO8] = 7,
+ [IRQ_DA8XX_I2CINT1] = 7,
+ [IRQ_DA8XX_LCDINT] = 7,
+ [IRQ_DA8XX_UARTINT1] = 7,
+ [IRQ_DA8XX_MCASPINT] = 7,
+ [IRQ_DA8XX_ALLINT1] = 7,
+ [IRQ_DA8XX_SPINT1] = 7,
+ [IRQ_DA8XX_UHPI_INT1] = 7,
+ [IRQ_DA8XX_USB_INT] = 7,
+ [IRQ_DA8XX_IRQN] = 7,
+ [IRQ_DA8XX_RWAKEUP] = 7,
+ [IRQ_DA8XX_UARTINT2] = 7,
+ [IRQ_DA8XX_DFTSSINT] = 7,
+ [IRQ_DA8XX_EHRPWM0] = 7,
+ [IRQ_DA8XX_EHRPWM0TZ] = 7,
+ [IRQ_DA8XX_EHRPWM1] = 7,
+ [IRQ_DA8XX_EHRPWM1TZ] = 7,
+ [IRQ_DA850_SATAINT] = 7,
+ [IRQ_DA850_TINTALL_2] = 7,
+ [IRQ_DA8XX_ECAP0] = 7,
+ [IRQ_DA8XX_ECAP1] = 7,
+ [IRQ_DA8XX_ECAP2] = 7,
+ [IRQ_DA850_MMCSDINT0_1] = 7,
+ [IRQ_DA850_MMCSDINT1_1] = 7,
+ [IRQ_DA850_T12CMPINT0_2] = 7,
+ [IRQ_DA850_T12CMPINT1_2] = 7,
+ [IRQ_DA850_T12CMPINT2_2] = 7,
+ [IRQ_DA850_T12CMPINT3_2] = 7,
+ [IRQ_DA850_T12CMPINT4_2] = 7,
+ [IRQ_DA850_T12CMPINT5_2] = 7,
+ [IRQ_DA850_T12CMPINT6_2] = 7,
+ [IRQ_DA850_T12CMPINT7_2] = 7,
+ [IRQ_DA850_T12CMPINT0_3] = 7,
+ [IRQ_DA850_T12CMPINT1_3] = 7,
+ [IRQ_DA850_T12CMPINT2_3] = 7,
+ [IRQ_DA850_T12CMPINT3_3] = 7,
+ [IRQ_DA850_T12CMPINT4_3] = 7,
+ [IRQ_DA850_T12CMPINT5_3] = 7,
+ [IRQ_DA850_T12CMPINT6_3] = 7,
+ [IRQ_DA850_T12CMPINT7_3] = 7,
+ [IRQ_DA850_RPIINT] = 7,
+ [IRQ_DA850_VPIFINT] = 7,
+ [IRQ_DA850_CCINT1] = 7,
+ [IRQ_DA850_CCERRINT1] = 7,
+ [IRQ_DA850_TCERRINT2] = 7,
+ [IRQ_DA850_TINTALL_3] = 7,
+ [IRQ_DA850_MCBSP0RINT] = 7,
+ [IRQ_DA850_MCBSP0XINT] = 7,
+ [IRQ_DA850_MCBSP1RINT] = 7,
+ [IRQ_DA850_MCBSP1XINT] = 7,
+ [IRQ_DA8XX_ARMCLKSTOPREQ] = 7,
+};
+
+static struct map_desc da850_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = DA8XX_CP_INTC_VIRT,
+ .pfn = __phys_to_pfn(DA8XX_CP_INTC_BASE),
+ .length = DA8XX_CP_INTC_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = SRAM_VIRT,
+ .pfn = __phys_to_pfn(DA8XX_ARM_RAM_BASE),
+ .length = SZ_8K,
+ .type = MT_DEVICE
+ },
+};
+
+static u32 da850_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id da850_ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb7d1,
+ .manufacturer = 0x017, /* 0x02f >> 1 */
+ .cpu_id = DAVINCI_CPU_ID_DA850,
+ .name = "da850/omap-l138",
+ },
+ {
+ .variant = 0x1,
+ .part_no = 0xb7d1,
+ .manufacturer = 0x017, /* 0x02f >> 1 */
+ .cpu_id = DAVINCI_CPU_ID_DA850,
+ .name = "da850/omap-l138/am18x",
+ },
+};
+
+static struct davinci_timer_instance da850_timer_instance[4] = {
+ {
+ .base = DA8XX_TIMER64P0_BASE,
+ .bottom_irq = IRQ_DA8XX_TINT12_0,
+ .top_irq = IRQ_DA8XX_TINT34_0,
+ },
+ {
+ .base = DA8XX_TIMER64P1_BASE,
+ .bottom_irq = IRQ_DA8XX_TINT12_1,
+ .top_irq = IRQ_DA8XX_TINT34_1,
+ },
+ {
+ .base = DA850_TIMER64P2_BASE,
+ .bottom_irq = IRQ_DA850_TINT12_2,
+ .top_irq = IRQ_DA850_TINT34_2,
+ },
+ {
+ .base = DA850_TIMER64P3_BASE,
+ .bottom_irq = IRQ_DA850_TINT12_3,
+ .top_irq = IRQ_DA850_TINT34_3,
+ },
+};
+
+/*
+ * T0_BOT: Timer 0, bottom : Used for clock_event
+ * T0_TOP: Timer 0, top : Used for clocksource
+ * T1_BOT, T1_TOP: Timer 1, bottom & top: Used for watchdog timer
+ */
+static struct davinci_timer_info da850_timer_info = {
+ .timers = da850_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
+static void da850_set_async3_src(int pllnum)
+{
+ struct clk *clk, *newparent = pllnum ? &pll1_sysclk2 : &pll0_sysclk2;
+ struct clk_lookup *c;
+ unsigned int v;
+ int ret;
+
+ for (c = da850_clks; c->clk; c++) {
+ clk = c->clk;
+ if (clk->flags & DA850_CLK_ASYNC3) {
+ ret = clk_set_parent(clk, newparent);
+ WARN(ret, "DA850: unable to re-parent clock %s",
+ clk->name);
+ }
+ }
+
+ v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+ if (pllnum)
+ v |= CFGCHIP3_ASYNC3_CLKSRC;
+ else
+ v &= ~CFGCHIP3_ASYNC3_CLKSRC;
+ __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Notes:
+ * According to the TRM, minimum PLLM results in maximum power savings.
+ * The OPP definitions below should keep the PLLM as low as possible.
+ *
+ * The output of the PLLM must be between 300 to 600 MHz.
+ */
+struct da850_opp {
+ unsigned int freq; /* in KHz */
+ unsigned int prediv;
+ unsigned int mult;
+ unsigned int postdiv;
+ unsigned int cvdd_min; /* in uV */
+ unsigned int cvdd_max; /* in uV */
+};
+
+static const struct da850_opp da850_opp_456 = {
+ .freq = 456000,
+ .prediv = 1,
+ .mult = 19,
+ .postdiv = 1,
+ .cvdd_min = 1300000,
+ .cvdd_max = 1350000,
+};
+
+static const struct da850_opp da850_opp_408 = {
+ .freq = 408000,
+ .prediv = 1,
+ .mult = 17,
+ .postdiv = 1,
+ .cvdd_min = 1300000,
+ .cvdd_max = 1350000,
+};
+
+static const struct da850_opp da850_opp_372 = {
+ .freq = 372000,
+ .prediv = 2,
+ .mult = 31,
+ .postdiv = 1,
+ .cvdd_min = 1200000,
+ .cvdd_max = 1320000,
+};
+
+static const struct da850_opp da850_opp_300 = {
+ .freq = 300000,
+ .prediv = 1,
+ .mult = 25,
+ .postdiv = 2,
+ .cvdd_min = 1200000,
+ .cvdd_max = 1320000,
+};
+
+static const struct da850_opp da850_opp_200 = {
+ .freq = 200000,
+ .prediv = 1,
+ .mult = 25,
+ .postdiv = 3,
+ .cvdd_min = 1100000,
+ .cvdd_max = 1160000,
+};
+
+static const struct da850_opp da850_opp_96 = {
+ .freq = 96000,
+ .prediv = 1,
+ .mult = 20,
+ .postdiv = 5,
+ .cvdd_min = 1000000,
+ .cvdd_max = 1050000,
+};
+
+#define OPP(freq) \
+ { \
+ .index = (unsigned int) &da850_opp_##freq, \
+ .frequency = freq * 1000, \
+ }
+
+static struct cpufreq_frequency_table da850_freq_table[] = {
+ OPP(456),
+ OPP(408),
+ OPP(372),
+ OPP(300),
+ OPP(200),
+ OPP(96),
+ {
+ .index = 0,
+ .frequency = CPUFREQ_TABLE_END,
+ },
+};
+
+#ifdef CONFIG_REGULATOR
+static int da850_set_voltage(unsigned int index);
+static int da850_regulator_init(void);
+#endif
+
+static struct davinci_cpufreq_config cpufreq_info = {
+ .freq_table = da850_freq_table,
+#ifdef CONFIG_REGULATOR
+ .init = da850_regulator_init,
+ .set_voltage = da850_set_voltage,
+#endif
+};
+
+#ifdef CONFIG_REGULATOR
+static struct regulator *cvdd;
+
+static int da850_set_voltage(unsigned int index)
+{
+ struct da850_opp *opp;
+
+ if (!cvdd)
+ return -ENODEV;
+
+ opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
+
+ return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max);
+}
+
+static int da850_regulator_init(void)
+{
+ cvdd = regulator_get(NULL, "cvdd");
+ if (WARN(IS_ERR(cvdd), "Unable to obtain voltage regulator for CVDD;"
+ " voltage scaling unsupported\n")) {
+ return PTR_ERR(cvdd);
+ }
+
+ return 0;
+}
+#endif
+
+static struct platform_device da850_cpufreq_device = {
+ .name = "cpufreq-davinci",
+ .dev = {
+ .platform_data = &cpufreq_info,
+ },
+ .id = -1,
+};
+
+unsigned int da850_max_speed = 300000;
+
+int __init da850_register_cpufreq(char *async_clk)
+{
+ int i;
+
+ /* cpufreq driver can help keep an "async" clock constant */
+ if (async_clk)
+ clk_add_alias("async", da850_cpufreq_device.name,
+ async_clk, NULL);
+ for (i = 0; i < ARRAY_SIZE(da850_freq_table); i++) {
+ if (da850_freq_table[i].frequency <= da850_max_speed) {
+ cpufreq_info.freq_table = &da850_freq_table[i];
+ break;
+ }
+ }
+
+ return platform_device_register(&da850_cpufreq_device);
+}
+
+static int da850_round_armrate(struct clk *clk, unsigned long rate)
+{
+ int i, ret = 0, diff;
+ unsigned int best = (unsigned int) -1;
+ struct cpufreq_frequency_table *table = cpufreq_info.freq_table;
+
+ rate /= 1000; /* convert to kHz */
+
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ diff = table[i].frequency - rate;
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff < best) {
+ best = diff;
+ ret = table[i].frequency;
+ }
+ }
+
+ return ret * 1000;
+}
+
+static int da850_set_armrate(struct clk *clk, unsigned long index)
+{
+ struct clk *pllclk = &pll0_clk;
+
+ return clk_set_rate(pllclk, index);
+}
+
+static int da850_set_pll0rate(struct clk *clk, unsigned long index)
+{
+ unsigned int prediv, mult, postdiv;
+ struct da850_opp *opp;
+ struct pll_data *pll = clk->pll_data;
+ int ret;
+
+ opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
+ prediv = opp->prediv;
+ mult = opp->mult;
+ postdiv = opp->postdiv;
+
+ ret = davinci_set_pllrate(pll, prediv, mult, postdiv);
+ if (WARN_ON(ret))
+ return ret;
+
+ return 0;
+}
+#else
+int __init da850_register_cpufreq(char *async_clk)
+{
+ return 0;
+}
+
+static int da850_set_armrate(struct clk *clk, unsigned long rate)
+{
+ return -EINVAL;
+}
+
+static int da850_set_pll0rate(struct clk *clk, unsigned long armrate)
+{
+ return -EINVAL;
+}
+
+static int da850_round_armrate(struct clk *clk, unsigned long rate)
+{
+ return clk->rate;
+}
+#endif
+
+int da850_register_pm(struct platform_device *pdev)
+{
+ int ret;
+ struct davinci_pm_config *pdata = pdev->dev.platform_data;
+
+ ret = davinci_cfg_reg(DA850_RTC_ALARM);
+ if (ret)
+ return ret;
+
+ pdata->ddr2_ctlr_base = da8xx_get_mem_ctlr();
+ pdata->deepsleep_reg = DA8XX_SYSCFG1_VIRT(DA8XX_DEEPSLEEP_REG);
+ pdata->ddrpsc_num = DA8XX_LPSC1_EMIF3C;
+
+ pdata->cpupll_reg_base = ioremap(DA8XX_PLL0_BASE, SZ_4K);
+ if (!pdata->cpupll_reg_base)
+ return -ENOMEM;
+
+ pdata->ddrpll_reg_base = ioremap(DA850_PLL1_BASE, SZ_4K);
+ if (!pdata->ddrpll_reg_base) {
+ ret = -ENOMEM;
+ goto no_ddrpll_mem;
+ }
+
+ pdata->ddrpsc_reg_base = ioremap(DA8XX_PSC1_BASE, SZ_4K);
+ if (!pdata->ddrpsc_reg_base) {
+ ret = -ENOMEM;
+ goto no_ddrpsc_mem;
+ }
+
+ return platform_device_register(pdev);
+
+no_ddrpsc_mem:
+ iounmap(pdata->ddrpll_reg_base);
+no_ddrpll_mem:
+ iounmap(pdata->cpupll_reg_base);
+ return ret;
+}
+
+static struct davinci_soc_info davinci_soc_info_da850 = {
+ .io_desc = da850_io_desc,
+ .io_desc_num = ARRAY_SIZE(da850_io_desc),
+ .jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
+ .ids = da850_ids,
+ .ids_num = ARRAY_SIZE(da850_ids),
+ .cpu_clks = da850_clks,
+ .psc_bases = da850_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(da850_psc_bases),
+ .pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
+ .pinmux_pins = da850_pins,
+ .pinmux_pins_num = ARRAY_SIZE(da850_pins),
+ .intc_base = DA8XX_CP_INTC_BASE,
+ .intc_type = DAVINCI_INTC_TYPE_CP_INTC,
+ .intc_irq_prios = da850_default_priorities,
+ .intc_irq_num = DA850_N_CP_INTC_IRQ,
+ .timer_info = &da850_timer_info,
+ .gpio_type = GPIO_TYPE_DAVINCI,
+ .gpio_base = DA8XX_GPIO_BASE,
+ .gpio_num = 144,
+ .gpio_irq = IRQ_DA8XX_GPIO0,
+ .serial_dev = &da8xx_serial_device,
+ .emac_pdata = &da8xx_emac_pdata,
+ .sram_dma = DA8XX_ARM_RAM_BASE,
+ .sram_len = SZ_8K,
+ .reset_device = &da8xx_wdt_device,
+};
+
+void __init da850_init(void)
+{
+ unsigned int v;
+
+ davinci_common_init(&davinci_soc_info_da850);
+
+ da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
+ if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
+ return;
+
+ da8xx_syscfg1_base = ioremap(DA8XX_SYSCFG1_BASE, SZ_4K);
+ if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module"))
+ return;
+
+ /*
+ * Move the clock source of Async3 domain to PLL1 SYSCLK2.
+ * This helps keeping the peripherals on this domain insulated
+ * from CPU frequency changes caused by DVFS. The firmware sets
+ * both PLL0 and PLL1 to the same frequency so, there should not
+ * be any noticeable change even in non-DVFS use cases.
+ */
+ da850_set_async3_src(1);
+
+ /* Unlock writing to PLL0 registers */
+ v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
+ v &= ~CFGCHIP0_PLL_MASTER_LOCK;
+ __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
+
+ /* Unlock writing to PLL1 registers */
+ v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+ v &= ~CFGCHIP3_PLL1_MASTER_LOCK;
+ __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+}
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
new file mode 100644
index 00000000..fc4e98ea
--- /dev/null
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -0,0 +1,844 @@
+/*
+ * DA8XX/OMAP L1XX platform device data
+ *
+ * Copyright (c) 2007-2009, MontaVista Software, Inc. <source@mvista.com>
+ * Derived from code that was:
+ * Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.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/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/serial_8250.h>
+
+#include <mach/cputype.h>
+#include <mach/common.h>
+#include <mach/time.h>
+#include <mach/da8xx.h>
+#include <mach/cpuidle.h>
+
+#include "clock.h"
+
+#define DA8XX_TPCC_BASE 0x01c00000
+#define DA8XX_TPTC0_BASE 0x01c08000
+#define DA8XX_TPTC1_BASE 0x01c08400
+#define DA8XX_WDOG_BASE 0x01c21000 /* DA8XX_TIMER64P1_BASE */
+#define DA8XX_I2C0_BASE 0x01c22000
+#define DA8XX_RTC_BASE 0x01c23000
+#define DA8XX_MMCSD0_BASE 0x01c40000
+#define DA8XX_SPI0_BASE 0x01c41000
+#define DA830_SPI1_BASE 0x01e12000
+#define DA8XX_LCD_CNTRL_BASE 0x01e13000
+#define DA850_MMCSD1_BASE 0x01e1b000
+#define DA8XX_EMAC_CPPI_PORT_BASE 0x01e20000
+#define DA8XX_EMAC_CPGMACSS_BASE 0x01e22000
+#define DA8XX_EMAC_CPGMAC_BASE 0x01e23000
+#define DA8XX_EMAC_MDIO_BASE 0x01e24000
+#define DA8XX_I2C1_BASE 0x01e28000
+#define DA850_TPCC1_BASE 0x01e30000
+#define DA850_TPTC2_BASE 0x01e38000
+#define DA850_SPI1_BASE 0x01f0e000
+#define DA8XX_DDR2_CTL_BASE 0xb0000000
+
+#define DA8XX_EMAC_CTRL_REG_OFFSET 0x3000
+#define DA8XX_EMAC_MOD_REG_OFFSET 0x2000
+#define DA8XX_EMAC_RAM_OFFSET 0x0000
+#define DA8XX_EMAC_CTRL_RAM_SIZE SZ_8K
+
+#define DA8XX_DMA_SPI0_RX EDMA_CTLR_CHAN(0, 14)
+#define DA8XX_DMA_SPI0_TX EDMA_CTLR_CHAN(0, 15)
+#define DA8XX_DMA_MMCSD0_RX EDMA_CTLR_CHAN(0, 16)
+#define DA8XX_DMA_MMCSD0_TX EDMA_CTLR_CHAN(0, 17)
+#define DA8XX_DMA_SPI1_RX EDMA_CTLR_CHAN(0, 18)
+#define DA8XX_DMA_SPI1_TX EDMA_CTLR_CHAN(0, 19)
+#define DA850_DMA_MMCSD1_RX EDMA_CTLR_CHAN(1, 28)
+#define DA850_DMA_MMCSD1_TX EDMA_CTLR_CHAN(1, 29)
+
+void __iomem *da8xx_syscfg0_base;
+void __iomem *da8xx_syscfg1_base;
+
+static struct plat_serial8250_port da8xx_serial_pdata[] = {
+ {
+ .mapbase = DA8XX_UART0_BASE,
+ .irq = IRQ_DA8XX_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DA8XX_UART1_BASE,
+ .irq = IRQ_DA8XX_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DA8XX_UART2_BASE,
+ .irq = IRQ_DA8XX_UARTINT2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ },
+};
+
+struct platform_device da8xx_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = da8xx_serial_pdata,
+ },
+};
+
+static const s8 da8xx_queue_tc_mapping[][2] = {
+ /* {event queue no, TC no} */
+ {0, 0},
+ {1, 1},
+ {-1, -1}
+};
+
+static const s8 da8xx_queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 3},
+ {1, 7},
+ {-1, -1}
+};
+
+static const s8 da850_queue_tc_mapping[][2] = {
+ /* {event queue no, TC no} */
+ {0, 0},
+ {-1, -1}
+};
+
+static const s8 da850_queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 3},
+ {-1, -1}
+};
+
+static struct edma_soc_info da830_edma_cc0_info = {
+ .n_channel = 32,
+ .n_region = 4,
+ .n_slot = 128,
+ .n_tc = 2,
+ .n_cc = 1,
+ .queue_tc_mapping = da8xx_queue_tc_mapping,
+ .queue_priority_mapping = da8xx_queue_priority_mapping,
+};
+
+static struct edma_soc_info *da830_edma_info[EDMA_MAX_CC] = {
+ &da830_edma_cc0_info,
+};
+
+static struct edma_soc_info da850_edma_cc_info[] = {
+ {
+ .n_channel = 32,
+ .n_region = 4,
+ .n_slot = 128,
+ .n_tc = 2,
+ .n_cc = 1,
+ .queue_tc_mapping = da8xx_queue_tc_mapping,
+ .queue_priority_mapping = da8xx_queue_priority_mapping,
+ },
+ {
+ .n_channel = 32,
+ .n_region = 4,
+ .n_slot = 128,
+ .n_tc = 1,
+ .n_cc = 1,
+ .queue_tc_mapping = da850_queue_tc_mapping,
+ .queue_priority_mapping = da850_queue_priority_mapping,
+ },
+};
+
+static struct edma_soc_info *da850_edma_info[EDMA_MAX_CC] = {
+ &da850_edma_cc_info[0],
+ &da850_edma_cc_info[1],
+};
+
+static struct resource da830_edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = DA8XX_TPCC_BASE,
+ .end = DA8XX_TPCC_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = DA8XX_TPTC0_BASE,
+ .end = DA8XX_TPTC0_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = DA8XX_TPTC1_BASE,
+ .end = DA8XX_TPTC1_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_DA8XX_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_DA8XX_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource da850_edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = DA8XX_TPCC_BASE,
+ .end = DA8XX_TPCC_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = DA8XX_TPTC0_BASE,
+ .end = DA8XX_TPTC0_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = DA8XX_TPTC1_BASE,
+ .end = DA8XX_TPTC1_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_cc1",
+ .start = DA850_TPCC1_BASE,
+ .end = DA850_TPCC1_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc2",
+ .start = DA850_TPTC2_BASE,
+ .end = DA850_TPTC2_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_DA8XX_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_DA8XX_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma1",
+ .start = IRQ_DA850_CCINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma1_err",
+ .start = IRQ_DA850_CCERRINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da830_edma_device = {
+ .name = "edma",
+ .id = -1,
+ .dev = {
+ .platform_data = da830_edma_info,
+ },
+ .num_resources = ARRAY_SIZE(da830_edma_resources),
+ .resource = da830_edma_resources,
+};
+
+static struct platform_device da850_edma_device = {
+ .name = "edma",
+ .id = -1,
+ .dev = {
+ .platform_data = da850_edma_info,
+ },
+ .num_resources = ARRAY_SIZE(da850_edma_resources),
+ .resource = da850_edma_resources,
+};
+
+int __init da830_register_edma(struct edma_rsv_info *rsv)
+{
+ da830_edma_cc0_info.rsv = rsv;
+
+ return platform_device_register(&da830_edma_device);
+}
+
+int __init da850_register_edma(struct edma_rsv_info *rsv[2])
+{
+ if (rsv) {
+ da850_edma_cc_info[0].rsv = rsv[0];
+ da850_edma_cc_info[1].rsv = rsv[1];
+ }
+
+ return platform_device_register(&da850_edma_device);
+}
+
+static struct resource da8xx_i2c_resources0[] = {
+ {
+ .start = DA8XX_I2C0_BASE,
+ .end = DA8XX_I2C0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DA8XX_I2CINT0,
+ .end = IRQ_DA8XX_I2CINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da8xx_i2c_device0 = {
+ .name = "i2c_davinci",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(da8xx_i2c_resources0),
+ .resource = da8xx_i2c_resources0,
+};
+
+static struct resource da8xx_i2c_resources1[] = {
+ {
+ .start = DA8XX_I2C1_BASE,
+ .end = DA8XX_I2C1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DA8XX_I2CINT1,
+ .end = IRQ_DA8XX_I2CINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da8xx_i2c_device1 = {
+ .name = "i2c_davinci",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(da8xx_i2c_resources1),
+ .resource = da8xx_i2c_resources1,
+};
+
+int __init da8xx_register_i2c(int instance,
+ struct davinci_i2c_platform_data *pdata)
+{
+ struct platform_device *pdev;
+
+ if (instance == 0)
+ pdev = &da8xx_i2c_device0;
+ else if (instance == 1)
+ pdev = &da8xx_i2c_device1;
+ else
+ return -EINVAL;
+
+ pdev->dev.platform_data = pdata;
+ return platform_device_register(pdev);
+}
+
+static struct resource da8xx_watchdog_resources[] = {
+ {
+ .start = DA8XX_WDOG_BASE,
+ .end = DA8XX_WDOG_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device da8xx_wdt_device = {
+ .name = "watchdog",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(da8xx_watchdog_resources),
+ .resource = da8xx_watchdog_resources,
+};
+
+int __init da8xx_register_watchdog(void)
+{
+ return platform_device_register(&da8xx_wdt_device);
+}
+
+static struct resource da8xx_emac_resources[] = {
+ {
+ .start = DA8XX_EMAC_CPPI_PORT_BASE,
+ .end = DA8XX_EMAC_CPPI_PORT_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DA8XX_C0_RX_THRESH_PULSE,
+ .end = IRQ_DA8XX_C0_RX_THRESH_PULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA8XX_C0_RX_PULSE,
+ .end = IRQ_DA8XX_C0_RX_PULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA8XX_C0_TX_PULSE,
+ .end = IRQ_DA8XX_C0_TX_PULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA8XX_C0_MISC_PULSE,
+ .end = IRQ_DA8XX_C0_MISC_PULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct emac_platform_data da8xx_emac_pdata = {
+ .ctrl_reg_offset = DA8XX_EMAC_CTRL_REG_OFFSET,
+ .ctrl_mod_reg_offset = DA8XX_EMAC_MOD_REG_OFFSET,
+ .ctrl_ram_offset = DA8XX_EMAC_RAM_OFFSET,
+ .ctrl_ram_size = DA8XX_EMAC_CTRL_RAM_SIZE,
+ .version = EMAC_VERSION_2,
+};
+
+static struct platform_device da8xx_emac_device = {
+ .name = "davinci_emac",
+ .id = 1,
+ .dev = {
+ .platform_data = &da8xx_emac_pdata,
+ },
+ .num_resources = ARRAY_SIZE(da8xx_emac_resources),
+ .resource = da8xx_emac_resources,
+};
+
+static struct resource da8xx_mdio_resources[] = {
+ {
+ .start = DA8XX_EMAC_MDIO_BASE,
+ .end = DA8XX_EMAC_MDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da8xx_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(da8xx_mdio_resources),
+ .resource = da8xx_mdio_resources,
+};
+
+int __init da8xx_register_emac(void)
+{
+ int ret;
+
+ ret = platform_device_register(&da8xx_mdio_device);
+ if (ret < 0)
+ return ret;
+ ret = platform_device_register(&da8xx_emac_device);
+ if (ret < 0)
+ return ret;
+ ret = clk_add_alias(NULL, dev_name(&da8xx_mdio_device.dev),
+ NULL, &da8xx_emac_device.dev);
+ return ret;
+}
+
+static struct resource da830_mcasp1_resources[] = {
+ {
+ .name = "mcasp1",
+ .start = DAVINCI_DA830_MCASP1_REG_BASE,
+ .end = DAVINCI_DA830_MCASP1_REG_BASE + (SZ_1K * 12) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* TX event */
+ {
+ .start = DAVINCI_DA830_DMA_MCASP1_AXEVT,
+ .end = DAVINCI_DA830_DMA_MCASP1_AXEVT,
+ .flags = IORESOURCE_DMA,
+ },
+ /* RX event */
+ {
+ .start = DAVINCI_DA830_DMA_MCASP1_AREVT,
+ .end = DAVINCI_DA830_DMA_MCASP1_AREVT,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device da830_mcasp1_device = {
+ .name = "davinci-mcasp",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(da830_mcasp1_resources),
+ .resource = da830_mcasp1_resources,
+};
+
+static struct resource da850_mcasp_resources[] = {
+ {
+ .name = "mcasp",
+ .start = DAVINCI_DA8XX_MCASP0_REG_BASE,
+ .end = DAVINCI_DA8XX_MCASP0_REG_BASE + (SZ_1K * 12) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* TX event */
+ {
+ .start = DAVINCI_DA8XX_DMA_MCASP0_AXEVT,
+ .end = DAVINCI_DA8XX_DMA_MCASP0_AXEVT,
+ .flags = IORESOURCE_DMA,
+ },
+ /* RX event */
+ {
+ .start = DAVINCI_DA8XX_DMA_MCASP0_AREVT,
+ .end = DAVINCI_DA8XX_DMA_MCASP0_AREVT,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device da850_mcasp_device = {
+ .name = "davinci-mcasp",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(da850_mcasp_resources),
+ .resource = da850_mcasp_resources,
+};
+
+static struct platform_device davinci_pcm_device = {
+ .name = "davinci-pcm-audio",
+ .id = -1,
+};
+
+void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata)
+{
+ platform_device_register(&davinci_pcm_device);
+
+ /* DA830/OMAP-L137 has 3 instances of McASP */
+ if (cpu_is_davinci_da830() && id == 1) {
+ da830_mcasp1_device.dev.platform_data = pdata;
+ platform_device_register(&da830_mcasp1_device);
+ } else if (cpu_is_davinci_da850()) {
+ da850_mcasp_device.dev.platform_data = pdata;
+ platform_device_register(&da850_mcasp_device);
+ }
+}
+
+static const struct display_panel disp_panel = {
+ QVGA,
+ 16,
+ 16,
+ COLOR_ACTIVE,
+};
+
+static struct lcd_ctrl_config lcd_cfg = {
+ &disp_panel,
+ .ac_bias = 255,
+ .ac_bias_intrpt = 0,
+ .dma_burst_sz = 16,
+ .bpp = 16,
+ .fdd = 255,
+ .tft_alt_mode = 0,
+ .stn_565_mode = 0,
+ .mono_8bit_mode = 0,
+ .invert_line_clock = 1,
+ .invert_frm_clock = 1,
+ .sync_edge = 0,
+ .sync_ctrl = 1,
+ .raster_order = 0,
+};
+
+struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = {
+ .manu_name = "sharp",
+ .controller_data = &lcd_cfg,
+ .type = "Sharp_LCD035Q3DG01",
+};
+
+struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata = {
+ .manu_name = "sharp",
+ .controller_data = &lcd_cfg,
+ .type = "Sharp_LK043T1DG01",
+};
+
+static struct resource da8xx_lcdc_resources[] = {
+ [0] = { /* registers */
+ .start = DA8XX_LCD_CNTRL_BASE,
+ .end = DA8XX_LCD_CNTRL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* interrupt */
+ .start = IRQ_DA8XX_LCDINT,
+ .end = IRQ_DA8XX_LCDINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da8xx_lcdc_device = {
+ .name = "da8xx_lcdc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(da8xx_lcdc_resources),
+ .resource = da8xx_lcdc_resources,
+};
+
+int __init da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata)
+{
+ da8xx_lcdc_device.dev.platform_data = pdata;
+ return platform_device_register(&da8xx_lcdc_device);
+}
+
+static struct resource da8xx_mmcsd0_resources[] = {
+ { /* registers */
+ .start = DA8XX_MMCSD0_BASE,
+ .end = DA8XX_MMCSD0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* interrupt */
+ .start = IRQ_DA8XX_MMCSDINT0,
+ .end = IRQ_DA8XX_MMCSDINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ { /* DMA RX */
+ .start = DA8XX_DMA_MMCSD0_RX,
+ .end = DA8XX_DMA_MMCSD0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ { /* DMA TX */
+ .start = DA8XX_DMA_MMCSD0_TX,
+ .end = DA8XX_DMA_MMCSD0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device da8xx_mmcsd0_device = {
+ .name = "davinci_mmc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(da8xx_mmcsd0_resources),
+ .resource = da8xx_mmcsd0_resources,
+};
+
+int __init da8xx_register_mmcsd0(struct davinci_mmc_config *config)
+{
+ da8xx_mmcsd0_device.dev.platform_data = config;
+ return platform_device_register(&da8xx_mmcsd0_device);
+}
+
+#ifdef CONFIG_ARCH_DAVINCI_DA850
+static struct resource da850_mmcsd1_resources[] = {
+ { /* registers */
+ .start = DA850_MMCSD1_BASE,
+ .end = DA850_MMCSD1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* interrupt */
+ .start = IRQ_DA850_MMCSDINT0_1,
+ .end = IRQ_DA850_MMCSDINT0_1,
+ .flags = IORESOURCE_IRQ,
+ },
+ { /* DMA RX */
+ .start = DA850_DMA_MMCSD1_RX,
+ .end = DA850_DMA_MMCSD1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ { /* DMA TX */
+ .start = DA850_DMA_MMCSD1_TX,
+ .end = DA850_DMA_MMCSD1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device da850_mmcsd1_device = {
+ .name = "davinci_mmc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(da850_mmcsd1_resources),
+ .resource = da850_mmcsd1_resources,
+};
+
+int __init da850_register_mmcsd1(struct davinci_mmc_config *config)
+{
+ da850_mmcsd1_device.dev.platform_data = config;
+ return platform_device_register(&da850_mmcsd1_device);
+}
+#endif
+
+static struct resource da8xx_rtc_resources[] = {
+ {
+ .start = DA8XX_RTC_BASE,
+ .end = DA8XX_RTC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* timer irq */
+ .start = IRQ_DA8XX_RTC,
+ .end = IRQ_DA8XX_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+ { /* alarm irq */
+ .start = IRQ_DA8XX_RTC,
+ .end = IRQ_DA8XX_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da8xx_rtc_device = {
+ .name = "omap_rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(da8xx_rtc_resources),
+ .resource = da8xx_rtc_resources,
+};
+
+int da8xx_register_rtc(void)
+{
+ int ret;
+ void __iomem *base;
+
+ base = ioremap(DA8XX_RTC_BASE, SZ_4K);
+ if (WARN_ON(!base))
+ return -ENOMEM;
+
+ /* Unlock the rtc's registers */
+ __raw_writel(0x83e70b13, base + 0x6c);
+ __raw_writel(0x95a4f1e0, base + 0x70);
+
+ iounmap(base);
+
+ ret = platform_device_register(&da8xx_rtc_device);
+ if (!ret)
+ /* Atleast on DA850, RTC is a wakeup source */
+ device_init_wakeup(&da8xx_rtc_device.dev, true);
+
+ return ret;
+}
+
+static void __iomem *da8xx_ddr2_ctlr_base;
+void __iomem * __init da8xx_get_mem_ctlr(void)
+{
+ if (da8xx_ddr2_ctlr_base)
+ return da8xx_ddr2_ctlr_base;
+
+ da8xx_ddr2_ctlr_base = ioremap(DA8XX_DDR2_CTL_BASE, SZ_32K);
+ if (!da8xx_ddr2_ctlr_base)
+ pr_warning("%s: Unable to map DDR2 controller", __func__);
+
+ return da8xx_ddr2_ctlr_base;
+}
+
+static struct resource da8xx_cpuidle_resources[] = {
+ {
+ .start = DA8XX_DDR2_CTL_BASE,
+ .end = DA8XX_DDR2_CTL_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+/* DA8XX devices support DDR2 power down */
+static struct davinci_cpuidle_config da8xx_cpuidle_pdata = {
+ .ddr2_pdown = 1,
+};
+
+
+static struct platform_device da8xx_cpuidle_device = {
+ .name = "cpuidle-davinci",
+ .num_resources = ARRAY_SIZE(da8xx_cpuidle_resources),
+ .resource = da8xx_cpuidle_resources,
+ .dev = {
+ .platform_data = &da8xx_cpuidle_pdata,
+ },
+};
+
+int __init da8xx_register_cpuidle(void)
+{
+ da8xx_cpuidle_pdata.ddr2_ctlr_base = da8xx_get_mem_ctlr();
+
+ return platform_device_register(&da8xx_cpuidle_device);
+}
+
+static struct resource da8xx_spi0_resources[] = {
+ [0] = {
+ .start = DA8XX_SPI0_BASE,
+ .end = DA8XX_SPI0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DA8XX_SPINT0,
+ .end = IRQ_DA8XX_SPINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DA8XX_DMA_SPI0_RX,
+ .end = DA8XX_DMA_SPI0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DA8XX_DMA_SPI0_TX,
+ .end = DA8XX_DMA_SPI0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct resource da8xx_spi1_resources[] = {
+ [0] = {
+ .start = DA830_SPI1_BASE,
+ .end = DA830_SPI1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DA8XX_SPINT1,
+ .end = IRQ_DA8XX_SPINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DA8XX_DMA_SPI1_RX,
+ .end = DA8XX_DMA_SPI1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DA8XX_DMA_SPI1_TX,
+ .end = DA8XX_DMA_SPI1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct davinci_spi_platform_data da8xx_spi_pdata[] = {
+ [0] = {
+ .version = SPI_VERSION_2,
+ .intr_line = 1,
+ .dma_event_q = EVENTQ_0,
+ },
+ [1] = {
+ .version = SPI_VERSION_2,
+ .intr_line = 1,
+ .dma_event_q = EVENTQ_0,
+ },
+};
+
+static struct platform_device da8xx_spi_device[] = {
+ [0] = {
+ .name = "spi_davinci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(da8xx_spi0_resources),
+ .resource = da8xx_spi0_resources,
+ .dev = {
+ .platform_data = &da8xx_spi_pdata[0],
+ },
+ },
+ [1] = {
+ .name = "spi_davinci",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(da8xx_spi1_resources),
+ .resource = da8xx_spi1_resources,
+ .dev = {
+ .platform_data = &da8xx_spi_pdata[1],
+ },
+ },
+};
+
+int __init da8xx_register_spi(int instance, struct spi_board_info *info,
+ unsigned len)
+{
+ int ret;
+
+ if (instance < 0 || instance > 1)
+ return -EINVAL;
+
+ ret = spi_register_board_info(info, len);
+ if (ret)
+ pr_warning("%s: failed to register board info for spi %d :"
+ " %d\n", __func__, instance, ret);
+
+ da8xx_spi_pdata[instance].num_chipselect = len;
+
+ if (instance == 1 && cpu_is_davinci_da850()) {
+ da8xx_spi1_resources[0].start = DA850_SPI1_BASE;
+ da8xx_spi1_resources[0].end = DA850_SPI1_BASE + SZ_4K - 1;
+ }
+
+ return platform_device_register(&da8xx_spi_device[instance]);
+}
diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c
new file mode 100644
index 00000000..6162cae7
--- /dev/null
+++ b/arch/arm/mach-davinci/devices-tnetv107x.c
@@ -0,0 +1,408 @@
+/*
+ * Texas Instruments TNETV107X SoC devices
+ *
+ * Copyright (C) 2010 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+
+#include <mach/common.h>
+#include <mach/irqs.h>
+#include <mach/edma.h>
+#include <mach/tnetv107x.h>
+
+#include "clock.h"
+
+/* Base addresses for on-chip devices */
+#define TNETV107X_TPCC_BASE 0x01c00000
+#define TNETV107X_TPTC0_BASE 0x01c10000
+#define TNETV107X_TPTC1_BASE 0x01c10400
+#define TNETV107X_WDOG_BASE 0x08086700
+#define TNETV107X_TSC_BASE 0x08088500
+#define TNETV107X_SDIO0_BASE 0x08088700
+#define TNETV107X_SDIO1_BASE 0x08088800
+#define TNETV107X_KEYPAD_BASE 0x08088a00
+#define TNETV107X_SSP_BASE 0x08088c00
+#define TNETV107X_ASYNC_EMIF_CNTRL_BASE 0x08200000
+#define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE 0x30000000
+#define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE 0x40000000
+#define TNETV107X_ASYNC_EMIF_DATA_CE2_BASE 0x44000000
+#define TNETV107X_ASYNC_EMIF_DATA_CE3_BASE 0x48000000
+
+/* TNETV107X specific EDMA3 information */
+#define EDMA_TNETV107X_NUM_DMACH 64
+#define EDMA_TNETV107X_NUM_TCC 64
+#define EDMA_TNETV107X_NUM_PARAMENTRY 128
+#define EDMA_TNETV107X_NUM_EVQUE 2
+#define EDMA_TNETV107X_NUM_TC 2
+#define EDMA_TNETV107X_CHMAP_EXIST 0
+#define EDMA_TNETV107X_NUM_REGIONS 4
+#define TNETV107X_DMACH2EVENT_MAP0 0x3C0CE000u
+#define TNETV107X_DMACH2EVENT_MAP1 0x000FFFFFu
+
+#define TNETV107X_DMACH_SDIO0_RX 26
+#define TNETV107X_DMACH_SDIO0_TX 27
+#define TNETV107X_DMACH_SDIO1_RX 28
+#define TNETV107X_DMACH_SDIO1_TX 29
+
+static const s8 edma_tc_mapping[][2] = {
+ /* event queue no TC no */
+ { 0, 0 },
+ { 1, 1 },
+ { -1, -1 }
+};
+
+static const s8 edma_priority_mapping[][2] = {
+ /* event queue no Prio */
+ { 0, 3 },
+ { 1, 7 },
+ { -1, -1 }
+};
+
+static struct edma_soc_info edma_cc0_info = {
+ .n_channel = EDMA_TNETV107X_NUM_DMACH,
+ .n_region = EDMA_TNETV107X_NUM_REGIONS,
+ .n_slot = EDMA_TNETV107X_NUM_PARAMENTRY,
+ .n_tc = EDMA_TNETV107X_NUM_TC,
+ .n_cc = 1,
+ .queue_tc_mapping = edma_tc_mapping,
+ .queue_priority_mapping = edma_priority_mapping,
+};
+
+static struct edma_soc_info *tnetv107x_edma_info[EDMA_MAX_CC] = {
+ &edma_cc0_info,
+};
+
+static struct resource edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = TNETV107X_TPCC_BASE,
+ .end = TNETV107X_TPCC_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = TNETV107X_TPTC0_BASE,
+ .end = TNETV107X_TPTC0_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = TNETV107X_TPTC1_BASE,
+ .end = TNETV107X_TPTC1_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_TNETV107X_TPCC,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_TNETV107X_TPCC_ERR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device edma_device = {
+ .name = "edma",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(edma_resources),
+ .resource = edma_resources,
+ .dev.platform_data = tnetv107x_edma_info,
+};
+
+static struct plat_serial8250_port serial_data[] = {
+ {
+ .mapbase = TNETV107X_UART0_BASE,
+ .irq = IRQ_TNETV107X_UART0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_FIXED_TYPE | UPF_IOREMAP,
+ .type = PORT_AR7,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .mapbase = TNETV107X_UART1_BASE,
+ .irq = IRQ_TNETV107X_UART1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_FIXED_TYPE | UPF_IOREMAP,
+ .type = PORT_AR7,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .mapbase = TNETV107X_UART2_BASE,
+ .irq = IRQ_TNETV107X_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_FIXED_TYPE | UPF_IOREMAP,
+ .type = PORT_AR7,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ },
+};
+
+struct platform_device tnetv107x_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = serial_data,
+};
+
+static struct resource mmc0_resources[] = {
+ { /* Memory mapped registers */
+ .start = TNETV107X_SDIO0_BASE,
+ .end = TNETV107X_SDIO0_BASE + 0x0ff,
+ .flags = IORESOURCE_MEM
+ },
+ { /* MMC interrupt */
+ .start = IRQ_TNETV107X_MMC0,
+ .flags = IORESOURCE_IRQ
+ },
+ { /* SDIO interrupt */
+ .start = IRQ_TNETV107X_SDIO0,
+ .flags = IORESOURCE_IRQ
+ },
+ { /* DMA RX */
+ .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_RX),
+ .flags = IORESOURCE_DMA
+ },
+ { /* DMA TX */
+ .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_TX),
+ .flags = IORESOURCE_DMA
+ },
+};
+
+static struct resource mmc1_resources[] = {
+ { /* Memory mapped registers */
+ .start = TNETV107X_SDIO1_BASE,
+ .end = TNETV107X_SDIO1_BASE + 0x0ff,
+ .flags = IORESOURCE_MEM
+ },
+ { /* MMC interrupt */
+ .start = IRQ_TNETV107X_MMC1,
+ .flags = IORESOURCE_IRQ
+ },
+ { /* SDIO interrupt */
+ .start = IRQ_TNETV107X_SDIO1,
+ .flags = IORESOURCE_IRQ
+ },
+ { /* DMA RX */
+ .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_RX),
+ .flags = IORESOURCE_DMA
+ },
+ { /* DMA TX */
+ .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_TX),
+ .flags = IORESOURCE_DMA
+ },
+};
+
+static u64 mmc0_dma_mask = DMA_BIT_MASK(32);
+static u64 mmc1_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device mmc_devices[2] = {
+ {
+ .name = "davinci_mmc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &mmc0_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(mmc0_resources),
+ .resource = mmc0_resources
+ },
+ {
+ .name = "davinci_mmc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &mmc1_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(mmc1_resources),
+ .resource = mmc1_resources
+ },
+};
+
+static const u32 emif_windows[] = {
+ TNETV107X_ASYNC_EMIF_DATA_CE0_BASE, TNETV107X_ASYNC_EMIF_DATA_CE1_BASE,
+ TNETV107X_ASYNC_EMIF_DATA_CE2_BASE, TNETV107X_ASYNC_EMIF_DATA_CE3_BASE,
+};
+
+static const u32 emif_window_sizes[] = { SZ_256M, SZ_64M, SZ_64M, SZ_64M };
+
+static struct resource wdt_resources[] = {
+ {
+ .start = TNETV107X_WDOG_BASE,
+ .end = TNETV107X_WDOG_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device tnetv107x_wdt_device = {
+ .name = "tnetv107x_wdt",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static int __init nand_init(int chipsel, struct davinci_nand_pdata *data)
+{
+ struct resource res[2];
+ struct platform_device *pdev;
+ u32 range;
+ int ret;
+
+ /* Figure out the resource range from the ale/cle masks */
+ range = max(data->mask_cle, data->mask_ale);
+ range = PAGE_ALIGN(range + 4) - 1;
+
+ if (range >= emif_window_sizes[chipsel])
+ return -EINVAL;
+
+ pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
+ if (!pdev)
+ return -ENOMEM;
+
+ pdev->name = "davinci_nand";
+ pdev->id = chipsel;
+ pdev->dev.platform_data = data;
+
+ memset(res, 0, sizeof(res));
+
+ res[0].start = emif_windows[chipsel];
+ res[0].end = res[0].start + range;
+ res[0].flags = IORESOURCE_MEM;
+
+ res[1].start = TNETV107X_ASYNC_EMIF_CNTRL_BASE;
+ res[1].end = res[1].start + SZ_4K - 1;
+ res[1].flags = IORESOURCE_MEM;
+
+ ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+ if (ret < 0) {
+ kfree(pdev);
+ return ret;
+ }
+
+ return platform_device_register(pdev);
+}
+
+static struct resource keypad_resources[] = {
+ {
+ .start = TNETV107X_KEYPAD_BASE,
+ .end = TNETV107X_KEYPAD_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_TNETV107X_KEYPAD,
+ .flags = IORESOURCE_IRQ,
+ .name = "press",
+ },
+ {
+ .start = IRQ_TNETV107X_KEYPAD_FREE,
+ .flags = IORESOURCE_IRQ,
+ .name = "release",
+ },
+};
+
+static struct platform_device keypad_device = {
+ .name = "tnetv107x-keypad",
+ .num_resources = ARRAY_SIZE(keypad_resources),
+ .resource = keypad_resources,
+};
+
+static struct resource tsc_resources[] = {
+ {
+ .start = TNETV107X_TSC_BASE,
+ .end = TNETV107X_TSC_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_TNETV107X_TSC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tsc_device = {
+ .name = "tnetv107x-ts",
+ .num_resources = ARRAY_SIZE(tsc_resources),
+ .resource = tsc_resources,
+};
+
+static struct resource ssp_resources[] = {
+ {
+ .start = TNETV107X_SSP_BASE,
+ .end = TNETV107X_SSP_BASE + 0x1ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_TNETV107X_SSP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ssp_device = {
+ .name = "ti-ssp",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ssp_resources),
+ .resource = ssp_resources,
+};
+
+void __init tnetv107x_devices_init(struct tnetv107x_device_info *info)
+{
+ int i, error;
+ struct clk *tsc_clk;
+
+ /*
+ * The reset defaults for tnetv107x tsc clock divider is set too high.
+ * This forces the clock down to a range that allows the ADC to
+ * complete sample conversion in time.
+ */
+ tsc_clk = clk_get(NULL, "sys_tsc_clk");
+ if (tsc_clk) {
+ error = clk_set_rate(tsc_clk, 5000000);
+ WARN_ON(error < 0);
+ clk_put(tsc_clk);
+ }
+
+ platform_device_register(&edma_device);
+ platform_device_register(&tnetv107x_wdt_device);
+ platform_device_register(&tsc_device);
+
+ if (info->serial_config)
+ davinci_serial_init(info->serial_config);
+
+ for (i = 0; i < 2; i++)
+ if (info->mmc_config[i]) {
+ mmc_devices[i].dev.platform_data = info->mmc_config[i];
+ platform_device_register(&mmc_devices[i]);
+ }
+
+ for (i = 0; i < 4; i++)
+ if (info->nand_config[i])
+ nand_init(i, info->nand_config[i]);
+
+ if (info->keypad_config) {
+ keypad_device.dev.platform_data = info->keypad_config;
+ platform_device_register(&keypad_device);
+ }
+
+ if (info->ssp_config) {
+ ssp_device.dev.platform_data = info->ssp_config;
+ platform_device_register(&ssp_device);
+ }
+}
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
new file mode 100644
index 00000000..806a2f02
--- /dev/null
+++ b/arch/arm/mach-davinci/devices.c
@@ -0,0 +1,339 @@
+/*
+ * mach-davinci/devices.c
+ *
+ * DaVinci platform device setup/initialization
+ *
+ * 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/i2c.h>
+#include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <mach/mux.h>
+#include <mach/edma.h>
+#include <mach/mmc.h>
+#include <mach/time.h>
+
+#include "clock.h"
+
+#define DAVINCI_I2C_BASE 0x01C21000
+#define DAVINCI_ATA_BASE 0x01C66000
+#define DAVINCI_MMCSD0_BASE 0x01E10000
+#define DM355_MMCSD0_BASE 0x01E11000
+#define DM355_MMCSD1_BASE 0x01E00000
+#define DM365_MMCSD0_BASE 0x01D11000
+#define DM365_MMCSD1_BASE 0x01D00000
+
+/* System control register offsets */
+#define DM64XX_VDD3P3V_PWDN 0x48
+
+static struct resource i2c_resources[] = {
+ {
+ .start = DAVINCI_I2C_BASE,
+ .end = DAVINCI_I2C_BASE + 0x40,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device davinci_i2c_device = {
+ .name = "i2c_davinci",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(i2c_resources),
+ .resource = i2c_resources,
+};
+
+void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
+{
+ if (cpu_is_davinci_dm644x())
+ davinci_cfg_reg(DM644X_I2C);
+
+ davinci_i2c_device.dev.platform_data = pdata;
+ (void) platform_device_register(&davinci_i2c_device);
+}
+
+static struct resource ide_resources[] = {
+ {
+ .start = DAVINCI_ATA_BASE,
+ .end = DAVINCI_ATA_BASE + 0x7ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_IDE,
+ .end = IRQ_IDE,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ide_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ide_device = {
+ .name = "palm_bk3710",
+ .id = -1,
+ .resource = ide_resources,
+ .num_resources = ARRAY_SIZE(ide_resources),
+ .dev = {
+ .dma_mask = &ide_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init davinci_init_ide(void)
+{
+ if (cpu_is_davinci_dm644x()) {
+ davinci_cfg_reg(DM644X_HPIEN_DISABLE);
+ davinci_cfg_reg(DM644X_ATAEN);
+ davinci_cfg_reg(DM644X_HDIREN);
+ } else if (cpu_is_davinci_dm646x()) {
+ /* IRQ_DM646X_IDE is the same as IRQ_IDE */
+ davinci_cfg_reg(DM646X_ATAEN);
+ } else {
+ WARN_ON(1);
+ return;
+ }
+
+ platform_device_register(&ide_device);
+}
+
+#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
+
+static u64 mmcsd0_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource mmcsd0_resources[] = {
+ {
+ /* different on dm355 */
+ .start = DAVINCI_MMCSD0_BASE,
+ .end = DAVINCI_MMCSD0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* IRQs: MMC/SD, then SDIO */
+ {
+ .start = IRQ_MMCINT,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ /* different on dm355 */
+ .start = IRQ_SDIOINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* DMA channels: RX, then TX */
+ {
+ .start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCRXEVT),
+ .flags = IORESOURCE_DMA,
+ }, {
+ .start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCTXEVT),
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device davinci_mmcsd0_device = {
+ .name = "davinci_mmc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &mmcsd0_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(mmcsd0_resources),
+ .resource = mmcsd0_resources,
+};
+
+static u64 mmcsd1_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource mmcsd1_resources[] = {
+ {
+ .start = DM355_MMCSD1_BASE,
+ .end = DM355_MMCSD1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* IRQs: MMC/SD, then SDIO */
+ {
+ .start = IRQ_DM355_MMCINT1,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = IRQ_DM355_SDIOINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* DMA channels: RX, then TX */
+ {
+ .start = EDMA_CTLR_CHAN(0, 30), /* rx */
+ .flags = IORESOURCE_DMA,
+ }, {
+ .start = EDMA_CTLR_CHAN(0, 31), /* tx */
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device davinci_mmcsd1_device = {
+ .name = "davinci_mmc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &mmcsd1_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(mmcsd1_resources),
+ .resource = mmcsd1_resources,
+};
+
+
+void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
+{
+ struct platform_device *pdev = NULL;
+
+ if (WARN_ON(cpu_is_davinci_dm646x()))
+ return;
+
+ /* REVISIT: update PINMUX, ARM_IRQMUX, and EDMA_EVTMUX here too;
+ * for example if MMCSD1 is used for SDIO, maybe DAT2 is unused.
+ *
+ * FIXME dm6441 (no MMC/SD), dm357 (one), and dm335 (two) are
+ * not handled right here ...
+ */
+ switch (module) {
+ case 1:
+ if (cpu_is_davinci_dm355()) {
+ /* REVISIT we may not need all these pins if e.g. this
+ * is a hard-wired SDIO device...
+ */
+ davinci_cfg_reg(DM355_SD1_CMD);
+ davinci_cfg_reg(DM355_SD1_CLK);
+ davinci_cfg_reg(DM355_SD1_DATA0);
+ davinci_cfg_reg(DM355_SD1_DATA1);
+ davinci_cfg_reg(DM355_SD1_DATA2);
+ davinci_cfg_reg(DM355_SD1_DATA3);
+ } else if (cpu_is_davinci_dm365()) {
+ void __iomem *pupdctl1 =
+ IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE + 0x7c);
+
+ /* Configure pull down control */
+ __raw_writel((__raw_readl(pupdctl1) & ~0xfc0),
+ pupdctl1);
+
+ mmcsd1_resources[0].start = DM365_MMCSD1_BASE;
+ mmcsd1_resources[0].end = DM365_MMCSD1_BASE +
+ SZ_4K - 1;
+ mmcsd1_resources[2].start = IRQ_DM365_SDIOINT1;
+ } else
+ break;
+
+ pdev = &davinci_mmcsd1_device;
+ break;
+ case 0:
+ if (cpu_is_davinci_dm355()) {
+ mmcsd0_resources[0].start = DM355_MMCSD0_BASE;
+ mmcsd0_resources[0].end = DM355_MMCSD0_BASE + SZ_4K - 1;
+ mmcsd0_resources[2].start = IRQ_DM355_SDIOINT0;
+
+ /* expose all 6 MMC0 signals: CLK, CMD, DATA[0..3] */
+ davinci_cfg_reg(DM355_MMCSD0);
+
+ /* enable RX EDMA */
+ davinci_cfg_reg(DM355_EVT26_MMC0_RX);
+ } else if (cpu_is_davinci_dm365()) {
+ mmcsd0_resources[0].start = DM365_MMCSD0_BASE;
+ mmcsd0_resources[0].end = DM365_MMCSD0_BASE +
+ SZ_4K - 1;
+ mmcsd0_resources[2].start = IRQ_DM365_SDIOINT0;
+ } else if (cpu_is_davinci_dm644x()) {
+ /* REVISIT: should this be in board-init code? */
+ void __iomem *base =
+ IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
+
+ /* Power-on 3.3V IO cells */
+ __raw_writel(0, base + DM64XX_VDD3P3V_PWDN);
+ /*Set up the pull regiter for MMC */
+ davinci_cfg_reg(DM644X_MSTK);
+ }
+
+ pdev = &davinci_mmcsd0_device;
+ break;
+ }
+
+ if (WARN_ON(!pdev))
+ return;
+
+ pdev->dev.platform_data = config;
+ platform_device_register(pdev);
+}
+
+#else
+
+void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
+{
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static struct resource wdt_resources[] = {
+ {
+ .start = DAVINCI_WDOG_BASE,
+ .end = DAVINCI_WDOG_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device davinci_wdt_device = {
+ .name = "watchdog",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static void davinci_init_wdt(void)
+{
+ platform_device_register(&davinci_wdt_device);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static struct platform_device davinci_pcm_device = {
+ .name = "davinci-pcm-audio",
+ .id = -1,
+};
+
+static void davinci_init_pcm(void)
+{
+ platform_device_register(&davinci_pcm_device);
+}
+
+/*-------------------------------------------------------------------------*/
+
+struct davinci_timer_instance davinci_timer_instance[2] = {
+ {
+ .base = DAVINCI_TIMER0_BASE,
+ .bottom_irq = IRQ_TINT0_TINT12,
+ .top_irq = IRQ_TINT0_TINT34,
+ },
+ {
+ .base = DAVINCI_TIMER1_BASE,
+ .bottom_irq = IRQ_TINT1_TINT12,
+ .top_irq = IRQ_TINT1_TINT34,
+ },
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int __init davinci_init_devices(void)
+{
+ /* please keep these calls, and their implementations above,
+ * in alphabetical order so they're easier to sort through.
+ */
+ davinci_init_pcm();
+ davinci_init_wdt();
+
+ return 0;
+}
+arch_initcall(davinci_init_devices);
+
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
new file mode 100644
index 00000000..a3a94e9c
--- /dev/null
+++ b/arch/arm/mach-davinci/dm355.c
@@ -0,0 +1,892 @@
+/*
+ * TI DaVinci DM355 chip specific setup
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. 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/init.h>
+#include <linux/clk.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <linux/spi/spi.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/dm355.h>
+#include <mach/cputype.h>
+#include <mach/edma.h>
+#include <mach/psc.h>
+#include <mach/mux.h>
+#include <mach/irqs.h>
+#include <mach/time.h>
+#include <mach/serial.h>
+#include <mach/common.h>
+#include <mach/asp.h>
+#include <mach/spi.h>
+
+#include "clock.h"
+#include "mux.h"
+
+#define DM355_UART2_BASE (IO_PHYS + 0x206000)
+
+/*
+ * Device specific clocks
+ */
+#define DM355_REF_FREQ 24000000 /* 24 or 36 MHz */
+
+static struct pll_data pll1_data = {
+ .num = 1,
+ .phys_base = DAVINCI_PLL1_BASE,
+ .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
+};
+
+static struct pll_data pll2_data = {
+ .num = 2,
+ .phys_base = DAVINCI_PLL2_BASE,
+ .flags = PLL_HAS_PREDIV,
+};
+
+static struct clk ref_clk = {
+ .name = "ref_clk",
+ /* FIXME -- crystal rate is board-specific */
+ .rate = DM355_REF_FREQ,
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &ref_clk,
+ .flags = CLK_PLL,
+ .pll_data = &pll1_data,
+};
+
+static struct clk pll1_aux_clk = {
+ .name = "pll1_aux_clk",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclk1 = {
+ .name = "pll1_sysclk1",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll1_sysclk2 = {
+ .name = "pll1_sysclk2",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll1_sysclk3 = {
+ .name = "pll1_sysclk3",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll1_sysclk4 = {
+ .name = "pll1_sysclk4",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll1_sysclkbp = {
+ .name = "pll1_sysclkbp",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+ .div_reg = BPDIV
+};
+
+static struct clk vpss_dac_clk = {
+ .name = "vpss_dac",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM355_LPSC_VPSS_DAC,
+};
+
+static struct clk vpss_master_clk = {
+ .name = "vpss_master",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_VPSSMSTR,
+ .flags = CLK_PSC,
+};
+
+static struct clk vpss_slave_clk = {
+ .name = "vpss_slave",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_VPSSSLV,
+};
+
+static struct clk clkout1_clk = {
+ .name = "clkout1",
+ .parent = &pll1_aux_clk,
+ /* NOTE: clkout1 can be externally gated by muxing GPIO-18 */
+};
+
+static struct clk clkout2_clk = {
+ .name = "clkout2",
+ .parent = &pll1_sysclkbp,
+};
+
+static struct clk pll2_clk = {
+ .name = "pll2",
+ .parent = &ref_clk,
+ .flags = CLK_PLL,
+ .pll_data = &pll2_data,
+};
+
+static struct clk pll2_sysclk1 = {
+ .name = "pll2_sysclk1",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll2_sysclkbp = {
+ .name = "pll2_sysclkbp",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL | PRE_PLL,
+ .div_reg = BPDIV
+};
+
+static struct clk clkout3_clk = {
+ .name = "clkout3",
+ .parent = &pll2_sysclkbp,
+ /* NOTE: clkout3 can be externally gated by muxing GPIO-16 */
+};
+
+static struct clk arm_clk = {
+ .name = "arm_clk",
+ .parent = &pll1_sysclk1,
+ .lpsc = DAVINCI_LPSC_ARM,
+ .flags = ALWAYS_ENABLED,
+};
+
+/*
+ * NOT LISTED below, and not touched by Linux
+ * - in SyncReset state by default
+ * .lpsc = DAVINCI_LPSC_TPCC,
+ * .lpsc = DAVINCI_LPSC_TPTC0,
+ * .lpsc = DAVINCI_LPSC_TPTC1,
+ * .lpsc = DAVINCI_LPSC_DDR_EMIF, .parent = &sysclk2_clk,
+ * .lpsc = DAVINCI_LPSC_MEMSTICK,
+ * - in Enabled state by default
+ * .lpsc = DAVINCI_LPSC_SYSTEM_SUBSYS,
+ * .lpsc = DAVINCI_LPSC_SCR2, // "bus"
+ * .lpsc = DAVINCI_LPSC_SCR3, // "bus"
+ * .lpsc = DAVINCI_LPSC_SCR4, // "bus"
+ * .lpsc = DAVINCI_LPSC_CROSSBAR, // "emulation"
+ * .lpsc = DAVINCI_LPSC_CFG27, // "test"
+ * .lpsc = DAVINCI_LPSC_CFG3, // "test"
+ * .lpsc = DAVINCI_LPSC_CFG5, // "test"
+ */
+
+static struct clk mjcp_clk = {
+ .name = "mjcp",
+ .parent = &pll1_sysclk1,
+ .lpsc = DAVINCI_LPSC_IMCOP,
+};
+
+static struct clk uart0_clk = {
+ .name = "uart0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_UART0,
+};
+
+static struct clk uart1_clk = {
+ .name = "uart1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_UART1,
+};
+
+static struct clk uart2_clk = {
+ .name = "uart2",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_UART2,
+};
+
+static struct clk i2c_clk = {
+ .name = "i2c",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_I2C,
+};
+
+static struct clk asp0_clk = {
+ .name = "asp0",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_McBSP,
+};
+
+static struct clk asp1_clk = {
+ .name = "asp1",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM355_LPSC_McBSP1,
+};
+
+static struct clk mmcsd0_clk = {
+ .name = "mmcsd0",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_MMC_SD,
+};
+
+static struct clk mmcsd1_clk = {
+ .name = "mmcsd1",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM355_LPSC_MMC_SD1,
+};
+
+static struct clk spi0_clk = {
+ .name = "spi0",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_SPI,
+};
+
+static struct clk spi1_clk = {
+ .name = "spi1",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM355_LPSC_SPI1,
+};
+
+static struct clk spi2_clk = {
+ .name = "spi2",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM355_LPSC_SPI2,
+};
+
+static struct clk gpio_clk = {
+ .name = "gpio",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_GPIO,
+};
+
+static struct clk aemif_clk = {
+ .name = "aemif",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_AEMIF,
+};
+
+static struct clk pwm0_clk = {
+ .name = "pwm0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM0,
+};
+
+static struct clk pwm1_clk = {
+ .name = "pwm1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM1,
+};
+
+static struct clk pwm2_clk = {
+ .name = "pwm2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM2,
+};
+
+static struct clk pwm3_clk = {
+ .name = "pwm3",
+ .parent = &pll1_aux_clk,
+ .lpsc = DM355_LPSC_PWM3,
+};
+
+static struct clk timer0_clk = {
+ .name = "timer0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER0,
+};
+
+static struct clk timer1_clk = {
+ .name = "timer1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER1,
+};
+
+static struct clk timer2_clk = {
+ .name = "timer2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER2,
+ .usecount = 1, /* REVISIT: why can't this be disabled? */
+};
+
+static struct clk timer3_clk = {
+ .name = "timer3",
+ .parent = &pll1_aux_clk,
+ .lpsc = DM355_LPSC_TIMER3,
+};
+
+static struct clk rto_clk = {
+ .name = "rto",
+ .parent = &pll1_aux_clk,
+ .lpsc = DM355_LPSC_RTO,
+};
+
+static struct clk usb_clk = {
+ .name = "usb",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_USB,
+};
+
+static struct clk_lookup dm355_clks[] = {
+ CLK(NULL, "ref", &ref_clk),
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
+ CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+ CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+ CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
+ CLK(NULL, "pll1_aux", &pll1_aux_clk),
+ CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
+ CLK(NULL, "vpss_dac", &vpss_dac_clk),
+ CLK(NULL, "vpss_master", &vpss_master_clk),
+ CLK(NULL, "vpss_slave", &vpss_slave_clk),
+ CLK(NULL, "clkout1", &clkout1_clk),
+ CLK(NULL, "clkout2", &clkout2_clk),
+ CLK(NULL, "pll2", &pll2_clk),
+ CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
+ CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
+ CLK(NULL, "clkout3", &clkout3_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "mjcp", &mjcp_clk),
+ CLK(NULL, "uart0", &uart0_clk),
+ CLK(NULL, "uart1", &uart1_clk),
+ CLK(NULL, "uart2", &uart2_clk),
+ CLK("i2c_davinci.1", NULL, &i2c_clk),
+ CLK("davinci-mcbsp.0", NULL, &asp0_clk),
+ CLK("davinci-mcbsp.1", NULL, &asp1_clk),
+ CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
+ CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
+ CLK("spi_davinci.0", NULL, &spi0_clk),
+ CLK("spi_davinci.1", NULL, &spi1_clk),
+ CLK("spi_davinci.2", NULL, &spi2_clk),
+ CLK(NULL, "gpio", &gpio_clk),
+ CLK(NULL, "aemif", &aemif_clk),
+ CLK(NULL, "pwm0", &pwm0_clk),
+ CLK(NULL, "pwm1", &pwm1_clk),
+ CLK(NULL, "pwm2", &pwm2_clk),
+ CLK(NULL, "pwm3", &pwm3_clk),
+ CLK(NULL, "timer0", &timer0_clk),
+ CLK(NULL, "timer1", &timer1_clk),
+ CLK("watchdog", NULL, &timer2_clk),
+ CLK(NULL, "timer3", &timer3_clk),
+ CLK(NULL, "rto", &rto_clk),
+ CLK(NULL, "usb", &usb_clk),
+ CLK(NULL, NULL, NULL),
+};
+
+/*----------------------------------------------------------------------*/
+
+static u64 dm355_spi0_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource dm355_spi0_resources[] = {
+ {
+ .start = 0x01c66000,
+ .end = 0x01c667ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DM355_SPINT0_0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 17,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = 16,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct davinci_spi_platform_data dm355_spi0_pdata = {
+ .version = SPI_VERSION_1,
+ .num_chipselect = 2,
+ .cshold_bug = true,
+ .dma_event_q = EVENTQ_1,
+};
+static struct platform_device dm355_spi0_device = {
+ .name = "spi_davinci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &dm355_spi0_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dm355_spi0_pdata,
+ },
+ .num_resources = ARRAY_SIZE(dm355_spi0_resources),
+ .resource = dm355_spi0_resources,
+};
+
+void __init dm355_init_spi0(unsigned chipselect_mask,
+ struct spi_board_info *info, unsigned len)
+{
+ /* for now, assume we need MISO */
+ davinci_cfg_reg(DM355_SPI0_SDI);
+
+ /* not all slaves will be wired up */
+ if (chipselect_mask & BIT(0))
+ davinci_cfg_reg(DM355_SPI0_SDENA0);
+ if (chipselect_mask & BIT(1))
+ davinci_cfg_reg(DM355_SPI0_SDENA1);
+
+ spi_register_board_info(info, len);
+
+ platform_device_register(&dm355_spi0_device);
+}
+
+/*----------------------------------------------------------------------*/
+
+#define INTMUX 0x18
+#define EVTMUX 0x1c
+
+/*
+ * Device specific mux setup
+ *
+ * soc description mux mode mode mux dbg
+ * reg offset mask mode
+ */
+static const struct mux_config dm355_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+MUX_CFG(DM355, MMCSD0, 4, 2, 1, 0, false)
+
+MUX_CFG(DM355, SD1_CLK, 3, 6, 1, 1, false)
+MUX_CFG(DM355, SD1_CMD, 3, 7, 1, 1, false)
+MUX_CFG(DM355, SD1_DATA3, 3, 8, 3, 1, false)
+MUX_CFG(DM355, SD1_DATA2, 3, 10, 3, 1, false)
+MUX_CFG(DM355, SD1_DATA1, 3, 12, 3, 1, false)
+MUX_CFG(DM355, SD1_DATA0, 3, 14, 3, 1, false)
+
+MUX_CFG(DM355, I2C_SDA, 3, 19, 1, 1, false)
+MUX_CFG(DM355, I2C_SCL, 3, 20, 1, 1, false)
+
+MUX_CFG(DM355, MCBSP0_BDX, 3, 0, 1, 1, false)
+MUX_CFG(DM355, MCBSP0_X, 3, 1, 1, 1, false)
+MUX_CFG(DM355, MCBSP0_BFSX, 3, 2, 1, 1, false)
+MUX_CFG(DM355, MCBSP0_BDR, 3, 3, 1, 1, false)
+MUX_CFG(DM355, MCBSP0_R, 3, 4, 1, 1, false)
+MUX_CFG(DM355, MCBSP0_BFSR, 3, 5, 1, 1, false)
+
+MUX_CFG(DM355, SPI0_SDI, 4, 1, 1, 0, false)
+MUX_CFG(DM355, SPI0_SDENA0, 4, 0, 1, 0, false)
+MUX_CFG(DM355, SPI0_SDENA1, 3, 28, 1, 1, false)
+
+INT_CFG(DM355, INT_EDMA_CC, 2, 1, 1, false)
+INT_CFG(DM355, INT_EDMA_TC0_ERR, 3, 1, 1, false)
+INT_CFG(DM355, INT_EDMA_TC1_ERR, 4, 1, 1, false)
+
+EVT_CFG(DM355, EVT8_ASP1_TX, 0, 1, 0, false)
+EVT_CFG(DM355, EVT9_ASP1_RX, 1, 1, 0, false)
+EVT_CFG(DM355, EVT26_MMC0_RX, 2, 1, 0, false)
+
+MUX_CFG(DM355, VOUT_FIELD, 1, 18, 3, 1, false)
+MUX_CFG(DM355, VOUT_FIELD_G70, 1, 18, 3, 0, false)
+MUX_CFG(DM355, VOUT_HVSYNC, 1, 16, 1, 0, false)
+MUX_CFG(DM355, VOUT_COUTL_EN, 1, 0, 0xff, 0x55, false)
+MUX_CFG(DM355, VOUT_COUTH_EN, 1, 8, 0xff, 0x55, false)
+
+MUX_CFG(DM355, VIN_PCLK, 0, 14, 1, 1, false)
+MUX_CFG(DM355, VIN_CAM_WEN, 0, 13, 1, 1, false)
+MUX_CFG(DM355, VIN_CAM_VD, 0, 12, 1, 1, false)
+MUX_CFG(DM355, VIN_CAM_HD, 0, 11, 1, 1, false)
+MUX_CFG(DM355, VIN_YIN_EN, 0, 10, 1, 1, false)
+MUX_CFG(DM355, VIN_CINL_EN, 0, 0, 0xff, 0x55, false)
+MUX_CFG(DM355, VIN_CINH_EN, 0, 8, 3, 3, false)
+#endif
+};
+
+static u8 dm355_default_priorities[DAVINCI_N_AINTC_IRQ] = {
+ [IRQ_DM355_CCDC_VDINT0] = 2,
+ [IRQ_DM355_CCDC_VDINT1] = 6,
+ [IRQ_DM355_CCDC_VDINT2] = 6,
+ [IRQ_DM355_IPIPE_HST] = 6,
+ [IRQ_DM355_H3AINT] = 6,
+ [IRQ_DM355_IPIPE_SDR] = 6,
+ [IRQ_DM355_IPIPEIFINT] = 6,
+ [IRQ_DM355_OSDINT] = 7,
+ [IRQ_DM355_VENCINT] = 6,
+ [IRQ_ASQINT] = 6,
+ [IRQ_IMXINT] = 6,
+ [IRQ_USBINT] = 4,
+ [IRQ_DM355_RTOINT] = 4,
+ [IRQ_DM355_UARTINT2] = 7,
+ [IRQ_DM355_TINT6] = 7,
+ [IRQ_CCINT0] = 5, /* dma */
+ [IRQ_CCERRINT] = 5, /* dma */
+ [IRQ_TCERRINT0] = 5, /* dma */
+ [IRQ_TCERRINT] = 5, /* dma */
+ [IRQ_DM355_SPINT2_1] = 7,
+ [IRQ_DM355_TINT7] = 4,
+ [IRQ_DM355_SDIOINT0] = 7,
+ [IRQ_MBXINT] = 7,
+ [IRQ_MBRINT] = 7,
+ [IRQ_MMCINT] = 7,
+ [IRQ_DM355_MMCINT1] = 7,
+ [IRQ_DM355_PWMINT3] = 7,
+ [IRQ_DDRINT] = 7,
+ [IRQ_AEMIFINT] = 7,
+ [IRQ_DM355_SDIOINT1] = 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_DM355_SPINT0_0] = 3,
+ [IRQ_DM355_SPINT0_1] = 3,
+ [IRQ_DM355_GPIO0] = 3,
+ [IRQ_DM355_GPIO1] = 7,
+ [IRQ_DM355_GPIO2] = 4,
+ [IRQ_DM355_GPIO3] = 4,
+ [IRQ_DM355_GPIO4] = 7,
+ [IRQ_DM355_GPIO5] = 7,
+ [IRQ_DM355_GPIO6] = 7,
+ [IRQ_DM355_GPIO7] = 7,
+ [IRQ_DM355_GPIO8] = 7,
+ [IRQ_DM355_GPIO9] = 7,
+ [IRQ_DM355_GPIOBNK0] = 7,
+ [IRQ_DM355_GPIOBNK1] = 7,
+ [IRQ_DM355_GPIOBNK2] = 7,
+ [IRQ_DM355_GPIOBNK3] = 7,
+ [IRQ_DM355_GPIOBNK4] = 7,
+ [IRQ_DM355_GPIOBNK5] = 7,
+ [IRQ_DM355_GPIOBNK6] = 7,
+ [IRQ_COMMTX] = 7,
+ [IRQ_COMMRX] = 7,
+ [IRQ_EMUINT] = 7,
+};
+
+/*----------------------------------------------------------------------*/
+
+static const s8
+queue_tc_mapping[][2] = {
+ /* {event queue no, TC no} */
+ {0, 0},
+ {1, 1},
+ {-1, -1},
+};
+
+static const s8
+queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 3},
+ {1, 7},
+ {-1, -1},
+};
+
+static struct edma_soc_info edma_cc0_info = {
+ .n_channel = 64,
+ .n_region = 4,
+ .n_slot = 128,
+ .n_tc = 2,
+ .n_cc = 1,
+ .queue_tc_mapping = queue_tc_mapping,
+ .queue_priority_mapping = queue_priority_mapping,
+};
+
+static struct edma_soc_info *dm355_edma_info[EDMA_MAX_CC] = {
+ &edma_cc0_info,
+};
+
+static struct resource edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = 0x01c00000,
+ .end = 0x01c00000 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = 0x01c10000,
+ .end = 0x01c10000 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = 0x01c10400,
+ .end = 0x01c10400 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* not using (or muxing) TC*_ERR */
+};
+
+static struct platform_device dm355_edma_device = {
+ .name = "edma",
+ .id = 0,
+ .dev.platform_data = dm355_edma_info,
+ .num_resources = ARRAY_SIZE(edma_resources),
+ .resource = edma_resources,
+};
+
+static struct resource dm355_asp1_resources[] = {
+ {
+ .start = DAVINCI_ASP1_BASE,
+ .end = DAVINCI_ASP1_BASE + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DAVINCI_DMA_ASP1_TX,
+ .end = DAVINCI_DMA_ASP1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = DAVINCI_DMA_ASP1_RX,
+ .end = DAVINCI_DMA_ASP1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device dm355_asp1_device = {
+ .name = "davinci-mcbsp",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(dm355_asp1_resources),
+ .resource = dm355_asp1_resources,
+};
+
+static void dm355_ccdc_setup_pinmux(void)
+{
+ davinci_cfg_reg(DM355_VIN_PCLK);
+ davinci_cfg_reg(DM355_VIN_CAM_WEN);
+ davinci_cfg_reg(DM355_VIN_CAM_VD);
+ davinci_cfg_reg(DM355_VIN_CAM_HD);
+ davinci_cfg_reg(DM355_VIN_YIN_EN);
+ davinci_cfg_reg(DM355_VIN_CINL_EN);
+ davinci_cfg_reg(DM355_VIN_CINH_EN);
+}
+
+static struct resource dm355_vpss_resources[] = {
+ {
+ /* VPSS BL Base address */
+ .name = "vpss",
+ .start = 0x01c70800,
+ .end = 0x01c70800 + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* VPSS CLK Base address */
+ .name = "vpss",
+ .start = 0x01c70000,
+ .end = 0x01c70000 + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm355_vpss_device = {
+ .name = "vpss",
+ .id = -1,
+ .dev.platform_data = "dm355_vpss",
+ .num_resources = ARRAY_SIZE(dm355_vpss_resources),
+ .resource = dm355_vpss_resources,
+};
+
+static struct resource vpfe_resources[] = {
+ {
+ .start = IRQ_VDINT0,
+ .end = IRQ_VDINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_VDINT1,
+ .end = IRQ_VDINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static struct resource dm355_ccdc_resource[] = {
+ /* CCDC Base address */
+ {
+ .flags = IORESOURCE_MEM,
+ .start = 0x01c70600,
+ .end = 0x01c70600 + 0x1ff,
+ },
+};
+static struct platform_device dm355_ccdc_dev = {
+ .name = "dm355_ccdc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm355_ccdc_resource),
+ .resource = dm355_ccdc_resource,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = dm355_ccdc_setup_pinmux,
+ },
+};
+
+static struct platform_device vpfe_capture_dev = {
+ .name = CAPTURE_DRV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(vpfe_resources),
+ .resource = vpfe_resources,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void dm355_set_vpfe_config(struct vpfe_config *cfg)
+{
+ vpfe_capture_dev.dev.platform_data = cfg;
+}
+
+/*----------------------------------------------------------------------*/
+
+static struct map_desc dm355_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = SRAM_VIRT,
+ .pfn = __phys_to_pfn(0x00010000),
+ .length = SZ_32K,
+ .type = MT_MEMORY_NONCACHED,
+ },
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id dm355_ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb73b,
+ .manufacturer = 0x00f,
+ .cpu_id = DAVINCI_CPU_ID_DM355,
+ .name = "dm355",
+ },
+};
+
+static u32 dm355_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
+
+/*
+ * 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>
+ */
+static struct davinci_timer_info dm355_timer_info = {
+ .timers = davinci_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
+static struct plat_serial8250_port dm355_serial_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART0_BASE,
+ .irq = IRQ_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DAVINCI_UART1_BASE,
+ .irq = IRQ_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DM355_UART2_BASE,
+ .irq = IRQ_DM355_UARTINT2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0
+ },
+};
+
+static struct platform_device dm355_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = dm355_serial_platform_data,
+ },
+};
+
+static struct davinci_soc_info davinci_soc_info_dm355 = {
+ .io_desc = dm355_io_desc,
+ .io_desc_num = ARRAY_SIZE(dm355_io_desc),
+ .jtag_id_reg = 0x01c40028,
+ .ids = dm355_ids,
+ .ids_num = ARRAY_SIZE(dm355_ids),
+ .cpu_clks = dm355_clks,
+ .psc_bases = dm355_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(dm355_psc_bases),
+ .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
+ .pinmux_pins = dm355_pins,
+ .pinmux_pins_num = ARRAY_SIZE(dm355_pins),
+ .intc_base = DAVINCI_ARM_INTC_BASE,
+ .intc_type = DAVINCI_INTC_TYPE_AINTC,
+ .intc_irq_prios = dm355_default_priorities,
+ .intc_irq_num = DAVINCI_N_AINTC_IRQ,
+ .timer_info = &dm355_timer_info,
+ .gpio_type = GPIO_TYPE_DAVINCI,
+ .gpio_base = DAVINCI_GPIO_BASE,
+ .gpio_num = 104,
+ .gpio_irq = IRQ_DM355_GPIOBNK0,
+ .serial_dev = &dm355_serial_device,
+ .sram_dma = 0x00010000,
+ .sram_len = SZ_32K,
+ .reset_device = &davinci_wdt_device,
+};
+
+void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata)
+{
+ /* we don't use ASP1 IRQs, or we'd need to mux them ... */
+ if (evt_enable & ASP1_TX_EVT_EN)
+ davinci_cfg_reg(DM355_EVT8_ASP1_TX);
+
+ if (evt_enable & ASP1_RX_EVT_EN)
+ davinci_cfg_reg(DM355_EVT9_ASP1_RX);
+
+ dm355_asp1_device.dev.platform_data = pdata;
+ platform_device_register(&dm355_asp1_device);
+}
+
+void __init dm355_init(void)
+{
+ davinci_common_init(&davinci_soc_info_dm355);
+}
+
+static int __init dm355_init_devices(void)
+{
+ if (!cpu_is_davinci_dm355())
+ return 0;
+
+ /* Add ccdc clock aliases */
+ clk_add_alias("master", dm355_ccdc_dev.name, "vpss_master", NULL);
+ clk_add_alias("slave", dm355_ccdc_dev.name, "vpss_master", NULL);
+ davinci_cfg_reg(DM355_INT_EDMA_CC);
+ platform_device_register(&dm355_edma_device);
+ platform_device_register(&dm355_vpss_device);
+ platform_device_register(&dm355_ccdc_dev);
+ platform_device_register(&vpfe_capture_dev);
+
+ return 0;
+}
+postcore_initcall(dm355_init_devices);
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
new file mode 100644
index 00000000..4604e72d
--- /dev/null
+++ b/arch/arm/mach-davinci/dm365.c
@@ -0,0 +1,1245 @@
+/*
+ * TI DaVinci DM365 chip specific setup
+ *
+ * Copyright (C) 2009 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/dm365.h>
+#include <mach/cputype.h>
+#include <mach/edma.h>
+#include <mach/psc.h>
+#include <mach/mux.h>
+#include <mach/irqs.h>
+#include <mach/time.h>
+#include <mach/serial.h>
+#include <mach/common.h>
+#include <mach/asp.h>
+#include <mach/keyscan.h>
+#include <mach/spi.h>
+
+
+#include "clock.h"
+#include "mux.h"
+
+#define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */
+
+static struct pll_data pll1_data = {
+ .num = 1,
+ .phys_base = DAVINCI_PLL1_BASE,
+ .flags = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
+};
+
+static struct pll_data pll2_data = {
+ .num = 2,
+ .phys_base = DAVINCI_PLL2_BASE,
+ .flags = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
+};
+
+static struct clk ref_clk = {
+ .name = "ref_clk",
+ .rate = DM365_REF_FREQ,
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &ref_clk,
+ .flags = CLK_PLL,
+ .pll_data = &pll1_data,
+};
+
+static struct clk pll1_aux_clk = {
+ .name = "pll1_aux_clk",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclkbp = {
+ .name = "pll1_sysclkbp",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+ .div_reg = BPDIV
+};
+
+static struct clk clkout0_clk = {
+ .name = "clkout0",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclk1 = {
+ .name = "pll1_sysclk1",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll1_sysclk2 = {
+ .name = "pll1_sysclk2",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll1_sysclk3 = {
+ .name = "pll1_sysclk3",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll1_sysclk4 = {
+ .name = "pll1_sysclk4",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll1_sysclk5 = {
+ .name = "pll1_sysclk5",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll1_sysclk6 = {
+ .name = "pll1_sysclk6",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV6,
+};
+
+static struct clk pll1_sysclk7 = {
+ .name = "pll1_sysclk7",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV7,
+};
+
+static struct clk pll1_sysclk8 = {
+ .name = "pll1_sysclk8",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV8,
+};
+
+static struct clk pll1_sysclk9 = {
+ .name = "pll1_sysclk9",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV9,
+};
+
+static struct clk pll2_clk = {
+ .name = "pll2",
+ .parent = &ref_clk,
+ .flags = CLK_PLL,
+ .pll_data = &pll2_data,
+};
+
+static struct clk pll2_aux_clk = {
+ .name = "pll2_aux_clk",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk clkout1_clk = {
+ .name = "clkout1",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll2_sysclk1 = {
+ .name = "pll2_sysclk1",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll2_sysclk2 = {
+ .name = "pll2_sysclk2",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll2_sysclk3 = {
+ .name = "pll2_sysclk3",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll2_sysclk4 = {
+ .name = "pll2_sysclk4",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll2_sysclk5 = {
+ .name = "pll2_sysclk5",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll2_sysclk6 = {
+ .name = "pll2_sysclk6",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV6,
+};
+
+static struct clk pll2_sysclk7 = {
+ .name = "pll2_sysclk7",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV7,
+};
+
+static struct clk pll2_sysclk8 = {
+ .name = "pll2_sysclk8",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV8,
+};
+
+static struct clk pll2_sysclk9 = {
+ .name = "pll2_sysclk9",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV9,
+};
+
+static struct clk vpss_dac_clk = {
+ .name = "vpss_dac",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM365_LPSC_DAC_CLK,
+};
+
+static struct clk vpss_master_clk = {
+ .name = "vpss_master",
+ .parent = &pll1_sysclk5,
+ .lpsc = DM365_LPSC_VPSSMSTR,
+ .flags = CLK_PSC,
+};
+
+static struct clk arm_clk = {
+ .name = "arm_clk",
+ .parent = &pll2_sysclk2,
+ .lpsc = DAVINCI_LPSC_ARM,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk uart0_clk = {
+ .name = "uart0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_UART0,
+};
+
+static struct clk uart1_clk = {
+ .name = "uart1",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_UART1,
+};
+
+static struct clk i2c_clk = {
+ .name = "i2c",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_I2C,
+};
+
+static struct clk mmcsd0_clk = {
+ .name = "mmcsd0",
+ .parent = &pll1_sysclk8,
+ .lpsc = DAVINCI_LPSC_MMC_SD,
+};
+
+static struct clk mmcsd1_clk = {
+ .name = "mmcsd1",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_MMC_SD1,
+};
+
+static struct clk spi0_clk = {
+ .name = "spi0",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_SPI,
+};
+
+static struct clk spi1_clk = {
+ .name = "spi1",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_SPI1,
+};
+
+static struct clk spi2_clk = {
+ .name = "spi2",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_SPI2,
+};
+
+static struct clk spi3_clk = {
+ .name = "spi3",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_SPI3,
+};
+
+static struct clk spi4_clk = {
+ .name = "spi4",
+ .parent = &pll1_aux_clk,
+ .lpsc = DM365_LPSC_SPI4,
+};
+
+static struct clk gpio_clk = {
+ .name = "gpio",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_GPIO,
+};
+
+static struct clk aemif_clk = {
+ .name = "aemif",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_AEMIF,
+};
+
+static struct clk pwm0_clk = {
+ .name = "pwm0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM0,
+};
+
+static struct clk pwm1_clk = {
+ .name = "pwm1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM1,
+};
+
+static struct clk pwm2_clk = {
+ .name = "pwm2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM2,
+};
+
+static struct clk pwm3_clk = {
+ .name = "pwm3",
+ .parent = &ref_clk,
+ .lpsc = DM365_LPSC_PWM3,
+};
+
+static struct clk timer0_clk = {
+ .name = "timer0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER0,
+};
+
+static struct clk timer1_clk = {
+ .name = "timer1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER1,
+};
+
+static struct clk timer2_clk = {
+ .name = "timer2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER2,
+ .usecount = 1,
+};
+
+static struct clk timer3_clk = {
+ .name = "timer3",
+ .parent = &pll1_aux_clk,
+ .lpsc = DM365_LPSC_TIMER3,
+};
+
+static struct clk usb_clk = {
+ .name = "usb",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_USB,
+};
+
+static struct clk emac_clk = {
+ .name = "emac",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_EMAC,
+};
+
+static struct clk voicecodec_clk = {
+ .name = "voice_codec",
+ .parent = &pll2_sysclk4,
+ .lpsc = DM365_LPSC_VOICE_CODEC,
+};
+
+static struct clk asp0_clk = {
+ .name = "asp0",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_McBSP1,
+};
+
+static struct clk rto_clk = {
+ .name = "rto",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_RTO,
+};
+
+static struct clk mjcp_clk = {
+ .name = "mjcp",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM365_LPSC_MJCP,
+};
+
+static struct clk_lookup dm365_clks[] = {
+ CLK(NULL, "ref", &ref_clk),
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_aux", &pll1_aux_clk),
+ CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
+ CLK(NULL, "clkout0", &clkout0_clk),
+ CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
+ CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+ CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+ CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
+ CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
+ CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
+ CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
+ CLK(NULL, "pll1_sysclk8", &pll1_sysclk8),
+ CLK(NULL, "pll1_sysclk9", &pll1_sysclk9),
+ CLK(NULL, "pll2", &pll2_clk),
+ CLK(NULL, "pll2_aux", &pll2_aux_clk),
+ CLK(NULL, "clkout1", &clkout1_clk),
+ CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
+ CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
+ CLK(NULL, "pll2_sysclk3", &pll2_sysclk3),
+ CLK(NULL, "pll2_sysclk4", &pll2_sysclk4),
+ CLK(NULL, "pll2_sysclk5", &pll2_sysclk5),
+ CLK(NULL, "pll2_sysclk6", &pll2_sysclk6),
+ CLK(NULL, "pll2_sysclk7", &pll2_sysclk7),
+ CLK(NULL, "pll2_sysclk8", &pll2_sysclk8),
+ CLK(NULL, "pll2_sysclk9", &pll2_sysclk9),
+ CLK(NULL, "vpss_dac", &vpss_dac_clk),
+ CLK(NULL, "vpss_master", &vpss_master_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "uart0", &uart0_clk),
+ CLK(NULL, "uart1", &uart1_clk),
+ CLK("i2c_davinci.1", NULL, &i2c_clk),
+ CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
+ CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
+ CLK("spi_davinci.0", NULL, &spi0_clk),
+ CLK("spi_davinci.1", NULL, &spi1_clk),
+ CLK("spi_davinci.2", NULL, &spi2_clk),
+ CLK("spi_davinci.3", NULL, &spi3_clk),
+ CLK("spi_davinci.4", NULL, &spi4_clk),
+ CLK(NULL, "gpio", &gpio_clk),
+ CLK(NULL, "aemif", &aemif_clk),
+ CLK(NULL, "pwm0", &pwm0_clk),
+ CLK(NULL, "pwm1", &pwm1_clk),
+ CLK(NULL, "pwm2", &pwm2_clk),
+ CLK(NULL, "pwm3", &pwm3_clk),
+ CLK(NULL, "timer0", &timer0_clk),
+ CLK(NULL, "timer1", &timer1_clk),
+ CLK("watchdog", NULL, &timer2_clk),
+ CLK(NULL, "timer3", &timer3_clk),
+ CLK(NULL, "usb", &usb_clk),
+ CLK("davinci_emac.1", NULL, &emac_clk),
+ CLK("davinci_voicecodec", NULL, &voicecodec_clk),
+ CLK("davinci-mcbsp", NULL, &asp0_clk),
+ CLK(NULL, "rto", &rto_clk),
+ CLK(NULL, "mjcp", &mjcp_clk),
+ CLK(NULL, NULL, NULL),
+};
+
+/*----------------------------------------------------------------------*/
+
+#define INTMUX 0x18
+#define EVTMUX 0x1c
+
+
+static const struct mux_config dm365_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+MUX_CFG(DM365, MMCSD0, 0, 24, 1, 0, false)
+
+MUX_CFG(DM365, SD1_CLK, 0, 16, 3, 1, false)
+MUX_CFG(DM365, SD1_CMD, 4, 30, 3, 1, false)
+MUX_CFG(DM365, SD1_DATA3, 4, 28, 3, 1, false)
+MUX_CFG(DM365, SD1_DATA2, 4, 26, 3, 1, false)
+MUX_CFG(DM365, SD1_DATA1, 4, 24, 3, 1, false)
+MUX_CFG(DM365, SD1_DATA0, 4, 22, 3, 1, false)
+
+MUX_CFG(DM365, I2C_SDA, 3, 23, 3, 2, false)
+MUX_CFG(DM365, I2C_SCL, 3, 21, 3, 2, false)
+
+MUX_CFG(DM365, AEMIF_AR_A14, 2, 0, 3, 1, false)
+MUX_CFG(DM365, AEMIF_AR_BA0, 2, 0, 3, 2, false)
+MUX_CFG(DM365, AEMIF_A3, 2, 2, 3, 1, false)
+MUX_CFG(DM365, AEMIF_A7, 2, 4, 3, 1, false)
+MUX_CFG(DM365, AEMIF_D15_8, 2, 6, 1, 1, false)
+MUX_CFG(DM365, AEMIF_CE0, 2, 7, 1, 0, false)
+MUX_CFG(DM365, AEMIF_CE1, 2, 8, 1, 0, false)
+MUX_CFG(DM365, AEMIF_WE_OE, 2, 9, 1, 0, false)
+
+MUX_CFG(DM365, MCBSP0_BDX, 0, 23, 1, 1, false)
+MUX_CFG(DM365, MCBSP0_X, 0, 22, 1, 1, false)
+MUX_CFG(DM365, MCBSP0_BFSX, 0, 21, 1, 1, false)
+MUX_CFG(DM365, MCBSP0_BDR, 0, 20, 1, 1, false)
+MUX_CFG(DM365, MCBSP0_R, 0, 19, 1, 1, false)
+MUX_CFG(DM365, MCBSP0_BFSR, 0, 18, 1, 1, false)
+
+MUX_CFG(DM365, SPI0_SCLK, 3, 28, 1, 1, false)
+MUX_CFG(DM365, SPI0_SDI, 3, 26, 3, 1, false)
+MUX_CFG(DM365, SPI0_SDO, 3, 25, 1, 1, false)
+MUX_CFG(DM365, SPI0_SDENA0, 3, 29, 3, 1, false)
+MUX_CFG(DM365, SPI0_SDENA1, 3, 26, 3, 2, false)
+
+MUX_CFG(DM365, UART0_RXD, 3, 20, 1, 1, false)
+MUX_CFG(DM365, UART0_TXD, 3, 19, 1, 1, false)
+MUX_CFG(DM365, UART1_RXD, 3, 17, 3, 2, false)
+MUX_CFG(DM365, UART1_TXD, 3, 15, 3, 2, false)
+MUX_CFG(DM365, UART1_RTS, 3, 23, 3, 1, false)
+MUX_CFG(DM365, UART1_CTS, 3, 21, 3, 1, false)
+
+MUX_CFG(DM365, EMAC_TX_EN, 3, 17, 3, 1, false)
+MUX_CFG(DM365, EMAC_TX_CLK, 3, 15, 3, 1, false)
+MUX_CFG(DM365, EMAC_COL, 3, 14, 1, 1, false)
+MUX_CFG(DM365, EMAC_TXD3, 3, 13, 1, 1, false)
+MUX_CFG(DM365, EMAC_TXD2, 3, 12, 1, 1, false)
+MUX_CFG(DM365, EMAC_TXD1, 3, 11, 1, 1, false)
+MUX_CFG(DM365, EMAC_TXD0, 3, 10, 1, 1, false)
+MUX_CFG(DM365, EMAC_RXD3, 3, 9, 1, 1, false)
+MUX_CFG(DM365, EMAC_RXD2, 3, 8, 1, 1, false)
+MUX_CFG(DM365, EMAC_RXD1, 3, 7, 1, 1, false)
+MUX_CFG(DM365, EMAC_RXD0, 3, 6, 1, 1, false)
+MUX_CFG(DM365, EMAC_RX_CLK, 3, 5, 1, 1, false)
+MUX_CFG(DM365, EMAC_RX_DV, 3, 4, 1, 1, false)
+MUX_CFG(DM365, EMAC_RX_ER, 3, 3, 1, 1, false)
+MUX_CFG(DM365, EMAC_CRS, 3, 2, 1, 1, false)
+MUX_CFG(DM365, EMAC_MDIO, 3, 1, 1, 1, false)
+MUX_CFG(DM365, EMAC_MDCLK, 3, 0, 1, 1, false)
+
+MUX_CFG(DM365, KEYSCAN, 2, 0, 0x3f, 0x3f, false)
+
+MUX_CFG(DM365, PWM0, 1, 0, 3, 2, false)
+MUX_CFG(DM365, PWM0_G23, 3, 26, 3, 3, false)
+MUX_CFG(DM365, PWM1, 1, 2, 3, 2, false)
+MUX_CFG(DM365, PWM1_G25, 3, 29, 3, 2, false)
+MUX_CFG(DM365, PWM2_G87, 1, 10, 3, 2, false)
+MUX_CFG(DM365, PWM2_G88, 1, 8, 3, 2, false)
+MUX_CFG(DM365, PWM2_G89, 1, 6, 3, 2, false)
+MUX_CFG(DM365, PWM2_G90, 1, 4, 3, 2, false)
+MUX_CFG(DM365, PWM3_G80, 1, 20, 3, 3, false)
+MUX_CFG(DM365, PWM3_G81, 1, 18, 3, 3, false)
+MUX_CFG(DM365, PWM3_G85, 1, 14, 3, 2, false)
+MUX_CFG(DM365, PWM3_G86, 1, 12, 3, 2, false)
+
+MUX_CFG(DM365, SPI1_SCLK, 4, 2, 3, 1, false)
+MUX_CFG(DM365, SPI1_SDI, 3, 31, 1, 1, false)
+MUX_CFG(DM365, SPI1_SDO, 4, 0, 3, 1, false)
+MUX_CFG(DM365, SPI1_SDENA0, 4, 4, 3, 1, false)
+MUX_CFG(DM365, SPI1_SDENA1, 4, 0, 3, 2, false)
+
+MUX_CFG(DM365, SPI2_SCLK, 4, 10, 3, 1, false)
+MUX_CFG(DM365, SPI2_SDI, 4, 6, 3, 1, false)
+MUX_CFG(DM365, SPI2_SDO, 4, 8, 3, 1, false)
+MUX_CFG(DM365, SPI2_SDENA0, 4, 12, 3, 1, false)
+MUX_CFG(DM365, SPI2_SDENA1, 4, 8, 3, 2, false)
+
+MUX_CFG(DM365, SPI3_SCLK, 0, 0, 3, 2, false)
+MUX_CFG(DM365, SPI3_SDI, 0, 2, 3, 2, false)
+MUX_CFG(DM365, SPI3_SDO, 0, 6, 3, 2, false)
+MUX_CFG(DM365, SPI3_SDENA0, 0, 4, 3, 2, false)
+MUX_CFG(DM365, SPI3_SDENA1, 0, 6, 3, 3, false)
+
+MUX_CFG(DM365, SPI4_SCLK, 4, 18, 3, 1, false)
+MUX_CFG(DM365, SPI4_SDI, 4, 14, 3, 1, false)
+MUX_CFG(DM365, SPI4_SDO, 4, 16, 3, 1, false)
+MUX_CFG(DM365, SPI4_SDENA0, 4, 20, 3, 1, false)
+MUX_CFG(DM365, SPI4_SDENA1, 4, 16, 3, 2, false)
+
+MUX_CFG(DM365, CLKOUT0, 4, 20, 3, 3, false)
+MUX_CFG(DM365, CLKOUT1, 4, 16, 3, 3, false)
+MUX_CFG(DM365, CLKOUT2, 4, 8, 3, 3, false)
+
+MUX_CFG(DM365, GPIO20, 3, 21, 3, 0, false)
+MUX_CFG(DM365, GPIO30, 4, 6, 3, 0, false)
+MUX_CFG(DM365, GPIO31, 4, 8, 3, 0, false)
+MUX_CFG(DM365, GPIO32, 4, 10, 3, 0, false)
+MUX_CFG(DM365, GPIO33, 4, 12, 3, 0, false)
+MUX_CFG(DM365, GPIO40, 4, 26, 3, 0, false)
+MUX_CFG(DM365, GPIO64_57, 2, 6, 1, 0, false)
+
+MUX_CFG(DM365, VOUT_FIELD, 1, 18, 3, 1, false)
+MUX_CFG(DM365, VOUT_FIELD_G81, 1, 18, 3, 0, false)
+MUX_CFG(DM365, VOUT_HVSYNC, 1, 16, 1, 0, false)
+MUX_CFG(DM365, VOUT_COUTL_EN, 1, 0, 0xff, 0x55, false)
+MUX_CFG(DM365, VOUT_COUTH_EN, 1, 8, 0xff, 0x55, false)
+MUX_CFG(DM365, VIN_CAM_WEN, 0, 14, 3, 0, false)
+MUX_CFG(DM365, VIN_CAM_VD, 0, 13, 1, 0, false)
+MUX_CFG(DM365, VIN_CAM_HD, 0, 12, 1, 0, false)
+MUX_CFG(DM365, VIN_YIN4_7_EN, 0, 0, 0xff, 0, false)
+MUX_CFG(DM365, VIN_YIN0_3_EN, 0, 8, 0xf, 0, false)
+
+INT_CFG(DM365, INT_EDMA_CC, 2, 1, 1, false)
+INT_CFG(DM365, INT_EDMA_TC0_ERR, 3, 1, 1, false)
+INT_CFG(DM365, INT_EDMA_TC1_ERR, 4, 1, 1, false)
+INT_CFG(DM365, INT_EDMA_TC2_ERR, 22, 1, 1, false)
+INT_CFG(DM365, INT_EDMA_TC3_ERR, 23, 1, 1, false)
+INT_CFG(DM365, INT_PRTCSS, 10, 1, 1, false)
+INT_CFG(DM365, INT_EMAC_RXTHRESH, 14, 1, 1, false)
+INT_CFG(DM365, INT_EMAC_RXPULSE, 15, 1, 1, false)
+INT_CFG(DM365, INT_EMAC_TXPULSE, 16, 1, 1, false)
+INT_CFG(DM365, INT_EMAC_MISCPULSE, 17, 1, 1, false)
+INT_CFG(DM365, INT_IMX0_ENABLE, 0, 1, 0, false)
+INT_CFG(DM365, INT_IMX0_DISABLE, 0, 1, 1, false)
+INT_CFG(DM365, INT_HDVICP_ENABLE, 0, 1, 1, false)
+INT_CFG(DM365, INT_HDVICP_DISABLE, 0, 1, 0, false)
+INT_CFG(DM365, INT_IMX1_ENABLE, 24, 1, 1, false)
+INT_CFG(DM365, INT_IMX1_DISABLE, 24, 1, 0, false)
+INT_CFG(DM365, INT_NSF_ENABLE, 25, 1, 1, false)
+INT_CFG(DM365, INT_NSF_DISABLE, 25, 1, 0, false)
+
+EVT_CFG(DM365, EVT2_ASP_TX, 0, 1, 0, false)
+EVT_CFG(DM365, EVT3_ASP_RX, 1, 1, 0, false)
+EVT_CFG(DM365, EVT2_VC_TX, 0, 1, 1, false)
+EVT_CFG(DM365, EVT3_VC_RX, 1, 1, 1, false)
+#endif
+};
+
+static u64 dm365_spi0_dma_mask = DMA_BIT_MASK(32);
+
+static struct davinci_spi_platform_data dm365_spi0_pdata = {
+ .version = SPI_VERSION_1,
+ .num_chipselect = 2,
+ .dma_event_q = EVENTQ_3,
+};
+
+static struct resource dm365_spi0_resources[] = {
+ {
+ .start = 0x01c66000,
+ .end = 0x01c667ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DM365_SPIINT0_0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 17,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = 16,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device dm365_spi0_device = {
+ .name = "spi_davinci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &dm365_spi0_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dm365_spi0_pdata,
+ },
+ .num_resources = ARRAY_SIZE(dm365_spi0_resources),
+ .resource = dm365_spi0_resources,
+};
+
+void __init dm365_init_spi0(unsigned chipselect_mask,
+ struct spi_board_info *info, unsigned len)
+{
+ davinci_cfg_reg(DM365_SPI0_SCLK);
+ davinci_cfg_reg(DM365_SPI0_SDI);
+ davinci_cfg_reg(DM365_SPI0_SDO);
+
+ /* not all slaves will be wired up */
+ if (chipselect_mask & BIT(0))
+ davinci_cfg_reg(DM365_SPI0_SDENA0);
+ if (chipselect_mask & BIT(1))
+ davinci_cfg_reg(DM365_SPI0_SDENA1);
+
+ spi_register_board_info(info, len);
+
+ platform_device_register(&dm365_spi0_device);
+}
+
+static struct emac_platform_data dm365_emac_pdata = {
+ .ctrl_reg_offset = DM365_EMAC_CNTRL_OFFSET,
+ .ctrl_mod_reg_offset = DM365_EMAC_CNTRL_MOD_OFFSET,
+ .ctrl_ram_offset = DM365_EMAC_CNTRL_RAM_OFFSET,
+ .ctrl_ram_size = DM365_EMAC_CNTRL_RAM_SIZE,
+ .version = EMAC_VERSION_2,
+};
+
+static struct resource dm365_emac_resources[] = {
+ {
+ .start = DM365_EMAC_BASE,
+ .end = DM365_EMAC_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DM365_EMAC_RXTHRESH,
+ .end = IRQ_DM365_EMAC_RXTHRESH,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM365_EMAC_RXPULSE,
+ .end = IRQ_DM365_EMAC_RXPULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM365_EMAC_TXPULSE,
+ .end = IRQ_DM365_EMAC_TXPULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM365_EMAC_MISCPULSE,
+ .end = IRQ_DM365_EMAC_MISCPULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dm365_emac_device = {
+ .name = "davinci_emac",
+ .id = 1,
+ .dev = {
+ .platform_data = &dm365_emac_pdata,
+ },
+ .num_resources = ARRAY_SIZE(dm365_emac_resources),
+ .resource = dm365_emac_resources,
+};
+
+static struct resource dm365_mdio_resources[] = {
+ {
+ .start = DM365_EMAC_MDIO_BASE,
+ .end = DM365_EMAC_MDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm365_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm365_mdio_resources),
+ .resource = dm365_mdio_resources,
+};
+
+static u8 dm365_default_priorities[DAVINCI_N_AINTC_IRQ] = {
+ [IRQ_VDINT0] = 2,
+ [IRQ_VDINT1] = 6,
+ [IRQ_VDINT2] = 6,
+ [IRQ_HISTINT] = 6,
+ [IRQ_H3AINT] = 6,
+ [IRQ_PRVUINT] = 6,
+ [IRQ_RSZINT] = 6,
+ [IRQ_DM365_INSFINT] = 7,
+ [IRQ_VENCINT] = 6,
+ [IRQ_ASQINT] = 6,
+ [IRQ_IMXINT] = 6,
+ [IRQ_DM365_IMCOPINT] = 4,
+ [IRQ_USBINT] = 4,
+ [IRQ_DM365_RTOINT] = 7,
+ [IRQ_DM365_TINT5] = 7,
+ [IRQ_DM365_TINT6] = 5,
+ [IRQ_CCINT0] = 5,
+ [IRQ_CCERRINT] = 5,
+ [IRQ_TCERRINT0] = 5,
+ [IRQ_TCERRINT] = 7,
+ [IRQ_PSCIN] = 4,
+ [IRQ_DM365_SPINT2_1] = 7,
+ [IRQ_DM365_TINT7] = 7,
+ [IRQ_DM365_SDIOINT0] = 7,
+ [IRQ_MBXINT] = 7,
+ [IRQ_MBRINT] = 7,
+ [IRQ_MMCINT] = 7,
+ [IRQ_DM365_MMCINT1] = 7,
+ [IRQ_DM365_PWMINT3] = 7,
+ [IRQ_AEMIFINT] = 2,
+ [IRQ_DM365_SDIOINT1] = 2,
+ [IRQ_TINT0_TINT12] = 7,
+ [IRQ_TINT0_TINT34] = 7,
+ [IRQ_TINT1_TINT12] = 7,
+ [IRQ_TINT1_TINT34] = 7,
+ [IRQ_PWMINT0] = 7,
+ [IRQ_PWMINT1] = 3,
+ [IRQ_PWMINT2] = 3,
+ [IRQ_I2C] = 3,
+ [IRQ_UARTINT0] = 3,
+ [IRQ_UARTINT1] = 3,
+ [IRQ_DM365_RTCINT] = 3,
+ [IRQ_DM365_SPIINT0_0] = 3,
+ [IRQ_DM365_SPIINT3_0] = 3,
+ [IRQ_DM365_GPIO0] = 3,
+ [IRQ_DM365_GPIO1] = 7,
+ [IRQ_DM365_GPIO2] = 4,
+ [IRQ_DM365_GPIO3] = 4,
+ [IRQ_DM365_GPIO4] = 7,
+ [IRQ_DM365_GPIO5] = 7,
+ [IRQ_DM365_GPIO6] = 7,
+ [IRQ_DM365_GPIO7] = 7,
+ [IRQ_DM365_EMAC_RXTHRESH] = 7,
+ [IRQ_DM365_EMAC_RXPULSE] = 7,
+ [IRQ_DM365_EMAC_TXPULSE] = 7,
+ [IRQ_DM365_EMAC_MISCPULSE] = 7,
+ [IRQ_DM365_GPIO12] = 7,
+ [IRQ_DM365_GPIO13] = 7,
+ [IRQ_DM365_GPIO14] = 7,
+ [IRQ_DM365_GPIO15] = 7,
+ [IRQ_DM365_KEYINT] = 7,
+ [IRQ_DM365_TCERRINT2] = 7,
+ [IRQ_DM365_TCERRINT3] = 7,
+ [IRQ_DM365_EMUINT] = 7,
+};
+
+/* Four Transfer Controllers on DM365 */
+static const s8
+dm365_queue_tc_mapping[][2] = {
+ /* {event queue no, TC no} */
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {3, 3},
+ {-1, -1},
+};
+
+static const s8
+dm365_queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 7},
+ {1, 7},
+ {2, 7},
+ {3, 0},
+ {-1, -1},
+};
+
+static struct edma_soc_info edma_cc0_info = {
+ .n_channel = 64,
+ .n_region = 4,
+ .n_slot = 256,
+ .n_tc = 4,
+ .n_cc = 1,
+ .queue_tc_mapping = dm365_queue_tc_mapping,
+ .queue_priority_mapping = dm365_queue_priority_mapping,
+ .default_queue = EVENTQ_3,
+};
+
+static struct edma_soc_info *dm365_edma_info[EDMA_MAX_CC] = {
+ &edma_cc0_info,
+};
+
+static struct resource edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = 0x01c00000,
+ .end = 0x01c00000 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = 0x01c10000,
+ .end = 0x01c10000 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = 0x01c10400,
+ .end = 0x01c10400 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc2",
+ .start = 0x01c10800,
+ .end = 0x01c10800 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc3",
+ .start = 0x01c10c00,
+ .end = 0x01c10c00 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* not using TC*_ERR */
+};
+
+static struct platform_device dm365_edma_device = {
+ .name = "edma",
+ .id = 0,
+ .dev.platform_data = dm365_edma_info,
+ .num_resources = ARRAY_SIZE(edma_resources),
+ .resource = edma_resources,
+};
+
+static struct resource dm365_asp_resources[] = {
+ {
+ .start = DAVINCI_DM365_ASP0_BASE,
+ .end = DAVINCI_DM365_ASP0_BASE + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DAVINCI_DMA_ASP0_TX,
+ .end = DAVINCI_DMA_ASP0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = DAVINCI_DMA_ASP0_RX,
+ .end = DAVINCI_DMA_ASP0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device dm365_asp_device = {
+ .name = "davinci-mcbsp",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm365_asp_resources),
+ .resource = dm365_asp_resources,
+};
+
+static struct resource dm365_vc_resources[] = {
+ {
+ .start = DAVINCI_DM365_VC_BASE,
+ .end = DAVINCI_DM365_VC_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DAVINCI_DMA_VC_TX,
+ .end = DAVINCI_DMA_VC_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = DAVINCI_DMA_VC_RX,
+ .end = DAVINCI_DMA_VC_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device dm365_vc_device = {
+ .name = "davinci_voicecodec",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm365_vc_resources),
+ .resource = dm365_vc_resources,
+};
+
+static struct resource dm365_rtc_resources[] = {
+ {
+ .start = DM365_RTC_BASE,
+ .end = DM365_RTC_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DM365_RTCINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dm365_rtc_device = {
+ .name = "rtc_davinci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm365_rtc_resources),
+ .resource = dm365_rtc_resources,
+};
+
+static struct map_desc dm365_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = SRAM_VIRT,
+ .pfn = __phys_to_pfn(0x00010000),
+ .length = SZ_32K,
+ .type = MT_MEMORY_NONCACHED,
+ },
+};
+
+static struct resource dm365_ks_resources[] = {
+ {
+ /* registers */
+ .start = DM365_KEYSCAN_BASE,
+ .end = DM365_KEYSCAN_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* interrupt */
+ .start = IRQ_DM365_KEYINT,
+ .end = IRQ_DM365_KEYINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dm365_ks_device = {
+ .name = "davinci_keyscan",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm365_ks_resources),
+ .resource = dm365_ks_resources,
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id dm365_ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb83e,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DM365,
+ .name = "dm365_rev1.1",
+ },
+ {
+ .variant = 0x8,
+ .part_no = 0xb83e,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DM365,
+ .name = "dm365_rev1.2",
+ },
+};
+
+static u32 dm365_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
+
+static struct davinci_timer_info dm365_timer_info = {
+ .timers = davinci_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
+#define DM365_UART1_BASE (IO_PHYS + 0x106000)
+
+static struct plat_serial8250_port dm365_serial_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART0_BASE,
+ .irq = IRQ_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DM365_UART1_BASE,
+ .irq = IRQ_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0
+ },
+};
+
+static struct platform_device dm365_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = dm365_serial_platform_data,
+ },
+};
+
+static struct davinci_soc_info davinci_soc_info_dm365 = {
+ .io_desc = dm365_io_desc,
+ .io_desc_num = ARRAY_SIZE(dm365_io_desc),
+ .jtag_id_reg = 0x01c40028,
+ .ids = dm365_ids,
+ .ids_num = ARRAY_SIZE(dm365_ids),
+ .cpu_clks = dm365_clks,
+ .psc_bases = dm365_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(dm365_psc_bases),
+ .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
+ .pinmux_pins = dm365_pins,
+ .pinmux_pins_num = ARRAY_SIZE(dm365_pins),
+ .intc_base = DAVINCI_ARM_INTC_BASE,
+ .intc_type = DAVINCI_INTC_TYPE_AINTC,
+ .intc_irq_prios = dm365_default_priorities,
+ .intc_irq_num = DAVINCI_N_AINTC_IRQ,
+ .timer_info = &dm365_timer_info,
+ .gpio_type = GPIO_TYPE_DAVINCI,
+ .gpio_base = DAVINCI_GPIO_BASE,
+ .gpio_num = 104,
+ .gpio_irq = IRQ_DM365_GPIO0,
+ .gpio_unbanked = 8, /* really 16 ... skip muxed GPIOs */
+ .serial_dev = &dm365_serial_device,
+ .emac_pdata = &dm365_emac_pdata,
+ .sram_dma = 0x00010000,
+ .sram_len = SZ_32K,
+ .reset_device = &davinci_wdt_device,
+};
+
+void __init dm365_init_asp(struct snd_platform_data *pdata)
+{
+ davinci_cfg_reg(DM365_MCBSP0_BDX);
+ davinci_cfg_reg(DM365_MCBSP0_X);
+ davinci_cfg_reg(DM365_MCBSP0_BFSX);
+ davinci_cfg_reg(DM365_MCBSP0_BDR);
+ davinci_cfg_reg(DM365_MCBSP0_R);
+ davinci_cfg_reg(DM365_MCBSP0_BFSR);
+ davinci_cfg_reg(DM365_EVT2_ASP_TX);
+ davinci_cfg_reg(DM365_EVT3_ASP_RX);
+ dm365_asp_device.dev.platform_data = pdata;
+ platform_device_register(&dm365_asp_device);
+}
+
+void __init dm365_init_vc(struct snd_platform_data *pdata)
+{
+ davinci_cfg_reg(DM365_EVT2_VC_TX);
+ davinci_cfg_reg(DM365_EVT3_VC_RX);
+ dm365_vc_device.dev.platform_data = pdata;
+ platform_device_register(&dm365_vc_device);
+}
+
+void __init dm365_init_ks(struct davinci_ks_platform_data *pdata)
+{
+ dm365_ks_device.dev.platform_data = pdata;
+ platform_device_register(&dm365_ks_device);
+}
+
+void __init dm365_init_rtc(void)
+{
+ davinci_cfg_reg(DM365_INT_PRTCSS);
+ platform_device_register(&dm365_rtc_device);
+}
+
+void __init dm365_init(void)
+{
+ davinci_common_init(&davinci_soc_info_dm365);
+}
+
+static struct resource dm365_vpss_resources[] = {
+ {
+ /* VPSS ISP5 Base address */
+ .name = "isp5",
+ .start = 0x01c70000,
+ .end = 0x01c70000 + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* VPSS CLK Base address */
+ .name = "vpss",
+ .start = 0x01c70200,
+ .end = 0x01c70200 + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm365_vpss_device = {
+ .name = "vpss",
+ .id = -1,
+ .dev.platform_data = "dm365_vpss",
+ .num_resources = ARRAY_SIZE(dm365_vpss_resources),
+ .resource = dm365_vpss_resources,
+};
+
+static struct resource vpfe_resources[] = {
+ {
+ .start = IRQ_VDINT0,
+ .end = IRQ_VDINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_VDINT1,
+ .end = IRQ_VDINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static struct platform_device vpfe_capture_dev = {
+ .name = CAPTURE_DRV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(vpfe_resources),
+ .resource = vpfe_resources,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static void dm365_isif_setup_pinmux(void)
+{
+ davinci_cfg_reg(DM365_VIN_CAM_WEN);
+ davinci_cfg_reg(DM365_VIN_CAM_VD);
+ davinci_cfg_reg(DM365_VIN_CAM_HD);
+ davinci_cfg_reg(DM365_VIN_YIN4_7_EN);
+ davinci_cfg_reg(DM365_VIN_YIN0_3_EN);
+}
+
+static struct resource isif_resource[] = {
+ /* ISIF Base address */
+ {
+ .start = 0x01c71000,
+ .end = 0x01c71000 + 0x1ff,
+ .flags = IORESOURCE_MEM,
+ },
+ /* ISIF Linearization table 0 */
+ {
+ .start = 0x1C7C000,
+ .end = 0x1C7C000 + 0x2ff,
+ .flags = IORESOURCE_MEM,
+ },
+ /* ISIF Linearization table 1 */
+ {
+ .start = 0x1C7C400,
+ .end = 0x1C7C400 + 0x2ff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+static struct platform_device dm365_isif_dev = {
+ .name = "isif",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(isif_resource),
+ .resource = isif_resource,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = dm365_isif_setup_pinmux,
+ },
+};
+
+static int __init dm365_init_devices(void)
+{
+ if (!cpu_is_davinci_dm365())
+ return 0;
+
+ davinci_cfg_reg(DM365_INT_EDMA_CC);
+ platform_device_register(&dm365_edma_device);
+
+ platform_device_register(&dm365_mdio_device);
+ platform_device_register(&dm365_emac_device);
+ clk_add_alias(NULL, dev_name(&dm365_mdio_device.dev),
+ NULL, &dm365_emac_device.dev);
+
+ /* Add isif clock alias */
+ clk_add_alias("master", dm365_isif_dev.name, "vpss_master", NULL);
+ platform_device_register(&dm365_vpss_device);
+ platform_device_register(&dm365_isif_dev);
+ platform_device_register(&vpfe_capture_dev);
+ return 0;
+}
+postcore_initcall(dm365_init_devices);
+
+void dm365_set_vpfe_config(struct vpfe_config *cfg)
+{
+ vpfe_capture_dev.dev.platform_data = cfg;
+}
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
new file mode 100644
index 00000000..4c82c271
--- /dev/null
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -0,0 +1,805 @@
+/*
+ * TI DaVinci DM644x chip specific setup
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. 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/init.h>
+#include <linux/clk.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/dm644x.h>
+#include <mach/cputype.h>
+#include <mach/edma.h>
+#include <mach/irqs.h>
+#include <mach/psc.h>
+#include <mach/mux.h>
+#include <mach/time.h>
+#include <mach/serial.h>
+#include <mach/common.h>
+#include <mach/asp.h>
+
+#include "clock.h"
+#include "mux.h"
+
+/*
+ * Device specific clocks
+ */
+#define DM644X_REF_FREQ 27000000
+
+static struct pll_data pll1_data = {
+ .num = 1,
+ .phys_base = DAVINCI_PLL1_BASE,
+};
+
+static struct pll_data pll2_data = {
+ .num = 2,
+ .phys_base = DAVINCI_PLL2_BASE,
+};
+
+static struct clk ref_clk = {
+ .name = "ref_clk",
+ .rate = DM644X_REF_FREQ,
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &ref_clk,
+ .pll_data = &pll1_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll1_sysclk1 = {
+ .name = "pll1_sysclk1",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll1_sysclk2 = {
+ .name = "pll1_sysclk2",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll1_sysclk3 = {
+ .name = "pll1_sysclk3",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll1_sysclk5 = {
+ .name = "pll1_sysclk5",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll1_aux_clk = {
+ .name = "pll1_aux_clk",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclkbp = {
+ .name = "pll1_sysclkbp",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+ .div_reg = BPDIV
+};
+
+static struct clk pll2_clk = {
+ .name = "pll2",
+ .parent = &ref_clk,
+ .pll_data = &pll2_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll2_sysclk1 = {
+ .name = "pll2_sysclk1",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll2_sysclk2 = {
+ .name = "pll2_sysclk2",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll2_sysclkbp = {
+ .name = "pll2_sysclkbp",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL | PRE_PLL,
+ .div_reg = BPDIV
+};
+
+static struct clk dsp_clk = {
+ .name = "dsp",
+ .parent = &pll1_sysclk1,
+ .lpsc = DAVINCI_LPSC_GEM,
+ .flags = PSC_DSP,
+ .usecount = 1, /* REVISIT how to disable? */
+};
+
+static struct clk arm_clk = {
+ .name = "arm",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_ARM,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk vicp_clk = {
+ .name = "vicp",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_IMCOP,
+ .flags = PSC_DSP,
+ .usecount = 1, /* REVISIT how to disable? */
+};
+
+static struct clk vpss_master_clk = {
+ .name = "vpss_master",
+ .parent = &pll1_sysclk3,
+ .lpsc = DAVINCI_LPSC_VPSSMSTR,
+ .flags = CLK_PSC,
+};
+
+static struct clk vpss_slave_clk = {
+ .name = "vpss_slave",
+ .parent = &pll1_sysclk3,
+ .lpsc = DAVINCI_LPSC_VPSSSLV,
+};
+
+static struct clk uart0_clk = {
+ .name = "uart0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_UART0,
+};
+
+static struct clk uart1_clk = {
+ .name = "uart1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_UART1,
+};
+
+static struct clk uart2_clk = {
+ .name = "uart2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_UART2,
+};
+
+static struct clk emac_clk = {
+ .name = "emac",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
+};
+
+static struct clk i2c_clk = {
+ .name = "i2c",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_I2C,
+};
+
+static struct clk ide_clk = {
+ .name = "ide",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_ATA,
+};
+
+static struct clk asp_clk = {
+ .name = "asp0",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_McBSP,
+};
+
+static struct clk mmcsd_clk = {
+ .name = "mmcsd",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_MMC_SD,
+};
+
+static struct clk spi_clk = {
+ .name = "spi",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_SPI,
+};
+
+static struct clk gpio_clk = {
+ .name = "gpio",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_GPIO,
+};
+
+static struct clk usb_clk = {
+ .name = "usb",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_USB,
+};
+
+static struct clk vlynq_clk = {
+ .name = "vlynq",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_VLYNQ,
+};
+
+static struct clk aemif_clk = {
+ .name = "aemif",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_AEMIF,
+};
+
+static struct clk pwm0_clk = {
+ .name = "pwm0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM0,
+};
+
+static struct clk pwm1_clk = {
+ .name = "pwm1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM1,
+};
+
+static struct clk pwm2_clk = {
+ .name = "pwm2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM2,
+};
+
+static struct clk timer0_clk = {
+ .name = "timer0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER0,
+};
+
+static struct clk timer1_clk = {
+ .name = "timer1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER1,
+};
+
+static struct clk timer2_clk = {
+ .name = "timer2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER2,
+ .usecount = 1, /* REVISIT: why can't this be disabled? */
+};
+
+static struct clk_lookup dm644x_clks[] = {
+ CLK(NULL, "ref", &ref_clk),
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
+ CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+ CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+ CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
+ CLK(NULL, "pll1_aux", &pll1_aux_clk),
+ CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
+ CLK(NULL, "pll2", &pll2_clk),
+ CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
+ CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
+ CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
+ CLK(NULL, "dsp", &dsp_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "vicp", &vicp_clk),
+ CLK(NULL, "vpss_master", &vpss_master_clk),
+ CLK(NULL, "vpss_slave", &vpss_slave_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "uart0", &uart0_clk),
+ CLK(NULL, "uart1", &uart1_clk),
+ CLK(NULL, "uart2", &uart2_clk),
+ CLK("davinci_emac.1", NULL, &emac_clk),
+ CLK("i2c_davinci.1", NULL, &i2c_clk),
+ CLK("palm_bk3710", NULL, &ide_clk),
+ CLK("davinci-mcbsp", NULL, &asp_clk),
+ CLK("davinci_mmc.0", NULL, &mmcsd_clk),
+ CLK(NULL, "spi", &spi_clk),
+ CLK(NULL, "gpio", &gpio_clk),
+ CLK(NULL, "usb", &usb_clk),
+ CLK(NULL, "vlynq", &vlynq_clk),
+ CLK(NULL, "aemif", &aemif_clk),
+ CLK(NULL, "pwm0", &pwm0_clk),
+ CLK(NULL, "pwm1", &pwm1_clk),
+ CLK(NULL, "pwm2", &pwm2_clk),
+ CLK(NULL, "timer0", &timer0_clk),
+ CLK(NULL, "timer1", &timer1_clk),
+ CLK("watchdog", NULL, &timer2_clk),
+ CLK(NULL, NULL, NULL),
+};
+
+static struct emac_platform_data dm644x_emac_pdata = {
+ .ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET,
+ .ctrl_mod_reg_offset = DM644X_EMAC_CNTRL_MOD_OFFSET,
+ .ctrl_ram_offset = DM644X_EMAC_CNTRL_RAM_OFFSET,
+ .ctrl_ram_size = DM644X_EMAC_CNTRL_RAM_SIZE,
+ .version = EMAC_VERSION_1,
+};
+
+static struct resource dm644x_emac_resources[] = {
+ {
+ .start = DM644X_EMAC_BASE,
+ .end = DM644X_EMAC_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_EMACINT,
+ .end = IRQ_EMACINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dm644x_emac_device = {
+ .name = "davinci_emac",
+ .id = 1,
+ .dev = {
+ .platform_data = &dm644x_emac_pdata,
+ },
+ .num_resources = ARRAY_SIZE(dm644x_emac_resources),
+ .resource = dm644x_emac_resources,
+};
+
+static struct resource dm644x_mdio_resources[] = {
+ {
+ .start = DM644X_EMAC_MDIO_BASE,
+ .end = DM644X_EMAC_MDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm644x_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm644x_mdio_resources),
+ .resource = dm644x_mdio_resources,
+};
+
+/*
+ * Device specific mux setup
+ *
+ * soc description mux mode mode mux dbg
+ * reg offset mask mode
+ */
+static const struct mux_config dm644x_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+MUX_CFG(DM644X, HDIREN, 0, 16, 1, 1, true)
+MUX_CFG(DM644X, ATAEN, 0, 17, 1, 1, true)
+MUX_CFG(DM644X, ATAEN_DISABLE, 0, 17, 1, 0, true)
+
+MUX_CFG(DM644X, HPIEN_DISABLE, 0, 29, 1, 0, true)
+
+MUX_CFG(DM644X, AEAW, 0, 0, 31, 31, true)
+MUX_CFG(DM644X, AEAW0, 0, 0, 1, 0, true)
+MUX_CFG(DM644X, AEAW1, 0, 1, 1, 0, true)
+MUX_CFG(DM644X, AEAW2, 0, 2, 1, 0, true)
+MUX_CFG(DM644X, AEAW3, 0, 3, 1, 0, true)
+MUX_CFG(DM644X, AEAW4, 0, 4, 1, 0, true)
+
+MUX_CFG(DM644X, MSTK, 1, 9, 1, 0, false)
+
+MUX_CFG(DM644X, I2C, 1, 7, 1, 1, false)
+
+MUX_CFG(DM644X, MCBSP, 1, 10, 1, 1, false)
+
+MUX_CFG(DM644X, UART1, 1, 1, 1, 1, true)
+MUX_CFG(DM644X, UART2, 1, 2, 1, 1, true)
+
+MUX_CFG(DM644X, PWM0, 1, 4, 1, 1, false)
+
+MUX_CFG(DM644X, PWM1, 1, 5, 1, 1, false)
+
+MUX_CFG(DM644X, PWM2, 1, 6, 1, 1, false)
+
+MUX_CFG(DM644X, VLYNQEN, 0, 15, 1, 1, false)
+MUX_CFG(DM644X, VLSCREN, 0, 14, 1, 1, false)
+MUX_CFG(DM644X, VLYNQWD, 0, 12, 3, 3, false)
+
+MUX_CFG(DM644X, EMACEN, 0, 31, 1, 1, true)
+
+MUX_CFG(DM644X, GPIO3V, 0, 31, 1, 0, true)
+
+MUX_CFG(DM644X, GPIO0, 0, 24, 1, 0, true)
+MUX_CFG(DM644X, GPIO3, 0, 25, 1, 0, false)
+MUX_CFG(DM644X, GPIO43_44, 1, 7, 1, 0, false)
+MUX_CFG(DM644X, GPIO46_47, 0, 22, 1, 0, true)
+
+MUX_CFG(DM644X, RGB666, 0, 22, 1, 1, true)
+
+MUX_CFG(DM644X, LOEEN, 0, 24, 1, 1, true)
+MUX_CFG(DM644X, LFLDEN, 0, 25, 1, 1, false)
+#endif
+};
+
+/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
+static u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
+ [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,
+};
+
+/*----------------------------------------------------------------------*/
+
+static const s8
+queue_tc_mapping[][2] = {
+ /* {event queue no, TC no} */
+ {0, 0},
+ {1, 1},
+ {-1, -1},
+};
+
+static const s8
+queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 3},
+ {1, 7},
+ {-1, -1},
+};
+
+static struct edma_soc_info edma_cc0_info = {
+ .n_channel = 64,
+ .n_region = 4,
+ .n_slot = 128,
+ .n_tc = 2,
+ .n_cc = 1,
+ .queue_tc_mapping = queue_tc_mapping,
+ .queue_priority_mapping = queue_priority_mapping,
+};
+
+static struct edma_soc_info *dm644x_edma_info[EDMA_MAX_CC] = {
+ &edma_cc0_info,
+};
+
+static struct resource edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = 0x01c00000,
+ .end = 0x01c00000 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = 0x01c10000,
+ .end = 0x01c10000 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = 0x01c10400,
+ .end = 0x01c10400 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* not using TC*_ERR */
+};
+
+static struct platform_device dm644x_edma_device = {
+ .name = "edma",
+ .id = 0,
+ .dev.platform_data = dm644x_edma_info,
+ .num_resources = ARRAY_SIZE(edma_resources),
+ .resource = edma_resources,
+};
+
+/* DM6446 EVM uses ASP0; line-out is a pair of RCA jacks */
+static struct resource dm644x_asp_resources[] = {
+ {
+ .start = DAVINCI_ASP0_BASE,
+ .end = DAVINCI_ASP0_BASE + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DAVINCI_DMA_ASP0_TX,
+ .end = DAVINCI_DMA_ASP0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = DAVINCI_DMA_ASP0_RX,
+ .end = DAVINCI_DMA_ASP0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device dm644x_asp_device = {
+ .name = "davinci-mcbsp",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm644x_asp_resources),
+ .resource = dm644x_asp_resources,
+};
+
+static struct resource dm644x_vpss_resources[] = {
+ {
+ /* VPSS Base address */
+ .name = "vpss",
+ .start = 0x01c73400,
+ .end = 0x01c73400 + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm644x_vpss_device = {
+ .name = "vpss",
+ .id = -1,
+ .dev.platform_data = "dm644x_vpss",
+ .num_resources = ARRAY_SIZE(dm644x_vpss_resources),
+ .resource = dm644x_vpss_resources,
+};
+
+static struct resource vpfe_resources[] = {
+ {
+ .start = IRQ_VDINT0,
+ .end = IRQ_VDINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_VDINT1,
+ .end = IRQ_VDINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static struct resource dm644x_ccdc_resource[] = {
+ /* CCDC Base address */
+ {
+ .start = 0x01c70400,
+ .end = 0x01c70400 + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm644x_ccdc_dev = {
+ .name = "dm644x_ccdc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm644x_ccdc_resource),
+ .resource = dm644x_ccdc_resource,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct platform_device vpfe_capture_dev = {
+ .name = CAPTURE_DRV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(vpfe_resources),
+ .resource = vpfe_resources,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void dm644x_set_vpfe_config(struct vpfe_config *cfg)
+{
+ vpfe_capture_dev.dev.platform_data = cfg;
+}
+
+/*----------------------------------------------------------------------*/
+
+static struct map_desc dm644x_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = SRAM_VIRT,
+ .pfn = __phys_to_pfn(0x00008000),
+ .length = SZ_16K,
+ .type = MT_MEMORY_NONCACHED,
+ },
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id dm644x_ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb700,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DM6446,
+ .name = "dm6446",
+ },
+ {
+ .variant = 0x1,
+ .part_no = 0xb700,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DM6446,
+ .name = "dm6446a",
+ },
+};
+
+static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
+
+/*
+ * 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>
+ */
+static struct davinci_timer_info dm644x_timer_info = {
+ .timers = davinci_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
+static struct plat_serial8250_port dm644x_serial_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART0_BASE,
+ .irq = IRQ_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DAVINCI_UART1_BASE,
+ .irq = IRQ_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DAVINCI_UART2_BASE,
+ .irq = IRQ_UARTINT2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0
+ },
+};
+
+static struct platform_device dm644x_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = dm644x_serial_platform_data,
+ },
+};
+
+static struct davinci_soc_info davinci_soc_info_dm644x = {
+ .io_desc = dm644x_io_desc,
+ .io_desc_num = ARRAY_SIZE(dm644x_io_desc),
+ .jtag_id_reg = 0x01c40028,
+ .ids = dm644x_ids,
+ .ids_num = ARRAY_SIZE(dm644x_ids),
+ .cpu_clks = dm644x_clks,
+ .psc_bases = dm644x_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(dm644x_psc_bases),
+ .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
+ .pinmux_pins = dm644x_pins,
+ .pinmux_pins_num = ARRAY_SIZE(dm644x_pins),
+ .intc_base = DAVINCI_ARM_INTC_BASE,
+ .intc_type = DAVINCI_INTC_TYPE_AINTC,
+ .intc_irq_prios = dm644x_default_priorities,
+ .intc_irq_num = DAVINCI_N_AINTC_IRQ,
+ .timer_info = &dm644x_timer_info,
+ .gpio_type = GPIO_TYPE_DAVINCI,
+ .gpio_base = DAVINCI_GPIO_BASE,
+ .gpio_num = 71,
+ .gpio_irq = IRQ_GPIOBNK0,
+ .serial_dev = &dm644x_serial_device,
+ .emac_pdata = &dm644x_emac_pdata,
+ .sram_dma = 0x00008000,
+ .sram_len = SZ_16K,
+ .reset_device = &davinci_wdt_device,
+};
+
+void __init dm644x_init_asp(struct snd_platform_data *pdata)
+{
+ davinci_cfg_reg(DM644X_MCBSP);
+ dm644x_asp_device.dev.platform_data = pdata;
+ platform_device_register(&dm644x_asp_device);
+}
+
+void __init dm644x_init(void)
+{
+ davinci_common_init(&davinci_soc_info_dm644x);
+}
+
+static int __init dm644x_init_devices(void)
+{
+ if (!cpu_is_davinci_dm644x())
+ return 0;
+
+ /* Add ccdc clock aliases */
+ clk_add_alias("master", dm644x_ccdc_dev.name, "vpss_master", NULL);
+ clk_add_alias("slave", dm644x_ccdc_dev.name, "vpss_slave", NULL);
+ platform_device_register(&dm644x_edma_device);
+
+ platform_device_register(&dm644x_mdio_device);
+ platform_device_register(&dm644x_emac_device);
+ clk_add_alias(NULL, dev_name(&dm644x_mdio_device.dev),
+ NULL, &dm644x_emac_device.dev);
+
+ platform_device_register(&dm644x_vpss_device);
+ platform_device_register(&dm644x_ccdc_dev);
+ platform_device_register(&vpfe_capture_dev);
+
+ return 0;
+}
+postcore_initcall(dm644x_init_devices);
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
new file mode 100644
index 00000000..e00d61e2
--- /dev/null
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -0,0 +1,921 @@
+/*
+ * TI DaVinci DM644x chip specific setup
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. 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/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/dm646x.h>
+#include <mach/cputype.h>
+#include <mach/edma.h>
+#include <mach/irqs.h>
+#include <mach/psc.h>
+#include <mach/mux.h>
+#include <mach/time.h>
+#include <mach/serial.h>
+#include <mach/common.h>
+#include <mach/asp.h>
+
+#include "clock.h"
+#include "mux.h"
+
+#define DAVINCI_VPIF_BASE (0x01C12000)
+#define VDD3P3V_PWDN_OFFSET (0x48)
+#define VSCLKDIS_OFFSET (0x6C)
+
+#define VDD3P3V_VID_MASK (BIT_MASK(3) | BIT_MASK(2) | BIT_MASK(1) |\
+ BIT_MASK(0))
+#define VSCLKDIS_MASK (BIT_MASK(11) | BIT_MASK(10) | BIT_MASK(9) |\
+ BIT_MASK(8))
+
+/*
+ * Device specific clocks
+ */
+#define DM646X_AUX_FREQ 24000000
+
+static struct pll_data pll1_data = {
+ .num = 1,
+ .phys_base = DAVINCI_PLL1_BASE,
+};
+
+static struct pll_data pll2_data = {
+ .num = 2,
+ .phys_base = DAVINCI_PLL2_BASE,
+};
+
+static struct clk ref_clk = {
+ .name = "ref_clk",
+};
+
+static struct clk aux_clkin = {
+ .name = "aux_clkin",
+ .rate = DM646X_AUX_FREQ,
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &ref_clk,
+ .pll_data = &pll1_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll1_sysclk1 = {
+ .name = "pll1_sysclk1",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll1_sysclk2 = {
+ .name = "pll1_sysclk2",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll1_sysclk3 = {
+ .name = "pll1_sysclk3",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll1_sysclk4 = {
+ .name = "pll1_sysclk4",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll1_sysclk5 = {
+ .name = "pll1_sysclk5",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll1_sysclk6 = {
+ .name = "pll1_sysclk6",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV6,
+};
+
+static struct clk pll1_sysclk8 = {
+ .name = "pll1_sysclk8",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV8,
+};
+
+static struct clk pll1_sysclk9 = {
+ .name = "pll1_sysclk9",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV9,
+};
+
+static struct clk pll1_sysclkbp = {
+ .name = "pll1_sysclkbp",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+ .div_reg = BPDIV,
+};
+
+static struct clk pll1_aux_clk = {
+ .name = "pll1_aux_clk",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll2_clk = {
+ .name = "pll2_clk",
+ .parent = &ref_clk,
+ .pll_data = &pll2_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll2_sysclk1 = {
+ .name = "pll2_sysclk1",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk dsp_clk = {
+ .name = "dsp",
+ .parent = &pll1_sysclk1,
+ .lpsc = DM646X_LPSC_C64X_CPU,
+ .flags = PSC_DSP,
+ .usecount = 1, /* REVISIT how to disable? */
+};
+
+static struct clk arm_clk = {
+ .name = "arm",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM646X_LPSC_ARM,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_cc_clk = {
+ .name = "edma_cc",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM646X_LPSC_TPCC,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc0_clk = {
+ .name = "edma_tc0",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM646X_LPSC_TPTC0,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc1_clk = {
+ .name = "edma_tc1",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM646X_LPSC_TPTC1,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc2_clk = {
+ .name = "edma_tc2",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM646X_LPSC_TPTC2,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc3_clk = {
+ .name = "edma_tc3",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM646X_LPSC_TPTC3,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk uart0_clk = {
+ .name = "uart0",
+ .parent = &aux_clkin,
+ .lpsc = DM646X_LPSC_UART0,
+};
+
+static struct clk uart1_clk = {
+ .name = "uart1",
+ .parent = &aux_clkin,
+ .lpsc = DM646X_LPSC_UART1,
+};
+
+static struct clk uart2_clk = {
+ .name = "uart2",
+ .parent = &aux_clkin,
+ .lpsc = DM646X_LPSC_UART2,
+};
+
+static struct clk i2c_clk = {
+ .name = "I2CCLK",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_I2C,
+};
+
+static struct clk gpio_clk = {
+ .name = "gpio",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_GPIO,
+};
+
+static struct clk mcasp0_clk = {
+ .name = "mcasp0",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_McASP0,
+};
+
+static struct clk mcasp1_clk = {
+ .name = "mcasp1",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_McASP1,
+};
+
+static struct clk aemif_clk = {
+ .name = "aemif",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_AEMIF,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk emac_clk = {
+ .name = "emac",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_EMAC,
+};
+
+static struct clk pwm0_clk = {
+ .name = "pwm0",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_PWM0,
+ .usecount = 1, /* REVIST: disabling hangs system */
+};
+
+static struct clk pwm1_clk = {
+ .name = "pwm1",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_PWM1,
+ .usecount = 1, /* REVIST: disabling hangs system */
+};
+
+static struct clk timer0_clk = {
+ .name = "timer0",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_TIMER0,
+};
+
+static struct clk timer1_clk = {
+ .name = "timer1",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_TIMER1,
+};
+
+static struct clk timer2_clk = {
+ .name = "timer2",
+ .parent = &pll1_sysclk3,
+ .flags = ALWAYS_ENABLED, /* no LPSC, always enabled; c.f. spruep9a */
+};
+
+
+static struct clk ide_clk = {
+ .name = "ide",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_ATA,
+};
+
+static struct clk vpif0_clk = {
+ .name = "vpif0",
+ .parent = &ref_clk,
+ .lpsc = DM646X_LPSC_VPSSMSTR,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk vpif1_clk = {
+ .name = "vpif1",
+ .parent = &ref_clk,
+ .lpsc = DM646X_LPSC_VPSSSLV,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk_lookup dm646x_clks[] = {
+ CLK(NULL, "ref", &ref_clk),
+ CLK(NULL, "aux", &aux_clkin),
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk1),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk2),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk3),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk4),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk5),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk6),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk8),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk9),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclkbp),
+ CLK(NULL, "pll1_aux", &pll1_aux_clk),
+ CLK(NULL, "pll2", &pll2_clk),
+ CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
+ CLK(NULL, "dsp", &dsp_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "edma_cc", &edma_cc_clk),
+ CLK(NULL, "edma_tc0", &edma_tc0_clk),
+ CLK(NULL, "edma_tc1", &edma_tc1_clk),
+ CLK(NULL, "edma_tc2", &edma_tc2_clk),
+ CLK(NULL, "edma_tc3", &edma_tc3_clk),
+ CLK(NULL, "uart0", &uart0_clk),
+ CLK(NULL, "uart1", &uart1_clk),
+ CLK(NULL, "uart2", &uart2_clk),
+ CLK("i2c_davinci.1", NULL, &i2c_clk),
+ CLK(NULL, "gpio", &gpio_clk),
+ CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
+ CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
+ CLK(NULL, "aemif", &aemif_clk),
+ CLK("davinci_emac.1", NULL, &emac_clk),
+ CLK(NULL, "pwm0", &pwm0_clk),
+ CLK(NULL, "pwm1", &pwm1_clk),
+ CLK(NULL, "timer0", &timer0_clk),
+ CLK(NULL, "timer1", &timer1_clk),
+ CLK("watchdog", NULL, &timer2_clk),
+ CLK("palm_bk3710", NULL, &ide_clk),
+ CLK(NULL, "vpif0", &vpif0_clk),
+ CLK(NULL, "vpif1", &vpif1_clk),
+ CLK(NULL, NULL, NULL),
+};
+
+static struct emac_platform_data dm646x_emac_pdata = {
+ .ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET,
+ .ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET,
+ .ctrl_ram_offset = DM646X_EMAC_CNTRL_RAM_OFFSET,
+ .ctrl_ram_size = DM646X_EMAC_CNTRL_RAM_SIZE,
+ .version = EMAC_VERSION_2,
+};
+
+static struct resource dm646x_emac_resources[] = {
+ {
+ .start = DM646X_EMAC_BASE,
+ .end = DM646X_EMAC_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DM646X_EMACRXTHINT,
+ .end = IRQ_DM646X_EMACRXTHINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM646X_EMACRXINT,
+ .end = IRQ_DM646X_EMACRXINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM646X_EMACTXINT,
+ .end = IRQ_DM646X_EMACTXINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM646X_EMACMISCINT,
+ .end = IRQ_DM646X_EMACMISCINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dm646x_emac_device = {
+ .name = "davinci_emac",
+ .id = 1,
+ .dev = {
+ .platform_data = &dm646x_emac_pdata,
+ },
+ .num_resources = ARRAY_SIZE(dm646x_emac_resources),
+ .resource = dm646x_emac_resources,
+};
+
+static struct resource dm646x_mdio_resources[] = {
+ {
+ .start = DM646X_EMAC_MDIO_BASE,
+ .end = DM646X_EMAC_MDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm646x_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm646x_mdio_resources),
+ .resource = dm646x_mdio_resources,
+};
+
+/*
+ * Device specific mux setup
+ *
+ * soc description mux mode mode mux dbg
+ * reg offset mask mode
+ */
+static const struct mux_config dm646x_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+MUX_CFG(DM646X, ATAEN, 0, 0, 5, 1, true)
+
+MUX_CFG(DM646X, AUDCK1, 0, 29, 1, 0, false)
+
+MUX_CFG(DM646X, AUDCK0, 0, 28, 1, 0, false)
+
+MUX_CFG(DM646X, CRGMUX, 0, 24, 7, 5, true)
+
+MUX_CFG(DM646X, STSOMUX_DISABLE, 0, 22, 3, 0, true)
+
+MUX_CFG(DM646X, STSIMUX_DISABLE, 0, 20, 3, 0, true)
+
+MUX_CFG(DM646X, PTSOMUX_DISABLE, 0, 18, 3, 0, true)
+
+MUX_CFG(DM646X, PTSIMUX_DISABLE, 0, 16, 3, 0, true)
+
+MUX_CFG(DM646X, STSOMUX, 0, 22, 3, 2, true)
+
+MUX_CFG(DM646X, STSIMUX, 0, 20, 3, 2, true)
+
+MUX_CFG(DM646X, PTSOMUX_PARALLEL, 0, 18, 3, 2, true)
+
+MUX_CFG(DM646X, PTSIMUX_PARALLEL, 0, 16, 3, 2, true)
+
+MUX_CFG(DM646X, PTSOMUX_SERIAL, 0, 18, 3, 3, true)
+
+MUX_CFG(DM646X, PTSIMUX_SERIAL, 0, 16, 3, 3, true)
+#endif
+};
+
+static u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
+ [IRQ_DM646X_VP_VERTINT0] = 7,
+ [IRQ_DM646X_VP_VERTINT1] = 7,
+ [IRQ_DM646X_VP_VERTINT2] = 7,
+ [IRQ_DM646X_VP_VERTINT3] = 7,
+ [IRQ_DM646X_VP_ERRINT] = 7,
+ [IRQ_DM646X_RESERVED_1] = 7,
+ [IRQ_DM646X_RESERVED_2] = 7,
+ [IRQ_DM646X_WDINT] = 7,
+ [IRQ_DM646X_CRGENINT0] = 7,
+ [IRQ_DM646X_CRGENINT1] = 7,
+ [IRQ_DM646X_TSIFINT0] = 7,
+ [IRQ_DM646X_TSIFINT1] = 7,
+ [IRQ_DM646X_VDCEINT] = 7,
+ [IRQ_DM646X_USBINT] = 7,
+ [IRQ_DM646X_USBDMAINT] = 7,
+ [IRQ_DM646X_PCIINT] = 7,
+ [IRQ_CCINT0] = 7, /* dma */
+ [IRQ_CCERRINT] = 7, /* dma */
+ [IRQ_TCERRINT0] = 7, /* dma */
+ [IRQ_TCERRINT] = 7, /* dma */
+ [IRQ_DM646X_TCERRINT2] = 7,
+ [IRQ_DM646X_TCERRINT3] = 7,
+ [IRQ_DM646X_IDE] = 7,
+ [IRQ_DM646X_HPIINT] = 7,
+ [IRQ_DM646X_EMACRXTHINT] = 7,
+ [IRQ_DM646X_EMACRXINT] = 7,
+ [IRQ_DM646X_EMACTXINT] = 7,
+ [IRQ_DM646X_EMACMISCINT] = 7,
+ [IRQ_DM646X_MCASP0TXINT] = 7,
+ [IRQ_DM646X_MCASP0RXINT] = 7,
+ [IRQ_AEMIFINT] = 7,
+ [IRQ_DM646X_RESERVED_3] = 7,
+ [IRQ_DM646X_MCASP1TXINT] = 7, /* clockevent */
+ [IRQ_TINT0_TINT34] = 7, /* clocksource */
+ [IRQ_TINT1_TINT12] = 7, /* DSP timer */
+ [IRQ_TINT1_TINT34] = 7, /* system tick */
+ [IRQ_PWMINT0] = 7,
+ [IRQ_PWMINT1] = 7,
+ [IRQ_DM646X_VLQINT] = 7,
+ [IRQ_I2C] = 7,
+ [IRQ_UARTINT0] = 7,
+ [IRQ_UARTINT1] = 7,
+ [IRQ_DM646X_UARTINT2] = 7,
+ [IRQ_DM646X_SPINT0] = 7,
+ [IRQ_DM646X_SPINT1] = 7,
+ [IRQ_DM646X_DSP2ARMINT] = 7,
+ [IRQ_DM646X_RESERVED_4] = 7,
+ [IRQ_DM646X_PSCINT] = 7,
+ [IRQ_DM646X_GPIO0] = 7,
+ [IRQ_DM646X_GPIO1] = 7,
+ [IRQ_DM646X_GPIO2] = 7,
+ [IRQ_DM646X_GPIO3] = 7,
+ [IRQ_DM646X_GPIO4] = 7,
+ [IRQ_DM646X_GPIO5] = 7,
+ [IRQ_DM646X_GPIO6] = 7,
+ [IRQ_DM646X_GPIO7] = 7,
+ [IRQ_DM646X_GPIOBNK0] = 7,
+ [IRQ_DM646X_GPIOBNK1] = 7,
+ [IRQ_DM646X_GPIOBNK2] = 7,
+ [IRQ_DM646X_DDRINT] = 7,
+ [IRQ_DM646X_AEMIFINT] = 7,
+ [IRQ_COMMTX] = 7,
+ [IRQ_COMMRX] = 7,
+ [IRQ_EMUINT] = 7,
+};
+
+/*----------------------------------------------------------------------*/
+
+/* Four Transfer Controllers on DM646x */
+static const s8
+dm646x_queue_tc_mapping[][2] = {
+ /* {event queue no, TC no} */
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {3, 3},
+ {-1, -1},
+};
+
+static const s8
+dm646x_queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 4},
+ {1, 0},
+ {2, 5},
+ {3, 1},
+ {-1, -1},
+};
+
+static struct edma_soc_info edma_cc0_info = {
+ .n_channel = 64,
+ .n_region = 6, /* 0-1, 4-7 */
+ .n_slot = 512,
+ .n_tc = 4,
+ .n_cc = 1,
+ .queue_tc_mapping = dm646x_queue_tc_mapping,
+ .queue_priority_mapping = dm646x_queue_priority_mapping,
+};
+
+static struct edma_soc_info *dm646x_edma_info[EDMA_MAX_CC] = {
+ &edma_cc0_info,
+};
+
+static struct resource edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = 0x01c00000,
+ .end = 0x01c00000 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = 0x01c10000,
+ .end = 0x01c10000 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = 0x01c10400,
+ .end = 0x01c10400 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc2",
+ .start = 0x01c10800,
+ .end = 0x01c10800 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc3",
+ .start = 0x01c10c00,
+ .end = 0x01c10c00 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* not using TC*_ERR */
+};
+
+static struct platform_device dm646x_edma_device = {
+ .name = "edma",
+ .id = 0,
+ .dev.platform_data = dm646x_edma_info,
+ .num_resources = ARRAY_SIZE(edma_resources),
+ .resource = edma_resources,
+};
+
+static struct resource dm646x_mcasp0_resources[] = {
+ {
+ .name = "mcasp0",
+ .start = DAVINCI_DM646X_MCASP0_REG_BASE,
+ .end = DAVINCI_DM646X_MCASP0_REG_BASE + (SZ_1K << 1) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* first TX, then RX */
+ {
+ .start = DAVINCI_DM646X_DMA_MCASP0_AXEVT0,
+ .end = DAVINCI_DM646X_DMA_MCASP0_AXEVT0,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = DAVINCI_DM646X_DMA_MCASP0_AREVT0,
+ .end = DAVINCI_DM646X_DMA_MCASP0_AREVT0,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct resource dm646x_mcasp1_resources[] = {
+ {
+ .name = "mcasp1",
+ .start = DAVINCI_DM646X_MCASP1_REG_BASE,
+ .end = DAVINCI_DM646X_MCASP1_REG_BASE + (SZ_1K << 1) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* DIT mode, only TX event */
+ {
+ .start = DAVINCI_DM646X_DMA_MCASP1_AXEVT1,
+ .end = DAVINCI_DM646X_DMA_MCASP1_AXEVT1,
+ .flags = IORESOURCE_DMA,
+ },
+ /* DIT mode, dummy entry */
+ {
+ .start = -1,
+ .end = -1,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device dm646x_mcasp0_device = {
+ .name = "davinci-mcasp",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm646x_mcasp0_resources),
+ .resource = dm646x_mcasp0_resources,
+};
+
+static struct platform_device dm646x_mcasp1_device = {
+ .name = "davinci-mcasp",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(dm646x_mcasp1_resources),
+ .resource = dm646x_mcasp1_resources,
+};
+
+static struct platform_device dm646x_dit_device = {
+ .name = "spdif-dit",
+ .id = -1,
+};
+
+static u64 vpif_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource vpif_resource[] = {
+ {
+ .start = DAVINCI_VPIF_BASE,
+ .end = DAVINCI_VPIF_BASE + 0x03ff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device vpif_dev = {
+ .name = "vpif",
+ .id = -1,
+ .dev = {
+ .dma_mask = &vpif_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = vpif_resource,
+ .num_resources = ARRAY_SIZE(vpif_resource),
+};
+
+static struct resource vpif_display_resource[] = {
+ {
+ .start = IRQ_DM646X_VP_VERTINT2,
+ .end = IRQ_DM646X_VP_VERTINT2,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM646X_VP_VERTINT3,
+ .end = IRQ_DM646X_VP_VERTINT3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device vpif_display_dev = {
+ .name = "vpif_display",
+ .id = -1,
+ .dev = {
+ .dma_mask = &vpif_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = vpif_display_resource,
+ .num_resources = ARRAY_SIZE(vpif_display_resource),
+};
+
+static struct resource vpif_capture_resource[] = {
+ {
+ .start = IRQ_DM646X_VP_VERTINT0,
+ .end = IRQ_DM646X_VP_VERTINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM646X_VP_VERTINT1,
+ .end = IRQ_DM646X_VP_VERTINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device vpif_capture_dev = {
+ .name = "vpif_capture",
+ .id = -1,
+ .dev = {
+ .dma_mask = &vpif_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = vpif_capture_resource,
+ .num_resources = ARRAY_SIZE(vpif_capture_resource),
+};
+
+/*----------------------------------------------------------------------*/
+
+static struct map_desc dm646x_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = SRAM_VIRT,
+ .pfn = __phys_to_pfn(0x00010000),
+ .length = SZ_32K,
+ .type = MT_MEMORY_NONCACHED,
+ },
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id dm646x_ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb770,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DM6467,
+ .name = "dm6467_rev1.x",
+ },
+ {
+ .variant = 0x1,
+ .part_no = 0xb770,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DM6467,
+ .name = "dm6467_rev3.x",
+ },
+};
+
+static u32 dm646x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
+
+/*
+ * 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>
+ */
+static struct davinci_timer_info dm646x_timer_info = {
+ .timers = davinci_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
+static struct plat_serial8250_port dm646x_serial_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART0_BASE,
+ .irq = IRQ_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DAVINCI_UART1_BASE,
+ .irq = IRQ_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DAVINCI_UART2_BASE,
+ .irq = IRQ_DM646X_UARTINT2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .flags = 0
+ },
+};
+
+static struct platform_device dm646x_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = dm646x_serial_platform_data,
+ },
+};
+
+static struct davinci_soc_info davinci_soc_info_dm646x = {
+ .io_desc = dm646x_io_desc,
+ .io_desc_num = ARRAY_SIZE(dm646x_io_desc),
+ .jtag_id_reg = 0x01c40028,
+ .ids = dm646x_ids,
+ .ids_num = ARRAY_SIZE(dm646x_ids),
+ .cpu_clks = dm646x_clks,
+ .psc_bases = dm646x_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(dm646x_psc_bases),
+ .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
+ .pinmux_pins = dm646x_pins,
+ .pinmux_pins_num = ARRAY_SIZE(dm646x_pins),
+ .intc_base = DAVINCI_ARM_INTC_BASE,
+ .intc_type = DAVINCI_INTC_TYPE_AINTC,
+ .intc_irq_prios = dm646x_default_priorities,
+ .intc_irq_num = DAVINCI_N_AINTC_IRQ,
+ .timer_info = &dm646x_timer_info,
+ .gpio_type = GPIO_TYPE_DAVINCI,
+ .gpio_base = DAVINCI_GPIO_BASE,
+ .gpio_num = 43, /* Only 33 usable */
+ .gpio_irq = IRQ_DM646X_GPIOBNK0,
+ .serial_dev = &dm646x_serial_device,
+ .emac_pdata = &dm646x_emac_pdata,
+ .sram_dma = 0x10010000,
+ .sram_len = SZ_32K,
+ .reset_device = &davinci_wdt_device,
+};
+
+void __init dm646x_init_mcasp0(struct snd_platform_data *pdata)
+{
+ dm646x_mcasp0_device.dev.platform_data = pdata;
+ platform_device_register(&dm646x_mcasp0_device);
+}
+
+void __init dm646x_init_mcasp1(struct snd_platform_data *pdata)
+{
+ dm646x_mcasp1_device.dev.platform_data = pdata;
+ platform_device_register(&dm646x_mcasp1_device);
+ platform_device_register(&dm646x_dit_device);
+}
+
+void dm646x_setup_vpif(struct vpif_display_config *display_config,
+ struct vpif_capture_config *capture_config)
+{
+ unsigned int value;
+ void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
+
+ value = __raw_readl(base + VSCLKDIS_OFFSET);
+ value &= ~VSCLKDIS_MASK;
+ __raw_writel(value, base + VSCLKDIS_OFFSET);
+
+ value = __raw_readl(base + VDD3P3V_PWDN_OFFSET);
+ value &= ~VDD3P3V_VID_MASK;
+ __raw_writel(value, base + VDD3P3V_PWDN_OFFSET);
+
+ davinci_cfg_reg(DM646X_STSOMUX_DISABLE);
+ davinci_cfg_reg(DM646X_STSIMUX_DISABLE);
+ davinci_cfg_reg(DM646X_PTSOMUX_DISABLE);
+ davinci_cfg_reg(DM646X_PTSIMUX_DISABLE);
+
+ vpif_display_dev.dev.platform_data = display_config;
+ vpif_capture_dev.dev.platform_data = capture_config;
+ platform_device_register(&vpif_dev);
+ platform_device_register(&vpif_display_dev);
+ platform_device_register(&vpif_capture_dev);
+}
+
+int __init dm646x_init_edma(struct edma_rsv_info *rsv)
+{
+ edma_cc0_info.rsv = rsv;
+
+ return platform_device_register(&dm646x_edma_device);
+}
+
+void __init dm646x_init(void)
+{
+ dm646x_board_setup_refclk(&ref_clk);
+ davinci_common_init(&davinci_soc_info_dm646x);
+}
+
+static int __init dm646x_init_devices(void)
+{
+ if (!cpu_is_davinci_dm646x())
+ return 0;
+
+ platform_device_register(&dm646x_mdio_device);
+ platform_device_register(&dm646x_emac_device);
+ clk_add_alias(NULL, dev_name(&dm646x_mdio_device.dev),
+ NULL, &dm646x_emac_device.dev);
+
+ return 0;
+}
+postcore_initcall(dm646x_init_devices);
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
new file mode 100644
index 00000000..6b966986
--- /dev/null
+++ b/arch/arm/mach-davinci/dma.c
@@ -0,0 +1,1596 @@
+/*
+ * EDMA3 support for DaVinci
+ *
+ * Copyright (C) 2006-2009 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/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <mach/edma.h>
+
+/* Offsets matching "struct edmacc_param" */
+#define PARM_OPT 0x00
+#define PARM_SRC 0x04
+#define PARM_A_B_CNT 0x08
+#define PARM_DST 0x0c
+#define PARM_SRC_DST_BIDX 0x10
+#define PARM_LINK_BCNTRLD 0x14
+#define PARM_SRC_DST_CIDX 0x18
+#define PARM_CCNT 0x1c
+
+#define PARM_SIZE 0x20
+
+/* Offsets for EDMA CC global channel registers and their shadows */
+#define SH_ER 0x00 /* 64 bits */
+#define SH_ECR 0x08 /* 64 bits */
+#define SH_ESR 0x10 /* 64 bits */
+#define SH_CER 0x18 /* 64 bits */
+#define SH_EER 0x20 /* 64 bits */
+#define SH_EECR 0x28 /* 64 bits */
+#define SH_EESR 0x30 /* 64 bits */
+#define SH_SER 0x38 /* 64 bits */
+#define SH_SECR 0x40 /* 64 bits */
+#define SH_IER 0x50 /* 64 bits */
+#define SH_IECR 0x58 /* 64 bits */
+#define SH_IESR 0x60 /* 64 bits */
+#define SH_IPR 0x68 /* 64 bits */
+#define SH_ICR 0x70 /* 64 bits */
+#define SH_IEVAL 0x78
+#define SH_QER 0x80
+#define SH_QEER 0x84
+#define SH_QEECR 0x88
+#define SH_QEESR 0x8c
+#define SH_QSER 0x90
+#define SH_QSECR 0x94
+#define SH_SIZE 0x200
+
+/* Offsets for EDMA CC global registers */
+#define EDMA_REV 0x0000
+#define EDMA_CCCFG 0x0004
+#define EDMA_QCHMAP 0x0200 /* 8 registers */
+#define EDMA_DMAQNUM 0x0240 /* 8 registers (4 on OMAP-L1xx) */
+#define EDMA_QDMAQNUM 0x0260
+#define EDMA_QUETCMAP 0x0280
+#define EDMA_QUEPRI 0x0284
+#define EDMA_EMR 0x0300 /* 64 bits */
+#define EDMA_EMCR 0x0308 /* 64 bits */
+#define EDMA_QEMR 0x0310
+#define EDMA_QEMCR 0x0314
+#define EDMA_CCERR 0x0318
+#define EDMA_CCERRCLR 0x031c
+#define EDMA_EEVAL 0x0320
+#define EDMA_DRAE 0x0340 /* 4 x 64 bits*/
+#define EDMA_QRAE 0x0380 /* 4 registers */
+#define EDMA_QUEEVTENTRY 0x0400 /* 2 x 16 registers */
+#define EDMA_QSTAT 0x0600 /* 2 registers */
+#define EDMA_QWMTHRA 0x0620
+#define EDMA_QWMTHRB 0x0624
+#define EDMA_CCSTAT 0x0640
+
+#define EDMA_M 0x1000 /* global channel registers */
+#define EDMA_ECR 0x1008
+#define EDMA_ECRH 0x100C
+#define EDMA_SHADOW0 0x2000 /* 4 regions shadowing global channels */
+#define EDMA_PARM 0x4000 /* 128 param entries */
+
+#define PARM_OFFSET(param_no) (EDMA_PARM + ((param_no) << 5))
+
+#define EDMA_DCHMAP 0x0100 /* 64 registers */
+#define CHMAP_EXIST BIT(24)
+
+#define EDMA_MAX_DMACH 64
+#define EDMA_MAX_PARAMENTRY 512
+
+/*****************************************************************************/
+
+static void __iomem *edmacc_regs_base[EDMA_MAX_CC];
+
+static inline unsigned int edma_read(unsigned ctlr, int offset)
+{
+ return (unsigned int)__raw_readl(edmacc_regs_base[ctlr] + offset);
+}
+
+static inline void edma_write(unsigned ctlr, int offset, int val)
+{
+ __raw_writel(val, edmacc_regs_base[ctlr] + offset);
+}
+static inline void edma_modify(unsigned ctlr, int offset, unsigned and,
+ unsigned or)
+{
+ unsigned val = edma_read(ctlr, offset);
+ val &= and;
+ val |= or;
+ edma_write(ctlr, offset, val);
+}
+static inline void edma_and(unsigned ctlr, int offset, unsigned and)
+{
+ unsigned val = edma_read(ctlr, offset);
+ val &= and;
+ edma_write(ctlr, offset, val);
+}
+static inline void edma_or(unsigned ctlr, int offset, unsigned or)
+{
+ unsigned val = edma_read(ctlr, offset);
+ val |= or;
+ edma_write(ctlr, offset, val);
+}
+static inline unsigned int edma_read_array(unsigned ctlr, int offset, int i)
+{
+ return edma_read(ctlr, offset + (i << 2));
+}
+static inline void edma_write_array(unsigned ctlr, int offset, int i,
+ unsigned val)
+{
+ edma_write(ctlr, offset + (i << 2), val);
+}
+static inline void edma_modify_array(unsigned ctlr, int offset, int i,
+ unsigned and, unsigned or)
+{
+ edma_modify(ctlr, offset + (i << 2), and, or);
+}
+static inline void edma_or_array(unsigned ctlr, int offset, int i, unsigned or)
+{
+ edma_or(ctlr, offset + (i << 2), or);
+}
+static inline void edma_or_array2(unsigned ctlr, int offset, int i, int j,
+ unsigned or)
+{
+ edma_or(ctlr, offset + ((i*2 + j) << 2), or);
+}
+static inline void edma_write_array2(unsigned ctlr, int offset, int i, int j,
+ unsigned val)
+{
+ edma_write(ctlr, offset + ((i*2 + j) << 2), val);
+}
+static inline unsigned int edma_shadow0_read(unsigned ctlr, int offset)
+{
+ return edma_read(ctlr, EDMA_SHADOW0 + offset);
+}
+static inline unsigned int edma_shadow0_read_array(unsigned ctlr, int offset,
+ int i)
+{
+ return edma_read(ctlr, EDMA_SHADOW0 + offset + (i << 2));
+}
+static inline void edma_shadow0_write(unsigned ctlr, int offset, unsigned val)
+{
+ edma_write(ctlr, EDMA_SHADOW0 + offset, val);
+}
+static inline void edma_shadow0_write_array(unsigned ctlr, int offset, int i,
+ unsigned val)
+{
+ edma_write(ctlr, EDMA_SHADOW0 + offset + (i << 2), val);
+}
+static inline unsigned int edma_parm_read(unsigned ctlr, int offset,
+ int param_no)
+{
+ return edma_read(ctlr, EDMA_PARM + offset + (param_no << 5));
+}
+static inline void edma_parm_write(unsigned ctlr, int offset, int param_no,
+ unsigned val)
+{
+ edma_write(ctlr, EDMA_PARM + offset + (param_no << 5), val);
+}
+static inline void edma_parm_modify(unsigned ctlr, int offset, int param_no,
+ unsigned and, unsigned or)
+{
+ edma_modify(ctlr, EDMA_PARM + offset + (param_no << 5), and, or);
+}
+static inline void edma_parm_and(unsigned ctlr, int offset, int param_no,
+ unsigned and)
+{
+ edma_and(ctlr, EDMA_PARM + offset + (param_no << 5), and);
+}
+static inline void edma_parm_or(unsigned ctlr, int offset, int param_no,
+ unsigned or)
+{
+ edma_or(ctlr, EDMA_PARM + offset + (param_no << 5), or);
+}
+
+static inline void set_bits(int offset, int len, unsigned long *p)
+{
+ for (; len > 0; len--)
+ set_bit(offset + (len - 1), p);
+}
+
+static inline void clear_bits(int offset, int len, unsigned long *p)
+{
+ for (; len > 0; len--)
+ clear_bit(offset + (len - 1), p);
+}
+
+/*****************************************************************************/
+
+/* actual number of DMA channels and slots on this silicon */
+struct edma {
+ /* how many dma resources of each type */
+ unsigned num_channels;
+ unsigned num_region;
+ unsigned num_slots;
+ unsigned num_tc;
+ unsigned num_cc;
+ enum dma_event_q default_queue;
+
+ /* list of channels with no even trigger; terminated by "-1" */
+ const s8 *noevent;
+
+ /* The edma_inuse bit for each PaRAM slot is clear unless the
+ * channel is in use ... by ARM or DSP, for QDMA, or whatever.
+ */
+ DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
+
+ /* The edma_unused bit for each channel is clear unless
+ * it is not being used on this platform. It uses a bit
+ * of SOC-specific initialization code.
+ */
+ DECLARE_BITMAP(edma_unused, EDMA_MAX_DMACH);
+
+ unsigned irq_res_start;
+ unsigned irq_res_end;
+
+ struct dma_interrupt_data {
+ void (*callback)(unsigned channel, unsigned short ch_status,
+ void *data);
+ void *data;
+ } intr_data[EDMA_MAX_DMACH];
+};
+
+static struct edma *edma_cc[EDMA_MAX_CC];
+static int arch_num_cc;
+
+/* dummy param set used to (re)initialize parameter RAM slots */
+static const struct edmacc_param dummy_paramset = {
+ .link_bcntrld = 0xffff,
+ .ccnt = 1,
+};
+
+/*****************************************************************************/
+
+static void map_dmach_queue(unsigned ctlr, unsigned ch_no,
+ enum dma_event_q queue_no)
+{
+ int bit = (ch_no & 0x7) * 4;
+
+ /* default to low priority queue */
+ if (queue_no == EVENTQ_DEFAULT)
+ queue_no = edma_cc[ctlr]->default_queue;
+
+ queue_no &= 7;
+ edma_modify_array(ctlr, EDMA_DMAQNUM, (ch_no >> 3),
+ ~(0x7 << bit), queue_no << bit);
+}
+
+static void __init map_queue_tc(unsigned ctlr, int queue_no, int tc_no)
+{
+ int bit = queue_no * 4;
+ edma_modify(ctlr, EDMA_QUETCMAP, ~(0x7 << bit), ((tc_no & 0x7) << bit));
+}
+
+static void __init assign_priority_to_queue(unsigned ctlr, int queue_no,
+ int priority)
+{
+ int bit = queue_no * 4;
+ edma_modify(ctlr, EDMA_QUEPRI, ~(0x7 << bit),
+ ((priority & 0x7) << bit));
+}
+
+/**
+ * map_dmach_param - Maps channel number to param entry number
+ *
+ * This maps the dma channel number to param entry numberter. In
+ * other words using the DMA channel mapping registers a param entry
+ * can be mapped to any channel
+ *
+ * Callers are responsible for ensuring the channel mapping logic is
+ * included in that particular EDMA variant (Eg : dm646x)
+ *
+ */
+static void __init map_dmach_param(unsigned ctlr)
+{
+ int i;
+ for (i = 0; i < EDMA_MAX_DMACH; i++)
+ edma_write_array(ctlr, EDMA_DCHMAP , i , (i << 5));
+}
+
+static inline void
+setup_dma_interrupt(unsigned lch,
+ void (*callback)(unsigned channel, u16 ch_status, void *data),
+ void *data)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(lch);
+ lch = EDMA_CHAN_SLOT(lch);
+
+ if (!callback)
+ edma_shadow0_write_array(ctlr, SH_IECR, lch >> 5,
+ BIT(lch & 0x1f));
+
+ edma_cc[ctlr]->intr_data[lch].callback = callback;
+ edma_cc[ctlr]->intr_data[lch].data = data;
+
+ if (callback) {
+ edma_shadow0_write_array(ctlr, SH_ICR, lch >> 5,
+ BIT(lch & 0x1f));
+ edma_shadow0_write_array(ctlr, SH_IESR, lch >> 5,
+ BIT(lch & 0x1f));
+ }
+}
+
+static int irq2ctlr(int irq)
+{
+ if (irq >= edma_cc[0]->irq_res_start && irq <= edma_cc[0]->irq_res_end)
+ return 0;
+ else if (irq >= edma_cc[1]->irq_res_start &&
+ irq <= edma_cc[1]->irq_res_end)
+ return 1;
+
+ return -1;
+}
+
+/******************************************************************************
+ *
+ * DMA interrupt handler
+ *
+ *****************************************************************************/
+static irqreturn_t dma_irq_handler(int irq, void *data)
+{
+ int i;
+ int ctlr;
+ unsigned int cnt = 0;
+
+ ctlr = irq2ctlr(irq);
+ if (ctlr < 0)
+ return IRQ_NONE;
+
+ dev_dbg(data, "dma_irq_handler\n");
+
+ if ((edma_shadow0_read_array(ctlr, SH_IPR, 0) == 0) &&
+ (edma_shadow0_read_array(ctlr, SH_IPR, 1) == 0))
+ return IRQ_NONE;
+
+ while (1) {
+ int j;
+ if (edma_shadow0_read_array(ctlr, SH_IPR, 0) &
+ edma_shadow0_read_array(ctlr, SH_IER, 0))
+ j = 0;
+ else if (edma_shadow0_read_array(ctlr, SH_IPR, 1) &
+ edma_shadow0_read_array(ctlr, SH_IER, 1))
+ j = 1;
+ else
+ break;
+ dev_dbg(data, "IPR%d %08x\n", j,
+ edma_shadow0_read_array(ctlr, SH_IPR, j));
+ for (i = 0; i < 32; i++) {
+ int k = (j << 5) + i;
+ if ((edma_shadow0_read_array(ctlr, SH_IPR, j) & BIT(i))
+ && (edma_shadow0_read_array(ctlr,
+ SH_IER, j) & BIT(i))) {
+ /* Clear the corresponding IPR bits */
+ edma_shadow0_write_array(ctlr, SH_ICR, j,
+ BIT(i));
+ if (edma_cc[ctlr]->intr_data[k].callback)
+ edma_cc[ctlr]->intr_data[k].callback(
+ k, DMA_COMPLETE,
+ edma_cc[ctlr]->intr_data[k].
+ data);
+ }
+ }
+ cnt++;
+ if (cnt > 10)
+ break;
+ }
+ edma_shadow0_write(ctlr, SH_IEVAL, 1);
+ return IRQ_HANDLED;
+}
+
+/******************************************************************************
+ *
+ * DMA error interrupt handler
+ *
+ *****************************************************************************/
+static irqreturn_t dma_ccerr_handler(int irq, void *data)
+{
+ int i;
+ int ctlr;
+ unsigned int cnt = 0;
+
+ ctlr = irq2ctlr(irq);
+ if (ctlr < 0)
+ return IRQ_NONE;
+
+ dev_dbg(data, "dma_ccerr_handler\n");
+
+ if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) &&
+ (edma_read_array(ctlr, EDMA_EMR, 1) == 0) &&
+ (edma_read(ctlr, EDMA_QEMR) == 0) &&
+ (edma_read(ctlr, EDMA_CCERR) == 0))
+ return IRQ_NONE;
+
+ while (1) {
+ int j = -1;
+ if (edma_read_array(ctlr, EDMA_EMR, 0))
+ j = 0;
+ else if (edma_read_array(ctlr, EDMA_EMR, 1))
+ j = 1;
+ if (j >= 0) {
+ dev_dbg(data, "EMR%d %08x\n", j,
+ edma_read_array(ctlr, EDMA_EMR, j));
+ for (i = 0; i < 32; i++) {
+ int k = (j << 5) + i;
+ if (edma_read_array(ctlr, EDMA_EMR, j) &
+ BIT(i)) {
+ /* Clear the corresponding EMR bits */
+ edma_write_array(ctlr, EDMA_EMCR, j,
+ BIT(i));
+ /* Clear any SER */
+ edma_shadow0_write_array(ctlr, SH_SECR,
+ j, BIT(i));
+ if (edma_cc[ctlr]->intr_data[k].
+ callback) {
+ edma_cc[ctlr]->intr_data[k].
+ callback(k,
+ DMA_CC_ERROR,
+ edma_cc[ctlr]->intr_data
+ [k].data);
+ }
+ }
+ }
+ } else if (edma_read(ctlr, EDMA_QEMR)) {
+ dev_dbg(data, "QEMR %02x\n",
+ edma_read(ctlr, EDMA_QEMR));
+ for (i = 0; i < 8; i++) {
+ if (edma_read(ctlr, EDMA_QEMR) & BIT(i)) {
+ /* Clear the corresponding IPR bits */
+ edma_write(ctlr, EDMA_QEMCR, BIT(i));
+ edma_shadow0_write(ctlr, SH_QSECR,
+ BIT(i));
+
+ /* NOTE: not reported!! */
+ }
+ }
+ } else if (edma_read(ctlr, EDMA_CCERR)) {
+ dev_dbg(data, "CCERR %08x\n",
+ edma_read(ctlr, EDMA_CCERR));
+ /* FIXME: CCERR.BIT(16) ignored! much better
+ * to just write CCERRCLR with CCERR value...
+ */
+ for (i = 0; i < 8; i++) {
+ if (edma_read(ctlr, EDMA_CCERR) & BIT(i)) {
+ /* Clear the corresponding IPR bits */
+ edma_write(ctlr, EDMA_CCERRCLR, BIT(i));
+
+ /* NOTE: not reported!! */
+ }
+ }
+ }
+ if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) &&
+ (edma_read_array(ctlr, EDMA_EMR, 1) == 0) &&
+ (edma_read(ctlr, EDMA_QEMR) == 0) &&
+ (edma_read(ctlr, EDMA_CCERR) == 0))
+ break;
+ cnt++;
+ if (cnt > 10)
+ break;
+ }
+ edma_write(ctlr, EDMA_EEVAL, 1);
+ return IRQ_HANDLED;
+}
+
+/******************************************************************************
+ *
+ * Transfer controller error interrupt handlers
+ *
+ *****************************************************************************/
+
+#define tc_errs_handled false /* disabled as long as they're NOPs */
+
+static irqreturn_t dma_tc0err_handler(int irq, void *data)
+{
+ dev_dbg(data, "dma_tc0err_handler\n");
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t dma_tc1err_handler(int irq, void *data)
+{
+ dev_dbg(data, "dma_tc1err_handler\n");
+ return IRQ_HANDLED;
+}
+
+static int reserve_contiguous_slots(int ctlr, unsigned int id,
+ unsigned int num_slots,
+ unsigned int start_slot)
+{
+ int i, j;
+ unsigned int count = num_slots;
+ int stop_slot = start_slot;
+ DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY);
+
+ for (i = start_slot; i < edma_cc[ctlr]->num_slots; ++i) {
+ j = EDMA_CHAN_SLOT(i);
+ if (!test_and_set_bit(j, edma_cc[ctlr]->edma_inuse)) {
+ /* Record our current beginning slot */
+ if (count == num_slots)
+ stop_slot = i;
+
+ count--;
+ set_bit(j, tmp_inuse);
+
+ if (count == 0)
+ break;
+ } else {
+ clear_bit(j, tmp_inuse);
+
+ if (id == EDMA_CONT_PARAMS_FIXED_EXACT) {
+ stop_slot = i;
+ break;
+ } else {
+ count = num_slots;
+ }
+ }
+ }
+
+ /*
+ * We have to clear any bits that we set
+ * if we run out parameter RAM slots, i.e we do find a set
+ * of contiguous parameter RAM slots but do not find the exact number
+ * requested as we may reach the total number of parameter RAM slots
+ */
+ if (i == edma_cc[ctlr]->num_slots)
+ stop_slot = i;
+
+ for (j = start_slot; j < stop_slot; j++)
+ if (test_bit(j, tmp_inuse))
+ clear_bit(j, edma_cc[ctlr]->edma_inuse);
+
+ if (count)
+ return -EBUSY;
+
+ for (j = i - num_slots + 1; j <= i; ++j)
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j),
+ &dummy_paramset, PARM_SIZE);
+
+ return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1);
+}
+
+static int prepare_unused_channel_list(struct device *dev, void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ int i, ctlr;
+
+ for (i = 0; i < pdev->num_resources; i++) {
+ if ((pdev->resource[i].flags & IORESOURCE_DMA) &&
+ (int)pdev->resource[i].start >= 0) {
+ ctlr = EDMA_CTLR(pdev->resource[i].start);
+ clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start),
+ edma_cc[ctlr]->edma_unused);
+ }
+ }
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+
+static bool unused_chan_list_done;
+
+/* Resource alloc/free: dma channels, parameter RAM slots */
+
+/**
+ * edma_alloc_channel - allocate DMA channel and paired parameter RAM
+ * @channel: specific channel to allocate; negative for "any unmapped channel"
+ * @callback: optional; to be issued on DMA completion or errors
+ * @data: passed to callback
+ * @eventq_no: an EVENTQ_* constant, used to choose which Transfer
+ * Controller (TC) executes requests using this channel. Use
+ * EVENTQ_DEFAULT unless you really need a high priority queue.
+ *
+ * This allocates a DMA channel and its associated parameter RAM slot.
+ * The parameter RAM is initialized to hold a dummy transfer.
+ *
+ * Normal use is to pass a specific channel number as @channel, to make
+ * use of hardware events mapped to that channel. When the channel will
+ * be used only for software triggering or event chaining, channels not
+ * mapped to hardware events (or mapped to unused events) are preferable.
+ *
+ * DMA transfers start from a channel using edma_start(), or by
+ * chaining. When the transfer described in that channel's parameter RAM
+ * slot completes, that slot's data may be reloaded through a link.
+ *
+ * DMA errors are only reported to the @callback associated with the
+ * channel driving that transfer, but transfer completion callbacks can
+ * be sent to another channel under control of the TCC field in
+ * the option word of the transfer's parameter RAM set. Drivers must not
+ * use DMA transfer completion callbacks for channels they did not allocate.
+ * (The same applies to TCC codes used in transfer chaining.)
+ *
+ * Returns the number of the channel, else negative errno.
+ */
+int edma_alloc_channel(int channel,
+ void (*callback)(unsigned channel, u16 ch_status, void *data),
+ void *data,
+ enum dma_event_q eventq_no)
+{
+ unsigned i, done = 0, ctlr = 0;
+ int ret = 0;
+
+ if (!unused_chan_list_done) {
+ /*
+ * Scan all the platform devices to find out the EDMA channels
+ * used and clear them in the unused list, making the rest
+ * available for ARM usage.
+ */
+ ret = bus_for_each_dev(&platform_bus_type, NULL, NULL,
+ prepare_unused_channel_list);
+ if (ret < 0)
+ return ret;
+
+ unused_chan_list_done = true;
+ }
+
+ if (channel >= 0) {
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+ }
+
+ if (channel < 0) {
+ for (i = 0; i < arch_num_cc; i++) {
+ channel = 0;
+ for (;;) {
+ channel = find_next_bit(edma_cc[i]->edma_unused,
+ edma_cc[i]->num_channels,
+ channel);
+ if (channel == edma_cc[i]->num_channels)
+ break;
+ if (!test_and_set_bit(channel,
+ edma_cc[i]->edma_inuse)) {
+ done = 1;
+ ctlr = i;
+ break;
+ }
+ channel++;
+ }
+ if (done)
+ break;
+ }
+ if (!done)
+ return -ENOMEM;
+ } else if (channel >= edma_cc[ctlr]->num_channels) {
+ return -EINVAL;
+ } else if (test_and_set_bit(channel, edma_cc[ctlr]->edma_inuse)) {
+ return -EBUSY;
+ }
+
+ /* ensure access through shadow region 0 */
+ edma_or_array2(ctlr, EDMA_DRAE, 0, channel >> 5, BIT(channel & 0x1f));
+
+ /* ensure no events are pending */
+ edma_stop(EDMA_CTLR_CHAN(ctlr, channel));
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel),
+ &dummy_paramset, PARM_SIZE);
+
+ if (callback)
+ setup_dma_interrupt(EDMA_CTLR_CHAN(ctlr, channel),
+ callback, data);
+
+ map_dmach_queue(ctlr, channel, eventq_no);
+
+ return EDMA_CTLR_CHAN(ctlr, channel);
+}
+EXPORT_SYMBOL(edma_alloc_channel);
+
+
+/**
+ * edma_free_channel - deallocate DMA channel
+ * @channel: dma channel returned from edma_alloc_channel()
+ *
+ * This deallocates the DMA channel and associated parameter RAM slot
+ * allocated by edma_alloc_channel().
+ *
+ * Callers are responsible for ensuring the channel is inactive, and
+ * will not be reactivated by linking, chaining, or software calls to
+ * edma_start().
+ */
+void edma_free_channel(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel >= edma_cc[ctlr]->num_channels)
+ return;
+
+ setup_dma_interrupt(channel, NULL, NULL);
+ /* REVISIT should probably take out of shadow region 0 */
+
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel),
+ &dummy_paramset, PARM_SIZE);
+ clear_bit(channel, edma_cc[ctlr]->edma_inuse);
+}
+EXPORT_SYMBOL(edma_free_channel);
+
+/**
+ * edma_alloc_slot - allocate DMA parameter RAM
+ * @slot: specific slot to allocate; negative for "any unused slot"
+ *
+ * This allocates a parameter RAM slot, initializing it to hold a
+ * dummy transfer. Slots allocated using this routine have not been
+ * mapped to a hardware DMA channel, and will normally be used by
+ * linking to them from a slot associated with a DMA channel.
+ *
+ * Normal use is to pass EDMA_SLOT_ANY as the @slot, but specific
+ * slots may be allocated on behalf of DSP firmware.
+ *
+ * Returns the number of the slot, else negative errno.
+ */
+int edma_alloc_slot(unsigned ctlr, int slot)
+{
+ if (slot >= 0)
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < 0) {
+ slot = edma_cc[ctlr]->num_channels;
+ for (;;) {
+ slot = find_next_zero_bit(edma_cc[ctlr]->edma_inuse,
+ edma_cc[ctlr]->num_slots, slot);
+ if (slot == edma_cc[ctlr]->num_slots)
+ return -ENOMEM;
+ if (!test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse))
+ break;
+ }
+ } else if (slot < edma_cc[ctlr]->num_channels ||
+ slot >= edma_cc[ctlr]->num_slots) {
+ return -EINVAL;
+ } else if (test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse)) {
+ return -EBUSY;
+ }
+
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
+ &dummy_paramset, PARM_SIZE);
+
+ return EDMA_CTLR_CHAN(ctlr, slot);
+}
+EXPORT_SYMBOL(edma_alloc_slot);
+
+/**
+ * edma_free_slot - deallocate DMA parameter RAM
+ * @slot: parameter RAM slot returned from edma_alloc_slot()
+ *
+ * This deallocates the parameter RAM slot allocated by edma_alloc_slot().
+ * Callers are responsible for ensuring the slot is inactive, and will
+ * not be activated.
+ */
+void edma_free_slot(unsigned slot)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_channels ||
+ slot >= edma_cc[ctlr]->num_slots)
+ return;
+
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
+ &dummy_paramset, PARM_SIZE);
+ clear_bit(slot, edma_cc[ctlr]->edma_inuse);
+}
+EXPORT_SYMBOL(edma_free_slot);
+
+
+/**
+ * edma_alloc_cont_slots- alloc contiguous parameter RAM slots
+ * The API will return the starting point of a set of
+ * contiguous parameter RAM slots that have been requested
+ *
+ * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT
+ * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
+ * @count: number of contiguous Paramter RAM slots
+ * @slot - the start value of Parameter RAM slot that should be passed if id
+ * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
+ *
+ * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of
+ * contiguous Parameter RAM slots from parameter RAM 64 in the case of
+ * DaVinci SOCs and 32 in the case of DA8xx SOCs.
+ *
+ * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a
+ * set of contiguous parameter RAM slots from the "slot" that is passed as an
+ * argument to the API.
+ *
+ * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries
+ * starts looking for a set of contiguous parameter RAMs from the "slot"
+ * that is passed as an argument to the API. On failure the API will try to
+ * find a set of contiguous Parameter RAM slots from the remaining Parameter
+ * RAM slots
+ */
+int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
+{
+ /*
+ * The start slot requested should be greater than
+ * the number of channels and lesser than the total number
+ * of slots
+ */
+ if ((id != EDMA_CONT_PARAMS_ANY) &&
+ (slot < edma_cc[ctlr]->num_channels ||
+ slot >= edma_cc[ctlr]->num_slots))
+ return -EINVAL;
+
+ /*
+ * The number of parameter RAM slots requested cannot be less than 1
+ * and cannot be more than the number of slots minus the number of
+ * channels
+ */
+ if (count < 1 || count >
+ (edma_cc[ctlr]->num_slots - edma_cc[ctlr]->num_channels))
+ return -EINVAL;
+
+ switch (id) {
+ case EDMA_CONT_PARAMS_ANY:
+ return reserve_contiguous_slots(ctlr, id, count,
+ edma_cc[ctlr]->num_channels);
+ case EDMA_CONT_PARAMS_FIXED_EXACT:
+ case EDMA_CONT_PARAMS_FIXED_NOT_EXACT:
+ return reserve_contiguous_slots(ctlr, id, count, slot);
+ default:
+ return -EINVAL;
+ }
+
+}
+EXPORT_SYMBOL(edma_alloc_cont_slots);
+
+/**
+ * edma_free_cont_slots - deallocate DMA parameter RAM slots
+ * @slot: first parameter RAM of a set of parameter RAM slots to be freed
+ * @count: the number of contiguous parameter RAM slots to be freed
+ *
+ * This deallocates the parameter RAM slots allocated by
+ * edma_alloc_cont_slots.
+ * Callers/applications need to keep track of sets of contiguous
+ * parameter RAM slots that have been allocated using the edma_alloc_cont_slots
+ * API.
+ * Callers are responsible for ensuring the slots are inactive, and will
+ * not be activated.
+ */
+int edma_free_cont_slots(unsigned slot, int count)
+{
+ unsigned ctlr, slot_to_free;
+ int i;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_channels ||
+ slot >= edma_cc[ctlr]->num_slots ||
+ count < 1)
+ return -EINVAL;
+
+ for (i = slot; i < slot + count; ++i) {
+ ctlr = EDMA_CTLR(i);
+ slot_to_free = EDMA_CHAN_SLOT(i);
+
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot_to_free),
+ &dummy_paramset, PARM_SIZE);
+ clear_bit(slot_to_free, edma_cc[ctlr]->edma_inuse);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(edma_free_cont_slots);
+
+/*-----------------------------------------------------------------------*/
+
+/* Parameter RAM operations (i) -- read/write partial slots */
+
+/**
+ * edma_set_src - set initial DMA source address in parameter RAM slot
+ * @slot: parameter RAM slot being configured
+ * @src_port: physical address of source (memory, controller FIFO, etc)
+ * @addressMode: INCR, except in very rare cases
+ * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the
+ * width to use when addressing the fifo (e.g. W8BIT, W32BIT)
+ *
+ * Note that the source address is modified during the DMA transfer
+ * according to edma_set_src_index().
+ */
+void edma_set_src(unsigned slot, dma_addr_t src_port,
+ enum address_mode mode, enum fifo_width width)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_slots) {
+ unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot);
+
+ if (mode) {
+ /* set SAM and program FWID */
+ i = (i & ~(EDMA_FWID)) | (SAM | ((width & 0x7) << 8));
+ } else {
+ /* clear SAM */
+ i &= ~SAM;
+ }
+ edma_parm_write(ctlr, PARM_OPT, slot, i);
+
+ /* set the source port address
+ in source register of param structure */
+ edma_parm_write(ctlr, PARM_SRC, slot, src_port);
+ }
+}
+EXPORT_SYMBOL(edma_set_src);
+
+/**
+ * edma_set_dest - set initial DMA destination address in parameter RAM slot
+ * @slot: parameter RAM slot being configured
+ * @dest_port: physical address of destination (memory, controller FIFO, etc)
+ * @addressMode: INCR, except in very rare cases
+ * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the
+ * width to use when addressing the fifo (e.g. W8BIT, W32BIT)
+ *
+ * Note that the destination address is modified during the DMA transfer
+ * according to edma_set_dest_index().
+ */
+void edma_set_dest(unsigned slot, dma_addr_t dest_port,
+ enum address_mode mode, enum fifo_width width)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_slots) {
+ unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot);
+
+ if (mode) {
+ /* set DAM and program FWID */
+ i = (i & ~(EDMA_FWID)) | (DAM | ((width & 0x7) << 8));
+ } else {
+ /* clear DAM */
+ i &= ~DAM;
+ }
+ edma_parm_write(ctlr, PARM_OPT, slot, i);
+ /* set the destination port address
+ in dest register of param structure */
+ edma_parm_write(ctlr, PARM_DST, slot, dest_port);
+ }
+}
+EXPORT_SYMBOL(edma_set_dest);
+
+/**
+ * edma_get_position - returns the current transfer points
+ * @slot: parameter RAM slot being examined
+ * @src: pointer to source port position
+ * @dst: pointer to destination port position
+ *
+ * Returns current source and destination addresses for a particular
+ * parameter RAM slot. Its channel should not be active when this is called.
+ */
+void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst)
+{
+ struct edmacc_param temp;
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ edma_read_slot(EDMA_CTLR_CHAN(ctlr, slot), &temp);
+ if (src != NULL)
+ *src = temp.src;
+ if (dst != NULL)
+ *dst = temp.dst;
+}
+EXPORT_SYMBOL(edma_get_position);
+
+/**
+ * edma_set_src_index - configure DMA source address indexing
+ * @slot: parameter RAM slot being configured
+ * @src_bidx: byte offset between source arrays in a frame
+ * @src_cidx: byte offset between source frames in a block
+ *
+ * Offsets are specified to support either contiguous or discontiguous
+ * memory transfers, or repeated access to a hardware register, as needed.
+ * When accessing hardware registers, both offsets are normally zero.
+ */
+void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_slots) {
+ edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot,
+ 0xffff0000, src_bidx);
+ edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot,
+ 0xffff0000, src_cidx);
+ }
+}
+EXPORT_SYMBOL(edma_set_src_index);
+
+/**
+ * edma_set_dest_index - configure DMA destination address indexing
+ * @slot: parameter RAM slot being configured
+ * @dest_bidx: byte offset between destination arrays in a frame
+ * @dest_cidx: byte offset between destination frames in a block
+ *
+ * Offsets are specified to support either contiguous or discontiguous
+ * memory transfers, or repeated access to a hardware register, as needed.
+ * When accessing hardware registers, both offsets are normally zero.
+ */
+void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_slots) {
+ edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot,
+ 0x0000ffff, dest_bidx << 16);
+ edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot,
+ 0x0000ffff, dest_cidx << 16);
+ }
+}
+EXPORT_SYMBOL(edma_set_dest_index);
+
+/**
+ * edma_set_transfer_params - configure DMA transfer parameters
+ * @slot: parameter RAM slot being configured
+ * @acnt: how many bytes per array (at least one)
+ * @bcnt: how many arrays per frame (at least one)
+ * @ccnt: how many frames per block (at least one)
+ * @bcnt_rld: used only for A-Synchronized transfers; this specifies
+ * the value to reload into bcnt when it decrements to zero
+ * @sync_mode: ASYNC or ABSYNC
+ *
+ * See the EDMA3 documentation to understand how to configure and link
+ * transfers using the fields in PaRAM slots. If you are not doing it
+ * all at once with edma_write_slot(), you will use this routine
+ * plus two calls each for source and destination, setting the initial
+ * address and saying how to index that address.
+ *
+ * An example of an A-Synchronized transfer is a serial link using a
+ * single word shift register. In that case, @acnt would be equal to
+ * that word size; the serial controller issues a DMA synchronization
+ * event to transfer each word, and memory access by the DMA transfer
+ * controller will be word-at-a-time.
+ *
+ * An example of an AB-Synchronized transfer is a device using a FIFO.
+ * In that case, @acnt equals the FIFO width and @bcnt equals its depth.
+ * The controller with the FIFO issues DMA synchronization events when
+ * the FIFO threshold is reached, and the DMA transfer controller will
+ * transfer one frame to (or from) the FIFO. It will probably use
+ * efficient burst modes to access memory.
+ */
+void edma_set_transfer_params(unsigned slot,
+ u16 acnt, u16 bcnt, u16 ccnt,
+ u16 bcnt_rld, enum sync_dimension sync_mode)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_slots) {
+ edma_parm_modify(ctlr, PARM_LINK_BCNTRLD, slot,
+ 0x0000ffff, bcnt_rld << 16);
+ if (sync_mode == ASYNC)
+ edma_parm_and(ctlr, PARM_OPT, slot, ~SYNCDIM);
+ else
+ edma_parm_or(ctlr, PARM_OPT, slot, SYNCDIM);
+ /* Set the acount, bcount, ccount registers */
+ edma_parm_write(ctlr, PARM_A_B_CNT, slot, (bcnt << 16) | acnt);
+ edma_parm_write(ctlr, PARM_CCNT, slot, ccnt);
+ }
+}
+EXPORT_SYMBOL(edma_set_transfer_params);
+
+/**
+ * edma_link - link one parameter RAM slot to another
+ * @from: parameter RAM slot originating the link
+ * @to: parameter RAM slot which is the link target
+ *
+ * The originating slot should not be part of any active DMA transfer.
+ */
+void edma_link(unsigned from, unsigned to)
+{
+ unsigned ctlr_from, ctlr_to;
+
+ ctlr_from = EDMA_CTLR(from);
+ from = EDMA_CHAN_SLOT(from);
+ ctlr_to = EDMA_CTLR(to);
+ to = EDMA_CHAN_SLOT(to);
+
+ if (from >= edma_cc[ctlr_from]->num_slots)
+ return;
+ if (to >= edma_cc[ctlr_to]->num_slots)
+ return;
+ edma_parm_modify(ctlr_from, PARM_LINK_BCNTRLD, from, 0xffff0000,
+ PARM_OFFSET(to));
+}
+EXPORT_SYMBOL(edma_link);
+
+/**
+ * edma_unlink - cut link from one parameter RAM slot
+ * @from: parameter RAM slot originating the link
+ *
+ * The originating slot should not be part of any active DMA transfer.
+ * Its link is set to 0xffff.
+ */
+void edma_unlink(unsigned from)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(from);
+ from = EDMA_CHAN_SLOT(from);
+
+ if (from >= edma_cc[ctlr]->num_slots)
+ return;
+ edma_parm_or(ctlr, PARM_LINK_BCNTRLD, from, 0xffff);
+}
+EXPORT_SYMBOL(edma_unlink);
+
+/*-----------------------------------------------------------------------*/
+
+/* Parameter RAM operations (ii) -- read/write whole parameter sets */
+
+/**
+ * edma_write_slot - write parameter RAM data for slot
+ * @slot: number of parameter RAM slot being modified
+ * @param: data to be written into parameter RAM slot
+ *
+ * Use this to assign all parameters of a transfer at once. This
+ * allows more efficient setup of transfers than issuing multiple
+ * calls to set up those parameters in small pieces, and provides
+ * complete control over all transfer options.
+ */
+void edma_write_slot(unsigned slot, const struct edmacc_param *param)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot >= edma_cc[ctlr]->num_slots)
+ return;
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), param,
+ PARM_SIZE);
+}
+EXPORT_SYMBOL(edma_write_slot);
+
+/**
+ * edma_read_slot - read parameter RAM data from slot
+ * @slot: number of parameter RAM slot being copied
+ * @param: where to store copy of parameter RAM data
+ *
+ * Use this to read data from a parameter RAM slot, perhaps to
+ * save them as a template for later reuse.
+ */
+void edma_read_slot(unsigned slot, struct edmacc_param *param)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot >= edma_cc[ctlr]->num_slots)
+ return;
+ memcpy_fromio(param, edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
+ PARM_SIZE);
+}
+EXPORT_SYMBOL(edma_read_slot);
+
+/*-----------------------------------------------------------------------*/
+
+/* Various EDMA channel control operations */
+
+/**
+ * edma_pause - pause dma on a channel
+ * @channel: on which edma_start() has been called
+ *
+ * This temporarily disables EDMA hardware events on the specified channel,
+ * preventing them from triggering new transfers on its behalf
+ */
+void edma_pause(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel < edma_cc[ctlr]->num_channels) {
+ unsigned int mask = BIT(channel & 0x1f);
+
+ edma_shadow0_write_array(ctlr, SH_EECR, channel >> 5, mask);
+ }
+}
+EXPORT_SYMBOL(edma_pause);
+
+/**
+ * edma_resume - resumes dma on a paused channel
+ * @channel: on which edma_pause() has been called
+ *
+ * This re-enables EDMA hardware events on the specified channel.
+ */
+void edma_resume(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel < edma_cc[ctlr]->num_channels) {
+ unsigned int mask = BIT(channel & 0x1f);
+
+ edma_shadow0_write_array(ctlr, SH_EESR, channel >> 5, mask);
+ }
+}
+EXPORT_SYMBOL(edma_resume);
+
+/**
+ * edma_start - start dma on a channel
+ * @channel: channel being activated
+ *
+ * Channels with event associations will be triggered by their hardware
+ * events, and channels without such associations will be triggered by
+ * software. (At this writing there is no interface for using software
+ * triggers except with channels that don't support hardware triggers.)
+ *
+ * Returns zero on success, else negative errno.
+ */
+int edma_start(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel < edma_cc[ctlr]->num_channels) {
+ int j = channel >> 5;
+ unsigned int mask = BIT(channel & 0x1f);
+
+ /* EDMA channels without event association */
+ if (test_bit(channel, edma_cc[ctlr]->edma_unused)) {
+ pr_debug("EDMA: ESR%d %08x\n", j,
+ edma_shadow0_read_array(ctlr, SH_ESR, j));
+ edma_shadow0_write_array(ctlr, SH_ESR, j, mask);
+ return 0;
+ }
+
+ /* EDMA channel with event association */
+ pr_debug("EDMA: ER%d %08x\n", j,
+ edma_shadow0_read_array(ctlr, SH_ER, j));
+ /* Clear any pending event or error */
+ edma_write_array(ctlr, EDMA_ECR, j, mask);
+ edma_write_array(ctlr, EDMA_EMCR, j, mask);
+ /* Clear any SER */
+ edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
+ edma_shadow0_write_array(ctlr, SH_EESR, j, mask);
+ pr_debug("EDMA: EER%d %08x\n", j,
+ edma_shadow0_read_array(ctlr, SH_EER, j));
+ return 0;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(edma_start);
+
+/**
+ * edma_stop - stops dma on the channel passed
+ * @channel: channel being deactivated
+ *
+ * When @lch is a channel, any active transfer is paused and
+ * all pending hardware events are cleared. The current transfer
+ * may not be resumed, and the channel's Parameter RAM should be
+ * reinitialized before being reused.
+ */
+void edma_stop(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel < edma_cc[ctlr]->num_channels) {
+ int j = channel >> 5;
+ unsigned int mask = BIT(channel & 0x1f);
+
+ edma_shadow0_write_array(ctlr, SH_EECR, j, mask);
+ edma_shadow0_write_array(ctlr, SH_ECR, j, mask);
+ edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
+ edma_write_array(ctlr, EDMA_EMCR, j, mask);
+
+ pr_debug("EDMA: EER%d %08x\n", j,
+ edma_shadow0_read_array(ctlr, SH_EER, j));
+
+ /* REVISIT: consider guarding against inappropriate event
+ * chaining by overwriting with dummy_paramset.
+ */
+ }
+}
+EXPORT_SYMBOL(edma_stop);
+
+/******************************************************************************
+ *
+ * It cleans ParamEntry qand bring back EDMA to initial state if media has
+ * been removed before EDMA has finished.It is usedful for removable media.
+ * Arguments:
+ * ch_no - channel no
+ *
+ * Return: zero on success, or corresponding error no on failure
+ *
+ * FIXME this should not be needed ... edma_stop() should suffice.
+ *
+ *****************************************************************************/
+
+void edma_clean_channel(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel < edma_cc[ctlr]->num_channels) {
+ int j = (channel >> 5);
+ unsigned int mask = BIT(channel & 0x1f);
+
+ pr_debug("EDMA: EMR%d %08x\n", j,
+ edma_read_array(ctlr, EDMA_EMR, j));
+ edma_shadow0_write_array(ctlr, SH_ECR, j, mask);
+ /* Clear the corresponding EMR bits */
+ edma_write_array(ctlr, EDMA_EMCR, j, mask);
+ /* Clear any SER */
+ edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
+ edma_write(ctlr, EDMA_CCERRCLR, BIT(16) | BIT(1) | BIT(0));
+ }
+}
+EXPORT_SYMBOL(edma_clean_channel);
+
+/*
+ * edma_clear_event - clear an outstanding event on the DMA channel
+ * Arguments:
+ * channel - channel number
+ */
+void edma_clear_event(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel >= edma_cc[ctlr]->num_channels)
+ return;
+ if (channel < 32)
+ edma_write(ctlr, EDMA_ECR, BIT(channel));
+ else
+ edma_write(ctlr, EDMA_ECRH, BIT(channel - 32));
+}
+EXPORT_SYMBOL(edma_clear_event);
+
+/*-----------------------------------------------------------------------*/
+
+static int __init edma_probe(struct platform_device *pdev)
+{
+ struct edma_soc_info **info = pdev->dev.platform_data;
+ const s8 (*queue_priority_mapping)[2];
+ const s8 (*queue_tc_mapping)[2];
+ int i, j, off, ln, found = 0;
+ int status = -1;
+ const s16 (*rsv_chans)[2];
+ const s16 (*rsv_slots)[2];
+ int irq[EDMA_MAX_CC] = {0, 0};
+ int err_irq[EDMA_MAX_CC] = {0, 0};
+ struct resource *r[EDMA_MAX_CC] = {NULL};
+ resource_size_t len[EDMA_MAX_CC];
+ char res_name[10];
+ char irq_name[10];
+
+ if (!info)
+ return -ENODEV;
+
+ for (j = 0; j < EDMA_MAX_CC; j++) {
+ sprintf(res_name, "edma_cc%d", j);
+ r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ res_name);
+ if (!r[j] || !info[j]) {
+ if (found)
+ break;
+ else
+ return -ENODEV;
+ } else {
+ found = 1;
+ }
+
+ len[j] = resource_size(r[j]);
+
+ r[j] = request_mem_region(r[j]->start, len[j],
+ dev_name(&pdev->dev));
+ if (!r[j]) {
+ status = -EBUSY;
+ goto fail1;
+ }
+
+ edmacc_regs_base[j] = ioremap(r[j]->start, len[j]);
+ if (!edmacc_regs_base[j]) {
+ status = -EBUSY;
+ goto fail1;
+ }
+
+ edma_cc[j] = kmalloc(sizeof(struct edma), GFP_KERNEL);
+ if (!edma_cc[j]) {
+ status = -ENOMEM;
+ goto fail1;
+ }
+ memset(edma_cc[j], 0, sizeof(struct edma));
+
+ edma_cc[j]->num_channels = min_t(unsigned, info[j]->n_channel,
+ EDMA_MAX_DMACH);
+ edma_cc[j]->num_slots = min_t(unsigned, info[j]->n_slot,
+ EDMA_MAX_PARAMENTRY);
+ edma_cc[j]->num_cc = min_t(unsigned, info[j]->n_cc,
+ EDMA_MAX_CC);
+
+ edma_cc[j]->default_queue = info[j]->default_queue;
+ if (!edma_cc[j]->default_queue)
+ edma_cc[j]->default_queue = EVENTQ_1;
+
+ dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n",
+ edmacc_regs_base[j]);
+
+ for (i = 0; i < edma_cc[j]->num_slots; i++)
+ memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i),
+ &dummy_paramset, PARM_SIZE);
+
+ /* Mark all channels as unused */
+ memset(edma_cc[j]->edma_unused, 0xff,
+ sizeof(edma_cc[j]->edma_unused));
+
+ if (info[j]->rsv) {
+
+ /* Clear the reserved channels in unused list */
+ rsv_chans = info[j]->rsv->rsv_chans;
+ if (rsv_chans) {
+ for (i = 0; rsv_chans[i][0] != -1; i++) {
+ off = rsv_chans[i][0];
+ ln = rsv_chans[i][1];
+ clear_bits(off, ln,
+ edma_cc[j]->edma_unused);
+ }
+ }
+
+ /* Set the reserved slots in inuse list */
+ rsv_slots = info[j]->rsv->rsv_slots;
+ if (rsv_slots) {
+ for (i = 0; rsv_slots[i][0] != -1; i++) {
+ off = rsv_slots[i][0];
+ ln = rsv_slots[i][1];
+ set_bits(off, ln,
+ edma_cc[j]->edma_inuse);
+ }
+ }
+ }
+
+ sprintf(irq_name, "edma%d", j);
+ irq[j] = platform_get_irq_byname(pdev, irq_name);
+ edma_cc[j]->irq_res_start = irq[j];
+ status = request_irq(irq[j], dma_irq_handler, 0, "edma",
+ &pdev->dev);
+ if (status < 0) {
+ dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
+ irq[j], status);
+ goto fail;
+ }
+
+ sprintf(irq_name, "edma%d_err", j);
+ err_irq[j] = platform_get_irq_byname(pdev, irq_name);
+ edma_cc[j]->irq_res_end = err_irq[j];
+ status = request_irq(err_irq[j], dma_ccerr_handler, 0,
+ "edma_error", &pdev->dev);
+ if (status < 0) {
+ dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
+ err_irq[j], status);
+ goto fail;
+ }
+
+ /* Everything lives on transfer controller 1 until otherwise
+ * specified. This way, long transfers on the low priority queue
+ * started by the codec engine will not cause audio defects.
+ */
+ for (i = 0; i < edma_cc[j]->num_channels; i++)
+ map_dmach_queue(j, i, EVENTQ_1);
+
+ queue_tc_mapping = info[j]->queue_tc_mapping;
+ queue_priority_mapping = info[j]->queue_priority_mapping;
+
+ /* Event queue to TC mapping */
+ for (i = 0; queue_tc_mapping[i][0] != -1; i++)
+ map_queue_tc(j, queue_tc_mapping[i][0],
+ queue_tc_mapping[i][1]);
+
+ /* Event queue priority mapping */
+ for (i = 0; queue_priority_mapping[i][0] != -1; i++)
+ assign_priority_to_queue(j,
+ queue_priority_mapping[i][0],
+ queue_priority_mapping[i][1]);
+
+ /* Map the channel to param entry if channel mapping logic
+ * exist
+ */
+ if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST)
+ map_dmach_param(j);
+
+ for (i = 0; i < info[j]->n_region; i++) {
+ edma_write_array2(j, EDMA_DRAE, i, 0, 0x0);
+ edma_write_array2(j, EDMA_DRAE, i, 1, 0x0);
+ edma_write_array(j, EDMA_QRAE, i, 0x0);
+ }
+ arch_num_cc++;
+ }
+
+ if (tc_errs_handled) {
+ status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0,
+ "edma_tc0", &pdev->dev);
+ if (status < 0) {
+ dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
+ IRQ_TCERRINT0, status);
+ return status;
+ }
+ status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0,
+ "edma_tc1", &pdev->dev);
+ if (status < 0) {
+ dev_dbg(&pdev->dev, "request_irq %d --> %d\n",
+ IRQ_TCERRINT, status);
+ return status;
+ }
+ }
+
+ return 0;
+
+fail:
+ for (i = 0; i < EDMA_MAX_CC; i++) {
+ if (err_irq[i])
+ free_irq(err_irq[i], &pdev->dev);
+ if (irq[i])
+ free_irq(irq[i], &pdev->dev);
+ }
+fail1:
+ for (i = 0; i < EDMA_MAX_CC; i++) {
+ if (r[i])
+ release_mem_region(r[i]->start, len[i]);
+ if (edmacc_regs_base[i])
+ iounmap(edmacc_regs_base[i]);
+ kfree(edma_cc[i]);
+ }
+ return status;
+}
+
+
+static struct platform_driver edma_driver = {
+ .driver.name = "edma",
+};
+
+static int __init edma_init(void)
+{
+ return platform_driver_probe(&edma_driver, edma_probe);
+}
+arch_initcall(edma_init);
+
diff --git a/arch/arm/mach-davinci/gpio-tnetv107x.c b/arch/arm/mach-davinci/gpio-tnetv107x.c
new file mode 100644
index 00000000..3fa3e286
--- /dev/null
+++ b/arch/arm/mach-davinci/gpio-tnetv107x.c
@@ -0,0 +1,205 @@
+/*
+ * Texas Instruments TNETV107X GPIO Controller
+ *
+ * Copyright (C) 2010 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+
+#include <mach/common.h>
+#include <mach/tnetv107x.h>
+
+struct tnetv107x_gpio_regs {
+ u32 idver;
+ u32 data_in[3];
+ u32 data_out[3];
+ u32 direction[3];
+ u32 enable[3];
+};
+
+#define gpio_reg_index(gpio) ((gpio) >> 5)
+#define gpio_reg_bit(gpio) BIT((gpio) & 0x1f)
+
+#define gpio_reg_rmw(reg, mask, val) \
+ __raw_writel((__raw_readl(reg) & ~(mask)) | (val), (reg))
+
+#define gpio_reg_set_bit(reg, gpio) \
+ gpio_reg_rmw((reg) + gpio_reg_index(gpio), 0, gpio_reg_bit(gpio))
+
+#define gpio_reg_clear_bit(reg, gpio) \
+ gpio_reg_rmw((reg) + gpio_reg_index(gpio), gpio_reg_bit(gpio), 0)
+
+#define gpio_reg_get_bit(reg, gpio) \
+ (__raw_readl((reg) + gpio_reg_index(gpio)) & gpio_reg_bit(gpio))
+
+#define chip2controller(chip) \
+ container_of(chip, struct davinci_gpio_controller, chip)
+
+#define TNETV107X_GPIO_CTLRS DIV_ROUND_UP(TNETV107X_N_GPIO, 32)
+
+static struct davinci_gpio_controller chips[TNETV107X_GPIO_CTLRS];
+
+static int tnetv107x_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ gpio_reg_set_bit(regs->enable, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+
+ return 0;
+}
+
+static void tnetv107x_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ gpio_reg_clear_bit(regs->enable, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+}
+
+static int tnetv107x_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ gpio_reg_set_bit(regs->direction, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+
+ return 0;
+}
+
+static int tnetv107x_gpio_dir_out(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ if (value)
+ gpio_reg_set_bit(regs->data_out, gpio);
+ else
+ gpio_reg_clear_bit(regs->data_out, gpio);
+
+ gpio_reg_clear_bit(regs->direction, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+
+ return 0;
+}
+
+static int tnetv107x_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ int ret;
+
+ ret = gpio_reg_get_bit(regs->data_in, gpio);
+
+ return ret ? 1 : 0;
+}
+
+static void tnetv107x_gpio_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ if (value)
+ gpio_reg_set_bit(regs->data_out, gpio);
+ else
+ gpio_reg_clear_bit(regs->data_out, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+}
+
+static int __init tnetv107x_gpio_setup(void)
+{
+ int i, base;
+ unsigned ngpio;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ struct tnetv107x_gpio_regs *regs;
+ struct davinci_gpio_controller *ctlr;
+
+ if (soc_info->gpio_type != GPIO_TYPE_TNETV107X)
+ return 0;
+
+ ngpio = soc_info->gpio_num;
+ if (ngpio == 0) {
+ pr_err("GPIO setup: how many GPIOs?\n");
+ return -EINVAL;
+ }
+
+ if (WARN_ON(TNETV107X_N_GPIO < ngpio))
+ ngpio = TNETV107X_N_GPIO;
+
+ regs = ioremap(soc_info->gpio_base, SZ_4K);
+ if (WARN_ON(!regs))
+ return -EINVAL;
+
+ for (i = 0, base = 0; base < ngpio; i++, base += 32) {
+ ctlr = &chips[i];
+
+ ctlr->chip.label = "tnetv107x";
+ ctlr->chip.can_sleep = 0;
+ ctlr->chip.base = base;
+ ctlr->chip.ngpio = ngpio - base;
+ if (ctlr->chip.ngpio > 32)
+ ctlr->chip.ngpio = 32;
+
+ ctlr->chip.request = tnetv107x_gpio_request;
+ ctlr->chip.free = tnetv107x_gpio_free;
+ ctlr->chip.direction_input = tnetv107x_gpio_dir_in;
+ ctlr->chip.get = tnetv107x_gpio_get;
+ ctlr->chip.direction_output = tnetv107x_gpio_dir_out;
+ ctlr->chip.set = tnetv107x_gpio_set;
+
+ spin_lock_init(&ctlr->lock);
+
+ ctlr->regs = regs;
+ ctlr->set_data = &regs->data_out[i];
+ ctlr->clr_data = &regs->data_out[i];
+ ctlr->in_data = &regs->data_in[i];
+
+ gpiochip_add(&ctlr->chip);
+ }
+
+ soc_info->gpio_ctlrs = chips;
+ soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32);
+ return 0;
+}
+pure_initcall(tnetv107x_gpio_setup);
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
new file mode 100644
index 00000000..cafbe13a
--- /dev/null
+++ b/arch/arm/mach-davinci/gpio.c
@@ -0,0 +1,460 @@
+/*
+ * TI DaVinci GPIO Support
+ *
+ * Copyright (c) 2006-2007 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/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/gpio.h>
+
+#include <asm/mach/irq.h>
+
+struct davinci_gpio_regs {
+ u32 dir;
+ u32 out_data;
+ u32 set_data;
+ u32 clr_data;
+ u32 in_data;
+ u32 set_rising;
+ u32 clr_rising;
+ u32 set_falling;
+ u32 clr_falling;
+ u32 intstat;
+};
+
+#define chip2controller(chip) \
+ container_of(chip, struct davinci_gpio_controller, chip)
+
+static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
+static void __iomem *gpio_base;
+
+static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio)
+{
+ void __iomem *ptr;
+
+ if (gpio < 32 * 1)
+ ptr = gpio_base + 0x10;
+ else if (gpio < 32 * 2)
+ ptr = gpio_base + 0x38;
+ else if (gpio < 32 * 3)
+ ptr = gpio_base + 0x60;
+ else if (gpio < 32 * 4)
+ ptr = gpio_base + 0x88;
+ else if (gpio < 32 * 5)
+ ptr = gpio_base + 0xb0;
+ else
+ ptr = NULL;
+ return ptr;
+}
+
+static inline struct davinci_gpio_regs __iomem *irq2regs(int irq)
+{
+ struct davinci_gpio_regs __iomem *g;
+
+ g = (__force struct davinci_gpio_regs __iomem *)irq_get_chip_data(irq);
+
+ return g;
+}
+
+static int __init davinci_gpio_irq_setup(void);
+
+/*--------------------------------------------------------------------------*/
+
+/* board setup code *MUST* setup pinmux and enable the GPIO clock. */
+static inline int __davinci_direction(struct gpio_chip *chip,
+ unsigned offset, bool out, int value)
+{
+ struct davinci_gpio_controller *d = chip2controller(chip);
+ struct davinci_gpio_regs __iomem *g = d->regs;
+ unsigned long flags;
+ u32 temp;
+ u32 mask = 1 << offset;
+
+ spin_lock_irqsave(&d->lock, flags);
+ temp = __raw_readl(&g->dir);
+ if (out) {
+ temp &= ~mask;
+ __raw_writel(mask, value ? &g->set_data : &g->clr_data);
+ } else {
+ temp |= mask;
+ }
+ __raw_writel(temp, &g->dir);
+ spin_unlock_irqrestore(&d->lock, flags);
+
+ return 0;
+}
+
+static int davinci_direction_in(struct gpio_chip *chip, unsigned offset)
+{
+ return __davinci_direction(chip, offset, false, 0);
+}
+
+static int
+davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value)
+{
+ return __davinci_direction(chip, offset, true, value);
+}
+
+/*
+ * 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.
+ */
+static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *d = chip2controller(chip);
+ struct davinci_gpio_regs __iomem *g = d->regs;
+
+ return (1 << offset) & __raw_readl(&g->in_data);
+}
+
+/*
+ * Assuming the pin is muxed as a gpio output, set its output value.
+ */
+static void
+davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct davinci_gpio_controller *d = chip2controller(chip);
+ struct davinci_gpio_regs __iomem *g = d->regs;
+
+ __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data);
+}
+
+static int __init davinci_gpio_setup(void)
+{
+ int i, base;
+ unsigned ngpio;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ struct davinci_gpio_regs *regs;
+
+ if (soc_info->gpio_type != GPIO_TYPE_DAVINCI)
+ return 0;
+
+ /*
+ * The gpio banks conceptually expose a segmented bitmap,
+ * and "ngpio" is one more than the largest zero-based
+ * bit index that's valid.
+ */
+ ngpio = soc_info->gpio_num;
+ if (ngpio == 0) {
+ pr_err("GPIO setup: how many GPIOs?\n");
+ return -EINVAL;
+ }
+
+ if (WARN_ON(DAVINCI_N_GPIO < ngpio))
+ ngpio = DAVINCI_N_GPIO;
+
+ gpio_base = ioremap(soc_info->gpio_base, SZ_4K);
+ if (WARN_ON(!gpio_base))
+ return -ENOMEM;
+
+ for (i = 0, base = 0; base < ngpio; i++, base += 32) {
+ chips[i].chip.label = "DaVinci";
+
+ chips[i].chip.direction_input = davinci_direction_in;
+ chips[i].chip.get = davinci_gpio_get;
+ chips[i].chip.direction_output = davinci_direction_out;
+ chips[i].chip.set = davinci_gpio_set;
+
+ chips[i].chip.base = base;
+ chips[i].chip.ngpio = ngpio - base;
+ if (chips[i].chip.ngpio > 32)
+ chips[i].chip.ngpio = 32;
+
+ spin_lock_init(&chips[i].lock);
+
+ regs = gpio2regs(base);
+ chips[i].regs = regs;
+ chips[i].set_data = &regs->set_data;
+ chips[i].clr_data = &regs->clr_data;
+ chips[i].in_data = &regs->in_data;
+
+ gpiochip_add(&chips[i].chip);
+ }
+
+ soc_info->gpio_ctlrs = chips;
+ soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32);
+
+ davinci_gpio_irq_setup();
+ return 0;
+}
+pure_initcall(davinci_gpio_setup);
+
+/*--------------------------------------------------------------------------*/
+/*
+ * 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: The first few GPIOs also have direct INTC hookups in addition
+ * to their GPIOBNK0 irq, with a bit less overhead.
+ *
+ * All those INTC hookups (direct, plus several IRQ banks) can also
+ * serve as EDMA event triggers.
+ */
+
+static void gpio_irq_disable(struct irq_data *d)
+{
+ struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
+ u32 mask = (u32) irq_data_get_irq_handler_data(d);
+
+ __raw_writel(mask, &g->clr_falling);
+ __raw_writel(mask, &g->clr_rising);
+}
+
+static void gpio_irq_enable(struct irq_data *d)
+{
+ struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
+ u32 mask = (u32) irq_data_get_irq_handler_data(d);
+ unsigned status = irqd_get_trigger_type(d);
+
+ status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
+ if (!status)
+ status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
+
+ if (status & IRQ_TYPE_EDGE_FALLING)
+ __raw_writel(mask, &g->set_falling);
+ if (status & IRQ_TYPE_EDGE_RISING)
+ __raw_writel(mask, &g->set_rising);
+}
+
+static int gpio_irq_type(struct irq_data *d, unsigned trigger)
+{
+ struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
+ u32 mask = (u32) irq_data_get_irq_handler_data(d);
+
+ if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+ return -EINVAL;
+
+ return 0;
+}
+
+static struct irq_chip gpio_irqchip = {
+ .name = "GPIO",
+ .irq_enable = gpio_irq_enable,
+ .irq_disable = gpio_irq_disable,
+ .irq_set_type = gpio_irq_type,
+ .flags = IRQCHIP_SET_TYPE_MASKED,
+};
+
+static void
+gpio_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+ struct davinci_gpio_regs __iomem *g;
+ u32 mask = 0xffff;
+ struct davinci_gpio_controller *d;
+
+ d = (struct davinci_gpio_controller *)irq_desc_get_handler_data(desc);
+ g = (struct davinci_gpio_regs __iomem *)d->regs;
+
+ /* we only care about one bank */
+ if (irq & 1)
+ mask <<= 16;
+
+ /* temporarily mask (level sensitive) parent IRQ */
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+ while (1) {
+ u32 status;
+ int n;
+ int res;
+
+ /* ack any irqs */
+ status = __raw_readl(&g->intstat) & mask;
+ if (!status)
+ break;
+ __raw_writel(status, &g->intstat);
+
+ /* now demux them to the right lowlevel handler */
+ n = d->irq_base;
+ if (irq & 1) {
+ n += 16;
+ status >>= 16;
+ }
+
+ while (status) {
+ res = ffs(status);
+ n += res;
+ generic_handle_irq(n - 1);
+ status >>= res;
+ }
+ }
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+ /* now it may re-trigger */
+}
+
+static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *d = chip2controller(chip);
+
+ if (d->irq_base >= 0)
+ return d->irq_base + offset;
+ else
+ return -ENODEV;
+}
+
+static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ /* NOTE: we assume for now that only irqs in the first gpio_chip
+ * can provide direct-mapped IRQs to AINTC (up to 32 GPIOs).
+ */
+ if (offset < soc_info->gpio_unbanked)
+ return soc_info->gpio_irq + offset;
+ else
+ return -ENODEV;
+}
+
+static int gpio_irq_type_unbanked(struct irq_data *d, unsigned trigger)
+{
+ struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
+ u32 mask = (u32) irq_data_get_irq_handler_data(d);
+
+ if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+ return -EINVAL;
+
+ __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;
+}
+
+/*
+ * NOTE: for suspend/resume, probably best to make a platform_device with
+ * suspend_late/resume_resume calls hooking into 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
+ * (dm6446) can be set appropriately for GPIOV33 pins.
+ */
+
+static int __init davinci_gpio_irq_setup(void)
+{
+ unsigned gpio, irq, bank;
+ struct clk *clk;
+ u32 binten = 0;
+ unsigned ngpio, bank_irq;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ struct davinci_gpio_regs __iomem *g;
+
+ ngpio = soc_info->gpio_num;
+
+ bank_irq = soc_info->gpio_irq;
+ if (bank_irq == 0) {
+ printk(KERN_ERR "Don't know first GPIO bank IRQ.\n");
+ return -EINVAL;
+ }
+
+ clk = clk_get(NULL, "gpio");
+ if (IS_ERR(clk)) {
+ printk(KERN_ERR "Error %ld getting gpio clock?\n",
+ PTR_ERR(clk));
+ return PTR_ERR(clk);
+ }
+ clk_enable(clk);
+
+ /* Arrange gpio_to_irq() support, handling either direct IRQs or
+ * banked IRQs. Having GPIOs in the first GPIO bank use direct
+ * IRQs, while the others use banked IRQs, would need some setup
+ * tweaks to recognize hardware which can do that.
+ */
+ for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) {
+ chips[bank].chip.to_irq = gpio_to_irq_banked;
+ chips[bank].irq_base = soc_info->gpio_unbanked
+ ? -EINVAL
+ : (soc_info->intc_irq_num + gpio);
+ }
+
+ /*
+ * AINTC can handle direct/unbanked IRQs for GPIOs, with the GPIO
+ * controller only handling trigger modes. We currently assume no
+ * IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs.
+ */
+ if (soc_info->gpio_unbanked) {
+ static struct irq_chip gpio_irqchip_unbanked;
+
+ /* pass "bank 0" GPIO IRQs to AINTC */
+ chips[0].chip.to_irq = gpio_to_irq_unbanked;
+ binten = BIT(0);
+
+ /* AINTC handles mask/unmask; GPIO handles triggering */
+ irq = bank_irq;
+ gpio_irqchip_unbanked = *irq_get_chip(irq);
+ gpio_irqchip_unbanked.name = "GPIO-AINTC";
+ gpio_irqchip_unbanked.irq_set_type = gpio_irq_type_unbanked;
+
+ /* default trigger: both edges */
+ g = gpio2regs(0);
+ __raw_writel(~0, &g->set_falling);
+ __raw_writel(~0, &g->set_rising);
+
+ /* set the direct IRQs up to use that irqchip */
+ for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) {
+ irq_set_chip(irq, &gpio_irqchip_unbanked);
+ irq_set_handler_data(irq, (void *)__gpio_mask(gpio));
+ irq_set_chip_data(irq, (__force void *)g);
+ irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH);
+ }
+
+ goto done;
+ }
+
+ /*
+ * Or, AINTC can handle IRQs for banks of 16 GPIO IRQs, which we
+ * then chain through our own handler.
+ */
+ for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
+ gpio < ngpio;
+ bank++, bank_irq++) {
+ unsigned i;
+
+ /* disabled by default, enabled only as needed */
+ g = gpio2regs(gpio);
+ __raw_writel(~0, &g->clr_falling);
+ __raw_writel(~0, &g->clr_rising);
+
+ /* set up all irqs in this bank */
+ irq_set_chained_handler(bank_irq, gpio_irq_handler);
+
+ /*
+ * Each chip handles 32 gpios, and each irq bank consists of 16
+ * gpio irqs. Pass the irq bank's corresponding controller to
+ * the chained irq handler.
+ */
+ irq_set_handler_data(bank_irq, &chips[gpio / 32]);
+
+ for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
+ irq_set_chip(irq, &gpio_irqchip);
+ irq_set_chip_data(irq, (__force void *)g);
+ irq_set_handler_data(irq, (void *)__gpio_mask(gpio));
+ irq_set_handler(irq, handle_simple_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ binten |= BIT(bank);
+ }
+
+done:
+ /* BINTEN -- per-bank interrupt enable. genirq would also let these
+ * bits be set/cleared dynamically.
+ */
+ __raw_writel(binten, gpio_base + 0x08);
+
+ printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
+
+ return 0;
+}
diff --git a/arch/arm/mach-davinci/include/mach/aemif.h b/arch/arm/mach-davinci/include/mach/aemif.h
new file mode 100644
index 00000000..05b29344
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/aemif.h
@@ -0,0 +1,36 @@
+/*
+ * TI DaVinci AEMIF support
+ *
+ * Copyright 2010 (C) Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+#ifndef _MACH_DAVINCI_AEMIF_H
+#define _MACH_DAVINCI_AEMIF_H
+
+#define NRCSR_OFFSET 0x00
+#define AWCCR_OFFSET 0x04
+#define A1CR_OFFSET 0x10
+
+#define ACR_ASIZE_MASK 0x3
+#define ACR_EW_MASK BIT(30)
+#define ACR_SS_MASK BIT(31)
+
+/* All timings in nanoseconds */
+struct davinci_aemif_timing {
+ u8 wsetup;
+ u8 wstrobe;
+ u8 whold;
+
+ u8 rsetup;
+ u8 rstrobe;
+ u8 rhold;
+
+ u8 ta;
+};
+
+int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
+ void __iomem *base, unsigned cs);
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/asp.h b/arch/arm/mach-davinci/include/mach/asp.h
new file mode 100644
index 00000000..9aa24090
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/asp.h
@@ -0,0 +1,137 @@
+/*
+ * <mach/asp.h> - DaVinci Audio Serial Port support
+ */
+#ifndef __ASM_ARCH_DAVINCI_ASP_H
+#define __ASM_ARCH_DAVINCI_ASP_H
+
+#include <mach/irqs.h>
+#include <mach/edma.h>
+
+/* Bases of dm644x and dm355 register banks */
+#define DAVINCI_ASP0_BASE 0x01E02000
+#define DAVINCI_ASP1_BASE 0x01E04000
+
+/* Bases of dm365 register banks */
+#define DAVINCI_DM365_ASP0_BASE 0x01D02000
+
+/* Bases of dm646x register banks */
+#define DAVINCI_DM646X_MCASP0_REG_BASE 0x01D01000
+#define DAVINCI_DM646X_MCASP1_REG_BASE 0x01D01800
+
+/* Bases of da850/da830 McASP0 register banks */
+#define DAVINCI_DA8XX_MCASP0_REG_BASE 0x01D00000
+
+/* Bases of da830 McASP1 register banks */
+#define DAVINCI_DA830_MCASP1_REG_BASE 0x01D04000
+
+/* EDMA channels of dm644x and dm355 */
+#define DAVINCI_DMA_ASP0_TX 2
+#define DAVINCI_DMA_ASP0_RX 3
+#define DAVINCI_DMA_ASP1_TX 8
+#define DAVINCI_DMA_ASP1_RX 9
+
+/* EDMA channels of dm646x */
+#define DAVINCI_DM646X_DMA_MCASP0_AXEVT0 6
+#define DAVINCI_DM646X_DMA_MCASP0_AREVT0 9
+#define DAVINCI_DM646X_DMA_MCASP1_AXEVT1 12
+
+/* EDMA channels of da850/da830 McASP0 */
+#define DAVINCI_DA8XX_DMA_MCASP0_AREVT 0
+#define DAVINCI_DA8XX_DMA_MCASP0_AXEVT 1
+
+/* EDMA channels of da830 McASP1 */
+#define DAVINCI_DA830_DMA_MCASP1_AREVT 2
+#define DAVINCI_DA830_DMA_MCASP1_AXEVT 3
+
+/* Interrupts */
+#define DAVINCI_ASP0_RX_INT IRQ_MBRINT
+#define DAVINCI_ASP0_TX_INT IRQ_MBXINT
+#define DAVINCI_ASP1_RX_INT IRQ_MBRINT
+#define DAVINCI_ASP1_TX_INT IRQ_MBXINT
+
+struct snd_platform_data {
+ u32 tx_dma_offset;
+ u32 rx_dma_offset;
+ enum dma_event_q asp_chan_q; /* event queue number for ASP channel */
+ enum dma_event_q ram_chan_q; /* event queue number for RAM channel */
+ unsigned int codec_fmt;
+ /*
+ * Allowing this is more efficient and eliminates left and right swaps
+ * caused by underruns, but will swap the left and right channels
+ * when compared to previous behavior.
+ */
+ unsigned enable_channel_combine:1;
+ unsigned sram_size_playback;
+ unsigned sram_size_capture;
+
+ /*
+ * If McBSP peripheral gets the clock from an external pin,
+ * there are three chooses, that are MCBSP_CLKX, MCBSP_CLKR
+ * and MCBSP_CLKS.
+ * Depending on different hardware connections it is possible
+ * to use this setting to change the behaviour of McBSP
+ * driver. The dm365_clk_input_pin enum is available for dm365
+ */
+ int clk_input_pin;
+
+ /*
+ * This flag works when both clock and FS are outputs for the cpu
+ * and makes clock more accurate (FS is not symmetrical and the
+ * clock is very fast.
+ * The clock becoming faster is named
+ * i2s continuous serial clock (I2S_SCK) and it is an externally
+ * visible bit clock.
+ *
+ * first line : WordSelect
+ * second line : ContinuousSerialClock
+ * third line: SerialData
+ *
+ * SYMMETRICAL APPROACH:
+ * _______________________ LEFT
+ * _| RIGHT |______________________|
+ * _ _ _ _ _ _ _ _
+ * _| |_| |_ x16 _| |_| |_| |_| |_ x16 _| |_| |_
+ * _ _ _ _ _ _ _ _
+ * _/ \_/ \_ ... _/ \_/ \_/ \_/ \_ ... _/ \_/ \_
+ * \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
+ *
+ * ACCURATE CLOCK APPROACH:
+ * ______________ LEFT
+ * _| RIGHT |_______________________________|
+ * _ _ _ _ _ _ _ _ _
+ * _| |_ x16 _| |_| |_ x16 _| |_| |_| |_| |_| |_| |
+ * _ _ _ _ dummy cycles
+ * _/ \_ ... _/ \_/ \_ ... _/ \__________________
+ * \_/ \_/ \_/ \_/
+ *
+ */
+ bool i2s_accurate_sck;
+
+ /* McASP specific fields */
+ int tdm_slots;
+ u8 op_mode;
+ u8 num_serializer;
+ u8 *serial_dir;
+ u8 version;
+ u8 txnumevt;
+ u8 rxnumevt;
+};
+
+enum {
+ MCASP_VERSION_1 = 0, /* DM646x */
+ MCASP_VERSION_2, /* DA8xx/OMAPL1x */
+};
+
+enum dm365_clk_input_pin {
+ MCBSP_CLKR = 0, /* DM365 */
+ MCBSP_CLKS,
+};
+
+#define INACTIVE_MODE 0
+#define TX_MODE 1
+#define RX_MODE 2
+
+#define DAVINCI_MCASP_IIS_MODE 0
+#define DAVINCI_MCASP_DIT_MODE 1
+
+#endif /* __ASM_ARCH_DAVINCI_ASP_H */
diff --git a/arch/arm/mach-davinci/include/mach/cdce949.h b/arch/arm/mach-davinci/include/mach/cdce949.h
new file mode 100644
index 00000000..c73331fa
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cdce949.h
@@ -0,0 +1,19 @@
+/*
+ * TI CDCE949 off-chip clock synthesizer support
+ *
+ * 2009 (C) Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+#ifndef _MACH_DAVINCI_CDCE949_H
+#define _MACH_DAVINCI_CDCE949_H
+
+#include <linux/clk.h>
+
+#include <mach/clock.h>
+
+int cdce_set_rate(struct clk *clk, unsigned long rate);
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/clkdev.h b/arch/arm/mach-davinci/include/mach/clkdev.h
new file mode 100644
index 00000000..14a50488
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/clkdev.h
@@ -0,0 +1,15 @@
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+struct clk;
+
+static inline int __clk_get(struct clk *clk)
+{
+ return 1;
+}
+
+static inline void __clk_put(struct clk *clk)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/clock.h b/arch/arm/mach-davinci/include/mach/clock.h
new file mode 100644
index 00000000..a3b04021
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/clock.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-davinci/include/mach/clock.h
+ *
+ * Clock control driver for DaVinci - header file
+ *
+ * Authors: Vladimir Barinov <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.
+ */
+#ifndef __ASM_ARCH_DAVINCI_CLOCK_H
+#define __ASM_ARCH_DAVINCI_CLOCK_H
+
+struct clk;
+
+extern int clk_register(struct clk *clk);
+extern void clk_unregister(struct clk *clk);
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
new file mode 100644
index 00000000..a57cba21
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -0,0 +1,93 @@
+/*
+ * Header for code common to all DaVinci machines.
+ *
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_DAVINCI_COMMON_H
+#define __ARCH_ARM_MACH_DAVINCI_COMMON_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+struct sys_timer;
+
+extern struct sys_timer davinci_timer;
+
+extern void davinci_irq_init(void);
+extern void __iomem *davinci_intc_base;
+extern int davinci_intc_type;
+
+struct davinci_timer_instance {
+ u32 base;
+ u32 bottom_irq;
+ u32 top_irq;
+ unsigned long cmp_off;
+ unsigned int cmp_irq;
+};
+
+struct davinci_timer_info {
+ struct davinci_timer_instance *timers;
+ unsigned int clockevent_id;
+ unsigned int clocksource_id;
+};
+
+struct davinci_gpio_controller;
+
+/*
+ * SoC info passed into common davinci modules.
+ *
+ * Base addresses in this structure should be physical and not virtual.
+ * Modules that take such base addresses, should internally ioremap() them to
+ * use.
+ */
+struct davinci_soc_info {
+ struct map_desc *io_desc;
+ unsigned long io_desc_num;
+ u32 cpu_id;
+ u32 jtag_id;
+ u32 jtag_id_reg;
+ struct davinci_id *ids;
+ unsigned long ids_num;
+ struct clk_lookup *cpu_clks;
+ u32 *psc_bases;
+ unsigned long psc_bases_num;
+ u32 pinmux_base;
+ const struct mux_config *pinmux_pins;
+ unsigned long pinmux_pins_num;
+ u32 intc_base;
+ int intc_type;
+ u8 *intc_irq_prios;
+ unsigned long intc_irq_num;
+ u32 *intc_host_map;
+ struct davinci_timer_info *timer_info;
+ int gpio_type;
+ u32 gpio_base;
+ unsigned gpio_num;
+ unsigned gpio_irq;
+ unsigned gpio_unbanked;
+ struct davinci_gpio_controller *gpio_ctlrs;
+ int gpio_ctlrs_num;
+ struct platform_device *serial_dev;
+ struct emac_platform_data *emac_pdata;
+ dma_addr_t sram_dma;
+ unsigned sram_len;
+ struct platform_device *reset_device;
+ void (*reset)(struct platform_device *);
+};
+
+extern struct davinci_soc_info davinci_soc_info;
+
+extern void davinci_common_init(struct davinci_soc_info *soc_info);
+extern void davinci_init_ide(void);
+
+/* standard place to map on-chip SRAMs; they *may* support DMA */
+#define SRAM_VIRT 0xfffe0000
+#define SRAM_SIZE SZ_128K
+
+#endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */
diff --git a/arch/arm/mach-davinci/include/mach/cp_intc.h b/arch/arm/mach-davinci/include/mach/cp_intc.h
new file mode 100644
index 00000000..4e8190ee
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cp_intc.h
@@ -0,0 +1,56 @@
+/*
+ * TI Common Platform Interrupt Controller (cp_intc) definitions
+ *
+ * Author: Steve Chen <schen@mvista.com>
+ * Copyright (C) 2008-2009, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+#ifndef __ASM_HARDWARE_CP_INTC_H
+#define __ASM_HARDWARE_CP_INTC_H
+
+#define CP_INTC_REV 0x00
+#define CP_INTC_CTRL 0x04
+#define CP_INTC_HOST_CTRL 0x0C
+#define CP_INTC_GLOBAL_ENABLE 0x10
+#define CP_INTC_GLOBAL_NESTING_LEVEL 0x1C
+#define CP_INTC_SYS_STAT_IDX_SET 0x20
+#define CP_INTC_SYS_STAT_IDX_CLR 0x24
+#define CP_INTC_SYS_ENABLE_IDX_SET 0x28
+#define CP_INTC_SYS_ENABLE_IDX_CLR 0x2C
+#define CP_INTC_GLOBAL_WAKEUP_ENABLE 0x30
+#define CP_INTC_HOST_ENABLE_IDX_SET 0x34
+#define CP_INTC_HOST_ENABLE_IDX_CLR 0x38
+#define CP_INTC_PACING_PRESCALE 0x40
+#define CP_INTC_VECTOR_BASE 0x50
+#define CP_INTC_VECTOR_SIZE 0x54
+#define CP_INTC_VECTOR_NULL 0x58
+#define CP_INTC_PRIO_IDX 0x80
+#define CP_INTC_PRIO_VECTOR 0x84
+#define CP_INTC_SECURE_ENABLE 0x90
+#define CP_INTC_SECURE_PRIO_IDX 0x94
+#define CP_INTC_PACING_PARAM(n) (0x0100 + (n << 4))
+#define CP_INTC_PACING_DEC(n) (0x0104 + (n << 4))
+#define CP_INTC_PACING_MAP(n) (0x0108 + (n << 4))
+#define CP_INTC_SYS_RAW_STAT(n) (0x0200 + (n << 2))
+#define CP_INTC_SYS_STAT_CLR(n) (0x0280 + (n << 2))
+#define CP_INTC_SYS_ENABLE_SET(n) (0x0300 + (n << 2))
+#define CP_INTC_SYS_ENABLE_CLR(n) (0x0380 + (n << 2))
+#define CP_INTC_CHAN_MAP(n) (0x0400 + (n << 2))
+#define CP_INTC_HOST_MAP(n) (0x0800 + (n << 2))
+#define CP_INTC_HOST_PRIO_IDX(n) (0x0900 + (n << 2))
+#define CP_INTC_SYS_POLARITY(n) (0x0D00 + (n << 2))
+#define CP_INTC_SYS_TYPE(n) (0x0D80 + (n << 2))
+#define CP_INTC_WAKEUP_ENABLE(n) (0x0E00 + (n << 2))
+#define CP_INTC_DEBUG_SELECT(n) (0x0F00 + (n << 2))
+#define CP_INTC_SYS_SECURE_ENABLE(n) (0x1000 + (n << 2))
+#define CP_INTC_HOST_NESTING_LEVEL(n) (0x1100 + (n << 2))
+#define CP_INTC_HOST_ENABLE(n) (0x1500 + (n << 2))
+#define CP_INTC_HOST_PRIO_VECTOR(n) (0x1600 + (n << 2))
+#define CP_INTC_VECTOR_ADDR(n) (0x2000 + (n << 2))
+
+void __init cp_intc_init(void);
+
+#endif /* __ASM_HARDWARE_CP_INTC_H */
diff --git a/arch/arm/mach-davinci/include/mach/cpufreq.h b/arch/arm/mach-davinci/include/mach/cpufreq.h
new file mode 100644
index 00000000..3c089cfb
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cpufreq.h
@@ -0,0 +1,26 @@
+/*
+ * TI DaVinci CPUFreq platform support.
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc. http://www.ti.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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _MACH_DAVINCI_CPUFREQ_H
+#define _MACH_DAVINCI_CPUFREQ_H
+
+#include <linux/cpufreq.h>
+
+struct davinci_cpufreq_config {
+ struct cpufreq_frequency_table *freq_table;
+ int (*set_voltage) (unsigned int index);
+ int (*init) (void);
+};
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/cpuidle.h b/arch/arm/mach-davinci/include/mach/cpuidle.h
new file mode 100644
index 00000000..74f088b0
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cpuidle.h
@@ -0,0 +1,18 @@
+/*
+ * TI DaVinci cpuidle platform support
+ *
+ * 2009 (C) Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+#ifndef _MACH_DAVINCI_CPUIDLE_H
+#define _MACH_DAVINCI_CPUIDLE_H
+
+struct davinci_cpuidle_config {
+ u32 ddr2_pdown;
+ void __iomem *ddr2_ctlr_base;
+};
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/cputype.h b/arch/arm/mach-davinci/include/mach/cputype.h
new file mode 100644
index 00000000..957fb87e
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cputype.h
@@ -0,0 +1,94 @@
+/*
+ * DaVinci CPU type detection
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * Defines the cpu_is_*() macros for runtime detection of DaVinci
+ * device type. In addition, if support for a given device is not
+ * compiled in to the kernel, the macros return 0 so that
+ * resulting code can be optimized out.
+ *
+ * 2009 (c) Deep Root Systems, LLC. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef _ASM_ARCH_CPU_H
+#define _ASM_ARCH_CPU_H
+
+#include <mach/common.h>
+
+struct davinci_id {
+ u8 variant; /* JTAG ID bits 31:28 */
+ u16 part_no; /* JTAG ID bits 27:12 */
+ u16 manufacturer; /* JTAG ID bits 11:1 */
+ u32 cpu_id;
+ char *name;
+};
+
+/* Can use lower 16 bits of cpu id for a variant when required */
+#define DAVINCI_CPU_ID_DM6446 0x64460000
+#define DAVINCI_CPU_ID_DM6467 0x64670000
+#define DAVINCI_CPU_ID_DM355 0x03550000
+#define DAVINCI_CPU_ID_DM365 0x03650000
+#define DAVINCI_CPU_ID_DA830 0x08300000
+#define DAVINCI_CPU_ID_DA850 0x08500000
+#define DAVINCI_CPU_ID_TNETV107X 0x0b8a0000
+
+#define IS_DAVINCI_CPU(type, id) \
+static inline int is_davinci_ ##type(void) \
+{ \
+ return (davinci_soc_info.cpu_id == (id)); \
+}
+
+IS_DAVINCI_CPU(dm644x, DAVINCI_CPU_ID_DM6446)
+IS_DAVINCI_CPU(dm646x, DAVINCI_CPU_ID_DM6467)
+IS_DAVINCI_CPU(dm355, DAVINCI_CPU_ID_DM355)
+IS_DAVINCI_CPU(dm365, DAVINCI_CPU_ID_DM365)
+IS_DAVINCI_CPU(da830, DAVINCI_CPU_ID_DA830)
+IS_DAVINCI_CPU(da850, DAVINCI_CPU_ID_DA850)
+IS_DAVINCI_CPU(tnetv107x, DAVINCI_CPU_ID_TNETV107X)
+
+#ifdef CONFIG_ARCH_DAVINCI_DM644x
+#define cpu_is_davinci_dm644x() is_davinci_dm644x()
+#else
+#define cpu_is_davinci_dm644x() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DM646x
+#define cpu_is_davinci_dm646x() is_davinci_dm646x()
+#else
+#define cpu_is_davinci_dm646x() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DM355
+#define cpu_is_davinci_dm355() is_davinci_dm355()
+#else
+#define cpu_is_davinci_dm355() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DM365
+#define cpu_is_davinci_dm365() is_davinci_dm365()
+#else
+#define cpu_is_davinci_dm365() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DA830
+#define cpu_is_davinci_da830() is_davinci_da830()
+#else
+#define cpu_is_davinci_da830() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DA850
+#define cpu_is_davinci_da850() is_davinci_da850()
+#else
+#define cpu_is_davinci_da850() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_TNETV107X
+#define cpu_is_davinci_tnetv107x() is_davinci_tnetv107x()
+#else
+#define cpu_is_davinci_tnetv107x() 0
+#endif
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
new file mode 100644
index 00000000..ad64da71
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -0,0 +1,130 @@
+/*
+ * Chip specific defines for DA8XX/OMAP L1XX SoC
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2007, 2009-2010 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_DAVINCI_DA8XX_H
+#define __ASM_ARCH_DAVINCI_DA8XX_H
+
+#include <video/da8xx-fb.h>
+
+#include <linux/platform_device.h>
+#include <linux/davinci_emac.h>
+#include <linux/spi/spi.h>
+
+#include <mach/serial.h>
+#include <mach/edma.h>
+#include <mach/i2c.h>
+#include <mach/asp.h>
+#include <mach/mmc.h>
+#include <mach/usb.h>
+#include <mach/pm.h>
+#include <mach/spi.h>
+
+extern void __iomem *da8xx_syscfg0_base;
+extern void __iomem *da8xx_syscfg1_base;
+
+/*
+ * If the DA850/OMAP-L138/AM18x SoC on board is of a higher speed grade
+ * (than the regular 300Mhz variant), the board code should set this up
+ * with the supported speed before calling da850_register_cpufreq().
+ */
+extern unsigned int da850_max_speed;
+
+/*
+ * The cp_intc interrupt controller for the da8xx isn't in the same
+ * chunk of physical memory space as the other registers (like it is
+ * on the davincis) so it needs to be mapped separately. It will be
+ * mapped early on when the I/O space is mapped and we'll put it just
+ * before the I/O space in the processor's virtual memory space.
+ */
+#define DA8XX_CP_INTC_BASE 0xfffee000
+#define DA8XX_CP_INTC_SIZE SZ_8K
+#define DA8XX_CP_INTC_VIRT (IO_VIRT - DA8XX_CP_INTC_SIZE - SZ_4K)
+
+#define DA8XX_SYSCFG0_BASE (IO_PHYS + 0x14000)
+#define DA8XX_SYSCFG0_VIRT(x) (da8xx_syscfg0_base + (x))
+#define DA8XX_JTAG_ID_REG 0x18
+#define DA8XX_CFGCHIP0_REG 0x17c
+#define DA8XX_CFGCHIP2_REG 0x184
+#define DA8XX_CFGCHIP3_REG 0x188
+
+#define DA8XX_SYSCFG1_BASE (IO_PHYS + 0x22C000)
+#define DA8XX_SYSCFG1_VIRT(x) (da8xx_syscfg1_base + (x))
+#define DA8XX_DEEPSLEEP_REG 0x8
+
+#define DA8XX_PSC0_BASE 0x01c10000
+#define DA8XX_PLL0_BASE 0x01c11000
+#define DA8XX_TIMER64P0_BASE 0x01c20000
+#define DA8XX_TIMER64P1_BASE 0x01c21000
+#define DA8XX_GPIO_BASE 0x01e26000
+#define DA8XX_PSC1_BASE 0x01e27000
+#define DA8XX_AEMIF_CS2_BASE 0x60000000
+#define DA8XX_AEMIF_CS3_BASE 0x62000000
+#define DA8XX_AEMIF_CTL_BASE 0x68000000
+#define DA8XX_ARM_RAM_BASE 0xffff0000
+
+void __init da830_init(void);
+void __init da850_init(void);
+
+int da830_register_edma(struct edma_rsv_info *rsv);
+int da850_register_edma(struct edma_rsv_info *rsv[2]);
+int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata);
+int da8xx_register_spi(int instance, struct spi_board_info *info, unsigned len);
+int da8xx_register_watchdog(void);
+int da8xx_register_usb20(unsigned mA, unsigned potpgt);
+int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
+int da8xx_register_emac(void);
+int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
+int da8xx_register_mmcsd0(struct davinci_mmc_config *config);
+int da850_register_mmcsd1(struct davinci_mmc_config *config);
+void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata);
+int da8xx_register_rtc(void);
+int da850_register_cpufreq(char *async_clk);
+int da8xx_register_cpuidle(void);
+void __iomem * __init da8xx_get_mem_ctlr(void);
+int da850_register_pm(struct platform_device *pdev);
+
+extern struct platform_device da8xx_serial_device;
+extern struct emac_platform_data da8xx_emac_pdata;
+extern struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata;
+extern struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata;
+extern struct davinci_spi_platform_data da8xx_spi_pdata[];
+
+extern struct platform_device da8xx_wdt_device;
+
+extern const short da830_emif25_pins[];
+extern const short da830_spi0_pins[];
+extern const short da830_spi1_pins[];
+extern const short da830_mmc_sd_pins[];
+extern const short da830_uart0_pins[];
+extern const short da830_uart1_pins[];
+extern const short da830_uart2_pins[];
+extern const short da830_usb20_pins[];
+extern const short da830_usb11_pins[];
+extern const short da830_uhpi_pins[];
+extern const short da830_cpgmac_pins[];
+extern const short da830_emif3c_pins[];
+extern const short da830_mcasp0_pins[];
+extern const short da830_mcasp1_pins[];
+extern const short da830_mcasp2_pins[];
+extern const short da830_i2c0_pins[];
+extern const short da830_i2c1_pins[];
+extern const short da830_lcdcntl_pins[];
+extern const short da830_pwm_pins[];
+extern const short da830_ecap0_pins[];
+extern const short da830_ecap1_pins[];
+extern const short da830_ecap2_pins[];
+extern const short da830_eqep0_pins[];
+extern const short da830_eqep1_pins[];
+
+extern const short da850_i2c0_pins[];
+extern const short da850_i2c1_pins[];
+extern const short da850_lcdcntl_pins[];
+
+#endif /* __ASM_ARCH_DAVINCI_DA8XX_H */
diff --git a/arch/arm/mach-davinci/include/mach/debug-macro.S b/arch/arm/mach-davinci/include/mach/debug-macro.S
new file mode 100644
index 00000000..f8b7ea4f
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/debug-macro.S
@@ -0,0 +1,91 @@
+/*
+ * Debugging macro for DaVinci
+ *
+ * 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.
+ */
+
+/* Modifications
+ * Jan 2009 Chaithrika U S Added senduart, busyuart, waituart
+ * macros, based on debug-8250.S file
+ * but using 32-bit accesses required for
+ * some davinci devices.
+ */
+
+#include <linux/serial_reg.h>
+
+#include <asm/memory.h>
+
+#include <mach/serial.h>
+
+#define UART_SHIFT 2
+
+#define davinci_uart_v2p(x) ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET)
+#define davinci_uart_p2v(x) ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET)
+
+ .pushsection .data
+davinci_uart_phys: .word 0
+davinci_uart_virt: .word 0
+ .popsection
+
+ .macro addruart, rp, rv
+
+ /* Use davinci_uart_phys/virt if already configured */
+10: mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+ ldreq \rp, =davinci_uart_v2p(davinci_uart_phys)
+ ldrne \rp, =davinci_uart_phys
+ add \rv, \rp, #4 @ davinci_uart_virt
+ ldr \rp, [\rp, #0]
+ ldr \rv, [\rv, #0]
+ cmp \rp, #0 @ is port configured?
+ cmpne \rv, #0
+ bne 99f @ already configured
+
+ /* Check the debug UART address set in uncompress.h */
+ mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+
+ /* Copy uart phys address from decompressor uart info */
+ ldreq \rv, =davinci_uart_v2p(davinci_uart_phys)
+ ldrne \rv, =davinci_uart_phys
+ ldreq \rp, =DAVINCI_UART_INFO
+ ldrne \rp, =davinci_uart_p2v(DAVINCI_UART_INFO)
+ ldr \rp, [\rp, #0]
+ str \rp, [\rv]
+
+ /* Copy uart virt address from decompressor uart info */
+ ldreq \rv, =davinci_uart_v2p(davinci_uart_virt)
+ ldrne \rv, =davinci_uart_virt
+ ldreq \rp, =DAVINCI_UART_INFO
+ ldrne \rp, =davinci_uart_p2v(DAVINCI_UART_INFO)
+ ldr \rp, [\rp, #4]
+ str \rp, [\rv]
+
+ b 10b
+99:
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #UART_TX << UART_SHIFT]
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldr \rd, [\rx, #UART_LSR << UART_SHIFT]
+ and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
+ teq \rd, #UART_LSR_TEMT | UART_LSR_THRE
+ bne 1002b
+ .endm
+
+ .macro waituart,rd,rx
+#ifdef FLOW_CONTROL
+1001: ldr \rd, [\rx, #UART_MSR << UART_SHIFT]
+ tst \rd, #UART_MSR_CTS
+ beq 1001b
+#endif
+ .endm
+
diff --git a/arch/arm/mach-davinci/include/mach/dm355.h b/arch/arm/mach-davinci/include/mach/dm355.h
new file mode 100644
index 00000000..36dff4a0
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/dm355.h
@@ -0,0 +1,32 @@
+/*
+ * Chip specific defines for DM355 SoC
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_DM355_H
+#define __ASM_ARCH_DM355_H
+
+#include <mach/hardware.h>
+#include <mach/asp.h>
+#include <media/davinci/vpfe_capture.h>
+
+#define DM355_ASYNC_EMIF_CONTROL_BASE 0x01E10000
+#define DM355_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+
+#define ASP1_TX_EVT_EN 1
+#define ASP1_RX_EVT_EN 2
+
+struct spi_board_info;
+
+void __init dm355_init(void);
+void dm355_init_spi0(unsigned chipselect_mask,
+ struct spi_board_info *info, unsigned len);
+void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
+void dm355_set_vpfe_config(struct vpfe_config *cfg);
+
+#endif /* __ASM_ARCH_DM355_H */
diff --git a/arch/arm/mach-davinci/include/mach/dm365.h b/arch/arm/mach-davinci/include/mach/dm365.h
new file mode 100644
index 00000000..2563bf4e
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/dm365.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Incorporated
+ *
+ * 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __ASM_ARCH_DM365_H
+#define __ASM_ARCH_DM665_H
+
+#include <linux/platform_device.h>
+#include <linux/davinci_emac.h>
+#include <mach/hardware.h>
+#include <mach/asp.h>
+#include <mach/keyscan.h>
+#include <media/davinci/vpfe_capture.h>
+
+#define DM365_EMAC_BASE (0x01D07000)
+#define DM365_EMAC_MDIO_BASE (DM365_EMAC_BASE + 0x4000)
+#define DM365_EMAC_CNTRL_OFFSET (0x0000)
+#define DM365_EMAC_CNTRL_MOD_OFFSET (0x3000)
+#define DM365_EMAC_CNTRL_RAM_OFFSET (0x1000)
+#define DM365_EMAC_CNTRL_RAM_SIZE (0x2000)
+
+/* Base of key scan register bank */
+#define DM365_KEYSCAN_BASE (0x01C69400)
+
+#define DM365_RTC_BASE (0x01C69000)
+
+#define DAVINCI_DM365_VC_BASE (0x01D0C000)
+#define DAVINCI_DMA_VC_TX 2
+#define DAVINCI_DMA_VC_RX 3
+
+#define DM365_ASYNC_EMIF_CONTROL_BASE 0x01D10000
+#define DM365_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+#define DM365_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
+
+void __init dm365_init(void);
+void __init dm365_init_asp(struct snd_platform_data *pdata);
+void __init dm365_init_vc(struct snd_platform_data *pdata);
+void __init dm365_init_ks(struct davinci_ks_platform_data *pdata);
+void __init dm365_init_rtc(void);
+void dm365_init_spi0(unsigned chipselect_mask,
+ struct spi_board_info *info, unsigned len);
+
+void dm365_set_vpfe_config(struct vpfe_config *cfg);
+#endif /* __ASM_ARCH_DM365_H */
diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h
new file mode 100644
index 00000000..5a1b26d4
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/dm644x.h
@@ -0,0 +1,47 @@
+/*
+ * This file contains the processor specific definitions
+ * of the TI DM644x.
+ *
+ * Copyright (C) 2008 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef __ASM_ARCH_DM644X_H
+#define __ASM_ARCH_DM644X_H
+
+#include <linux/davinci_emac.h>
+#include <mach/hardware.h>
+#include <mach/asp.h>
+#include <media/davinci/vpfe_capture.h>
+
+#define DM644X_EMAC_BASE (0x01C80000)
+#define DM644X_EMAC_MDIO_BASE (DM644X_EMAC_BASE + 0x4000)
+#define DM644X_EMAC_CNTRL_OFFSET (0x0000)
+#define DM644X_EMAC_CNTRL_MOD_OFFSET (0x1000)
+#define DM644X_EMAC_CNTRL_RAM_OFFSET (0x2000)
+#define DM644X_EMAC_CNTRL_RAM_SIZE (0x2000)
+
+#define DM644X_ASYNC_EMIF_CONTROL_BASE 0x01E00000
+#define DM644X_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+#define DM644X_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
+#define DM644X_ASYNC_EMIF_DATA_CE2_BASE 0x06000000
+#define DM644X_ASYNC_EMIF_DATA_CE3_BASE 0x08000000
+
+void __init dm644x_init(void);
+void __init dm644x_init_asp(struct snd_platform_data *pdata);
+void dm644x_set_vpfe_config(struct vpfe_config *cfg);
+
+#endif /* __ASM_ARCH_DM644X_H */
diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h
new file mode 100644
index 00000000..7a27f3f1
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/dm646x.h
@@ -0,0 +1,94 @@
+/*
+ * Chip specific defines for DM646x SoC
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_DM646X_H
+#define __ASM_ARCH_DM646X_H
+
+#include <mach/hardware.h>
+#include <mach/asp.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/clk.h>
+#include <linux/davinci_emac.h>
+
+#define DM646X_EMAC_BASE (0x01C80000)
+#define DM646X_EMAC_MDIO_BASE (DM646X_EMAC_BASE + 0x4000)
+#define DM646X_EMAC_CNTRL_OFFSET (0x0000)
+#define DM646X_EMAC_CNTRL_MOD_OFFSET (0x1000)
+#define DM646X_EMAC_CNTRL_RAM_OFFSET (0x2000)
+#define DM646X_EMAC_CNTRL_RAM_SIZE (0x2000)
+
+#define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000
+#define DM646X_ASYNC_EMIF_CS2_SPACE_BASE 0x42000000
+
+void __init dm646x_init(void);
+void __init dm646x_init_mcasp0(struct snd_platform_data *pdata);
+void __init dm646x_init_mcasp1(struct snd_platform_data *pdata);
+void __init dm646x_board_setup_refclk(struct clk *clk);
+int __init dm646x_init_edma(struct edma_rsv_info *rsv);
+
+void dm646x_video_init(void);
+
+enum vpif_if_type {
+ VPIF_IF_BT656,
+ VPIF_IF_BT1120,
+ VPIF_IF_RAW_BAYER
+};
+
+struct vpif_interface {
+ enum vpif_if_type if_type;
+ unsigned hd_pol:1;
+ unsigned vd_pol:1;
+ unsigned fid_pol:1;
+};
+
+struct vpif_subdev_info {
+ const char *name;
+ struct i2c_board_info board_info;
+ u32 input;
+ u32 output;
+ unsigned can_route:1;
+ struct vpif_interface vpif_if;
+};
+
+struct vpif_display_config {
+ int (*set_clock)(int, int);
+ struct vpif_subdev_info *subdevinfo;
+ int subdev_count;
+ const char **output;
+ int output_count;
+ const char *card_name;
+};
+
+struct vpif_input {
+ struct v4l2_input input;
+ const char *subdev_name;
+};
+
+#define VPIF_CAPTURE_MAX_CHANNELS 2
+
+struct vpif_capture_chan_config {
+ const struct vpif_input *inputs;
+ int input_count;
+};
+
+struct vpif_capture_config {
+ int (*setup_input_channel_mode)(int);
+ int (*setup_input_path)(int, const char *);
+ struct vpif_capture_chan_config chan_config[VPIF_CAPTURE_MAX_CHANNELS];
+ struct vpif_subdev_info *subdev_info;
+ int subdev_count;
+ const char *card_name;
+};
+
+void dm646x_setup_vpif(struct vpif_display_config *,
+ struct vpif_capture_config *);
+
+#endif /* __ASM_ARCH_DM646X_H */
diff --git a/arch/arm/mach-davinci/include/mach/edma.h b/arch/arm/mach-davinci/include/mach/edma.h
new file mode 100644
index 00000000..20c77f29
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/edma.h
@@ -0,0 +1,262 @@
+/*
+ * TI DAVINCI dma definitions
+ *
+ * Copyright (C) 2006-2009 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * This EDMA3 programming framework exposes two basic kinds of resource:
+ *
+ * Channel Triggers transfers, usually from a hardware event but
+ * also manually or by "chaining" from DMA completions.
+ * Each channel is coupled to a Parameter RAM (PaRAM) slot.
+ *
+ * Slot Each PaRAM slot holds a DMA transfer descriptor (PaRAM
+ * "set"), source and destination addresses, a link to a
+ * next PaRAM slot (if any), options for the transfer, and
+ * instructions for updating those addresses. There are
+ * more than twice as many slots as event channels.
+ *
+ * Each PaRAM set describes a sequence of transfers, either for one large
+ * buffer or for several discontiguous smaller buffers. An EDMA transfer
+ * is driven only from a channel, which performs the transfers specified
+ * in its PaRAM slot until there are no more transfers. When that last
+ * transfer completes, the "link" field may be used to reload the channel's
+ * PaRAM slot with a new transfer descriptor.
+ *
+ * The EDMA Channel Controller (CC) maps requests from channels into physical
+ * Transfer Controller (TC) requests when the channel triggers (by hardware
+ * or software events, or by chaining). The two physical DMA channels provided
+ * by the TCs are thus shared by many logical channels.
+ *
+ * DaVinci hardware also has a "QDMA" mechanism which is not currently
+ * supported through this interface. (DSP firmware uses it though.)
+ */
+
+#ifndef EDMA_H_
+#define EDMA_H_
+
+/* PaRAM slots are laid out like this */
+struct edmacc_param {
+ unsigned int opt;
+ unsigned int src;
+ unsigned int a_b_cnt;
+ unsigned int dst;
+ unsigned int src_dst_bidx;
+ unsigned int link_bcntrld;
+ unsigned int src_dst_cidx;
+ unsigned int ccnt;
+};
+
+#define CCINT0_INTERRUPT 16
+#define CCERRINT_INTERRUPT 17
+#define TCERRINT0_INTERRUPT 18
+#define TCERRINT1_INTERRUPT 19
+
+/* fields in edmacc_param.opt */
+#define SAM BIT(0)
+#define DAM BIT(1)
+#define SYNCDIM BIT(2)
+#define STATIC BIT(3)
+#define EDMA_FWID (0x07 << 8)
+#define TCCMODE BIT(11)
+#define EDMA_TCC(t) ((t) << 12)
+#define TCINTEN BIT(20)
+#define ITCINTEN BIT(21)
+#define TCCHEN BIT(22)
+#define ITCCHEN BIT(23)
+
+#define TRWORD (0x7<<2)
+#define PAENTRY (0x1ff<<5)
+
+/* Drivers should avoid using these symbolic names for dm644x
+ * channels, and use platform_device IORESOURCE_DMA resources
+ * instead. (Other DaVinci chips have different peripherals
+ * and thus have different DMA channel mappings.)
+ */
+#define DAVINCI_DMA_MCBSP_TX 2
+#define DAVINCI_DMA_MCBSP_RX 3
+#define DAVINCI_DMA_VPSS_HIST 4
+#define DAVINCI_DMA_VPSS_H3A 5
+#define DAVINCI_DMA_VPSS_PRVU 6
+#define DAVINCI_DMA_VPSS_RSZ 7
+#define DAVINCI_DMA_IMCOP_IMXINT 8
+#define DAVINCI_DMA_IMCOP_VLCDINT 9
+#define DAVINCI_DMA_IMCO_PASQINT 10
+#define DAVINCI_DMA_IMCOP_DSQINT 11
+#define DAVINCI_DMA_SPI_SPIX 16
+#define DAVINCI_DMA_SPI_SPIR 17
+#define DAVINCI_DMA_UART0_URXEVT0 18
+#define DAVINCI_DMA_UART0_UTXEVT0 19
+#define DAVINCI_DMA_UART1_URXEVT1 20
+#define DAVINCI_DMA_UART1_UTXEVT1 21
+#define DAVINCI_DMA_UART2_URXEVT2 22
+#define DAVINCI_DMA_UART2_UTXEVT2 23
+#define DAVINCI_DMA_MEMSTK_MSEVT 24
+#define DAVINCI_DMA_MMCRXEVT 26
+#define DAVINCI_DMA_MMCTXEVT 27
+#define DAVINCI_DMA_I2C_ICREVT 28
+#define DAVINCI_DMA_I2C_ICXEVT 29
+#define DAVINCI_DMA_GPIO_GPINT0 32
+#define DAVINCI_DMA_GPIO_GPINT1 33
+#define DAVINCI_DMA_GPIO_GPINT2 34
+#define DAVINCI_DMA_GPIO_GPINT3 35
+#define DAVINCI_DMA_GPIO_GPINT4 36
+#define DAVINCI_DMA_GPIO_GPINT5 37
+#define DAVINCI_DMA_GPIO_GPINT6 38
+#define DAVINCI_DMA_GPIO_GPINT7 39
+#define DAVINCI_DMA_GPIO_GPBNKINT0 40
+#define DAVINCI_DMA_GPIO_GPBNKINT1 41
+#define DAVINCI_DMA_GPIO_GPBNKINT2 42
+#define DAVINCI_DMA_GPIO_GPBNKINT3 43
+#define DAVINCI_DMA_GPIO_GPBNKINT4 44
+#define DAVINCI_DMA_TIMER0_TINT0 48
+#define DAVINCI_DMA_TIMER1_TINT1 49
+#define DAVINCI_DMA_TIMER2_TINT2 50
+#define DAVINCI_DMA_TIMER3_TINT3 51
+#define DAVINCI_DMA_PWM0 52
+#define DAVINCI_DMA_PWM1 53
+#define DAVINCI_DMA_PWM2 54
+
+/* DA830 specific EDMA3 information */
+#define EDMA_DA830_NUM_DMACH 32
+#define EDMA_DA830_NUM_TCC 32
+#define EDMA_DA830_NUM_PARAMENTRY 128
+#define EDMA_DA830_NUM_EVQUE 2
+#define EDMA_DA830_NUM_TC 2
+#define EDMA_DA830_CHMAP_EXIST 0
+#define EDMA_DA830_NUM_REGIONS 4
+#define DA830_DMACH2EVENT_MAP0 0x000FC03Fu
+#define DA830_DMACH2EVENT_MAP1 0x00000000u
+#define DA830_EDMA_ARM_OWN 0x30FFCCFFu
+
+/*ch_status paramater of callback function possible values*/
+#define DMA_COMPLETE 1
+#define DMA_CC_ERROR 2
+#define DMA_TC1_ERROR 3
+#define DMA_TC2_ERROR 4
+
+enum address_mode {
+ INCR = 0,
+ FIFO = 1
+};
+
+enum fifo_width {
+ W8BIT = 0,
+ W16BIT = 1,
+ W32BIT = 2,
+ W64BIT = 3,
+ W128BIT = 4,
+ W256BIT = 5
+};
+
+enum dma_event_q {
+ EVENTQ_0 = 0,
+ EVENTQ_1 = 1,
+ EVENTQ_2 = 2,
+ EVENTQ_3 = 3,
+ EVENTQ_DEFAULT = -1
+};
+
+enum sync_dimension {
+ ASYNC = 0,
+ ABSYNC = 1
+};
+
+#define EDMA_CTLR_CHAN(ctlr, chan) (((ctlr) << 16) | (chan))
+#define EDMA_CTLR(i) ((i) >> 16)
+#define EDMA_CHAN_SLOT(i) ((i) & 0xffff)
+
+#define EDMA_CHANNEL_ANY -1 /* for edma_alloc_channel() */
+#define EDMA_SLOT_ANY -1 /* for edma_alloc_slot() */
+#define EDMA_CONT_PARAMS_ANY 1001
+#define EDMA_CONT_PARAMS_FIXED_EXACT 1002
+#define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003
+
+#define EDMA_MAX_CC 2
+
+/* alloc/free DMA channels and their dedicated parameter RAM slots */
+int edma_alloc_channel(int channel,
+ void (*callback)(unsigned channel, u16 ch_status, void *data),
+ void *data, enum dma_event_q);
+void edma_free_channel(unsigned channel);
+
+/* alloc/free parameter RAM slots */
+int edma_alloc_slot(unsigned ctlr, int slot);
+void edma_free_slot(unsigned slot);
+
+/* alloc/free a set of contiguous parameter RAM slots */
+int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count);
+int edma_free_cont_slots(unsigned slot, int count);
+
+/* calls that operate on part of a parameter RAM slot */
+void edma_set_src(unsigned slot, dma_addr_t src_port,
+ enum address_mode mode, enum fifo_width);
+void edma_set_dest(unsigned slot, dma_addr_t dest_port,
+ enum address_mode mode, enum fifo_width);
+void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst);
+void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx);
+void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx);
+void edma_set_transfer_params(unsigned slot, u16 acnt, u16 bcnt, u16 ccnt,
+ u16 bcnt_rld, enum sync_dimension sync_mode);
+void edma_link(unsigned from, unsigned to);
+void edma_unlink(unsigned from);
+
+/* calls that operate on an entire parameter RAM slot */
+void edma_write_slot(unsigned slot, const struct edmacc_param *params);
+void edma_read_slot(unsigned slot, struct edmacc_param *params);
+
+/* channel control operations */
+int edma_start(unsigned channel);
+void edma_stop(unsigned channel);
+void edma_clean_channel(unsigned channel);
+void edma_clear_event(unsigned channel);
+void edma_pause(unsigned channel);
+void edma_resume(unsigned channel);
+
+struct edma_rsv_info {
+
+ const s16 (*rsv_chans)[2];
+ const s16 (*rsv_slots)[2];
+};
+
+/* platform_data for EDMA driver */
+struct edma_soc_info {
+
+ /* how many dma resources of each type */
+ unsigned n_channel;
+ unsigned n_region;
+ unsigned n_slot;
+ unsigned n_tc;
+ unsigned n_cc;
+ enum dma_event_q default_queue;
+
+ /* Resource reservation for other cores */
+ struct edma_rsv_info *rsv;
+
+ const s8 (*queue_tc_mapping)[2];
+ const s8 (*queue_priority_mapping)[2];
+};
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/entry-macro.S b/arch/arm/mach-davinci/include/mach/entry-macro.S
new file mode 100644
index 00000000..fbdebc7c
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/entry-macro.S
@@ -0,0 +1,51 @@
+/*
+ * Low-level IRQ helper macros for TI DaVinci-based platforms
+ *
+ * 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 <mach/io.h>
+#include <mach/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =davinci_intc_base
+ ldr \base, [\base]
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+#if defined(CONFIG_AINTC) && defined(CONFIG_CP_INTC)
+ ldr \tmp, =davinci_intc_type
+ ldr \tmp, [\tmp]
+ cmp \tmp, #DAVINCI_INTC_TYPE_CP_INTC
+ beq 1001f
+#endif
+#if defined(CONFIG_AINTC)
+ ldr \tmp, [\base, #0x14]
+ movs \tmp, \tmp, lsr #2
+ sub \irqnr, \tmp, #1
+ b 1002f
+#endif
+#if defined(CONFIG_CP_INTC)
+1001: ldr \irqnr, [\base, #0x80] /* get irq number */
+ and \irqnr, \irqnr, #0xff /* irq is in bits 0-9 */
+ mov \tmp, \irqnr, lsr #3
+ and \tmp, \tmp, #0xfc
+ add \tmp, \tmp, #0x280 /* get the register offset */
+ ldr \irqstat, [\base, \tmp] /* get the intc status */
+ cmp \irqstat, #0x0
+#endif
+1002:
+ .endm
+
+ .macro irq_prio_table
+ .endm
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h
new file mode 100644
index 00000000..fbece126
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/gpio.h
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+#ifndef __DAVINCI_GPIO_H
+#define __DAVINCI_GPIO_H
+
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm-generic/gpio.h>
+
+#include <mach/irqs.h>
+#include <mach/common.h>
+
+#define DAVINCI_GPIO_BASE 0x01C67000
+
+enum davinci_gpio_type {
+ GPIO_TYPE_DAVINCI = 0,
+ GPIO_TYPE_TNETV107X,
+};
+
+/*
+ * basic gpio routines
+ *
+ * board-specific init should be done by arch/.../.../board-XXX.c (maybe
+ * initializing banks together) rather than boot loaders; kexec() won't
+ * go through boot loaders.
+ *
+ * the gpio clock will be turned on when gpios are used, and you may also
+ * need to pay attention to PINMUX registers to be sure those pins are
+ * used as gpios, not with other peripherals.
+ *
+ * On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1). For documentation,
+ * and maybe for later updates, code may write GPIO(N). These may be
+ * all 1.8V signals, all 3.3V ones, or a mix of the two. A given chip
+ * may not support all the GPIOs in that range.
+ *
+ * GPIOs can also be on external chips, numbered after the ones built-in
+ * to the DaVinci chip. For now, they won't be usable as IRQ sources.
+ */
+#define GPIO(X) (X) /* 0 <= X <= (DAVINCI_N_GPIO - 1) */
+
+/* Convert GPIO signal to GPIO pin number */
+#define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio))
+
+struct davinci_gpio_controller {
+ struct gpio_chip chip;
+ int irq_base;
+ spinlock_t lock;
+ void __iomem *regs;
+ void __iomem *set_data;
+ void __iomem *clr_data;
+ void __iomem *in_data;
+};
+
+/* The __gpio_to_controller() and __gpio_mask() functions inline to constants
+ * with constant parameters; or in outlined code they execute at runtime.
+ *
+ * You'd access the controller directly when reading or writing more than
+ * one gpio value at a time, and to support wired logic where the value
+ * being driven by the cpu need not match the value read back.
+ *
+ * These are NOT part of the cross-platform GPIO interface
+ */
+static inline struct davinci_gpio_controller *
+__gpio_to_controller(unsigned gpio)
+{
+ struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs;
+ int index = gpio / 32;
+
+ if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num)
+ return NULL;
+
+ return ctlrs + index;
+}
+
+static inline u32 __gpio_mask(unsigned gpio)
+{
+ return 1 << (gpio % 32);
+}
+
+/*
+ * The get/set/clear functions will inline when called with constant
+ * parameters referencing built-in GPIOs, for low-overhead bitbanging.
+ *
+ * gpio_set_value() will inline only on traditional Davinci style controllers
+ * with distinct set/clear registers.
+ *
+ * Otherwise, calls with variable parameters or referencing external
+ * GPIOs (e.g. on GPIO expander chips) use outlined functions.
+ */
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ if (__builtin_constant_p(value) && gpio < davinci_soc_info.gpio_num) {
+ struct davinci_gpio_controller *ctlr;
+ u32 mask;
+
+ ctlr = __gpio_to_controller(gpio);
+
+ if (ctlr->set_data != ctlr->clr_data) {
+ mask = __gpio_mask(gpio);
+ if (value)
+ __raw_writel(mask, ctlr->set_data);
+ else
+ __raw_writel(mask, ctlr->clr_data);
+ return;
+ }
+ }
+
+ __gpio_set_value(gpio, value);
+}
+
+/* Returns zero or nonzero; works for gpios configured as inputs OR
+ * as outputs, at least for built-in GPIOs.
+ *
+ * NOTE: for built-in GPIOs, changes in reported values are synchronized
+ * to the GPIO clock. This is easily seen after calling gpio_set_value()
+ * and then immediately gpio_get_value(), where the gpio_get_value() will
+ * return the old value until the GPIO clock ticks and the new value gets
+ * latched.
+ */
+static inline int gpio_get_value(unsigned gpio)
+{
+ struct davinci_gpio_controller *ctlr;
+
+ if (!__builtin_constant_p(gpio) || gpio >= davinci_soc_info.gpio_num)
+ return __gpio_get_value(gpio);
+
+ ctlr = __gpio_to_controller(gpio);
+ return __gpio_mask(gpio) & __raw_readl(ctlr->in_data);
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+ if (__builtin_constant_p(gpio) && gpio < davinci_soc_info.gpio_num)
+ return 0;
+ else
+ return __gpio_cansleep(gpio);
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+ return __gpio_to_irq(gpio);
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+ /* don't support the reverse mapping */
+ return -ENOSYS;
+}
+
+#endif /* __DAVINCI_GPIO_H */
diff --git a/arch/arm/mach-davinci/include/mach/hardware.h b/arch/arm/mach-davinci/include/mach/hardware.h
new file mode 100644
index 00000000..414e0b93
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/hardware.h
@@ -0,0 +1,41 @@
+/*
+ * Hardware definitions common to all DaVinci family processors
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/*
+ * Before you add anything to ths file:
+ *
+ * This header is for defines common to ALL DaVinci family chips.
+ * Anything that is chip specific should go in <chipname>.h,
+ * and the chip/board init code should then explicitly include
+ * <chipname>.h
+ */
+#define DAVINCI_SYSTEM_MODULE_BASE 0x01C40000
+
+/*
+ * I/O mapping
+ */
+#define IO_PHYS 0x01c00000UL
+#define IO_OFFSET 0xfd000000 /* Virtual IO = 0xfec00000 */
+#define IO_SIZE 0x00400000
+#define IO_VIRT (IO_PHYS + IO_OFFSET)
+#define io_v2p(va) ((va) - IO_OFFSET)
+#define __IO_ADDRESS(x) ((x) + IO_OFFSET)
+#define IO_ADDRESS(pa) IOMEM(__IO_ADDRESS(pa))
+
+#ifdef __ASSEMBLER__
+#define IOMEM(x) x
+#else
+#define IOMEM(x) ((void __force __iomem *)(x))
+#endif
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-davinci/include/mach/i2c.h b/arch/arm/mach-davinci/include/mach/i2c.h
new file mode 100644
index 00000000..2312d197
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/i2c.h
@@ -0,0 +1,26 @@
+/*
+ * DaVinci I2C controller platform_device info
+ *
+ * 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.
+*/
+
+#ifndef __ASM_ARCH_I2C_H
+#define __ASM_ARCH_I2C_H
+
+/* All frequencies are expressed in kHz */
+struct davinci_i2c_platform_data {
+ unsigned int bus_freq; /* standard bus frequency (kHz) */
+ unsigned int bus_delay; /* post-transaction delay (usec) */
+ unsigned int sda_pin; /* GPIO pin ID to use for SDA */
+ unsigned int scl_pin; /* GPIO pin ID to use for SCL */
+};
+
+/* for board setup code */
+void davinci_init_i2c(struct davinci_i2c_platform_data *);
+
+#endif /* __ASM_ARCH_I2C_H */
diff --git a/arch/arm/mach-davinci/include/mach/io.h b/arch/arm/mach-davinci/include/mach/io.h
new file mode 100644
index 00000000..d1b95495
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/io.h
@@ -0,0 +1,32 @@
+/*
+ * DaVinci IO address definitions
+ *
+ * Copied from include/asm/arm/arch-omap/io.h
+ *
+ * 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.
+ */
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+#define __mem_isa(a) (a)
+
+#ifndef __ASSEMBLER__
+#define __arch_ioremap davinci_ioremap
+#define __arch_iounmap davinci_iounmap
+
+void __iomem *davinci_ioremap(unsigned long phys, size_t size,
+ unsigned int type);
+void davinci_iounmap(volatile void __iomem *addr);
+#endif
+#endif /* __ASM_ARCH_IO_H */
diff --git a/arch/arm/mach-davinci/include/mach/irqs.h b/arch/arm/mach-davinci/include/mach/irqs.h
new file mode 100644
index 00000000..ec76c777
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/irqs.h
@@ -0,0 +1,506 @@
+/*
+ * DaVinci interrupt controller 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 as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.
+ *
+ */
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+/* Base address */
+#define DAVINCI_ARM_INTC_BASE 0x01C48000
+
+#define DAVINCI_INTC_TYPE_AINTC 0
+#define DAVINCI_INTC_TYPE_CP_INTC 1
+
+/* Interrupt lines */
+#define IRQ_VDINT0 0
+#define IRQ_VDINT1 1
+#define IRQ_VDINT2 2
+#define IRQ_HISTINT 3
+#define IRQ_H3AINT 4
+#define IRQ_PRVUINT 5
+#define IRQ_RSZINT 6
+#define IRQ_VFOCINT 7
+#define IRQ_VENCINT 8
+#define IRQ_ASQINT 9
+#define IRQ_IMXINT 10
+#define IRQ_VLCDINT 11
+#define IRQ_USBINT 12
+#define IRQ_EMACINT 13
+
+#define IRQ_CCINT0 16
+#define IRQ_CCERRINT 17
+#define IRQ_TCERRINT0 18
+#define IRQ_TCERRINT 19
+#define IRQ_PSCIN 20
+
+#define IRQ_IDE 22
+#define IRQ_HPIINT 23
+#define IRQ_MBXINT 24
+#define IRQ_MBRINT 25
+#define IRQ_MMCINT 26
+#define IRQ_SDIOINT 27
+#define IRQ_MSINT 28
+#define IRQ_DDRINT 29
+#define IRQ_AEMIFINT 30
+#define IRQ_VLQINT 31
+#define IRQ_TINT0_TINT12 32
+#define IRQ_TINT0_TINT34 33
+#define IRQ_TINT1_TINT12 34
+#define IRQ_TINT1_TINT34 35
+#define IRQ_PWMINT0 36
+#define IRQ_PWMINT1 37
+#define IRQ_PWMINT2 38
+#define IRQ_I2C 39
+#define IRQ_UARTINT0 40
+#define IRQ_UARTINT1 41
+#define IRQ_UARTINT2 42
+#define IRQ_SPINT0 43
+#define IRQ_SPINT1 44
+
+#define IRQ_DSP2ARM0 46
+#define IRQ_DSP2ARM1 47
+#define IRQ_GPIO0 48
+#define IRQ_GPIO1 49
+#define IRQ_GPIO2 50
+#define IRQ_GPIO3 51
+#define IRQ_GPIO4 52
+#define IRQ_GPIO5 53
+#define IRQ_GPIO6 54
+#define IRQ_GPIO7 55
+#define IRQ_GPIOBNK0 56
+#define IRQ_GPIOBNK1 57
+#define IRQ_GPIOBNK2 58
+#define IRQ_GPIOBNK3 59
+#define IRQ_GPIOBNK4 60
+#define IRQ_COMMTX 61
+#define IRQ_COMMRX 62
+#define IRQ_EMUINT 63
+
+#define DAVINCI_N_AINTC_IRQ 64
+
+#define ARCH_TIMER_IRQ IRQ_TINT1_TINT34
+
+/* DaVinci DM6467-specific Interrupts */
+#define IRQ_DM646X_VP_VERTINT0 0
+#define IRQ_DM646X_VP_VERTINT1 1
+#define IRQ_DM646X_VP_VERTINT2 2
+#define IRQ_DM646X_VP_VERTINT3 3
+#define IRQ_DM646X_VP_ERRINT 4
+#define IRQ_DM646X_RESERVED_1 5
+#define IRQ_DM646X_RESERVED_2 6
+#define IRQ_DM646X_WDINT 7
+#define IRQ_DM646X_CRGENINT0 8
+#define IRQ_DM646X_CRGENINT1 9
+#define IRQ_DM646X_TSIFINT0 10
+#define IRQ_DM646X_TSIFINT1 11
+#define IRQ_DM646X_VDCEINT 12
+#define IRQ_DM646X_USBINT 13
+#define IRQ_DM646X_USBDMAINT 14
+#define IRQ_DM646X_PCIINT 15
+#define IRQ_DM646X_TCERRINT2 20
+#define IRQ_DM646X_TCERRINT3 21
+#define IRQ_DM646X_IDE 22
+#define IRQ_DM646X_HPIINT 23
+#define IRQ_DM646X_EMACRXTHINT 24
+#define IRQ_DM646X_EMACRXINT 25
+#define IRQ_DM646X_EMACTXINT 26
+#define IRQ_DM646X_EMACMISCINT 27
+#define IRQ_DM646X_MCASP0TXINT 28
+#define IRQ_DM646X_MCASP0RXINT 29
+#define IRQ_DM646X_RESERVED_3 31
+#define IRQ_DM646X_MCASP1TXINT 32
+#define IRQ_DM646X_VLQINT 38
+#define IRQ_DM646X_UARTINT2 42
+#define IRQ_DM646X_SPINT0 43
+#define IRQ_DM646X_SPINT1 44
+#define IRQ_DM646X_DSP2ARMINT 45
+#define IRQ_DM646X_RESERVED_4 46
+#define IRQ_DM646X_PSCINT 47
+#define IRQ_DM646X_GPIO0 48
+#define IRQ_DM646X_GPIO1 49
+#define IRQ_DM646X_GPIO2 50
+#define IRQ_DM646X_GPIO3 51
+#define IRQ_DM646X_GPIO4 52
+#define IRQ_DM646X_GPIO5 53
+#define IRQ_DM646X_GPIO6 54
+#define IRQ_DM646X_GPIO7 55
+#define IRQ_DM646X_GPIOBNK0 56
+#define IRQ_DM646X_GPIOBNK1 57
+#define IRQ_DM646X_GPIOBNK2 58
+#define IRQ_DM646X_DDRINT 59
+#define IRQ_DM646X_AEMIFINT 60
+
+/* DaVinci DM355-specific Interrupts */
+#define IRQ_DM355_CCDC_VDINT0 0
+#define IRQ_DM355_CCDC_VDINT1 1
+#define IRQ_DM355_CCDC_VDINT2 2
+#define IRQ_DM355_IPIPE_HST 3
+#define IRQ_DM355_H3AINT 4
+#define IRQ_DM355_IPIPE_SDR 5
+#define IRQ_DM355_IPIPEIFINT 6
+#define IRQ_DM355_OSDINT 7
+#define IRQ_DM355_VENCINT 8
+#define IRQ_DM355_IMCOPINT 11
+#define IRQ_DM355_RTOINT 13
+#define IRQ_DM355_TINT4 13
+#define IRQ_DM355_TINT2_TINT12 13
+#define IRQ_DM355_UARTINT2 14
+#define IRQ_DM355_TINT5 14
+#define IRQ_DM355_TINT2_TINT34 14
+#define IRQ_DM355_TINT6 15
+#define IRQ_DM355_TINT3_TINT12 15
+#define IRQ_DM355_SPINT1_0 17
+#define IRQ_DM355_SPINT1_1 18
+#define IRQ_DM355_SPINT2_0 19
+#define IRQ_DM355_SPINT2_1 21
+#define IRQ_DM355_TINT7 22
+#define IRQ_DM355_TINT3_TINT34 22
+#define IRQ_DM355_SDIOINT0 23
+#define IRQ_DM355_MMCINT0 26
+#define IRQ_DM355_MSINT 26
+#define IRQ_DM355_MMCINT1 27
+#define IRQ_DM355_PWMINT3 28
+#define IRQ_DM355_SDIOINT1 31
+#define IRQ_DM355_SPINT0_0 42
+#define IRQ_DM355_SPINT0_1 43
+#define IRQ_DM355_GPIO0 44
+#define IRQ_DM355_GPIO1 45
+#define IRQ_DM355_GPIO2 46
+#define IRQ_DM355_GPIO3 47
+#define IRQ_DM355_GPIO4 48
+#define IRQ_DM355_GPIO5 49
+#define IRQ_DM355_GPIO6 50
+#define IRQ_DM355_GPIO7 51
+#define IRQ_DM355_GPIO8 52
+#define IRQ_DM355_GPIO9 53
+#define IRQ_DM355_GPIOBNK0 54
+#define IRQ_DM355_GPIOBNK1 55
+#define IRQ_DM355_GPIOBNK2 56
+#define IRQ_DM355_GPIOBNK3 57
+#define IRQ_DM355_GPIOBNK4 58
+#define IRQ_DM355_GPIOBNK5 59
+#define IRQ_DM355_GPIOBNK6 60
+
+/* DaVinci DM365-specific Interrupts */
+#define IRQ_DM365_INSFINT 7
+#define IRQ_DM365_IMXINT1 8
+#define IRQ_DM365_IMXINT0 10
+#define IRQ_DM365_KLD_ARMINT 10
+#define IRQ_DM365_IMCOPINT 11
+#define IRQ_DM365_RTOINT 13
+#define IRQ_DM365_TINT5 14
+#define IRQ_DM365_TINT6 15
+#define IRQ_DM365_SPINT2_1 21
+#define IRQ_DM365_TINT7 22
+#define IRQ_DM365_SDIOINT0 23
+#define IRQ_DM365_MMCINT1 27
+#define IRQ_DM365_PWMINT3 28
+#define IRQ_DM365_RTCINT 29
+#define IRQ_DM365_SDIOINT1 31
+#define IRQ_DM365_SPIINT0_0 42
+#define IRQ_DM365_SPIINT3_0 43
+#define IRQ_DM365_GPIO0 44
+#define IRQ_DM365_GPIO1 45
+#define IRQ_DM365_GPIO2 46
+#define IRQ_DM365_GPIO3 47
+#define IRQ_DM365_GPIO4 48
+#define IRQ_DM365_GPIO5 49
+#define IRQ_DM365_GPIO6 50
+#define IRQ_DM365_GPIO7 51
+#define IRQ_DM365_EMAC_RXTHRESH 52
+#define IRQ_DM365_EMAC_RXPULSE 53
+#define IRQ_DM365_EMAC_TXPULSE 54
+#define IRQ_DM365_EMAC_MISCPULSE 55
+#define IRQ_DM365_GPIO12 56
+#define IRQ_DM365_GPIO13 57
+#define IRQ_DM365_GPIO14 58
+#define IRQ_DM365_GPIO15 59
+#define IRQ_DM365_ADCINT 59
+#define IRQ_DM365_KEYINT 60
+#define IRQ_DM365_TCERRINT2 61
+#define IRQ_DM365_TCERRINT3 62
+#define IRQ_DM365_EMUINT 63
+
+/* DA8XX interrupts */
+#define IRQ_DA8XX_COMMTX 0
+#define IRQ_DA8XX_COMMRX 1
+#define IRQ_DA8XX_NINT 2
+#define IRQ_DA8XX_EVTOUT0 3
+#define IRQ_DA8XX_EVTOUT1 4
+#define IRQ_DA8XX_EVTOUT2 5
+#define IRQ_DA8XX_EVTOUT3 6
+#define IRQ_DA8XX_EVTOUT4 7
+#define IRQ_DA8XX_EVTOUT5 8
+#define IRQ_DA8XX_EVTOUT6 9
+#define IRQ_DA8XX_EVTOUT7 10
+#define IRQ_DA8XX_CCINT0 11
+#define IRQ_DA8XX_CCERRINT 12
+#define IRQ_DA8XX_TCERRINT0 13
+#define IRQ_DA8XX_AEMIFINT 14
+#define IRQ_DA8XX_I2CINT0 15
+#define IRQ_DA8XX_MMCSDINT0 16
+#define IRQ_DA8XX_MMCSDINT1 17
+#define IRQ_DA8XX_ALLINT0 18
+#define IRQ_DA8XX_RTC 19
+#define IRQ_DA8XX_SPINT0 20
+#define IRQ_DA8XX_TINT12_0 21
+#define IRQ_DA8XX_TINT34_0 22
+#define IRQ_DA8XX_TINT12_1 23
+#define IRQ_DA8XX_TINT34_1 24
+#define IRQ_DA8XX_UARTINT0 25
+#define IRQ_DA8XX_KEYMGRINT 26
+#define IRQ_DA8XX_SECINT 26
+#define IRQ_DA8XX_SECKEYERR 26
+#define IRQ_DA8XX_CHIPINT0 28
+#define IRQ_DA8XX_CHIPINT1 29
+#define IRQ_DA8XX_CHIPINT2 30
+#define IRQ_DA8XX_CHIPINT3 31
+#define IRQ_DA8XX_TCERRINT1 32
+#define IRQ_DA8XX_C0_RX_THRESH_PULSE 33
+#define IRQ_DA8XX_C0_RX_PULSE 34
+#define IRQ_DA8XX_C0_TX_PULSE 35
+#define IRQ_DA8XX_C0_MISC_PULSE 36
+#define IRQ_DA8XX_C1_RX_THRESH_PULSE 37
+#define IRQ_DA8XX_C1_RX_PULSE 38
+#define IRQ_DA8XX_C1_TX_PULSE 39
+#define IRQ_DA8XX_C1_MISC_PULSE 40
+#define IRQ_DA8XX_MEMERR 41
+#define IRQ_DA8XX_GPIO0 42
+#define IRQ_DA8XX_GPIO1 43
+#define IRQ_DA8XX_GPIO2 44
+#define IRQ_DA8XX_GPIO3 45
+#define IRQ_DA8XX_GPIO4 46
+#define IRQ_DA8XX_GPIO5 47
+#define IRQ_DA8XX_GPIO6 48
+#define IRQ_DA8XX_GPIO7 49
+#define IRQ_DA8XX_GPIO8 50
+#define IRQ_DA8XX_I2CINT1 51
+#define IRQ_DA8XX_LCDINT 52
+#define IRQ_DA8XX_UARTINT1 53
+#define IRQ_DA8XX_MCASPINT 54
+#define IRQ_DA8XX_ALLINT1 55
+#define IRQ_DA8XX_SPINT1 56
+#define IRQ_DA8XX_UHPI_INT1 57
+#define IRQ_DA8XX_USB_INT 58
+#define IRQ_DA8XX_IRQN 59
+#define IRQ_DA8XX_RWAKEUP 60
+#define IRQ_DA8XX_UARTINT2 61
+#define IRQ_DA8XX_DFTSSINT 62
+#define IRQ_DA8XX_EHRPWM0 63
+#define IRQ_DA8XX_EHRPWM0TZ 64
+#define IRQ_DA8XX_EHRPWM1 65
+#define IRQ_DA8XX_EHRPWM1TZ 66
+#define IRQ_DA8XX_ECAP0 69
+#define IRQ_DA8XX_ECAP1 70
+#define IRQ_DA8XX_ECAP2 71
+#define IRQ_DA8XX_ARMCLKSTOPREQ 90
+
+/* DA830 specific interrupts */
+#define IRQ_DA830_MPUERR 27
+#define IRQ_DA830_IOPUERR 27
+#define IRQ_DA830_BOOTCFGERR 27
+#define IRQ_DA830_EHRPWM2 67
+#define IRQ_DA830_EHRPWM2TZ 68
+#define IRQ_DA830_EQEP0 72
+#define IRQ_DA830_EQEP1 73
+#define IRQ_DA830_T12CMPINT0_0 74
+#define IRQ_DA830_T12CMPINT1_0 75
+#define IRQ_DA830_T12CMPINT2_0 76
+#define IRQ_DA830_T12CMPINT3_0 77
+#define IRQ_DA830_T12CMPINT4_0 78
+#define IRQ_DA830_T12CMPINT5_0 79
+#define IRQ_DA830_T12CMPINT6_0 80
+#define IRQ_DA830_T12CMPINT7_0 81
+#define IRQ_DA830_T12CMPINT0_1 82
+#define IRQ_DA830_T12CMPINT1_1 83
+#define IRQ_DA830_T12CMPINT2_1 84
+#define IRQ_DA830_T12CMPINT3_1 85
+#define IRQ_DA830_T12CMPINT4_1 86
+#define IRQ_DA830_T12CMPINT5_1 87
+#define IRQ_DA830_T12CMPINT6_1 88
+#define IRQ_DA830_T12CMPINT7_1 89
+
+#define DA830_N_CP_INTC_IRQ 96
+
+/* DA850 speicific interrupts */
+#define IRQ_DA850_MPUADDRERR0 27
+#define IRQ_DA850_MPUPROTERR0 27
+#define IRQ_DA850_IOPUADDRERR0 27
+#define IRQ_DA850_IOPUPROTERR0 27
+#define IRQ_DA850_IOPUADDRERR1 27
+#define IRQ_DA850_IOPUPROTERR1 27
+#define IRQ_DA850_IOPUADDRERR2 27
+#define IRQ_DA850_IOPUPROTERR2 27
+#define IRQ_DA850_BOOTCFG_ADDR_ERR 27
+#define IRQ_DA850_BOOTCFG_PROT_ERR 27
+#define IRQ_DA850_MPUADDRERR1 27
+#define IRQ_DA850_MPUPROTERR1 27
+#define IRQ_DA850_IOPUADDRERR3 27
+#define IRQ_DA850_IOPUPROTERR3 27
+#define IRQ_DA850_IOPUADDRERR4 27
+#define IRQ_DA850_IOPUPROTERR4 27
+#define IRQ_DA850_IOPUADDRERR5 27
+#define IRQ_DA850_IOPUPROTERR5 27
+#define IRQ_DA850_MIOPU_BOOTCFG_ERR 27
+#define IRQ_DA850_SATAINT 67
+#define IRQ_DA850_TINT12_2 68
+#define IRQ_DA850_TINT34_2 68
+#define IRQ_DA850_TINTALL_2 68
+#define IRQ_DA850_MMCSDINT0_1 72
+#define IRQ_DA850_MMCSDINT1_1 73
+#define IRQ_DA850_T12CMPINT0_2 74
+#define IRQ_DA850_T12CMPINT1_2 75
+#define IRQ_DA850_T12CMPINT2_2 76
+#define IRQ_DA850_T12CMPINT3_2 77
+#define IRQ_DA850_T12CMPINT4_2 78
+#define IRQ_DA850_T12CMPINT5_2 79
+#define IRQ_DA850_T12CMPINT6_2 80
+#define IRQ_DA850_T12CMPINT7_2 81
+#define IRQ_DA850_T12CMPINT0_3 82
+#define IRQ_DA850_T12CMPINT1_3 83
+#define IRQ_DA850_T12CMPINT2_3 84
+#define IRQ_DA850_T12CMPINT3_3 85
+#define IRQ_DA850_T12CMPINT4_3 86
+#define IRQ_DA850_T12CMPINT5_3 87
+#define IRQ_DA850_T12CMPINT6_3 88
+#define IRQ_DA850_T12CMPINT7_3 89
+#define IRQ_DA850_RPIINT 91
+#define IRQ_DA850_VPIFINT 92
+#define IRQ_DA850_CCINT1 93
+#define IRQ_DA850_CCERRINT1 94
+#define IRQ_DA850_TCERRINT2 95
+#define IRQ_DA850_TINT12_3 96
+#define IRQ_DA850_TINT34_3 96
+#define IRQ_DA850_TINTALL_3 96
+#define IRQ_DA850_MCBSP0RINT 97
+#define IRQ_DA850_MCBSP0XINT 98
+#define IRQ_DA850_MCBSP1RINT 99
+#define IRQ_DA850_MCBSP1XINT 100
+
+#define DA850_N_CP_INTC_IRQ 101
+
+
+/* TNETV107X specific interrupts */
+#define IRQ_TNETV107X_TDM1_TXDMA 0
+#define IRQ_TNETV107X_EXT_INT_0 1
+#define IRQ_TNETV107X_EXT_INT_1 2
+#define IRQ_TNETV107X_GPIO_INT12 3
+#define IRQ_TNETV107X_GPIO_INT13 4
+#define IRQ_TNETV107X_TIMER_0_TINT12 5
+#define IRQ_TNETV107X_TIMER_1_TINT12 6
+#define IRQ_TNETV107X_UART0 7
+#define IRQ_TNETV107X_TDM1_RXDMA 8
+#define IRQ_TNETV107X_MCDMA_INT0 9
+#define IRQ_TNETV107X_MCDMA_INT1 10
+#define IRQ_TNETV107X_TPCC 11
+#define IRQ_TNETV107X_TPCC_INT0 12
+#define IRQ_TNETV107X_TPCC_INT1 13
+#define IRQ_TNETV107X_TPCC_INT2 14
+#define IRQ_TNETV107X_TPCC_INT3 15
+#define IRQ_TNETV107X_TPTC0 16
+#define IRQ_TNETV107X_TPTC1 17
+#define IRQ_TNETV107X_TIMER_0_TINT34 18
+#define IRQ_TNETV107X_ETHSS 19
+#define IRQ_TNETV107X_TIMER_1_TINT34 20
+#define IRQ_TNETV107X_DSP2ARM_INT0 21
+#define IRQ_TNETV107X_DSP2ARM_INT1 22
+#define IRQ_TNETV107X_ARM_NPMUIRQ 23
+#define IRQ_TNETV107X_USB1 24
+#define IRQ_TNETV107X_VLYNQ 25
+#define IRQ_TNETV107X_UART0_DMATX 26
+#define IRQ_TNETV107X_UART0_DMARX 27
+#define IRQ_TNETV107X_TDM1_TXMCSP 28
+#define IRQ_TNETV107X_SSP 29
+#define IRQ_TNETV107X_MCDMA_INT2 30
+#define IRQ_TNETV107X_MCDMA_INT3 31
+#define IRQ_TNETV107X_TDM_CODECIF_EOT 32
+#define IRQ_TNETV107X_IMCOP_SQR_ARM 33
+#define IRQ_TNETV107X_USB0 34
+#define IRQ_TNETV107X_USB_CDMA 35
+#define IRQ_TNETV107X_LCD 36
+#define IRQ_TNETV107X_KEYPAD 37
+#define IRQ_TNETV107X_KEYPAD_FREE 38
+#define IRQ_TNETV107X_RNG 39
+#define IRQ_TNETV107X_PKA 40
+#define IRQ_TNETV107X_TDM0_TXDMA 41
+#define IRQ_TNETV107X_TDM0_RXDMA 42
+#define IRQ_TNETV107X_TDM0_TXMCSP 43
+#define IRQ_TNETV107X_TDM0_RXMCSP 44
+#define IRQ_TNETV107X_TDM1_RXMCSP 45
+#define IRQ_TNETV107X_SDIO1 46
+#define IRQ_TNETV107X_SDIO0 47
+#define IRQ_TNETV107X_TSC 48
+#define IRQ_TNETV107X_TS 49
+#define IRQ_TNETV107X_UART1 50
+#define IRQ_TNETV107X_MBX_LITE 51
+#define IRQ_TNETV107X_GPIO_INT00 52
+#define IRQ_TNETV107X_GPIO_INT01 53
+#define IRQ_TNETV107X_GPIO_INT02 54
+#define IRQ_TNETV107X_GPIO_INT03 55
+#define IRQ_TNETV107X_UART2 56
+#define IRQ_TNETV107X_UART2_DMATX 57
+#define IRQ_TNETV107X_UART2_DMARX 58
+#define IRQ_TNETV107X_IMCOP_IMX 59
+#define IRQ_TNETV107X_IMCOP_VLCD 60
+#define IRQ_TNETV107X_AES 61
+#define IRQ_TNETV107X_DES 62
+#define IRQ_TNETV107X_SHAMD5 63
+#define IRQ_TNETV107X_TPCC_ERR 68
+#define IRQ_TNETV107X_TPCC_PROT 69
+#define IRQ_TNETV107X_TPTC0_ERR 70
+#define IRQ_TNETV107X_TPTC1_ERR 71
+#define IRQ_TNETV107X_UART0_ERR 72
+#define IRQ_TNETV107X_UART1_ERR 73
+#define IRQ_TNETV107X_AEMIF_ERR 74
+#define IRQ_TNETV107X_DDR_ERR 75
+#define IRQ_TNETV107X_WDTARM_INT0 76
+#define IRQ_TNETV107X_MCDMA_ERR 77
+#define IRQ_TNETV107X_GPIO_ERR 78
+#define IRQ_TNETV107X_MPU_ADDR 79
+#define IRQ_TNETV107X_MPU_PROT 80
+#define IRQ_TNETV107X_IOPU_ADDR 81
+#define IRQ_TNETV107X_IOPU_PROT 82
+#define IRQ_TNETV107X_KEYPAD_ADDR_ERR 83
+#define IRQ_TNETV107X_WDT0_ADDR_ERR 84
+#define IRQ_TNETV107X_WDT1_ADDR_ERR 85
+#define IRQ_TNETV107X_CLKCTL_ADDR_ERR 86
+#define IRQ_TNETV107X_PLL_UNLOCK 87
+#define IRQ_TNETV107X_WDTDSP_INT0 88
+#define IRQ_TNETV107X_SEC_CTRL_VIOLATION 89
+#define IRQ_TNETV107X_KEY_MNG_VIOLATION 90
+#define IRQ_TNETV107X_PBIST_CPU 91
+#define IRQ_TNETV107X_WDTARM 92
+#define IRQ_TNETV107X_PSC 93
+#define IRQ_TNETV107X_MMC0 94
+#define IRQ_TNETV107X_MMC1 95
+
+#define TNETV107X_N_CP_INTC_IRQ 96
+
+/* da850 currently has the most gpio pins (144) */
+#define DAVINCI_N_GPIO 144
+/* da850 currently has the most irqs so use DA850_N_CP_INTC_IRQ */
+#define NR_IRQS (DA850_N_CP_INTC_IRQ + DAVINCI_N_GPIO)
+
+#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-davinci/include/mach/keyscan.h b/arch/arm/mach-davinci/include/mach/keyscan.h
new file mode 100644
index 00000000..7a560e05
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/keyscan.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 Texas Instruments, Inc
+ *
+ * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DAVINCI_KEYSCAN_H
+#define DAVINCI_KEYSCAN_H
+
+#include <linux/io.h>
+
+enum davinci_matrix_types {
+ DAVINCI_KEYSCAN_MATRIX_4X4,
+ DAVINCI_KEYSCAN_MATRIX_5X3,
+};
+
+struct davinci_ks_platform_data {
+ int (*device_enable)(struct device *dev);
+ unsigned short *keymap;
+ u32 keymapsize;
+ u8 rep:1;
+ u8 strobe;
+ u8 interval;
+ u8 matrix_type;
+};
+
+#endif
+
diff --git a/arch/arm/mach-davinci/include/mach/memory.h b/arch/arm/mach-davinci/include/mach/memory.h
new file mode 100644
index 00000000..491249ef
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/memory.h
@@ -0,0 +1,51 @@
+/*
+ * DaVinci memory space definitions
+ *
+ * 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.
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/**************************************************************************
+ * Included Files
+ **************************************************************************/
+#include <asm/page.h>
+#include <asm/sizes.h>
+
+/**************************************************************************
+ * Definitions
+ **************************************************************************/
+#define DAVINCI_DDR_BASE 0x80000000
+#define DA8XX_DDR_BASE 0xc0000000
+
+#if defined(CONFIG_ARCH_DAVINCI_DA8XX) && defined(CONFIG_ARCH_DAVINCI_DMx)
+#error Cannot enable DaVinci and DA8XX platforms concurrently
+#elif defined(CONFIG_ARCH_DAVINCI_DA8XX)
+#define PLAT_PHYS_OFFSET DA8XX_DDR_BASE
+#else
+#define PLAT_PHYS_OFFSET DAVINCI_DDR_BASE
+#endif
+
+#define DDR2_SDRCR_OFFSET 0xc
+#define DDR2_SRPD_BIT BIT(23)
+#define DDR2_MCLKSTOPEN_BIT BIT(30)
+#define DDR2_LPMODEN_BIT BIT(31)
+
+/*
+ * Increase size of DMA-consistent memory region
+ */
+#define CONSISTENT_DMA_SIZE (14<<20)
+
+/*
+ * Restrict DMA-able region to workaround silicon bug. The bug
+ * restricts buffers available for DMA to video hardware to be
+ * below 128M
+ */
+#define ARM_DMA_ZONE_SIZE SZ_128M
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-davinci/include/mach/mmc.h b/arch/arm/mach-davinci/include/mach/mmc.h
new file mode 100644
index 00000000..d4f1e967
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/mmc.h
@@ -0,0 +1,36 @@
+/*
+ * Board-specific MMC configuration
+ */
+
+#ifndef _DAVINCI_MMC_H
+#define _DAVINCI_MMC_H
+
+#include <linux/types.h>
+#include <linux/mmc/host.h>
+
+struct davinci_mmc_config {
+ /* get_cd()/get_wp() may sleep */
+ int (*get_cd)(int module);
+ int (*get_ro)(int module);
+ /* wires == 0 is equivalent to wires == 4 (4-bit parallel) */
+ u8 wires;
+
+ u32 max_freq;
+
+ /* any additional host capabilities: OR'd in to mmc->f_caps */
+ u32 caps;
+
+ /* Version of the MMC/SD controller */
+ u8 version;
+
+ /* Number of sg segments */
+ u8 nr_sg;
+};
+void davinci_setup_mmc(int module, struct davinci_mmc_config *config);
+
+enum {
+ MMC_CTLR_VERSION_1 = 0, /* DM644x and DM355 */
+ MMC_CTLR_VERSION_2, /* DA830 */
+};
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h
new file mode 100644
index 00000000..5d4e0fed
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/mux.h
@@ -0,0 +1,1207 @@
+/*
+ * Table of the DAVINCI register configurations for the PINMUX combinations
+ *
+ * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * Based on linux/include/asm-arm/arch-omap/mux.h:
+ * Copyright (C) 2003 - 2005 Nokia Corporation
+ *
+ * Written by Tony Lindgren
+ *
+ * 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.
+ *
+ * Copyright (C) 2008 Texas Instruments.
+ */
+
+#ifndef __INC_MACH_MUX_H
+#define __INC_MACH_MUX_H
+
+struct mux_config {
+ const char *name;
+ const char *mux_reg_name;
+ const unsigned char mux_reg;
+ const unsigned char mask_offset;
+ const unsigned char mask;
+ const unsigned char mode;
+ bool debug;
+};
+
+enum davinci_dm644x_index {
+ /* ATA and HDDIR functions */
+ DM644X_HDIREN,
+ DM644X_ATAEN,
+ DM644X_ATAEN_DISABLE,
+
+ /* HPI functions */
+ DM644X_HPIEN_DISABLE,
+
+ /* AEAW functions */
+ DM644X_AEAW,
+ DM644X_AEAW0,
+ DM644X_AEAW1,
+ DM644X_AEAW2,
+ DM644X_AEAW3,
+ DM644X_AEAW4,
+
+ /* Memory Stick */
+ DM644X_MSTK,
+
+ /* I2C */
+ DM644X_I2C,
+
+ /* ASP function */
+ DM644X_MCBSP,
+
+ /* UART1 */
+ DM644X_UART1,
+
+ /* UART2 */
+ DM644X_UART2,
+
+ /* PWM0 */
+ DM644X_PWM0,
+
+ /* PWM1 */
+ DM644X_PWM1,
+
+ /* PWM2 */
+ DM644X_PWM2,
+
+ /* VLYNQ function */
+ DM644X_VLYNQEN,
+ DM644X_VLSCREN,
+ DM644X_VLYNQWD,
+
+ /* EMAC and MDIO function */
+ DM644X_EMACEN,
+
+ /* GPIO3V[0:16] pins */
+ DM644X_GPIO3V,
+
+ /* GPIO pins */
+ DM644X_GPIO0,
+ DM644X_GPIO3,
+ DM644X_GPIO43_44,
+ DM644X_GPIO46_47,
+
+ /* VPBE */
+ DM644X_RGB666,
+
+ /* LCD */
+ DM644X_LOEEN,
+ DM644X_LFLDEN,
+};
+
+enum davinci_dm646x_index {
+ /* ATA function */
+ DM646X_ATAEN,
+
+ /* AUDIO Clock */
+ DM646X_AUDCK1,
+ DM646X_AUDCK0,
+
+ /* CRGEN Control */
+ DM646X_CRGMUX,
+
+ /* VPIF Control */
+ DM646X_STSOMUX_DISABLE,
+ DM646X_STSIMUX_DISABLE,
+ DM646X_PTSOMUX_DISABLE,
+ DM646X_PTSIMUX_DISABLE,
+
+ /* TSIF Control */
+ DM646X_STSOMUX,
+ DM646X_STSIMUX,
+ DM646X_PTSOMUX_PARALLEL,
+ DM646X_PTSIMUX_PARALLEL,
+ DM646X_PTSOMUX_SERIAL,
+ DM646X_PTSIMUX_SERIAL,
+};
+
+enum davinci_dm355_index {
+ /* MMC/SD 0 */
+ DM355_MMCSD0,
+
+ /* MMC/SD 1 */
+ DM355_SD1_CLK,
+ DM355_SD1_CMD,
+ DM355_SD1_DATA3,
+ DM355_SD1_DATA2,
+ DM355_SD1_DATA1,
+ DM355_SD1_DATA0,
+
+ /* I2C */
+ DM355_I2C_SDA,
+ DM355_I2C_SCL,
+
+ /* ASP0 function */
+ DM355_MCBSP0_BDX,
+ DM355_MCBSP0_X,
+ DM355_MCBSP0_BFSX,
+ DM355_MCBSP0_BDR,
+ DM355_MCBSP0_R,
+ DM355_MCBSP0_BFSR,
+
+ /* SPI0 */
+ DM355_SPI0_SDI,
+ DM355_SPI0_SDENA0,
+ DM355_SPI0_SDENA1,
+
+ /* IRQ muxing */
+ DM355_INT_EDMA_CC,
+ DM355_INT_EDMA_TC0_ERR,
+ DM355_INT_EDMA_TC1_ERR,
+
+ /* EDMA event muxing */
+ DM355_EVT8_ASP1_TX,
+ DM355_EVT9_ASP1_RX,
+ DM355_EVT26_MMC0_RX,
+
+ /* Video Out */
+ DM355_VOUT_FIELD,
+ DM355_VOUT_FIELD_G70,
+ DM355_VOUT_HVSYNC,
+ DM355_VOUT_COUTL_EN,
+ DM355_VOUT_COUTH_EN,
+
+ /* Video In Pin Mux */
+ DM355_VIN_PCLK,
+ DM355_VIN_CAM_WEN,
+ DM355_VIN_CAM_VD,
+ DM355_VIN_CAM_HD,
+ DM355_VIN_YIN_EN,
+ DM355_VIN_CINL_EN,
+ DM355_VIN_CINH_EN,
+};
+
+enum davinci_dm365_index {
+ /* MMC/SD 0 */
+ DM365_MMCSD0,
+
+ /* MMC/SD 1 */
+ DM365_SD1_CLK,
+ DM365_SD1_CMD,
+ DM365_SD1_DATA3,
+ DM365_SD1_DATA2,
+ DM365_SD1_DATA1,
+ DM365_SD1_DATA0,
+
+ /* I2C */
+ DM365_I2C_SDA,
+ DM365_I2C_SCL,
+
+ /* AEMIF */
+ DM365_AEMIF_AR_A14,
+ DM365_AEMIF_AR_BA0,
+ DM365_AEMIF_A3,
+ DM365_AEMIF_A7,
+ DM365_AEMIF_D15_8,
+ DM365_AEMIF_CE0,
+ DM365_AEMIF_CE1,
+ DM365_AEMIF_WE_OE,
+
+ /* ASP0 function */
+ DM365_MCBSP0_BDX,
+ DM365_MCBSP0_X,
+ DM365_MCBSP0_BFSX,
+ DM365_MCBSP0_BDR,
+ DM365_MCBSP0_R,
+ DM365_MCBSP0_BFSR,
+
+ /* SPI0 */
+ DM365_SPI0_SCLK,
+ DM365_SPI0_SDI,
+ DM365_SPI0_SDO,
+ DM365_SPI0_SDENA0,
+ DM365_SPI0_SDENA1,
+
+ /* UART */
+ DM365_UART0_RXD,
+ DM365_UART0_TXD,
+ DM365_UART1_RXD,
+ DM365_UART1_TXD,
+ DM365_UART1_RTS,
+ DM365_UART1_CTS,
+
+ /* EMAC */
+ DM365_EMAC_TX_EN,
+ DM365_EMAC_TX_CLK,
+ DM365_EMAC_COL,
+ DM365_EMAC_TXD3,
+ DM365_EMAC_TXD2,
+ DM365_EMAC_TXD1,
+ DM365_EMAC_TXD0,
+ DM365_EMAC_RXD3,
+ DM365_EMAC_RXD2,
+ DM365_EMAC_RXD1,
+ DM365_EMAC_RXD0,
+ DM365_EMAC_RX_CLK,
+ DM365_EMAC_RX_DV,
+ DM365_EMAC_RX_ER,
+ DM365_EMAC_CRS,
+ DM365_EMAC_MDIO,
+ DM365_EMAC_MDCLK,
+
+ /* Key Scan */
+ DM365_KEYSCAN,
+
+ /* PWM */
+ DM365_PWM0,
+ DM365_PWM0_G23,
+ DM365_PWM1,
+ DM365_PWM1_G25,
+ DM365_PWM2_G87,
+ DM365_PWM2_G88,
+ DM365_PWM2_G89,
+ DM365_PWM2_G90,
+ DM365_PWM3_G80,
+ DM365_PWM3_G81,
+ DM365_PWM3_G85,
+ DM365_PWM3_G86,
+
+ /* SPI1 */
+ DM365_SPI1_SCLK,
+ DM365_SPI1_SDO,
+ DM365_SPI1_SDI,
+ DM365_SPI1_SDENA0,
+ DM365_SPI1_SDENA1,
+
+ /* SPI2 */
+ DM365_SPI2_SCLK,
+ DM365_SPI2_SDO,
+ DM365_SPI2_SDI,
+ DM365_SPI2_SDENA0,
+ DM365_SPI2_SDENA1,
+
+ /* SPI3 */
+ DM365_SPI3_SCLK,
+ DM365_SPI3_SDO,
+ DM365_SPI3_SDI,
+ DM365_SPI3_SDENA0,
+ DM365_SPI3_SDENA1,
+
+ /* SPI4 */
+ DM365_SPI4_SCLK,
+ DM365_SPI4_SDO,
+ DM365_SPI4_SDI,
+ DM365_SPI4_SDENA0,
+ DM365_SPI4_SDENA1,
+
+ /* Clock */
+ DM365_CLKOUT0,
+ DM365_CLKOUT1,
+ DM365_CLKOUT2,
+
+ /* GPIO */
+ DM365_GPIO20,
+ DM365_GPIO30,
+ DM365_GPIO31,
+ DM365_GPIO32,
+ DM365_GPIO33,
+ DM365_GPIO40,
+ DM365_GPIO64_57,
+
+ /* Video */
+ DM365_VOUT_FIELD,
+ DM365_VOUT_FIELD_G81,
+ DM365_VOUT_HVSYNC,
+ DM365_VOUT_COUTL_EN,
+ DM365_VOUT_COUTH_EN,
+ DM365_VIN_CAM_WEN,
+ DM365_VIN_CAM_VD,
+ DM365_VIN_CAM_HD,
+ DM365_VIN_YIN4_7_EN,
+ DM365_VIN_YIN0_3_EN,
+
+ /* IRQ muxing */
+ DM365_INT_EDMA_CC,
+ DM365_INT_EDMA_TC0_ERR,
+ DM365_INT_EDMA_TC1_ERR,
+ DM365_INT_EDMA_TC2_ERR,
+ DM365_INT_EDMA_TC3_ERR,
+ DM365_INT_PRTCSS,
+ DM365_INT_EMAC_RXTHRESH,
+ DM365_INT_EMAC_RXPULSE,
+ DM365_INT_EMAC_TXPULSE,
+ DM365_INT_EMAC_MISCPULSE,
+ DM365_INT_IMX0_ENABLE,
+ DM365_INT_IMX0_DISABLE,
+ DM365_INT_HDVICP_ENABLE,
+ DM365_INT_HDVICP_DISABLE,
+ DM365_INT_IMX1_ENABLE,
+ DM365_INT_IMX1_DISABLE,
+ DM365_INT_NSF_ENABLE,
+ DM365_INT_NSF_DISABLE,
+
+ /* EDMA event muxing */
+ DM365_EVT2_ASP_TX,
+ DM365_EVT3_ASP_RX,
+ DM365_EVT2_VC_TX,
+ DM365_EVT3_VC_RX,
+ DM365_EVT26_MMC0_RX,
+};
+
+enum da830_index {
+ DA830_GPIO7_14,
+ DA830_RTCK,
+ DA830_GPIO7_15,
+ DA830_EMU_0,
+ DA830_EMB_SDCKE,
+ DA830_EMB_CLK_GLUE,
+ DA830_EMB_CLK,
+ DA830_NEMB_CS_0,
+ DA830_NEMB_CAS,
+ DA830_NEMB_RAS,
+ DA830_NEMB_WE,
+ DA830_EMB_BA_1,
+ DA830_EMB_BA_0,
+ DA830_EMB_A_0,
+ DA830_EMB_A_1,
+ DA830_EMB_A_2,
+ DA830_EMB_A_3,
+ DA830_EMB_A_4,
+ DA830_EMB_A_5,
+ DA830_GPIO7_0,
+ DA830_GPIO7_1,
+ DA830_GPIO7_2,
+ DA830_GPIO7_3,
+ DA830_GPIO7_4,
+ DA830_GPIO7_5,
+ DA830_GPIO7_6,
+ DA830_GPIO7_7,
+ DA830_EMB_A_6,
+ DA830_EMB_A_7,
+ DA830_EMB_A_8,
+ DA830_EMB_A_9,
+ DA830_EMB_A_10,
+ DA830_EMB_A_11,
+ DA830_EMB_A_12,
+ DA830_EMB_D_31,
+ DA830_GPIO7_8,
+ DA830_GPIO7_9,
+ DA830_GPIO7_10,
+ DA830_GPIO7_11,
+ DA830_GPIO7_12,
+ DA830_GPIO7_13,
+ DA830_GPIO3_13,
+ DA830_EMB_D_30,
+ DA830_EMB_D_29,
+ DA830_EMB_D_28,
+ DA830_EMB_D_27,
+ DA830_EMB_D_26,
+ DA830_EMB_D_25,
+ DA830_EMB_D_24,
+ DA830_EMB_D_23,
+ DA830_EMB_D_22,
+ DA830_EMB_D_21,
+ DA830_EMB_D_20,
+ DA830_EMB_D_19,
+ DA830_EMB_D_18,
+ DA830_EMB_D_17,
+ DA830_EMB_D_16,
+ DA830_NEMB_WE_DQM_3,
+ DA830_NEMB_WE_DQM_2,
+ DA830_EMB_D_0,
+ DA830_EMB_D_1,
+ DA830_EMB_D_2,
+ DA830_EMB_D_3,
+ DA830_EMB_D_4,
+ DA830_EMB_D_5,
+ DA830_EMB_D_6,
+ DA830_GPIO6_0,
+ DA830_GPIO6_1,
+ DA830_GPIO6_2,
+ DA830_GPIO6_3,
+ DA830_GPIO6_4,
+ DA830_GPIO6_5,
+ DA830_GPIO6_6,
+ DA830_EMB_D_7,
+ DA830_EMB_D_8,
+ DA830_EMB_D_9,
+ DA830_EMB_D_10,
+ DA830_EMB_D_11,
+ DA830_EMB_D_12,
+ DA830_EMB_D_13,
+ DA830_EMB_D_14,
+ DA830_GPIO6_7,
+ DA830_GPIO6_8,
+ DA830_GPIO6_9,
+ DA830_GPIO6_10,
+ DA830_GPIO6_11,
+ DA830_GPIO6_12,
+ DA830_GPIO6_13,
+ DA830_GPIO6_14,
+ DA830_EMB_D_15,
+ DA830_NEMB_WE_DQM_1,
+ DA830_NEMB_WE_DQM_0,
+ DA830_SPI0_SOMI_0,
+ DA830_SPI0_SIMO_0,
+ DA830_SPI0_CLK,
+ DA830_NSPI0_ENA,
+ DA830_NSPI0_SCS_0,
+ DA830_EQEP0I,
+ DA830_EQEP0S,
+ DA830_EQEP1I,
+ DA830_NUART0_CTS,
+ DA830_NUART0_RTS,
+ DA830_EQEP0A,
+ DA830_EQEP0B,
+ DA830_GPIO6_15,
+ DA830_GPIO5_14,
+ DA830_GPIO5_15,
+ DA830_GPIO5_0,
+ DA830_GPIO5_1,
+ DA830_GPIO5_2,
+ DA830_GPIO5_3,
+ DA830_GPIO5_4,
+ DA830_SPI1_SOMI_0,
+ DA830_SPI1_SIMO_0,
+ DA830_SPI1_CLK,
+ DA830_UART0_RXD,
+ DA830_UART0_TXD,
+ DA830_AXR1_10,
+ DA830_AXR1_11,
+ DA830_NSPI1_ENA,
+ DA830_I2C1_SCL,
+ DA830_I2C1_SDA,
+ DA830_EQEP1S,
+ DA830_I2C0_SDA,
+ DA830_I2C0_SCL,
+ DA830_UART2_RXD,
+ DA830_TM64P0_IN12,
+ DA830_TM64P0_OUT12,
+ DA830_GPIO5_5,
+ DA830_GPIO5_6,
+ DA830_GPIO5_7,
+ DA830_GPIO5_8,
+ DA830_GPIO5_9,
+ DA830_GPIO5_10,
+ DA830_GPIO5_11,
+ DA830_GPIO5_12,
+ DA830_NSPI1_SCS_0,
+ DA830_USB0_DRVVBUS,
+ DA830_AHCLKX0,
+ DA830_ACLKX0,
+ DA830_AFSX0,
+ DA830_AHCLKR0,
+ DA830_ACLKR0,
+ DA830_AFSR0,
+ DA830_UART2_TXD,
+ DA830_AHCLKX2,
+ DA830_ECAP0_APWM0,
+ DA830_RMII_MHZ_50_CLK,
+ DA830_ECAP1_APWM1,
+ DA830_USB_REFCLKIN,
+ DA830_GPIO5_13,
+ DA830_GPIO4_15,
+ DA830_GPIO2_11,
+ DA830_GPIO2_12,
+ DA830_GPIO2_13,
+ DA830_GPIO2_14,
+ DA830_GPIO2_15,
+ DA830_GPIO3_12,
+ DA830_AMUTE0,
+ DA830_AXR0_0,
+ DA830_AXR0_1,
+ DA830_AXR0_2,
+ DA830_AXR0_3,
+ DA830_AXR0_4,
+ DA830_AXR0_5,
+ DA830_AXR0_6,
+ DA830_RMII_TXD_0,
+ DA830_RMII_TXD_1,
+ DA830_RMII_TXEN,
+ DA830_RMII_CRS_DV,
+ DA830_RMII_RXD_0,
+ DA830_RMII_RXD_1,
+ DA830_RMII_RXER,
+ DA830_AFSR2,
+ DA830_ACLKX2,
+ DA830_AXR2_3,
+ DA830_AXR2_2,
+ DA830_AXR2_1,
+ DA830_AFSX2,
+ DA830_ACLKR2,
+ DA830_NRESETOUT,
+ DA830_GPIO3_0,
+ DA830_GPIO3_1,
+ DA830_GPIO3_2,
+ DA830_GPIO3_3,
+ DA830_GPIO3_4,
+ DA830_GPIO3_5,
+ DA830_GPIO3_6,
+ DA830_AXR0_7,
+ DA830_AXR0_8,
+ DA830_UART1_RXD,
+ DA830_UART1_TXD,
+ DA830_AXR0_11,
+ DA830_AHCLKX1,
+ DA830_ACLKX1,
+ DA830_AFSX1,
+ DA830_MDIO_CLK,
+ DA830_MDIO_D,
+ DA830_AXR0_9,
+ DA830_AXR0_10,
+ DA830_EPWM0B,
+ DA830_EPWM0A,
+ DA830_EPWMSYNCI,
+ DA830_AXR2_0,
+ DA830_EPWMSYNC0,
+ DA830_GPIO3_7,
+ DA830_GPIO3_8,
+ DA830_GPIO3_9,
+ DA830_GPIO3_10,
+ DA830_GPIO3_11,
+ DA830_GPIO3_14,
+ DA830_GPIO3_15,
+ DA830_GPIO4_10,
+ DA830_AHCLKR1,
+ DA830_ACLKR1,
+ DA830_AFSR1,
+ DA830_AMUTE1,
+ DA830_AXR1_0,
+ DA830_AXR1_1,
+ DA830_AXR1_2,
+ DA830_AXR1_3,
+ DA830_ECAP2_APWM2,
+ DA830_EHRPWMGLUETZ,
+ DA830_EQEP1A,
+ DA830_GPIO4_11,
+ DA830_GPIO4_12,
+ DA830_GPIO4_13,
+ DA830_GPIO4_14,
+ DA830_GPIO4_0,
+ DA830_GPIO4_1,
+ DA830_GPIO4_2,
+ DA830_GPIO4_3,
+ DA830_AXR1_4,
+ DA830_AXR1_5,
+ DA830_AXR1_6,
+ DA830_AXR1_7,
+ DA830_AXR1_8,
+ DA830_AXR1_9,
+ DA830_EMA_D_0,
+ DA830_EMA_D_1,
+ DA830_EQEP1B,
+ DA830_EPWM2B,
+ DA830_EPWM2A,
+ DA830_EPWM1B,
+ DA830_EPWM1A,
+ DA830_MMCSD_DAT_0,
+ DA830_MMCSD_DAT_1,
+ DA830_UHPI_HD_0,
+ DA830_UHPI_HD_1,
+ DA830_GPIO4_4,
+ DA830_GPIO4_5,
+ DA830_GPIO4_6,
+ DA830_GPIO4_7,
+ DA830_GPIO4_8,
+ DA830_GPIO4_9,
+ DA830_GPIO0_0,
+ DA830_GPIO0_1,
+ DA830_EMA_D_2,
+ DA830_EMA_D_3,
+ DA830_EMA_D_4,
+ DA830_EMA_D_5,
+ DA830_EMA_D_6,
+ DA830_EMA_D_7,
+ DA830_EMA_D_8,
+ DA830_EMA_D_9,
+ DA830_MMCSD_DAT_2,
+ DA830_MMCSD_DAT_3,
+ DA830_MMCSD_DAT_4,
+ DA830_MMCSD_DAT_5,
+ DA830_MMCSD_DAT_6,
+ DA830_MMCSD_DAT_7,
+ DA830_UHPI_HD_8,
+ DA830_UHPI_HD_9,
+ DA830_UHPI_HD_2,
+ DA830_UHPI_HD_3,
+ DA830_UHPI_HD_4,
+ DA830_UHPI_HD_5,
+ DA830_UHPI_HD_6,
+ DA830_UHPI_HD_7,
+ DA830_LCD_D_8,
+ DA830_LCD_D_9,
+ DA830_GPIO0_2,
+ DA830_GPIO0_3,
+ DA830_GPIO0_4,
+ DA830_GPIO0_5,
+ DA830_GPIO0_6,
+ DA830_GPIO0_7,
+ DA830_GPIO0_8,
+ DA830_GPIO0_9,
+ DA830_EMA_D_10,
+ DA830_EMA_D_11,
+ DA830_EMA_D_12,
+ DA830_EMA_D_13,
+ DA830_EMA_D_14,
+ DA830_EMA_D_15,
+ DA830_EMA_A_0,
+ DA830_EMA_A_1,
+ DA830_UHPI_HD_10,
+ DA830_UHPI_HD_11,
+ DA830_UHPI_HD_12,
+ DA830_UHPI_HD_13,
+ DA830_UHPI_HD_14,
+ DA830_UHPI_HD_15,
+ DA830_LCD_D_7,
+ DA830_MMCSD_CLK,
+ DA830_LCD_D_10,
+ DA830_LCD_D_11,
+ DA830_LCD_D_12,
+ DA830_LCD_D_13,
+ DA830_LCD_D_14,
+ DA830_LCD_D_15,
+ DA830_UHPI_HCNTL0,
+ DA830_GPIO0_10,
+ DA830_GPIO0_11,
+ DA830_GPIO0_12,
+ DA830_GPIO0_13,
+ DA830_GPIO0_14,
+ DA830_GPIO0_15,
+ DA830_GPIO1_0,
+ DA830_GPIO1_1,
+ DA830_EMA_A_2,
+ DA830_EMA_A_3,
+ DA830_EMA_A_4,
+ DA830_EMA_A_5,
+ DA830_EMA_A_6,
+ DA830_EMA_A_7,
+ DA830_EMA_A_8,
+ DA830_EMA_A_9,
+ DA830_MMCSD_CMD,
+ DA830_LCD_D_6,
+ DA830_LCD_D_3,
+ DA830_LCD_D_2,
+ DA830_LCD_D_1,
+ DA830_LCD_D_0,
+ DA830_LCD_PCLK,
+ DA830_LCD_HSYNC,
+ DA830_UHPI_HCNTL1,
+ DA830_GPIO1_2,
+ DA830_GPIO1_3,
+ DA830_GPIO1_4,
+ DA830_GPIO1_5,
+ DA830_GPIO1_6,
+ DA830_GPIO1_7,
+ DA830_GPIO1_8,
+ DA830_GPIO1_9,
+ DA830_EMA_A_10,
+ DA830_EMA_A_11,
+ DA830_EMA_A_12,
+ DA830_EMA_BA_1,
+ DA830_EMA_BA_0,
+ DA830_EMA_CLK,
+ DA830_EMA_SDCKE,
+ DA830_NEMA_CAS,
+ DA830_LCD_VSYNC,
+ DA830_NLCD_AC_ENB_CS,
+ DA830_LCD_MCLK,
+ DA830_LCD_D_5,
+ DA830_LCD_D_4,
+ DA830_OBSCLK,
+ DA830_NEMA_CS_4,
+ DA830_UHPI_HHWIL,
+ DA830_AHCLKR2,
+ DA830_GPIO1_10,
+ DA830_GPIO1_11,
+ DA830_GPIO1_12,
+ DA830_GPIO1_13,
+ DA830_GPIO1_14,
+ DA830_GPIO1_15,
+ DA830_GPIO2_0,
+ DA830_GPIO2_1,
+ DA830_NEMA_RAS,
+ DA830_NEMA_WE,
+ DA830_NEMA_CS_0,
+ DA830_NEMA_CS_2,
+ DA830_NEMA_CS_3,
+ DA830_NEMA_OE,
+ DA830_NEMA_WE_DQM_1,
+ DA830_NEMA_WE_DQM_0,
+ DA830_NEMA_CS_5,
+ DA830_UHPI_HRNW,
+ DA830_NUHPI_HAS,
+ DA830_NUHPI_HCS,
+ DA830_NUHPI_HDS1,
+ DA830_NUHPI_HDS2,
+ DA830_NUHPI_HINT,
+ DA830_AXR0_12,
+ DA830_AMUTE2,
+ DA830_AXR0_13,
+ DA830_AXR0_14,
+ DA830_AXR0_15,
+ DA830_GPIO2_2,
+ DA830_GPIO2_3,
+ DA830_GPIO2_4,
+ DA830_GPIO2_5,
+ DA830_GPIO2_6,
+ DA830_GPIO2_7,
+ DA830_GPIO2_8,
+ DA830_GPIO2_9,
+ DA830_EMA_WAIT_0,
+ DA830_NUHPI_HRDY,
+ DA830_GPIO2_10,
+};
+
+enum davinci_da850_index {
+ /* UART0 function */
+ DA850_NUART0_CTS,
+ DA850_NUART0_RTS,
+ DA850_UART0_RXD,
+ DA850_UART0_TXD,
+
+ /* UART1 function */
+ DA850_NUART1_CTS,
+ DA850_NUART1_RTS,
+ DA850_UART1_RXD,
+ DA850_UART1_TXD,
+
+ /* UART2 function */
+ DA850_NUART2_CTS,
+ DA850_NUART2_RTS,
+ DA850_UART2_RXD,
+ DA850_UART2_TXD,
+
+ /* I2C1 function */
+ DA850_I2C1_SCL,
+ DA850_I2C1_SDA,
+
+ /* I2C0 function */
+ DA850_I2C0_SDA,
+ DA850_I2C0_SCL,
+
+ /* EMAC function */
+ DA850_MII_TXEN,
+ DA850_MII_TXCLK,
+ DA850_MII_COL,
+ DA850_MII_TXD_3,
+ DA850_MII_TXD_2,
+ DA850_MII_TXD_1,
+ DA850_MII_TXD_0,
+ DA850_MII_RXER,
+ DA850_MII_CRS,
+ DA850_MII_RXCLK,
+ DA850_MII_RXDV,
+ DA850_MII_RXD_3,
+ DA850_MII_RXD_2,
+ DA850_MII_RXD_1,
+ DA850_MII_RXD_0,
+ DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ DA850_RMII_TXD_0,
+ DA850_RMII_TXD_1,
+ DA850_RMII_TXEN,
+ DA850_RMII_CRS_DV,
+ DA850_RMII_RXD_0,
+ DA850_RMII_RXD_1,
+ DA850_RMII_RXER,
+ DA850_RMII_MHZ_50_CLK,
+
+ /* McASP function */
+ DA850_ACLKR,
+ DA850_ACLKX,
+ DA850_AFSR,
+ DA850_AFSX,
+ DA850_AHCLKR,
+ DA850_AHCLKX,
+ DA850_AMUTE,
+ DA850_AXR_15,
+ DA850_AXR_14,
+ DA850_AXR_13,
+ DA850_AXR_12,
+ DA850_AXR_11,
+ DA850_AXR_10,
+ DA850_AXR_9,
+ DA850_AXR_8,
+ DA850_AXR_7,
+ DA850_AXR_6,
+ DA850_AXR_5,
+ DA850_AXR_4,
+ DA850_AXR_3,
+ DA850_AXR_2,
+ DA850_AXR_1,
+ DA850_AXR_0,
+
+ /* LCD function */
+ DA850_LCD_D_7,
+ DA850_LCD_D_6,
+ DA850_LCD_D_5,
+ DA850_LCD_D_4,
+ DA850_LCD_D_3,
+ DA850_LCD_D_2,
+ DA850_LCD_D_1,
+ DA850_LCD_D_0,
+ DA850_LCD_D_15,
+ DA850_LCD_D_14,
+ DA850_LCD_D_13,
+ DA850_LCD_D_12,
+ DA850_LCD_D_11,
+ DA850_LCD_D_10,
+ DA850_LCD_D_9,
+ DA850_LCD_D_8,
+ DA850_LCD_PCLK,
+ DA850_LCD_HSYNC,
+ DA850_LCD_VSYNC,
+ DA850_NLCD_AC_ENB_CS,
+
+ /* MMC/SD0 function */
+ DA850_MMCSD0_DAT_0,
+ DA850_MMCSD0_DAT_1,
+ DA850_MMCSD0_DAT_2,
+ DA850_MMCSD0_DAT_3,
+ DA850_MMCSD0_CLK,
+ DA850_MMCSD0_CMD,
+
+ /* EMIF2.5/EMIFA function */
+ DA850_EMA_D_7,
+ DA850_EMA_D_6,
+ DA850_EMA_D_5,
+ DA850_EMA_D_4,
+ DA850_EMA_D_3,
+ DA850_EMA_D_2,
+ DA850_EMA_D_1,
+ DA850_EMA_D_0,
+ DA850_EMA_A_1,
+ DA850_EMA_A_2,
+ DA850_NEMA_CS_3,
+ DA850_NEMA_CS_4,
+ DA850_NEMA_WE,
+ DA850_NEMA_OE,
+ DA850_EMA_D_15,
+ DA850_EMA_D_14,
+ DA850_EMA_D_13,
+ DA850_EMA_D_12,
+ DA850_EMA_D_11,
+ DA850_EMA_D_10,
+ DA850_EMA_D_9,
+ DA850_EMA_D_8,
+ DA850_EMA_A_0,
+ DA850_EMA_A_3,
+ DA850_EMA_A_4,
+ DA850_EMA_A_5,
+ DA850_EMA_A_6,
+ DA850_EMA_A_7,
+ DA850_EMA_A_8,
+ DA850_EMA_A_9,
+ DA850_EMA_A_10,
+ DA850_EMA_A_11,
+ DA850_EMA_A_12,
+ DA850_EMA_A_13,
+ DA850_EMA_A_14,
+ DA850_EMA_A_15,
+ DA850_EMA_A_16,
+ DA850_EMA_A_17,
+ DA850_EMA_A_18,
+ DA850_EMA_A_19,
+ DA850_EMA_A_20,
+ DA850_EMA_A_21,
+ DA850_EMA_A_22,
+ DA850_EMA_A_23,
+ DA850_EMA_BA_1,
+ DA850_EMA_CLK,
+ DA850_EMA_WAIT_1,
+ DA850_NEMA_CS_2,
+
+ /* GPIO function */
+ DA850_GPIO2_4,
+ DA850_GPIO2_6,
+ DA850_GPIO2_8,
+ DA850_GPIO2_15,
+ DA850_GPIO3_12,
+ DA850_GPIO3_13,
+ DA850_GPIO4_0,
+ DA850_GPIO4_1,
+ DA850_GPIO6_13,
+ DA850_RTC_ALARM,
+};
+
+enum davinci_tnetv107x_index {
+ TNETV107X_ASR_A00,
+ TNETV107X_GPIO32,
+ TNETV107X_ASR_A01,
+ TNETV107X_GPIO33,
+ TNETV107X_ASR_A02,
+ TNETV107X_GPIO34,
+ TNETV107X_ASR_A03,
+ TNETV107X_GPIO35,
+ TNETV107X_ASR_A04,
+ TNETV107X_GPIO36,
+ TNETV107X_ASR_A05,
+ TNETV107X_GPIO37,
+ TNETV107X_ASR_A06,
+ TNETV107X_GPIO38,
+ TNETV107X_ASR_A07,
+ TNETV107X_GPIO39,
+ TNETV107X_ASR_A08,
+ TNETV107X_GPIO40,
+ TNETV107X_ASR_A09,
+ TNETV107X_GPIO41,
+ TNETV107X_ASR_A10,
+ TNETV107X_GPIO42,
+ TNETV107X_ASR_A11,
+ TNETV107X_BOOT_STRP_0,
+ TNETV107X_ASR_A12,
+ TNETV107X_BOOT_STRP_1,
+ TNETV107X_ASR_A13,
+ TNETV107X_GPIO43,
+ TNETV107X_ASR_A14,
+ TNETV107X_GPIO44,
+ TNETV107X_ASR_A15,
+ TNETV107X_GPIO45,
+ TNETV107X_ASR_A16,
+ TNETV107X_GPIO46,
+ TNETV107X_ASR_A17,
+ TNETV107X_GPIO47,
+ TNETV107X_ASR_A18,
+ TNETV107X_GPIO48,
+ TNETV107X_SDIO1_DATA3_0,
+ TNETV107X_ASR_A19,
+ TNETV107X_GPIO49,
+ TNETV107X_SDIO1_DATA2_0,
+ TNETV107X_ASR_A20,
+ TNETV107X_GPIO50,
+ TNETV107X_SDIO1_DATA1_0,
+ TNETV107X_ASR_A21,
+ TNETV107X_GPIO51,
+ TNETV107X_SDIO1_DATA0_0,
+ TNETV107X_ASR_A22,
+ TNETV107X_GPIO52,
+ TNETV107X_SDIO1_CMD_0,
+ TNETV107X_ASR_A23,
+ TNETV107X_GPIO53,
+ TNETV107X_SDIO1_CLK_0,
+ TNETV107X_ASR_BA_1,
+ TNETV107X_GPIO54,
+ TNETV107X_SYS_PLL_CLK,
+ TNETV107X_ASR_CS0,
+ TNETV107X_ASR_CS1,
+ TNETV107X_ASR_CS2,
+ TNETV107X_TDM_PLL_CLK,
+ TNETV107X_ASR_CS3,
+ TNETV107X_ETH_PHY_CLK,
+ TNETV107X_ASR_D00,
+ TNETV107X_GPIO55,
+ TNETV107X_ASR_D01,
+ TNETV107X_GPIO56,
+ TNETV107X_ASR_D02,
+ TNETV107X_GPIO57,
+ TNETV107X_ASR_D03,
+ TNETV107X_GPIO58,
+ TNETV107X_ASR_D04,
+ TNETV107X_GPIO59_0,
+ TNETV107X_ASR_D05,
+ TNETV107X_GPIO60_0,
+ TNETV107X_ASR_D06,
+ TNETV107X_GPIO61_0,
+ TNETV107X_ASR_D07,
+ TNETV107X_GPIO62_0,
+ TNETV107X_ASR_D08,
+ TNETV107X_GPIO63_0,
+ TNETV107X_ASR_D09,
+ TNETV107X_GPIO64_0,
+ TNETV107X_ASR_D10,
+ TNETV107X_SDIO1_DATA3_1,
+ TNETV107X_ASR_D11,
+ TNETV107X_SDIO1_DATA2_1,
+ TNETV107X_ASR_D12,
+ TNETV107X_SDIO1_DATA1_1,
+ TNETV107X_ASR_D13,
+ TNETV107X_SDIO1_DATA0_1,
+ TNETV107X_ASR_D14,
+ TNETV107X_SDIO1_CMD_1,
+ TNETV107X_ASR_D15,
+ TNETV107X_SDIO1_CLK_1,
+ TNETV107X_ASR_OE,
+ TNETV107X_BOOT_STRP_2,
+ TNETV107X_ASR_RNW,
+ TNETV107X_GPIO29_0,
+ TNETV107X_ASR_WAIT,
+ TNETV107X_GPIO30_0,
+ TNETV107X_ASR_WE,
+ TNETV107X_BOOT_STRP_3,
+ TNETV107X_ASR_WE_DQM0,
+ TNETV107X_GPIO31,
+ TNETV107X_LCD_PD17_0,
+ TNETV107X_ASR_WE_DQM1,
+ TNETV107X_ASR_BA0_0,
+ TNETV107X_VLYNQ_CLK,
+ TNETV107X_GPIO14,
+ TNETV107X_LCD_PD19_0,
+ TNETV107X_VLYNQ_RXD0,
+ TNETV107X_GPIO15,
+ TNETV107X_LCD_PD20_0,
+ TNETV107X_VLYNQ_RXD1,
+ TNETV107X_GPIO16,
+ TNETV107X_LCD_PD21_0,
+ TNETV107X_VLYNQ_TXD0,
+ TNETV107X_GPIO17,
+ TNETV107X_LCD_PD22_0,
+ TNETV107X_VLYNQ_TXD1,
+ TNETV107X_GPIO18,
+ TNETV107X_LCD_PD23_0,
+ TNETV107X_SDIO0_CLK,
+ TNETV107X_GPIO19,
+ TNETV107X_SDIO0_CMD,
+ TNETV107X_GPIO20,
+ TNETV107X_SDIO0_DATA0,
+ TNETV107X_GPIO21,
+ TNETV107X_SDIO0_DATA1,
+ TNETV107X_GPIO22,
+ TNETV107X_SDIO0_DATA2,
+ TNETV107X_GPIO23,
+ TNETV107X_SDIO0_DATA3,
+ TNETV107X_GPIO24,
+ TNETV107X_EMU0,
+ TNETV107X_EMU1,
+ TNETV107X_RTCK,
+ TNETV107X_TRST_N,
+ TNETV107X_TCK,
+ TNETV107X_TDI,
+ TNETV107X_TDO,
+ TNETV107X_TMS,
+ TNETV107X_TDM1_CLK,
+ TNETV107X_TDM1_RX,
+ TNETV107X_TDM1_TX,
+ TNETV107X_TDM1_FS,
+ TNETV107X_KEYPAD_R0,
+ TNETV107X_KEYPAD_R1,
+ TNETV107X_KEYPAD_R2,
+ TNETV107X_KEYPAD_R3,
+ TNETV107X_KEYPAD_R4,
+ TNETV107X_KEYPAD_R5,
+ TNETV107X_KEYPAD_R6,
+ TNETV107X_GPIO12,
+ TNETV107X_KEYPAD_R7,
+ TNETV107X_GPIO10,
+ TNETV107X_KEYPAD_C0,
+ TNETV107X_KEYPAD_C1,
+ TNETV107X_KEYPAD_C2,
+ TNETV107X_KEYPAD_C3,
+ TNETV107X_KEYPAD_C4,
+ TNETV107X_KEYPAD_C5,
+ TNETV107X_KEYPAD_C6,
+ TNETV107X_GPIO13,
+ TNETV107X_TEST_CLK_IN,
+ TNETV107X_KEYPAD_C7,
+ TNETV107X_GPIO11,
+ TNETV107X_SSP0_0,
+ TNETV107X_SCC_DCLK,
+ TNETV107X_LCD_PD20_1,
+ TNETV107X_SSP0_1,
+ TNETV107X_SCC_CS_N,
+ TNETV107X_LCD_PD21_1,
+ TNETV107X_SSP0_2,
+ TNETV107X_SCC_D,
+ TNETV107X_LCD_PD22_1,
+ TNETV107X_SSP0_3,
+ TNETV107X_SCC_RESETN,
+ TNETV107X_LCD_PD23_1,
+ TNETV107X_SSP1_0,
+ TNETV107X_GPIO25,
+ TNETV107X_UART2_CTS,
+ TNETV107X_SSP1_1,
+ TNETV107X_GPIO26,
+ TNETV107X_UART2_RD,
+ TNETV107X_SSP1_2,
+ TNETV107X_GPIO27,
+ TNETV107X_UART2_RTS,
+ TNETV107X_SSP1_3,
+ TNETV107X_GPIO28,
+ TNETV107X_UART2_TD,
+ TNETV107X_UART0_CTS,
+ TNETV107X_UART0_RD,
+ TNETV107X_UART0_RTS,
+ TNETV107X_UART0_TD,
+ TNETV107X_UART1_RD,
+ TNETV107X_UART1_TD,
+ TNETV107X_LCD_AC_NCS,
+ TNETV107X_LCD_HSYNC_RNW,
+ TNETV107X_LCD_VSYNC_A0,
+ TNETV107X_LCD_MCLK,
+ TNETV107X_LCD_PD16_0,
+ TNETV107X_LCD_PCLK_E,
+ TNETV107X_LCD_PD00,
+ TNETV107X_LCD_PD01,
+ TNETV107X_LCD_PD02,
+ TNETV107X_LCD_PD03,
+ TNETV107X_LCD_PD04,
+ TNETV107X_LCD_PD05,
+ TNETV107X_LCD_PD06,
+ TNETV107X_LCD_PD07,
+ TNETV107X_LCD_PD08,
+ TNETV107X_GPIO59_1,
+ TNETV107X_LCD_PD09,
+ TNETV107X_GPIO60_1,
+ TNETV107X_LCD_PD10,
+ TNETV107X_ASR_BA0_1,
+ TNETV107X_GPIO61_1,
+ TNETV107X_LCD_PD11,
+ TNETV107X_GPIO62_1,
+ TNETV107X_LCD_PD12,
+ TNETV107X_GPIO63_1,
+ TNETV107X_LCD_PD13,
+ TNETV107X_GPIO64_1,
+ TNETV107X_LCD_PD14,
+ TNETV107X_GPIO29_1,
+ TNETV107X_LCD_PD15,
+ TNETV107X_GPIO30_1,
+ TNETV107X_EINT0,
+ TNETV107X_GPIO08,
+ TNETV107X_EINT1,
+ TNETV107X_GPIO09,
+ TNETV107X_GPIO00,
+ TNETV107X_LCD_PD20_2,
+ TNETV107X_TDM_CLK_IN_2,
+ TNETV107X_GPIO01,
+ TNETV107X_LCD_PD21_2,
+ TNETV107X_24M_CLK_OUT_1,
+ TNETV107X_GPIO02,
+ TNETV107X_LCD_PD22_2,
+ TNETV107X_GPIO03,
+ TNETV107X_LCD_PD23_2,
+ TNETV107X_GPIO04,
+ TNETV107X_LCD_PD16_1,
+ TNETV107X_USB0_RXERR,
+ TNETV107X_GPIO05,
+ TNETV107X_LCD_PD17_1,
+ TNETV107X_TDM_CLK_IN_1,
+ TNETV107X_GPIO06,
+ TNETV107X_LCD_PD18,
+ TNETV107X_24M_CLK_OUT_2,
+ TNETV107X_GPIO07,
+ TNETV107X_LCD_PD19_1,
+ TNETV107X_USB1_RXERR,
+ TNETV107X_ETH_PLL_CLK,
+ TNETV107X_MDIO,
+ TNETV107X_MDC,
+ TNETV107X_AIC_MUTE_STAT_N,
+ TNETV107X_TDM0_CLK,
+ TNETV107X_AIC_HNS_EN_N,
+ TNETV107X_TDM0_FS,
+ TNETV107X_AIC_HDS_EN_STAT_N,
+ TNETV107X_TDM0_TX,
+ TNETV107X_AIC_HNF_EN_STAT_N,
+ TNETV107X_TDM0_RX,
+};
+
+#define PINMUX(x) (4 * (x))
+
+#ifdef CONFIG_DAVINCI_MUX
+/* setup pin muxing */
+extern int davinci_cfg_reg(unsigned long reg_cfg);
+extern int davinci_cfg_reg_list(const short pins[]);
+#else
+/* boot loader does it all (no warnings from CONFIG_DAVINCI_MUX_WARNINGS) */
+static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; }
+static inline int davinci_cfg_reg_list(const short pins[])
+{
+ return 0;
+}
+#endif
+
+#endif /* __INC_MACH_MUX_H */
diff --git a/arch/arm/mach-davinci/include/mach/nand.h b/arch/arm/mach-davinci/include/mach/nand.h
new file mode 100644
index 00000000..02515104
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/nand.h
@@ -0,0 +1,88 @@
+/*
+ * mach-davinci/nand.h
+ *
+ * Copyright © 2006 Texas Instruments.
+ *
+ * Ported to 2.6.23 Copyright © 2008 by
+ * Sander Huijsen <Shuijsen@optelecom-nkf.com>
+ * Troy Kisky <troy.kisky@boundarydevices.com>
+ * Dirk Behme <Dirk.Behme@gmail.com>
+ *
+ * --------------------------------------------------------------------------
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_DAVINCI_NAND_H
+#define __ARCH_ARM_DAVINCI_NAND_H
+
+#include <linux/mtd/nand.h>
+
+#define NANDFCR_OFFSET 0x60
+#define NANDFSR_OFFSET 0x64
+#define NANDF1ECC_OFFSET 0x70
+
+/* 4-bit ECC syndrome registers */
+#define NAND_4BIT_ECC_LOAD_OFFSET 0xbc
+#define NAND_4BIT_ECC1_OFFSET 0xc0
+#define NAND_4BIT_ECC2_OFFSET 0xc4
+#define NAND_4BIT_ECC3_OFFSET 0xc8
+#define NAND_4BIT_ECC4_OFFSET 0xcc
+#define NAND_ERR_ADD1_OFFSET 0xd0
+#define NAND_ERR_ADD2_OFFSET 0xd4
+#define NAND_ERR_ERRVAL1_OFFSET 0xd8
+#define NAND_ERR_ERRVAL2_OFFSET 0xdc
+
+/* NOTE: boards don't need to use these address bits
+ * for ALE/CLE unless they support booting from NAND.
+ * They're used unless platform data overrides them.
+ */
+#define MASK_ALE 0x08
+#define MASK_CLE 0x10
+
+struct davinci_nand_pdata { /* platform_data */
+ uint32_t mask_ale;
+ uint32_t mask_cle;
+
+ /* for packages using two chipselects */
+ uint32_t mask_chipsel;
+
+ /* board's default static partition info */
+ struct mtd_partition *parts;
+ unsigned nr_parts;
+
+ /* none == NAND_ECC_NONE (strongly *not* advised!!)
+ * soft == NAND_ECC_SOFT
+ * else == NAND_ECC_HW, according to ecc_bits
+ *
+ * All DaVinci-family chips support 1-bit hardware ECC.
+ * Newer ones also support 4-bit ECC, but are awkward
+ * using it with large page chips.
+ */
+ nand_ecc_modes_t ecc_mode;
+ u8 ecc_bits;
+
+ /* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */
+ unsigned options;
+
+ /* Main and mirror bbt descriptor overrides */
+ struct nand_bbt_descr *bbt_td;
+ struct nand_bbt_descr *bbt_md;
+
+ /* Access timings */
+ struct davinci_aemif_timing *timing;
+};
+
+#endif /* __ARCH_ARM_DAVINCI_NAND_H */
diff --git a/arch/arm/mach-davinci/include/mach/pm.h b/arch/arm/mach-davinci/include/mach/pm.h
new file mode 100644
index 00000000..37b19bf3
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/pm.h
@@ -0,0 +1,54 @@
+/*
+ * TI DaVinci platform support for power management.
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc. http://www.ti.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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _MACH_DAVINCI_PM_H
+#define _MACH_DAVINCI_PM_H
+
+/*
+ * Caution: Assembly code in sleep.S makes assumtion on the order
+ * of the members of this structure.
+ */
+struct davinci_pm_config {
+ void __iomem *ddr2_ctlr_base;
+ void __iomem *ddrpsc_reg_base;
+ int ddrpsc_num;
+ void __iomem *ddrpll_reg_base;
+ void __iomem *deepsleep_reg;
+ void __iomem *cpupll_reg_base;
+ /*
+ * Note on SLEEPCOUNT:
+ * The SLEEPCOUNT feature is mainly intended for cases in which
+ * the internal oscillator is used. The internal oscillator is
+ * fully disabled in deep sleep mode. When you exist deep sleep
+ * mode, the oscillator will be turned on and will generate very
+ * small oscillations which will not be detected by the deep sleep
+ * counter. Eventually those oscillations will grow to an amplitude
+ * large enough to start incrementing the deep sleep counter.
+ * In this case recommendation from hardware engineers is that the
+ * SLEEPCOUNT be set to 4096. This means that 4096 valid clock cycles
+ * must be detected before the clock is passed to the rest of the
+ * system.
+ * In the case that the internal oscillator is not used and the
+ * clock is generated externally, the SLEEPCOUNT value can be very
+ * small since the clock input is assumed to be stable before SoC
+ * is taken out of deepsleep mode. A value of 128 would be more than
+ * adequate.
+ */
+ int sleepcount;
+};
+
+extern unsigned int davinci_cpu_suspend_sz;
+extern void davinci_cpu_suspend(struct davinci_pm_config *);
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h
new file mode 100644
index 00000000..a47e6f29
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/psc.h
@@ -0,0 +1,256 @@
+/*
+ * DaVinci Power & Sleep Controller (PSC) defines
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.
+ *
+ */
+#ifndef __ASM_ARCH_PSC_H
+#define __ASM_ARCH_PSC_H
+
+#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000
+
+/* Power and Sleep Controller (PSC) Domains */
+#define DAVINCI_GPSC_ARMDOMAIN 0
+#define DAVINCI_GPSC_DSPDOMAIN 1
+
+#define DAVINCI_LPSC_VPSSMSTR 0
+#define DAVINCI_LPSC_VPSSSLV 1
+#define DAVINCI_LPSC_TPCC 2
+#define DAVINCI_LPSC_TPTC0 3
+#define DAVINCI_LPSC_TPTC1 4
+#define DAVINCI_LPSC_EMAC 5
+#define DAVINCI_LPSC_EMAC_WRAPPER 6
+#define DAVINCI_LPSC_USB 9
+#define DAVINCI_LPSC_ATA 10
+#define DAVINCI_LPSC_VLYNQ 11
+#define DAVINCI_LPSC_UHPI 12
+#define DAVINCI_LPSC_DDR_EMIF 13
+#define DAVINCI_LPSC_AEMIF 14
+#define DAVINCI_LPSC_MMC_SD 15
+#define DAVINCI_LPSC_McBSP 17
+#define DAVINCI_LPSC_I2C 18
+#define DAVINCI_LPSC_UART0 19
+#define DAVINCI_LPSC_UART1 20
+#define DAVINCI_LPSC_UART2 21
+#define DAVINCI_LPSC_SPI 22
+#define DAVINCI_LPSC_PWM0 23
+#define DAVINCI_LPSC_PWM1 24
+#define DAVINCI_LPSC_PWM2 25
+#define DAVINCI_LPSC_GPIO 26
+#define DAVINCI_LPSC_TIMER0 27
+#define DAVINCI_LPSC_TIMER1 28
+#define DAVINCI_LPSC_TIMER2 29
+#define DAVINCI_LPSC_SYSTEM_SUBSYS 30
+#define DAVINCI_LPSC_ARM 31
+#define DAVINCI_LPSC_SCR2 32
+#define DAVINCI_LPSC_SCR3 33
+#define DAVINCI_LPSC_SCR4 34
+#define DAVINCI_LPSC_CROSSBAR 35
+#define DAVINCI_LPSC_CFG27 36
+#define DAVINCI_LPSC_CFG3 37
+#define DAVINCI_LPSC_CFG5 38
+#define DAVINCI_LPSC_GEM 39
+#define DAVINCI_LPSC_IMCOP 40
+
+#define DM355_LPSC_TIMER3 5
+#define DM355_LPSC_SPI1 6
+#define DM355_LPSC_MMC_SD1 7
+#define DM355_LPSC_McBSP1 8
+#define DM355_LPSC_PWM3 10
+#define DM355_LPSC_SPI2 11
+#define DM355_LPSC_RTO 12
+#define DM355_LPSC_VPSS_DAC 41
+
+/* DM365 */
+#define DM365_LPSC_TIMER3 5
+#define DM365_LPSC_SPI1 6
+#define DM365_LPSC_MMC_SD1 7
+#define DM365_LPSC_McBSP1 8
+#define DM365_LPSC_PWM3 10
+#define DM365_LPSC_SPI2 11
+#define DM365_LPSC_RTO 12
+#define DM365_LPSC_TIMER4 17
+#define DM365_LPSC_SPI0 22
+#define DM365_LPSC_SPI3 38
+#define DM365_LPSC_SPI4 39
+#define DM365_LPSC_EMAC 40
+#define DM365_LPSC_VOICE_CODEC 44
+#define DM365_LPSC_DAC_CLK 46
+#define DM365_LPSC_VPSSMSTR 47
+#define DM365_LPSC_MJCP 50
+
+/*
+ * LPSC Assignments
+ */
+#define DM646X_LPSC_ARM 0
+#define DM646X_LPSC_C64X_CPU 1
+#define DM646X_LPSC_HDVICP0 2
+#define DM646X_LPSC_HDVICP1 3
+#define DM646X_LPSC_TPCC 4
+#define DM646X_LPSC_TPTC0 5
+#define DM646X_LPSC_TPTC1 6
+#define DM646X_LPSC_TPTC2 7
+#define DM646X_LPSC_TPTC3 8
+#define DM646X_LPSC_PCI 13
+#define DM646X_LPSC_EMAC 14
+#define DM646X_LPSC_VDCE 15
+#define DM646X_LPSC_VPSSMSTR 16
+#define DM646X_LPSC_VPSSSLV 17
+#define DM646X_LPSC_TSIF0 18
+#define DM646X_LPSC_TSIF1 19
+#define DM646X_LPSC_DDR_EMIF 20
+#define DM646X_LPSC_AEMIF 21
+#define DM646X_LPSC_McASP0 22
+#define DM646X_LPSC_McASP1 23
+#define DM646X_LPSC_CRGEN0 24
+#define DM646X_LPSC_CRGEN1 25
+#define DM646X_LPSC_UART0 26
+#define DM646X_LPSC_UART1 27
+#define DM646X_LPSC_UART2 28
+#define DM646X_LPSC_PWM0 29
+#define DM646X_LPSC_PWM1 30
+#define DM646X_LPSC_I2C 31
+#define DM646X_LPSC_SPI 32
+#define DM646X_LPSC_GPIO 33
+#define DM646X_LPSC_TIMER0 34
+#define DM646X_LPSC_TIMER1 35
+#define DM646X_LPSC_ARM_INTC 45
+
+/* PSC0 defines */
+#define DA8XX_LPSC0_TPCC 0
+#define DA8XX_LPSC0_TPTC0 1
+#define DA8XX_LPSC0_TPTC1 2
+#define DA8XX_LPSC0_EMIF25 3
+#define DA8XX_LPSC0_SPI0 4
+#define DA8XX_LPSC0_MMC_SD 5
+#define DA8XX_LPSC0_AINTC 6
+#define DA8XX_LPSC0_ARM_RAM_ROM 7
+#define DA8XX_LPSC0_SECU_MGR 8
+#define DA8XX_LPSC0_UART0 9
+#define DA8XX_LPSC0_SCR0_SS 10
+#define DA8XX_LPSC0_SCR1_SS 11
+#define DA8XX_LPSC0_SCR2_SS 12
+#define DA8XX_LPSC0_PRUSS 13
+#define DA8XX_LPSC0_ARM 14
+#define DA8XX_LPSC0_GEM 15
+
+/* PSC1 defines */
+#define DA850_LPSC1_TPCC1 0
+#define DA8XX_LPSC1_USB20 1
+#define DA8XX_LPSC1_USB11 2
+#define DA8XX_LPSC1_GPIO 3
+#define DA8XX_LPSC1_UHPI 4
+#define DA8XX_LPSC1_CPGMAC 5
+#define DA8XX_LPSC1_EMIF3C 6
+#define DA8XX_LPSC1_McASP0 7
+#define DA830_LPSC1_McASP1 8
+#define DA850_LPSC1_SATA 8
+#define DA830_LPSC1_McASP2 9
+#define DA8XX_LPSC1_SPI1 10
+#define DA8XX_LPSC1_I2C 11
+#define DA8XX_LPSC1_UART1 12
+#define DA8XX_LPSC1_UART2 13
+#define DA8XX_LPSC1_LCDC 16
+#define DA8XX_LPSC1_PWM 17
+#define DA850_LPSC1_MMC_SD1 18
+#define DA8XX_LPSC1_ECAP 20
+#define DA830_LPSC1_EQEP 21
+#define DA850_LPSC1_TPTC2 21
+#define DA8XX_LPSC1_SCR_P0_SS 24
+#define DA8XX_LPSC1_SCR_P1_SS 25
+#define DA8XX_LPSC1_CR_P3_SS 26
+#define DA8XX_LPSC1_L3_CBA_RAM 31
+
+/* TNETV107X LPSC Assignments */
+#define TNETV107X_LPSC_ARM 0
+#define TNETV107X_LPSC_GEM 1
+#define TNETV107X_LPSC_DDR2_PHY 2
+#define TNETV107X_LPSC_TPCC 3
+#define TNETV107X_LPSC_TPTC0 4
+#define TNETV107X_LPSC_TPTC1 5
+#define TNETV107X_LPSC_RAM 6
+#define TNETV107X_LPSC_MBX_LITE 7
+#define TNETV107X_LPSC_LCD 8
+#define TNETV107X_LPSC_ETHSS 9
+#define TNETV107X_LPSC_AEMIF 10
+#define TNETV107X_LPSC_CHIP_CFG 11
+#define TNETV107X_LPSC_TSC 12
+#define TNETV107X_LPSC_ROM 13
+#define TNETV107X_LPSC_UART2 14
+#define TNETV107X_LPSC_PKTSEC 15
+#define TNETV107X_LPSC_SECCTL 16
+#define TNETV107X_LPSC_KEYMGR 17
+#define TNETV107X_LPSC_KEYPAD 18
+#define TNETV107X_LPSC_GPIO 19
+#define TNETV107X_LPSC_MDIO 20
+#define TNETV107X_LPSC_SDIO0 21
+#define TNETV107X_LPSC_UART0 22
+#define TNETV107X_LPSC_UART1 23
+#define TNETV107X_LPSC_TIMER0 24
+#define TNETV107X_LPSC_TIMER1 25
+#define TNETV107X_LPSC_WDT_ARM 26
+#define TNETV107X_LPSC_WDT_DSP 27
+#define TNETV107X_LPSC_SSP 28
+#define TNETV107X_LPSC_TDM0 29
+#define TNETV107X_LPSC_VLYNQ 30
+#define TNETV107X_LPSC_MCDMA 31
+#define TNETV107X_LPSC_USB0 32
+#define TNETV107X_LPSC_TDM1 33
+#define TNETV107X_LPSC_DEBUGSS 34
+#define TNETV107X_LPSC_ETHSS_RGMII 35
+#define TNETV107X_LPSC_SYSTEM 36
+#define TNETV107X_LPSC_IMCOP 37
+#define TNETV107X_LPSC_SPARE 38
+#define TNETV107X_LPSC_SDIO1 39
+#define TNETV107X_LPSC_USB1 40
+#define TNETV107X_LPSC_USBSS 41
+#define TNETV107X_LPSC_DDR2_EMIF1_VRST 42
+#define TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST 43
+#define TNETV107X_LPSC_MAX 44
+
+/* PSC register offsets */
+#define EPCPR 0x070
+#define PTCMD 0x120
+#define PTSTAT 0x128
+#define PDSTAT 0x200
+#define PDCTL1 0x304
+#define MDSTAT 0x800
+#define MDCTL 0xA00
+
+/* PSC module states */
+#define PSC_STATE_SWRSTDISABLE 0
+#define PSC_STATE_SYNCRST 1
+#define PSC_STATE_DISABLE 2
+#define PSC_STATE_ENABLE 3
+
+#define MDSTAT_STATE_MASK 0x1f
+
+#ifndef __ASSEMBLER__
+
+extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
+extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
+ unsigned int id, u32 next_state);
+
+#endif
+
+#endif /* __ASM_ARCH_PSC_H */
diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h
new file mode 100644
index 00000000..c9e6ce18
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/serial.h
@@ -0,0 +1,57 @@
+/*
+ * DaVinci serial device definitions
+ *
+ * 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.
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <asm/memory.h>
+
+#include <mach/hardware.h>
+
+/*
+ * Stolen area that contains debug uart physical and virtual addresses. These
+ * addresses are filled in by the uncompress.h code, and are used by the debug
+ * macros in debug-macro.S.
+ *
+ * This area sits just below the page tables (see arch/arm/kernel/head.S).
+ */
+#define DAVINCI_UART_INFO (PLAT_PHYS_OFFSET + 0x3ff8)
+
+#define DAVINCI_UART0_BASE (IO_PHYS + 0x20000)
+#define DAVINCI_UART1_BASE (IO_PHYS + 0x20400)
+#define DAVINCI_UART2_BASE (IO_PHYS + 0x20800)
+
+#define DA8XX_UART0_BASE (IO_PHYS + 0x042000)
+#define DA8XX_UART1_BASE (IO_PHYS + 0x10c000)
+#define DA8XX_UART2_BASE (IO_PHYS + 0x10d000)
+
+#define TNETV107X_UART0_BASE 0x08108100
+#define TNETV107X_UART1_BASE 0x08088400
+#define TNETV107X_UART2_BASE 0x08108300
+
+#define TNETV107X_UART0_VIRT IOMEM(0xfee08100)
+#define TNETV107X_UART1_VIRT IOMEM(0xfed88400)
+#define TNETV107X_UART2_VIRT IOMEM(0xfee08300)
+
+/* DaVinci UART register offsets */
+#define UART_DAVINCI_PWREMU 0x0c
+#define UART_DM646X_SCR 0x10
+#define UART_DM646X_SCR_TX_WATERMARK 0x08
+
+#ifndef __ASSEMBLY__
+struct davinci_uart_config {
+ /* Bit field of UARTs present; bit 0 --> UART1 */
+ unsigned int enabled_uarts;
+};
+
+extern int davinci_serial_init(struct davinci_uart_config *);
+#endif
+
+#endif /* __ASM_ARCH_SERIAL_H */
diff --git a/arch/arm/mach-davinci/include/mach/spi.h b/arch/arm/mach-davinci/include/mach/spi.h
new file mode 100644
index 00000000..7af305b3
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/spi.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2009 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.
+ */
+
+#ifndef __ARCH_ARM_DAVINCI_SPI_H
+#define __ARCH_ARM_DAVINCI_SPI_H
+
+#include <mach/edma.h>
+
+#define SPI_INTERN_CS 0xFF
+
+enum {
+ SPI_VERSION_1, /* For DM355/DM365/DM6467 */
+ SPI_VERSION_2, /* For DA8xx */
+};
+
+/**
+ * davinci_spi_platform_data - Platform data for SPI master device on DaVinci
+ *
+ * @version: version of the SPI IP. Different DaVinci devices have slightly
+ * varying versions of the same IP.
+ * @num_chipselect: number of chipselects supported by this SPI master
+ * @intr_line: interrupt line used to connect the SPI IP to the ARM interrupt
+ * controller withn the SoC. Possible values are 0 and 1.
+ * @chip_sel: list of GPIOs which can act as chip-selects for the SPI.
+ * SPI_INTERN_CS denotes internal SPI chip-select. Not necessary
+ * to populate if all chip-selects are internal.
+ * @cshold_bug: set this to true if the SPI controller on your chip requires
+ * a write to CSHOLD bit in between transfers (like in DM355).
+ * @dma_event_q: DMA event queue to use if SPI_IO_TYPE_DMA is used for any
+ * device on the bus.
+ */
+struct davinci_spi_platform_data {
+ u8 version;
+ u8 num_chipselect;
+ u8 intr_line;
+ u8 *chip_sel;
+ bool cshold_bug;
+ enum dma_event_q dma_event_q;
+};
+
+/**
+ * davinci_spi_config - Per-chip-select configuration for SPI slave devices
+ *
+ * @wdelay: amount of delay between transmissions. Measured in number of
+ * SPI module clocks.
+ * @odd_parity: polarity of parity flag at the end of transmit data stream.
+ * 0 - odd parity, 1 - even parity.
+ * @parity_enable: enable transmission of parity at end of each transmit
+ * data stream.
+ * @io_type: type of IO transfer. Choose between polled, interrupt and DMA.
+ * @timer_disable: disable chip-select timers (setup and hold)
+ * @c2tdelay: chip-select setup time. Measured in number of SPI module clocks.
+ * @t2cdelay: chip-select hold time. Measured in number of SPI module clocks.
+ * @t2edelay: transmit data finished to SPI ENAn pin inactive time. Measured
+ * in number of SPI clocks.
+ * @c2edelay: chip-select active to SPI ENAn signal active time. Measured in
+ * number of SPI clocks.
+ */
+struct davinci_spi_config {
+ u8 wdelay;
+ u8 odd_parity;
+ u8 parity_enable;
+#define SPI_IO_TYPE_INTR 0
+#define SPI_IO_TYPE_POLL 1
+#define SPI_IO_TYPE_DMA 2
+ u8 io_type;
+ u8 timer_disable;
+ u8 c2tdelay;
+ u8 t2cdelay;
+ u8 t2edelay;
+ u8 c2edelay;
+};
+
+#endif /* __ARCH_ARM_DAVINCI_SPI_H */
diff --git a/arch/arm/mach-davinci/include/mach/sram.h b/arch/arm/mach-davinci/include/mach/sram.h
new file mode 100644
index 00000000..111f7cc7
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/sram.h
@@ -0,0 +1,27 @@
+/*
+ * mach/sram.h - DaVinci simple SRAM allocator
+ *
+ * Copyright (C) 2009 David Brownell
+ *
+ * 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_SRAM_H
+#define __MACH_SRAM_H
+
+/* ARBITRARY: SRAM allocations are multiples of this 2^N size */
+#define SRAM_GRANULARITY 512
+
+/*
+ * SRAM allocations return a CPU virtual address, or NULL on error.
+ * If a DMA address is requested and the SRAM supports DMA, its
+ * mapped address is also returned.
+ *
+ * Errors include SRAM memory not being available, and requesting
+ * DMA mapped SRAM on systems which don't allow that.
+ */
+extern void *sram_alloc(size_t len, dma_addr_t *dma);
+extern void sram_free(void *addr, size_t len);
+
+#endif /* __MACH_SRAM_H */
diff --git a/arch/arm/mach-davinci/include/mach/system.h b/arch/arm/mach-davinci/include/mach/system.h
new file mode 100644
index 00000000..e65629c2
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ * DaVinci system defines
+ *
+ * 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.
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/common.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ if (davinci_soc_info.reset)
+ davinci_soc_info.reset(davinci_soc_info.reset_device);
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h
new file mode 100644
index 00000000..1c971d8d
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/time.h
@@ -0,0 +1,35 @@
+/*
+ * Local header file for DaVinci time code.
+ *
+ * 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.
+ */
+#ifndef __ARCH_ARM_MACH_DAVINCI_TIME_H
+#define __ARCH_ARM_MACH_DAVINCI_TIME_H
+
+#define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400)
+#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800)
+#define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00)
+
+enum {
+ T0_BOT,
+ 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))
+
+#define ID_TO_TIMER(id) (IS_TIMER1(id) != 0)
+
+extern struct davinci_timer_instance davinci_timer_instance[];
+
+#endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */
diff --git a/arch/arm/mach-davinci/include/mach/timex.h b/arch/arm/mach-davinci/include/mach/timex.h
new file mode 100644
index 00000000..9b885298
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/timex.h
@@ -0,0 +1,22 @@
+/*
+ * DaVinci timer defines
+ *
+ * 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.
+ */
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/*
+ * Alert: Not all timers of the DaVinci family run at a frequency of 27MHz,
+ * but we should be fine as long as CLOCK_TICK_RATE or LATCH (see include/
+ * linux/jiffies.h) are not used directly in code. Currently none of the
+ * code relevant to DaVinci platform depends on these values directly.
+ */
+#define CLOCK_TICK_RATE 27000000
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h
new file mode 100644
index 00000000..89c1fdc6
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h
@@ -0,0 +1,60 @@
+/*
+ * Texas Instruments TNETV107X SoC Specific Defines
+ *
+ * Copyright (C) 2010 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __ASM_ARCH_DAVINCI_TNETV107X_H
+#define __ASM_ARCH_DAVINCI_TNETV107X_H
+
+#include <asm/sizes.h>
+
+#define TNETV107X_DDR_BASE 0x80000000
+
+/*
+ * Fixed mapping for early init starts here. If low-level debug is enabled,
+ * this area also gets mapped via io_pg_offset and io_phys by the boot code.
+ * To fit in with the io_pg_offset calculation, the io base address selected
+ * here _must_ be a multiple of 2^20.
+ */
+#define TNETV107X_IO_BASE 0x08000000
+#define TNETV107X_IO_VIRT (IO_VIRT + SZ_1M)
+
+#define TNETV107X_N_GPIO 65
+
+#ifndef __ASSEMBLY__
+
+#include <linux/serial_8250.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/mfd/ti_ssp.h>
+
+#include <mach/mmc.h>
+#include <mach/nand.h>
+#include <mach/serial.h>
+
+struct tnetv107x_device_info {
+ struct davinci_uart_config *serial_config;
+ struct davinci_mmc_config *mmc_config[2]; /* 2 controllers */
+ struct davinci_nand_pdata *nand_config[4]; /* 4 chipsels */
+ struct matrix_keypad_platform_data *keypad_config;
+ struct ti_ssp_data *ssp_config;
+};
+
+extern struct platform_device tnetv107x_wdt_device;
+extern struct platform_device tnetv107x_serial_device;
+
+extern void __init tnetv107x_init(void);
+extern void __init tnetv107x_devices_init(struct tnetv107x_device_info *);
+extern void __init tnetv107x_irq_init(void);
+
+#endif
+
+#endif /* __ASM_ARCH_DAVINCI_TNETV107X_H */
diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h
new file mode 100644
index 00000000..78d80683
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/uncompress.h
@@ -0,0 +1,101 @@
+/*
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Initially based on:
+ * arch/arm/plat-omap/include/mach/uncompress.h
+ *
+ * Original copyrights follow.
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Rewritten by:
+ * Author: <source@mvista.com>
+ * 2004 (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/types.h>
+#include <linux/serial_reg.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/serial.h>
+
+u32 *uart;
+
+/* PORT_16C550A, in polled non-fifo mode */
+static void putc(char c)
+{
+ while (!(uart[UART_LSR] & UART_LSR_THRE))
+ barrier();
+ uart[UART_TX] = c;
+}
+
+static inline void flush(void)
+{
+ while (!(uart[UART_LSR] & UART_LSR_THRE))
+ barrier();
+}
+
+static inline void set_uart_info(u32 phys, void * __iomem virt)
+{
+ u32 *uart_info = (u32 *)(DAVINCI_UART_INFO);
+
+ uart = (u32 *)phys;
+ uart_info[0] = phys;
+ uart_info[1] = (u32)virt;
+}
+
+#define _DEBUG_LL_ENTRY(machine, phys, virt) \
+ if (machine_is_##machine()) { \
+ set_uart_info(phys, virt); \
+ break; \
+ }
+
+#define DEBUG_LL_DAVINCI(machine, port) \
+ _DEBUG_LL_ENTRY(machine, DAVINCI_UART##port##_BASE, \
+ IO_ADDRESS(DAVINCI_UART##port##_BASE))
+
+#define DEBUG_LL_DA8XX(machine, port) \
+ _DEBUG_LL_ENTRY(machine, DA8XX_UART##port##_BASE, \
+ IO_ADDRESS(DA8XX_UART##port##_BASE))
+
+#define DEBUG_LL_TNETV107X(machine, port) \
+ _DEBUG_LL_ENTRY(machine, TNETV107X_UART##port##_BASE, \
+ TNETV107X_UART##port##_VIRT)
+
+static inline void __arch_decomp_setup(unsigned long arch_id)
+{
+ /*
+ * Initialize the port based on the machine ID from the bootloader.
+ * Note that we're using macros here instead of switch statement
+ * as machine_is functions are optimized out for the boards that
+ * are not selected.
+ */
+ do {
+ /* Davinci boards */
+ DEBUG_LL_DAVINCI(davinci_evm, 0);
+ DEBUG_LL_DAVINCI(sffsdr, 0);
+ DEBUG_LL_DAVINCI(neuros_osd2, 0);
+ DEBUG_LL_DAVINCI(davinci_dm355_evm, 0);
+ DEBUG_LL_DAVINCI(dm355_leopard, 0);
+ DEBUG_LL_DAVINCI(davinci_dm6467_evm, 0);
+ DEBUG_LL_DAVINCI(davinci_dm365_evm, 0);
+
+ /* DA8xx boards */
+ DEBUG_LL_DA8XX(davinci_da830_evm, 2);
+ DEBUG_LL_DA8XX(davinci_da850_evm, 2);
+ DEBUG_LL_DA8XX(mityomapl138, 1);
+ DEBUG_LL_DA8XX(omapl138_hawkboard, 2);
+
+ /* TNETV107x boards */
+ DEBUG_LL_TNETV107X(tnetv107x, 1);
+ } while (0);
+}
+
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-davinci/include/mach/usb.h b/arch/arm/mach-davinci/include/mach/usb.h
new file mode 100644
index 00000000..e0bc4abe
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/usb.h
@@ -0,0 +1,59 @@
+/*
+ * USB related definitions
+ *
+ * Copyright (C) 2009 MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_USB_H
+#define __ASM_ARCH_USB_H
+
+/* DA8xx CFGCHIP2 (USB 2.0 PHY Control) register bits */
+#define CFGCHIP2_PHYCLKGD (1 << 17)
+#define CFGCHIP2_VBUSSENSE (1 << 16)
+#define CFGCHIP2_RESET (1 << 15)
+#define CFGCHIP2_OTGMODE (3 << 13)
+#define CFGCHIP2_NO_OVERRIDE (0 << 13)
+#define CFGCHIP2_FORCE_HOST (1 << 13)
+#define CFGCHIP2_FORCE_DEVICE (2 << 13)
+#define CFGCHIP2_FORCE_HOST_VBUS_LOW (3 << 13)
+#define CFGCHIP2_USB1PHYCLKMUX (1 << 12)
+#define CFGCHIP2_USB2PHYCLKMUX (1 << 11)
+#define CFGCHIP2_PHYPWRDN (1 << 10)
+#define CFGCHIP2_OTGPWRDN (1 << 9)
+#define CFGCHIP2_DATPOL (1 << 8)
+#define CFGCHIP2_USB1SUSPENDM (1 << 7)
+#define CFGCHIP2_PHY_PLLON (1 << 6) /* override PLL suspend */
+#define CFGCHIP2_SESENDEN (1 << 5) /* Vsess_end comparator */
+#define CFGCHIP2_VBDTCTEN (1 << 4) /* Vbus comparator */
+#define CFGCHIP2_REFFREQ (0xf << 0)
+#define CFGCHIP2_REFFREQ_12MHZ (1 << 0)
+#define CFGCHIP2_REFFREQ_24MHZ (2 << 0)
+#define CFGCHIP2_REFFREQ_48MHZ (3 << 0)
+
+struct da8xx_ohci_root_hub;
+
+typedef void (*da8xx_ocic_handler_t)(struct da8xx_ohci_root_hub *hub,
+ unsigned port);
+
+/* Passed as the platform data to the OHCI driver */
+struct da8xx_ohci_root_hub {
+ /* Switch the port power on/off */
+ int (*set_power)(unsigned port, int on);
+ /* Read the port power status */
+ int (*get_power)(unsigned port);
+ /* Read the port over-current indicator */
+ int (*get_oci)(unsigned port);
+ /* Over-current indicator change notification (pass NULL to disable) */
+ int (*ocic_notify)(da8xx_ocic_handler_t handler);
+
+ /* Time from power on to power good (in 2 ms units) */
+ u8 potpgt;
+};
+
+void davinci_setup_usb(unsigned mA, unsigned potpgt_ms);
+
+#endif /* ifndef __ASM_ARCH_USB_H */
diff --git a/arch/arm/mach-davinci/include/mach/vmalloc.h b/arch/arm/mach-davinci/include/mach/vmalloc.h
new file mode 100644
index 00000000..d49646a8
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/vmalloc.h
@@ -0,0 +1,14 @@
+/*
+ * DaVinci vmalloc definitions
+ *
+ * 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 <mach/hardware.h>
+
+/* Allow vmalloc range until the IO virtual range minus a 2M "hole" */
+#define VMALLOC_END (IO_VIRT - (2<<20))
diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c
new file mode 100644
index 00000000..8ea60a8b
--- /dev/null
+++ b/arch/arm/mach-davinci/io.c
@@ -0,0 +1,48 @@
+/*
+ * 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/io.h>
+
+#include <asm/tlb.h>
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+
+/*
+ * Intercept ioremap() requests for addresses in our fixed mapping regions.
+ */
+void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type)
+{
+ struct map_desc *desc = davinci_soc_info.io_desc;
+ int desc_num = davinci_soc_info.io_desc_num;
+ int i;
+
+ for (i = 0; i < desc_num; i++, desc++) {
+ unsigned long iophys = __pfn_to_phys(desc->pfn);
+ unsigned long iosize = desc->length;
+
+ if (p >= iophys && (p + size) <= (iophys + iosize))
+ return __io(desc->virtual + p - iophys);
+ }
+
+ return __arm_ioremap_caller(p, size, type,
+ __builtin_return_address(0));
+}
+EXPORT_SYMBOL(davinci_ioremap);
+
+void davinci_iounmap(volatile void __iomem *addr)
+{
+ unsigned long virt = (unsigned long)addr;
+
+ if (virt >= VMALLOC_START && virt < VMALLOC_END)
+ __iounmap(addr);
+}
+EXPORT_SYMBOL(davinci_iounmap);
diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
new file mode 100644
index 00000000..952dc126
--- /dev/null
+++ b/arch/arm/mach-davinci/irq.c
@@ -0,0 +1,117 @@
+/*
+ * 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 <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/cputype.h>
+#include <mach/common.h>
+#include <asm/mach/irq.h>
+
+#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 void davinci_irq_writel(unsigned long value, int offset)
+{
+ __raw_writel(value, davinci_intc_base + offset);
+}
+
+static __init void
+davinci_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
+{
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+
+ gc = irq_alloc_generic_chip("AINTC", 1, irq_start, base, handle_edge_irq);
+ if (!gc) {
+ pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n",
+ __func__, irq_start);
+ return;
+ }
+
+ ct = gc->chip_types;
+ ct->chip.irq_ack = irq_gc_ack_set_bit;
+ ct->chip.irq_mask = irq_gc_mask_clr_bit;
+ ct->chip.irq_unmask = irq_gc_mask_set_bit;
+
+ ct->regs.ack = IRQ_REG0_OFFSET;
+ ct->regs.mask = IRQ_ENT_REG0_OFFSET;
+ irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+}
+
+/* ARM Interrupt Controller Initialization */
+void __init davinci_irq_init(void)
+{
+ unsigned i, j;
+ const u8 *davinci_def_priorities = davinci_soc_info.intc_irq_prios;
+
+ davinci_intc_type = DAVINCI_INTC_TYPE_AINTC;
+ davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_4K);
+ if (WARN_ON(!davinci_intc_base))
+ return;
+
+ /* 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) {
+ u32 pri;
+
+ for (j = 0, pri = 0; j < 32; j += 4, davinci_def_priorities++)
+ pri |= (*davinci_def_priorities & 0x07) << j;
+ davinci_irq_writel(pri, i);
+ }
+
+ for (i = 0, j = 0; i < davinci_soc_info.intc_irq_num; i += 32, j += 0x04)
+ davinci_alloc_gc(davinci_intc_base + j, i, 32);
+
+ irq_set_handler(IRQ_TINT1_TINT34, handle_level_irq);
+}
diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c
new file mode 100644
index 00000000..f34a8dcd
--- /dev/null
+++ b/arch/arm/mach-davinci/mux.c
@@ -0,0 +1,113 @@
+/*
+ * Utility to set the DAVINCI MUX register from a table in mux.h
+ *
+ * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * Based on linux/arch/arm/plat-omap/mux.c:
+ * Copyright (C) 2003 - 2005 Nokia Corporation
+ *
+ * Written by Tony Lindgren
+ *
+ * 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.
+ *
+ * Copyright (C) 2008 Texas Instruments.
+ */
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+#include <mach/mux.h>
+#include <mach/common.h>
+
+static void __iomem *pinmux_base;
+
+/*
+ * Sets the DAVINCI MUX register based on the table
+ */
+int __init_or_module davinci_cfg_reg(const unsigned long index)
+{
+ static DEFINE_SPINLOCK(mux_spin_lock);
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ unsigned long flags;
+ const struct mux_config *cfg;
+ unsigned int reg_orig = 0, reg = 0;
+ unsigned int mask, warn = 0;
+
+ if (WARN_ON(!soc_info->pinmux_pins))
+ return -ENODEV;
+
+ if (!pinmux_base) {
+ pinmux_base = ioremap(soc_info->pinmux_base, SZ_4K);
+ if (WARN_ON(!pinmux_base))
+ return -ENOMEM;
+ }
+
+ if (index >= soc_info->pinmux_pins_num) {
+ printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
+ index, soc_info->pinmux_pins_num);
+ dump_stack();
+ return -ENODEV;
+ }
+
+ cfg = &soc_info->pinmux_pins[index];
+
+ if (cfg->name == NULL) {
+ printk(KERN_ERR "No entry for the specified index\n");
+ return -ENODEV;
+ }
+
+ /* Update the mux register in question */
+ if (cfg->mask) {
+ unsigned tmp1, tmp2;
+
+ spin_lock_irqsave(&mux_spin_lock, flags);
+ reg_orig = __raw_readl(pinmux_base + cfg->mux_reg);
+
+ mask = (cfg->mask << cfg->mask_offset);
+ tmp1 = reg_orig & mask;
+ reg = reg_orig & ~mask;
+
+ tmp2 = (cfg->mode << cfg->mask_offset);
+ reg |= tmp2;
+
+ if (tmp1 != tmp2)
+ warn = 1;
+
+ __raw_writel(reg, pinmux_base + cfg->mux_reg);
+ spin_unlock_irqrestore(&mux_spin_lock, flags);
+ }
+
+ if (warn) {
+#ifdef CONFIG_DAVINCI_MUX_WARNINGS
+ printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);
+#endif
+ }
+
+#ifdef CONFIG_DAVINCI_MUX_DEBUG
+ if (cfg->debug || warn) {
+ printk(KERN_WARNING "MUX: Setting register %s\n", cfg->name);
+ printk(KERN_WARNING " %s (0x%08x) = 0x%08x -> 0x%08x\n",
+ cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);
+ }
+#endif
+
+ return 0;
+}
+EXPORT_SYMBOL(davinci_cfg_reg);
+
+int __init_or_module davinci_cfg_reg_list(const short pins[])
+{
+ int i, error = -EINVAL;
+
+ if (pins)
+ for (i = 0; pins[i] >= 0; i++) {
+ error = davinci_cfg_reg(pins[i]);
+ if (error)
+ break;
+ }
+
+ return error;
+}
diff --git a/arch/arm/mach-davinci/mux.h b/arch/arm/mach-davinci/mux.h
new file mode 100644
index 00000000..5aad1e7d
--- /dev/null
+++ b/arch/arm/mach-davinci/mux.h
@@ -0,0 +1,51 @@
+/*
+ * Pin-multiplex helper macros for TI DaVinci family devices
+ *
+ * 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.
+ *
+ * Copyright (C) 2008 Texas Instruments.
+ */
+#ifndef _MACH_DAVINCI_MUX_H_
+#define _MACH_DAVINCI_MUX_H_
+
+#include <mach/mux.h>
+
+#define MUX_CFG(soc, desc, muxreg, mode_offset, mode_mask, mux_mode, dbg)\
+[soc##_##desc] = { \
+ .name = #desc, \
+ .debug = dbg, \
+ .mux_reg_name = "PINMUX"#muxreg, \
+ .mux_reg = PINMUX(muxreg), \
+ .mask_offset = mode_offset, \
+ .mask = mode_mask, \
+ .mode = mux_mode, \
+ },
+
+#define INT_CFG(soc, desc, mode_offset, mode_mask, mux_mode, dbg) \
+[soc##_##desc] = { \
+ .name = #desc, \
+ .debug = dbg, \
+ .mux_reg_name = "INTMUX", \
+ .mux_reg = INTMUX, \
+ .mask_offset = mode_offset, \
+ .mask = mode_mask, \
+ .mode = mux_mode, \
+ },
+
+#define EVT_CFG(soc, desc, mode_offset, mode_mask, mux_mode, dbg) \
+[soc##_##desc] = { \
+ .name = #desc, \
+ .debug = dbg, \
+ .mux_reg_name = "EVTMUX", \
+ .mux_reg = EVTMUX, \
+ .mask_offset = mode_offset, \
+ .mask = mode_mask, \
+ .mode = mux_mode, \
+ },
+
+#endif /* _MACH_DAVINCI_MUX_H */
diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c
new file mode 100644
index 00000000..04c49f75
--- /dev/null
+++ b/arch/arm/mach-davinci/pm.c
@@ -0,0 +1,159 @@
+/*
+ * DaVinci Power Management Routines
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/pm.h>
+#include <linux/suspend.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+
+#include <asm/cacheflush.h>
+#include <asm/delay.h>
+#include <asm/io.h>
+
+#include <mach/da8xx.h>
+#include <mach/sram.h>
+#include <mach/pm.h>
+
+#include "clock.h"
+
+#define DEEPSLEEP_SLEEPCOUNT_MASK 0xFFFF
+
+static void (*davinci_sram_suspend) (struct davinci_pm_config *);
+static struct davinci_pm_config *pdata;
+
+static void davinci_sram_push(void *dest, void *src, unsigned int size)
+{
+ memcpy(dest, src, size);
+ flush_icache_range((unsigned long)dest, (unsigned long)(dest + size));
+}
+
+static void davinci_pm_suspend(void)
+{
+ unsigned val;
+
+ if (pdata->cpupll_reg_base != pdata->ddrpll_reg_base) {
+
+ /* Switch CPU PLL to bypass mode */
+ val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
+ __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+
+ udelay(PLL_BYPASS_TIME);
+
+ /* Powerdown CPU PLL */
+ val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val |= PLLCTL_PLLPWRDN;
+ __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+ }
+
+ /* Configure sleep count in deep sleep register */
+ val = __raw_readl(pdata->deepsleep_reg);
+ val &= ~DEEPSLEEP_SLEEPCOUNT_MASK,
+ val |= pdata->sleepcount;
+ __raw_writel(val, pdata->deepsleep_reg);
+
+ /* System goes to sleep in this call */
+ davinci_sram_suspend(pdata);
+
+ if (pdata->cpupll_reg_base != pdata->ddrpll_reg_base) {
+
+ /* put CPU PLL in reset */
+ val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val &= ~PLLCTL_PLLRST;
+ __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+
+ /* put CPU PLL in power down */
+ val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val &= ~PLLCTL_PLLPWRDN;
+ __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+
+ /* wait for CPU PLL reset */
+ udelay(PLL_RESET_TIME);
+
+ /* bring CPU PLL out of reset */
+ val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val |= PLLCTL_PLLRST;
+ __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+
+ /* Wait for CPU PLL to lock */
+ udelay(PLL_LOCK_TIME);
+
+ /* Remove CPU PLL from bypass mode */
+ val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val &= ~PLLCTL_PLLENSRC;
+ val |= PLLCTL_PLLEN;
+ __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+ }
+}
+
+static int davinci_pm_enter(suspend_state_t state)
+{
+ int ret = 0;
+
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ case PM_SUSPEND_MEM:
+ davinci_pm_suspend();
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct platform_suspend_ops davinci_pm_ops = {
+ .enter = davinci_pm_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+static int __init davinci_pm_probe(struct platform_device *pdev)
+{
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&pdev->dev, "cannot get platform data\n");
+ return -ENOENT;
+ }
+
+ davinci_sram_suspend = sram_alloc(davinci_cpu_suspend_sz, NULL);
+ if (!davinci_sram_suspend) {
+ dev_err(&pdev->dev, "cannot allocate SRAM memory\n");
+ return -ENOMEM;
+ }
+
+ davinci_sram_push(davinci_sram_suspend, davinci_cpu_suspend,
+ davinci_cpu_suspend_sz);
+
+ suspend_set_ops(&davinci_pm_ops);
+
+ return 0;
+}
+
+static int __exit davinci_pm_remove(struct platform_device *pdev)
+{
+ sram_free(davinci_sram_suspend, davinci_cpu_suspend_sz);
+ return 0;
+}
+
+static struct platform_driver davinci_pm_driver = {
+ .driver = {
+ .name = "pm-davinci",
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(davinci_pm_remove),
+};
+
+static int __init davinci_pm_init(void)
+{
+ return platform_driver_probe(&davinci_pm_driver, davinci_pm_probe);
+}
+late_initcall(davinci_pm_init);
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
new file mode 100644
index 00000000..a4158040
--- /dev/null
+++ b/arch/arm/mach-davinci/psc.c
@@ -0,0 +1,100 @@
+/*
+ * 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/init.h>
+#include <linux/io.h>
+
+#include <mach/cputype.h>
+#include <mach/psc.h>
+
+/* Return nonzero iff the domain's clock is active */
+int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
+{
+ void __iomem *psc_base;
+ u32 mdstat;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
+ pr_warning("PSC: Bad psc data: 0x%x[%d]\n",
+ (int)soc_info->psc_bases, ctlr);
+ return 0;
+ }
+
+ psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
+ mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
+ iounmap(psc_base);
+
+ /* if clocked, state can be "Enable" or "SyncReset" */
+ return mdstat & BIT(12);
+}
+
+/* Enable or disable a PSC domain */
+void davinci_psc_config(unsigned int domain, unsigned int ctlr,
+ unsigned int id, u32 next_state)
+{
+ u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl;
+ void __iomem *psc_base;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
+ pr_warning("PSC: Bad psc data: 0x%x[%d]\n",
+ (int)soc_info->psc_bases, ctlr);
+ return;
+ }
+
+ psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
+
+ mdctl = __raw_readl(psc_base + MDCTL + 4 * id);
+ mdctl &= ~MDSTAT_STATE_MASK;
+ mdctl |= next_state;
+ __raw_writel(mdctl, psc_base + MDCTL + 4 * id);
+
+ pdstat = __raw_readl(psc_base + PDSTAT);
+ if ((pdstat & 0x00000001) == 0) {
+ pdctl1 = __raw_readl(psc_base + PDCTL1);
+ pdctl1 |= 0x1;
+ __raw_writel(pdctl1, psc_base + PDCTL1);
+
+ ptcmd = 1 << domain;
+ __raw_writel(ptcmd, psc_base + PTCMD);
+
+ do {
+ epcpr = __raw_readl(psc_base + EPCPR);
+ } while ((((epcpr >> domain) & 1) == 0));
+
+ pdctl1 = __raw_readl(psc_base + PDCTL1);
+ pdctl1 |= 0x100;
+ __raw_writel(pdctl1, psc_base + PDCTL1);
+ } else {
+ ptcmd = 1 << domain;
+ __raw_writel(ptcmd, psc_base + PTCMD);
+ }
+
+ do {
+ ptstat = __raw_readl(psc_base + PTSTAT);
+ } while (!(((ptstat >> domain) & 1) == 0));
+
+ do {
+ mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
+ } while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
+
+ iounmap(psc_base);
+}
diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c
new file mode 100644
index 00000000..1875740f
--- /dev/null
+++ b/arch/arm/mach-davinci/serial.c
@@ -0,0 +1,115 @@
+/*
+ * 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 <linux/io.h>
+
+#include <mach/serial.h>
+#include <mach/cputype.h>
+
+static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
+ int offset)
+{
+ offset <<= up->regshift;
+
+ WARN_ONCE(!up->membase, "unmapped read: uart[%d]\n", offset);
+
+ return (unsigned int)__raw_readl(up->membase + offset);
+}
+
+static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
+ int value)
+{
+ offset <<= p->regshift;
+
+ WARN_ONCE(!p->membase, "unmapped write: uart[%d]\n", offset);
+
+ __raw_writel(value, p->membase + offset);
+}
+
+static void __init davinci_serial_reset(struct plat_serial8250_port *p)
+{
+ unsigned int pwremu = 0;
+
+ serial_write_reg(p, UART_IER, 0); /* disable all interrupts */
+
+ /* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */
+ serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
+ mdelay(10);
+
+ pwremu |= (0x3 << 13);
+ pwremu |= 0x1;
+ serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
+
+ if (cpu_is_davinci_dm646x())
+ serial_write_reg(p, UART_DM646X_SCR,
+ UART_DM646X_SCR_TX_WATERMARK);
+}
+
+int __init davinci_serial_init(struct davinci_uart_config *info)
+{
+ int i;
+ char name[16];
+ struct clk *uart_clk;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ struct device *dev = &soc_info->serial_dev->dev;
+ struct plat_serial8250_port *p = dev->platform_data;
+
+ /*
+ * Make sure the serial ports are muxed on at this point.
+ * You have to mux them off in device drivers later on if not needed.
+ */
+ for (i = 0; p->flags; i++, p++) {
+ if (!(info->enabled_uarts & (1 << i)))
+ continue;
+
+ sprintf(name, "uart%d", i);
+ uart_clk = clk_get(dev, name);
+ if (IS_ERR(uart_clk)) {
+ printk(KERN_ERR "%s:%d: failed to get UART%d clock\n",
+ __func__, __LINE__, i);
+ continue;
+ }
+
+ clk_enable(uart_clk);
+ p->uartclk = clk_get_rate(uart_clk);
+
+ if (!p->membase && p->mapbase) {
+ p->membase = ioremap(p->mapbase, SZ_4K);
+
+ if (p->membase)
+ p->flags &= ~UPF_IOREMAP;
+ else
+ pr_err("uart regs ioremap failed\n");
+ }
+
+ if (p->membase && p->type != PORT_AR7)
+ davinci_serial_reset(p);
+ }
+
+ return platform_device_register(soc_info->serial_dev);
+}
diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S
new file mode 100644
index 00000000..5f1e045a
--- /dev/null
+++ b/arch/arm/mach-davinci/sleep.S
@@ -0,0 +1,228 @@
+/*
+ * (C) Copyright 2009, Texas Instruments, Inc. http://www.ti.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* replicated define because linux/bitops.h cannot be included in assembly */
+#define BIT(nr) (1 << (nr))
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/psc.h>
+#include <mach/memory.h>
+
+#include "clock.h"
+
+/* Arbitrary, hardware currently does not update PHYRDY correctly */
+#define PHYRDY_CYCLES 0x1000
+
+/* Assume 25 MHz speed for the cycle conversions since PLLs are bypassed */
+#define PLL_BYPASS_CYCLES (PLL_BYPASS_TIME * 25)
+#define PLL_RESET_CYCLES (PLL_RESET_TIME * 25)
+#define PLL_LOCK_CYCLES (PLL_LOCK_TIME * 25)
+
+#define DEEPSLEEP_SLEEPENABLE_BIT BIT(31)
+
+ .text
+/*
+ * Move DaVinci into deep sleep state
+ *
+ * Note: This code is copied to internal SRAM by PM code. When the DaVinci
+ * wakes up it continues execution at the point it went to sleep.
+ * Register Usage:
+ * r0: contains virtual base for DDR2 controller
+ * r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
+ * r2: contains PSC number for DDR2
+ * r3: contains virtual base DDR2 PLL controller
+ * r4: contains virtual address of the DEEPSLEEP register
+ */
+ENTRY(davinci_cpu_suspend)
+ stmfd sp!, {r0-r12, lr} @ save registers on stack
+
+ ldr ip, CACHE_FLUSH
+ blx ip
+
+ ldmia r0, {r0-r4}
+
+ /*
+ * Switch DDR to self-refresh mode.
+ */
+
+ /* calculate SDRCR address */
+ ldr ip, [r0, #DDR2_SDRCR_OFFSET]
+ bic ip, ip, #DDR2_SRPD_BIT
+ orr ip, ip, #DDR2_LPMODEN_BIT
+ str ip, [r0, #DDR2_SDRCR_OFFSET]
+
+ ldr ip, [r0, #DDR2_SDRCR_OFFSET]
+ orr ip, ip, #DDR2_MCLKSTOPEN_BIT
+ str ip, [r0, #DDR2_SDRCR_OFFSET]
+
+ mov ip, #PHYRDY_CYCLES
+1: subs ip, ip, #0x1
+ bne 1b
+
+ /* Disable DDR2 LPSC */
+ mov r7, r0
+ mov r0, #0x2
+ bl davinci_ddr_psc_config
+ mov r0, r7
+
+ /* Disable clock to DDR PHY */
+ ldr ip, [r3, #PLLDIV1]
+ bic ip, ip, #PLLDIV_EN
+ str ip, [r3, #PLLDIV1]
+
+ /* Put the DDR PLL in bypass and power down */
+ ldr ip, [r3, #PLLCTL]
+ bic ip, ip, #PLLCTL_PLLENSRC
+ bic ip, ip, #PLLCTL_PLLEN
+ str ip, [r3, #PLLCTL]
+
+ /* Wait for PLL to switch to bypass */
+ mov ip, #PLL_BYPASS_CYCLES
+2: subs ip, ip, #0x1
+ bne 2b
+
+ /* Power down the PLL */
+ ldr ip, [r3, #PLLCTL]
+ orr ip, ip, #PLLCTL_PLLPWRDN
+ str ip, [r3, #PLLCTL]
+
+ /* Go to deep sleep */
+ ldr ip, [r4]
+ orr ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
+ /* System goes to sleep beyond after this instruction */
+ str ip, [r4]
+
+ /* Wake up from sleep */
+
+ /* Clear sleep enable */
+ ldr ip, [r4]
+ bic ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
+ str ip, [r4]
+
+ /* initialize the DDR PLL controller */
+
+ /* Put PLL in reset */
+ ldr ip, [r3, #PLLCTL]
+ bic ip, ip, #PLLCTL_PLLRST
+ str ip, [r3, #PLLCTL]
+
+ /* Clear PLL power down */
+ ldr ip, [r3, #PLLCTL]
+ bic ip, ip, #PLLCTL_PLLPWRDN
+ str ip, [r3, #PLLCTL]
+
+ mov ip, #PLL_RESET_CYCLES
+3: subs ip, ip, #0x1
+ bne 3b
+
+ /* Bring PLL out of reset */
+ ldr ip, [r3, #PLLCTL]
+ orr ip, ip, #PLLCTL_PLLRST
+ str ip, [r3, #PLLCTL]
+
+ /* Wait for PLL to lock (assume prediv = 1, 25MHz OSCIN) */
+ mov ip, #PLL_LOCK_CYCLES
+4: subs ip, ip, #0x1
+ bne 4b
+
+ /* Remove PLL from bypass mode */
+ ldr ip, [r3, #PLLCTL]
+ bic ip, ip, #PLLCTL_PLLENSRC
+ orr ip, ip, #PLLCTL_PLLEN
+ str ip, [r3, #PLLCTL]
+
+ /* Start 2x clock to DDR2 */
+
+ ldr ip, [r3, #PLLDIV1]
+ orr ip, ip, #PLLDIV_EN
+ str ip, [r3, #PLLDIV1]
+
+ /* Enable VCLK */
+
+ /* Enable DDR2 LPSC */
+ mov r7, r0
+ mov r0, #0x3
+ bl davinci_ddr_psc_config
+ mov r0, r7
+
+ /* clear MCLKSTOPEN */
+
+ ldr ip, [r0, #DDR2_SDRCR_OFFSET]
+ bic ip, ip, #DDR2_MCLKSTOPEN_BIT
+ str ip, [r0, #DDR2_SDRCR_OFFSET]
+
+ ldr ip, [r0, #DDR2_SDRCR_OFFSET]
+ bic ip, ip, #DDR2_LPMODEN_BIT
+ str ip, [r0, #DDR2_SDRCR_OFFSET]
+
+ /* Restore registers and return */
+ ldmfd sp!, {r0-r12, pc}
+
+ENDPROC(davinci_cpu_suspend)
+
+/*
+ * Disables or Enables DDR2 LPSC
+ * Register Usage:
+ * r0: Enable or Disable LPSC r0 = 0x3 => Enable, r0 = 0x2 => Disable LPSC
+ * r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
+ * r2: contains PSC number for DDR2
+ */
+ENTRY(davinci_ddr_psc_config)
+ /* Set next state in mdctl for DDR2 */
+ mov r6, #MDCTL
+ add r6, r6, r2, lsl #2
+ ldr ip, [r1, r6]
+ bic ip, ip, #MDSTAT_STATE_MASK
+ orr ip, ip, r0
+ str ip, [r1, r6]
+
+ /* Enable the Power Domain Transition Command */
+ ldr ip, [r1, #PTCMD]
+ orr ip, ip, #0x1
+ str ip, [r1, #PTCMD]
+
+ /* Check for Transition Complete (PTSTAT) */
+ptstat_done:
+ ldr ip, [r1, #PTSTAT]
+ and ip, ip, #0x1
+ cmp ip, #0x0
+ bne ptstat_done
+
+ /* Check for DDR2 clock disable completion; */
+ mov r6, #MDSTAT
+ add r6, r6, r2, lsl #2
+ddr2clk_stop_done:
+ ldr ip, [r1, r6]
+ and ip, ip, #MDSTAT_STATE_MASK
+ cmp ip, r0
+ bne ddr2clk_stop_done
+
+ mov pc, lr
+ENDPROC(davinci_ddr_psc_config)
+
+CACHE_FLUSH:
+#ifdef CONFIG_CPU_V6
+ .word v6_flush_kern_cache_all
+#else
+ .word arm926_flush_kern_cache_all
+#endif
+
+ENTRY(davinci_cpu_suspend_sz)
+ .word . - davinci_cpu_suspend
+ENDPROC(davinci_cpu_suspend_sz)
diff --git a/arch/arm/mach-davinci/sram.c b/arch/arm/mach-davinci/sram.c
new file mode 100644
index 00000000..db0f7787
--- /dev/null
+++ b/arch/arm/mach-davinci/sram.c
@@ -0,0 +1,71 @@
+/*
+ * mach-davinci/sram.c - DaVinci simple SRAM allocator
+ *
+ * Copyright (C) 2009 David Brownell
+ *
+ * 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/init.h>
+#include <linux/genalloc.h>
+
+#include <mach/common.h>
+#include <mach/sram.h>
+
+static struct gen_pool *sram_pool;
+
+void *sram_alloc(size_t len, dma_addr_t *dma)
+{
+ unsigned long vaddr;
+ dma_addr_t dma_base = davinci_soc_info.sram_dma;
+
+ if (dma)
+ *dma = 0;
+ if (!sram_pool || (dma && !dma_base))
+ return NULL;
+
+ vaddr = gen_pool_alloc(sram_pool, len);
+ if (!vaddr)
+ return NULL;
+
+ if (dma)
+ *dma = dma_base + (vaddr - SRAM_VIRT);
+ return (void *)vaddr;
+
+}
+EXPORT_SYMBOL(sram_alloc);
+
+void sram_free(void *addr, size_t len)
+{
+ gen_pool_free(sram_pool, (unsigned long) addr, len);
+}
+EXPORT_SYMBOL(sram_free);
+
+
+/*
+ * REVISIT This supports CPU and DMA access to/from SRAM, but it
+ * doesn't (yet?) support some other notable uses of SRAM: as TCM
+ * for data and/or instructions; and holding code needed to enter
+ * and exit suspend states (while DRAM can't be used).
+ */
+static int __init sram_init(void)
+{
+ unsigned len = davinci_soc_info.sram_len;
+ int status = 0;
+
+ if (len) {
+ len = min_t(unsigned, len, SRAM_SIZE);
+ sram_pool = gen_pool_create(ilog2(SRAM_GRANULARITY), -1);
+ if (!sram_pool)
+ status = -ENOMEM;
+ }
+ if (sram_pool)
+ status = gen_pool_add(sram_pool, SRAM_VIRT, len, -1);
+ WARN_ON(status < 0);
+ return status;
+}
+core_initcall(sram_init);
+
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
new file mode 100644
index 00000000..e1969ce9
--- /dev/null
+++ b/arch/arm/mach-davinci/time.c
@@ -0,0 +1,474 @@
+/*
+ * 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/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <mach/cputype.h>
+#include <mach/time.h>
+#include "clock.h"
+
+static struct clock_event_device clockevent_davinci;
+static unsigned int davinci_clock_tick_rate;
+
+/*
+ * This driver configures the 2 64-bit count-up timers as 4 independent
+ * 32-bit count-up timers used as follows:
+ */
+
+enum {
+ TID_CLOCKEVENT,
+ TID_CLOCKSOURCE,
+};
+
+/* 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
+
+/* Offsets of the 8 compare registers */
+#define CMP12_0 0x60
+#define CMP12_1 0x64
+#define CMP12_2 0x68
+#define CMP12_3 0x6c
+#define CMP12_4 0x70
+#define CMP12_5 0x74
+#define CMP12_6 0x78
+#define CMP12_7 0x7c
+
+/* 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 flags;
+ void __iomem *base;
+ unsigned long tim_off;
+ unsigned long prd_off;
+ unsigned long enamode_shift;
+ struct irqaction irqaction;
+};
+static struct timer_s timers[];
+
+/* values for 'opts' field of struct timer_s */
+#define TIMER_OPTS_DISABLED 0x01
+#define TIMER_OPTS_ONESHOT 0x02
+#define TIMER_OPTS_PERIODIC 0x04
+#define TIMER_OPTS_STATE_MASK 0x07
+
+#define TIMER_OPTS_USE_COMPARE 0x80000000
+#define USING_COMPARE(t) ((t)->opts & TIMER_OPTS_USE_COMPARE)
+
+static char *id_to_name[] = {
+ [T0_BOT] = "timer0_0",
+ [T0_TOP] = "timer0_1",
+ [T1_BOT] = "timer1_0",
+ [T1_TOP] = "timer1_1",
+};
+
+static int timer32_config(struct timer_s *t)
+{
+ u32 tcr;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ if (USING_COMPARE(t)) {
+ struct davinci_timer_instance *dtip =
+ soc_info->timer_info->timers;
+ int event_timer = ID_TO_TIMER(timers[TID_CLOCKEVENT].id);
+
+ /*
+ * Next interrupt should be the current time reg value plus
+ * the new period (using 32-bit unsigned addition/wrapping
+ * to 0 on overflow). This assumes that the clocksource
+ * is setup to count to 2^32-1 before wrapping around to 0.
+ */
+ __raw_writel(__raw_readl(t->base + t->tim_off) + t->period,
+ t->base + dtip[event_timer].cmp_off);
+ } else {
+ tcr = __raw_readl(t->base + TCR);
+
+ /* disable timer */
+ tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift);
+ __raw_writel(tcr, t->base + TCR);
+
+ /* reset counter to zero, set new period */
+ __raw_writel(0, t->base + t->tim_off);
+ __raw_writel(t->period, t->base + t->prd_off);
+
+ /* 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;
+
+ __raw_writel(tcr, t->base + TCR);
+ }
+ return 0;
+}
+
+static inline u32 timer32_read(struct timer_s *t)
+{
+ return __raw_readl(t->base + t->tim_off);
+}
+
+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)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ struct davinci_timer_instance *dtip = soc_info->timer_info->timers;
+ void __iomem *base[2];
+ int i;
+
+ /* Global init of each 64-bit timer as a whole */
+ for(i=0; i<2; i++) {
+ u32 tgcr;
+
+ base[i] = ioremap(dtip[i].base, SZ_4K);
+ if (WARN_ON(!base[i]))
+ continue;
+
+ /* Disabled, Internal clock source */
+ __raw_writel(0, base[i] + TCR);
+
+ /* reset both timers, no pre-scaler for timer34 */
+ tgcr = 0;
+ __raw_writel(tgcr, base[i] + TGCR);
+
+ /* Set both timers to unchained 32-bit */
+ tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT;
+ __raw_writel(tgcr, base[i] + TGCR);
+
+ /* Unreset timers */
+ tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
+ (TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
+ __raw_writel(tgcr, base[i] + TGCR);
+
+ /* Init both counters to zero */
+ __raw_writel(0, base[i] + TIM12);
+ __raw_writel(0, base[i] + TIM34);
+ }
+
+ /* Init of each timer as a 32-bit timer */
+ for (i=0; i< ARRAY_SIZE(timers); i++) {
+ struct timer_s *t = &timers[i];
+ int timer = ID_TO_TIMER(t->id);
+ u32 irq;
+
+ t->base = base[timer];
+ if (!t->base)
+ continue;
+
+ if (IS_TIMER_BOT(t->id)) {
+ t->enamode_shift = 6;
+ t->tim_off = TIM12;
+ t->prd_off = PRD12;
+ irq = dtip[timer].bottom_irq;
+ } else {
+ t->enamode_shift = 22;
+ t->tim_off = TIM34;
+ t->prd_off = PRD34;
+ irq = dtip[timer].top_irq;
+ }
+
+ /* Register interrupt */
+ t->irqaction.name = t->name;
+ t->irqaction.dev_id = (void *)t;
+
+ if (t->irqaction.handler != NULL) {
+ irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq;
+ setup_irq(irq, &t->irqaction);
+ }
+ }
+}
+
+/*
+ * clocksource
+ */
+static cycle_t read_cycles(struct clocksource *cs)
+{
+ struct timer_s *t = &timers[TID_CLOCKSOURCE];
+
+ return (cycles_t)timer32_read(t);
+}
+
+/*
+ * Kernel assumes that sched_clock can be called early but may not have
+ * things ready yet.
+ */
+static cycle_t read_dummy(struct clocksource *cs)
+{
+ return 0;
+}
+
+
+static struct clocksource clocksource_davinci = {
+ .rating = 300,
+ .read = read_dummy,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/*
+ * Overwrite weak default sched_clock with something more precise
+ */
+unsigned long long notrace sched_clock(void)
+{
+ const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci);
+
+ return clocksource_cyc2ns(cyc, clocksource_davinci.mult,
+ clocksource_davinci.shift);
+}
+
+/*
+ * 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 = davinci_clock_tick_rate / (HZ);
+ t->opts &= ~TIMER_OPTS_STATE_MASK;
+ t->opts |= TIMER_OPTS_PERIODIC;
+ timer32_config(t);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ t->opts &= ~TIMER_OPTS_STATE_MASK;
+ t->opts |= TIMER_OPTS_ONESHOT;
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ t->opts &= ~TIMER_OPTS_STATE_MASK;
+ t->opts |= TIMER_OPTS_DISABLED;
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device clockevent_davinci = {
+ .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)
+{
+ struct clk *timer_clk;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ unsigned int clockevent_id;
+ unsigned int clocksource_id;
+ static char err[] __initdata = KERN_ERR
+ "%s: can't register clocksource!\n";
+ int i;
+
+ clockevent_id = soc_info->timer_info->clockevent_id;
+ clocksource_id = soc_info->timer_info->clocksource_id;
+
+ timers[TID_CLOCKEVENT].id = clockevent_id;
+ timers[TID_CLOCKSOURCE].id = clocksource_id;
+
+ /*
+ * If using same timer for both clock events & clocksource,
+ * a compare register must be used to generate an event interrupt.
+ * This is equivalent to a oneshot timer only (not periodic).
+ */
+ if (clockevent_id == clocksource_id) {
+ struct davinci_timer_instance *dtip =
+ soc_info->timer_info->timers;
+ int event_timer = ID_TO_TIMER(clockevent_id);
+
+ /* Only bottom timers can use compare regs */
+ if (IS_TIMER_TOP(clockevent_id))
+ pr_warning("davinci_timer_init: Invalid use"
+ " of system timers. Results unpredictable.\n");
+ else if ((dtip[event_timer].cmp_off == 0)
+ || (dtip[event_timer].cmp_irq == 0))
+ pr_warning("davinci_timer_init: Invalid timer instance"
+ " setup. Results unpredictable.\n");
+ else {
+ timers[TID_CLOCKEVENT].opts |= TIMER_OPTS_USE_COMPARE;
+ clockevent_davinci.features = CLOCK_EVT_FEAT_ONESHOT;
+ }
+ }
+
+ timer_clk = clk_get(NULL, "timer0");
+ BUG_ON(IS_ERR(timer_clk));
+ clk_enable(timer_clk);
+
+ /* init timer hw */
+ timer_init();
+
+ davinci_clock_tick_rate = clk_get_rate(timer_clk);
+
+ /* setup clocksource */
+ clocksource_davinci.read = read_cycles;
+ clocksource_davinci.name = id_to_name[clocksource_id];
+ if (clocksource_register_hz(&clocksource_davinci,
+ davinci_clock_tick_rate))
+ printk(err, clocksource_davinci.name);
+
+ /* setup clockevent */
+ clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id];
+ clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC,
+ clockevent_davinci.shift);
+ clockevent_davinci.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_davinci);
+ clockevent_davinci.min_delta_ns = 50000; /* 50 usec */
+
+ clockevent_davinci.cpumask = cpumask_of(0);
+ clockevents_register_device(&clockevent_davinci);
+
+ for (i=0; i< ARRAY_SIZE(timers); i++)
+ timer32_config(&timers[i]);
+}
+
+struct sys_timer davinci_timer = {
+ .init = davinci_timer_init,
+};
+
+
+/* reset board using watchdog timer */
+void davinci_watchdog_reset(struct platform_device *pdev)
+{
+ u32 tgcr, wdtcr;
+ void __iomem *base;
+ struct clk *wd_clk;
+
+ base = ioremap(pdev->resource[0].start, SZ_4K);
+ if (WARN_ON(!base))
+ return;
+
+ wd_clk = clk_get(&pdev->dev, NULL);
+ if (WARN_ON(IS_ERR(wd_clk)))
+ return;
+ clk_enable(wd_clk);
+
+ /* disable, internal clock source */
+ __raw_writel(0, base + TCR);
+
+ /* reset timer, set mode to 64-bit watchdog, and unreset */
+ tgcr = 0;
+ __raw_writel(tgcr, base + TGCR);
+ tgcr = TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT;
+ tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
+ (TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
+ __raw_writel(tgcr, base + TGCR);
+
+ /* clear counter and period regs */
+ __raw_writel(0, base + TIM12);
+ __raw_writel(0, base + TIM34);
+ __raw_writel(0, base + PRD12);
+ __raw_writel(0, base + PRD34);
+
+ /* put watchdog in pre-active state */
+ wdtcr = __raw_readl(base + WDTCR);
+ wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) |
+ (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
+ __raw_writel(wdtcr, base + WDTCR);
+
+ /* put watchdog in active state */
+ wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) |
+ (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
+ __raw_writel(wdtcr, base + WDTCR);
+
+ /* write an invalid value to the WDKEY field to trigger
+ * a watchdog reset */
+ wdtcr = 0x00004000;
+ __raw_writel(wdtcr, base + WDTCR);
+}
diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c
new file mode 100644
index 00000000..1b28fdd8
--- /dev/null
+++ b/arch/arm/mach-davinci/tnetv107x.c
@@ -0,0 +1,761 @@
+/*
+ * Texas Instruments TNETV107X SoC Support
+ *
+ * Copyright (C) 2010 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/time.h>
+#include <mach/cputype.h>
+#include <mach/psc.h>
+#include <mach/cp_intc.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+#include <mach/hardware.h>
+#include <mach/tnetv107x.h>
+
+#include "clock.h"
+#include "mux.h"
+
+/* Base addresses for on-chip devices */
+#define TNETV107X_INTC_BASE 0x03000000
+#define TNETV107X_TIMER0_BASE 0x08086500
+#define TNETV107X_TIMER1_BASE 0x08086600
+#define TNETV107X_CHIP_CFG_BASE 0x08087000
+#define TNETV107X_GPIO_BASE 0x08088000
+#define TNETV107X_CLOCK_CONTROL_BASE 0x0808a000
+#define TNETV107X_PSC_BASE 0x0808b000
+
+/* Reference clock frequencies */
+#define OSC_FREQ_ONCHIP (24000 * 1000)
+#define OSC_FREQ_OFFCHIP_SYS (25000 * 1000)
+#define OSC_FREQ_OFFCHIP_ETH (25000 * 1000)
+#define OSC_FREQ_OFFCHIP_TDM (19200 * 1000)
+
+#define N_PLLS 3
+
+/* Clock Control Registers */
+struct clk_ctrl_regs {
+ u32 pll_bypass;
+ u32 _reserved0;
+ u32 gem_lrst;
+ u32 _reserved1;
+ u32 pll_unlock_stat;
+ u32 sys_unlock;
+ u32 eth_unlock;
+ u32 tdm_unlock;
+};
+
+/* SSPLL Registers */
+struct sspll_regs {
+ u32 modes;
+ u32 post_div;
+ u32 pre_div;
+ u32 mult_factor;
+ u32 divider_range;
+ u32 bw_divider;
+ u32 spr_amount;
+ u32 spr_rate_div;
+ u32 diag;
+};
+
+/* Watchdog Timer Registers */
+struct wdt_regs {
+ u32 kick_lock;
+ u32 kick;
+ u32 change_lock;
+ u32 change ;
+ u32 disable_lock;
+ u32 disable;
+ u32 prescale_lock;
+ u32 prescale;
+};
+
+static struct clk_ctrl_regs __iomem *clk_ctrl_regs;
+
+static struct sspll_regs __iomem *sspll_regs[N_PLLS];
+static int sspll_regs_base[N_PLLS] = { 0x40, 0x80, 0xc0 };
+
+/* PLL bypass bit shifts in clk_ctrl_regs->pll_bypass register */
+static u32 bypass_mask[N_PLLS] = { BIT(0), BIT(2), BIT(1) };
+
+/* offchip (external) reference clock frequencies */
+static u32 pll_ext_freq[] = {
+ OSC_FREQ_OFFCHIP_SYS,
+ OSC_FREQ_OFFCHIP_TDM,
+ OSC_FREQ_OFFCHIP_ETH
+};
+
+/* PSC control registers */
+static u32 psc_regs[] = { TNETV107X_PSC_BASE };
+
+/* Host map for interrupt controller */
+static u32 intc_host_map[] = { 0x01010000, 0x01010101, -1 };
+
+static unsigned long clk_sspll_recalc(struct clk *clk);
+
+/* Level 1 - the PLLs */
+#define define_pll_clk(cname, pll, divmask, base) \
+ static struct pll_data pll_##cname##_data = { \
+ .num = pll, \
+ .div_ratio_mask = divmask, \
+ .phys_base = base + \
+ TNETV107X_CLOCK_CONTROL_BASE, \
+ }; \
+ static struct clk pll_##cname##_clk = { \
+ .name = "pll_" #cname "_clk", \
+ .pll_data = &pll_##cname##_data, \
+ .flags = CLK_PLL, \
+ .recalc = clk_sspll_recalc, \
+ }
+
+define_pll_clk(sys, 0, 0x1ff, 0x600);
+define_pll_clk(tdm, 1, 0x0ff, 0x200);
+define_pll_clk(eth, 2, 0x0ff, 0x400);
+
+/* Level 2 - divided outputs from the PLLs */
+#define define_pll_div_clk(pll, cname, div) \
+ static struct clk pll##_##cname##_clk = { \
+ .name = #pll "_" #cname "_clk", \
+ .parent = &pll_##pll##_clk, \
+ .flags = CLK_PLL, \
+ .div_reg = PLLDIV##div, \
+ .set_rate = davinci_set_sysclk_rate, \
+ }
+
+define_pll_div_clk(sys, arm1176, 1);
+define_pll_div_clk(sys, dsp, 2);
+define_pll_div_clk(sys, ddr, 3);
+define_pll_div_clk(sys, full, 4);
+define_pll_div_clk(sys, lcd, 5);
+define_pll_div_clk(sys, vlynq_ref, 6);
+define_pll_div_clk(sys, tsc, 7);
+define_pll_div_clk(sys, half, 8);
+
+define_pll_div_clk(eth, 5mhz, 1);
+define_pll_div_clk(eth, 50mhz, 2);
+define_pll_div_clk(eth, 125mhz, 3);
+define_pll_div_clk(eth, 250mhz, 4);
+define_pll_div_clk(eth, 25mhz, 5);
+
+define_pll_div_clk(tdm, 0, 1);
+define_pll_div_clk(tdm, extra, 2);
+define_pll_div_clk(tdm, 1, 3);
+
+
+/* Level 3 - LPSC gated clocks */
+#define __lpsc_clk(cname, _parent, mod, flg) \
+ static struct clk clk_##cname = { \
+ .name = #cname, \
+ .parent = &_parent, \
+ .lpsc = TNETV107X_LPSC_##mod,\
+ .flags = flg, \
+ }
+
+#define lpsc_clk_enabled(cname, parent, mod) \
+ __lpsc_clk(cname, parent, mod, ALWAYS_ENABLED)
+
+#define lpsc_clk(cname, parent, mod) \
+ __lpsc_clk(cname, parent, mod, 0)
+
+lpsc_clk_enabled(arm, sys_arm1176_clk, ARM);
+lpsc_clk_enabled(gem, sys_dsp_clk, GEM);
+lpsc_clk_enabled(ddr2_phy, sys_ddr_clk, DDR2_PHY);
+lpsc_clk_enabled(tpcc, sys_full_clk, TPCC);
+lpsc_clk_enabled(tptc0, sys_full_clk, TPTC0);
+lpsc_clk_enabled(tptc1, sys_full_clk, TPTC1);
+lpsc_clk_enabled(ram, sys_full_clk, RAM);
+lpsc_clk_enabled(aemif, sys_full_clk, AEMIF);
+lpsc_clk_enabled(chipcfg, sys_half_clk, CHIP_CFG);
+lpsc_clk_enabled(rom, sys_half_clk, ROM);
+lpsc_clk_enabled(secctl, sys_half_clk, SECCTL);
+lpsc_clk_enabled(keymgr, sys_half_clk, KEYMGR);
+lpsc_clk_enabled(gpio, sys_half_clk, GPIO);
+lpsc_clk_enabled(debugss, sys_half_clk, DEBUGSS);
+lpsc_clk_enabled(system, sys_half_clk, SYSTEM);
+lpsc_clk_enabled(ddr2_vrst, sys_ddr_clk, DDR2_EMIF1_VRST);
+lpsc_clk_enabled(ddr2_vctl_rst, sys_ddr_clk, DDR2_EMIF2_VCTL_RST);
+lpsc_clk_enabled(wdt_arm, sys_half_clk, WDT_ARM);
+lpsc_clk_enabled(timer1, sys_half_clk, TIMER1);
+
+lpsc_clk(mbx_lite, sys_arm1176_clk, MBX_LITE);
+lpsc_clk(ethss, eth_125mhz_clk, ETHSS);
+lpsc_clk(tsc, sys_tsc_clk, TSC);
+lpsc_clk(uart0, sys_half_clk, UART0);
+lpsc_clk(uart1, sys_half_clk, UART1);
+lpsc_clk(uart2, sys_half_clk, UART2);
+lpsc_clk(pktsec, sys_half_clk, PKTSEC);
+lpsc_clk(keypad, sys_half_clk, KEYPAD);
+lpsc_clk(mdio, sys_half_clk, MDIO);
+lpsc_clk(sdio0, sys_half_clk, SDIO0);
+lpsc_clk(sdio1, sys_half_clk, SDIO1);
+lpsc_clk(timer0, sys_half_clk, TIMER0);
+lpsc_clk(wdt_dsp, sys_half_clk, WDT_DSP);
+lpsc_clk(ssp, sys_half_clk, SSP);
+lpsc_clk(tdm0, tdm_0_clk, TDM0);
+lpsc_clk(tdm1, tdm_1_clk, TDM1);
+lpsc_clk(vlynq, sys_vlynq_ref_clk, VLYNQ);
+lpsc_clk(mcdma, sys_half_clk, MCDMA);
+lpsc_clk(usbss, sys_half_clk, USBSS);
+lpsc_clk(usb0, clk_usbss, USB0);
+lpsc_clk(usb1, clk_usbss, USB1);
+lpsc_clk(ethss_rgmii, eth_250mhz_clk, ETHSS_RGMII);
+lpsc_clk(imcop, sys_dsp_clk, IMCOP);
+lpsc_clk(spare, sys_half_clk, SPARE);
+
+/* LCD needs a full power down to clear controller state */
+__lpsc_clk(lcd, sys_lcd_clk, LCD, PSC_SWRSTDISABLE);
+
+
+/* Level 4 - leaf clocks for LPSC modules shared across drivers */
+static struct clk clk_rng = { .name = "rng", .parent = &clk_pktsec };
+static struct clk clk_pka = { .name = "pka", .parent = &clk_pktsec };
+
+static struct clk_lookup clks[] = {
+ CLK(NULL, "pll_sys_clk", &pll_sys_clk),
+ CLK(NULL, "pll_eth_clk", &pll_eth_clk),
+ CLK(NULL, "pll_tdm_clk", &pll_tdm_clk),
+ CLK(NULL, "sys_arm1176_clk", &sys_arm1176_clk),
+ CLK(NULL, "sys_dsp_clk", &sys_dsp_clk),
+ CLK(NULL, "sys_ddr_clk", &sys_ddr_clk),
+ CLK(NULL, "sys_full_clk", &sys_full_clk),
+ CLK(NULL, "sys_lcd_clk", &sys_lcd_clk),
+ CLK(NULL, "sys_vlynq_ref_clk", &sys_vlynq_ref_clk),
+ CLK(NULL, "sys_tsc_clk", &sys_tsc_clk),
+ CLK(NULL, "sys_half_clk", &sys_half_clk),
+ CLK(NULL, "eth_5mhz_clk", &eth_5mhz_clk),
+ CLK(NULL, "eth_50mhz_clk", &eth_50mhz_clk),
+ CLK(NULL, "eth_125mhz_clk", &eth_125mhz_clk),
+ CLK(NULL, "eth_250mhz_clk", &eth_250mhz_clk),
+ CLK(NULL, "eth_25mhz_clk", &eth_25mhz_clk),
+ CLK(NULL, "tdm_0_clk", &tdm_0_clk),
+ CLK(NULL, "tdm_extra_clk", &tdm_extra_clk),
+ CLK(NULL, "tdm_1_clk", &tdm_1_clk),
+ CLK(NULL, "clk_arm", &clk_arm),
+ CLK(NULL, "clk_gem", &clk_gem),
+ CLK(NULL, "clk_ddr2_phy", &clk_ddr2_phy),
+ CLK(NULL, "clk_tpcc", &clk_tpcc),
+ CLK(NULL, "clk_tptc0", &clk_tptc0),
+ CLK(NULL, "clk_tptc1", &clk_tptc1),
+ CLK(NULL, "clk_ram", &clk_ram),
+ CLK(NULL, "clk_mbx_lite", &clk_mbx_lite),
+ CLK("tnetv107x-fb.0", NULL, &clk_lcd),
+ CLK(NULL, "clk_ethss", &clk_ethss),
+ CLK(NULL, "aemif", &clk_aemif),
+ CLK(NULL, "clk_chipcfg", &clk_chipcfg),
+ CLK("tnetv107x-ts.0", NULL, &clk_tsc),
+ CLK(NULL, "clk_rom", &clk_rom),
+ CLK(NULL, "uart2", &clk_uart2),
+ CLK(NULL, "clk_pktsec", &clk_pktsec),
+ CLK("tnetv107x-rng.0", NULL, &clk_rng),
+ CLK("tnetv107x-pka.0", NULL, &clk_pka),
+ CLK(NULL, "clk_secctl", &clk_secctl),
+ CLK(NULL, "clk_keymgr", &clk_keymgr),
+ CLK("tnetv107x-keypad.0", NULL, &clk_keypad),
+ CLK(NULL, "clk_gpio", &clk_gpio),
+ CLK(NULL, "clk_mdio", &clk_mdio),
+ CLK("davinci_mmc.0", NULL, &clk_sdio0),
+ CLK(NULL, "uart0", &clk_uart0),
+ CLK(NULL, "uart1", &clk_uart1),
+ CLK(NULL, "timer0", &clk_timer0),
+ CLK(NULL, "timer1", &clk_timer1),
+ CLK("tnetv107x_wdt.0", NULL, &clk_wdt_arm),
+ CLK(NULL, "clk_wdt_dsp", &clk_wdt_dsp),
+ CLK("ti-ssp", NULL, &clk_ssp),
+ CLK(NULL, "clk_tdm0", &clk_tdm0),
+ CLK(NULL, "clk_vlynq", &clk_vlynq),
+ CLK(NULL, "clk_mcdma", &clk_mcdma),
+ CLK(NULL, "clk_usbss", &clk_usbss),
+ CLK(NULL, "clk_usb0", &clk_usb0),
+ CLK(NULL, "clk_usb1", &clk_usb1),
+ CLK(NULL, "clk_tdm1", &clk_tdm1),
+ CLK(NULL, "clk_debugss", &clk_debugss),
+ CLK(NULL, "clk_ethss_rgmii", &clk_ethss_rgmii),
+ CLK(NULL, "clk_system", &clk_system),
+ CLK(NULL, "clk_imcop", &clk_imcop),
+ CLK(NULL, "clk_spare", &clk_spare),
+ CLK("davinci_mmc.1", NULL, &clk_sdio1),
+ CLK(NULL, "clk_ddr2_vrst", &clk_ddr2_vrst),
+ CLK(NULL, "clk_ddr2_vctl_rst", &clk_ddr2_vctl_rst),
+ CLK(NULL, NULL, NULL),
+};
+
+static const struct mux_config pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+ MUX_CFG(TNETV107X, ASR_A00, 0, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO32, 0, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A01, 0, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO33, 0, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A02, 0, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO34, 0, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A03, 0, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO35, 0, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A04, 0, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO36, 0, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A05, 0, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO37, 0, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A06, 1, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO38, 1, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A07, 1, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO39, 1, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A08, 1, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO40, 1, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A09, 1, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO41, 1, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A10, 1, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO42, 1, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A11, 1, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, BOOT_STRP_0, 1, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A12, 2, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, BOOT_STRP_1, 2, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A13, 2, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO43, 2, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A14, 2, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO44, 2, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A15, 2, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO45, 2, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A16, 2, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO46, 2, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A17, 2, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO47, 2, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A18, 3, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO48, 3, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA3_0, 3, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A19, 3, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO49, 3, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA2_0, 3, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A20, 3, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO50, 3, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA1_0, 3, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A21, 3, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO51, 3, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA0_0, 3, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A22, 3, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO52, 3, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_CMD_0, 3, 20, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A23, 3, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO53, 3, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_CLK_0, 3, 25, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_BA_1, 4, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO54, 4, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SYS_PLL_CLK, 4, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_CS0, 4, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ASR_CS1, 4, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ASR_CS2, 4, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM_PLL_CLK, 4, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_CS3, 4, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ETH_PHY_CLK, 4, 20, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, ASR_D00, 4, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO55, 4, 25, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D01, 5, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO56, 5, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D02, 5, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO57, 5, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D03, 5, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO58, 5, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D04, 5, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO59_0, 5, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D05, 5, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO60_0, 5, 20, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D06, 5, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO61_0, 5, 25, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D07, 6, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO62_0, 6, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D08, 6, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO63_0, 6, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D09, 6, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO64_0, 6, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D10, 6, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA3_1, 6, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D11, 6, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA2_1, 6, 20, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D12, 6, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA1_1, 6, 25, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D13, 7, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA0_1, 7, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D14, 7, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_CMD_1, 7, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D15, 7, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_CLK_1, 7, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_OE, 7, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, BOOT_STRP_2, 7, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_RNW, 7, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO29_0, 7, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_WAIT, 7, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO30_0, 7, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_WE, 8, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, BOOT_STRP_3, 8, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_WE_DQM0, 8, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO31, 8, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD17_0, 8, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_WE_DQM1, 8, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ASR_BA0_0, 8, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, VLYNQ_CLK, 9, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO14, 9, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD19_0, 9, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, VLYNQ_RXD0, 9, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO15, 9, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD20_0, 9, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, VLYNQ_RXD1, 9, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO16, 9, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD21_0, 9, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, VLYNQ_TXD0, 9, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO17, 9, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD22_0, 9, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, VLYNQ_TXD1, 9, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO18, 9, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD23_0, 9, 20, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, SDIO0_CLK, 10, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO19, 10, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_CMD, 10, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO20, 10, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_DATA0, 10, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO21, 10, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_DATA1, 10, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO22, 10, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_DATA2, 10, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO23, 10, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_DATA3, 10, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO24, 10, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, EMU0, 11, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, EMU1, 11, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, RTCK, 12, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TRST_N, 12, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TCK, 12, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDI, 12, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDO, 12, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TMS, 12, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM1_CLK, 13, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM1_RX, 13, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM1_TX, 13, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM1_FS, 13, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R0, 14, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R1, 14, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R2, 14, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R3, 14, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R4, 14, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R5, 14, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R6, 15, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO12, 15, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, KEYPAD_R7, 15, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO10, 15, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, KEYPAD_C0, 15, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C1, 15, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C2, 15, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C3, 15, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C4, 16, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C5, 16, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C6, 16, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO13, 16, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, TEST_CLK_IN, 16, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, KEYPAD_C7, 16, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO11, 16, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SSP0_0, 17, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SCC_DCLK, 17, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD20_1, 17, 0, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP0_1, 17, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SCC_CS_N, 17, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD21_1, 17, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP0_2, 17, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SCC_D, 17, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD22_1, 17, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP0_3, 17, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SCC_RESETN, 17, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD23_1, 17, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP1_0, 18, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO25, 18, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, UART2_CTS, 18, 0, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP1_1, 18, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO26, 18, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, UART2_RD, 18, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP1_2, 18, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO27, 18, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, UART2_RTS, 18, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP1_3, 18, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO28, 18, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, UART2_TD, 18, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, UART0_CTS, 19, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART0_RD, 19, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART0_RTS, 19, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART0_TD, 19, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART1_RD, 19, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART1_TD, 19, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_AC_NCS, 20, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_HSYNC_RNW, 20, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_VSYNC_A0, 20, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_MCLK, 20, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD16_0, 20, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PCLK_E, 20, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD00, 20, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD01, 21, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD02, 21, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD03, 21, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD04, 21, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD05, 21, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD06, 21, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD07, 22, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD08, 22, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO59_1, 22, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD09, 22, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO60_1, 22, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD10, 22, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ASR_BA0_1, 22, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, GPIO61_1, 22, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD11, 22, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO62_1, 22, 20, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD12, 22, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO63_1, 22, 25, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD13, 23, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO64_1, 23, 0, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD14, 23, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO29_1, 23, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD15, 23, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO30_1, 23, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, EINT0, 24, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO08, 24, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, EINT1, 24, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO09, 24, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, GPIO00, 24, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD20_2, 24, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, TDM_CLK_IN_2, 24, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO01, 24, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD21_2, 24, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, 24M_CLK_OUT_1, 24, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO02, 24, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD22_2, 24, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, GPIO03, 24, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD23_2, 24, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, GPIO04, 25, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD16_1, 25, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, USB0_RXERR, 25, 0, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO05, 25, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD17_1, 25, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, TDM_CLK_IN_1, 25, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO06, 25, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD18, 25, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, 24M_CLK_OUT_2, 25, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO07, 25, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD19_1, 25, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, USB1_RXERR, 25, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, ETH_PLL_CLK, 25, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, MDIO, 26, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, MDC, 26, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, AIC_MUTE_STAT_N, 26, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM0_CLK, 26, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, AIC_HNS_EN_N, 26, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM0_FS, 26, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, AIC_HDS_EN_STAT_N, 26, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM0_TX, 26, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, AIC_HNF_EN_STAT_N, 26, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM0_RX, 26, 25, 0x1f, 0x04, false)
+#endif
+};
+
+/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
+static u8 irq_prios[TNETV107X_N_CP_INTC_IRQ] = {
+ /* fill in default priority 7 */
+ [0 ... (TNETV107X_N_CP_INTC_IRQ - 1)] = 7,
+ /* now override as needed, e.g. [xxx] = 5 */
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb8a1,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_TNETV107X,
+ .name = "tnetv107x rev 1.0",
+ },
+ {
+ .variant = 0x1,
+ .part_no = 0xb8a1,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_TNETV107X,
+ .name = "tnetv107x rev 1.1/1.2",
+ },
+};
+
+static struct davinci_timer_instance timer_instance[2] = {
+ {
+ .base = TNETV107X_TIMER0_BASE,
+ .bottom_irq = IRQ_TNETV107X_TIMER_0_TINT12,
+ .top_irq = IRQ_TNETV107X_TIMER_0_TINT34,
+ },
+ {
+ .base = TNETV107X_TIMER1_BASE,
+ .bottom_irq = IRQ_TNETV107X_TIMER_1_TINT12,
+ .top_irq = IRQ_TNETV107X_TIMER_1_TINT34,
+ },
+};
+
+static struct davinci_timer_info timer_info = {
+ .timers = timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
+/*
+ * TNETV107X platforms do not use the static mappings from Davinci
+ * IO_PHYS/IO_VIRT. This SOC's interesting MMRs are at different addresses,
+ * and changing IO_PHYS would break away from existing Davinci SOCs.
+ *
+ * The primary impact of the current model is that IO_ADDRESS() is not to be
+ * used to map registers on TNETV107X.
+ *
+ * 1. The first chunk is for INTC: This needs to be mapped in via iotable
+ * because ioremap() does not seem to be operational at the time when
+ * irqs are initialized. Without this, consistent dma init bombs.
+ *
+ * 2. The second chunk maps in register areas that need to be populated into
+ * davinci_soc_info. Note that alignment restrictions come into play if
+ * low-level debug is enabled (see note in <mach/tnetv107x.h>).
+ */
+static struct map_desc io_desc[] = {
+ { /* INTC */
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(TNETV107X_INTC_BASE),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ },
+ { /* Most of the rest */
+ .virtual = TNETV107X_IO_VIRT,
+ .pfn = __phys_to_pfn(TNETV107X_IO_BASE),
+ .length = IO_SIZE - SZ_1M,
+ .type = MT_DEVICE
+ },
+};
+
+static unsigned long clk_sspll_recalc(struct clk *clk)
+{
+ int pll;
+ unsigned long mult = 0, prediv = 1, postdiv = 1;
+ unsigned long ref = OSC_FREQ_ONCHIP, ret;
+ u32 tmp;
+
+ if (WARN_ON(!clk->pll_data))
+ return clk->rate;
+
+ if (!clk_ctrl_regs) {
+ void __iomem *tmp;
+
+ tmp = ioremap(TNETV107X_CLOCK_CONTROL_BASE, SZ_4K);
+
+ if (WARN(!tmp, "failed ioremap for clock control regs\n"))
+ return clk->parent ? clk->parent->rate : 0;
+
+ for (pll = 0; pll < N_PLLS; pll++)
+ sspll_regs[pll] = tmp + sspll_regs_base[pll];
+
+ clk_ctrl_regs = tmp;
+ }
+
+ pll = clk->pll_data->num;
+
+ tmp = __raw_readl(&clk_ctrl_regs->pll_bypass);
+ if (!(tmp & bypass_mask[pll])) {
+ mult = __raw_readl(&sspll_regs[pll]->mult_factor);
+ prediv = __raw_readl(&sspll_regs[pll]->pre_div) + 1;
+ postdiv = __raw_readl(&sspll_regs[pll]->post_div) + 1;
+ }
+
+ tmp = __raw_readl(clk->pll_data->base + PLLCTL);
+ if (tmp & PLLCTL_CLKMODE)
+ ref = pll_ext_freq[pll];
+
+ clk->pll_data->input_rate = ref;
+
+ tmp = __raw_readl(clk->pll_data->base + PLLCTL);
+ if (!(tmp & PLLCTL_PLLEN))
+ return ref;
+
+ ret = ref;
+ if (mult)
+ ret += ((unsigned long long)ref * mult) / 256;
+
+ ret /= (prediv * postdiv);
+
+ return ret;
+}
+
+static void tnetv107x_watchdog_reset(struct platform_device *pdev)
+{
+ struct wdt_regs __iomem *regs;
+
+ regs = ioremap(pdev->resource[0].start, SZ_4K);
+
+ /* disable watchdog */
+ __raw_writel(0x7777, &regs->disable_lock);
+ __raw_writel(0xcccc, &regs->disable_lock);
+ __raw_writel(0xdddd, &regs->disable_lock);
+ __raw_writel(0, &regs->disable);
+
+ /* program prescale */
+ __raw_writel(0x5a5a, &regs->prescale_lock);
+ __raw_writel(0xa5a5, &regs->prescale_lock);
+ __raw_writel(0, &regs->prescale);
+
+ /* program countdown */
+ __raw_writel(0x6666, &regs->change_lock);
+ __raw_writel(0xbbbb, &regs->change_lock);
+ __raw_writel(1, &regs->change);
+
+ /* enable watchdog */
+ __raw_writel(0x7777, &regs->disable_lock);
+ __raw_writel(0xcccc, &regs->disable_lock);
+ __raw_writel(0xdddd, &regs->disable_lock);
+ __raw_writel(1, &regs->disable);
+
+ /* kick */
+ __raw_writel(0x5555, &regs->kick_lock);
+ __raw_writel(0xaaaa, &regs->kick_lock);
+ __raw_writel(1, &regs->kick);
+}
+
+static struct davinci_soc_info tnetv107x_soc_info = {
+ .io_desc = io_desc,
+ .io_desc_num = ARRAY_SIZE(io_desc),
+ .ids = ids,
+ .ids_num = ARRAY_SIZE(ids),
+ .jtag_id_reg = TNETV107X_CHIP_CFG_BASE + 0x018,
+ .cpu_clks = clks,
+ .psc_bases = psc_regs,
+ .psc_bases_num = ARRAY_SIZE(psc_regs),
+ .pinmux_base = TNETV107X_CHIP_CFG_BASE + 0x150,
+ .pinmux_pins = pins,
+ .pinmux_pins_num = ARRAY_SIZE(pins),
+ .intc_type = DAVINCI_INTC_TYPE_CP_INTC,
+ .intc_base = TNETV107X_INTC_BASE,
+ .intc_irq_prios = irq_prios,
+ .intc_irq_num = TNETV107X_N_CP_INTC_IRQ,
+ .intc_host_map = intc_host_map,
+ .gpio_base = TNETV107X_GPIO_BASE,
+ .gpio_type = GPIO_TYPE_TNETV107X,
+ .gpio_num = TNETV107X_N_GPIO,
+ .timer_info = &timer_info,
+ .serial_dev = &tnetv107x_serial_device,
+ .reset = tnetv107x_watchdog_reset,
+ .reset_device = &tnetv107x_wdt_device,
+};
+
+void __init tnetv107x_init(void)
+{
+ davinci_common_init(&tnetv107x_soc_info);
+}
diff --git a/arch/arm/mach-davinci/usb.c b/arch/arm/mach-davinci/usb.c
new file mode 100644
index 00000000..23d2b6d9
--- /dev/null
+++ b/arch/arm/mach-davinci/usb.c
@@ -0,0 +1,180 @@
+/*
+ * USB
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/usb/musb.h>
+
+#include <mach/common.h>
+#include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <mach/usb.h>
+
+#define DAVINCI_USB_OTG_BASE 0x01c64000
+
+#define DA8XX_USB0_BASE 0x01e00000
+#define DA8XX_USB1_BASE 0x01e25000
+
+#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
+static struct musb_hdrc_eps_bits musb_eps[] = {
+ { "ep1_tx", 8, },
+ { "ep1_rx", 8, },
+ { "ep2_tx", 8, },
+ { "ep2_rx", 8, },
+ { "ep3_tx", 5, },
+ { "ep3_rx", 5, },
+ { "ep4_tx", 5, },
+ { "ep4_rx", 5, },
+};
+
+static struct musb_hdrc_config musb_config = {
+ .multipoint = true,
+ .dyn_fifo = true,
+ .soft_con = true,
+ .dma = true,
+
+ .num_eps = 5,
+ .dma_channels = 8,
+ .ram_bits = 10,
+ .eps_bits = musb_eps,
+};
+
+static struct musb_hdrc_platform_data usb_data = {
+#if defined(CONFIG_USB_MUSB_OTG)
+ /* OTG requires a Mini-AB connector */
+ .mode = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
+ .mode = MUSB_PERIPHERAL,
+#elif defined(CONFIG_USB_MUSB_HOST)
+ .mode = MUSB_HOST,
+#endif
+ .clock = "usb",
+ .config = &musb_config,
+};
+
+static struct resource usb_resources[] = {
+ {
+ /* physical address */
+ .start = DAVINCI_USB_OTG_BASE,
+ .end = DAVINCI_USB_OTG_BASE + 0x5ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_USBINT,
+ .flags = IORESOURCE_IRQ,
+ .name = "mc"
+ },
+ {
+ /* placeholder for the dedicated CPPI IRQ */
+ .flags = IORESOURCE_IRQ,
+ .name = "dma"
+ },
+};
+
+static u64 usb_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device usb_dev = {
+ .name = "musb-davinci",
+ .id = -1,
+ .dev = {
+ .platform_data = &usb_data,
+ .dma_mask = &usb_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = usb_resources,
+ .num_resources = ARRAY_SIZE(usb_resources),
+};
+
+void __init davinci_setup_usb(unsigned mA, unsigned potpgt_ms)
+{
+ usb_data.power = mA > 510 ? 255 : mA / 2;
+ usb_data.potpgt = (potpgt_ms + 1) / 2;
+
+ if (cpu_is_davinci_dm646x()) {
+ /* Override the defaults as DM6467 uses different IRQs. */
+ usb_dev.resource[1].start = IRQ_DM646X_USBINT;
+ usb_dev.resource[2].start = IRQ_DM646X_USBDMAINT;
+ } else /* other devices don't have dedicated CPPI IRQ */
+ usb_dev.num_resources = 2;
+
+ platform_device_register(&usb_dev);
+}
+
+#ifdef CONFIG_ARCH_DAVINCI_DA8XX
+static struct resource da8xx_usb20_resources[] = {
+ {
+ .start = DA8XX_USB0_BASE,
+ .end = DA8XX_USB0_BASE + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DA8XX_USB_INT,
+ .flags = IORESOURCE_IRQ,
+ .name = "mc",
+ },
+};
+
+int __init da8xx_register_usb20(unsigned mA, unsigned potpgt)
+{
+ usb_data.clock = "usb20";
+ usb_data.power = mA > 510 ? 255 : mA / 2;
+ usb_data.potpgt = (potpgt + 1) / 2;
+
+ usb_dev.resource = da8xx_usb20_resources;
+ usb_dev.num_resources = ARRAY_SIZE(da8xx_usb20_resources);
+ usb_dev.name = "musb-da8xx";
+
+ return platform_device_register(&usb_dev);
+}
+#endif /* CONFIG_DAVINCI_DA8XX */
+
+#else
+
+void __init davinci_setup_usb(unsigned mA, unsigned potpgt_ms)
+{
+}
+
+#ifdef CONFIG_ARCH_DAVINCI_DA8XX
+int __init da8xx_register_usb20(unsigned mA, unsigned potpgt)
+{
+ return 0;
+}
+#endif
+
+#endif /* CONFIG_USB_MUSB_HDRC */
+
+#ifdef CONFIG_ARCH_DAVINCI_DA8XX
+static struct resource da8xx_usb11_resources[] = {
+ [0] = {
+ .start = DA8XX_USB1_BASE,
+ .end = DA8XX_USB1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DA8XX_IRQN,
+ .end = IRQ_DA8XX_IRQN,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 da8xx_usb11_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device da8xx_usb11_device = {
+ .name = "ohci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &da8xx_usb11_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(da8xx_usb11_resources),
+ .resource = da8xx_usb11_resources,
+};
+
+int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
+{
+ da8xx_usb11_device.dev.platform_data = pdata;
+ return platform_device_register(&da8xx_usb11_device);
+}
+#endif /* CONFIG_DAVINCI_DA8XX */