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  * linux/arch/arm/mach-realview/core.c
3  *
4  * Copyright (C) 1999 - 2003 ARM Limited
5  * Copyright (C) 2000 Deep Blue Solutions Ltd
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 #include <linux/init.h>
22 #include <linux/platform_device.h>
23 #include <linux/dma-mapping.h>
24 #include <linux/device.h>
25 #include <linux/interrupt.h>
26 #include <linux/amba/bus.h>
27 #include <linux/amba/clcd.h>
28 #include <linux/io.h>
29 #include <linux/smsc911x.h>
30 #include <linux/ata_platform.h>
31 #include <linux/amba/mmci.h>
32 #include <linux/gfp.h>
33 #include <linux/mtd/physmap.h>
34 
35 #include <mach/hardware.h>
36 #include <asm/irq.h>
37 #include <asm/mach-types.h>
38 #include <asm/hardware/arm_timer.h>
39 #include <asm/hardware/icst.h>
40 
41 #include <asm/mach/arch.h>
42 #include <asm/mach/irq.h>
43 #include <asm/mach/map.h>
44 
45 #include <asm/hardware/gic.h>
46 
47 #include <mach/platform.h>
48 #include <mach/irqs.h>
49 #include <asm/hardware/timer-sp.h>
50 
51 #include <plat/clcd.h>
52 #include <plat/sched_clock.h>
53 
54 #include "core.h"
55 
56 #define REALVIEW_FLASHCTRL (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET)
57 
58 static void realview_flash_set_vpp(struct platform_device *pdev, int on)
59 {
60  u32 val;
61 
63  if (on)
65  else
68 }
69 
70 static struct physmap_flash_data realview_flash_data = {
71  .width = 4,
72  .set_vpp = realview_flash_set_vpp,
73 };
74 
76  .name = "physmap-flash",
77  .id = 0,
78  .dev = {
79  .platform_data = &realview_flash_data,
80  },
81 };
82 
84 {
85  realview_flash_device.resource = res;
86  realview_flash_device.num_resources = num;
87  return platform_device_register(&realview_flash_device);
88 }
89 
90 static struct smsc911x_platform_config smsc911x_config = {
91  .flags = SMSC911X_USE_32BIT,
92  .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
93  .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
94  .phy_interface = PHY_INTERFACE_MODE_MII,
95 };
96 
97 static struct platform_device realview_eth_device = {
98  .name = "smsc911x",
99  .id = 0,
100  .num_resources = 2,
101 };
102 
103 int realview_eth_register(const char *name, struct resource *res)
104 {
105  if (name)
106  realview_eth_device.name = name;
107  realview_eth_device.resource = res;
108  if (strcmp(realview_eth_device.name, "smsc911x") == 0)
109  realview_eth_device.dev.platform_data = &smsc911x_config;
110 
111  return platform_device_register(&realview_eth_device);
112 }
113 
115  .name = "isp1760",
116  .num_resources = 2,
117 };
118 
120 {
121  realview_usb_device.resource = res;
122  return platform_device_register(&realview_usb_device);
123 }
124 
125 static struct pata_platform_info pata_platform_data = {
126  .ioport_shift = 1,
127 };
128 
129 static struct resource pata_resources[] = {
130  [0] = {
131  .start = REALVIEW_CF_BASE,
132  .end = REALVIEW_CF_BASE + 0xff,
133  .flags = IORESOURCE_MEM,
134  },
135  [1] = {
136  .start = REALVIEW_CF_BASE + 0x100,
137  .end = REALVIEW_CF_BASE + SZ_4K - 1,
138  .flags = IORESOURCE_MEM,
139  },
140 };
141 
143  .name = "pata_platform",
144  .id = -1,
145  .num_resources = ARRAY_SIZE(pata_resources),
146  .resource = pata_resources,
147  .dev = {
148  .platform_data = &pata_platform_data,
149  },
150 };
151 
152 static struct resource realview_i2c_resource = {
153  .start = REALVIEW_I2C_BASE,
154  .end = REALVIEW_I2C_BASE + SZ_4K - 1,
155  .flags = IORESOURCE_MEM,
156 };
157 
159  .name = "versatile-i2c",
160  .id = 0,
161  .num_resources = 1,
162  .resource = &realview_i2c_resource,
163 };
164 
165 static struct i2c_board_info realview_i2c_board_info[] = {
166  {
167  I2C_BOARD_INFO("ds1338", 0xd0 >> 1),
168  },
169 };
170 
171 static int __init realview_i2c_init(void)
172 {
173  return i2c_register_board_info(0, realview_i2c_board_info,
174  ARRAY_SIZE(realview_i2c_board_info));
175 }
176 arch_initcall(realview_i2c_init);
177 
178 #define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
179 
180 /*
181  * This is only used if GPIOLIB support is disabled
182  */
183 static unsigned int realview_mmc_status(struct device *dev)
184 {
185  struct amba_device *adev = container_of(dev, struct amba_device, dev);
186  u32 mask;
187 
188  if (machine_is_realview_pb1176()) {
189  static bool inserted = false;
190 
191  /*
192  * The PB1176 does not have the status register,
193  * assume it is inserted at startup, then invert
194  * for each call so card insertion/removal will
195  * be detected anyway. This will not be called if
196  * GPIO on PL061 is active, which is the proper
197  * way to do this on the PB1176.
198  */
199  inserted = !inserted;
200  return inserted ? 0 : 1;
201  }
202 
203  if (adev->res.start == REALVIEW_MMCI0_BASE)
204  mask = 1;
205  else
206  mask = 2;
207 
208  return readl(REALVIEW_SYSMCI) & mask;
209 }
210 
212  .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
213  .status = realview_mmc_status,
214  .gpio_wp = 17,
215  .gpio_cd = 16,
216  .cd_invert = true,
217 };
218 
220  .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
221  .status = realview_mmc_status,
222  .gpio_wp = 19,
223  .gpio_cd = 18,
224  .cd_invert = true,
225 };
226 
228 {
230 
232 }
233 
234 /*
235  * CLCD support.
236  */
237 #define SYS_CLCD_NLCDIOON (1 << 2)
238 #define SYS_CLCD_VDDPOSSWITCH (1 << 3)
239 #define SYS_CLCD_PWR3V5SWITCH (1 << 4)
240 #define SYS_CLCD_ID_MASK (0x1f << 8)
241 #define SYS_CLCD_ID_SANYO_3_8 (0x00 << 8)
242 #define SYS_CLCD_ID_UNKNOWN_8_4 (0x01 << 8)
243 #define SYS_CLCD_ID_EPSON_2_2 (0x02 << 8)
244 #define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8)
245 #define SYS_CLCD_ID_VGA (0x1f << 8)
246 
247 /*
248  * Disable all display connectors on the interface module.
249  */
250 static void realview_clcd_disable(struct clcd_fb *fb)
251 {
253  u32 val;
254 
255  val = readl(sys_clcd);
257  writel(val, sys_clcd);
258 }
259 
260 /*
261  * Enable the relevant connector on the interface module.
262  */
263 static void realview_clcd_enable(struct clcd_fb *fb)
264 {
266  u32 val;
267 
268  /*
269  * Enable the PSUs
270  */
271  val = readl(sys_clcd);
273  writel(val, sys_clcd);
274 }
275 
276 /*
277  * Detect which LCD panel is connected, and return the appropriate
278  * clcd_panel structure. Note: we do not have any information on
279  * the required timings for the 8.4in panel, so we presently assume
280  * VGA timings.
281  */
282 static int realview_clcd_setup(struct clcd_fb *fb)
283 {
285  const char *panel_name, *vga_panel_name;
286  unsigned long framesize;
287  u32 val;
288 
289  if (machine_is_realview_eb()) {
290  /* VGA, 16bpp */
291  framesize = 640 * 480 * 2;
292  vga_panel_name = "VGA";
293  } else {
294  /* XVGA, 16bpp */
295  framesize = 1024 * 768 * 2;
296  vga_panel_name = "XVGA";
297  }
298 
299  val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
300  if (val == SYS_CLCD_ID_SANYO_3_8)
301  panel_name = "Sanyo TM38QV67A02A";
302  else if (val == SYS_CLCD_ID_SANYO_2_5)
303  panel_name = "Sanyo QVGA Portrait";
304  else if (val == SYS_CLCD_ID_EPSON_2_2)
305  panel_name = "Epson L2F50113T00";
306  else if (val == SYS_CLCD_ID_VGA)
307  panel_name = vga_panel_name;
308  else {
309  pr_err("CLCD: unknown LCD panel ID 0x%08x, using VGA\n", val);
310  panel_name = vga_panel_name;
311  }
312 
313  fb->panel = versatile_clcd_get_panel(panel_name);
314  if (!fb->panel)
315  return -EINVAL;
316 
317  return versatile_clcd_setup_dma(fb, framesize);
318 }
319 
321  .name = "RealView",
322  .caps = CLCD_CAP_ALL,
323  .check = clcdfb_check,
324  .decode = clcdfb_decode,
325  .disable = realview_clcd_disable,
326  .enable = realview_clcd_enable,
327  .setup = realview_clcd_setup,
328  .mmap = versatile_clcd_mmap_dma,
329  .remove = versatile_clcd_remove_dma,
330 };
331 
332 /*
333  * Where is the timer (VA)?
334  */
339 
340 /*
341  * Set up the clock source and clock events devices
342  */
343 void __init realview_timer_init(unsigned int timer_irq)
344 {
345  u32 val;
346 
347  /*
348  * set clock frequency:
349  * REALVIEW_REFCLK is 32KHz
350  * REALVIEW_TIMCLK is 1MHz
351  */
358 
359  /*
360  * Initialise to a known state (all timers off)
361  */
362  writel(0, timer0_va_base + TIMER_CTRL);
363  writel(0, timer1_va_base + TIMER_CTRL);
364  writel(0, timer2_va_base + TIMER_CTRL);
365  writel(0, timer3_va_base + TIMER_CTRL);
366 
367  sp804_clocksource_init(timer3_va_base, "timer3");
368  sp804_clockevents_init(timer0_va_base, timer_irq, "timer0");
369 }
370 
371 /*
372  * Setup the memory banks.
373  */
374 void realview_fixup(struct tag *tags, char **from, struct meminfo *meminfo)
375 {
376  /*
377  * Most RealView platforms have 512MB contiguous RAM at 0x70000000.
378  * Half of this is mirrored at 0.
379  */
380 #ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
381  meminfo->bank[0].start = 0x70000000;
382  meminfo->bank[0].size = SZ_512M;
383  meminfo->nr_banks = 1;
384 #else
385  meminfo->bank[0].start = 0;
386  meminfo->bank[0].size = SZ_256M;
387  meminfo->nr_banks = 1;
388 #endif
389 }