aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-davinci
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-05-29 10:04:24 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-05-29 10:04:24 +0100
commit42f1d2e06a25628ae4ceaadccc4fa67c7787e2b4 (patch)
tree8aac83e399de7ad13748a59853a0feea9ed2c5cb /arch/arm/mach-davinci
parent9af5324a070e0b2dcb6e22c89e17424eba245fcc (diff)
parent77bbca138c64cb80259732db6f70e1668123f2a7 (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci into devel
Diffstat (limited to 'arch/arm/mach-davinci')
-rw-r--r--arch/arm/mach-davinci/Kconfig47
-rw-r--r--arch/arm/mach-davinci/Makefile13
-rw-r--r--arch/arm/mach-davinci/board-dm355-evm.c298
-rw-r--r--arch/arm/mach-davinci/board-dm355-leopard.c296
-rw-r--r--arch/arm/mach-davinci/board-dm644x-evm.c68
-rw-r--r--arch/arm/mach-davinci/board-dm646x-evm.c262
-rw-r--r--arch/arm/mach-davinci/board-sffsdr.c189
-rw-r--r--arch/arm/mach-davinci/clock.c10
-rw-r--r--arch/arm/mach-davinci/clock.h4
-rw-r--r--arch/arm/mach-davinci/common.c108
-rw-r--r--arch/arm/mach-davinci/cp_intc.c161
-rw-r--r--arch/arm/mach-davinci/devices.c211
-rw-r--r--arch/arm/mach-davinci/dm355.c730
-rw-r--r--arch/arm/mach-davinci/dm644x.c204
-rw-r--r--arch/arm/mach-davinci/dm646x.c636
-rw-r--r--arch/arm/mach-davinci/gpio.c63
-rw-r--r--arch/arm/mach-davinci/id.c116
-rw-r--r--arch/arm/mach-davinci/include/mach/board-dm6446evm.h20
-rw-r--r--arch/arm/mach-davinci/include/mach/common.h55
-rw-r--r--arch/arm/mach-davinci/include/mach/cp_intc.h57
-rw-r--r--arch/arm/mach-davinci/include/mach/cputype.h29
-rw-r--r--arch/arm/mach-davinci/include/mach/debug-macro.S31
-rw-r--r--arch/arm/mach-davinci/include/mach/dm355.h22
-rw-r--r--arch/arm/mach-davinci/include/mach/dm644x.h1
-rw-r--r--arch/arm/mach-davinci/include/mach/dm646x.h26
-rw-r--r--arch/arm/mach-davinci/include/mach/edma.h4
-rw-r--r--arch/arm/mach-davinci/include/mach/emac.h36
-rw-r--r--arch/arm/mach-davinci/include/mach/entry-macro.S25
-rw-r--r--arch/arm/mach-davinci/include/mach/gpio.h14
-rw-r--r--arch/arm/mach-davinci/include/mach/irqs.h3
-rw-r--r--arch/arm/mach-davinci/include/mach/memory.h1
-rw-r--r--arch/arm/mach-davinci/include/mach/mmc.h33
-rw-r--r--arch/arm/mach-davinci/include/mach/mux.h16
-rw-r--r--arch/arm/mach-davinci/include/mach/psc.h8
-rw-r--r--arch/arm/mach-davinci/include/mach/serial.h4
-rw-r--r--arch/arm/mach-davinci/include/mach/sram.h27
-rw-r--r--arch/arm/mach-davinci/include/mach/time.h35
-rw-r--r--arch/arm/mach-davinci/include/mach/uncompress.h19
-rw-r--r--arch/arm/mach-davinci/io.c38
-rw-r--r--arch/arm/mach-davinci/irq.c217
-rw-r--r--arch/arm/mach-davinci/mux.c24
-rw-r--r--arch/arm/mach-davinci/psc.c32
-rw-r--r--arch/arm/mach-davinci/serial.c74
-rw-r--r--arch/arm/mach-davinci/sram.c74
-rw-r--r--arch/arm/mach-davinci/time.c247
45 files changed, 3890 insertions, 698 deletions
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index a9c78bc72b8..76408670554 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -1,11 +1,26 @@
if ARCH_DAVINCI
+config AINTC
+ bool
+
+config CP_INTC
+ bool
+
menu "TI DaVinci Implementations"
comment "DaVinci Core Type"
config ARCH_DAVINCI_DM644x
bool "DaVinci 644x based system"
+ select AINTC
+
+config ARCH_DAVINCI_DM355
+ bool "DaVinci 355 based system"
+ select AINTC
+
+config ARCH_DAVINCI_DM646x
+ bool "DaVinci 646x based system"
+ select AINTC
comment "DaVinci Board Type"
@@ -17,6 +32,38 @@ config MACH_DAVINCI_EVM
Configure this option to specify the whether the board used
for development is a DM644x EVM
+config MACH_SFFSDR
+ bool "Lyrtech SFFSDR"
+ default n
+ depends on ARCH_DAVINCI_DM644x
+ help
+ Say Y here to select the Lyrtech Small Form Factor
+ Software Defined Radio (SFFSDR) board.
+
+config MACH_DAVINCI_DM355_EVM
+ bool "TI DM355 EVM"
+ default n
+ 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"
+ default n
+ 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 n
+ depends on ARCH_DAVINCI_DM646x
+ help
+ Configure this option to specify the whether the board used
+ for development is a DM6467 EVM
+
config DAVINCI_MUX
bool "DAVINCI multiplexing support"
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 1674661942f..059ab78084b 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -4,13 +4,22 @@
#
# Common objects
-obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \
- gpio.o devices.o dma.o usb.o
+obj-y := time.o clock.o serial.o io.o psc.o \
+ gpio.o devices.o dma.o usb.o common.o sram.o
obj-$(CONFIG_DAVINCI_MUX) += mux.o
# Chip specific
obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o
+obj-$(CONFIG_ARCH_DAVINCI_DM355) += dm355.o
+obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.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_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
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 00000000000..5ac2f565d86
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -0,0 +1,298 @@
+/*
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <mach/hardware.h>
+#include <mach/dm355.h>
+#include <mach/psc.h>
+#include <mach/common.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/nand.h>
+#include <mach/mmc.h>
+#include <mach/common.h>
+
+#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+
+/* 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 = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE,
+ .end = DAVINCI_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 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("tlv320aic3x", 0x1b), }, */
+ /* { I2C_BOARD_INFO("tvp5146", 0x5d), }, */
+};
+
+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 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)
+{
+ 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 */
+ setup_usb(500, 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));
+}
+
+static __init void dm355_evm_irq_init(void)
+{
+ davinci_irq_init();
+}
+
+MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
+ .phys_io = IO_PHYS,
+ .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
+ .boot_params = (0x80000100),
+ .map_io = dm355_evm_map_io,
+ .init_irq = dm355_evm_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 00000000000..28c9008df4f
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -0,0 +1,296 @@
+/*
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <mach/hardware.h>
+#include <mach/dm355.h>
+#include <mach/psc.h>
+#include <mach/common.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/nand.h>
+#include <mach/mmc.h>
+#include <mach/common.h>
+
+#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+
+/* 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 = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE,
+ .end = DAVINCI_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 */
+ setup_usb(500, 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));
+}
+
+static __init void dm355_leopard_irq_init(void)
+{
+ davinci_irq_init();
+}
+
+MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard")
+ .phys_io = IO_PHYS,
+ .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
+ .boot_params = (0x80000100),
+ .map_io = dm355_leopard_map_io,
+ .init_irq = dm355_leopard_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = dm355_leopard_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index b2e7f9c63bc..d9d40450bdc 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -16,12 +16,11 @@
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/memory.h>
-#include <linux/etherdevice.h>
#include <linux/i2c.h>
#include <linux/i2c/pcf857x.h>
#include <linux/i2c/at24.h>
-
+#include <linux/etherdevice.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
@@ -44,6 +43,9 @@
#include <mach/mux.h>
#include <mach/psc.h>
#include <mach/nand.h>
+#include <mach/mmc.h>
+#include <mach/emac.h>
+#include <mach/common.h>
#define DM644X_EVM_PHY_MASK (0x2)
#define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
@@ -436,45 +438,15 @@ static struct pcf857x_platform_data pcf_data_u35 = {
* - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL)
* - ... newer boards may have more
*/
-static struct memory_accessor *at24_mem_acc;
-
-static void at24_setup(struct memory_accessor *mem_acc, void *context)
-{
- DECLARE_MAC_BUF(mac_str);
- char mac_addr[6];
-
- at24_mem_acc = mem_acc;
-
- /* Read MAC addr from EEPROM */
- if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x7f00, 6) == 6) {
- printk(KERN_INFO "Read MAC addr from EEPROM: %s\n",
- print_mac(mac_str, mac_addr));
- }
-}
static struct at24_platform_data eeprom_info = {
.byte_len = (256*1024) / 8,
.page_size = 64,
.flags = AT24_FLAG_ADDR16,
- .setup = at24_setup,
+ .setup = davinci_get_mac_addr,
+ .context = (void *)0x7f00,
};
-int dm6446evm_eeprom_read(void *buf, off_t off, size_t count)
-{
- if (at24_mem_acc)
- return at24_mem_acc->read(at24_mem_acc, buf, off, count);
- return -ENODEV;
-}
-EXPORT_SYMBOL(dm6446evm_eeprom_read);
-
-int dm6446evm_eeprom_write(void *buf, off_t off, size_t count)
-{
- if (at24_mem_acc)
- return at24_mem_acc->write(at24_mem_acc, buf, off, count);
- return -ENODEV;
-}
-EXPORT_SYMBOL(dm6446evm_eeprom_write);
-
/*
* MSP430 supports RTC, card detection, input from IR remote, and
* a bit more. It triggers interrupts on GPIO(7) from pressing
@@ -545,6 +517,27 @@ static int dm6444evm_msp430_get_pins(void)
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),
@@ -598,7 +591,6 @@ static struct davinci_uart_config uart_config __initdata = {
static void __init
davinci_evm_map_io(void)
{
- davinci_map_common_io();
dm644x_init();
}
@@ -639,6 +631,7 @@ static int davinci_phy_fixup(struct phy_device *phydev)
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);
@@ -671,8 +664,13 @@ static __init void davinci_evm_init(void)
ARRAY_SIZE(davinci_evm_devices));
evm_init_i2c();
+ davinci_setup_mmc(0, &dm6446evm_mmc_config);
+
davinci_serial_init(&uart_config);
+ soc_info->emac_pdata->phy_mask = DM644X_EVM_PHY_MASK;
+ soc_info->emac_pdata->mdio_max_freq = DM644X_EVM_MDIO_FREQUENCY;
+
/* Register the fixup for PHY on DaVinci */
phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK,
davinci_phy_fixup);
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 00000000000..e17de635262
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -0,0 +1,262 @@
+/*
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/major.h>
+#include <linux/root_dev.h>
+#include <linux/dma-mapping.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/etherdevice.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <mach/dm646x.h>
+#include <mach/common.h>
+#include <mach/psc.h>
+#include <mach/serial.h>
+#include <mach/i2c.h>
+#include <mach/mmc.h>
+#include <mach/emac.h>
+#include <mach/common.h>
+
+#define DM646X_EVM_PHY_MASK (0x2)
+#define DM646X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+/* 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 __initconst 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 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,
+ },
+};
+
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 100 /* kHz */,
+ .bus_delay = 0 /* usec */,
+};
+
+static void __init evm_init_i2c(void)
+{
+ davinci_init_i2c(&i2c_pdata);
+ i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+}
+
+static void __init davinci_map_io(void)
+{
+ dm646x_init();
+}
+
+static __init void evm_init(void)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ evm_init_i2c();
+ davinci_serial_init(&uart_config);
+
+ soc_info->emac_pdata->phy_mask = DM646X_EVM_PHY_MASK;
+ soc_info->emac_pdata->mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY;
+}
+
+static __init void davinci_dm646x_evm_irq_init(void)
+{
+ davinci_irq_init();
+}
+
+MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
+ .phys_io = IO_PHYS,
+ .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
+ .boot_params = (0x80000100),
+ .map_io = davinci_map_io,
+ .init_irq = davinci_dm646x_evm_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = evm_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 00000000000..748a8e48541
--- /dev/null
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -0,0 +1,189 @@
+/*
+ * 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/kernel.h>
+#include <linux/module.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/at24.h>
+#include <linux/etherdevice.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <mach/dm644x.h>
+#include <mach/common.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/psc.h>
+#include <mach/mux.h>
+#include <mach/common.h>
+
+#define SFFSDR_PHY_MASK (0x2)
+#define SFFSDR_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
+
+#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e00000
+#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+
+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 = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DAVINCI_ASYNC_EMIF_CONTROL_BASE,
+ .end = DAVINCI_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 emac_platform_data sffsdr_emac_pdata = {
+ .phy_mask = SFFSDR_PHY_MASK,
+ .mdio_max_freq = SFFSDR_MDIO_FREQUENCY,
+};
+
+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_mask = SFFSDR_PHY_MASK;
+ soc_info->emac_pdata->mdio_max_freq = SFFSDR_MDIO_FREQUENCY;
+ setup_usb(0, 0); /* We support only peripheral mode. */
+
+ /* mux VLYNQ pins */
+ davinci_cfg_reg(DM644X_VLYNQEN);
+ davinci_cfg_reg(DM644X_VLYNQWD);
+}
+
+static __init void davinci_sffsdr_irq_init(void)
+{
+ davinci_irq_init();
+}
+
+MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
+ /* Maintainer: Hugo Villeneuve hugo.villeneuve@lyrtech.com */
+ .phys_io = IO_PHYS,
+ .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
+ .boot_params = (DAVINCI_DDR_BASE + 0x100),
+ .map_io = davinci_sffsdr_map_io,
+ .init_irq = davinci_sffsdr_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = davinci_sffsdr_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index f0baaa15a57..39bf321d70a 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -42,7 +42,8 @@ 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->lpsc, 1);
+ davinci_psc_config(psc_domain(clk), clk->psc_ctlr,
+ clk->lpsc, 1);
}
static void __clk_disable(struct clk *clk)
@@ -50,7 +51,8 @@ static void __clk_disable(struct clk *clk)
if (WARN_ON(clk->usecount == 0))
return;
if (--clk->usecount == 0 && !(clk->flags & CLK_PLL))
- davinci_psc_config(psc_domain(clk), clk->lpsc, 0);
+ davinci_psc_config(psc_domain(clk), clk->psc_ctlr,
+ clk->lpsc, 0);
if (clk->parent)
__clk_disable(clk->parent);
}
@@ -164,11 +166,11 @@ static int __init clk_disable_unused(void)
continue;
/* ignore if in Disabled or SwRstDisable states */
- if (!davinci_psc_is_clk_active(ck->lpsc))
+ if (!davinci_psc_is_clk_active(ck->psc_ctlr, ck->lpsc))
continue;
pr_info("Clocks: disable unused %s\n", ck->name);
- davinci_psc_config(psc_domain(ck), ck->lpsc, 0);
+ davinci_psc_config(psc_domain(ck), ck->psc_ctlr, ck->lpsc, 0);
}
spin_unlock_irq(&clockfw_lock);
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index 35736ec202f..27233cb4a2f 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -67,6 +67,7 @@ struct clk {
u8 usecount;
u8 flags;
u8 lpsc;
+ u8 psc_ctlr;
struct clk *parent;
struct pll_data *pll_data;
u32 div_reg;
@@ -93,4 +94,7 @@ struct davinci_clk {
}
int davinci_clk_init(struct davinci_clk *clocks);
+
+extern struct platform_device davinci_wdt_device;
+
#endif
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
new file mode 100644
index 00000000000..61ede19c6b5
--- /dev/null
+++ b/arch/arm/mach-davinci/common.c
@@ -0,0 +1,108 @@
+/*
+ * 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 <asm/tlb.h>
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/cputype.h>
+#include <mach/emac.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 struct davinci_id * __init davinci_get_id(u32 jtag_id)
+{
+ int i;
+ struct davinci_id *dip;
+ u8 variant = (jtag_id & 0xf0000000) >> 28;
+ u16 part_no = (jtag_id & 0x0ffff000) >> 12;
+
+ for (i = 0, dip = davinci_soc_info.ids; i < davinci_soc_info.ids_num;
+ i++, dip++)
+ /* Don't care about the manufacturer right now */
+ if ((dip->part_no == part_no) && (dip->variant == variant))
+ return dip;
+
+ return NULL;
+}
+
+void __init davinci_common_init(struct davinci_soc_info *soc_info)
+{
+ int ret;
+ struct davinci_id *dip;
+
+ 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();
+
+ /*
+ * We want to check CPU revision early for cpu_is_xxxx() macros.
+ * IO space mapping must be initialized before we can do that.
+ */
+ davinci_soc_info.jtag_id = __raw_readl(davinci_soc_info.jtag_id_base);
+
+ dip = davinci_get_id(davinci_soc_info.jtag_id);
+ if (!dip) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ davinci_soc_info.cpu_id = dip->cpu_id;
+ pr_info("DaVinci %s variant 0x%x\n", dip->name, dip->variant);
+
+ if (davinci_soc_info.cpu_clks) {
+ ret = davinci_clk_init(davinci_soc_info.cpu_clks);
+
+ if (ret != 0)
+ goto err;
+ }
+
+ davinci_intc_base = davinci_soc_info.intc_base;
+ davinci_intc_type = davinci_soc_info.intc_type;
+ return;
+
+err:
+ pr_err("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 00000000000..96c8e97a7de
--- /dev/null
+++ b/arch/arm/mach-davinci/cp_intc.c
@@ -0,0 +1,161 @@
+/*
+ * 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/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/cp_intc.h>
+
+static void __iomem *cp_intc_base;
+
+static inline unsigned int cp_intc_read(unsigned offset)
+{
+ return __raw_readl(cp_intc_base + offset);
+}
+
+static inline void cp_intc_write(unsigned long value, unsigned offset)
+{
+ __raw_writel(value, cp_intc_base + offset);
+}
+
+static void cp_intc_ack_irq(unsigned int irq)
+{
+ cp_intc_write(irq, CP_INTC_SYS_STAT_IDX_CLR);
+}
+
+/* Disable interrupt */
+static void cp_intc_mask_irq(unsigned int irq)
+{
+ /* XXX don't know why we need to disable nIRQ here... */
+ cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_CLR);
+ cp_intc_write(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(unsigned int irq)
+{
+ cp_intc_write(irq, CP_INTC_SYS_ENABLE_IDX_SET);
+}
+
+static int cp_intc_set_irq_type(unsigned int irq, unsigned int flow_type)
+{
+ unsigned reg = BIT_WORD(irq);
+ unsigned mask = BIT_MASK(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;
+}
+
+static struct irq_chip cp_intc_irq_chip = {
+ .name = "cp_intc",
+ .ack = cp_intc_ack_irq,
+ .mask = cp_intc_mask_irq,
+ .unmask = cp_intc_unmask_irq,
+ .set_type = cp_intc_set_irq_type,
+};
+
+void __init cp_intc_init(void __iomem *base, unsigned short num_irq,
+ u8 *irq_prio)
+{
+ unsigned num_reg = BITS_TO_LONGS(num_irq);
+ int i;
+
+ cp_intc_base = base;
+
+ 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));
+ }
+
+ /* Set up genirq dispatching for cp_intc */
+ for (i = 0; i < num_irq; i++) {
+ set_irq_chip(i, &cp_intc_irq_chip);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ set_irq_handler(i, handle_edge_irq);
+ }
+
+ /* Enable global interrupt */
+ cp_intc_write(1, CP_INTC_GLOBAL_ENABLE);
+}
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index a31370b93dd..c85091c25d1 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -23,8 +23,14 @@
#include <mach/irqs.h>
#include <mach/cputype.h>
#include <mach/mux.h>
+#include <mach/edma.h>
+#include <mach/mmc.h>
+#include <mach/time.h>
#define DAVINCI_I2C_BASE 0x01C21000
+#define DAVINCI_MMCSD0_BASE 0x01E10000
+#define DM355_MMCSD0_BASE 0x01E11000
+#define DM355_MMCSD1_BASE 0x01E00000
static struct resource i2c_resources[] = {
{
@@ -54,3 +60,208 @@ void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
(void) platform_device_register(&davinci_i2c_device);
}
+#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
+
+static u64 mmcsd0_dma_mask = DMA_32BIT_MASK;
+
+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 = DAVINCI_DMA_MMCRXEVT,
+ .flags = IORESOURCE_DMA,
+ }, {
+ .start = 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_32BIT_MASK,
+ },
+ .num_resources = ARRAY_SIZE(mmcsd0_resources),
+ .resource = mmcsd0_resources,
+};
+
+static u64 mmcsd1_dma_mask = DMA_32BIT_MASK;
+
+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 = 30, /* rx */
+ .flags = IORESOURCE_DMA,
+ }, {
+ .start = 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_32BIT_MASK,
+ },
+ .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())
+ break;
+
+ /* 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);
+
+ 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_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[] = {
+ {
+ .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)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ wdt_resources[0].start = (resource_size_t)soc_info->wdt_base;
+ wdt_resources[0].end = (resource_size_t)soc_info->wdt_base + SZ_1K - 1;
+
+ platform_device_register(&davinci_wdt_device);
+}
+
+/*-------------------------------------------------------------------------*/
+
+struct davinci_timer_instance davinci_timer_instance[2] = {
+ {
+ .base = IO_ADDRESS(DAVINCI_TIMER0_BASE),
+ .bottom_irq = IRQ_TINT0_TINT12,
+ .top_irq = IRQ_TINT0_TINT34,
+ },
+ {
+ .base = IO_ADDRESS(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_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 00000000000..baaaf328de2
--- /dev/null
+++ b/arch/arm/mach-davinci/dm355.c
@@ -0,0 +1,730 @@
+/*
+ * 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/kernel.h>
+#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/clock.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 "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 cant' 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 davinci_clk 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("soc-audio.0", NULL, &asp0_clk),
+ CLK("soc-audio.1", NULL, &asp1_clk),
+ CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
+ CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
+ CLK(NULL, "spi0", &spi0_clk),
+ CLK(NULL, "spi1", &spi1_clk),
+ CLK(NULL, "spi2", &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_1,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* Not yet used, so not included:
+ * IORESOURCE_IRQ:
+ * - IRQ_DM355_SPINT0_0
+ * IORESOURCE_DMA:
+ * - DAVINCI_DMA_SPI_SPIX
+ * - DAVINCI_DMA_SPI_SPIR
+ */
+};
+
+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),
+ },
+ .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 PINMUX0 0x00
+#define PINMUX1 0x04
+#define PINMUX2 0x08
+#define PINMUX3 0x0c
+#define PINMUX4 0x10
+#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)
+#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 dma_chan_dm355_no_event[] = {
+ 12, 13, 24, 56, 57,
+ 58, 59, 60, 61, 62,
+ 63,
+ -1
+};
+
+static struct edma_soc_info dm355_edma_info = {
+ .n_channel = 64,
+ .n_region = 4,
+ .n_slot = 128,
+ .n_tc = 2,
+ .noevent = dma_chan_dm355_no_event,
+};
+
+static struct resource edma_resources[] = {
+ {
+ .name = "edma_cc",
+ .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,
+ },
+ {
+ .start = IRQ_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* not using (or muxing) TC*_ERR */
+};
+
+static struct platform_device dm355_edma_device = {
+ .name = "edma",
+ .id = -1,
+ .dev.platform_data = &dm355_edma_info,
+ .num_resources = ARRAY_SIZE(edma_resources),
+ .resource = edma_resources,
+};
+
+/*----------------------------------------------------------------------*/
+
+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,
+ /* MT_MEMORY_NONCACHED requires supersection alignment */
+ .type = MT_DEVICE,
+ },
+};
+
+/* 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 void __iomem *dm355_psc_bases[] = {
+ IO_ADDRESS(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>
+ */
+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_base = IO_ADDRESS(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 = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE),
+ .pinmux_pins = dm355_pins,
+ .pinmux_pins_num = ARRAY_SIZE(dm355_pins),
+ .intc_base = IO_ADDRESS(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,
+ .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE),
+ .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE),
+ .gpio_num = 104,
+ .gpio_irq = IRQ_DM355_GPIOBNK0,
+ .serial_dev = &dm355_serial_device,
+ .sram_dma = 0x00010000,
+ .sram_len = SZ_32K,
+};
+
+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;
+
+ davinci_cfg_reg(DM355_INT_EDMA_CC);
+ platform_device_register(&dm355_edma_device);
+ return 0;
+}
+postcore_initcall(dm355_init_devices);
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index d428ef192ea..fb5449b3c97 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -11,7 +11,11 @@
#include <linux/kernel.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/dm644x.h>
#include <mach/clock.h>
@@ -20,6 +24,9 @@
#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 "clock.h"
#include "mux.h"
@@ -312,7 +319,14 @@ struct davinci_clk dm644x_clks[] = {
CLK(NULL, NULL, NULL),
};
-#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE)
+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,
+ .mdio_reg_offset = DM644X_EMAC_MDIO_OFFSET,
+ .ctrl_ram_size = DM644X_EMAC_CNTRL_RAM_SIZE,
+ .version = EMAC_VERSION_1,
+};
static struct resource dm644x_emac_resources[] = {
{
@@ -330,11 +344,15 @@ static struct resource dm644x_emac_resources[] = {
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,
};
-#endif
+#define PINMUX0 0x00
+#define PINMUX1 0x04
/*
* Device specific mux setup
@@ -343,6 +361,7 @@ static struct platform_device dm644x_emac_device = {
* 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)
@@ -383,8 +402,76 @@ 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,
+};
/*----------------------------------------------------------------------*/
@@ -444,10 +531,118 @@ static struct platform_device dm644x_edma_device = {
};
/*----------------------------------------------------------------------*/
+
+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,
+ /* MT_MEMORY_NONCACHED requires supersection alignment */
+ .type = MT_DEVICE,
+ },
+};
+
+/* 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",
+ },
+};
+
+static void __iomem *dm644x_psc_bases[] = {
+ IO_ADDRESS(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>
+ */
+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_base = IO_ADDRESS(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 = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE),
+ .pinmux_pins = dm644x_pins,
+ .pinmux_pins_num = ARRAY_SIZE(dm644x_pins),
+ .intc_base = IO_ADDRESS(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,
+ .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE),
+ .gpio_base = IO_ADDRESS(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,
+};
+
void __init dm644x_init(void)
{
- davinci_clk_init(dm644x_clks);
- davinci_mux_register(dm644x_pins, ARRAY_SIZE(dm644x_pins));
+ davinci_common_init(&davinci_soc_info_dm644x);
}
static int __init dm644x_init_devices(void)
@@ -456,6 +651,7 @@ static int __init dm644x_init_devices(void)
return 0;
platform_device_register(&dm644x_edma_device);
+ platform_device_register(&dm644x_emac_device);
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 00000000000..334f0711e0f
--- /dev/null
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -0,0 +1,636 @@
+/*
+ * 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/kernel.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/clock.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 "clock.h"
+#include "mux.h"
+
+/*
+ * Device specific clocks
+ */
+#define DM646X_REF_FREQ 27000000
+#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",
+ .rate = DM646X_REF_FREQ,
+};
+
+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 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 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 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,
+};
+
+struct davinci_clk 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, "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(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(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,
+ .mdio_reg_offset = DM646X_EMAC_MDIO_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 + 0x47ff,
+ .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,
+};
+
+#define PINMUX0 0x00
+#define PINMUX1 0x04
+
+/*
+ * 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, 1, 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,
+};
+
+/*----------------------------------------------------------------------*/
+
+static const s8 dma_chan_dm646x_no_event[] = {
+ 0, 1, 2, 3, 13,
+ 14, 15, 24, 25, 26,
+ 27, 30, 31, 54, 55,
+ 56,
+ -1
+};
+
+static struct edma_soc_info dm646x_edma_info = {
+ .n_channel = 64,
+ .n_region = 6, /* 0-1, 4-7 */
+ .n_slot = 512,
+ .n_tc = 4,
+ .noevent = dma_chan_dm646x_no_event,
+};
+
+static struct resource edma_resources[] = {
+ {
+ .name = "edma_cc",
+ .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,
+ },
+ {
+ .start = IRQ_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* not using TC*_ERR */
+};
+
+static struct platform_device dm646x_edma_device = {
+ .name = "edma",
+ .id = -1,
+ .dev.platform_data = &dm646x_edma_info,
+ .num_resources = ARRAY_SIZE(edma_resources),
+ .resource = edma_resources,
+};
+
+/*----------------------------------------------------------------------*/
+
+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,
+ /* MT_MEMORY_NONCACHED requires supersection alignment */
+ .type = MT_DEVICE,
+ },
+};
+
+/* 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",
+ },
+};
+
+static void __iomem *dm646x_psc_bases[] = {
+ IO_ADDRESS(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>
+ */
+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_base = IO_ADDRESS(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 = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE),
+ .pinmux_pins = dm646x_pins,
+ .pinmux_pins_num = ARRAY_SIZE(dm646x_pins),
+ .intc_base = IO_ADDRESS(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,
+ .wdt_base = IO_ADDRESS(DAVINCI_WDOG_BASE),
+ .gpio_base = IO_ADDRESS(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,
+};
+
+void __init dm646x_init(void)
+{
+ 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_edma_device);
+ platform_device_register(&dm646x_emac_device);
+ return 0;
+}
+postcore_initcall(dm646x_init_devices);
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index 1aba41c6351..1b6532159c5 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -23,6 +23,7 @@
#include <mach/cputype.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
+#include <mach/common.h>
#include <mach/gpio.h>
#include <asm/mach/irq.h>
@@ -37,14 +38,13 @@ struct davinci_gpio {
static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
-static unsigned __initdata ngpio;
-
/* create a non-inlined version */
static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio)
{
return __gpio_to_controller(gpio);
}
+static int __init davinci_gpio_irq_setup(void);
/*--------------------------------------------------------------------------*/
@@ -115,23 +115,16 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
static int __init davinci_gpio_setup(void)
{
int i, base;
+ unsigned ngpio;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
- /* The gpio banks conceptually expose a segmented bitmap,
+ /*
+ * The gpio banks conceptually expose a segmented bitmap,
* and "ngpio" is one more than the largest zero-based
* bit index that's valid.
*/
- if (cpu_is_davinci_dm355()) { /* or dm335() */
- ngpio = 104;
- } else if (cpu_is_davinci_dm644x()) { /* or dm337() */
- ngpio = 71;
- } else if (cpu_is_davinci_dm646x()) {
- /* NOTE: each bank has several "reserved" bits,
- * unusable as GPIOs. Only 33 of the GPIO numbers
- * are usable, and we're not rejecting the others.
- */
- ngpio = 43;
- } else {
- /* if cpu_is_davinci_dm643x() ngpio = 111 */
+ ngpio = soc_info->gpio_num;
+ if (ngpio == 0) {
pr_err("GPIO setup: how many GPIOs?\n");
return -EINVAL;
}
@@ -157,6 +150,7 @@ static int __init davinci_gpio_setup(void)
gpiochip_add(&chips[i].chip);
}
+ davinci_gpio_irq_setup();
return 0;
}
pure_initcall(davinci_gpio_setup);
@@ -187,10 +181,15 @@ static void gpio_irq_enable(unsigned irq)
{
struct gpio_controller *__iomem g = get_irq_chip_data(irq);
u32 mask = __gpio_mask(irq_to_gpio(irq));
+ unsigned status = irq_desc[irq].status;
+
+ status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
+ if (!status)
+ status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
- if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING)
+ if (status & IRQ_TYPE_EDGE_FALLING)
__raw_writel(mask, &g->set_falling);
- if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING)
+ if (status & IRQ_TYPE_EDGE_RISING)
__raw_writel(mask, &g->set_rising);
}
@@ -205,10 +204,13 @@ static int gpio_irq_type(unsigned irq, unsigned trigger)
irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
irq_desc[irq].status |= trigger;
- __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
- ? &g->set_falling : &g->clr_falling);
- __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
- ? &g->set_rising : &g->clr_rising);
+ /* don't enable the IRQ if it's currently disabled */
+ if (irq_desc[irq].depth == 0) {
+ __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;
}
@@ -230,6 +232,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
mask <<= 16;
/* temporarily mask (level sensitive) parent IRQ */
+ desc->chip->mask(irq);
desc->chip->ack(irq);
while (1) {
u32 status;
@@ -268,17 +271,15 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
static int __init davinci_gpio_irq_setup(void)
{
unsigned gpio, irq, bank;
- unsigned bank_irq;
struct clk *clk;
u32 binten = 0;
+ unsigned ngpio, bank_irq;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ ngpio = soc_info->gpio_num;
- if (cpu_is_davinci_dm355()) { /* or dm335() */
- bank_irq = IRQ_DM355_GPIOBNK0;
- } else if (cpu_is_davinci_dm644x()) {
- bank_irq = IRQ_GPIOBNK0;
- } else if (cpu_is_davinci_dm646x()) {
- bank_irq = IRQ_DM646X_GPIOBNK0;
- } else {
+ bank_irq = soc_info->gpio_irq;
+ if (bank_irq == 0) {
printk(KERN_ERR "Don't know first GPIO bank IRQ.\n");
return -EINVAL;
}
@@ -318,11 +319,9 @@ static int __init davinci_gpio_irq_setup(void)
/* BINTEN -- per-bank interrupt enable. genirq would also let these
* bits be set/cleared dynamically.
*/
- __raw_writel(binten, (void *__iomem)
- IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
+ __raw_writel(binten, soc_info->gpio_base + 0x08);
printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
return 0;
}
-arch_initcall(davinci_gpio_irq_setup);
diff --git a/arch/arm/mach-davinci/id.c b/arch/arm/mach-davinci/id.c
deleted file mode 100644
index 018b994cd79..00000000000
--- a/arch/arm/mach-davinci/id.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Davinci CPU identification code
- *
- * Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.com>
- *
- * Derived from OMAP1 CPU identification code.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-
-#define JTAG_ID_BASE IO_ADDRESS(0x01c40028)
-
-static unsigned int davinci_revision;
-
-struct davinci_id {
- u8 variant; /* JTAG ID bits 31:28 */
- u16 part_no; /* JTAG ID bits 27:12 */
- u32 manufacturer; /* JTAG ID bits 11:1 */
- u32 type; /* Cpu id bits [31:8], cpu class bits [7:0] */
-};
-
-/* Register values to detect the DaVinci version */
-static struct davinci_id davinci_ids[] __initdata = {
- {
- /* DM6446 */
- .part_no = 0xb700,
- .variant = 0x0,
- .manufacturer = 0x017,
- .type = 0x64460000,
- },
- {
- /* DM646X */
- .part_no = 0xb770,
- .variant = 0x0,
- .manufacturer = 0x017,
- .type = 0x64670000,
- },
- {
- /* DM355 */
- .part_no = 0xb73b,
- .variant = 0x0,
- .manufacturer = 0x00f,
- .type = 0x03550000,
- },
-};
-
-/*
- * Get Device Part No. from JTAG ID register
- */
-static u16 __init davinci_get_part_no(void)
-{
- u32 dev_id, part_no;
-
- dev_id = __raw_readl(JTAG_ID_BASE);
-
- part_no = ((dev_id >> 12) & 0xffff);
-
- return part_no;
-}
-
-/*
- * Get Device Revision from JTAG ID register
- */
-static u8 __init davinci_get_variant(void)
-{
- u32 variant;
-
- variant = __raw_readl(JTAG_ID_BASE);
-
- variant = (variant >> 28) & 0xf;
-
- return variant;
-}
-
-unsigned int davinci_rev(void)
-{
- return davinci_revision >> 16;
-}
-EXPORT_SYMBOL(davinci_rev);
-
-void __init davinci_check_revision(void)
-{
- int i;
- u16 part_no;
- u8 variant;
-
- part_no = davinci_get_part_no();
- variant = davinci_get_variant();
-
- /* First check only the major version in a safe way */
- for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
- if (part_no == (davinci_ids[i].part_no)) {
- davinci_revision = davinci_ids[i].type;
- break;
- }
- }
-
- /* Check if we can find the dev revision */
- for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
- if (part_no == davinci_ids[i].part_no &&
- variant == davinci_ids[i].variant) {
- davinci_revision = davinci_ids[i].type;
- break;
- }
- }
-
- printk(KERN_INFO "DaVinci DM%04x variant 0x%x\n",
- davinci_rev(), variant);
-}
diff --git a/arch/arm/mach-davinci/include/mach/board-dm6446evm.h b/arch/arm/mach-davinci/include/mach/board-dm6446evm.h
deleted file mode 100644
index 3216f21c123..00000000000
--- a/arch/arm/mach-davinci/include/mach/board-dm6446evm.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * DaVinci DM6446 EVM board specific headers
- *
- * 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 ifndef.
- */
-
-#ifndef _MACH_DAVINCI_DM6446EVM_H
-#define _MACH_DAVINCI_DM6446EVM_H
-
-#include <linux/types.h>
-
-int dm6446evm_eeprom_read(char *buf, off_t off, size_t count);
-int dm6446evm_eeprom_write(char *buf, off_t off, size_t count);
-
-#endif
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 19177097625..a1f03b606d8 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -17,7 +17,8 @@ struct sys_timer;
extern struct sys_timer davinci_timer;
extern void davinci_irq_init(void);
-extern void davinci_map_common_io(void);
+extern void __iomem *davinci_intc_base;
+extern int davinci_intc_type;
/* parameters describe VBUS sourcing for host mode */
extern void setup_usb(unsigned mA, unsigned potpgt_msec);
@@ -25,4 +26,56 @@ extern void setup_usb(unsigned mA, unsigned potpgt_msec);
/* parameters describe VBUS sourcing for host mode */
extern void setup_usb(unsigned mA, unsigned potpgt_msec);
+struct davinci_timer_instance {
+ void __iomem *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;
+};
+
+/* SoC specific init support */
+struct davinci_soc_info {
+ struct map_desc *io_desc;
+ unsigned long io_desc_num;
+ u32 cpu_id;
+ u32 jtag_id;
+ void __iomem *jtag_id_base;
+ struct davinci_id *ids;
+ unsigned long ids_num;
+ struct davinci_clk *cpu_clks;
+ void __iomem **psc_bases;
+ unsigned long psc_bases_num;
+ void __iomem *pinmux_base;
+ const struct mux_config *pinmux_pins;
+ unsigned long pinmux_pins_num;
+ void __iomem *intc_base;
+ int intc_type;
+ u8 *intc_irq_prios;
+ unsigned long intc_irq_num;
+ struct davinci_timer_info *timer_info;
+ void __iomem *wdt_base;
+ void __iomem *gpio_base;
+ unsigned gpio_num;
+ unsigned gpio_irq;
+ struct platform_device *serial_dev;
+ struct emac_platform_data *emac_pdata;
+ dma_addr_t sram_dma;
+ unsigned sram_len;
+};
+
+extern struct davinci_soc_info davinci_soc_info;
+
+extern void davinci_common_init(struct davinci_soc_info *soc_info);
+
+/* 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 00000000000..c4d27eec806
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cp_intc.h
@@ -0,0 +1,57 @@
+/*
+ * 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 __iomem *base, unsigned short num_irq,
+ u8 *irq_prio);
+
+#endif /* __ASM_HARDWARE_CP_INTC_H */
diff --git a/arch/arm/mach-davinci/include/mach/cputype.h b/arch/arm/mach-davinci/include/mach/cputype.h
index 27cfb1b3a66..d12a5ed2959 100644
--- a/arch/arm/mach-davinci/include/mach/cputype.h
+++ b/arch/arm/mach-davinci/include/mach/cputype.h
@@ -16,17 +16,30 @@
#ifndef _ASM_ARCH_CPU_H
#define _ASM_ARCH_CPU_H
-extern unsigned int davinci_rev(void);
+#include <mach/common.h>
-#define IS_DAVINCI_CPU(type, id) \
-static inline int is_davinci_dm ##type(void) \
-{ \
- return (davinci_rev() == (id)) ? 1 : 0; \
+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 IS_DAVINCI_CPU(type, id) \
+static inline int is_davinci_ ##type(void) \
+{ \
+ return (davinci_soc_info.cpu_id == (id)); \
}
-IS_DAVINCI_CPU(644x, 0x6446)
-IS_DAVINCI_CPU(646x, 0x6467)
-IS_DAVINCI_CPU(355, 0x355)
+IS_DAVINCI_CPU(dm644x, DAVINCI_CPU_ID_DM6446)
+IS_DAVINCI_CPU(dm646x, DAVINCI_CPU_ID_DM6467)
+IS_DAVINCI_CPU(dm355, DAVINCI_CPU_ID_DM355)
#ifdef CONFIG_ARCH_DAVINCI_DM644x
#define cpu_is_davinci_dm644x() is_davinci_dm644x()
diff --git a/arch/arm/mach-davinci/include/mach/debug-macro.S b/arch/arm/mach-davinci/include/mach/debug-macro.S
index e6c0f0d5d06..de3fc2182b4 100644
--- a/arch/arm/mach-davinci/include/mach/debug-macro.S
+++ b/arch/arm/mach-davinci/include/mach/debug-macro.S
@@ -9,6 +9,16 @@
* 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>
+#define UART_SHIFT 2
+
.macro addruart, rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
@@ -17,5 +27,22 @@
orr \rx, \rx, #0x00c20000 @ UART 0
.endm
-#define UART_SHIFT 2
-#include <asm/hardware/debug-8250.S>
+ .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 00000000000..54903b72438
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/dm355.h
@@ -0,0 +1,22 @@
+/*
+ * 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>
+
+struct spi_board_info;
+
+void __init dm355_init(void);
+void dm355_init_spi0(unsigned chipselect_mask,
+ struct spi_board_info *info, unsigned len);
+
+#endif /* __ASM_ARCH_DM355_H */
diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h
index 3dcb9f4e58b..15d42b92a8c 100644
--- a/arch/arm/mach-davinci/include/mach/dm644x.h
+++ b/arch/arm/mach-davinci/include/mach/dm644x.h
@@ -24,6 +24,7 @@
#include <linux/platform_device.h>
#include <mach/hardware.h>
+#include <mach/emac.h>
#define DM644X_EMAC_BASE (0x01C80000)
#define DM644X_EMAC_CNTRL_OFFSET (0x0000)
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 00000000000..1fc764c8646
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/dm646x.h
@@ -0,0 +1,26 @@
+/*
+ * 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/emac.h>
+
+#define DM646X_EMAC_BASE (0x01C80000)
+#define DM646X_EMAC_CNTRL_OFFSET (0x0000)
+#define DM646X_EMAC_CNTRL_MOD_OFFSET (0x1000)
+#define DM646X_EMAC_CNTRL_RAM_OFFSET (0x2000)
+#define DM646X_EMAC_MDIO_OFFSET (0x4000)
+#define DM646X_EMAC_CNTRL_RAM_SIZE (0x2000)
+
+void __init dm646x_init(void);
+
+#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
index f6fc5396daf..24a379239d7 100644
--- a/arch/arm/mach-davinci/include/mach/edma.h
+++ b/arch/arm/mach-davinci/include/mach/edma.h
@@ -208,10 +208,6 @@ void edma_clear_event(unsigned channel);
void edma_pause(unsigned channel);
void edma_resume(unsigned channel);
-/* UNRELATED TO DMA */
-int davinci_alloc_iram(unsigned size);
-void davinci_free_iram(unsigned addr, unsigned size);
-
/* platform_data for EDMA driver */
struct edma_soc_info {
diff --git a/arch/arm/mach-davinci/include/mach/emac.h b/arch/arm/mach-davinci/include/mach/emac.h
new file mode 100644
index 00000000000..beff4fb7c84
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/emac.h
@@ -0,0 +1,36 @@
+/*
+ * TI DaVinci EMAC platform support
+ *
+ * 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 _MACH_DAVINCI_EMAC_H
+#define _MACH_DAVINCI_EMAC_H
+
+#include <linux/if_ether.h>
+#include <linux/memory.h>
+
+struct emac_platform_data {
+ char mac_addr[ETH_ALEN];
+ u32 ctrl_reg_offset;
+ u32 ctrl_mod_reg_offset;
+ u32 ctrl_ram_offset;
+ u32 mdio_reg_offset;
+ u32 ctrl_ram_size;
+ u32 phy_mask;
+ u32 mdio_max_freq;
+ u8 rmii_en;
+ u8 version;
+};
+
+enum {
+ EMAC_VERSION_1, /* DM644x */
+ EMAC_VERSION_2, /* DM646x */
+};
+
+void davinci_get_mac_addr(struct memory_accessor *mem_acc, void *context);
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/entry-macro.S b/arch/arm/mach-davinci/include/mach/entry-macro.S
index 039b84f933b..fbdebc7cb40 100644
--- a/arch/arm/mach-davinci/include/mach/entry-macro.S
+++ b/arch/arm/mach-davinci/include/mach/entry-macro.S
@@ -15,17 +15,36 @@
.endm
.macro get_irqnr_preamble, base, tmp
- ldr \base, =IO_ADDRESS(DAVINCI_ARM_INTC_BASE)
+ 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]
- mov \tmp, \tmp, lsr #2
+ movs \tmp, \tmp, lsr #2
sub \irqnr, \tmp, #1
- cmp \tmp, #0
+ 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
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h
index efe3281364e..ae074556831 100644
--- a/arch/arm/mach-davinci/include/mach/gpio.h
+++ b/arch/arm/mach-davinci/include/mach/gpio.h
@@ -17,6 +17,7 @@
#include <asm-generic/gpio.h>
#include <mach/irqs.h>
+#include <mach/common.h>
#define DAVINCI_GPIO_BASE 0x01C67000
@@ -67,15 +68,16 @@ static inline struct gpio_controller *__iomem
__gpio_to_controller(unsigned gpio)
{
void *__iomem ptr;
+ void __iomem *base = davinci_soc_info.gpio_base;
if (gpio < 32 * 1)
- ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10);
+ ptr = base + 0x10;
else if (gpio < 32 * 2)
- ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38);
+ ptr = base + 0x38;
else if (gpio < 32 * 3)
- ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60);
+ ptr = base + 0x60;
else if (gpio < 32 * 4)
- ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x88);
+ ptr = base + 0x88;
else
ptr = NULL;
return ptr;
@@ -142,13 +144,13 @@ static inline int gpio_to_irq(unsigned gpio)
{
if (gpio >= DAVINCI_N_GPIO)
return -EINVAL;
- return DAVINCI_N_AINTC_IRQ + gpio;
+ return davinci_soc_info.intc_irq_num + gpio;
}
static inline int irq_to_gpio(unsigned irq)
{
/* caller guarantees gpio_to_irq() succeeded */
- return irq - DAVINCI_N_AINTC_IRQ;
+ return irq - davinci_soc_info.intc_irq_num;
}
#endif /* __DAVINCI_GPIO_H */
diff --git a/arch/arm/mach-davinci/include/mach/irqs.h b/arch/arm/mach-davinci/include/mach/irqs.h
index 18066074c99..bc5d6aaa69a 100644
--- a/arch/arm/mach-davinci/include/mach/irqs.h
+++ b/arch/arm/mach-davinci/include/mach/irqs.h
@@ -30,6 +30,9 @@
/* 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
diff --git a/arch/arm/mach-davinci/include/mach/memory.h b/arch/arm/mach-davinci/include/mach/memory.h
index 86c25c7f3ce..c712c7cdf38 100644
--- a/arch/arm/mach-davinci/include/mach/memory.h
+++ b/arch/arm/mach-davinci/include/mach/memory.h
@@ -21,7 +21,6 @@
* Definitions
**************************************************************************/
#define DAVINCI_DDR_BASE 0x80000000
-#define DAVINCI_IRAM_BASE 0x00008000 /* ARM Internal RAM */
#define PHYS_OFFSET DAVINCI_DDR_BASE
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 00000000000..5a85e24f367
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/mmc.h
@@ -0,0 +1,33 @@
+/*
+ * 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;
+};
+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
index bae22cb3e27..27378458542 100644
--- a/arch/arm/mach-davinci/include/mach/mux.h
+++ b/arch/arm/mach-davinci/include/mach/mux.h
@@ -19,16 +19,6 @@
#ifndef __INC_MACH_MUX_H
#define __INC_MACH_MUX_H
-/* System module registers */
-#define PINMUX0 0x00
-#define PINMUX1 0x04
-/* dm355 only */
-#define PINMUX2 0x08
-#define PINMUX3 0x0c
-#define PINMUX4 0x10
-#define INTMUX 0x18
-#define EVTMUX 0x1c
-
struct mux_config {
const char *name;
const char *mux_reg_name;
@@ -168,15 +158,9 @@ enum davinci_dm355_index {
#ifdef CONFIG_DAVINCI_MUX
/* setup pin muxing */
-extern void davinci_mux_init(void);
-extern int davinci_mux_register(const struct mux_config *pins,
- unsigned long size);
extern int davinci_cfg_reg(unsigned long reg_cfg);
#else
/* boot loader does it all (no warnings from CONFIG_DAVINCI_MUX_WARNINGS) */
-static inline void davinci_mux_init(void) {}
-static inline int davinci_mux_register(const struct mux_config *pins,
- unsigned long size) { return 0; }
static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; }
#endif
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h
index 55a90d419fa..ab8a2586d1c 100644
--- a/arch/arm/mach-davinci/include/mach/psc.h
+++ b/arch/arm/mach-davinci/include/mach/psc.h
@@ -27,6 +27,8 @@
#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
@@ -116,8 +118,8 @@
#define DM646X_LPSC_TIMER1 35
#define DM646X_LPSC_ARM_INTC 45
-extern int davinci_psc_is_clk_active(unsigned int id);
-extern void davinci_psc_config(unsigned int domain, unsigned int id,
- char enable);
+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, char enable);
#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
index 632847d74a1..794fa5cf93c 100644
--- a/arch/arm/mach-davinci/include/mach/serial.h
+++ b/arch/arm/mach-davinci/include/mach/serial.h
@@ -18,8 +18,6 @@
#define DAVINCI_UART1_BASE (IO_PHYS + 0x20400)
#define DAVINCI_UART2_BASE (IO_PHYS + 0x20800)
-#define DM355_UART2_BASE (IO_PHYS + 0x206000)
-
/* DaVinci UART register offsets */
#define UART_DAVINCI_PWREMU 0x0c
#define UART_DM646X_SCR 0x10
@@ -30,6 +28,6 @@ struct davinci_uart_config {
unsigned int enabled_uarts;
};
-extern void davinci_serial_init(struct davinci_uart_config *);
+extern int davinci_serial_init(struct davinci_uart_config *);
#endif /* __ASM_ARCH_SERIAL_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 00000000000..111f7cc71e0
--- /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/time.h b/arch/arm/mach-davinci/include/mach/time.h
new file mode 100644
index 00000000000..1c971d8d8ba
--- /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/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h
index 8c165def37b..1e27475f9a2 100644
--- a/arch/arm/mach-davinci/include/mach/uncompress.h
+++ b/arch/arm/mach-davinci/include/mach/uncompress.h
@@ -13,11 +13,24 @@
#include <linux/serial_reg.h>
#include <mach/serial.h>
+#include <asm/mach-types.h>
+
+extern unsigned int __machine_arch_type;
+
+static u32 *uart;
+
+static u32 *get_uart_base(void)
+{
+ /* Add logic here for new platforms, using __macine_arch_type */
+ return (u32 *)DAVINCI_UART0_BASE;
+}
+
/* PORT_16C550A, in polled non-fifo mode */
static void putc(char c)
{
- volatile u32 *uart = (volatile void *) DAVINCI_UART0_BASE;
+ if (!uart)
+ uart = get_uart_base();
while (!(uart[UART_LSR] & UART_LSR_THRE))
barrier();
@@ -26,7 +39,9 @@ static void putc(char c)
static inline void flush(void)
{
- volatile u32 *uart = (volatile void *) DAVINCI_UART0_BASE;
+ if (!uart)
+ uart = get_uart_base();
+
while (!(uart[UART_LSR] & UART_LSR_THRE))
barrier();
}
diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c
index a548abb513e..49912b48b1b 100644
--- a/arch/arm/mach-davinci/io.c
+++ b/arch/arm/mach-davinci/io.c
@@ -9,47 +9,9 @@
*/
#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
#include <linux/io.h>
#include <asm/tlb.h>
-#include <asm/memory.h>
-
-#include <asm/mach/map.h>
-#include <mach/clock.h>
-
-extern void davinci_check_revision(void);
-
-/*
- * The machine specific code may provide the extra mapping besides the
- * default mapping provided here.
- */
-static struct map_desc davinci_io_desc[] __initdata = {
- {
- .virtual = IO_VIRT,
- .pfn = __phys_to_pfn(IO_PHYS),
- .length = IO_SIZE,
- .type = MT_DEVICE
- },
-};
-
-void __init davinci_map_common_io(void)
-{
- iotable_init(davinci_io_desc, ARRAY_SIZE(davinci_io_desc));
-
- /* Normally devicemaps_init() would flush caches and tlb after
- * mdesc->map_io(), but we must also do it here because of the CPU
- * revision check below.
- */
- local_flush_tlb_all();
- flush_cache_all();
-
- /* We want to check CPU revision early for cpu_is_xxxx() macros.
- * IO space mapping must be initialized before we can do that.
- */
- davinci_check_revision();
-}
#define BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz)))
#define XLATE(p, pst, vst) ((void __iomem *)((p) - (pst) + (vst)))
diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
index 5a324c90e29..af92ffee847 100644
--- a/arch/arm/mach-davinci/irq.c
+++ b/arch/arm/mach-davinci/irq.c
@@ -26,6 +26,7 @@
#include <mach/hardware.h>
#include <mach/cputype.h>
+#include <mach/common.h>
#include <asm/mach/irq.h>
#define IRQ_BIT(irq) ((irq) & 0x1f)
@@ -41,18 +42,14 @@
#define IRQ_INTPRI0_REG_OFFSET 0x0030
#define IRQ_INTPRI7_REG_OFFSET 0x004C
-const u8 *davinci_def_priorities;
-
-#define INTC_BASE IO_ADDRESS(DAVINCI_ARM_INTC_BASE)
-
static inline unsigned int davinci_irq_readl(int offset)
{
- return __raw_readl(INTC_BASE + offset);
+ return __raw_readl(davinci_intc_base + offset);
}
static inline void davinci_irq_writel(unsigned long value, int offset)
{
- __raw_writel(value, INTC_BASE + offset);
+ __raw_writel(value, davinci_intc_base + offset);
}
/* Disable interrupt */
@@ -113,217 +110,11 @@ static struct irq_chip davinci_irq_chip_0 = {
.unmask = davinci_unmask_irq,
};
-/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
-static const u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] __initdata = {
- [IRQ_VDINT0] = 2,
- [IRQ_VDINT1] = 6,
- [IRQ_VDINT2] = 6,
- [IRQ_HISTINT] = 6,
- [IRQ_H3AINT] = 6,
- [IRQ_PRVUINT] = 6,
- [IRQ_RSZINT] = 6,
- [7] = 7,
- [IRQ_VENCINT] = 6,
- [IRQ_ASQINT] = 6,
- [IRQ_IMXINT] = 6,
- [IRQ_VLCDINT] = 6,
- [IRQ_USBINT] = 4,
- [IRQ_EMACINT] = 4,
- [14] = 7,
- [15] = 7,
- [IRQ_CCINT0] = 5, /* dma */
- [IRQ_CCERRINT] = 5, /* dma */
- [IRQ_TCERRINT0] = 5, /* dma */
- [IRQ_TCERRINT] = 5, /* dma */
- [IRQ_PSCIN] = 7,
- [21] = 7,
- [IRQ_IDE] = 4,
- [23] = 7,
- [IRQ_MBXINT] = 7,
- [IRQ_MBRINT] = 7,
- [IRQ_MMCINT] = 7,
- [IRQ_SDIOINT] = 7,
- [28] = 7,
- [IRQ_DDRINT] = 7,
- [IRQ_AEMIFINT] = 7,
- [IRQ_VLQINT] = 4,
- [IRQ_TINT0_TINT12] = 2, /* clockevent */
- [IRQ_TINT0_TINT34] = 2, /* clocksource */
- [IRQ_TINT1_TINT12] = 7, /* DSP timer */
- [IRQ_TINT1_TINT34] = 7, /* system tick */
- [IRQ_PWMINT0] = 7,
- [IRQ_PWMINT1] = 7,
- [IRQ_PWMINT2] = 7,
- [IRQ_I2C] = 3,
- [IRQ_UARTINT0] = 3,
- [IRQ_UARTINT1] = 3,
- [IRQ_UARTINT2] = 3,
- [IRQ_SPINT0] = 3,
- [IRQ_SPINT1] = 3,
- [45] = 7,
- [IRQ_DSP2ARM0] = 4,
- [IRQ_DSP2ARM1] = 4,
- [IRQ_GPIO0] = 7,
- [IRQ_GPIO1] = 7,
- [IRQ_GPIO2] = 7,
- [IRQ_GPIO3] = 7,
- [IRQ_GPIO4] = 7,
- [IRQ_GPIO5] = 7,
- [IRQ_GPIO6] = 7,
- [IRQ_GPIO7] = 7,
- [IRQ_GPIOBNK0] = 7,
- [IRQ_GPIOBNK1] = 7,
- [IRQ_GPIOBNK2] = 7,
- [IRQ_GPIOBNK3] = 7,
- [IRQ_GPIOBNK4] = 7,
- [IRQ_COMMTX] = 7,
- [IRQ_COMMRX] = 7,
- [IRQ_EMUINT] = 7,
-};
-
-static const 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,
-};
-
-static const 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,
-};
-
/* ARM Interrupt Controller Initialization */
void __init davinci_irq_init(void)
{
unsigned i;
-
- if (cpu_is_davinci_dm644x())
- davinci_def_priorities = dm644x_default_priorities;
- else if (cpu_is_davinci_dm646x())
- davinci_def_priorities = dm646x_default_priorities;
- else if (cpu_is_davinci_dm355())
- davinci_def_priorities = dm355_default_priorities;
+ const u8 *davinci_def_priorities = davinci_soc_info.intc_irq_prios;
/* Clear all interrupt requests */
davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c
index bbba0b247a4..d310f579aa8 100644
--- a/arch/arm/mach-davinci/mux.c
+++ b/arch/arm/mach-davinci/mux.c
@@ -21,18 +21,7 @@
#include <mach/hardware.h>
#include <mach/mux.h>
-
-static const struct mux_config *mux_table;
-static unsigned long pin_table_sz;
-
-int __init davinci_mux_register(const struct mux_config *pins,
- unsigned long size)
-{
- mux_table = pins;
- pin_table_sz = size;
-
- return 0;
-}
+#include <mach/common.h>
/*
* Sets the DAVINCI MUX register based on the table
@@ -40,23 +29,24 @@ int __init davinci_mux_register(const struct mux_config *pins,
int __init_or_module davinci_cfg_reg(const unsigned long index)
{
static DEFINE_SPINLOCK(mux_spin_lock);
- void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ void __iomem *base = soc_info->pinmux_base;
unsigned long flags;
const struct mux_config *cfg;
unsigned int reg_orig = 0, reg = 0;
unsigned int mask, warn = 0;
- if (!mux_table)
+ if (!soc_info->pinmux_pins)
BUG();
- if (index >= pin_table_sz) {
+ if (index >= soc_info->pinmux_pins_num) {
printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
- index, pin_table_sz);
+ index, soc_info->pinmux_pins_num);
dump_stack();
return -ENODEV;
}
- cfg = &mux_table[index];
+ cfg = &soc_info->pinmux_pins[index];
if (cfg->name == NULL) {
printk(KERN_ERR "No entry for the specified index\n");
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
index 84171abf5f7..a78b657e916 100644
--- a/arch/arm/mach-davinci/psc.c
+++ b/arch/arm/mach-davinci/psc.c
@@ -28,8 +28,6 @@
#include <mach/psc.h>
#include <mach/mux.h>
-#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000
-
/* PSC register offsets */
#define EPCPR 0x070
#define PTCMD 0x120
@@ -42,22 +40,42 @@
#define MDSTAT_STATE_MASK 0x1f
/* Return nonzero iff the domain's clock is active */
-int __init davinci_psc_is_clk_active(unsigned int id)
+int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
{
- void __iomem *psc_base = IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE);
- u32 mdstat = __raw_readl(psc_base + MDSTAT + 4 * 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 = soc_info->psc_bases[ctlr];
+ mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
/* 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 id, char enable)
+void davinci_psc_config(unsigned int domain, unsigned int ctlr,
+ unsigned int id, char enable)
{
u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl;
- void __iomem *psc_base = IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE);
+ void __iomem *psc_base;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
u32 next_state = enable ? 0x3 : 0x2; /* 0x3 enables, 0x2 disables */
+ 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 = soc_info->psc_bases[ctlr];
+
mdctl = __raw_readl(psc_base + MDCTL + 4 * id);
mdctl &= ~MDSTAT_STATE_MASK;
mdctl |= next_state;
diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c
index 69507579652..c530c7333d0 100644
--- a/arch/arm/mach-davinci/serial.c
+++ b/arch/arm/mach-davinci/serial.c
@@ -33,6 +33,8 @@
#include <mach/serial.h>
#include <mach/irqs.h>
#include <mach/cputype.h>
+#include <mach/common.h>
+
#include "clock.h"
static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
@@ -49,44 +51,6 @@ static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
__raw_writel(value, IO_ADDRESS(p->mapbase) + offset);
}
-static struct plat_serial8250_port 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 serial_device = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM,
- .dev = {
- .platform_data = serial_platform_data,
- },
-};
-
static void __init davinci_serial_reset(struct plat_serial8250_port *p)
{
unsigned int pwremu = 0;
@@ -106,35 +70,22 @@ static void __init davinci_serial_reset(struct plat_serial8250_port *p)
UART_DM646X_SCR_TX_WATERMARK);
}
-void __init davinci_serial_init(struct davinci_uart_config *info)
+int __init davinci_serial_init(struct davinci_uart_config *info)
{
int i;
char name[16];
struct clk *uart_clk;
- struct device *dev = &serial_device.dev;
+ 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.
+ * You have to mux them off in device drivers later on if not needed.
*/
- for (i = 0; i < DAVINCI_MAX_NR_UARTS; i++) {
- struct plat_serial8250_port *p = serial_platform_data + i;
-
- if (!(info->enabled_uarts & (1 << i))) {
- p->flags = 0;
+ for (i = 0; i < DAVINCI_MAX_NR_UARTS; i++, p++) {
+ if (!(info->enabled_uarts & (1 << i)))
continue;
- }
-
- if (cpu_is_davinci_dm646x())
- p->iotype = UPIO_MEM32;
-
- if (cpu_is_davinci_dm355()) {
- if (i == 2) {
- p->mapbase = (unsigned long)DM355_UART2_BASE;
- p->irq = IRQ_DM355_UARTINT2;
- }
- }
sprintf(name, "uart%d", i);
uart_clk = clk_get(dev, name);
@@ -147,11 +98,6 @@ void __init davinci_serial_init(struct davinci_uart_config *info)
davinci_serial_reset(p);
}
}
-}
-static int __init davinci_init(void)
-{
- return platform_device_register(&serial_device);
+ return platform_device_register(soc_info->serial_dev);
}
-
-arch_initcall(davinci_init);
diff --git a/arch/arm/mach-davinci/sram.c b/arch/arm/mach-davinci/sram.c
new file mode 100644
index 00000000000..db54b2a66b4
--- /dev/null
+++ b/arch/arm/mach-davinci/sram.c
@@ -0,0 +1,74 @@
+/*
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/genalloc.h>
+
+#include <mach/common.h>
+#include <mach/memory.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(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
index 494e01bff5c..0884ca57bfb 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -19,6 +19,7 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/device.h>
+#include <linux/platform_device.h>
#include <mach/hardware.h>
#include <asm/system.h>
@@ -28,52 +29,41 @@
#include <asm/errno.h>
#include <mach/io.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;
-#define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400)
-#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800)
-#define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00)
-
-enum {
- T0_BOT = 0, T0_TOP, T1_BOT, T1_TOP, NUM_TIMERS,
-};
-
-#define IS_TIMER1(id) (id & 0x2)
-#define IS_TIMER0(id) (!IS_TIMER1(id))
-#define IS_TIMER_TOP(id) ((id & 0x1))
-#define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id))
-
-static int timer_irqs[NUM_TIMERS] = {
- IRQ_TINT0_TINT12,
- IRQ_TINT0_TINT34,
- IRQ_TINT1_TINT12,
- IRQ_TINT1_TINT34,
-};
-
/*
* This driver configures the 2 64-bit count-up timers as 4 independent
* 32-bit count-up timers used as follows:
- *
- * T0_BOT: Timer 0, bottom: clockevent source for hrtimers
- * T0_TOP: Timer 0, top : clocksource for generic timekeeping
- * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code)
- * T1_TOP: Timer 1, top : <unused>
*/
-#define TID_CLOCKEVENT T0_BOT
-#define TID_CLOCKSOURCE T0_TOP
+
+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
+#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
@@ -105,6 +95,7 @@ struct timer_s {
unsigned int id;
unsigned long period;
unsigned long opts;
+ unsigned long flags;
void __iomem *base;
unsigned long tim_off;
unsigned long prd_off;
@@ -114,30 +105,58 @@ struct timer_s {
static struct timer_s timers[];
/* values for 'opts' field of struct timer_s */
-#define TIMER_OPTS_DISABLED 0x00
-#define TIMER_OPTS_ONESHOT 0x01
-#define TIMER_OPTS_PERIODIC 0x02
+#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 = __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;
+ 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);
}
-
- __raw_writel(tcr, t->base + TCR);
return 0;
}
@@ -182,13 +201,14 @@ static struct timer_s timers[] = {
static void __init timer_init(void)
{
- u32 phys_bases[] = {DAVINCI_TIMER0_BASE, DAVINCI_TIMER1_BASE};
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ struct davinci_timer_instance *dtip = soc_info->timer_info->timers;
int i;
/* Global init of each 64-bit timer as a whole */
for(i=0; i<2; i++) {
u32 tgcr;
- void __iomem *base = IO_ADDRESS(phys_bases[i]);
+ void __iomem *base = dtip[i].base;
/* Disabled, Internal clock source */
__raw_writel(0, base + TCR);
@@ -214,33 +234,33 @@ static void __init timer_init(void)
/* Init of each timer as a 32-bit timer */
for (i=0; i< ARRAY_SIZE(timers); i++) {
struct timer_s *t = &timers[i];
- u32 phys_base;
-
- if (t->name) {
- t->id = i;
- phys_base = (IS_TIMER1(t->id) ?
- DAVINCI_TIMER1_BASE : DAVINCI_TIMER0_BASE);
- t->base = IO_ADDRESS(phys_base);
-
- if (IS_TIMER_BOT(t->id)) {
- t->enamode_shift = 6;
- t->tim_off = TIM12;
- t->prd_off = PRD12;
- } else {
- t->enamode_shift = 22;
- t->tim_off = TIM34;
- t->prd_off = PRD34;
- }
-
- /* Register interrupt */
- t->irqaction.name = t->name;
- t->irqaction.dev_id = (void *)t;
- if (t->irqaction.handler != NULL) {
- setup_irq(timer_irqs[t->id], &t->irqaction);
- }
-
- timer32_config(&timers[i]);
+ int timer = ID_TO_TIMER(t->id);
+ u32 irq;
+
+ t->base = dtip[timer].base;
+
+ 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);
}
+
+ timer32_config(&timers[i]);
}
}
@@ -255,7 +275,6 @@ static cycle_t read_cycles(struct clocksource *cs)
}
static struct clocksource clocksource_davinci = {
- .name = "timer0_1",
.rating = 300,
.read = read_cycles,
.mask = CLOCKSOURCE_MASK(32),
@@ -284,15 +303,18 @@ static void davinci_set_mode(enum clock_event_mode mode,
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
t->period = davinci_clock_tick_rate / (HZ);
- t->opts = TIMER_OPTS_PERIODIC;
+ t->opts &= ~TIMER_OPTS_STATE_MASK;
+ t->opts |= TIMER_OPTS_PERIODIC;
timer32_config(t);
break;
case CLOCK_EVT_MODE_ONESHOT:
- t->opts = TIMER_OPTS_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_DISABLED;
+ t->opts &= ~TIMER_OPTS_STATE_MASK;
+ t->opts |= TIMER_OPTS_DISABLED;
break;
case CLOCK_EVT_MODE_RESUME:
break;
@@ -300,7 +322,6 @@ static void davinci_set_mode(enum clock_event_mode mode,
}
static struct clock_event_device clockevent_davinci = {
- .name = "timer0_0",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.shift = 32,
.set_next_event = davinci_set_next_event,
@@ -311,10 +332,42 @@ static struct clock_event_device clockevent_davinci = {
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";
+ 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;
+ }
+ }
+
/* init timer hw */
timer_init();
@@ -325,6 +378,7 @@ static void __init davinci_timer_init(void)
davinci_clock_tick_rate = clk_get_rate(timer_clk);
/* setup clocksource */
+ clocksource_davinci.name = id_to_name[clocksource_id];
clocksource_davinci.mult =
clocksource_khz2mult(davinci_clock_tick_rate/1000,
clocksource_davinci.shift);
@@ -332,12 +386,12 @@ static void __init davinci_timer_init(void)
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 =
- clockevent_delta2ns(1, &clockevent_davinci);
+ clockevent_davinci.min_delta_ns = 50000; /* 50 usec */
clockevent_davinci.cpumask = cpumask_of(0);
clockevents_register_device(&clockevent_davinci);
@@ -349,15 +403,14 @@ struct sys_timer davinci_timer = {
/* reset board using watchdog timer */
-void davinci_watchdog_reset(void) {
+void davinci_watchdog_reset(void)
+{
u32 tgcr, wdtcr;
- void __iomem *base = IO_ADDRESS(DAVINCI_WDOG_BASE);
- struct device dev;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ void __iomem *base = soc_info->wdt_base;
struct clk *wd_clk;
- char *name = "watchdog";
- dev_set_name(&dev, name);
- wd_clk = clk_get(&dev, NULL);
+ wd_clk = clk_get(&davinci_wdt_device.dev, NULL);
if (WARN_ON(IS_ERR(wd_clk)))
return;
clk_enable(wd_clk);