diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-12-19 22:46:52 +0300 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-12-19 22:46:52 +0300 |
commit | 828aac2ee239dca9c1856c4856a57912e6a487c4 (patch) | |
tree | 44de8a7d318bbcef29da00992ebfa7356f470af7 /arch/arm/mach-netx | |
parent | 6fd7c7fe72a46dfd227fe8db0c7b6863af90a982 (diff) | |
parent | 7971db5a4b4176ad5df590fce07a962c643a2740 (diff) | |
download | linux-828aac2ee239dca9c1856c4856a57912e6a487c4.tar.xz |
Merge branch 'for-rmk' of git://git.pengutronix.de/git/ukl/linux-2.6 into devel
Diffstat (limited to 'arch/arm/mach-netx')
-rw-r--r-- | arch/arm/mach-netx/include/mach/netx-regs.h | 22 | ||||
-rw-r--r-- | arch/arm/mach-netx/time.c | 98 | ||||
-rw-r--r-- | arch/arm/mach-netx/xc.c | 6 |
3 files changed, 109 insertions, 17 deletions
diff --git a/arch/arm/mach-netx/include/mach/netx-regs.h b/arch/arm/mach-netx/include/mach/netx-regs.h index 5104a00d40f4..08c60ff227be 100644 --- a/arch/arm/mach-netx/include/mach/netx-regs.h +++ b/arch/arm/mach-netx/include/mach/netx-regs.h @@ -328,6 +328,28 @@ #define NETX_PFIFO_FILL_LEVEL(pfifo) NETX_PFIFO_REG(0x180 + ((pfifo)<<2)) #define NETX_PFIFO_XPEC_ISR(xpec) NETX_PFIFO_REG(0x400 + ((xpec) << 2)) + +/******************************* + * Memory Controller * + *******************************/ + +/* Registers */ +#define NETX_MEMCR_REG(ofs) __io(NETX_VA_MEMCR + (ofs)) +#define NETX_MEMCR_SRAM_CTRL(cs) NETX_MEMCR_REG(0x0 + 4 * (cs)) /* SRAM for CS 0..2 */ +#define NETX_MEMCR_SDRAM_CFG_CTRL NETX_MEMCR_REG(0x40) +#define NETX_MEMCR_SDRAM_TIMING_CTRL NETX_MEMCR_REG(0x44) +#define NETX_MEMCR_SDRAM_MODE NETX_MEMCR_REG(0x48) +#define NETX_MEMCR_SDRAM_EXT_MODE NETX_MEMCR_REG(0x4c) +#define NETX_MEMCR_PRIO_TIMESLOT_CTRL NETX_MEMCR_REG(0x80) +#define NETX_MEMCR_PRIO_ACCESS_CTRL NETX_MEMCR_REG(0x84) + +/* Bits */ +#define NETX_MEMCR_SRAM_CTRL_WIDTHEXTMEM(x) (((x) & 0x3) << 24) +#define NETX_MEMCR_SRAM_CTRL_WSPOSTPAUSEEXTMEM(x) (((x) & 0x3) << 16) +#define NETX_MEMCR_SRAM_CTRL_WSPREPASEEXTMEM(x) (((x) & 0x3) << 8) +#define NETX_MEMCR_SRAM_CTRL_WSEXTMEM(x) (((x) & 0x1f) << 0) + + /******************************* * Dual Port Memory * *******************************/ diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c index 7c540c1f01fa..d51d627ce7cf 100644 --- a/arch/arm/mach-netx/time.c +++ b/arch/arm/mach-netx/time.c @@ -21,43 +21,100 @@ #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/clocksource.h> +#include <linux/clockchips.h> #include <linux/io.h> #include <mach/hardware.h> #include <asm/mach/time.h> #include <mach/netx-regs.h> +#define TIMER_CLOCKEVENT 0 +#define TIMER_CLOCKSOURCE 1 + +static void netx_set_mode(enum clock_event_mode mode, + struct clock_event_device *clk) +{ + u32 tmode; + + /* disable timer */ + writel(0, NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKEVENT)); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + writel(LATCH, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKEVENT)); + tmode = NETX_GPIO_COUNTER_CTRL_RST_EN | + NETX_GPIO_COUNTER_CTRL_IRQ_EN | + NETX_GPIO_COUNTER_CTRL_RUN; + break; + + case CLOCK_EVT_MODE_ONESHOT: + writel(0, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKEVENT)); + tmode = NETX_GPIO_COUNTER_CTRL_IRQ_EN | + NETX_GPIO_COUNTER_CTRL_RUN; + break; + + default: + WARN(1, "%s: unhandled mode %d\n", __func__, mode); + /* fall through */ + + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_RESUME: + tmode = 0; + break; + } + + writel(tmode, NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKEVENT)); +} + +static int netx_set_next_event(unsigned long evt, + struct clock_event_device *clk) +{ + writel(0 - evt, NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKEVENT)); + return 0; +} + +static struct clock_event_device netx_clockevent = { + .name = "netx-timer" __stringify(TIMER_CLOCKEVENT), + .shift = 32, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_next_event = netx_set_next_event, + .set_mode = netx_set_mode, +}; + /* * IRQ handler for the timer */ static irqreturn_t netx_timer_interrupt(int irq, void *dev_id) { - timer_tick(); + struct clock_event_device *evt = &netx_clockevent; /* acknowledge interrupt */ writel(COUNTER_BIT(0), NETX_GPIO_IRQ); + evt->event_handler(evt); + return IRQ_HANDLED; } static struct irqaction netx_timer_irq = { - .name = "NetX Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = netx_timer_interrupt, + .name = "NetX Timer Tick", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = netx_timer_interrupt, }; cycle_t netx_get_cycles(void) { - return readl(NETX_GPIO_COUNTER_CURRENT(1)); + return readl(NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE)); } static struct clocksource clocksource_netx = { - .name = "netx_timer", + .name = "netx_timer", .rating = 200, .read = netx_get_cycles, .mask = CLOCKSOURCE_MASK(32), - .shift = 20, + .shift = 20, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -77,24 +134,37 @@ static void __init netx_timer_init(void) /* acknowledge interrupt */ writel(COUNTER_BIT(0), NETX_GPIO_IRQ); - /* Enable the interrupt in the specific timer register and start timer */ + /* Enable the interrupt in the specific timer + * register and start timer + */ writel(COUNTER_BIT(0), NETX_GPIO_IRQ_ENABLE); writel(NETX_GPIO_COUNTER_CTRL_IRQ_EN | NETX_GPIO_COUNTER_CTRL_RUN, - NETX_GPIO_COUNTER_CTRL(0)); + NETX_GPIO_COUNTER_CTRL(0)); setup_irq(NETX_IRQ_TIMER0, &netx_timer_irq); /* Setup timer one for clocksource */ - writel(0, NETX_GPIO_COUNTER_CTRL(1)); - writel(0, NETX_GPIO_COUNTER_CURRENT(1)); - writel(0xFFFFFFFF, NETX_GPIO_COUNTER_MAX(1)); + writel(0, NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE)); + writel(0, NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE)); + writel(0xffffffff, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKSOURCE)); - writel(NETX_GPIO_COUNTER_CTRL_RUN, - NETX_GPIO_COUNTER_CTRL(1)); + writel(NETX_GPIO_COUNTER_CTRL_RUN, + NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE)); clocksource_netx.mult = clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_netx.shift); clocksource_register(&clocksource_netx); + + netx_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, + netx_clockevent.shift); + netx_clockevent.max_delta_ns = + clockevent_delta2ns(0xfffffffe, &netx_clockevent); + /* with max_delta_ns >= delta2ns(0x800) the system currently runs fine. + * Adding some safety ... */ + netx_clockevent.min_delta_ns = + clockevent_delta2ns(0xa00, &netx_clockevent); + netx_clockevent.cpumask = cpumask_of_cpu(0); + clockevents_register_device(&netx_clockevent); } struct sys_timer netx_timer = { diff --git a/arch/arm/mach-netx/xc.c b/arch/arm/mach-netx/xc.c index 32eabf5dfa4f..8fc6205dc3a5 100644 --- a/arch/arm/mach-netx/xc.c +++ b/arch/arm/mach-netx/xc.c @@ -92,10 +92,10 @@ static int xc_check_ptr(struct xc *x, unsigned long adr, unsigned int size) return -1; } -static int xc_patch(struct xc *x, void *patch, int count) +static int xc_patch(struct xc *x, const void *patch, int count) { unsigned int val, adr; - unsigned int *data = patch; + const unsigned int *data = patch; int i; for (i = 0; i < count; i++) { @@ -117,7 +117,7 @@ int xc_request_firmware(struct xc *x) struct fw_header *head; unsigned int size; int i; - void *src; + const void *src; unsigned long dst; sprintf(name, "xc%d.bin", x->no); |