Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
core.c
Go to the documentation of this file.
1 /*
2  * Copyright 1999 - 2003 ARM Limited
3  * Copyright 2000 Deep Blue Solutions Ltd
4  * Copyright 2008 Cavium Networks
5  *
6  * This file is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License, Version 2, as
8  * published by the Free Software Foundation.
9  */
10 
11 #include <linux/init.h>
12 #include <linux/interrupt.h>
13 #include <linux/clockchips.h>
14 #include <linux/io.h>
15 #include <asm/mach/map.h>
16 #include <asm/mach/time.h>
17 #include <asm/mach/irq.h>
18 #include <asm/hardware/gic.h>
20 #include <mach/cns3xxx.h>
21 #include "core.h"
22 
23 static struct map_desc cns3xxx_io_desc[] __initdata = {
24  {
27  .length = SZ_4K,
28  .type = MT_DEVICE,
29  }, {
32  .length = SZ_4K,
33  .type = MT_DEVICE,
34  }, {
37  .length = SZ_4K,
38  .type = MT_DEVICE,
39  }, {
42  .length = SZ_4K,
43  .type = MT_DEVICE,
44  }, {
45  .virtual = CNS3XXX_GPIOA_BASE_VIRT,
47  .length = SZ_4K,
48  .type = MT_DEVICE,
49  }, {
50  .virtual = CNS3XXX_GPIOB_BASE_VIRT,
52  .length = SZ_4K,
53  .type = MT_DEVICE,
54  }, {
55  .virtual = CNS3XXX_MISC_BASE_VIRT,
57  .length = SZ_4K,
58  .type = MT_DEVICE,
59  }, {
60  .virtual = CNS3XXX_PM_BASE_VIRT,
62  .length = SZ_4K,
63  .type = MT_DEVICE,
64  },
65 };
66 
68 {
69  iotable_init(cns3xxx_io_desc, ARRAY_SIZE(cns3xxx_io_desc));
70 }
71 
72 /* used by entry-macro.S */
74 {
77 }
78 
80 {
82  u32 clkctrl;
83 
84  printk(KERN_INFO "powering system down...\n");
85 
86  clkctrl = readl(pm_base + PM_SYS_CLK_CTRL_OFFSET);
87  clkctrl &= 0xfffff1ff;
88  clkctrl |= (0x5 << 9); /* Hibernate */
89  writel(clkctrl, pm_base + PM_SYS_CLK_CTRL_OFFSET);
90 
91 }
92 
93 /*
94  * Timer
95  */
96 static void __iomem *cns3xxx_tmr1;
97 
98 static void cns3xxx_timer_set_mode(enum clock_event_mode mode,
99  struct clock_event_device *clk)
100 {
101  unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
102  int pclk = cns3xxx_cpu_clock() / 8;
103  int reload;
104 
105  switch (mode) {
106  case CLOCK_EVT_MODE_PERIODIC:
107  reload = pclk * 20 / (3 * HZ) * 0x25000;
108  writel(reload, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
109  ctrl |= (1 << 0) | (1 << 2) | (1 << 9);
110  break;
111  case CLOCK_EVT_MODE_ONESHOT:
112  /* period set, and timer enabled in 'next_event' hook */
113  ctrl |= (1 << 2) | (1 << 9);
114  break;
115  case CLOCK_EVT_MODE_UNUSED:
116  case CLOCK_EVT_MODE_SHUTDOWN:
117  default:
118  ctrl = 0;
119  }
120 
121  writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
122 }
123 
124 static int cns3xxx_timer_set_next_event(unsigned long evt,
125  struct clock_event_device *unused)
126 {
127  unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
128 
129  writel(evt, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
130  writel(ctrl | (1 << 0), cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
131 
132  return 0;
133 }
134 
135 static struct clock_event_device cns3xxx_tmr1_clockevent = {
136  .name = "cns3xxx timer1",
137  .shift = 8,
138  .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
139  .set_mode = cns3xxx_timer_set_mode,
140  .set_next_event = cns3xxx_timer_set_next_event,
141  .rating = 350,
142  .cpumask = cpu_all_mask,
143 };
144 
145 static void __init cns3xxx_clockevents_init(unsigned int timer_irq)
146 {
147  cns3xxx_tmr1_clockevent.irq = timer_irq;
148  cns3xxx_tmr1_clockevent.mult =
149  div_sc((cns3xxx_cpu_clock() >> 3) * 1000000, NSEC_PER_SEC,
150  cns3xxx_tmr1_clockevent.shift);
151  cns3xxx_tmr1_clockevent.max_delta_ns =
152  clockevent_delta2ns(0xffffffff, &cns3xxx_tmr1_clockevent);
153  cns3xxx_tmr1_clockevent.min_delta_ns =
154  clockevent_delta2ns(0xf, &cns3xxx_tmr1_clockevent);
155 
156  clockevents_register_device(&cns3xxx_tmr1_clockevent);
157 }
158 
159 /*
160  * IRQ handler for the timer
161  */
162 static irqreturn_t cns3xxx_timer_interrupt(int irq, void *dev_id)
163 {
164  struct clock_event_device *evt = &cns3xxx_tmr1_clockevent;
166  u32 val;
167 
168  /* Clear the interrupt */
169  val = readl(stat);
170  writel(val & ~(1 << 2), stat);
171 
172  evt->event_handler(evt);
173 
174  return IRQ_HANDLED;
175 }
176 
177 static struct irqaction cns3xxx_timer_irq = {
178  .name = "timer",
180  .handler = cns3xxx_timer_interrupt,
181 };
182 
183 /*
184  * Set up the clock source and clock events devices
185  */
186 static void __init __cns3xxx_timer_init(unsigned int timer_irq)
187 {
188  u32 val;
189  u32 irq_mask;
190 
191  /*
192  * Initialise to a known state (all timers off)
193  */
194 
195  /* disable timer1 and timer2 */
196  writel(0, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
197  /* stop free running timer3 */
198  writel(0, cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
199 
200  /* timer1 */
201  writel(0x5C800, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET);
202  writel(0x5C800, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
203 
204  writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V1_OFFSET);
205  writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V2_OFFSET);
206 
207  /* mask irq, non-mask timer1 overflow */
208  irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
209  irq_mask &= ~(1 << 2);
210  irq_mask |= 0x03;
211  writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
212 
213  /* down counter */
214  val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
215  val |= (1 << 9);
216  writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
217 
218  /* timer2 */
219  writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V1_OFFSET);
220  writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V2_OFFSET);
221 
222  /* mask irq */
223  irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
224  irq_mask |= ((1 << 3) | (1 << 4) | (1 << 5));
225  writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
226 
227  /* down counter */
228  val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
229  val |= (1 << 10);
230  writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
231 
232  /* Make irqs happen for the system timer */
233  setup_irq(timer_irq, &cns3xxx_timer_irq);
234 
235  cns3xxx_clockevents_init(timer_irq);
236 }
237 
238 static void __init cns3xxx_timer_init(void)
239 {
240  cns3xxx_tmr1 = IOMEM(CNS3XXX_TIMER1_2_3_BASE_VIRT);
241 
242  __cns3xxx_timer_init(IRQ_CNS3XXX_TIMER0);
243 }
244 
246  .init = cns3xxx_timer_init,
247 };
248 
249 #ifdef CONFIG_CACHE_L2X0
250 
251 void __init cns3xxx_l2x0_init(void)
252 {
254  u32 val;
255 
256  if (WARN_ON(!base))
257  return;
258 
259  /*
260  * Tag RAM Control register
261  *
262  * bit[10:8] - 1 cycle of write accesses latency
263  * bit[6:4] - 1 cycle of read accesses latency
264  * bit[3:0] - 1 cycle of setup latency
265  *
266  * 1 cycle of latency for setup, read and write accesses
267  */
268  val = readl(base + L2X0_TAG_LATENCY_CTRL);
269  val &= 0xfffff888;
270  writel(val, base + L2X0_TAG_LATENCY_CTRL);
271 
272  /*
273  * Data RAM Control register
274  *
275  * bit[10:8] - 1 cycles of write accesses latency
276  * bit[6:4] - 1 cycles of read accesses latency
277  * bit[3:0] - 1 cycle of setup latency
278  *
279  * 1 cycle of latency for setup, read and write accesses
280  */
281  val = readl(base + L2X0_DATA_LATENCY_CTRL);
282  val &= 0xfffff888;
283  writel(val, base + L2X0_DATA_LATENCY_CTRL);
284 
285  /* 32 KiB, 8-way, parity disable */
286  l2x0_init(base, 0x00540000, 0xfe000fff);
287 }
288 
289 #endif /* CONFIG_CACHE_L2X0 */