Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
spear13xx.c
Go to the documentation of this file.
1 /*
2  * arch/arm/mach-spear13xx/spear13xx.c
3  *
4  * SPEAr13XX machines common source file
5  *
6  * Copyright (C) 2012 ST Microelectronics
7  * Viresh Kumar <[email protected]>
8  *
9  * This file is licensed under the terms of the GNU General Public
10  * License version 2. This program is licensed "as is" without any
11  * warranty of any kind, whether express or implied.
12  */
13 
14 #define pr_fmt(fmt) "SPEAr13xx: " fmt
15 
16 #include <linux/amba/pl022.h>
17 #include <linux/clk.h>
18 #include <linux/dw_dmac.h>
19 #include <linux/err.h>
20 #include <linux/of_irq.h>
22 #include <asm/hardware/gic.h>
23 #include <asm/mach/map.h>
24 #include <asm/smp_twd.h>
25 #include <mach/dma.h>
26 #include <mach/generic.h>
27 #include <mach/spear.h>
28 
29 /* common dw_dma filter routine to be used by peripherals */
30 bool dw_dma_filter(struct dma_chan *chan, void *slave)
31 {
32  struct dw_dma_slave *dws = (struct dw_dma_slave *)slave;
33 
34  if (chan->device->dev == dws->dma_dev) {
35  chan->private = slave;
36  return true;
37  } else {
38  return false;
39  }
40 }
41 
42 /* ssp device registration */
43 static struct dw_dma_slave ssp_dma_param[] = {
44  {
45  /* Tx */
47  .cfg_lo = 0,
48  .src_master = DMA_MASTER_MEMORY,
49  .dst_master = DMA_MASTER_SSP0,
50  }, {
51  /* Rx */
53  .cfg_lo = 0,
54  .src_master = DMA_MASTER_SSP0,
55  .dst_master = DMA_MASTER_MEMORY,
56  }
57 };
58 
60  .bus_id = 0,
61  .enable_dma = 1,
62  .dma_filter = dw_dma_filter,
63  .dma_rx_param = &ssp_dma_param[1],
64  .dma_tx_param = &ssp_dma_param[0],
65  .num_chipselect = 3,
66 };
67 
68 /* CF device registration */
70  .cfg_hi = 0,
71  .cfg_lo = 0,
72  .src_master = 0,
73  .dst_master = 0,
74 };
75 
76 /* dmac device registeration */
78  .nr_channels = 8,
79  .chan_allocation_order = CHAN_ALLOCATION_DESCENDING,
80  .chan_priority = CHAN_PRIORITY_DESCENDING,
81  .block_size = 4095U,
82  .nr_masters = 2,
83  .data_width = { 3, 3, 0, 0 },
84 };
85 
87 {
88  /*
89  * 512KB (64KB/way), 8-way associativity, parity supported
90  *
91  * FIXME: 9th bit, of Auxillary Controller register must be set
92  * for some spear13xx devices for stable L2 operation.
93  *
94  * Enable Early BRESP, L2 prefetch for Instruction and Data,
95  * write alloc and 'Full line of zero' options
96  *
97  */
98 
99  writel_relaxed(0x06, VA_L2CC_BASE + L2X0_PREFETCH_CTRL);
100 
101  /*
102  * Program following latencies in order to make
103  * SPEAr1340 work at 600 MHz
104  */
105  writel_relaxed(0x221, VA_L2CC_BASE + L2X0_TAG_LATENCY_CTRL);
106  writel_relaxed(0x441, VA_L2CC_BASE + L2X0_DATA_LATENCY_CTRL);
107  l2x0_init(VA_L2CC_BASE, 0x70A60001, 0xfe00ffff);
108 }
109 
110 /*
111  * Following will create 16MB static virtual/physical mappings
112  * PHYSICAL VIRTUAL
113  * 0xB3000000 0xFE000000
114  * 0xE0000000 0xFD000000
115  * 0xEC000000 0xFC000000
116  * 0xED000000 0xFB000000
117  */
118 struct map_desc spear13xx_io_desc[] __initdata = {
119  {
120  .virtual = (unsigned long)VA_PERIP_GRP2_BASE,
122  .length = SZ_16M,
123  .type = MT_DEVICE
124  }, {
125  .virtual = (unsigned long)VA_PERIP_GRP1_BASE,
127  .length = SZ_16M,
128  .type = MT_DEVICE
129  }, {
130  .virtual = (unsigned long)VA_A9SM_AND_MPMC_BASE,
132  .length = SZ_16M,
133  .type = MT_DEVICE
134  }, {
135  .virtual = (unsigned long)VA_L2CC_BASE,
137  .length = SZ_4K,
138  .type = MT_DEVICE
139  },
140 };
141 
142 /* This will create static memory mapping for selected devices */
144 {
145  iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
146 }
147 
148 static void __init spear13xx_clk_init(void)
149 {
150  if (of_machine_is_compatible("st,spear1310"))
152  else if (of_machine_is_compatible("st,spear1340"))
154  else
155  pr_err("%s: Unknown machine\n", __func__);
156 }
157 
158 static void __init spear13xx_timer_init(void)
159 {
160  char pclk_name[] = "osc_24m_clk";
161  struct clk *gpt_clk, *pclk;
162 
163  spear13xx_clk_init();
164 
165  /* get the system timer clock */
166  gpt_clk = clk_get_sys("gpt0", NULL);
167  if (IS_ERR(gpt_clk)) {
168  pr_err("%s:couldn't get clk for gpt\n", __func__);
169  BUG();
170  }
171 
172  /* get the suitable parent clock for timer*/
173  pclk = clk_get(NULL, pclk_name);
174  if (IS_ERR(pclk)) {
175  pr_err("%s:couldn't get %s as parent for gpt\n", __func__,
176  pclk_name);
177  BUG();
178  }
179 
180  clk_set_parent(gpt_clk, pclk);
181  clk_put(gpt_clk);
182  clk_put(pclk);
183 
185  twd_local_timer_of_register();
186 }
187 
189  .init = spear13xx_timer_init,
190 };
191 
192 static const struct of_device_id gic_of_match[] __initconst = {
193  { .compatible = "arm,cortex-a9-gic", .data = gic_of_init },
194  { /* Sentinel */ }
195 };
196 
198 {
199  of_irq_init(gic_of_match);
200 }