From 3e062b07ada88edb9ffdd147e39c7df4b4418f64 Mon Sep 17 00:00:00 2001 From: Vladimir Barinov Date: Tue, 5 Jun 2007 16:36:55 +0100 Subject: [ARM] 4430/1: davinci: clock control support Support clock control driver for TI DaVinci SoC Signed-off-by: Vladimir Barinov Signed-off-by: Kevin Hilman Signed-off-by: Russell King diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index a8f88cd..b86c7f0 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 serial.o io.o id.o psc.o +obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o # Board specific obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o diff --git a/arch/arm/mach-davinci/board-evm.c b/arch/arm/mach-davinci/board-evm.c index 633c12e..9e4024c 100644 --- a/arch/arm/mach-davinci/board-evm.c +++ b/arch/arm/mach-davinci/board-evm.c @@ -32,6 +32,7 @@ void __init davinci_psc_init(void); void __init davinci_irq_init(void); void __init davinci_map_common_io(void); +void __init davinci_init_common_hw(void); /* NOR Flash base address set to CS0 by default */ #define NOR_FLASH_PHYS 0x02000000 @@ -116,6 +117,7 @@ static __init void davinci_evm_init(void) static __init void davinci_evm_irq_init(void) { + davinci_init_common_hw(); davinci_irq_init(); } diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c new file mode 100644 index 0000000..139ceaa --- /dev/null +++ b/arch/arm/mach-davinci/clock.c @@ -0,0 +1,323 @@ +/* + * TI DaVinci clock config file + * + * Copyright (C) 2006 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include "clock.h" + +/* PLL/Reset register offsets */ +#define PLLM 0x110 + +static LIST_HEAD(clocks); +static DEFINE_MUTEX(clocks_mutex); +static DEFINE_SPINLOCK(clockfw_lock); + +static unsigned int commonrate; +static unsigned int armrate; +static unsigned int fixedrate = 27000000; /* 27 MHZ */ + +extern void davinci_psc_config(unsigned int domain, unsigned int id, char enable); + +/* + * Returns a clock. Note that we first try to use device id on the bus + * and clock name. If this fails, we try to use clock name only. + */ +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + int idno; + + if (dev == NULL || dev->bus != &platform_bus_type) + idno = -1; + else + idno = to_platform_device(dev)->id; + + mutex_lock(&clocks_mutex); + + list_for_each_entry(p, &clocks, node) { + if (p->id == idno && + strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + clk = p; + goto found; + } + } + + list_for_each_entry(p, &clocks, node) { + if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + clk = p; + break; + } + } + +found: + mutex_unlock(&clocks_mutex); + + return clk; +} +EXPORT_SYMBOL(clk_get); + +void clk_put(struct clk *clk) +{ + if (clk && !IS_ERR(clk)) + module_put(clk->owner); +} +EXPORT_SYMBOL(clk_put); + +static int __clk_enable(struct clk *clk) +{ + if (clk->flags & ALWAYS_ENABLED) + return 0; + + davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 1); + return 0; +} + +static void __clk_disable(struct clk *clk) +{ + if (clk->usecount) + return; + + davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 0); +} + +int clk_enable(struct clk *clk) +{ + unsigned long flags; + int ret = 0; + + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + if (clk->usecount++ == 0) { + spin_lock_irqsave(&clockfw_lock, flags); + ret = __clk_enable(clk); + spin_unlock_irqrestore(&clockfw_lock, flags); + } + + return ret; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ + unsigned long flags; + + if (clk == NULL || IS_ERR(clk)) + return; + + if (clk->usecount > 0 && !(--clk->usecount)) { + spin_lock_irqsave(&clockfw_lock, flags); + __clk_disable(clk); + spin_unlock_irqrestore(&clockfw_lock, flags); + } +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + return *(clk->rate); +} +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + return *(clk->rate); +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + /* changing the clk rate is not supported */ + return -EINVAL; +} +EXPORT_SYMBOL(clk_set_rate); + +int clk_register(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + mutex_lock(&clocks_mutex); + list_add(&clk->node, &clocks); + mutex_unlock(&clocks_mutex); + + return 0; +} +EXPORT_SYMBOL(clk_register); + +void clk_unregister(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return; + + mutex_lock(&clocks_mutex); + list_del(&clk->node); + mutex_unlock(&clocks_mutex); +} +EXPORT_SYMBOL(clk_unregister); + +static struct clk davinci_clks[] = { + { + .name = "ARMCLK", + .rate = &armrate, + .lpsc = -1, + .flags = ALWAYS_ENABLED, + }, + { + .name = "UART", + .rate = &fixedrate, + .lpsc = DAVINCI_LPSC_UART0, + }, + { + .name = "EMACCLK", + .rate = &commonrate, + .lpsc = DAVINCI_LPSC_EMAC_WRAPPER, + }, + { + .name = "I2CCLK", + .rate = &fixedrate, + .lpsc = DAVINCI_LPSC_I2C, + }, + { + .name = "IDECLK", + .rate = &commonrate, + .lpsc = DAVINCI_LPSC_ATA, + }, + { + .name = "McBSPCLK", + .rate = &commonrate, + .lpsc = DAVINCI_LPSC_McBSP, + }, + { + .name = "MMCSDCLK", + .rate = &commonrate, + .lpsc = DAVINCI_LPSC_MMC_SD, + }, + { + .name = "SPICLK", + .rate = &commonrate, + .lpsc = DAVINCI_LPSC_SPI, + }, + { + .name = "gpio", + .rate = &commonrate, + .lpsc = DAVINCI_LPSC_GPIO, + }, + { + .name = "AEMIFCLK", + .rate = &commonrate, + .lpsc = DAVINCI_LPSC_AEMIF, + .usecount = 1, + } +}; + +int __init davinci_clk_init(void) +{ + struct clk *clkp; + int count = 0; + u32 pll_mult; + + pll_mult = davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLM); + commonrate = ((pll_mult + 1) * 27000000) / 6; + armrate = ((pll_mult + 1) * 27000000) / 2; + + for (clkp = davinci_clks; count < ARRAY_SIZE(davinci_clks); + count++, clkp++) { + clk_register(clkp); + + /* Turn on clocks that have been enabled in the + * table above */ + if (clkp->usecount) + clk_enable(clkp); + } + + return 0; +} + +#ifdef CONFIG_PROC_FS +#include +#include + +static void *davinci_ck_start(struct seq_file *m, loff_t *pos) +{ + return *pos < 1 ? (void *)1 : NULL; +} + +static void *davinci_ck_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return NULL; +} + +static void davinci_ck_stop(struct seq_file *m, void *v) +{ +} + +static int davinci_ck_show(struct seq_file *m, void *v) +{ + struct clk *cp; + + list_for_each_entry(cp, &clocks, node) + seq_printf(m,"%s %d %d\n", cp->name, *(cp->rate), cp->usecount); + + return 0; +} + +static struct seq_operations davinci_ck_op = { + .start = davinci_ck_start, + .next = davinci_ck_next, + .stop = davinci_ck_stop, + .show = davinci_ck_show +}; + +static int davinci_ck_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &davinci_ck_op); +} + +static struct file_operations proc_davinci_ck_operations = { + .open = davinci_ck_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int __init davinci_ck_proc_init(void) +{ + struct proc_dir_entry *entry; + + entry = create_proc_entry("davinci_clocks", 0, NULL); + if (entry) + entry->proc_fops = &proc_davinci_ck_operations; + return 0; + +} +__initcall(davinci_ck_proc_init); +#endif /* CONFIG_DEBUG_PROC_FS */ diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h new file mode 100644 index 0000000..ed47079 --- /dev/null +++ b/arch/arm/mach-davinci/clock.h @@ -0,0 +1,33 @@ +/* + * TI DaVinci clock definitions + * + * Copyright (C) 2006 Texas Instruments. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_DAVINCI_CLOCK_H +#define __ARCH_ARM_DAVINCI_CLOCK_H + +struct clk { + struct list_head node; + struct module *owner; + const char *name; + unsigned int *rate; + int id; + __s8 usecount; + __u8 flags; + __u8 lpsc; +}; + +/* Clock flags */ +#define RATE_CKCTL 1 +#define RATE_FIXED 2 +#define RATE_PROPAGATES 4 +#define VIRTUAL_CLOCK 8 +#define ALWAYS_ENABLED 16 +#define ENABLE_REG_32BIT 32 + +#endif diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c index 87fae6f..47787ff 100644 --- a/arch/arm/mach-davinci/io.c +++ b/arch/arm/mach-davinci/io.c @@ -17,6 +17,7 @@ #include #include +#include extern void davinci_check_revision(void); @@ -49,3 +50,8 @@ void __init davinci_map_common_io(void) */ davinci_check_revision(); } + +void __init davinci_init_common_hw(void) +{ + davinci_clk_init(); +} diff --git a/include/asm-arm/arch-davinci/clock.h b/include/asm-arm/arch-davinci/clock.h new file mode 100644 index 0000000..cc168b7 --- /dev/null +++ b/include/asm-arm/arch-davinci/clock.h @@ -0,0 +1,22 @@ +/* + * include/asm-arm/arch-davinci/clock.h + * + * Clock control driver for DaVinci - header file + * + * Authors: Vladimir Barinov + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#ifndef __ASM_ARCH_DAVINCI_CLOCK_H +#define __ASM_ARCH_DAVINCI_CLOCK_H + +struct clk; + +extern int clk_register(struct clk *clk); +extern void clk_unregister(struct clk *clk); +extern int davinci_clk_init(void); + +#endif -- cgit v0.10.2 From 3d9edf09d4525dad95f98b31f31aa86b8071fab9 Mon Sep 17 00:00:00 2001 From: Vladimir Barinov Date: Tue, 10 Jul 2007 13:03:43 +0100 Subject: [ARM] 4457/2: davinci: GPIO support Support GPIO driver for TI DaVinci SoC Signed-off-by: Vladimir Barinov Acked-by: David Brownell Acked-by: Kevin Hilman Signed-off-by: Russell King diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 50d9f3e..d0aaecb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -384,6 +384,7 @@ config ARCH_DAVINCI bool "TI DaVinci" select GENERIC_TIME select GENERIC_CLOCKEVENTS + select GENERIC_GPIO help Support for TI's DaVinci platform. diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index b86c7f0..731c0a6 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -4,7 +4,8 @@ # # 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 id.o psc.o \ + gpio.o # Board specific obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c new file mode 100644 index 0000000..9c67886 --- /dev/null +++ b/arch/arm/mach-davinci/gpio.c @@ -0,0 +1,286 @@ +/* + * TI DaVinci GPIO Support + * + * Copyright (c) 2006 David Brownell + * Copyright (c) 2007, MontaVista Software, Inc. + * + * 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 +#include +#include + +#include +#include +#include + +#include + +static DEFINE_SPINLOCK(gpio_lock); +static DECLARE_BITMAP(gpio_in_use, DAVINCI_N_GPIO); + +int gpio_request(unsigned gpio, const char *tag) +{ + if (gpio >= DAVINCI_N_GPIO) + return -EINVAL; + + if (test_and_set_bit(gpio, gpio_in_use)) + return -EBUSY; + + return 0; +} +EXPORT_SYMBOL(gpio_request); + +void gpio_free(unsigned gpio) +{ + if (gpio >= DAVINCI_N_GPIO) + return; + + clear_bit(gpio, gpio_in_use); +} +EXPORT_SYMBOL(gpio_free); + +/* create a non-inlined version */ +static struct gpio_controller *__iomem gpio2controller(unsigned gpio) +{ + return __gpio_to_controller(gpio); +} + +/* + * Assuming the pin is muxed as a gpio output, set its output value. + */ +void __gpio_set(unsigned gpio, int value) +{ + struct gpio_controller *__iomem g = gpio2controller(gpio); + + __raw_writel(__gpio_mask(gpio), value ? &g->set_data : &g->clr_data); +} +EXPORT_SYMBOL(__gpio_set); + + +/* + * Read the pin's value (works even if it's set up as output); + * returns zero/nonzero. + * + * Note that changes are synched to the GPIO clock, so reading values back + * right after you've set them may give old values. + */ +int __gpio_get(unsigned gpio) +{ + struct gpio_controller *__iomem g = gpio2controller(gpio); + + return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data)); +} +EXPORT_SYMBOL(__gpio_get); + + +/*--------------------------------------------------------------------------*/ + +/* + * board setup code *MUST* set PINMUX0 and PINMUX1 as + * needed, and enable the GPIO clock. + */ + +int gpio_direction_input(unsigned gpio) +{ + struct gpio_controller *__iomem g = gpio2controller(gpio); + u32 temp; + u32 mask; + + if (!g) + return -EINVAL; + + spin_lock(&gpio_lock); + mask = __gpio_mask(gpio); + temp = __raw_readl(&g->dir); + temp |= mask; + __raw_writel(temp, &g->dir); + spin_unlock(&gpio_lock); + return 0; +} +EXPORT_SYMBOL(gpio_direction_input); + +int gpio_direction_output(unsigned gpio, int value) +{ + struct gpio_controller *__iomem g = gpio2controller(gpio); + u32 temp; + u32 mask; + + if (!g) + return -EINVAL; + + spin_lock(&gpio_lock); + mask = __gpio_mask(gpio); + temp = __raw_readl(&g->dir); + temp &= ~mask; + __raw_writel(mask, value ? &g->set_data : &g->clr_data); + __raw_writel(temp, &g->dir); + spin_unlock(&gpio_lock); + return 0; +} +EXPORT_SYMBOL(gpio_direction_output); + +/* + * We expect irqs will normally be set up as input pins, but they can also be + * used as output pins ... which is convenient for testing. + * + * NOTE: GPIO0..GPIO7 also have direct INTC hookups, which work in addition + * to their GPIOBNK0 irq (but with a bit less overhead). But we don't have + * a good way to hook those up ... + * + * All those INTC hookups (GPIO0..GPIO7 plus five IRQ banks) can also + * serve as EDMA event triggers. + */ + +static void gpio_irq_disable(unsigned irq) +{ + struct gpio_controller *__iomem g = get_irq_chip_data(irq); + u32 mask = __gpio_mask(irq_to_gpio(irq)); + + __raw_writel(mask, &g->clr_falling); + __raw_writel(mask, &g->clr_rising); +} + +static void gpio_irq_enable(unsigned irq) +{ + struct gpio_controller *__iomem g = get_irq_chip_data(irq); + u32 mask = __gpio_mask(irq_to_gpio(irq)); + + if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING) + __raw_writel(mask, &g->set_falling); + if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING) + __raw_writel(mask, &g->set_rising); +} + +static int gpio_irq_type(unsigned irq, unsigned trigger) +{ + struct gpio_controller *__iomem g = get_irq_chip_data(irq); + u32 mask = __gpio_mask(irq_to_gpio(irq)); + + if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) + return -EINVAL; + + irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; + irq_desc[irq].status |= trigger; + + __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING) + ? &g->set_falling : &g->clr_falling); + __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING) + ? &g->set_rising : &g->clr_rising); + return 0; +} + +static struct irq_chip gpio_irqchip = { + .name = "GPIO", + .enable = gpio_irq_enable, + .disable = gpio_irq_disable, + .set_type = gpio_irq_type, +}; + +static void +gpio_irq_handler(unsigned irq, struct irq_desc *desc) +{ + struct gpio_controller *__iomem g = get_irq_chip_data(irq); + u32 mask = 0xffff; + + /* we only care about one bank */ + if (irq & 1) + mask <<= 16; + + /* temporarily mask (level sensitive) parent IRQ */ + desc->chip->ack(irq); + while (1) { + u32 status; + struct irq_desc *gpio; + int n; + int res; + + /* ack any irqs */ + status = __raw_readl(&g->intstat) & mask; + if (!status) + break; + __raw_writel(status, &g->intstat); + if (irq & 1) + status >>= 16; + + /* now demux them to the right lowlevel handler */ + n = (int)get_irq_data(irq); + gpio = &irq_desc[n]; + while (status) { + res = ffs(status); + n += res; + gpio += res; + desc_handle_irq(n - 1, gpio - 1); + status >>= res; + } + } + desc->chip->unmask(irq); + /* now it may re-trigger */ +} + +/* + * NOTE: for suspend/resume, probably best to make a sysdev (and class) + * with its suspend/resume calls hooking into the results of the set_wake() + * calls ... so if no gpios are wakeup events the clock can be disabled, + * with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0 + * can be set appropriately for GPIOV33 pins. + */ + +static int __init davinci_gpio_irq_setup(void) +{ + unsigned gpio, irq, bank; + struct clk *clk; + + clk = clk_get(NULL, "gpio"); + if (IS_ERR(clk)) { + printk(KERN_ERR "Error %ld getting gpio clock?\n", + PTR_ERR(clk)); + return 0; + } + + clk_enable(clk); + + for (gpio = 0, irq = gpio_to_irq(0), bank = IRQ_GPIOBNK0; + gpio < DAVINCI_N_GPIO; bank++) { + struct gpio_controller *__iomem g = gpio2controller(gpio); + unsigned i; + + __raw_writel(~0, &g->clr_falling); + __raw_writel(~0, &g->clr_rising); + + /* set up all irqs in this bank */ + set_irq_chained_handler(bank, gpio_irq_handler); + set_irq_chip_data(bank, g); + set_irq_data(bank, (void *)irq); + + for (i = 0; i < 16 && gpio < DAVINCI_N_GPIO; + i++, irq++, gpio++) { + set_irq_chip(irq, &gpio_irqchip); + set_irq_chip_data(irq, g); + set_irq_handler(irq, handle_simple_irq); + set_irq_flags(irq, IRQF_VALID); + } + } + + /* BINTEN -- per-bank interrupt enable. genirq would also let these + * bits be set/cleared dynamically. + */ + __raw_writel(0x1f, (void *__iomem) + IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08)); + + printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0)); + + return 0; +} + +arch_initcall(davinci_gpio_irq_setup); diff --git a/include/asm-arm/arch-davinci/gpio.h b/include/asm-arm/arch-davinci/gpio.h new file mode 100644 index 0000000..ea24a0e --- /dev/null +++ b/include/asm-arm/arch-davinci/gpio.h @@ -0,0 +1,156 @@ +/* + * TI DaVinci GPIO Support + * + * Copyright (c) 2006 David Brownell + * 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. + */ + +#ifndef __DAVINCI_GPIO_H +#define __DAVINCI_GPIO_H + +/* + * basic gpio routines + * + * board-specific init should be done by arch/.../.../board-XXX.c (maybe + * initializing banks together) rather than boot loaders; kexec() won't + * go through boot loaders. + * + * the gpio clock will be turned on when gpios are used, and you may also + * need to pay attention to PINMUX0 and PINMUX1 to be sure those pins are + * used as gpios, not with other peripherals. + * + * GPIOs are numbered 0..(DAVINCI_N_GPIO-1). For documentation, and maybe + * for later updates, code should write GPIO(N) or: + * - GPIOV18(N) for 1.8V pins, N in 0..53; same as GPIO(0)..GPIO(53) + * - GPIOV33(N) for 3.3V pins, N in 0..17; same as GPIO(54)..GPIO(70) + * + * For GPIO IRQs use gpio_to_irq(GPIO(N)) or gpio_to_irq(GPIOV33(N)) etc + * for now, that's != GPIO(N) + */ +#define GPIO(X) (X) /* 0 <= X <= 70 */ +#define GPIOV18(X) (X) /* 1.8V i/o; 0 <= X <= 53 */ +#define GPIOV33(X) ((X)+54) /* 3.3V i/o; 0 <= X <= 17 */ + +struct gpio_controller { + u32 dir; + u32 out_data; + u32 set_data; + u32 clr_data; + u32 in_data; + u32 set_rising; + u32 clr_rising; + u32 set_falling; + u32 clr_falling; + u32 intstat; +}; + +/* The __gpio_to_controller() and __gpio_mask() functions inline to constants + * with constant parameters; or in outlined code they execute at runtime. + * + * You'd access the controller directly when reading or writing more than + * one gpio value at a time, and to support wired logic where the value + * being driven by the cpu need not match the value read back. + * + * These are NOT part of the cross-platform GPIO interface + */ +static inline struct gpio_controller *__iomem +__gpio_to_controller(unsigned gpio) +{ + void *__iomem ptr; + + if (gpio < 32) + ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10); + else if (gpio < 64) + ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38); + else if (gpio < DAVINCI_N_GPIO) + ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60); + else + ptr = NULL; + return ptr; +} + +static inline u32 __gpio_mask(unsigned gpio) +{ + return 1 << (gpio % 32); +} + +/* The get/set/clear functions will inline when called with constant + * parameters, for low-overhead bitbanging. Illegal constant parameters + * cause link-time errors. + * + * Otherwise, calls with variable parameters use outlined functions. + */ +extern int __error_inval_gpio(void); + +extern void __gpio_set(unsigned gpio, int value); +extern int __gpio_get(unsigned gpio); + +static inline void gpio_set_value(unsigned gpio, int value) +{ + if (__builtin_constant_p(value)) { + struct gpio_controller *__iomem g; + u32 mask; + + if (gpio >= DAVINCI_N_GPIO) + __error_inval_gpio(); + + g = __gpio_to_controller(gpio); + mask = __gpio_mask(gpio); + if (value) + __raw_writel(mask, &g->set_data); + else + __raw_writel(mask, &g->clr_data); + return; + } + + __gpio_set(gpio, value); +} + +/* Returns zero or nonzero; works for gpios configured as inputs OR + * as outputs. + * + * NOTE: changes in reported values are synchronized to the GPIO clock. + * This is most easily seen after calling gpio_set_value() and then immediatly + * gpio_get_value(), where the gpio_get_value() would return the old value + * until the GPIO clock ticks and the new value gets latched. + */ + +static inline int gpio_get_value(unsigned gpio) +{ + struct gpio_controller *__iomem g; + + if (!__builtin_constant_p(gpio)) + return __gpio_get(gpio); + + if (gpio >= DAVINCI_N_GPIO) + return __error_inval_gpio(); + + g = __gpio_to_controller(gpio); + return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data)); +} + +/* powerup default direction is IN */ +extern int gpio_direction_input(unsigned gpio); +extern int gpio_direction_output(unsigned gpio, int value); + +#include /* cansleep wrappers */ + +extern int gpio_request(unsigned gpio, const char *tag); +extern void gpio_free(unsigned gpio); + +static inline int gpio_to_irq(unsigned gpio) +{ + return DAVINCI_N_AINTC_IRQ + gpio; +} + +static inline int irq_to_gpio(unsigned irq) +{ + return irq - DAVINCI_N_AINTC_IRQ; +} + +#endif /* __DAVINCI_GPIO_H */ diff --git a/include/asm-arm/arch-davinci/hardware.h b/include/asm-arm/arch-davinci/hardware.h index 60362d8..a2e8969 100644 --- a/include/asm-arm/arch-davinci/hardware.h +++ b/include/asm-arm/arch-davinci/hardware.h @@ -11,4 +11,42 @@ #ifndef __ASM_ARCH_HARDWARE_H #define __ASM_ARCH_HARDWARE_H +/* + * Base register addresses + */ +#define DAVINCI_DMA_3PCC_BASE (0x01C00000) +#define DAVINCI_DMA_3PTC0_BASE (0x01C10000) +#define DAVINCI_DMA_3PTC1_BASE (0x01C10400) +#define DAVINCI_I2C_BASE (0x01C21000) +#define DAVINCI_PWM0_BASE (0x01C22000) +#define DAVINCI_PWM1_BASE (0x01C22400) +#define DAVINCI_PWM2_BASE (0x01C22800) +#define DAVINCI_SYSTEM_MODULE_BASE (0x01C40000) +#define DAVINCI_PLL_CNTRL0_BASE (0x01C40800) +#define DAVINCI_PLL_CNTRL1_BASE (0x01C40C00) +#define DAVINCI_PWR_SLEEP_CNTRL_BASE (0x01C41000) +#define DAVINCI_SYSTEM_DFT_BASE (0x01C42000) +#define DAVINCI_IEEE1394_BASE (0x01C60000) +#define DAVINCI_USB_OTG_BASE (0x01C64000) +#define DAVINCI_CFC_ATA_BASE (0x01C66000) +#define DAVINCI_SPI_BASE (0x01C66800) +#define DAVINCI_GPIO_BASE (0x01C67000) +#define DAVINCI_UHPI_BASE (0x01C67800) +#define DAVINCI_VPSS_REGS_BASE (0x01C70000) +#define DAVINCI_EMAC_CNTRL_REGS_BASE (0x01C80000) +#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE (0x01C81000) +#define DAVINCI_EMAC_WRAPPER_RAM_BASE (0x01C82000) +#define DAVINCI_MDIO_CNTRL_REGS_BASE (0x01C84000) +#define DAVINCI_IMCOP_BASE (0x01CC0000) +#define DAVINCI_ASYNC_EMIF_CNTRL_BASE (0x01E00000) +#define DAVINCI_VLYNQ_BASE (0x01E01000) +#define DAVINCI_MCBSP_BASE (0x01E02000) +#define DAVINCI_MMC_SD_BASE (0x01E10000) +#define DAVINCI_MS_BASE (0x01E20000) +#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE (0x02000000) +#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE (0x04000000) +#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE (0x06000000) +#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE (0x08000000) +#define DAVINCI_VLYNQ_REMOTE_BASE (0x0C000000) + #endif /* __ASM_ARCH_HARDWARE_H */ -- cgit v0.10.2 From 83f53220f8313f097cdf181928be13bafbb697ea Mon Sep 17 00:00:00 2001 From: Vladimir Barinov Date: Tue, 10 Jul 2007 13:10:04 +0100 Subject: [ARM] 4432/5: davinci: pin mux support Support pin multiplexing configurations driver for TI DaVinci SoC Signed-off-by: Vladimir Barinov Acked-by: Kevin Hilman Signed-off-by: Russell King diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 731c0a6..99ac2e5 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 + gpio.o mux.o # Board specific obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c new file mode 100644 index 0000000..92d26bd --- /dev/null +++ b/arch/arm/mach-davinci/mux.c @@ -0,0 +1,41 @@ +/* + * DaVinci pin multiplexing configurations + * + * Author: Vladimir Barinov, 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. + */ +#include +#include + +#include + +#include + +/* System control register offsets */ +#define PINMUX0 0x00 +#define PINMUX1 0x04 + +static DEFINE_SPINLOCK(mux_lock); + +void davinci_mux_peripheral(unsigned int mux, unsigned int enable) +{ + u32 pinmux, muxreg = PINMUX0; + + if (mux >= DAVINCI_MUX_LEVEL2) { + muxreg = PINMUX1; + mux -= DAVINCI_MUX_LEVEL2; + } + + spin_lock(&mux_lock); + pinmux = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + muxreg); + if (enable) + pinmux |= (1 << mux); + else + pinmux &= ~(1 << mux); + davinci_writel(pinmux, DAVINCI_SYSTEM_MODULE_BASE + muxreg); + spin_unlock(&mux_lock); +} diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c index e1b0050..1334416 100644 --- a/arch/arm/mach-davinci/psc.c +++ b/arch/arm/mach-davinci/psc.c @@ -25,39 +25,40 @@ #include #include #include +#include -#define PTCMD __REG(0x01C41120) -#define PDSTAT __REG(0x01C41200) -#define PDCTL1 __REG(0x01C41304) -#define EPCPR __REG(0x01C41070) -#define PTSTAT __REG(0x01C41128) +/* PSC register offsets */ +#define EPCPR 0x070 +#define PTCMD 0x120 +#define PTSTAT 0x128 +#define PDSTAT 0x200 +#define PDCTL1 0x304 +#define MDSTAT 0x800 +#define MDCTL 0xA00 -#define MDSTAT IO_ADDRESS(0x01C41800) -#define MDCTL IO_ADDRESS(0x01C41A00) - -#define PINMUX0 __REG(0x01c40000) -#define PINMUX1 __REG(0x01c40004) -#define VDD3P3V_PWDN __REG(0x01C40048) +/* System control register offsets */ +#define VDD3P3V_PWDN 0x48 static void davinci_psc_mux(unsigned int id) { switch (id) { case DAVINCI_LPSC_ATA: - PINMUX0 |= (1 << 17) | (1 << 16); + davinci_mux_peripheral(DAVINCI_MUX_HDIREN, 1); + davinci_mux_peripheral(DAVINCI_MUX_ATAEN, 1); break; case DAVINCI_LPSC_MMC_SD: /* VDD power manupulations are done in U-Boot for CPMAC * so applies to MMC as well */ /*Set up the pull regiter for MMC */ - VDD3P3V_PWDN = 0x0; - PINMUX1 &= (~(1 << 9)); + davinci_writel(0, DAVINCI_SYSTEM_MODULE_BASE + VDD3P3V_PWDN); + davinci_mux_peripheral(DAVINCI_MUX_MSTK, 0); break; case DAVINCI_LPSC_I2C: - PINMUX1 |= (1 << 7); + davinci_mux_peripheral(DAVINCI_MUX_I2C, 1); break; case DAVINCI_LPSC_McBSP: - PINMUX1 |= (1 << 10); + davinci_mux_peripheral(DAVINCI_MUX_ASP, 1); break; default: break; @@ -67,33 +68,59 @@ static void davinci_psc_mux(unsigned int id) /* Enable or disable a PSC domain */ void davinci_psc_config(unsigned int domain, unsigned int id, char enable) { - volatile unsigned int *mdstat = (unsigned int *)((int)MDSTAT + 4 * id); - volatile unsigned int *mdctl = (unsigned int *)((int)MDCTL + 4 * id); + u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl, mdstat_mask; if (id < 0) return; + mdctl = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id); if (enable) - *mdctl |= 0x00000003; /* Enable Module */ + mdctl |= 0x00000003; /* Enable Module */ else - *mdctl &= 0xFFFFFFF2; /* Disable Module */ + mdctl &= 0xFFFFFFF2; /* Disable Module */ + davinci_writel(mdctl, DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id); + + pdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDSTAT); + if ((pdstat & 0x00000001) == 0) { + pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1); + pdctl1 |= 0x1; + davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1); + + ptcmd = 1 << domain; + davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD); - if ((PDSTAT & 0x00000001) == 0) { - PDCTL1 |= 0x1; - PTCMD = (1 << domain); - while ((((EPCPR >> domain) & 1) == 0)); + do { + epcpr = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + + EPCPR); + } while ((((epcpr >> domain) & 1) == 0)); - PDCTL1 |= 0x100; - while (!(((PTSTAT >> domain) & 1) == 0)); + pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1); + pdctl1 |= 0x100; + davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1); + + do { + ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + + PTSTAT); + } while (!(((ptstat >> domain) & 1) == 0)); } else { - PTCMD = (1 << domain); - while (!(((PTSTAT >> domain) & 1) == 0)); + ptcmd = 1 << domain; + davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD); + + do { + ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + + PTSTAT); + } while (!(((ptstat >> domain) & 1) == 0)); } if (enable) - while (!((*mdstat & 0x0000001F) == 0x3)); + mdstat_mask = 0x3; else - while (!((*mdstat & 0x0000001F) == 0x2)); + mdstat_mask = 0x2; + + do { + mdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + + MDSTAT + 4 * id); + } while (!((mdstat & 0x0000001F) == mdstat_mask)); if (enable) davinci_psc_mux(id); diff --git a/include/asm-arm/arch-davinci/mux.h b/include/asm-arm/arch-davinci/mux.h new file mode 100644 index 0000000..c24b678 --- /dev/null +++ b/include/asm-arm/arch-davinci/mux.h @@ -0,0 +1,55 @@ +/* + * DaVinci pin multiplexing defines + * + * Author: Vladimir Barinov, 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 __ASM_ARCH_MUX_H +#define __ASM_ARCH_MUX_H + +#define DAVINCI_MUX_AEAW0 0 +#define DAVINCI_MUX_AEAW1 1 +#define DAVINCI_MUX_AEAW2 2 +#define DAVINCI_MUX_AEAW3 3 +#define DAVINCI_MUX_AEAW4 4 +#define DAVINCI_MUX_AECS4 10 +#define DAVINCI_MUX_AECS5 11 +#define DAVINCI_MUX_VLYNQWD0 12 +#define DAVINCI_MUX_VLYNQWD1 13 +#define DAVINCI_MUX_VLSCREN 14 +#define DAVINCI_MUX_VLYNQEN 15 +#define DAVINCI_MUX_HDIREN 16 +#define DAVINCI_MUX_ATAEN 17 +#define DAVINCI_MUX_RGB666 22 +#define DAVINCI_MUX_RGB888 23 +#define DAVINCI_MUX_LOEEN 24 +#define DAVINCI_MUX_LFLDEN 25 +#define DAVINCI_MUX_CWEN 26 +#define DAVINCI_MUX_CFLDEN 27 +#define DAVINCI_MUX_HPIEN 29 +#define DAVINCI_MUX_1394EN 30 +#define DAVINCI_MUX_EMACEN 31 + +#define DAVINCI_MUX_LEVEL2 32 +#define DAVINCI_MUX_UART0 (DAVINCI_MUX_LEVEL2 + 0) +#define DAVINCI_MUX_UART1 (DAVINCI_MUX_LEVEL2 + 1) +#define DAVINCI_MUX_UART2 (DAVINCI_MUX_LEVEL2 + 2) +#define DAVINCI_MUX_U2FLO (DAVINCI_MUX_LEVEL2 + 3) +#define DAVINCI_MUX_PWM0 (DAVINCI_MUX_LEVEL2 + 4) +#define DAVINCI_MUX_PWM1 (DAVINCI_MUX_LEVEL2 + 5) +#define DAVINCI_MUX_PWM2 (DAVINCI_MUX_LEVEL2 + 6) +#define DAVINCI_MUX_I2C (DAVINCI_MUX_LEVEL2 + 7) +#define DAVINCI_MUX_SPI (DAVINCI_MUX_LEVEL2 + 8) +#define DAVINCI_MUX_MSTK (DAVINCI_MUX_LEVEL2 + 9) +#define DAVINCI_MUX_ASP (DAVINCI_MUX_LEVEL2 + 10) +#define DAVINCI_MUX_CLK0 (DAVINCI_MUX_LEVEL2 + 16) +#define DAVINCI_MUX_CLK1 (DAVINCI_MUX_LEVEL2 + 17) +#define DAVINCI_MUX_TIMIN (DAVINCI_MUX_LEVEL2 + 18) + +extern void davinci_mux_peripheral(unsigned int mux, unsigned int enable); + +#endif /* __ASM_ARCH_MUX_H */ -- cgit v0.10.2 From eac1d8dab03bde6d20679c961a6409c1b786c201 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 11 Jul 2007 10:14:53 +0100 Subject: [ARM] 4466/1: ANUBIS: Anubis AX88796 support This patch adds the resources necessary for the AX88796 driver to attach to the AX88796 network controller fitted on the Simtec Anubis board. Signed-off-by: Ben Dooks Signed-off-by: Russell King diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c index bff7ddd..64456f9 100644 --- a/arch/arm/mach-s3c2440/mach-anubis.c +++ b/arch/arm/mach-s3c2440/mach-anubis.c @@ -42,6 +42,8 @@ #include #include +#include + #include #include #include @@ -260,6 +262,38 @@ static struct platform_device anubis_device_ide1 = { .resource = anubis_ide1_resource, }; +/* Asix AX88796 10/100 ethernet controller */ + +static struct ax_plat_data anubis_asix_platdata = { + .flags = AXFLG_MAC_FROMDEV, + .wordlength = 2, + .dcr_val = 0x48, + .rcr_val = 0x40, +}; + +static struct resource anubis_asix_resource[] = { + [0] = { + .start = S3C2410_CS5, + .end = S3C2410_CS5 + (0x20 * 0x20) -1, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = IRQ_ASIX, + .end = IRQ_ASIX, + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device anubis_device_asix = { + .name = "ax88796", + .id = 0, + .num_resources = ARRAY_SIZE(anubis_asix_resource), + .resource = anubis_asix_resource, + .dev = { + .platform_data = &anubis_asix_platdata, + } +}; + /* Standard Anubis devices */ static struct platform_device *anubis_devices[] __initdata = { @@ -271,6 +305,7 @@ static struct platform_device *anubis_devices[] __initdata = { &s3c_device_nand, &anubis_device_ide0, &anubis_device_ide1, + &anubis_device_asix, }; static struct clk *anubis_clocks[] = { -- cgit v0.10.2 From 8a9ccb7f182d15d6d6d0debb819790f25c87a30b Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 12 Jul 2007 10:47:35 +0100 Subject: [ARM] 4468/2: ANUBIS: Add SM501 device resources Add resources for the SM501 present on the Simtec Anubis board, including the framebuffer and the I2C for DDC. Signed-off-by: Ben Dooks Signed-off-by: Russell King diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c index 64456f9..53675aa 100644 --- a/arch/arm/mach-s3c2440/mach-anubis.c +++ b/arch/arm/mach-s3c2440/mach-anubis.c @@ -18,6 +18,9 @@ #include #include +#include +#include + #include #include #include @@ -294,6 +297,72 @@ static struct platform_device anubis_device_asix = { } }; +/* SM501 */ + +static struct resource anubis_sm501_resource[] = { + [0] = { + .start = S3C2410_CS2, + .end = S3C2410_CS2 + SZ_8M, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = S3C2410_CS2 + SZ_64M - SZ_2M, + .end = S3C2410_CS2 + SZ_64M - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_EINT0, + .end = IRQ_EINT0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sm501_initdata anubis_sm501_initdata = { + .gpio_high = { + .set = 0x3F000000, /* 24bit panel */ + .mask = 0x0, + }, + .misc_timing = { + .set = 0x010100, /* SDRAM timing */ + .mask = 0x1F1F00, + }, + .misc_control = { + .set = SM501_MISC_PNL_24BIT, + .mask = 0, + }, + + /* set the SDRAM and bus clocks */ + .mclk = 72 * MHZ, + .m1xclk = 144 * MHZ, +}; + +static struct sm501_platdata_gpio_i2c anubis_sm501_gpio_i2c[] = { + [0] = { + .pin_scl = 44, + .pin_sda = 45, + }, + [1] = { + .pin_scl = 40, + .pin_sda = 41, + }, +}; + +static struct sm501_platdata anubis_sm501_platdata = { + .init = &anubis_sm501_initdata, + .gpio_i2c = anubis_sm501_gpio_i2c, + .gpio_i2c_nr = ARRAY_SIZE(anubis_sm501_gpio_i2c), +}; + +static struct platform_device anubis_device_sm501 = { + .name = "sm501", + .id = 0, + .num_resources = ARRAY_SIZE(anubis_sm501_resource), + .resource = anubis_sm501_resource, + .dev = { + .platform_data = &anubis_sm501_platdata, + }, +}; + /* Standard Anubis devices */ static struct platform_device *anubis_devices[] __initdata = { @@ -306,6 +375,7 @@ static struct platform_device *anubis_devices[] __initdata = { &anubis_device_ide0, &anubis_device_ide1, &anubis_device_asix, + &anubis_device_sm501, }; static struct clk *anubis_clocks[] = { -- cgit v0.10.2 From ad3613f4798e229c8885b924c88e17ab85fef96a Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 11 Jul 2007 11:10:42 +0100 Subject: [ARM] 4469/1: ANUBIS: large page NAND support Add support for the partition layour used on the revision B modules which ship with large page NAND flash as default. The differnce between the old and new layouts is that the large page devices use 128KiB blocks, so the initial loader partition now ends at 128KiB boundary pushing the begining of partition 1 up. The rest of the partitions are in the same place as the small page NAND devices. Signed-off-by: Ben Dooks Signed-off-by: Russell King diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c index 53675aa..29c163d 100644 --- a/arch/arm/mach-s3c2440/mach-anubis.c +++ b/arch/arm/mach-s3c2440/mach-anubis.c @@ -158,6 +158,29 @@ static struct mtd_partition anubis_default_nand_part[] = { } }; +static struct mtd_partition anubis_default_nand_part_large[] = { + [0] = { + .name = "Boot Agent", + .size = SZ_128K, + .offset = 0, + }, + [1] = { + .name = "/boot", + .size = SZ_4M - SZ_128K, + .offset = SZ_128K, + }, + [2] = { + .name = "user1", + .offset = SZ_4M, + .size = SZ_32M - SZ_4M, + }, + [3] = { + .name = "user2", + .offset = SZ_32M, + .size = MTDPART_SIZ_FULL, + } +}; + /* the Anubis has 3 selectable slots for nand-flash, the two * on-board chip areas, as well as the external slot. * @@ -409,8 +432,17 @@ static void __init anubis_map_io(void) s3c24xx_init_clocks(0); s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs)); - /* ensure that the GPIO is setup */ - s3c2410_gpio_setpin(S3C2410_GPA0, 1); + /* check for the newer revision boards with large page nand */ + + if ((__raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK) >= 4) { + printk(KERN_INFO "ANUBIS-B detected (revision %d)\n", + __raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK); + anubis_nand_sets[0].partitions = anubis_default_nand_part_large; + anubis_nand_sets[0].nr_partitions = ARRAY_SIZE(anubis_default_nand_part_large); + } else { + /* ensure that the GPIO is setup */ + s3c2410_gpio_setpin(S3C2410_GPA0, 1); + } } static void __init anubis_init(void) -- cgit v0.10.2 From 5ce4b1fe6c6a126f9274f19d8b2d2c8d29cd49b6 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 12 Jul 2007 10:44:53 +0100 Subject: [ARM] 4467/3: BAST: AX88796 device resources Add resources for the AX88796 on the Simtec BAST. Signed-off-by: Ben Dooks Signed-off-by: Russell King diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index f01de80..8b52ea9 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -20,6 +20,8 @@ #include #include +#include + #include #include #include @@ -409,6 +411,61 @@ static struct s3c2410_platform_i2c bast_i2c_info = { .max_freq = 130*1000, }; +/* Asix AX88796 10/100 ethernet controller */ + +static struct ax_plat_data bast_asix_platdata = { + .flags = AXFLG_MAC_FROMDEV, + .wordlength = 2, + .dcr_val = 0x48, + .rcr_val = 0x40, +}; + +static struct resource bast_asix_resource[] = { + [0] = { + .start = S3C2410_CS5 + BAST_PA_ASIXNET, + .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20) - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20), + .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20), + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_ASIX, + .end = IRQ_ASIX, + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device bast_device_asix = { + .name = "ax88796", + .id = 0, + .num_resources = ARRAY_SIZE(bast_asix_resource), + .resource = bast_asix_resource, + .dev = { + .platform_data = &bast_asix_platdata + } +}; + +/* Asix AX88796 10/100 ethernet controller parallel port */ + +static struct resource bast_asixpp_resource[] = { + [0] = { + .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20), + .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1b * 0x20) - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device bast_device_axpp = { + .name = "ax88796-pp", + .id = 0, + .num_resources = ARRAY_SIZE(bast_asixpp_resource), + .resource = bast_asixpp_resource, +}; + +/* LCD/VGA controller */ static struct s3c2410fb_mach_info __initdata bast_lcd_info = { .width = 640, @@ -453,6 +510,8 @@ static struct platform_device *bast_devices[] __initdata = { &s3c_device_nand, &bast_device_nor, &bast_device_dm9k, + &bast_device_asix, + &bast_device_axpp, &bast_sio, }; -- cgit v0.10.2 From 3c3e69cd4c667e6ce7939d83b274d48c57779479 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 12 Jul 2007 10:57:37 +0100 Subject: [ARM] 4470/2: OSIRIS: large page NAND support Add support for the partition layout on the revision B modules which have large page NAND fitted. The new partition table accounts for the use of the 128KiB block parts, which means the second partition on the device is moved to the new boundary. Signed-off-by: Ben Dooks Signed-off-by: Russell King diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c index 1581160..89f4c9c 100644 --- a/arch/arm/mach-s3c2440/mach-osiris.c +++ b/arch/arm/mach-s3c2440/mach-osiris.c @@ -166,6 +166,29 @@ static struct mtd_partition osiris_default_nand_part[] = { } }; +static struct mtd_partition osiris_default_nand_part_large[] = { + [0] = { + .name = "Boot Agent", + .size = SZ_128K, + .offset = 0, + }, + [1] = { + .name = "/boot", + .size = SZ_4M - SZ_128K, + .offset = SZ_128K, + }, + [2] = { + .name = "user1", + .offset = SZ_4M, + .size = SZ_32M - SZ_4M, + }, + [3] = { + .name = "user2", + .offset = SZ_32M, + .size = MTDPART_SIZ_FULL, + } +}; + /* the Osiris has 3 selectable slots for nand-flash, the two * on-board chip areas, as well as the external slot. * @@ -322,14 +345,23 @@ static void __init osiris_map_io(void) s3c24xx_init_clocks(0); s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs)); + /* check for the newer revision boards with large page nand */ + + if ((__raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK) >= 4) { + printk(KERN_INFO "OSIRIS-B detected (revision %d)\n", + __raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK); + osiris_nand_sets[0].partitions = osiris_default_nand_part_large; + osiris_nand_sets[0].nr_partitions = ARRAY_SIZE(osiris_default_nand_part_large); + } else { + /* write-protect line to the NAND */ + s3c2410_gpio_setpin(S3C2410_GPA0, 1); + } + /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */ local_irq_save(flags); __raw_writel(__raw_readl(S3C2410_BWSCON) | S3C2410_BWSCON_ST1 | S3C2410_BWSCON_ST2 | S3C2410_BWSCON_ST3 | S3C2410_BWSCON_ST4 | S3C2410_BWSCON_ST5, S3C2410_BWSCON); local_irq_restore(flags); - - /* write-protect line to the NAND */ - s3c2410_gpio_setpin(S3C2410_GPA0, 1); } static void __init osiris_init(void) -- cgit v0.10.2 From cdf95c73694e464cf9877cb5aa51df77f42815bc Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Mon, 14 May 2007 15:08:21 +0100 Subject: [ARM] 4379/1: AT91: LCD support on SAM9261-EK and SAM9263-EK boards Add board-specific setup for the LCD on the Atmel AT91SAM9261-EK and AT91SAM9263-EK boards. Signed-off-by: Nicolas Ferre Signed-off-by: Andrew Victor Signed-off-by: Russell King diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index 26ca8ab3..579b41f 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -27,6 +27,9 @@ #include #include #include +#include + +#include