aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze
diff options
context:
space:
mode:
authorMichal Simek <michal.simek@xilinx.com>2014-02-24 09:04:03 -0500
committerMichal Simek <michal.simek@xilinx.com>2014-04-07 05:58:33 -0400
commita1715bb7ff2e09f580a1f2f7f0c34e832f54a5fe (patch)
treeb5eced148966ea80d8166f422a0fb5813c714f56 /arch/microblaze
parent1aa1243c339d4c902c0f9c1ced45742729a86e6a (diff)
microblaze: Make timer driver endian aware
Detect endianess directly on the hardware and use ioread/iowrite functions. Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Diffstat (limited to 'arch/microblaze')
-rw-r--r--arch/microblaze/kernel/timer.c62
1 files changed, 47 insertions, 15 deletions
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index 717a3d90e1b8..dd96f0e4bfa2 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -43,10 +43,33 @@ static unsigned int timer_clock_freq;
43#define TCSR_PWMA (1<<9) 43#define TCSR_PWMA (1<<9)
44#define TCSR_ENALL (1<<10) 44#define TCSR_ENALL (1<<10)
45 45
46static unsigned int (*read_fn)(void __iomem *);
47static void (*write_fn)(u32, void __iomem *);
48
49static void timer_write32(u32 val, void __iomem *addr)
50{
51 iowrite32(val, addr);
52}
53
54static unsigned int timer_read32(void __iomem *addr)
55{
56 return ioread32(addr);
57}
58
59static void timer_write32_be(u32 val, void __iomem *addr)
60{
61 iowrite32be(val, addr);
62}
63
64static unsigned int timer_read32_be(void __iomem *addr)
65{
66 return ioread32be(addr);
67}
68
46static inline void xilinx_timer0_stop(void) 69static inline void xilinx_timer0_stop(void)
47{ 70{
48 out_be32(timer_baseaddr + TCSR0, 71 write_fn(read_fn(timer_baseaddr + TCSR0) & ~TCSR_ENT,
49 in_be32(timer_baseaddr + TCSR0) & ~TCSR_ENT); 72 timer_baseaddr + TCSR0);
50} 73}
51 74
52static inline void xilinx_timer0_start_periodic(unsigned long load_val) 75static inline void xilinx_timer0_start_periodic(unsigned long load_val)
@@ -54,10 +77,10 @@ static inline void xilinx_timer0_start_periodic(unsigned long load_val)
54 if (!load_val) 77 if (!load_val)
55 load_val = 1; 78 load_val = 1;
56 /* loading value to timer reg */ 79 /* loading value to timer reg */
57 out_be32(timer_baseaddr + TLR0, load_val); 80 write_fn(load_val, timer_baseaddr + TLR0);
58 81
59 /* load the initial value */ 82 /* load the initial value */
60 out_be32(timer_baseaddr + TCSR0, TCSR_LOAD); 83 write_fn(TCSR_LOAD, timer_baseaddr + TCSR0);
61 84
62 /* see timer data sheet for detail 85 /* see timer data sheet for detail
63 * !ENALL - don't enable 'em all 86 * !ENALL - don't enable 'em all
@@ -72,8 +95,8 @@ static inline void xilinx_timer0_start_periodic(unsigned long load_val)
72 * UDT - set the timer as down counter 95 * UDT - set the timer as down counter
73 * !MDT0 - generate mode 96 * !MDT0 - generate mode
74 */ 97 */
75 out_be32(timer_baseaddr + TCSR0, 98 write_fn(TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT,
76 TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT); 99 timer_baseaddr + TCSR0);
77} 100}
78 101
79static inline void xilinx_timer0_start_oneshot(unsigned long load_val) 102static inline void xilinx_timer0_start_oneshot(unsigned long load_val)
@@ -81,13 +104,13 @@ static inline void xilinx_timer0_start_oneshot(unsigned long load_val)
81 if (!load_val) 104 if (!load_val)
82 load_val = 1; 105 load_val = 1;
83 /* loading value to timer reg */ 106 /* loading value to timer reg */
84 out_be32(timer_baseaddr + TLR0, load_val); 107 write_fn(load_val, timer_baseaddr + TLR0);
85 108
86 /* load the initial value */ 109 /* load the initial value */
87 out_be32(timer_baseaddr + TCSR0, TCSR_LOAD); 110 write_fn(TCSR_LOAD, timer_baseaddr + TCSR0);
88 111
89 out_be32(timer_baseaddr + TCSR0, 112 write_fn(TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT,
90 TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT); 113 timer_baseaddr + TCSR0);
91} 114}
92 115
93static int xilinx_timer_set_next_event(unsigned long delta, 116static int xilinx_timer_set_next_event(unsigned long delta,
@@ -133,7 +156,7 @@ static struct clock_event_device clockevent_xilinx_timer = {
133 156
134static inline void timer_ack(void) 157static inline void timer_ack(void)
135{ 158{
136 out_be32(timer_baseaddr + TCSR0, in_be32(timer_baseaddr + TCSR0)); 159 write_fn(read_fn(timer_baseaddr + TCSR0), timer_baseaddr + TCSR0);
137} 160}
138 161
139static irqreturn_t timer_interrupt(int irq, void *dev_id) 162static irqreturn_t timer_interrupt(int irq, void *dev_id)
@@ -169,7 +192,7 @@ static __init void xilinx_clockevent_init(void)
169 192
170static u64 xilinx_clock_read(void) 193static u64 xilinx_clock_read(void)
171{ 194{
172 return in_be32(timer_baseaddr + TCR1); 195 return read_fn(timer_baseaddr + TCR1);
173} 196}
174 197
175static cycle_t xilinx_read(struct clocksource *cs) 198static cycle_t xilinx_read(struct clocksource *cs)
@@ -217,10 +240,10 @@ static int __init xilinx_clocksource_init(void)
217 panic("failed to register clocksource"); 240 panic("failed to register clocksource");
218 241
219 /* stop timer1 */ 242 /* stop timer1 */
220 out_be32(timer_baseaddr + TCSR1, 243 write_fn(read_fn(timer_baseaddr + TCSR1) & ~TCSR_ENT,
221 in_be32(timer_baseaddr + TCSR1) & ~TCSR_ENT); 244 timer_baseaddr + TCSR1);
222 /* start timer1 - up counting without interrupt */ 245 /* start timer1 - up counting without interrupt */
223 out_be32(timer_baseaddr + TCSR1, TCSR_TINT|TCSR_ENT|TCSR_ARHT); 246 write_fn(TCSR_TINT|TCSR_ENT|TCSR_ARHT, timer_baseaddr + TCSR1);
224 247
225 /* register timecounter - for ftrace support */ 248 /* register timecounter - for ftrace support */
226 init_xilinx_timecounter(); 249 init_xilinx_timecounter();
@@ -245,6 +268,15 @@ static void __init xilinx_timer_init(struct device_node *timer)
245 BUG(); 268 BUG();
246 } 269 }
247 270
271 write_fn = timer_write32;
272 read_fn = timer_read32;
273
274 write_fn(TCSR_MDT, timer_baseaddr + TCSR0);
275 if (!(read_fn(timer_baseaddr + TCSR0) & TCSR_MDT)) {
276 write_fn = timer_write32_be;
277 read_fn = timer_read32_be;
278 }
279
248 irq = irq_of_parse_and_map(timer, 0); 280 irq = irq_of_parse_and_map(timer, 0);
249 281
250 of_property_read_u32(timer, "xlnx,one-timer-only", &timer_num); 282 of_property_read_u32(timer, "xlnx,one-timer-only", &timer_num);