From df4aab46a8256ac0f0c2701b3fe23b7dd05e6b48 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 4 May 2009 13:14:27 -0700 Subject: davinci: gpio irq enable tweaks Fix two IRQ triggering bugs affecting GPIO IRQs: - Make sure enabling with IRQ_TYPE_NONE ("default, unspecified") isn't a NOP ... default to both edges, at least one must work. - As noted by Kevin Hilman, setting the irq trigger type for a banked gpio interrupt shouldn't enable irqs that are disabled. Since GPIO IRQs haven't been used much yet, it's not clear these bugs could have affected anything. The few current users don't seem to have been obviously suffering from these issues. Signed-off-by: David Brownell Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/gpio.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index 1aba41c6351..34ba4ceda34 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c @@ -187,10 +187,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; - if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING) + status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; + if (!status) + status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; + + if (status & IRQ_TYPE_EDGE_FALLING) __raw_writel(mask, &g->set_falling); - if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING) + if (status & IRQ_TYPE_EDGE_RISING) __raw_writel(mask, &g->set_rising); } @@ -205,10 +210,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; } -- cgit v1.2.3 From dc75602628472d7fbc4cb43f010bf0257e95ab71 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 11 May 2009 11:04:53 -0700 Subject: davinci: fixups for banked GPIO interrupt handling This patch seems to get me much more reliable performance using the GPIO banked interrupts on dm355 for the dm9000 driver. Changes include: - init GPIO handling along with normal GPIO init - mask the level-sensitive bank IRQ during handling Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/gpio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index 34ba4ceda34..40327b557d7 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c @@ -45,6 +45,7 @@ static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio) return __gpio_to_controller(gpio); } +static int __init davinci_gpio_irq_setup(void); /*--------------------------------------------------------------------------*/ @@ -157,6 +158,7 @@ static int __init davinci_gpio_setup(void) gpiochip_add(&chips[i].chip); } + davinci_gpio_irq_setup(); return 0; } pure_initcall(davinci_gpio_setup); @@ -238,6 +240,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; @@ -333,4 +336,3 @@ static int __init davinci_gpio_irq_setup(void) return 0; } -arch_initcall(davinci_gpio_irq_setup); -- cgit v1.2.3 From 17eb15704142dc1b302a3f0cd632c426ee326b6d Mon Sep 17 00:00:00 2001 From: Chaithrika U S Date: Mon, 19 Jan 2009 14:13:05 +0530 Subject: davinci: use 32-bit accesses for low-level debug macros This patch defines debug macros for low-level debugging for Davinci based platforms Tested on : - DM644x DaVinci EVM - DM646X DaVinciHD EVM - DM355 EVM This patch attempts to solve the low-level debug issue in DM646x. The UART on DM646x SoC allows only 32-bit access. The existing debug-macro.S uses the macros from debug-8250.S file. This led to garbage serial out in the case of DM646x. The inclusion of debug-8250.S does not allow for run time fix for this issue. There are compile time errors due to multiple definitions of the macros. Also when building a single image for multiple DaVinci Platforms, the ifdefs cannot be relied upon. The solution below does not include the debug-8250.S file and defines the necessary macros. This solution was arrived at after observing that word access does not affect the low-level debug messages on DM644x/DM355. The other approach to this issue is to use the UART module information available in the peripheral registers to decide the access mechanism. But this will have to be done for every access of UART specifically for DM646x. Also this calls for a modification of the debug-8250.S file. Signed-off-by: Chaithrika U S Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/include/mach/debug-macro.S | 31 ++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-davinci') 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 +#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 + .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 + -- cgit v1.2.3 From ce8ccaf0efeb43cd23393a9590365587ad879b2a Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Mon, 11 Feb 2008 14:44:07 -0700 Subject: davinci: interrupts: get_irqnr_and_base: save an instruction Signed-off-by: Troy Kisky Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/include/mach/entry-macro.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/include/mach/entry-macro.S b/arch/arm/mach-davinci/include/mach/entry-macro.S index 039b84f933b..0ebb4454505 100644 --- a/arch/arm/mach-davinci/include/mach/entry-macro.S +++ b/arch/arm/mach-davinci/include/mach/entry-macro.S @@ -23,9 +23,8 @@ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \tmp, [\base, #0x14] - mov \tmp, \tmp, lsr #2 + movs \tmp, \tmp, lsr #2 sub \irqnr, \tmp, #1 - cmp \tmp, #0 .endm .macro irq_prio_table -- cgit v1.2.3 From 27428e39da8e45f861c79e7dcec32d38965afeb3 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 18 Feb 2009 14:00:36 -0700 Subject: davinci: support different UART bases for zImage uncompress The davinci pre-kernel boot code assumes that all platforms use the same UART base address for the console. That assumption is not longer valid with some newer SoCs so determine the console UART base address from the machine number passed in from bootloader. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/include/mach/uncompress.h | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-davinci') 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 #include +#include + +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(); } -- cgit v1.2.3 From 0521444d497ee1f8a31314d2ce3c6b9edab25b51 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 11 Mar 2009 19:49:05 +0400 Subject: davinci: INTC: add support for TI cp_intc Add support for Texas Instuments Common Platform Interrupt Controller (cp_intc) used on DA830/OMAP-L137. Signed-off-by: Steve Chen Signed-off-by: Mark Greer Signed-off-by: Sergei Shtylyov Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/Kconfig | 3 + arch/arm/mach-davinci/Makefile | 1 + arch/arm/mach-davinci/cp_intc.c | 161 +++++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/cp_intc.h | 57 ++++++++++ 4 files changed, 222 insertions(+) create mode 100644 arch/arm/mach-davinci/cp_intc.c create mode 100644 arch/arm/mach-davinci/include/mach/cp_intc.h (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index a9c78bc72b8..56cd03f908e 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -1,5 +1,8 @@ if ARCH_DAVINCI +config CP_INTC + bool + menu "TI DaVinci Implementations" comment "DaVinci Core Type" diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 1674661942f..9a696ae60fc 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -8,6 +8,7 @@ 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-$(CONFIG_DAVINCI_MUX) += mux.o +obj-$(CONFIG_CP_INTC) += cp_intc.o # Chip specific obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o 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 + * Copyright (C) 2008-2009, 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 +#include +#include +#include +#include +#include + +#include + +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/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 + * Copyright (C) 2008-2009, MontaVista Software, Inc. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ +#ifndef __ASM_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 */ -- cgit v1.2.3 From fb6313879caa46831d71a316b97b51d37d100269 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 29 Apr 2009 16:23:59 -0700 Subject: davinci: add platform support for watchdog timer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/clock.h | 3 +++ arch/arm/mach-davinci/devices.c | 35 +++++++++++++++++++++++++++++++++++ arch/arm/mach-davinci/time.c | 9 ++++----- 3 files changed, 42 insertions(+), 5 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index 35736ec202f..584494a3207 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -93,4 +93,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/devices.c b/arch/arm/mach-davinci/devices.c index a31370b93dd..7fdc408105b 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -54,3 +54,38 @@ void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata) (void) platform_device_register(&davinci_i2c_device); } +/*-------------------------------------------------------------------------*/ + +static struct resource wdt_resources[] = { + { + .start = 0x01c21c00, + .end = 0x01c21fff, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device davinci_wdt_device = { + .name = "watchdog", + .id = -1, + .num_resources = ARRAY_SIZE(wdt_resources), + .resource = wdt_resources, +}; + +static void davinci_init_wdt(void) +{ + platform_device_register(&davinci_wdt_device); +} + +/*-------------------------------------------------------------------------*/ + +static 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/time.c b/arch/arm/mach-davinci/time.c index 494e01bff5c..efbbc2ac63b 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -349,15 +350,13 @@ 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 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); -- cgit v1.2.3 From f5ce6a67a78357da5e88782b1cf1cc10b36f102c Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Wed, 29 Apr 2009 16:46:57 -0700 Subject: davinci: DM644x: add support for SFFSDR board Signed-off-by: Hugo Villeneuve Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/Kconfig | 7 ++ arch/arm/mach-davinci/Makefile | 1 + arch/arm/mach-davinci/board-sffsdr.c | 180 +++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+) create mode 100644 arch/arm/mach-davinci/board-sffsdr.c (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index 56cd03f908e..0d8ad593a46 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -20,6 +20,13 @@ 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 DAVINCI_MUX bool "DAVINCI multiplexing support" diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 9a696ae60fc..2bb6ffa3faa 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o # Board specific obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o +obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c new file mode 100644 index 00000000000..c6525e43ea3 --- /dev/null +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -0,0 +1,180 @@ +/* + * Lyrtech SFFSDR board support. + * + * Copyright (C) 2008 Philip Balister, OpenSDR + * Copyright (C) 2008 Lyrtech + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#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, +}; + +/* Get Ethernet address from kernel boot params */ +static u8 mac_addr[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + +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) +{ + davinci_map_common_io(); + dm644x_init(); +} + +static __init void davinci_sffsdr_init(void) +{ + platform_add_devices(davinci_sffsdr_devices, + ARRAY_SIZE(davinci_sffsdr_devices)); + sffsdr_init_i2c(); + davinci_serial_init(&uart_config); + 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 -- cgit v1.2.3 From 95a3477fe57e0669dcb531516f2930fe1cf27e6b Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 29 Apr 2009 12:10:55 -0700 Subject: davinci: DM355: add base SoC and board support In addition, add board support for the DM355 Evaluation Module (EVM) and the DM355 Leopard board. Original DM355 EVM support done by Sandeep Paulraj, with significant updates and improvements by David Brownell. DM355 Leopord support done by Koen Kooi. Signed-off-by: Sandeep Paulraj Signed-off-by: Koen Kooi Cc: David Brownell Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/Kconfig | 19 + arch/arm/mach-davinci/Makefile | 3 + arch/arm/mach-davinci/board-dm355-evm.c | 269 ++++++++++++++ arch/arm/mach-davinci/board-dm355-leopard.c | 268 ++++++++++++++ arch/arm/mach-davinci/dm355.c | 540 ++++++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/dm355.h | 23 ++ arch/arm/mach-davinci/include/mach/serial.h | 2 +- 7 files changed, 1123 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-davinci/board-dm355-evm.c create mode 100644 arch/arm/mach-davinci/board-dm355-leopard.c create mode 100644 arch/arm/mach-davinci/dm355.c create mode 100644 arch/arm/mach-davinci/include/mach/dm355.h (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index 0d8ad593a46..1c3ab40e2b6 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -10,6 +10,9 @@ comment "DaVinci Core Type" config ARCH_DAVINCI_DM644x bool "DaVinci 644x based system" +config ARCH_DAVINCI_DM355 + bool "DaVinci 355 based system" + comment "DaVinci Board Type" config MACH_DAVINCI_EVM @@ -28,6 +31,22 @@ config MACH_SFFSDR 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 DAVINCI_MUX bool "DAVINCI multiplexing support" depends on ARCH_DAVINCI diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 2bb6ffa3faa..381c363d98a 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -12,7 +12,10 @@ obj-$(CONFIG_CP_INTC) += cp_intc.o # Chip specific obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o +obj-$(CONFIG_ARCH_DAVINCI_DM355) += dm355.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 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..6af3c6c863a --- /dev/null +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -0,0 +1,269 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#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) +{ + davinci_map_common_io(); + dm355_init(); +} + +/* 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); + + 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..22f16f38a0b --- /dev/null +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -0,0 +1,268 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#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) +{ + davinci_map_common_io(); + dm355_init(); +} + +/* 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); + + 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/dm355.c b/arch/arm/mach-davinci/dm355.c new file mode 100644 index 00000000000..c02115f1eb9 --- /dev/null +++ b/arch/arm/mach-davinci/dm355.c @@ -0,0 +1,540 @@ +/* + * 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 +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "clock.h" +#include "mux.h" + +/* + * 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); +} + +/*----------------------------------------------------------------------*/ + +/* + * Device specific mux setup + * + * soc description mux mode mode mux dbg + * reg offset mask mode + */ +static const struct mux_config dm355_pins[] = { +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) +}; + +/*----------------------------------------------------------------------*/ + +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, +}; + +/*----------------------------------------------------------------------*/ + +void __init dm355_init(void) +{ + davinci_clk_init(dm355_clks); + davinci_mux_register(dm355_pins, ARRAY_SIZE(dm355_pins));; +} + +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/include/mach/dm355.h b/arch/arm/mach-davinci/include/mach/dm355.h new file mode 100644 index 00000000000..f7100b65899 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/dm355.h @@ -0,0 +1,23 @@ +/* + * 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 + +void __init dm355_init(void); + +struct spi_board_info; + +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/serial.h b/arch/arm/mach-davinci/include/mach/serial.h index 632847d74a1..761ab2b483a 100644 --- a/arch/arm/mach-davinci/include/mach/serial.h +++ b/arch/arm/mach-davinci/include/mach/serial.h @@ -18,7 +18,7 @@ #define DAVINCI_UART1_BASE (IO_PHYS + 0x20400) #define DAVINCI_UART2_BASE (IO_PHYS + 0x20800) -#define DM355_UART2_BASE (IO_PHYS + 0x206000) +#define DM355_UART2_BASE (IO_PHYS + 0x206000) /* DaVinci UART register offsets */ #define UART_DAVINCI_PWREMU 0x0c -- cgit v1.2.3 From e38d92fdcd04c79d28679682f63a83487c4c4c05 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 29 Apr 2009 17:44:58 -0700 Subject: davinci: DM646x: add base SoC and board support Add support for DM646x SoC (a.k.a DaVinci HD) and its Evalution Module (EVM.) Original support done by Sudhakar Rajashekhara. Signed-off-by: Sudhakar Rajashekhara Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/Kconfig | 12 + arch/arm/mach-davinci/Makefile | 2 + arch/arm/mach-davinci/board-dm646x-evm.c | 280 +++++++++++++++++++ arch/arm/mach-davinci/dm646x.c | 402 ++++++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/dm646x.h | 18 ++ 5 files changed, 714 insertions(+) create mode 100644 arch/arm/mach-davinci/board-dm646x-evm.c create mode 100644 arch/arm/mach-davinci/dm646x.c create mode 100644 arch/arm/mach-davinci/include/mach/dm646x.h (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index 1c3ab40e2b6..d7614a0ab2f 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -13,6 +13,9 @@ config ARCH_DAVINCI_DM644x config ARCH_DAVINCI_DM355 bool "DaVinci 355 based system" +config ARCH_DAVINCI_DM646x + bool "DaVinci 646x based system" + comment "DaVinci Board Type" config MACH_DAVINCI_EVM @@ -47,6 +50,15 @@ config MACH_DM355_LEOPARD 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" depends on ARCH_DAVINCI diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 381c363d98a..2873149da7f 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -13,9 +13,11 @@ obj-$(CONFIG_CP_INTC) += cp_intc.o # Chip specific obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o obj-$(CONFIG_ARCH_DAVINCI_DM355) += dm355.o +obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.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-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c new file mode 100644 index 00000000000..94cb623b1ec --- /dev/null +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -0,0 +1,280 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +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 memory_accessor *at24_mem_acc; + +static void at24_setup(struct memory_accessor *mem_acc, void *context) +{ + 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, ETH_ALEN) == + ETH_ALEN) + pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr); +} + +static struct at24_platform_data eeprom_info = { + .byte_len = (256*1024) / 8, + .page_size = 64, + .flags = AT24_FLAG_ADDR16, + .setup = at24_setup, +}; + +int dm646xevm_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(dm646xevm_eeprom_read); + +int dm646xevm_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(dm646xevm_eeprom_write); + +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) +{ + davinci_map_common_io(); + dm646x_init(); +} + +static __init void evm_init(void) +{ + evm_init_i2c(); + davinci_serial_init(&uart_config); +} + +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/dm646x.c b/arch/arm/mach-davinci/dm646x.c new file mode 100644 index 00000000000..93443a6637e --- /dev/null +++ b/arch/arm/mach-davinci/dm646x.c @@ -0,0 +1,402 @@ +/* + * 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#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), +}; + +/* + * Device specific mux setup + * + * soc description mux mode mode mux dbg + * reg offset mask mode + */ +static const struct mux_config dm646x_pins[] = { +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) +}; + +/*----------------------------------------------------------------------*/ + +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, +}; + +/*----------------------------------------------------------------------*/ + +void __init dm646x_init(void) +{ + davinci_clk_init(dm646x_clks); + davinci_mux_register(dm646x_pins, ARRAY_SIZE(dm646x_pins)); +} + +static int __init dm646x_init_devices(void) +{ + if (!cpu_is_davinci_dm646x()) + return 0; + + platform_device_register(&dm646x_edma_device); + return 0; +} +postcore_initcall(dm646x_init_devices); 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..d917939af15 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/dm646x.h @@ -0,0 +1,18 @@ +/* + * 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 + +void __init dm646x_init(void); + +#endif /* __ASM_ARCH_DM646X_H */ -- cgit v1.2.3 From 2dbf56aeb7986b54651c93ed171877e8179289bc Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 11 May 2009 15:55:03 -0700 Subject: davinci: MMC platform support Add SoC and platform-specific data and init for MMC driver. Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-dm355-evm.c | 29 +++++ arch/arm/mach-davinci/board-dm355-leopard.c | 28 +++++ arch/arm/mach-davinci/board-dm644x-evm.c | 24 +++++ arch/arm/mach-davinci/devices.c | 157 ++++++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/mmc.h | 33 ++++++ 5 files changed, 271 insertions(+) create mode 100644 arch/arm/mach-davinci/include/mach/mmc.h (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 6af3c6c863a..087441313dd 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -36,6 +36,7 @@ #include #include #include +#include #define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 @@ -191,6 +192,31 @@ 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) @@ -249,6 +275,9 @@ static __init void dm355_evm_init(void) /* 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)); } diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index 22f16f38a0b..d4562f5ff93 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -35,6 +35,7 @@ #include #include #include +#include #define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 @@ -190,6 +191,30 @@ 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) @@ -248,6 +273,9 @@ static __init void dm355_leopard_init(void) /* 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)); } diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index b2e7f9c63bc..9c3ce311d5d 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -44,6 +44,7 @@ #include #include #include +#include #define DM644X_EVM_PHY_MASK (0x2) #define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ @@ -545,6 +546,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), @@ -671,6 +693,8 @@ 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); /* Register the fixup for PHY on DaVinci */ diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 7fdc408105b..56c19319a7d 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -23,8 +23,13 @@ #include #include #include +#include +#include #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,6 +59,158 @@ 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[] = { 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 +#include + +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 -- cgit v1.2.3 From ac7b75b5bbbfd60b752869a22daa3be99b5b4f99 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 7 May 2009 06:19:40 -0700 Subject: davinci: EMAC platform support Add SoC and platform-specific data and init for DaVinci EMAC network driver. Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-dm644x-evm.c | 37 +++++++------------ arch/arm/mach-davinci/board-dm646x-evm.c | 17 ++++++++- arch/arm/mach-davinci/board-sffsdr.c | 11 +++++- arch/arm/mach-davinci/dm644x.c | 19 ++++++++++ arch/arm/mach-davinci/dm646x.c | 57 +++++++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/dm644x.h | 2 + arch/arm/mach-davinci/include/mach/dm646x.h | 9 +++++ arch/arm/mach-davinci/include/mach/emac.h | 36 ++++++++++++++++++ 8 files changed, 161 insertions(+), 27 deletions(-) create mode 100644 arch/arm/mach-davinci/include/mach/emac.h (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 9c3ce311d5d..02e7cdaf8da 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -16,12 +16,11 @@ #include #include #include -#include #include #include #include - +#include #include #include #include @@ -39,6 +38,7 @@ #include #include +#include #include #include #include @@ -60,6 +60,11 @@ #define LXT971_PHY_ID (0x001378e2) #define LXT971_PHY_MASK (0xfffffff0) +static struct emac_platform_data dm644x_evm_emac_pdata = { + .phy_mask = DM644X_EVM_PHY_MASK, + .mdio_max_freq = DM644X_EVM_MDIO_FREQUENCY, +}; + static struct mtd_partition davinci_evm_norflash_partitions[] = { /* bootloader (UBL, U-Boot, etc) in first 5 sectors */ { @@ -441,15 +446,15 @@ 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]; + char mac_addr[ETH_ALEN]; 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)); + if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x7f00, ETH_ALEN) == + ETH_ALEN) { + printk(KERN_INFO "Read MAC addr from EEPROM: %pM\n", mac_addr); + memcpy(dm644x_evm_emac_pdata.mac_addr, mac_addr, ETH_ALEN); } } @@ -460,22 +465,6 @@ static struct at24_platform_data eeprom_info = { .setup = at24_setup, }; -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 @@ -697,6 +686,8 @@ static __init void davinci_evm_init(void) davinci_serial_init(&uart_config); + dm644x_init_emac(&dm644x_evm_emac_pdata); + /* 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 index 94cb623b1ec..aedde3cdb82 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -45,6 +45,16 @@ #include #include #include +#include +#include + +#define DM646X_EVM_PHY_MASK (0x2) +#define DM646X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ + +static struct emac_platform_data dm646x_evm_emac_pdata = { + .phy_mask = DM646X_EVM_PHY_MASK, + .mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY, +}; static struct davinci_uart_config uart_config __initdata = { .enabled_uarts = (1 << 0), @@ -196,14 +206,16 @@ static struct memory_accessor *at24_mem_acc; static void at24_setup(struct memory_accessor *mem_acc, void *context) { - char mac_addr[6]; + char mac_addr[ETH_ALEN]; at24_mem_acc = mem_acc; /* Read MAC addr from EEPROM */ if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x7f00, ETH_ALEN) == - ETH_ALEN) + ETH_ALEN) { pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr); + memcpy(dm646x_evm_emac_pdata.mac_addr, mac_addr, ETH_ALEN); + } } static struct at24_platform_data eeprom_info = { @@ -261,6 +273,7 @@ static __init void evm_init(void) { evm_init_i2c(); davinci_serial_init(&uart_config); + dm646x_init_emac(&dm646x_evm_emac_pdata); } static __init void davinci_dm646x_evm_irq_init(void) diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index c6525e43ea3..913dad93540 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -48,11 +48,15 @@ #include #include +#include #include #include #include #include +#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 @@ -104,8 +108,10 @@ static struct platform_device davinci_sffsdr_nandflash_device = { .resource = davinci_sffsdr_nandflash_resource, }; -/* Get Ethernet address from kernel boot params */ -static u8 mac_addr[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +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, @@ -156,6 +162,7 @@ static __init void davinci_sffsdr_init(void) ARRAY_SIZE(davinci_sffsdr_devices)); sffsdr_init_i2c(); davinci_serial_init(&uart_config); + dm644x_init_emac(&sffsdr_emac_pdata); setup_usb(0, 0); /* We support only peripheral mode. */ /* mux VLYNQ pins */ diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index d428ef192ea..0419d571bdc 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -444,6 +444,25 @@ static struct platform_device dm644x_edma_device = { }; /*----------------------------------------------------------------------*/ +#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) + +void dm644x_init_emac(struct emac_platform_data *pdata) +{ + pdata->ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET; + pdata->ctrl_mod_reg_offset = DM644X_EMAC_CNTRL_MOD_OFFSET; + pdata->ctrl_ram_offset = DM644X_EMAC_CNTRL_RAM_OFFSET; + pdata->mdio_reg_offset = DM644X_EMAC_MDIO_OFFSET; + pdata->ctrl_ram_size = DM644X_EMAC_CNTRL_RAM_SIZE; + pdata->version = EMAC_VERSION_1; + dm644x_emac_device.dev.platform_data = pdata; + platform_device_register(&dm644x_emac_device); +} +#else + +void dm644x_init_emac(struct emac_platform_data *unused) {} + +#endif + void __init dm644x_init(void) { davinci_clk_init(dm644x_clks); diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 93443a6637e..975ed062ce2 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -279,6 +279,44 @@ struct davinci_clk dm646x_clks[] = { CLK(NULL, NULL, NULL), }; +#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) +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, + .num_resources = ARRAY_SIZE(dm646x_emac_resources), + .resource = dm646x_emac_resources, +}; + +#endif + /* * Device specific mux setup * @@ -385,6 +423,25 @@ static struct platform_device dm646x_edma_device = { /*----------------------------------------------------------------------*/ +#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) + +void dm646x_init_emac(struct emac_platform_data *pdata) +{ + pdata->ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET; + pdata->ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET; + pdata->ctrl_ram_offset = DM646X_EMAC_CNTRL_RAM_OFFSET; + pdata->mdio_reg_offset = DM646X_EMAC_MDIO_OFFSET; + pdata->ctrl_ram_size = DM646X_EMAC_CNTRL_RAM_SIZE; + pdata->version = EMAC_VERSION_2; + dm646x_emac_device.dev.platform_data = pdata; + platform_device_register(&dm646x_emac_device); +} +#else + +void dm646x_init_emac(struct emac_platform_data *unused) {} + +#endif + void __init dm646x_init(void) { davinci_clk_init(dm646x_clks); diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h index 3dcb9f4e58b..ace167aec46 100644 --- a/arch/arm/mach-davinci/include/mach/dm644x.h +++ b/arch/arm/mach-davinci/include/mach/dm644x.h @@ -24,6 +24,7 @@ #include #include +#include #define DM644X_EMAC_BASE (0x01C80000) #define DM644X_EMAC_CNTRL_OFFSET (0x0000) @@ -33,5 +34,6 @@ #define DM644X_EMAC_CNTRL_RAM_SIZE (0x2000) void __init dm644x_init(void); +void dm644x_init_emac(struct emac_platform_data *pdata); #endif /* __ASM_ARCH_DM644X_H */ diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h index d917939af15..ea7b28e112f 100644 --- a/arch/arm/mach-davinci/include/mach/dm646x.h +++ b/arch/arm/mach-davinci/include/mach/dm646x.h @@ -12,7 +12,16 @@ #define __ASM_ARCH_DM646X_H #include +#include + +#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); +void dm646x_init_emac(struct emac_platform_data *pdata); #endif /* __ASM_ARCH_DM646X_H */ 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..549fcced217 --- /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 + +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_init_emac(struct emac_platform_data *pdata); +#endif + + -- cgit v1.2.3 From 79c3c0b729647a6246c120408f36e6804dab244e Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:38:58 -0700 Subject: davinci: Encapsulate SoC-specific data in a structure Create a structure to encapsulate SoC-specific information. This will assist in generalizing code so it can be used by different SoCs that have similar hardware but with minor differences such as having a different base address. The idea is that the code for each SoC fills out a structure with the correct information. The board-specific code then calls the SoC init routine which in turn will call a common init routine that makes a copy of the structure, maps in I/O regions, etc. After initialization, code can get a pointer to the structure by calling davinci_get_soc_info(). Eventually, the common init routine will make a copy of all of the data pointed to by the structure so the original data can be made __init_data. That way the data for SoC's that aren't being used won't consume memory for the entire life of the kernel. The structure will be extended in subsequent patches but initially, it holds the map_desc structure for any I/O regions the SoC/board wants statically mapped. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/Makefile | 2 +- arch/arm/mach-davinci/board-dm355-evm.c | 2 +- arch/arm/mach-davinci/board-dm355-leopard.c | 2 +- arch/arm/mach-davinci/board-dm644x-evm.c | 2 +- arch/arm/mach-davinci/board-dm646x-evm.c | 2 +- arch/arm/mach-davinci/board-sffsdr.c | 2 +- arch/arm/mach-davinci/common.c | 55 +++++++++++++++++++++++++++++ arch/arm/mach-davinci/dm355.c | 18 ++++++++++ arch/arm/mach-davinci/dm644x.c | 18 ++++++++++ arch/arm/mach-davinci/dm646x.c | 18 ++++++++++ arch/arm/mach-davinci/include/mach/common.h | 12 ++++++- arch/arm/mach-davinci/include/mach/dm355.h | 3 +- arch/arm/mach-davinci/io.c | 38 -------------------- 13 files changed, 127 insertions(+), 47 deletions(-) create mode 100644 arch/arm/mach-davinci/common.c (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 2873149da7f..74d25f69934 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -5,7 +5,7 @@ # 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 + gpio.o devices.o dma.o usb.o common.o obj-$(CONFIG_DAVINCI_MUX) += mux.o obj-$(CONFIG_CP_INTC) += cp_intc.o diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 087441313dd..5ac2f565d86 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -37,6 +37,7 @@ #include #include #include +#include #define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 @@ -188,7 +189,6 @@ static struct davinci_uart_config uart_config __initdata = { static void __init dm355_evm_map_io(void) { - davinci_map_common_io(); dm355_init(); } diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index d4562f5ff93..28c9008df4f 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -36,6 +36,7 @@ #include #include #include +#include #define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e10000 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 @@ -187,7 +188,6 @@ static struct davinci_uart_config uart_config __initdata = { static void __init dm355_leopard_map_io(void) { - davinci_map_common_io(); dm355_init(); } diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 02e7cdaf8da..cfe89c40973 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -45,6 +45,7 @@ #include #include #include +#include #define DM644X_EVM_PHY_MASK (0x2) #define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ @@ -609,7 +610,6 @@ static struct davinci_uart_config uart_config __initdata = { static void __init davinci_evm_map_io(void) { - davinci_map_common_io(); dm644x_init(); } diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index aedde3cdb82..becae51d6dd 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -47,6 +47,7 @@ #include #include #include +#include #define DM646X_EVM_PHY_MASK (0x2) #define DM646X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ @@ -265,7 +266,6 @@ static void __init evm_init_i2c(void) static void __init davinci_map_io(void) { - davinci_map_common_io(); dm646x_init(); } diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index 913dad93540..938b4467809 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -53,6 +53,7 @@ #include #include #include +#include #define SFFSDR_PHY_MASK (0x2) #define SFFSDR_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ @@ -152,7 +153,6 @@ static struct davinci_uart_config uart_config __initdata = { static void __init davinci_sffsdr_map_io(void) { - davinci_map_common_io(); dm644x_init(); } diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c new file mode 100644 index 00000000000..9a5486f5519 --- /dev/null +++ b/arch/arm/mach-davinci/common.c @@ -0,0 +1,55 @@ +/* + * Code commons to all DaVinci SoCs. + * + * Author: Mark A. Greer + * + * 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 +#include + +#include +#include + +#include + +struct davinci_soc_info davinci_soc_info; +EXPORT_SYMBOL(davinci_soc_info); + +void __init davinci_common_init(struct davinci_soc_info *soc_info) +{ + int ret; + + if (!soc_info) { + ret = -EINVAL; + goto err; + } + + memcpy(&davinci_soc_info, soc_info, sizeof(struct davinci_soc_info)); + + if (davinci_soc_info.io_desc && (davinci_soc_info.io_desc_num > 0)) + iotable_init(davinci_soc_info.io_desc, + davinci_soc_info.io_desc_num); + + /* + * Normally devicemaps_init() would flush caches and tlb after + * mdesc->map_io(), but we must also do it here because of the CPU + * revision check below. + */ + local_flush_tlb_all(); + flush_cache_all(); + + /* + * 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(); + + return; + +err: + pr_err("davinci_common_init: SoC Initialization failed\n"); +} diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index c02115f1eb9..6d1abfdcfb7 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -16,6 +16,8 @@ #include +#include + #include #include #include @@ -23,6 +25,7 @@ #include #include #include +#include #include "clock.h" #include "mux.h" @@ -522,8 +525,23 @@ static struct platform_device dm355_edma_device = { /*----------------------------------------------------------------------*/ +static struct map_desc dm355_io_desc[] = { + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + }, +}; + +static struct davinci_soc_info davinci_soc_info_dm355 = { + .io_desc = dm355_io_desc, + .io_desc_num = ARRAY_SIZE(dm355_io_desc), +}; + void __init dm355_init(void) { + davinci_common_init(&davinci_soc_info_dm355); davinci_clk_init(dm355_clks); davinci_mux_register(dm355_pins, ARRAY_SIZE(dm355_pins));; } diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 0419d571bdc..79f113698b0 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -13,6 +13,8 @@ #include #include +#include + #include #include #include @@ -20,6 +22,7 @@ #include #include #include +#include #include "clock.h" #include "mux.h" @@ -463,8 +466,23 @@ void dm644x_init_emac(struct emac_platform_data *unused) {} #endif +static struct map_desc dm644x_io_desc[] = { + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + }, +}; + +static struct davinci_soc_info davinci_soc_info_dm644x = { + .io_desc = dm644x_io_desc, + .io_desc_num = ARRAY_SIZE(dm644x_io_desc), +}; + void __init dm644x_init(void) { + davinci_common_init(&davinci_soc_info_dm644x); davinci_clk_init(dm644x_clks); davinci_mux_register(dm644x_pins, ARRAY_SIZE(dm644x_pins)); } diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 975ed062ce2..8547ec02c9e 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -13,6 +13,8 @@ #include #include +#include + #include #include #include @@ -20,6 +22,7 @@ #include #include #include +#include #include "clock.h" #include "mux.h" @@ -442,8 +445,23 @@ void dm646x_init_emac(struct emac_platform_data *unused) {} #endif +static struct map_desc dm646x_io_desc[] = { + { + .virtual = IO_VIRT, + .pfn = __phys_to_pfn(IO_PHYS), + .length = IO_SIZE, + .type = MT_DEVICE + }, +}; + +static struct davinci_soc_info davinci_soc_info_dm646x = { + .io_desc = dm646x_io_desc, + .io_desc_num = ARRAY_SIZE(dm646x_io_desc), +}; + void __init dm646x_init(void) { + davinci_common_init(&davinci_soc_info_dm646x); davinci_clk_init(dm646x_clks); davinci_mux_register(dm646x_pins, ARRAY_SIZE(dm646x_pins)); } diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 19177097625..770a1baa97d 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -17,7 +17,6 @@ struct sys_timer; extern struct sys_timer davinci_timer; extern void davinci_irq_init(void); -extern void davinci_map_common_io(void); /* parameters describe VBUS sourcing for host mode */ extern void setup_usb(unsigned mA, unsigned potpgt_msec); @@ -25,4 +24,15 @@ 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); +/* SoC specific init support */ +struct davinci_soc_info { + struct map_desc *io_desc; + unsigned long io_desc_num; +}; + +extern struct davinci_soc_info davinci_soc_info; + +extern void davinci_common_init(struct davinci_soc_info *soc_info); +extern void davinci_check_revision(void); + #endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */ diff --git a/arch/arm/mach-davinci/include/mach/dm355.h b/arch/arm/mach-davinci/include/mach/dm355.h index f7100b65899..54903b72438 100644 --- a/arch/arm/mach-davinci/include/mach/dm355.h +++ b/arch/arm/mach-davinci/include/mach/dm355.h @@ -13,10 +13,9 @@ #include -void __init dm355_init(void); - struct spi_board_info; +void __init dm355_init(void); void dm355_init_spi0(unsigned chipselect_mask, struct spi_board_info *info, unsigned len); 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 -#include -#include #include #include -#include - -#include -#include - -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))) -- cgit v1.2.3 From b9ab12797e74d93a3656ea0bf5591f8b3e094fd5 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:39:09 -0700 Subject: davinci: Support JTAG ID register at any address The Davinci cpu_is_davinci_*() macros use the SoC part number and variant retrieved from the JTAG ID register to determine the type of cpu that the kernel is running on. Currently, the code to read the JTAG ID register assumes that the register is always at the same base address. This isn't true on some newer SoCs. To solve this, have the SoC-specific code set the JTAG ID register base address in soc_info structure and add a 'cpu_id' member to it. 'cpu_id' will be used by the cpu_is_davinci_*() macros to match the cpu id. Also move the info used to identify the cpu type into the SoC-specific code to keep all SoC-specific code together. The common code will read the JTAG ID register, search through an array of davinci_id structures to identify the cpu type. Once identified, it will set the 'cpu_id' member of the soc_info structure to the proper value and the cpu_is_davinci_*() macros will now work. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/Makefile | 2 +- arch/arm/mach-davinci/common.c | 29 ++++++- arch/arm/mach-davinci/dm355.c | 14 ++++ arch/arm/mach-davinci/dm644x.c | 15 +++- arch/arm/mach-davinci/dm646x.c | 14 ++++ arch/arm/mach-davinci/id.c | 116 --------------------------- arch/arm/mach-davinci/include/mach/common.h | 6 +- arch/arm/mach-davinci/include/mach/cputype.h | 29 +++++-- 8 files changed, 97 insertions(+), 128 deletions(-) delete mode 100644 arch/arm/mach-davinci/id.c (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 74d25f69934..a65d03bb467 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -4,7 +4,7 @@ # # Common objects -obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \ +obj-y := time.o irq.o clock.o serial.o io.o psc.o \ gpio.o devices.o dma.o usb.o common.o obj-$(CONFIG_DAVINCI_MUX) += mux.o diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index 9a5486f5519..29b3a8d5121 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -15,13 +15,31 @@ #include #include +#include struct davinci_soc_info davinci_soc_info; EXPORT_SYMBOL(davinci_soc_info); +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; @@ -46,7 +64,16 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) * 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(); + 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); return; diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 6d1abfdcfb7..0f724c06008 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -534,9 +534,23 @@ static struct map_desc dm355_io_desc[] = { }, }; +/* 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 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), }; void __init dm355_init(void) diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 79f113698b0..9bcd98c6820 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -388,7 +388,6 @@ MUX_CFG(DM644X, LOEEN, 0, 24, 1, 1, true) MUX_CFG(DM644X, LFLDEN, 0, 25, 1, 1, false) }; - /*----------------------------------------------------------------------*/ static const s8 dma_chan_dm644x_no_event[] = { @@ -475,9 +474,23 @@ static struct map_desc dm644x_io_desc[] = { }, }; +/* 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 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), }; void __init dm644x_init(void) diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 8547ec02c9e..cd86bb78e0c 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -454,9 +454,23 @@ static struct map_desc dm646x_io_desc[] = { }, }; +/* 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 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), }; void __init dm646x_init(void) 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 - * - * 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 -#include -#include -#include - -#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/common.h b/arch/arm/mach-davinci/include/mach/common.h index 770a1baa97d..ece1cd42738 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -28,11 +28,15 @@ extern void setup_usb(unsigned mA, unsigned potpgt_msec); 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; }; extern struct davinci_soc_info davinci_soc_info; extern void davinci_common_init(struct davinci_soc_info *soc_info); -extern void davinci_check_revision(void); #endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_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 -#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() -- cgit v1.2.3 From 66e0c3991c5a1735dd8add77ab8aff5005f57681 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:39:23 -0700 Subject: davinci: Add clock init call to common init routine All of the davinci SoCs need to call davinci_clk_init() so put the call in the common init routine. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/common.c | 9 +++++++++ arch/arm/mach-davinci/dm355.c | 2 +- arch/arm/mach-davinci/dm644x.c | 2 +- arch/arm/mach-davinci/dm646x.c | 2 +- arch/arm/mach-davinci/include/mach/common.h | 1 + 5 files changed, 13 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index 29b3a8d5121..2e5b888e6ca 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -17,6 +17,8 @@ #include #include +#include "clock.h" + struct davinci_soc_info davinci_soc_info; EXPORT_SYMBOL(davinci_soc_info); @@ -75,6 +77,13 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) 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; + } + return; err: diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 0f724c06008..e93840a814e 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -551,12 +551,12 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .jtag_id_base = IO_ADDRESS(0x01c40028), .ids = dm355_ids, .ids_num = ARRAY_SIZE(dm355_ids), + .cpu_clks = dm355_clks, }; void __init dm355_init(void) { davinci_common_init(&davinci_soc_info_dm355); - davinci_clk_init(dm355_clks); davinci_mux_register(dm355_pins, ARRAY_SIZE(dm355_pins));; } diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 9bcd98c6820..648160c2960 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -491,12 +491,12 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .jtag_id_base = IO_ADDRESS(0x01c40028), .ids = dm644x_ids, .ids_num = ARRAY_SIZE(dm644x_ids), + .cpu_clks = dm644x_clks, }; void __init dm644x_init(void) { davinci_common_init(&davinci_soc_info_dm644x); - davinci_clk_init(dm644x_clks); davinci_mux_register(dm644x_pins, ARRAY_SIZE(dm644x_pins)); } diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index cd86bb78e0c..7cf9705be9c 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -471,12 +471,12 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .jtag_id_base = IO_ADDRESS(0x01c40028), .ids = dm646x_ids, .ids_num = ARRAY_SIZE(dm646x_ids), + .cpu_clks = dm646x_clks, }; void __init dm646x_init(void) { davinci_common_init(&davinci_soc_info_dm646x); - davinci_clk_init(dm646x_clks); davinci_mux_register(dm646x_pins, ARRAY_SIZE(dm646x_pins)); } diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index ece1cd42738..97782a76588 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -33,6 +33,7 @@ struct davinci_soc_info { void __iomem *jtag_id_base; struct davinci_id *ids; unsigned long ids_num; + struct davinci_clk *cpu_clks; }; extern struct davinci_soc_info davinci_soc_info; -- cgit v1.2.3 From d81d188cafecbc9e01df51527ac4c84a5b19e033 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:39:33 -0700 Subject: davinci: Add support for multiple PSCs The current code to support the DaVinci Power and Sleep Controller (PSC) assumes that there is only one controller. This assumption is no longer valid so expand the support to allow greater than one PSC. To accomplish this, put the base addresses for the PSCs in the SoC infrastructure so it can be referenced by the PSC code. This also requires adding an extra parameter to davinci_psc_config() to specify the PSC that is to be enabled/disabled. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/clock.c | 10 +++++---- arch/arm/mach-davinci/clock.h | 1 + arch/arm/mach-davinci/dm355.c | 6 ++++++ arch/arm/mach-davinci/dm644x.c | 6 ++++++ arch/arm/mach-davinci/dm646x.c | 6 ++++++ arch/arm/mach-davinci/include/mach/common.h | 2 ++ arch/arm/mach-davinci/include/mach/psc.h | 8 +++++--- arch/arm/mach-davinci/psc.c | 32 ++++++++++++++++++++++------- 8 files changed, 57 insertions(+), 14 deletions(-) (limited to 'arch/arm/mach-davinci') 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 584494a3207..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; diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index e93840a814e..37f20a7214b 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -545,6 +545,10 @@ static struct davinci_id dm355_ids[] = { }, }; +static void __iomem *dm355_psc_bases[] = { + IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), +}; + static struct davinci_soc_info davinci_soc_info_dm355 = { .io_desc = dm355_io_desc, .io_desc_num = ARRAY_SIZE(dm355_io_desc), @@ -552,6 +556,8 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .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), }; void __init dm355_init(void) diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 648160c2960..7b15faba56e 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -485,6 +485,10 @@ static struct davinci_id dm644x_ids[] = { }, }; +static void __iomem *dm644x_psc_bases[] = { + IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), +}; + static struct davinci_soc_info davinci_soc_info_dm644x = { .io_desc = dm644x_io_desc, .io_desc_num = ARRAY_SIZE(dm644x_io_desc), @@ -492,6 +496,8 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .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), }; void __init dm644x_init(void) diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 7cf9705be9c..3c61543c7cf 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -465,6 +465,10 @@ static struct davinci_id dm646x_ids[] = { }, }; +static void __iomem *dm646x_psc_bases[] = { + IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE), +}; + static struct davinci_soc_info davinci_soc_info_dm646x = { .io_desc = dm646x_io_desc, .io_desc_num = ARRAY_SIZE(dm646x_io_desc), @@ -472,6 +476,8 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .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), }; void __init dm646x_init(void) diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 97782a76588..7851d5680c1 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -34,6 +34,8 @@ struct davinci_soc_info { struct davinci_id *ids; unsigned long ids_num; struct davinci_clk *cpu_clks; + void __iomem **psc_bases; + unsigned long psc_bases_num; }; extern struct davinci_soc_info davinci_soc_info; 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/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 #include -#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; -- cgit v1.2.3 From 0e585952ac6a06b3c77d6b8eadb9c359766a700d Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:39:48 -0700 Subject: davinci: Move pinmux setup info to SoC infrastructure The pinmux register base and setup can be different for different SoCs so move the pinmux reg base, pinmux table (and its size) to the SoC infrastructure. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm355.c | 6 +++++- arch/arm/mach-davinci/dm644x.c | 6 +++++- arch/arm/mach-davinci/dm646x.c | 6 +++++- arch/arm/mach-davinci/include/mach/common.h | 3 +++ arch/arm/mach-davinci/include/mach/mux.h | 6 ------ arch/arm/mach-davinci/mux.c | 24 +++++++----------------- 6 files changed, 25 insertions(+), 26 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 37f20a7214b..f735ed9d2d1 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -436,6 +436,7 @@ void __init dm355_init_spi0(unsigned chipselect_mask, * 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) @@ -466,6 +467,7 @@ 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 }; /*----------------------------------------------------------------------*/ @@ -558,12 +560,14 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .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), }; void __init dm355_init(void) { davinci_common_init(&davinci_soc_info_dm355); - davinci_mux_register(dm355_pins, ARRAY_SIZE(dm355_pins));; } static int __init dm355_init_devices(void) diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 7b15faba56e..b7c17dd6795 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -346,6 +346,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) @@ -386,6 +387,7 @@ 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 }; /*----------------------------------------------------------------------*/ @@ -498,12 +500,14 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .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), }; void __init dm644x_init(void) { davinci_common_init(&davinci_soc_info_dm644x); - davinci_mux_register(dm644x_pins, ARRAY_SIZE(dm644x_pins)); } static int __init dm644x_init_devices(void) diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 3c61543c7cf..299d8d9d26e 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -327,6 +327,7 @@ static struct platform_device dm646x_emac_device = { * 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) @@ -354,6 +355,7 @@ 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 }; /*----------------------------------------------------------------------*/ @@ -478,12 +480,14 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .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), }; void __init dm646x_init(void) { davinci_common_init(&davinci_soc_info_dm646x); - davinci_mux_register(dm646x_pins, ARRAY_SIZE(dm646x_pins)); } static int __init dm646x_init_devices(void) diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 7851d5680c1..c00d375946d 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -36,6 +36,9 @@ struct davinci_soc_info { 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; }; extern struct davinci_soc_info davinci_soc_info; diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index bae22cb3e27..5d6efa80af6 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -168,15 +168,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/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 #include - -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 /* * 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"); -- cgit v1.2.3 From 673dd36f0d0cf8893d6b46d524ad80e81076b885 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:40:00 -0700 Subject: davinci: Move interrupt ctlr info to SoC infrastructure Use the SoC infrastructure to hold the interrupt controller information (i.e., base address, default priorities, interrupt controller type, and the number of IRQs). The interrupt controller base, although initially put in the soc_info structure's intc_base field, is eventually put in the global 'davinci_intc_base' so the low-level interrupt code can access it without a dereference. These changes enable the SoC default irq priorities to be put in the SoC-specific files, and the interrupt controller to be at any base address. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/common.c | 3 + arch/arm/mach-davinci/dm355.c | 69 +++++++ arch/arm/mach-davinci/dm644x.c | 72 ++++++++ arch/arm/mach-davinci/dm646x.c | 71 ++++++++ arch/arm/mach-davinci/include/mach/common.h | 5 + arch/arm/mach-davinci/include/mach/entry-macro.S | 3 +- arch/arm/mach-davinci/include/mach/irqs.h | 3 + arch/arm/mach-davinci/irq.c | 217 +---------------------- 8 files changed, 229 insertions(+), 214 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index 2e5b888e6ca..d72d517d090 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -22,6 +22,8 @@ struct davinci_soc_info davinci_soc_info; EXPORT_SYMBOL(davinci_soc_info); +void __iomem *davinci_intc_base; + static struct davinci_id * __init davinci_get_id(u32 jtag_id) { int i; @@ -84,6 +86,7 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) goto err; } + davinci_intc_base = davinci_soc_info.intc_base; return; err: diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index f735ed9d2d1..e8c01ffe818 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -470,6 +470,71 @@ 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[] = { @@ -563,6 +628,10 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .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, }; void __init dm355_init(void) diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index b7c17dd6795..5c6a7b17578 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -390,6 +390,74 @@ MUX_CFG(DM644X, LFLDEN, 0, 25, 1, 1, false) #endif }; +/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */ +static u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] = { + [IRQ_VDINT0] = 2, + [IRQ_VDINT1] = 6, + [IRQ_VDINT2] = 6, + [IRQ_HISTINT] = 6, + [IRQ_H3AINT] = 6, + [IRQ_PRVUINT] = 6, + [IRQ_RSZINT] = 6, + [7] = 7, + [IRQ_VENCINT] = 6, + [IRQ_ASQINT] = 6, + [IRQ_IMXINT] = 6, + [IRQ_VLCDINT] = 6, + [IRQ_USBINT] = 4, + [IRQ_EMACINT] = 4, + [14] = 7, + [15] = 7, + [IRQ_CCINT0] = 5, /* dma */ + [IRQ_CCERRINT] = 5, /* dma */ + [IRQ_TCERRINT0] = 5, /* dma */ + [IRQ_TCERRINT] = 5, /* dma */ + [IRQ_PSCIN] = 7, + [21] = 7, + [IRQ_IDE] = 4, + [23] = 7, + [IRQ_MBXINT] = 7, + [IRQ_MBRINT] = 7, + [IRQ_MMCINT] = 7, + [IRQ_SDIOINT] = 7, + [28] = 7, + [IRQ_DDRINT] = 7, + [IRQ_AEMIFINT] = 7, + [IRQ_VLQINT] = 4, + [IRQ_TINT0_TINT12] = 2, /* clockevent */ + [IRQ_TINT0_TINT34] = 2, /* clocksource */ + [IRQ_TINT1_TINT12] = 7, /* DSP timer */ + [IRQ_TINT1_TINT34] = 7, /* system tick */ + [IRQ_PWMINT0] = 7, + [IRQ_PWMINT1] = 7, + [IRQ_PWMINT2] = 7, + [IRQ_I2C] = 3, + [IRQ_UARTINT0] = 3, + [IRQ_UARTINT1] = 3, + [IRQ_UARTINT2] = 3, + [IRQ_SPINT0] = 3, + [IRQ_SPINT1] = 3, + [45] = 7, + [IRQ_DSP2ARM0] = 4, + [IRQ_DSP2ARM1] = 4, + [IRQ_GPIO0] = 7, + [IRQ_GPIO1] = 7, + [IRQ_GPIO2] = 7, + [IRQ_GPIO3] = 7, + [IRQ_GPIO4] = 7, + [IRQ_GPIO5] = 7, + [IRQ_GPIO6] = 7, + [IRQ_GPIO7] = 7, + [IRQ_GPIOBNK0] = 7, + [IRQ_GPIOBNK1] = 7, + [IRQ_GPIOBNK2] = 7, + [IRQ_GPIOBNK3] = 7, + [IRQ_GPIOBNK4] = 7, + [IRQ_COMMTX] = 7, + [IRQ_COMMRX] = 7, + [IRQ_EMUINT] = 7, +}; + /*----------------------------------------------------------------------*/ static const s8 dma_chan_dm644x_no_event[] = { @@ -503,6 +571,10 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .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, }; void __init dm644x_init(void) diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 299d8d9d26e..beb522e8a1a 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -358,6 +358,73 @@ 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[] = { @@ -483,6 +550,10 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .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, }; void __init dm646x_init(void) diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index c00d375946d..838ae13595a 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -17,6 +17,7 @@ struct sys_timer; extern struct sys_timer davinci_timer; extern void davinci_irq_init(void); +extern void __iomem *davinci_intc_base; /* parameters describe VBUS sourcing for host mode */ extern void setup_usb(unsigned mA, unsigned potpgt_msec); @@ -39,6 +40,10 @@ struct davinci_soc_info { 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; }; extern struct davinci_soc_info davinci_soc_info; diff --git a/arch/arm/mach-davinci/include/mach/entry-macro.S b/arch/arm/mach-davinci/include/mach/entry-macro.S index 0ebb4454505..ed78851fe4a 100644 --- a/arch/arm/mach-davinci/include/mach/entry-macro.S +++ b/arch/arm/mach-davinci/include/mach/entry-macro.S @@ -15,7 +15,8 @@ .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 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/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 #include +#include #include #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); -- cgit v1.2.3 From f64691b3ab795268072e76ddb89290b6277cdf33 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:40:11 -0700 Subject: davinci: Add base address and timer flexibility The davinci timer code currently hardcodes the timer register base addresses, the timer irq numbers, and the timers to use for clock events and clocksource. This won't work for some a new SoC so put those values into the soc_info structure and set them up in the SoC-specific files. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/devices.c | 47 +++++++++++++ arch/arm/mach-davinci/dm355.c | 14 ++++ arch/arm/mach-davinci/dm644x.c | 14 ++++ arch/arm/mach-davinci/dm646x.c | 14 ++++ arch/arm/mach-davinci/include/mach/common.h | 13 ++++ arch/arm/mach-davinci/include/mach/time.h | 34 ++++++++++ arch/arm/mach-davinci/time.c | 100 +++++++++++++--------------- 7 files changed, 181 insertions(+), 55 deletions(-) create mode 100644 arch/arm/mach-davinci/include/mach/time.h (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 56c19319a7d..36c528ff30f 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -25,6 +25,7 @@ #include #include #include +#include #define DAVINCI_I2C_BASE 0x01C21000 #define DAVINCI_MMCSD0_BASE 0x01E10000 @@ -235,6 +236,52 @@ static void davinci_init_wdt(void) /*-------------------------------------------------------------------------*/ +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, + }, +}; + +/*-------------------------------------------------------------------------*/ + +#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) + +void davinci_init_emac(struct emac_platform_data *pdata) +{ + DECLARE_MAC_BUF(buf); + + if (cpu_is_davinci_dm644x()) + dm644x_init_emac(pdata); + else if (cpu_is_davinci_dm646x()) + dm646x_init_emac(pdata); + + /* if valid MAC exists, don't re-register */ + if (is_valid_ether_addr(pdata->mac_addr)) + return; + else { + /* Use random MAC if none passed */ + random_ether_addr(pdata->mac_addr); + + printk(KERN_WARNING "%s: using random MAC addr: %s\n", + __func__, print_mac(buf, pdata->mac_addr)); + } +} + +#else + +void davinci_init_emac(struct emac_platform_data *unused) {} + +#endif + +/*-------------------------------------------------------------------------*/ + static int __init davinci_init_devices(void) { /* please keep these calls, and their implementations above, diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index e8c01ffe818..293a419a4a8 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "clock.h" @@ -616,6 +617,18 @@ 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 : + */ +struct davinci_timer_info dm355_timer_info = { + .timers = davinci_timer_instance, + .clockevent_id = T0_BOT, + .clocksource_id = T0_TOP, +}; + static struct davinci_soc_info davinci_soc_info_dm355 = { .io_desc = dm355_io_desc, .io_desc_num = ARRAY_SIZE(dm355_io_desc), @@ -632,6 +645,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .intc_type = DAVINCI_INTC_TYPE_AINTC, .intc_irq_prios = dm355_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, + .timer_info = &dm355_timer_info, }; void __init dm355_init(void) diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 5c6a7b17578..8e9385c3485 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "clock.h" @@ -559,6 +560,18 @@ 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 : + */ +struct davinci_timer_info dm644x_timer_info = { + .timers = davinci_timer_instance, + .clockevent_id = T0_BOT, + .clocksource_id = T0_TOP, +}; + static struct davinci_soc_info davinci_soc_info_dm644x = { .io_desc = dm644x_io_desc, .io_desc_num = ARRAY_SIZE(dm644x_io_desc), @@ -575,6 +588,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .intc_type = DAVINCI_INTC_TYPE_AINTC, .intc_irq_prios = dm644x_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, + .timer_info = &dm644x_timer_info, }; void __init dm644x_init(void) diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index beb522e8a1a..219063f4d00 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "clock.h" @@ -538,6 +539,18 @@ 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 : + */ +struct davinci_timer_info dm646x_timer_info = { + .timers = davinci_timer_instance, + .clockevent_id = T0_BOT, + .clocksource_id = T0_TOP, +}; + static struct davinci_soc_info davinci_soc_info_dm646x = { .io_desc = dm646x_io_desc, .io_desc_num = ARRAY_SIZE(dm646x_io_desc), @@ -554,6 +567,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .intc_type = DAVINCI_INTC_TYPE_AINTC, .intc_irq_prios = dm646x_default_priorities, .intc_irq_num = DAVINCI_N_AINTC_IRQ, + .timer_info = &dm646x_timer_info, }; void __init dm646x_init(void) diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 838ae13595a..90b43be1174 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -25,6 +25,18 @@ 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; +}; + +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; @@ -44,6 +56,7 @@ struct davinci_soc_info { int intc_type; u8 *intc_irq_prios; unsigned long intc_irq_num; + struct davinci_timer_info *timer_info; }; extern struct davinci_soc_info davinci_soc_info; 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..1428d77c989 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/time.h @@ -0,0 +1,34 @@ +/* + * Local header file for DaVinci time code. + * + * Author: Kevin Hilman, MontaVista Software, Inc. + * + * 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) + +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/time.c b/arch/arm/mach-davinci/time.c index efbbc2ac63b..faafb897f4b 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -29,42 +29,23 @@ #include #include #include +#include #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 : */ -#define TID_CLOCKEVENT T0_BOT -#define TID_CLOCKSOURCE T0_TOP + +enum { + TID_CLOCKEVENT, + TID_CLOCKSOURCE, +}; /* Timer register offsets */ #define PID12 0x0 @@ -119,6 +100,13 @@ static struct timer_s timers[]; #define TIMER_OPTS_ONESHOT 0x01 #define TIMER_OPTS_PERIODIC 0x02 +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); @@ -183,13 +171,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); @@ -215,33 +204,30 @@ 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) + setup_irq(irq, &t->irqaction); + + timer32_config(&timers[i]); } } @@ -256,7 +242,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), @@ -301,7 +286,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, @@ -312,10 +296,14 @@ 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; static char err[] __initdata = KERN_ERR "%s: can't register clocksource!\n"; + timers[TID_CLOCKEVENT].id = soc_info->timer_info->clockevent_id; + timers[TID_CLOCKSOURCE].id = soc_info->timer_info->clocksource_id; + /* init timer hw */ timer_init(); @@ -326,6 +314,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[timers[TID_CLOCKSOURCE].id]; clocksource_davinci.mult = clocksource_khz2mult(davinci_clock_tick_rate/1000, clocksource_davinci.shift); @@ -333,6 +322,7 @@ 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 = -- cgit v1.2.3 From 951d6f6d703110790256abfce03ced117d2dcc6b Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:40:21 -0700 Subject: davinci: Add watchdog base address flexibility The watchdog code currently hardcodes the base address of the timer its using. To support new SoCs, make it support timers at any address. Use the soc_info structure to do this. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/devices.c | 7 +++++-- arch/arm/mach-davinci/dm355.c | 1 + arch/arm/mach-davinci/dm644x.c | 1 + arch/arm/mach-davinci/dm646x.c | 1 + arch/arm/mach-davinci/include/mach/common.h | 1 + arch/arm/mach-davinci/include/mach/time.h | 1 + arch/arm/mach-davinci/time.c | 5 ++--- 7 files changed, 12 insertions(+), 5 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 36c528ff30f..7ebf6713f6a 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -216,8 +216,6 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config) static struct resource wdt_resources[] = { { - .start = 0x01c21c00, - .end = 0x01c21fff, .flags = IORESOURCE_MEM, }, }; @@ -231,6 +229,11 @@ struct platform_device davinci_wdt_device = { 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); } diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 293a419a4a8..1b7c16cd267 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -646,6 +646,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .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), }; void __init dm355_init(void) diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 8e9385c3485..c66269264cc 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -589,6 +589,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .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), }; void __init dm644x_init(void) diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 219063f4d00..83d67cf6935 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -568,6 +568,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .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), }; void __init dm646x_init(void) diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 90b43be1174..d63703826a6 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -57,6 +57,7 @@ struct davinci_soc_info { u8 *intc_irq_prios; unsigned long intc_irq_num; struct davinci_timer_info *timer_info; + void __iomem *wdt_base; }; extern struct davinci_soc_info davinci_soc_info; diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h index 1428d77c989..1c971d8d8ba 100644 --- a/arch/arm/mach-davinci/include/mach/time.h +++ b/arch/arm/mach-davinci/include/mach/time.h @@ -13,6 +13,7 @@ #define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400) #define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800) +#define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00) enum { T0_BOT, diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index faafb897f4b..f80ae25a52e 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -35,8 +35,6 @@ static struct clock_event_device clockevent_davinci; static unsigned int davinci_clock_tick_rate; -#define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00) - /* * This driver configures the 2 64-bit count-up timers as 4 independent * 32-bit count-up timers used as follows: @@ -343,7 +341,8 @@ struct sys_timer davinci_timer = { void davinci_watchdog_reset(void) { u32 tgcr, wdtcr; - void __iomem *base = IO_ADDRESS(DAVINCI_WDOG_BASE); + struct davinci_soc_info *soc_info = &davinci_soc_info; + void __iomem *base = soc_info->wdt_base; struct clk *wd_clk; wd_clk = clk_get(&davinci_wdt_device.dev, NULL); -- cgit v1.2.3 From a994955cc091a8a51b7d7412174d9cf6de04d26b Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:40:35 -0700 Subject: davinci: Make GPIO code more generic The current gpio code needs to know the number of gpio irqs there are and what the bank irq number is. To determine those values, it checks the SoC type. It also assumes that the base address and the number of irqs the interrupt controller uses is fixed. To clean up the SoC checks and make it support different base addresses and interrupt controllers, have the SoC-specific code set those values in the soc_info structure and have the gpio code reference them there. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm355.c | 4 +++ arch/arm/mach-davinci/dm644x.c | 4 +++ arch/arm/mach-davinci/dm646x.c | 4 +++ arch/arm/mach-davinci/gpio.c | 39 +++++++++++------------------ arch/arm/mach-davinci/include/mach/common.h | 3 +++ arch/arm/mach-davinci/include/mach/gpio.h | 14 ++++++----- 6 files changed, 37 insertions(+), 31 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 1b7c16cd267..757def75201 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -647,6 +648,9 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .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, }; void __init dm355_init(void) diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index c66269264cc..cfd918e41e2 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -590,6 +591,9 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .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, }; void __init dm644x_init(void) diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 83d67cf6935..f980c2f95de 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -569,6 +570,9 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .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, }; void __init dm646x_init(void) diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index 40327b557d7..1b6532159c5 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -37,8 +38,6 @@ 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) { @@ -116,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; } @@ -279,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; } @@ -329,8 +319,7 @@ 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)); diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index d63703826a6..06ff6d6e367 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -58,6 +58,9 @@ struct davinci_soc_info { 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; }; extern struct davinci_soc_info davinci_soc_info; 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 #include +#include #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 */ -- cgit v1.2.3 From 65e866a9741126c678e6dcd5d4fa8c9eca18e945 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 18 Mar 2009 12:36:08 -0500 Subject: davinci: Move serial platform_device into SoC-specific files Currently, there is one set of platform_device and platform_data structures for all DaVinci SoCs. The differences in the data between the various SoCs is handled by davinci_serial_init() by checking the SoC type. However, as new SoCs appear, this routine will become more & more cluttered. To clean up the routine and make it easier to add support for new SoCs, move the platform_device and platform_data structures into the SoC-specific code and use the SoC infrastructure to provide access to the data. In the process, fix a bug where the wrong irq is used for uart2 of the dm646x. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm355.c | 41 ++++++++++++++++ arch/arm/mach-davinci/dm644x.c | 41 ++++++++++++++++ arch/arm/mach-davinci/dm646x.c | 41 ++++++++++++++++ arch/arm/mach-davinci/include/mach/common.h | 1 + arch/arm/mach-davinci/include/mach/serial.h | 2 +- arch/arm/mach-davinci/serial.c | 74 ++++------------------------- 6 files changed, 135 insertions(+), 65 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 757def75201..4c3257ef5dd 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include #include "clock.h" @@ -630,6 +632,44 @@ struct davinci_timer_info dm355_timer_info = { .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), @@ -651,6 +691,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), .gpio_num = 104, .gpio_irq = IRQ_DM355_GPIOBNK0, + .serial_dev = &dm355_serial_device, }; void __init dm355_init(void) diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index cfd918e41e2..a5629864d02 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include "clock.h" @@ -573,6 +575,44 @@ struct davinci_timer_info dm644x_timer_info = { .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), @@ -594,6 +634,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), .gpio_num = 71, .gpio_irq = IRQ_GPIOBNK0, + .serial_dev = &dm644x_serial_device, }; void __init dm644x_init(void) diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index f980c2f95de..544658e5885 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include "clock.h" @@ -552,6 +554,44 @@ struct davinci_timer_info dm646x_timer_info = { .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), @@ -573,6 +613,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .gpio_base = IO_ADDRESS(DAVINCI_GPIO_BASE), .gpio_num = 43, /* Only 33 usable */ .gpio_irq = IRQ_DM646X_GPIOBNK0, + .serial_dev = &dm646x_serial_device, }; void __init dm646x_init(void) diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 06ff6d6e367..9624e038253 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -61,6 +61,7 @@ struct davinci_soc_info { void __iomem *gpio_base; unsigned gpio_num; unsigned gpio_irq; + struct platform_device *serial_dev; }; extern struct davinci_soc_info davinci_soc_info; diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h index 761ab2b483a..b0c57fa9e4e 100644 --- a/arch/arm/mach-davinci/include/mach/serial.h +++ b/arch/arm/mach-davinci/include/mach/serial.h @@ -30,6 +30,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/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 #include #include +#include + #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); -- cgit v1.2.3 From 972412b648dcf0c4303dca7e515d5c24ce3cd1d5 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:40:56 -0700 Subject: davinci: Move emac platform_data to SoC-specific files Since most of the emac platform_data is really SoC specific and not board specific, move it to the SoC-specific files. Put a pointer to the platform_data in the soc_info structure so the board-specific code can set some of the platform_data if it needs to. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-dm644x-evm.c | 14 +++++------ arch/arm/mach-davinci/board-dm646x-evm.c | 15 ++++++------ arch/arm/mach-davinci/board-sffsdr.c | 6 +++-- arch/arm/mach-davinci/devices.c | 5 ---- arch/arm/mach-davinci/dm644x.c | 34 +++++++++++---------------- arch/arm/mach-davinci/dm646x.c | 36 +++++++++++------------------ arch/arm/mach-davinci/include/mach/common.h | 1 + arch/arm/mach-davinci/include/mach/dm644x.h | 1 - arch/arm/mach-davinci/include/mach/dm646x.h | 1 - 9 files changed, 46 insertions(+), 67 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index cfe89c40973..987d27fcacb 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -38,7 +38,6 @@ #include #include -#include #include #include #include @@ -61,11 +60,6 @@ #define LXT971_PHY_ID (0x001378e2) #define LXT971_PHY_MASK (0xfffffff0) -static struct emac_platform_data dm644x_evm_emac_pdata = { - .phy_mask = DM644X_EVM_PHY_MASK, - .mdio_max_freq = DM644X_EVM_MDIO_FREQUENCY, -}; - static struct mtd_partition davinci_evm_norflash_partitions[] = { /* bootloader (UBL, U-Boot, etc) in first 5 sectors */ { @@ -448,6 +442,7 @@ static struct memory_accessor *at24_mem_acc; static void at24_setup(struct memory_accessor *mem_acc, void *context) { char mac_addr[ETH_ALEN]; + struct davinci_soc_info *soc_info = &davinci_soc_info; at24_mem_acc = mem_acc; @@ -455,7 +450,7 @@ static void at24_setup(struct memory_accessor *mem_acc, void *context) if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x7f00, ETH_ALEN) == ETH_ALEN) { printk(KERN_INFO "Read MAC addr from EEPROM: %pM\n", mac_addr); - memcpy(dm644x_evm_emac_pdata.mac_addr, mac_addr, ETH_ALEN); + memcpy(soc_info->emac_pdata->mac_addr, mac_addr, ETH_ALEN); } } @@ -650,6 +645,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); @@ -686,7 +682,9 @@ static __init void davinci_evm_init(void) davinci_serial_init(&uart_config); - dm644x_init_emac(&dm644x_evm_emac_pdata); + soc_info->emac_pdata->phy_mask = DM644X_EVM_PHY_MASK; + soc_info->emac_pdata->mdio_max_freq = DM644X_EVM_MDIO_FREQUENCY; + dm644x_init_emac(soc_info->emac_pdata); /* Register the fixup for PHY on DaVinci */ phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK, diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index becae51d6dd..0de0637aed5 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -52,11 +52,6 @@ #define DM646X_EVM_PHY_MASK (0x2) #define DM646X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ -static struct emac_platform_data dm646x_evm_emac_pdata = { - .phy_mask = DM646X_EVM_PHY_MASK, - .mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY, -}; - static struct davinci_uart_config uart_config __initdata = { .enabled_uarts = (1 << 0), }; @@ -208,6 +203,7 @@ static struct memory_accessor *at24_mem_acc; static void at24_setup(struct memory_accessor *mem_acc, void *context) { char mac_addr[ETH_ALEN]; + struct davinci_soc_info *soc_info = &davinci_soc_info; at24_mem_acc = mem_acc; @@ -215,7 +211,7 @@ static void at24_setup(struct memory_accessor *mem_acc, void *context) if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x7f00, ETH_ALEN) == ETH_ALEN) { pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr); - memcpy(dm646x_evm_emac_pdata.mac_addr, mac_addr, ETH_ALEN); + memcpy(soc_info->emac_pdata->mac_addr, mac_addr, ETH_ALEN); } } @@ -271,9 +267,14 @@ static void __init davinci_map_io(void) static __init void evm_init(void) { + struct davinci_soc_info *soc_info = &davinci_soc_info; + evm_init_i2c(); davinci_serial_init(&uart_config); - dm646x_init_emac(&dm646x_evm_emac_pdata); + + soc_info->emac_pdata->phy_mask = DM646X_EVM_PHY_MASK; + soc_info->emac_pdata->mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY; + dm646x_init_emac(soc_info->emac_pdata); } static __init void davinci_dm646x_evm_irq_init(void) diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index 938b4467809..748a8e48541 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -48,7 +48,6 @@ #include #include -#include #include #include #include @@ -158,11 +157,14 @@ static void __init davinci_sffsdr_map_io(void) 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); - dm644x_init_emac(&sffsdr_emac_pdata); + 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 */ diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 7ebf6713f6a..c0195cd3a2c 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -260,11 +260,6 @@ void davinci_init_emac(struct emac_platform_data *pdata) { DECLARE_MAC_BUF(buf); - if (cpu_is_davinci_dm644x()) - dm644x_init_emac(pdata); - else if (cpu_is_davinci_dm646x()) - dm646x_init_emac(pdata); - /* if valid MAC exists, don't re-register */ if (is_valid_ether_addr(pdata->mac_addr)) return; diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index a5629864d02..3844fc34cbb 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -319,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[] = { { @@ -337,12 +344,13 @@ 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 - /* * Device specific mux setup * @@ -520,24 +528,6 @@ static struct platform_device dm644x_edma_device = { }; /*----------------------------------------------------------------------*/ -#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) - -void dm644x_init_emac(struct emac_platform_data *pdata) -{ - pdata->ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET; - pdata->ctrl_mod_reg_offset = DM644X_EMAC_CNTRL_MOD_OFFSET; - pdata->ctrl_ram_offset = DM644X_EMAC_CNTRL_RAM_OFFSET; - pdata->mdio_reg_offset = DM644X_EMAC_MDIO_OFFSET; - pdata->ctrl_ram_size = DM644X_EMAC_CNTRL_RAM_SIZE; - pdata->version = EMAC_VERSION_1; - dm644x_emac_device.dev.platform_data = pdata; - platform_device_register(&dm644x_emac_device); -} -#else - -void dm644x_init_emac(struct emac_platform_data *unused) {} - -#endif static struct map_desc dm644x_io_desc[] = { { @@ -635,6 +625,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .gpio_num = 71, .gpio_irq = IRQ_GPIOBNK0, .serial_dev = &dm644x_serial_device, + .emac_pdata = &dm644x_emac_pdata, }; void __init dm644x_init(void) @@ -648,6 +639,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 index 544658e5885..5185ad55fc5 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -286,7 +286,15 @@ struct davinci_clk dm646x_clks[] = { CLK(NULL, NULL, NULL), }; -#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) +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, @@ -318,12 +326,13 @@ static struct resource dm646x_emac_resources[] = { 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, }; -#endif - /* * Device specific mux setup * @@ -499,25 +508,6 @@ static struct platform_device dm646x_edma_device = { /*----------------------------------------------------------------------*/ -#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) - -void dm646x_init_emac(struct emac_platform_data *pdata) -{ - pdata->ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET; - pdata->ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET; - pdata->ctrl_ram_offset = DM646X_EMAC_CNTRL_RAM_OFFSET; - pdata->mdio_reg_offset = DM646X_EMAC_MDIO_OFFSET; - pdata->ctrl_ram_size = DM646X_EMAC_CNTRL_RAM_SIZE; - pdata->version = EMAC_VERSION_2; - dm646x_emac_device.dev.platform_data = pdata; - platform_device_register(&dm646x_emac_device); -} -#else - -void dm646x_init_emac(struct emac_platform_data *unused) {} - -#endif - static struct map_desc dm646x_io_desc[] = { { .virtual = IO_VIRT, @@ -614,6 +604,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .gpio_num = 43, /* Only 33 usable */ .gpio_irq = IRQ_DM646X_GPIOBNK0, .serial_dev = &dm646x_serial_device, + .emac_pdata = &dm646x_emac_pdata, }; void __init dm646x_init(void) @@ -627,6 +618,7 @@ static int __init dm646x_init_devices(void) 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/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 9624e038253..b773d92e737 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -62,6 +62,7 @@ struct davinci_soc_info { unsigned gpio_num; unsigned gpio_irq; struct platform_device *serial_dev; + struct emac_platform_data *emac_pdata; }; extern struct davinci_soc_info davinci_soc_info; diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h index ace167aec46..15d42b92a8c 100644 --- a/arch/arm/mach-davinci/include/mach/dm644x.h +++ b/arch/arm/mach-davinci/include/mach/dm644x.h @@ -34,6 +34,5 @@ #define DM644X_EMAC_CNTRL_RAM_SIZE (0x2000) void __init dm644x_init(void); -void dm644x_init_emac(struct emac_platform_data *pdata); #endif /* __ASM_ARCH_DM644X_H */ diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h index ea7b28e112f..1fc764c8646 100644 --- a/arch/arm/mach-davinci/include/mach/dm646x.h +++ b/arch/arm/mach-davinci/include/mach/dm646x.h @@ -22,6 +22,5 @@ #define DM646X_EMAC_CNTRL_RAM_SIZE (0x2000) void __init dm646x_init(void); -void dm646x_init_emac(struct emac_platform_data *pdata); #endif /* __ASM_ARCH_DM646X_H */ -- cgit v1.2.3 From c97909fcf1611645f0fe235b332e39623588d84c Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:41:15 -0700 Subject: davinci: Remove unused i2c eeprom_read/write routines The dm644x and dm646x board files have i2c eeprom read and write routines but they are not used so remove them. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-dm646x-evm.c | 16 ---------------- arch/arm/mach-davinci/include/mach/board-dm6446evm.h | 20 -------------------- 2 files changed, 36 deletions(-) delete mode 100644 arch/arm/mach-davinci/include/mach/board-dm6446evm.h (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 0de0637aed5..44e2ab665af 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -222,22 +222,6 @@ static struct at24_platform_data eeprom_info = { .setup = at24_setup, }; -int dm646xevm_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(dm646xevm_eeprom_read); - -int dm646xevm_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(dm646xevm_eeprom_write); - static struct i2c_board_info __initdata i2c_info[] = { { I2C_BOARD_INFO("24c256", 0x50), 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 - -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 -- cgit v1.2.3 From b14dc0f9942a9c318c6c49f29511d88b3642e2d0 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:41:27 -0700 Subject: davinci: Factor out emac mac address handling Factor out the code to extract that mac address from i2c eeprom. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-dm644x-evm.c | 21 +++------------------ arch/arm/mach-davinci/board-dm646x-evm.c | 20 ++------------------ arch/arm/mach-davinci/common.c | 12 ++++++++++++ arch/arm/mach-davinci/devices.c | 26 -------------------------- arch/arm/mach-davinci/include/mach/emac.h | 6 +++--- 5 files changed, 20 insertions(+), 65 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 987d27fcacb..d9d40450bdc 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #define DM644X_EVM_PHY_MASK (0x2) @@ -437,28 +438,13 @@ 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) -{ - char mac_addr[ETH_ALEN]; - struct davinci_soc_info *soc_info = &davinci_soc_info; - - at24_mem_acc = mem_acc; - - /* Read MAC addr from EEPROM */ - if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x7f00, ETH_ALEN) == - ETH_ALEN) { - printk(KERN_INFO "Read MAC addr from EEPROM: %pM\n", mac_addr); - memcpy(soc_info->emac_pdata->mac_addr, mac_addr, ETH_ALEN); - } -} 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, }; /* @@ -684,7 +670,6 @@ static __init void davinci_evm_init(void) soc_info->emac_pdata->phy_mask = DM644X_EVM_PHY_MASK; soc_info->emac_pdata->mdio_max_freq = DM644X_EVM_MDIO_FREQUENCY; - dm644x_init_emac(soc_info->emac_pdata); /* Register the fixup for PHY on DaVinci */ phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK, diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 44e2ab665af..e17de635262 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -198,28 +198,13 @@ static struct pcf857x_platform_data pcf_data = { * - 0x7f00, 6 bytes Ethernet Address * - ... newer boards may have more */ -static struct memory_accessor *at24_mem_acc; - -static void at24_setup(struct memory_accessor *mem_acc, void *context) -{ - char mac_addr[ETH_ALEN]; - struct davinci_soc_info *soc_info = &davinci_soc_info; - - at24_mem_acc = mem_acc; - - /* Read MAC addr from EEPROM */ - if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x7f00, ETH_ALEN) == - ETH_ALEN) { - pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr); - memcpy(soc_info->emac_pdata->mac_addr, mac_addr, ETH_ALEN); - } -} 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, }; static struct i2c_board_info __initdata i2c_info[] = { @@ -258,7 +243,6 @@ static __init void evm_init(void) soc_info->emac_pdata->phy_mask = DM646X_EVM_PHY_MASK; soc_info->emac_pdata->mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY; - dm646x_init_emac(soc_info->emac_pdata); } static __init void davinci_dm646x_evm_irq_init(void) diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index d72d517d090..169ec73f8d7 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -10,12 +10,14 @@ */ #include #include +#include #include #include #include #include +#include #include "clock.h" @@ -24,6 +26,16 @@ EXPORT_SYMBOL(davinci_soc_info); void __iomem *davinci_intc_base; +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; diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index c0195cd3a2c..c85091c25d1 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -254,32 +254,6 @@ struct davinci_timer_instance davinci_timer_instance[2] = { /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) - -void davinci_init_emac(struct emac_platform_data *pdata) -{ - DECLARE_MAC_BUF(buf); - - /* if valid MAC exists, don't re-register */ - if (is_valid_ether_addr(pdata->mac_addr)) - return; - else { - /* Use random MAC if none passed */ - random_ether_addr(pdata->mac_addr); - - printk(KERN_WARNING "%s: using random MAC addr: %s\n", - __func__, print_mac(buf, pdata->mac_addr)); - } -} - -#else - -void davinci_init_emac(struct emac_platform_data *unused) {} - -#endif - -/*-------------------------------------------------------------------------*/ - static int __init davinci_init_devices(void) { /* please keep these calls, and their implementations above, diff --git a/arch/arm/mach-davinci/include/mach/emac.h b/arch/arm/mach-davinci/include/mach/emac.h index 549fcced217..beff4fb7c84 100644 --- a/arch/arm/mach-davinci/include/mach/emac.h +++ b/arch/arm/mach-davinci/include/mach/emac.h @@ -12,6 +12,7 @@ #define _MACH_DAVINCI_EMAC_H #include +#include struct emac_platform_data { char mac_addr[ETH_ALEN]; @@ -30,7 +31,6 @@ enum { EMAC_VERSION_1, /* DM644x */ EMAC_VERSION_2, /* DM646x */ }; -void davinci_init_emac(struct emac_platform_data *pdata); -#endif - +void davinci_get_mac_addr(struct memory_accessor *mem_acc, void *context); +#endif -- cgit v1.2.3 From 0b0c4c2a6974eae7b96066cb0da35b526fe58468 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:41:40 -0700 Subject: davinci: Integrate cp_intc support into low-level irq code Integrate the Common Platform Interrupt Controller (cp_intc) support into the low-level irq handling for davinci and similar platforms. Do it such that support for cp_intc and the original aintc can coexist in the same kernel binary. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/Kconfig | 6 ++++++ arch/arm/mach-davinci/Makefile | 6 ++++-- arch/arm/mach-davinci/common.c | 2 ++ arch/arm/mach-davinci/include/mach/common.h | 1 + arch/arm/mach-davinci/include/mach/entry-macro.S | 19 +++++++++++++++++++ 5 files changed, 32 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index d7614a0ab2f..76408670554 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -1,5 +1,8 @@ if ARCH_DAVINCI +config AINTC + bool + config CP_INTC bool @@ -9,12 +12,15 @@ 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" diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index a65d03bb467..5b62d8a4b18 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -4,17 +4,19 @@ # # Common objects -obj-y := time.o irq.o clock.o serial.o io.o psc.o \ +obj-y := time.o clock.o serial.o io.o psc.o \ gpio.o devices.o dma.o usb.o common.o obj-$(CONFIG_DAVINCI_MUX) += mux.o -obj-$(CONFIG_CP_INTC) += cp_intc.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 diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index 169ec73f8d7..61ede19c6b5 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -25,6 +25,7 @@ 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) { @@ -99,6 +100,7 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) } davinci_intc_base = davinci_soc_info.intc_base; + davinci_intc_type = davinci_soc_info.intc_type; return; err: diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index b773d92e737..22db6774487 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -18,6 +18,7 @@ extern struct sys_timer davinci_timer; extern void davinci_irq_init(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); diff --git a/arch/arm/mach-davinci/include/mach/entry-macro.S b/arch/arm/mach-davinci/include/mach/entry-macro.S index ed78851fe4a..fbdebc7cb40 100644 --- a/arch/arm/mach-davinci/include/mach/entry-macro.S +++ b/arch/arm/mach-davinci/include/mach/entry-macro.S @@ -23,9 +23,28 @@ .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp +#if defined(CONFIG_AINTC) && defined(CONFIG_CP_INTC) + ldr \tmp, =davinci_intc_type + ldr \tmp, [\tmp] + cmp \tmp, #DAVINCI_INTC_TYPE_CP_INTC + beq 1001f +#endif +#if defined(CONFIG_AINTC) ldr \tmp, [\base, #0x14] movs \tmp, \tmp, lsr #2 sub \irqnr, \tmp, #1 + b 1002f +#endif +#if defined(CONFIG_CP_INTC) +1001: ldr \irqnr, [\base, #0x80] /* get irq number */ + and \irqnr, \irqnr, #0xff /* irq is in bits 0-9 */ + mov \tmp, \irqnr, lsr #3 + and \tmp, \tmp, #0xfc + add \tmp, \tmp, #0x280 /* get the register offset */ + ldr \irqstat, [\base, \tmp] /* get the intc status */ + cmp \irqstat, #0x0 +#endif +1002: .endm .macro irq_prio_table -- cgit v1.2.3 From 3abd5acfff0111809463bcfd7236a1bdf09e4e2d Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:41:54 -0700 Subject: davinci: Add compare register support to timer code The Timer64p timer has 8 compare registers that can be used to generate interrupts when the timer value matches the compare reg's value. They do not disturb the timer itself. This can be useful when there is only one timer available for both clock events and clocksource. When enabled, the clocksource remains a continuous 32-bit counter but the clock event will no longer support periodic interrupts. Instead only oneshot timers will be supported and implemented by setting the compare register to the current timer value plus the period that the clock event subsystem is requesting. Compare registers support is enabled automatically when the following conditions are met: 1) The same timer is being used for clock events and clocksource. 2) The timer is the bottom half (32 bits) of the 64-bit timer (hardware limitation). 3) The the compare register offset and irq are not zero. Since the timer is always running, there is a hardware race in timer32_config() between reading the current timer value, and adding the period to the current timer value and writing the compare register. Testing on a da830 evm board with the timer clocked at 24 MHz and the processor clocked at 300 MHz, showed the number of counter ticks to do this ranged from 20-53 (~1-2.2 usecs) but usually around 41 ticks. This includes some artifacts from collecting the information. So, the minimum period should be at least 5 usecs to be safe. There is also an non-critical lower limit that the period should be since there is no point in setting an event that is much shorter than the time it takes to set the event, and get & handle the timer interrupt for that event. There can also be all sorts of delays from activities occuring elsewhere in the system (including hardware activitis like cache & TLB management). These are virtually impossible to quantify so a minimum period of 50 usecs was chosen. That will certianly be enough to avoid the actual hardware race but hopefully not large enough to cause unreasonably course-grained timers. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/include/mach/common.h | 2 + arch/arm/mach-davinci/time.c | 141 ++++++++++++++++++++-------- 2 files changed, 105 insertions(+), 38 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 22db6774487..715528f0dbd 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -30,6 +30,8 @@ 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 { diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index f80ae25a52e..fc90d3ee0eb 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -46,14 +46,24 @@ enum { }; /* 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 @@ -85,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; @@ -94,9 +105,13 @@ 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", @@ -107,24 +122,41 @@ static char *id_to_name[] = { 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_get_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; } @@ -222,8 +254,11 @@ static void __init timer_init(void) /* Register interrupt */ t->irqaction.name = t->name; t->irqaction.dev_id = (void *)t; - if (t->irqaction.handler != NULL) + + if (t->irqaction.handler != NULL) { + irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq; setup_irq(irq, &t->irqaction); + } timer32_config(&timers[i]); } @@ -268,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; @@ -295,12 +333,40 @@ 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"; - timers[TID_CLOCKEVENT].id = soc_info->timer_info->clockevent_id; - timers[TID_CLOCKSOURCE].id = soc_info->timer_info->clocksource_id; + 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(); @@ -312,7 +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[timers[TID_CLOCKSOURCE].id]; + clocksource_davinci.name = id_to_name[clocksource_id]; clocksource_davinci.mult = clocksource_khz2mult(davinci_clock_tick_rate/1000, clocksource_davinci.shift); @@ -325,8 +391,7 @@ static void __init davinci_timer_init(void) 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); -- cgit v1.2.3 From 5570078c0ec5ecc5df0bbd7d06f43549b7127ae7 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 15 Apr 2009 12:42:06 -0700 Subject: davinci: Move PINMUX defines to SoC files Different SoC have different numbers of pinmux registers and other resources that overlap with each other. To clean up the code and eliminate defines that overlap with each other, move the PINMUX defines to the SoC specific files. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm355.c | 8 ++++++++ arch/arm/mach-davinci/dm644x.c | 3 +++ arch/arm/mach-davinci/dm646x.c | 3 +++ arch/arm/mach-davinci/include/mach/mux.h | 10 ---------- arch/arm/mach-davinci/time.c | 2 +- 5 files changed, 15 insertions(+), 11 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 4c3257ef5dd..78fc598b0bc 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -433,6 +433,14 @@ void __init dm355_init_spi0(unsigned chipselect_mask, /*----------------------------------------------------------------------*/ +#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 * diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 3844fc34cbb..4ab5f07ead0 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -351,6 +351,9 @@ static struct platform_device dm644x_emac_device = { .resource = dm644x_emac_resources, }; +#define PINMUX0 0x00 +#define PINMUX1 0x04 + /* * Device specific mux setup * diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 5185ad55fc5..12189c737a3 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -333,6 +333,9 @@ static struct platform_device dm646x_emac_device = { .resource = dm646x_emac_resources, }; +#define PINMUX0 0x00 +#define PINMUX1 0x04 + /* * Device specific mux setup * diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index 5d6efa80af6..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; diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index fc90d3ee0eb..0884ca57bfb 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -123,7 +123,7 @@ static char *id_to_name[] = { static int timer32_config(struct timer_s *t) { u32 tcr; - struct davinci_soc_info *soc_info = davinci_get_soc_info(); + struct davinci_soc_info *soc_info = &davinci_soc_info; if (USING_COMPARE(t)) { struct davinci_timer_instance *dtip = -- cgit v1.2.3 From 96ed299fdb572fd694d361dc49285dddc0c87da4 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 30 Apr 2009 11:20:24 -0700 Subject: davinci: cleanup: move dm355 UART2 define to dm355.c Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm355.c | 2 ++ arch/arm/mach-davinci/include/mach/serial.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 78fc598b0bc..893d5ba21d5 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -34,6 +34,8 @@ #include "clock.h" #include "mux.h" +#define DM355_UART2_BASE (IO_PHYS + 0x206000) + /* * Device specific clocks */ diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h index b0c57fa9e4e..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 -- cgit v1.2.3 From b79dbdefd2be0980c58b5e36fdc23eb14a7caab4 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 30 Apr 2009 17:33:27 -0700 Subject: davinci: remove remnants of IRAM allocator Remove remnants of dm6446-specific SRAM allocator, as preparation for a more generic replacement. Signed-off-by: David Brownell Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/include/mach/edma.h | 4 ---- arch/arm/mach-davinci/include/mach/memory.h | 1 - 2 files changed, 5 deletions(-) (limited to 'arch/arm/mach-davinci') 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/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 -- cgit v1.2.3 From 0d04eb47054f685b23033ed6ceadfb20db77c5b3 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 30 Apr 2009 17:35:48 -0700 Subject: davinci: soc-specific SRAM setup Package on-chip SRAM. It's always accessible from the ARM, so set up a standardized virtual address mapping into a 128 KiB area that's reserved for platform use. In some cases (dm6467) the physical addresses used for EDMA are not the same as the ones used by the ARM ... so record that info separately in the SOC data, for chips (unlike the OMAP-L137) where SRAM may be used with EDMA. Other blocks of SRAM, such as the ETB buffer or DSP L1/L2 RAM, may be unused/available on some system. They are ignored here. Signed-off-by: David Brownell Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm355.c | 9 +++++++++ arch/arm/mach-davinci/dm644x.c | 9 +++++++++ arch/arm/mach-davinci/dm646x.c | 9 +++++++++ arch/arm/mach-davinci/include/mach/common.h | 6 ++++++ 4 files changed, 33 insertions(+) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 893d5ba21d5..baaaf328de2 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -613,6 +613,13 @@ static struct map_desc dm355_io_desc[] = { .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 */ @@ -702,6 +709,8 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .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) diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 4ab5f07ead0..fb5449b3c97 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -539,6 +539,13 @@ static struct map_desc dm644x_io_desc[] = { .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 */ @@ -629,6 +636,8 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .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) diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 12189c737a3..334f0711e0f 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -518,6 +518,13 @@ static struct map_desc dm646x_io_desc[] = { .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 */ @@ -608,6 +615,8 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .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) diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 715528f0dbd..a1f03b606d8 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -66,10 +66,16 @@ struct davinci_soc_info { 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 */ -- cgit v1.2.3 From 20e9969b3aa5166d50c8df474967c9d80bf6d481 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 7 May 2009 09:31:42 -0700 Subject: davinci: add SRAM allocator Provide a generic SRAM allocator using genalloc, and vaguely modeled after what AVR32 uses. This builds on top of the static CPU mapping set up in the previous patch, and returns DMA mappings as requested (if possible). Compared to its OMAP cousin, there's no current support for (currently non-existent) DaVinci power management code running in SRAM; and this has ways to deallocate, instead of being allocate-only. The initial user of this should probably be the audio code, because EDMA from DDR is subject to various dropouts on at least DM355 and DM6446 chips. Signed-off-by: David Brownell Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/Makefile | 2 +- arch/arm/mach-davinci/include/mach/sram.h | 27 +++++++++++ arch/arm/mach-davinci/sram.c | 74 +++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-davinci/include/mach/sram.h create mode 100644 arch/arm/mach-davinci/sram.c (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 5b62d8a4b18..059ab78084b 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -5,7 +5,7 @@ # Common objects obj-y := time.o clock.o serial.o io.o psc.o \ - gpio.o devices.o dma.o usb.o common.o + gpio.o devices.o dma.o usb.o common.o sram.o obj-$(CONFIG_DAVINCI_MUX) += mux.o 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/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 +#include +#include +#include + +#include +#include +#include + + +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); + -- cgit v1.2.3