aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/mach-netx/include/mach/netx-regs.h22
-rw-r--r--arch/arm/mach-netx/time.c98
-rw-r--r--arch/arm/mach-netx/xc.c6
4 files changed, 111 insertions, 17 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 65f423cc610c..fb2877526d58 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -286,6 +286,8 @@ config ARCH_FOOTBRIDGE
286config ARCH_NETX 286config ARCH_NETX
287 bool "Hilscher NetX based" 287 bool "Hilscher NetX based"
288 select ARM_VIC 288 select ARM_VIC
289 select GENERIC_CLOCKEVENTS
290 select GENERIC_TIME
289 help 291 help
290 This enables support for systems based on the Hilscher NetX Soc 292 This enables support for systems based on the Hilscher NetX Soc
291 293
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 @@
328#define NETX_PFIFO_FILL_LEVEL(pfifo) NETX_PFIFO_REG(0x180 + ((pfifo)<<2)) 328#define NETX_PFIFO_FILL_LEVEL(pfifo) NETX_PFIFO_REG(0x180 + ((pfifo)<<2))
329#define NETX_PFIFO_XPEC_ISR(xpec) NETX_PFIFO_REG(0x400 + ((xpec) << 2)) 329#define NETX_PFIFO_XPEC_ISR(xpec) NETX_PFIFO_REG(0x400 + ((xpec) << 2))
330 330
331
332/*******************************
333 * Memory Controller *
334 *******************************/
335
336/* Registers */
337#define NETX_MEMCR_REG(ofs) __io(NETX_VA_MEMCR + (ofs))
338#define NETX_MEMCR_SRAM_CTRL(cs) NETX_MEMCR_REG(0x0 + 4 * (cs)) /* SRAM for CS 0..2 */
339#define NETX_MEMCR_SDRAM_CFG_CTRL NETX_MEMCR_REG(0x40)
340#define NETX_MEMCR_SDRAM_TIMING_CTRL NETX_MEMCR_REG(0x44)
341#define NETX_MEMCR_SDRAM_MODE NETX_MEMCR_REG(0x48)
342#define NETX_MEMCR_SDRAM_EXT_MODE NETX_MEMCR_REG(0x4c)
343#define NETX_MEMCR_PRIO_TIMESLOT_CTRL NETX_MEMCR_REG(0x80)
344#define NETX_MEMCR_PRIO_ACCESS_CTRL NETX_MEMCR_REG(0x84)
345
346/* Bits */
347#define NETX_MEMCR_SRAM_CTRL_WIDTHEXTMEM(x) (((x) & 0x3) << 24)
348#define NETX_MEMCR_SRAM_CTRL_WSPOSTPAUSEEXTMEM(x) (((x) & 0x3) << 16)
349#define NETX_MEMCR_SRAM_CTRL_WSPREPASEEXTMEM(x) (((x) & 0x3) << 8)
350#define NETX_MEMCR_SRAM_CTRL_WSEXTMEM(x) (((x) & 0x1f) << 0)
351
352
331/******************************* 353/*******************************
332 * Dual Port Memory * 354 * Dual Port Memory *
333 *******************************/ 355 *******************************/
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 @@
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/clocksource.h> 23#include <linux/clocksource.h>
24#include <linux/clockchips.h>
24#include <linux/io.h> 25#include <linux/io.h>
25 26
26#include <mach/hardware.h> 27#include <mach/hardware.h>
27#include <asm/mach/time.h> 28#include <asm/mach/time.h>
28#include <mach/netx-regs.h> 29#include <mach/netx-regs.h>
29 30
31#define TIMER_CLOCKEVENT 0
32#define TIMER_CLOCKSOURCE 1
33
34static void netx_set_mode(enum clock_event_mode mode,
35 struct clock_event_device *clk)
36{
37 u32 tmode;
38
39 /* disable timer */
40 writel(0, NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKEVENT));
41
42 switch (mode) {
43 case CLOCK_EVT_MODE_PERIODIC:
44 writel(LATCH, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKEVENT));
45 tmode = NETX_GPIO_COUNTER_CTRL_RST_EN |
46 NETX_GPIO_COUNTER_CTRL_IRQ_EN |
47 NETX_GPIO_COUNTER_CTRL_RUN;
48 break;
49
50 case CLOCK_EVT_MODE_ONESHOT:
51 writel(0, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKEVENT));
52 tmode = NETX_GPIO_COUNTER_CTRL_IRQ_EN |
53 NETX_GPIO_COUNTER_CTRL_RUN;
54 break;
55
56 default:
57 WARN(1, "%s: unhandled mode %d\n", __func__, mode);
58 /* fall through */
59
60 case CLOCK_EVT_MODE_SHUTDOWN:
61 case CLOCK_EVT_MODE_UNUSED:
62 case CLOCK_EVT_MODE_RESUME:
63 tmode = 0;
64 break;
65 }
66
67 writel(tmode, NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKEVENT));
68}
69
70static int netx_set_next_event(unsigned long evt,
71 struct clock_event_device *clk)
72{
73 writel(0 - evt, NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKEVENT));
74 return 0;
75}
76
77static struct clock_event_device netx_clockevent = {
78 .name = "netx-timer" __stringify(TIMER_CLOCKEVENT),
79 .shift = 32,
80 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
81 .set_next_event = netx_set_next_event,
82 .set_mode = netx_set_mode,
83};
84
30/* 85/*
31 * IRQ handler for the timer 86 * IRQ handler for the timer
32 */ 87 */
33static irqreturn_t 88static irqreturn_t
34netx_timer_interrupt(int irq, void *dev_id) 89netx_timer_interrupt(int irq, void *dev_id)
35{ 90{
36 timer_tick(); 91 struct clock_event_device *evt = &netx_clockevent;
37 92
38 /* acknowledge interrupt */ 93 /* acknowledge interrupt */
39 writel(COUNTER_BIT(0), NETX_GPIO_IRQ); 94 writel(COUNTER_BIT(0), NETX_GPIO_IRQ);
40 95
96 evt->event_handler(evt);
97
41 return IRQ_HANDLED; 98 return IRQ_HANDLED;
42} 99}
43 100
44static struct irqaction netx_timer_irq = { 101static struct irqaction netx_timer_irq = {
45 .name = "NetX Timer Tick", 102 .name = "NetX Timer Tick",
46 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 103 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
47 .handler = netx_timer_interrupt, 104 .handler = netx_timer_interrupt,
48}; 105};
49 106
50cycle_t netx_get_cycles(void) 107cycle_t netx_get_cycles(void)
51{ 108{
52 return readl(NETX_GPIO_COUNTER_CURRENT(1)); 109 return readl(NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE));
53} 110}
54 111
55static struct clocksource clocksource_netx = { 112static struct clocksource clocksource_netx = {
56 .name = "netx_timer", 113 .name = "netx_timer",
57 .rating = 200, 114 .rating = 200,
58 .read = netx_get_cycles, 115 .read = netx_get_cycles,
59 .mask = CLOCKSOURCE_MASK(32), 116 .mask = CLOCKSOURCE_MASK(32),
60 .shift = 20, 117 .shift = 20,
61 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 118 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
62}; 119};
63 120
@@ -77,24 +134,37 @@ static void __init netx_timer_init(void)
77 /* acknowledge interrupt */ 134 /* acknowledge interrupt */
78 writel(COUNTER_BIT(0), NETX_GPIO_IRQ); 135 writel(COUNTER_BIT(0), NETX_GPIO_IRQ);
79 136
80 /* Enable the interrupt in the specific timer register and start timer */ 137 /* Enable the interrupt in the specific timer
138 * register and start timer
139 */
81 writel(COUNTER_BIT(0), NETX_GPIO_IRQ_ENABLE); 140 writel(COUNTER_BIT(0), NETX_GPIO_IRQ_ENABLE);
82 writel(NETX_GPIO_COUNTER_CTRL_IRQ_EN | NETX_GPIO_COUNTER_CTRL_RUN, 141 writel(NETX_GPIO_COUNTER_CTRL_IRQ_EN | NETX_GPIO_COUNTER_CTRL_RUN,
83 NETX_GPIO_COUNTER_CTRL(0)); 142 NETX_GPIO_COUNTER_CTRL(0));
84 143
85 setup_irq(NETX_IRQ_TIMER0, &netx_timer_irq); 144 setup_irq(NETX_IRQ_TIMER0, &netx_timer_irq);
86 145
87 /* Setup timer one for clocksource */ 146 /* Setup timer one for clocksource */
88 writel(0, NETX_GPIO_COUNTER_CTRL(1)); 147 writel(0, NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE));
89 writel(0, NETX_GPIO_COUNTER_CURRENT(1)); 148 writel(0, NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE));
90 writel(0xFFFFFFFF, NETX_GPIO_COUNTER_MAX(1)); 149 writel(0xffffffff, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKSOURCE));
91 150
92 writel(NETX_GPIO_COUNTER_CTRL_RUN, 151 writel(NETX_GPIO_COUNTER_CTRL_RUN,
93 NETX_GPIO_COUNTER_CTRL(1)); 152 NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE));
94 153
95 clocksource_netx.mult = 154 clocksource_netx.mult =
96 clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_netx.shift); 155 clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_netx.shift);
97 clocksource_register(&clocksource_netx); 156 clocksource_register(&clocksource_netx);
157
158 netx_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
159 netx_clockevent.shift);
160 netx_clockevent.max_delta_ns =
161 clockevent_delta2ns(0xfffffffe, &netx_clockevent);
162 /* with max_delta_ns >= delta2ns(0x800) the system currently runs fine.
163 * Adding some safety ... */
164 netx_clockevent.min_delta_ns =
165 clockevent_delta2ns(0xa00, &netx_clockevent);
166 netx_clockevent.cpumask = cpumask_of_cpu(0);
167 clockevents_register_device(&netx_clockevent);
98} 168}
99 169
100struct sys_timer netx_timer = { 170struct 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)
92 return -1; 92 return -1;
93} 93}
94 94
95static int xc_patch(struct xc *x, void *patch, int count) 95static int xc_patch(struct xc *x, const void *patch, int count)
96{ 96{
97 unsigned int val, adr; 97 unsigned int val, adr;
98 unsigned int *data = patch; 98 const unsigned int *data = patch;
99 99
100 int i; 100 int i;
101 for (i = 0; i < count; i++) { 101 for (i = 0; i < count; i++) {
@@ -117,7 +117,7 @@ int xc_request_firmware(struct xc *x)
117 struct fw_header *head; 117 struct fw_header *head;
118 unsigned int size; 118 unsigned int size;
119 int i; 119 int i;
120 void *src; 120 const void *src;
121 unsigned long dst; 121 unsigned long dst;
122 122
123 sprintf(name, "xc%d.bin", x->no); 123 sprintf(name, "xc%d.bin", x->no);