diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2009-05-29 10:04:24 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-05-29 10:04:24 +0100 |
commit | 42f1d2e06a25628ae4ceaadccc4fa67c7787e2b4 (patch) | |
tree | 8aac83e399de7ad13748a59853a0feea9ed2c5cb /arch/arm | |
parent | 9af5324a070e0b2dcb6e22c89e17424eba245fcc (diff) | |
parent | 77bbca138c64cb80259732db6f70e1668123f2a7 (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')
77 files changed, 4058 insertions, 833 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c52f6909f65..65bf774a26f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -281,6 +281,7 @@ config ARCH_EP93XX select HAVE_CLK select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB + select ARCH_HAS_HOLES_MEMORYMODEL help This enables support for the Cirrus EP93xx series of CPUs. @@ -595,6 +596,7 @@ config ARCH_DAVINCI select ZONE_DMA select HAVE_IDE select COMMON_CLKDEV + select GENERIC_ALLOCATOR help Support for TI's DaVinci platform. @@ -965,10 +967,9 @@ config OABI_COMPAT UNPREDICTABLE (in fact it can be predicted that it won't work at all). If in doubt say Y. -config ARCH_FLATMEM_HAS_HOLES +config ARCH_HAS_HOLES_MEMORYMODEL bool - default y - depends on FLATMEM + default n # Discontigmem is deprecated config ARCH_DISCONTIGMEM_ENABLE diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index c6884ba1d5e..3e1714c6523 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -253,9 +253,9 @@ void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base) } #ifdef CONFIG_SMP -void gic_raise_softirq(cpumask_t cpumask, unsigned int irq) +void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) { - unsigned long map = *cpus_addr(cpumask); + unsigned long map = *cpus_addr(*mask); /* this always happens on GIC0 */ writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT); diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig index eb2738b5be5..ac18662f38c 100644 --- a/arch/arm/configs/davinci_all_defconfig +++ b/arch/arm/configs/davinci_all_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.30-rc2 -# Wed Apr 15 08:16:53 2009 +# Linux kernel version: 2.6.30-rc7 +# Tue May 26 07:24:28 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -179,6 +179,7 @@ CONFIG_ARCH_DAVINCI=y # CONFIG_ARCH_OMAP is not set # CONFIG_ARCH_MSM is not set # CONFIG_ARCH_W90X900 is not set +CONFIG_AINTC=y # # TI DaVinci Implementations @@ -188,11 +189,17 @@ CONFIG_ARCH_DAVINCI=y # DaVinci Core Type # CONFIG_ARCH_DAVINCI_DM644x=y +CONFIG_ARCH_DAVINCI_DM355=y +CONFIG_ARCH_DAVINCI_DM646x=y # # DaVinci Board Type # CONFIG_MACH_DAVINCI_EVM=y +CONFIG_MACH_SFFSDR=y +CONFIG_MACH_DAVINCI_DM355_EVM=y +CONFIG_MACH_DM355_LEOPARD=y +CONFIG_MACH_DAVINCI_DM6467_EVM=y CONFIG_DAVINCI_MUX=y CONFIG_DAVINCI_MUX_DEBUG=y CONFIG_DAVINCI_MUX_WARNINGS=y @@ -245,7 +252,7 @@ CONFIG_PREEMPT=y CONFIG_HZ=100 CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set -CONFIG_ARCH_FLATMEM_HAS_HOLES=y +# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set # CONFIG_HIGHMEM is not set @@ -661,7 +668,10 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_AX88796 is not set # CONFIG_SMC91X is not set -# CONFIG_DM9000 is not set +CONFIG_TI_DAVINCI_EMAC=y +CONFIG_DM9000=y +CONFIG_DM9000_DEBUGLEVEL=4 +# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set # CONFIG_ETHOC is not set # CONFIG_SMC911X is not set # CONFIG_SMSC911X is not set @@ -963,6 +973,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_ASIC3 is not set +# CONFIG_MFD_DM355EVM_MSP is not set # CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TPS65010 is not set @@ -1317,6 +1328,7 @@ CONFIG_MMC_BLOCK=m # MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_DAVINCI is not set # CONFIG_MEMSTICK is not set # CONFIG_ACCESSIBILITY is not set CONFIG_NEW_LEDS=y @@ -1778,6 +1790,7 @@ CONFIG_CRC32=y CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 4924914af18..7f34333bb54 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -36,7 +36,7 @@ void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start); void gic_cpu_init(unsigned int gic_nr, void __iomem *base); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); -void gic_raise_softirq(cpumask_t cpumask, unsigned int irq); +void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); #endif #endif diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index fad70da5911..5995935338e 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h @@ -53,17 +53,12 @@ extern void smp_store_cpu_info(unsigned int cpuid); /* * Raise an IPI cross call on CPUs in callmap. */ -extern void smp_cross_call(cpumask_t callmap); - -/* - * Broadcast a timer interrupt to the other CPUs. - */ -extern void smp_send_timer(void); +extern void smp_cross_call(const struct cpumask *mask); /* * Broadcast a clock event to other CPUs. */ -extern void smp_timer_broadcast(cpumask_t mask); +extern void smp_timer_broadcast(const struct cpumask *mask); /* * Boot a secondary CPU, and assign it the specified idle task. @@ -102,7 +97,8 @@ extern int platform_cpu_kill(unsigned int cpu); extern void platform_cpu_enable(unsigned int cpu); extern void arch_send_call_function_single_ipi(int cpu); -extern void arch_send_call_function_ipi(cpumask_t mask); +extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); +#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask /* * Local timer interrupt handling function (can be IPI'ed). diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 7801aac3c04..6014dfd22af 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -326,14 +326,14 @@ void __init smp_prepare_boot_cpu(void) per_cpu(cpu_data, cpu).idle = current; } -static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg) +static void send_ipi_message(const struct cpumask *mask, enum ipi_msg_type msg) { unsigned long flags; unsigned int cpu; local_irq_save(flags); - for_each_cpu_mask(cpu, callmap) { + for_each_cpu(cpu, mask) { struct ipi_data *ipi = &per_cpu(ipi_data, cpu); spin_lock(&ipi->lock); @@ -344,19 +344,19 @@ static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg) /* * Call the platform specific cross-CPU call function. */ - smp_cross_call(callmap); + smp_cross_call(mask); local_irq_restore(flags); } -void arch_send_call_function_ipi(cpumask_t mask) +void arch_send_call_function_ipi_mask(const struct cpumask *mask) { send_ipi_message(mask, IPI_CALL_FUNC); } void arch_send_call_function_single_ipi(int cpu) { - send_ipi_message(cpumask_of_cpu(cpu), IPI_CALL_FUNC_SINGLE); + send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); } void show_ipi_list(struct seq_file *p) @@ -498,17 +498,10 @@ asmlinkage void __exception do_IPI(struct pt_regs *regs) void smp_send_reschedule(int cpu) { - send_ipi_message(cpumask_of_cpu(cpu), IPI_RESCHEDULE); + send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE); } -void smp_send_timer(void) -{ - cpumask_t mask = cpu_online_map; - cpu_clear(smp_processor_id(), mask); - send_ipi_message(mask, IPI_TIMER); -} - -void smp_timer_broadcast(cpumask_t mask) +void smp_timer_broadcast(const struct cpumask *mask) { send_ipi_message(mask, IPI_TIMER); } @@ -517,7 +510,7 @@ void smp_send_stop(void) { cpumask_t mask = cpu_online_map; cpu_clear(smp_processor_id(), mask); - send_ipi_message(mask, IPI_CPU_STOP); + send_ipi_message(&mask, IPI_CPU_STOP); } /* @@ -528,20 +521,17 @@ int setup_profiling_timer(unsigned int multiplier) return -EINVAL; } -static int -on_each_cpu_mask(void (*func)(void *), void *info, int wait, cpumask_t mask) +static void +on_each_cpu_mask(void (*func)(void *), void *info, int wait, + const struct cpumask *mask) { - int ret = 0; - preempt_disable(); - ret = smp_call_function_mask(mask, func, info, wait); - if (cpu_isset(smp_processor_id(), mask)) + smp_call_function_many(mask, func, info, wait); + if (cpumask_test_cpu(smp_processor_id(), mask)) func(info); preempt_enable(); - - return ret; } /**********************************************************************/ @@ -602,20 +592,17 @@ void flush_tlb_all(void) void flush_tlb_mm(struct mm_struct *mm) { - cpumask_t mask = mm->cpu_vm_mask; - - on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mask); + on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, &mm->cpu_vm_mask); } void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) { - cpumask_t mask = vma->vm_mm->cpu_vm_mask; struct tlb_args ta; ta.ta_vma = vma; ta.ta_start = uaddr; - on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mask); + on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, &vma->vm_mm->cpu_vm_mask); } void flush_tlb_kernel_page(unsigned long kaddr) @@ -630,14 +617,13 @@ void flush_tlb_kernel_page(unsigned long kaddr) void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - cpumask_t mask = vma->vm_mm->cpu_vm_mask; struct tlb_args ta; ta.ta_vma = vma; ta.ta_start = start; ta.ta_end = end; - on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mask); + on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, &vma->vm_mm->cpu_vm_mask); } void flush_tlb_kernel_range(unsigned long start, unsigned long end) 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); diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index e8ebeaea6c4..b2eede5531c 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -21,15 +21,50 @@ #include <asm/div64.h> #include <mach/hardware.h> + +/* + * The EP93xx has two external crystal oscillators. To generate the + * required high-frequency clocks, the processor uses two phase-locked- + * loops (PLLs) to multiply the incoming external clock signal to much + * higher frequencies that are then divided down by programmable dividers + * to produce the needed clocks. The PLLs operate independently of one + * another. + */ +#define EP93XX_EXT_CLK_RATE 14745600 +#define EP93XX_EXT_RTC_RATE 32768 + + struct clk { unsigned long rate; int users; + int sw_locked; u32 enable_reg; u32 enable_mask; + + unsigned long (*get_rate)(struct clk *clk); }; -static struct clk clk_uart = { - .rate = 14745600, + +static unsigned long get_uart_rate(struct clk *clk); + + +static struct clk clk_uart1 = { + .sw_locked = 1, + .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, + .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U1EN, + .get_rate = get_uart_rate, +}; +static struct clk clk_uart2 = { + .sw_locked = 1, + .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, + .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U2EN, + .get_rate = get_uart_rate, +}; +static struct clk clk_uart3 = { + .sw_locked = 1, + .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, + .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U3EN, + .get_rate = get_uart_rate, }; static struct clk clk_pll1; static struct clk clk_f; @@ -95,9 +130,9 @@ static struct clk clk_m2m1 = { { .dev_id = dev, .con_id = con, .clk = ck } static struct clk_lookup clocks[] = { - INIT_CK("apb:uart1", NULL, &clk_uart), - INIT_CK("apb:uart2", NULL, &clk_uart), - INIT_CK("apb:uart3", NULL, &clk_uart), + INIT_CK("apb:uart1", NULL, &clk_uart1), + INIT_CK("apb:uart2", NULL, &clk_uart2), + INIT_CK("apb:uart3", NULL, &clk_uart3), INIT_CK(NULL, "pll1", &clk_pll1), INIT_CK(NULL, "fclk", &clk_f), INIT_CK(NULL, "hclk", &clk_h), @@ -125,6 +160,8 @@ int clk_enable(struct clk *clk) u32 value; value = __raw_readl(clk->enable_reg); + if (clk->sw_locked) + __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); __raw_writel(value | clk->enable_mask, clk->enable_reg); } @@ -138,13 +175,29 @@ void clk_disable(struct clk *clk) u32 value; value = __raw_readl(clk->enable_reg); + if (clk->sw_locked) + __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); __raw_writel(value & ~clk->enable_mask, clk->enable_reg); } } EXPORT_SYMBOL(clk_disable); +static unsigned long get_uart_rate(struct clk *clk) +{ + u32 value; + + value = __raw_readl(EP93XX_SYSCON_CLOCK_CONTROL); + if (value & EP93XX_SYSCON_CLOCK_UARTBAUD) + return EP93XX_EXT_CLK_RATE; + else + return EP93XX_EXT_CLK_RATE / 2; +} + unsigned long clk_get_rate(struct clk *clk) { + if (clk->get_rate) + return clk->get_rate(clk); + return clk->rate; } EXPORT_SYMBOL(clk_get_rate); @@ -162,7 +215,7 @@ static unsigned long calc_pll_rate(u32 config_word) unsigned long long rate; int i; - rate = 14745600; + rate = EP93XX_EXT_CLK_RATE; rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */ rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */ do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */ @@ -195,7 +248,7 @@ static int __init ep93xx_clock_init(void) value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1); if (!(value & 0x00800000)) { /* PLL1 bypassed? */ - clk_pll1.rate = 14745600; + clk_pll1.rate = EP93XX_EXT_CLK_RATE; } else { clk_pll1.rate = calc_pll_rate(value); } @@ -206,7 +259,7 @@ static int __init ep93xx_clock_init(void) value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2); if (!(value & 0x00080000)) { /* PLL2 bypassed? */ - clk_pll2.rate = 14745600; + clk_pll2.rate = EP93XX_EXT_CLK_RATE; } else if (value & 0x00040000) { /* PLL2 enabled? */ clk_pll2.rate = calc_pll_rate(value); } else { diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index 78ac1bddc8b..420f71b8512 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h @@ -160,7 +160,10 @@ #define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20) #define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24) #define EP93XX_SYSCON_DEVICE_CONFIG EP93XX_SYSCON_REG(0x80) -#define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE 0x00800000 +#define EP93XX_SYSCON_DEVICE_CONFIG_U3EN (1<<24) +#define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE (1<<23) +#define EP93XX_SYSCON_DEVICE_CONFIG_U2EN (1<<20) +#define EP93XX_SYSCON_DEVICE_CONFIG_U1EN (1<<18) #define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) #define EP93XX_WATCHDOG_BASE (EP93XX_APB_VIRT_BASE + 0x00140000) diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 6f887291307..a0f60e55da6 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -121,7 +121,7 @@ static struct clk uartclk = { .rate = 14745600, }; -static struct clk_lookup lookups[] __initdata = { +static struct clk_lookup lookups[] = { { /* UART0 */ .dev_id = "mb:16", .clk = &uartclk, diff --git a/arch/arm/mach-l7200/include/mach/sys-clock.h b/arch/arm/mach-l7200/include/mach/sys-clock.h index 2d7722be60e..e9729a35751 100644 --- a/arch/arm/mach-l7200/include/mach/sys-clock.h +++ b/arch/arm/mach-l7200/include/mach/sys-clock.h @@ -18,7 +18,7 @@ /* IO_START and IO_BASE are defined in hardware.h */ -#define SYS_CLOCK_START (IO_START + SYS_CLCOK_OFF) /* Physical address */ +#define SYS_CLOCK_START (IO_START + SYS_CLOCK_OFF) /* Physical address */ #define SYS_CLOCK_BASE (IO_BASE + SYS_CLOCK_OFF) /* Virtual address */ /* Define the interface to the SYS_CLOCK */ diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c index efc59c49341..e4cef333e29 100644 --- a/arch/arm/mach-omap2/clock24xx.c +++ b/arch/arm/mach-omap2/clock24xx.c @@ -103,10 +103,10 @@ static struct omap_clk omap24xx_clks[] = { CLK(NULL, "mdm_ick", &mdm_ick, CK_243X), CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X), /* DSS domain clocks */ - CLK(NULL, "dss_ick", &dss_ick, CK_243X | CK_242X), - CLK(NULL, "dss1_fck", &dss1_fck, CK_243X | CK_242X), - CLK(NULL, "dss2_fck", &dss2_fck, CK_243X | CK_242X), - CLK(NULL, "dss_54m_fck", &dss_54m_fck, CK_243X | CK_242X), + CLK("omapfb", "ick", &dss_ick, CK_243X | CK_242X), + CLK("omapfb", "dss1_fck", &dss1_fck, CK_243X | CK_242X), + CLK("omapfb", "dss2_fck", &dss2_fck, CK_243X | CK_242X), + CLK("omapfb", "tv_fck", &dss_54m_fck, CK_243X | CK_242X), /* L3 domain clocks */ CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X | CK_242X), CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X | CK_242X), @@ -206,7 +206,7 @@ static struct omap_clk omap24xx_clks[] = { CLK(NULL, "aes_ick", &aes_ick, CK_243X | CK_242X), CLK(NULL, "pka_ick", &pka_ick, CK_243X | CK_242X), CLK(NULL, "usb_fck", &usb_fck, CK_243X | CK_242X), - CLK(NULL, "usbhs_ick", &usbhs_ick, CK_243X), + CLK("musb_hdrc", "ick", &usbhs_ick, CK_243X), CLK("mmci-omap-hs.0", "ick", &mmchs1_ick, CK_243X), CLK("mmci-omap-hs.0", "fck", &mmchs1_fck, CK_243X), CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_243X), diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 0a14dca31e3..ba05aa42bd8 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -157,7 +157,7 @@ static struct omap_clk omap34xx_clks[] = { CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck, CK_343X), CLK(NULL, "ssi_sst_fck", &ssi_sst_fck, CK_343X), CLK(NULL, "core_l3_ick", &core_l3_ick, CK_343X), - CLK(NULL, "hsotgusb_ick", &hsotgusb_ick, CK_343X), + CLK("musb_hdrc", "ick", &hsotgusb_ick, CK_343X), CLK(NULL, "sdrc_ick", &sdrc_ick, CK_343X), CLK(NULL, "gpmc_fck", &gpmc_fck, CK_343X), CLK(NULL, "security_l3_ick", &security_l3_ick, CK_343X), @@ -197,11 +197,11 @@ static struct omap_clk omap34xx_clks[] = { CLK("omap_rng", "ick", &rng_ick, CK_343X), CLK(NULL, "sha11_ick", &sha11_ick, CK_343X), CLK(NULL, "des1_ick", &des1_ick, CK_343X), - CLK(NULL, "dss1_alwon_fck", &dss1_alwon_fck, CK_343X), - CLK(NULL, "dss_tv_fck", &dss_tv_fck, CK_343X), - CLK(NULL, "dss_96m_fck", &dss_96m_fck, CK_343X), - CLK(NULL, "dss2_alwon_fck", &dss2_alwon_fck, CK_343X), - CLK(NULL, "dss_ick", &dss_ick, CK_343X), + CLK("omapfb", "dss1_fck", &dss1_alwon_fck, CK_343X), + CLK("omapfb", "tv_fck", &dss_tv_fck, CK_343X), + CLK("omapfb", "video_fck", &dss_96m_fck, CK_343X), + CLK("omapfb", "dss2_fck", &dss2_alwon_fck, CK_343X), + CLK("omapfb", "ick", &dss_ick, CK_343X), CLK(NULL, "cam_mclk", &cam_mclk, CK_343X), CLK(NULL, "cam_ick", &cam_ick, CK_343X), CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X), diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index 6763b8f7302..017a30e9aa1 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h @@ -2182,7 +2182,7 @@ static struct clk wkup_32k_fck = { static struct clk gpio1_dbck = { .name = "gpio1_dbck", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_dflt, .parent = &wkup_32k_fck, .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_GPIO1_SHIFT, @@ -2427,7 +2427,7 @@ static struct clk per_32k_alwon_fck = { static struct clk gpio6_dbck = { .name = "gpio6_dbck", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_dflt, .parent = &per_32k_alwon_fck, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_GPIO6_SHIFT, @@ -2437,7 +2437,7 @@ static struct clk gpio6_dbck = { static struct clk gpio5_dbck = { .name = "gpio5_dbck", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_dflt, .parent = &per_32k_alwon_fck, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_GPIO5_SHIFT, @@ -2447,7 +2447,7 @@ static struct clk gpio5_dbck = { static struct clk gpio4_dbck = { .name = "gpio4_dbck", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_dflt, .parent = &per_32k_alwon_fck, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_GPIO4_SHIFT, @@ -2457,7 +2457,7 @@ static struct clk gpio4_dbck = { static struct clk gpio3_dbck = { .name = "gpio3_dbck", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_dflt, .parent = &per_32k_alwon_fck, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_GPIO3_SHIFT, @@ -2467,7 +2467,7 @@ static struct clk gpio3_dbck = { static struct clk gpio2_dbck = { .name = "gpio2_dbck", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_dflt, .parent = &per_32k_alwon_fck, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_GPIO2_SHIFT, diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 496983ade97..894cc355818 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -354,10 +354,12 @@ static void omap_init_mcspi(void) platform_device_register(&omap2_mcspi1); platform_device_register(&omap2_mcspi2); #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) - platform_device_register(&omap2_mcspi3); + if (cpu_is_omap2430() || cpu_is_omap343x()) + platform_device_register(&omap2_mcspi3); #endif #ifdef CONFIG_ARCH_OMAP3 - platform_device_register(&omap2_mcspi4); + if (cpu_is_omap343x()) + platform_device_register(&omap2_mcspi4); #endif } diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h index c6a7940f428..9fd03a2ec95 100644 --- a/arch/arm/mach-omap2/prm-regbits-34xx.h +++ b/arch/arm/mach-omap2/prm-regbits-34xx.h @@ -409,7 +409,7 @@ /* PM_PREPWSTST_CAM specific bits */ /* PM_PWSTCTRL_USBHOST specific bits */ -#define OMAP3430ES2_SAVEANDRESTORE_SHIFT (1 << 4) +#define OMAP3430ES2_SAVEANDRESTORE_SHIFT 4 /* RM_RSTST_PER specific bits */ diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c index 8df55f40f4c..8622c24cd27 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c @@ -187,7 +187,7 @@ int tusb6010_platform_retime(unsigned is_refclk) unsigned sysclk_ps; int status; - if (!refclk_psec || sysclk_ps == 0) + if (!refclk_psec || fclk_ps == 0) return -ENODEV; sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60; diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index 0e65344e9f5..dd031cc4184 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -46,6 +46,7 @@ #include <mach/audio.h> #include <mach/pxafb.h> #include <mach/i2c.h> +#include <mach/regs-uart.h> #include <mach/viper.h> #include <asm/setup.h> diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 942e1a7eb9b..076acbc5070 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -750,14 +750,6 @@ void __init realview_timer_init(unsigned int timer_irq) { u32 val; -#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST - /* - * The dummy clock device has to be registered before the main device - * so that the latter will broadcast the clock events - */ - local_timer_setup(); -#endif - /* * set clock frequency: * REALVIEW_REFCLK is 32KHz diff --git a/arch/arm/mach-realview/include/mach/smp.h b/arch/arm/mach-realview/include/mach/smp.h index 515819efd04..dd53892d44a 100644 --- a/arch/arm/mach-realview/include/mach/smp.h +++ b/arch/arm/mach-realview/include/mach/smp.h @@ -15,16 +15,9 @@ /* * We use IRQ1 as the IPI */ -static inline void smp_cross_call(cpumask_t callmap) -{ - gic_raise_softirq(callmap, 1); -} - -/* - * Do nothing on MPcore. - */ -static inline void smp_cross_call_done(cpumask_t callmap) +static inline void smp_cross_call(const struct cpumask *mask) { + gic_raise_softirq(mask, 1); } #endif diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c index d0d39adf640..1c01d13460f 100644 --- a/arch/arm/mach-realview/localtimer.c +++ b/arch/arm/mach-realview/localtimer.c @@ -189,8 +189,10 @@ void __cpuinit local_timer_setup(void) struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); clk->name = "dummy_timer"; - clk->features = CLOCK_EVT_FEAT_DUMMY; - clk->rating = 200; + clk->features = CLOCK_EVT_FEAT_ONESHOT | + CLOCK_EVT_FEAT_PERIODIC | + CLOCK_EVT_FEAT_DUMMY; + clk->rating = 400; clk->mult = 1; clk->set_mode = dummy_timer_set_mode; clk->broadcast = smp_timer_broadcast; diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index ea3c75595fa..30a9c68591f 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c @@ -78,13 +78,6 @@ void __cpuinit platform_secondary_init(unsigned int cpu) trace_hardirqs_off(); /* - * the primary core may have used a "cross call" soft interrupt - * to get this processor out of WFI in the BootMonitor - make - * sure that we are no longer being sent this soft interrupt - */ - smp_cross_call_done(cpumask_of_cpu(cpu)); - - /* * if any interrupts are already enabled for the primary * core (e.g. timer irq), then they will not have been enabled * for us: do so @@ -136,7 +129,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) * Use smp_cross_call() for this, since there's little * point duplicating the code here */ - smp_cross_call(cpumask_of_cpu(cpu)); + smp_cross_call(cpumask_of(cpu)); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { @@ -224,11 +217,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) if (max_cpus > ncores) max_cpus = ncores; -#ifdef CONFIG_LOCAL_TIMERS +#if defined(CONFIG_LOCAL_TIMERS) || defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) /* - * Enable the local timer for primary CPU. If the device is - * dummy (!CONFIG_LOCAL_TIMERS), it was already registers in - * realview_timer_init + * Enable the local timer or broadcast device for the boot CPU. */ local_timer_setup(); #endif diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 4389c160f7d..8637dea5e15 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -588,8 +588,6 @@ static void __init bast_map_io(void) s3c_device_nand.dev.platform_data = &bast_nand_info; - s3c_i2c0_set_platdata(&bast_i2c_info); - s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs)); @@ -602,6 +600,7 @@ static void __init bast_init(void) sysdev_class_register(&bast_pm_sysclass); sysdev_register(&bast_pm_sysdev); + s3c_i2c0_set_platdata(&bast_i2c_info); s3c24xx_fb_set_platdata(&bast_fb_info); platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices)); diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 1f929c391af..b3bebcc5623 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -413,7 +413,7 @@ static struct clk ref24_clk = { .rate = 24000000, }; -static struct clk_lookup lookups[] __initdata = { +static struct clk_lookup lookups[] = { { /* UART0 */ .dev_id = "dev:f1", .clk = &ref24_clk, diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h index 386cbd13eaf..d3a6f9298e9 100644 --- a/arch/arm/nwfpe/fpa11.h +++ b/arch/arm/nwfpe/fpa11.h @@ -114,4 +114,8 @@ extern unsigned int SingleCPDO(struct roundingData *roundData, extern unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd); +/* extneded_cpdo.c */ +extern unsigned int ExtendedCPDO(struct roundingData *roundData, + const unsigned int opcode, FPREG * rFd); + #endif diff --git a/arch/arm/nwfpe/fpa11_cprt.c b/arch/arm/nwfpe/fpa11_cprt.c index 9843dc53304..31c4eeec18b 100644 --- a/arch/arm/nwfpe/fpa11_cprt.c +++ b/arch/arm/nwfpe/fpa11_cprt.c @@ -27,10 +27,6 @@ #include "fpmodule.inl" #include "softfloat.h" -#ifdef CONFIG_FPE_NWFPE_XP -extern flag floatx80_is_nan(floatx80); -#endif - unsigned int PerformFLT(const unsigned int opcode); unsigned int PerformFIX(const unsigned int opcode); diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h index 260fe29d73f..13e479c5da5 100644 --- a/arch/arm/nwfpe/softfloat.h +++ b/arch/arm/nwfpe/softfloat.h @@ -226,6 +226,8 @@ char floatx80_le_quiet( floatx80, floatx80 ); char floatx80_lt_quiet( floatx80, floatx80 ); char floatx80_is_signaling_nan( floatx80 ); +extern flag floatx80_is_nan(floatx80); + #endif static inline flag extractFloat32Sign(float32 a) diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c index ce6b4baeede..3746222bed1 100644 --- a/arch/arm/plat-omap/fb.c +++ b/arch/arm/plat-omap/fb.c @@ -206,9 +206,10 @@ void __init omapfb_reserve_sdram(void) config_invalid = 1; return; } - if (rg.paddr) + if (rg.paddr) { reserve_bootmem(rg.paddr, rg.size, BOOTMEM_DEFAULT); - reserved += rg.size; + reserved += rg.size; + } omapfb_config.mem_desc.region[i] = rg; configured_regions++; } diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 17d7afe42b8..ee0b21f5b09 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -307,7 +307,7 @@ static inline int gpio_valid(int gpio) return 0; if (cpu_is_omap24xx() && gpio < 128) return 0; - if (cpu_is_omap34xx() && gpio < 160) + if (cpu_is_omap34xx() && gpio < 192) return 0; return -1; } diff --git a/arch/arm/plat-s3c/clock.c b/arch/arm/plat-s3c/clock.c index b6be76e2fe5..4d01ef1a25d 100644 --- a/arch/arm/plat-s3c/clock.c +++ b/arch/arm/plat-s3c/clock.c @@ -306,8 +306,6 @@ struct clk s3c24xx_uclk = { int s3c24xx_register_clock(struct clk *clk) { - clk->owner = THIS_MODULE; - if (clk->enable == NULL) clk->enable = clk_null_enable; diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index aee2aeb46c6..07326f63236 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -1235,7 +1235,7 @@ int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *d EXPORT_SYMBOL(s3c2410_dma_getposition); -static struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev) +static inline struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev) { return container_of(dev, struct s3c2410_dma_chan, dev); } diff --git a/arch/arm/plat-s3c64xx/gpiolib.c b/arch/arm/plat-s3c64xx/gpiolib.c index ee9188add8f..78ee52cffc9 100644 --- a/arch/arm/plat-s3c64xx/gpiolib.c +++ b/arch/arm/plat-s3c64xx/gpiolib.c @@ -57,7 +57,7 @@ #if 1 #define gpio_dbg(x...) do { } while(0) #else -#define gpio_dbg(x...) printk(KERN_DEBUG ## x) +#define gpio_dbg(x...) printk(KERN_DEBUG x) #endif /* The s3c64xx_gpiolib_4bit routines are to control the gpio banks where diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h index 81549516572..2ba1767512d 100644 --- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h +++ b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h @@ -61,14 +61,14 @@ #define S3C64XX_GPH7_ADDR_CF1 (0x06 << 28) #define S3C64XX_GPH7_EINT_G6_7 (0x07 << 28) -#define S3C64XX_GPH8_MMC1_DATA6 (0x02 << 32) -#define S3C64XX_GPH8_MMC2_DATA2 (0x03 << 32) -#define S3C64XX_GPH8_I2S_V40_LRCLK (0x05 << 32) -#define S3C64XX_GPH8_ADDR_CF2 (0x06 << 32) -#define S3C64XX_GPH8_EINT_G6_8 (0x07 << 32) - -#define S3C64XX_GPH9_MMC1_DATA7 (0x02 << 36) -#define S3C64XX_GPH9_MMC2_DATA3 (0x03 << 36) -#define S3C64XX_GPH9_I2S_V40_DI (0x05 << 36) -#define S3C64XX_GPH9_EINT_G6_9 (0x07 << 36) +#define S3C64XX_GPH8_MMC1_DATA6 (0x02 << 0) +#define S3C64XX_GPH8_MMC2_DATA2 (0x03 << 0) +#define S3C64XX_GPH8_I2S_V40_LRCLK (0x05 << 0) +#define S3C64XX_GPH8_ADDR_CF2 (0x06 << 0) +#define S3C64XX_GPH8_EINT_G6_8 (0x07 << 0) +#define S3C64XX_GPH9_OUTPUT (0x01 << 4) +#define S3C64XX_GPH9_MMC1_DATA7 (0x02 << 4) +#define S3C64XX_GPH9_MMC2_DATA3 (0x03 << 4) +#define S3C64XX_GPH9_I2S_V40_DI (0x05 << 4) +#define S3C64XX_GPH9_EINT_G6_9 (0x07 << 4) |