board-gpr.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /*
  2. * GPR board platform device registration (Au1550)
  3. *
  4. * Copyright (C) 2010 Wolfgang Grandegger <wg@denx.de>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include <linux/delay.h>
  21. #include <linux/init.h>
  22. #include <linux/interrupt.h>
  23. #include <linux/kernel.h>
  24. #include <linux/platform_device.h>
  25. #include <linux/pm.h>
  26. #include <linux/mtd/partitions.h>
  27. #include <linux/mtd/physmap.h>
  28. #include <linux/leds.h>
  29. #include <linux/gpio.h>
  30. #include <linux/i2c.h>
  31. #include <linux/platform_data/i2c-gpio.h>
  32. #include <linux/gpio/machine.h>
  33. #include <asm/bootinfo.h>
  34. #include <asm/idle.h>
  35. #include <asm/reboot.h>
  36. #include <asm/setup.h>
  37. #include <asm/mach-au1x00/au1000.h>
  38. #include <asm/mach-au1x00/gpio-au1000.h>
  39. #include <prom.h>
  40. const char *get_system_type(void)
  41. {
  42. return "GPR";
  43. }
  44. void __init prom_init(void)
  45. {
  46. unsigned char *memsize_str;
  47. unsigned long memsize;
  48. prom_argc = fw_arg0;
  49. prom_argv = (char **)fw_arg1;
  50. prom_envp = (char **)fw_arg2;
  51. prom_init_cmdline();
  52. memsize_str = prom_getenv("memsize");
  53. if (!memsize_str || kstrtoul(memsize_str, 0, &memsize))
  54. memsize = 0x04000000;
  55. add_memory_region(0, memsize, BOOT_MEM_RAM);
  56. }
  57. void prom_putchar(char c)
  58. {
  59. alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
  60. }
  61. static void gpr_reset(char *c)
  62. {
  63. /* switch System-LED to orange (red# and green# on) */
  64. alchemy_gpio_direction_output(4, 0);
  65. alchemy_gpio_direction_output(5, 0);
  66. /* trigger watchdog to reset board in 200ms */
  67. printk(KERN_EMERG "Triggering watchdog soft reset...\n");
  68. raw_local_irq_disable();
  69. alchemy_gpio_direction_output(1, 0);
  70. udelay(1);
  71. alchemy_gpio_set_value(1, 1);
  72. while (1)
  73. cpu_wait();
  74. }
  75. static void gpr_power_off(void)
  76. {
  77. while (1)
  78. cpu_wait();
  79. }
  80. void __init board_setup(void)
  81. {
  82. printk(KERN_INFO "Trapeze ITS GPR board\n");
  83. pm_power_off = gpr_power_off;
  84. _machine_halt = gpr_power_off;
  85. _machine_restart = gpr_reset;
  86. /* Enable UART1/3 */
  87. alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
  88. alchemy_uart_enable(AU1000_UART1_PHYS_ADDR);
  89. /* Take away Reset of UMTS-card */
  90. alchemy_gpio_direction_output(215, 1);
  91. }
  92. /*
  93. * Watchdog
  94. */
  95. static struct resource gpr_wdt_resource[] = {
  96. [0] = {
  97. .start = 1,
  98. .end = 1,
  99. .name = "gpr-adm6320-wdt",
  100. .flags = IORESOURCE_IRQ,
  101. }
  102. };
  103. static struct platform_device gpr_wdt_device = {
  104. .name = "adm6320-wdt",
  105. .id = 0,
  106. .num_resources = ARRAY_SIZE(gpr_wdt_resource),
  107. .resource = gpr_wdt_resource,
  108. };
  109. /*
  110. * FLASH
  111. *
  112. * 0x00000000-0x00200000 : "kernel"
  113. * 0x00200000-0x00a00000 : "rootfs"
  114. * 0x01d00000-0x01f00000 : "config"
  115. * 0x01c00000-0x01d00000 : "yamon"
  116. * 0x01d00000-0x01d40000 : "yamon env vars"
  117. * 0x00000000-0x00a00000 : "kernel+rootfs"
  118. */
  119. static struct mtd_partition gpr_mtd_partitions[] = {
  120. {
  121. .name = "kernel",
  122. .size = 0x00200000,
  123. .offset = 0,
  124. },
  125. {
  126. .name = "rootfs",
  127. .size = 0x00800000,
  128. .offset = MTDPART_OFS_APPEND,
  129. .mask_flags = MTD_WRITEABLE,
  130. },
  131. {
  132. .name = "config",
  133. .size = 0x00200000,
  134. .offset = 0x01d00000,
  135. },
  136. {
  137. .name = "yamon",
  138. .size = 0x00100000,
  139. .offset = 0x01c00000,
  140. },
  141. {
  142. .name = "yamon env vars",
  143. .size = 0x00040000,
  144. .offset = MTDPART_OFS_APPEND,
  145. },
  146. {
  147. .name = "kernel+rootfs",
  148. .size = 0x00a00000,
  149. .offset = 0,
  150. },
  151. };
  152. static struct physmap_flash_data gpr_flash_data = {
  153. .width = 4,
  154. .nr_parts = ARRAY_SIZE(gpr_mtd_partitions),
  155. .parts = gpr_mtd_partitions,
  156. };
  157. static struct resource gpr_mtd_resource = {
  158. .start = 0x1e000000,
  159. .end = 0x1fffffff,
  160. .flags = IORESOURCE_MEM,
  161. };
  162. static struct platform_device gpr_mtd_device = {
  163. .name = "physmap-flash",
  164. .dev = {
  165. .platform_data = &gpr_flash_data,
  166. },
  167. .num_resources = 1,
  168. .resource = &gpr_mtd_resource,
  169. };
  170. /*
  171. * LEDs
  172. */
  173. static const struct gpio_led gpr_gpio_leds[] = {
  174. { /* green */
  175. .name = "gpr:green",
  176. .gpio = 4,
  177. .active_low = 1,
  178. },
  179. { /* red */
  180. .name = "gpr:red",
  181. .gpio = 5,
  182. .active_low = 1,
  183. }
  184. };
  185. static struct gpio_led_platform_data gpr_led_data = {
  186. .num_leds = ARRAY_SIZE(gpr_gpio_leds),
  187. .leds = gpr_gpio_leds,
  188. };
  189. static struct platform_device gpr_led_devices = {
  190. .name = "leds-gpio",
  191. .id = -1,
  192. .dev = {
  193. .platform_data = &gpr_led_data,
  194. }
  195. };
  196. /*
  197. * I2C
  198. */
  199. static struct gpiod_lookup_table gpr_i2c_gpiod_table = {
  200. .dev_id = "i2c-gpio",
  201. .table = {
  202. /*
  203. * This should be on "GPIO2" which has base at 200 so
  204. * the global numbers 209 and 210 should correspond to
  205. * local offsets 9 and 10.
  206. */
  207. GPIO_LOOKUP_IDX("alchemy-gpio2", 9, NULL, 0,
  208. GPIO_ACTIVE_HIGH),
  209. GPIO_LOOKUP_IDX("alchemy-gpio2", 10, NULL, 1,
  210. GPIO_ACTIVE_HIGH),
  211. },
  212. };
  213. static struct i2c_gpio_platform_data gpr_i2c_data = {
  214. /*
  215. * The open drain mode is hardwired somewhere or an electrical
  216. * property of the alchemy GPIO controller.
  217. */
  218. .sda_is_open_drain = 1,
  219. .scl_is_open_drain = 1,
  220. .udelay = 2, /* ~100 kHz */
  221. .timeout = HZ,
  222. };
  223. static struct platform_device gpr_i2c_device = {
  224. .name = "i2c-gpio",
  225. .id = -1,
  226. .dev.platform_data = &gpr_i2c_data,
  227. };
  228. static struct i2c_board_info gpr_i2c_info[] __initdata = {
  229. {
  230. I2C_BOARD_INFO("lm83", 0x18),
  231. }
  232. };
  233. static struct resource alchemy_pci_host_res[] = {
  234. [0] = {
  235. .start = AU1500_PCI_PHYS_ADDR,
  236. .end = AU1500_PCI_PHYS_ADDR + 0xfff,
  237. .flags = IORESOURCE_MEM,
  238. },
  239. };
  240. static int gpr_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
  241. {
  242. if ((slot == 0) && (pin == 1))
  243. return AU1550_PCI_INTA;
  244. else if ((slot == 0) && (pin == 2))
  245. return AU1550_PCI_INTB;
  246. return 0xff;
  247. }
  248. static struct alchemy_pci_platdata gpr_pci_pd = {
  249. .board_map_irq = gpr_map_pci_irq,
  250. .pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H |
  251. PCI_CONFIG_CH |
  252. #if defined(__MIPSEB__)
  253. PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM,
  254. #else
  255. 0,
  256. #endif
  257. };
  258. static struct platform_device gpr_pci_host_dev = {
  259. .dev.platform_data = &gpr_pci_pd,
  260. .name = "alchemy-pci",
  261. .id = 0,
  262. .num_resources = ARRAY_SIZE(alchemy_pci_host_res),
  263. .resource = alchemy_pci_host_res,
  264. };
  265. static struct platform_device *gpr_devices[] __initdata = {
  266. &gpr_wdt_device,
  267. &gpr_mtd_device,
  268. &gpr_i2c_device,
  269. &gpr_led_devices,
  270. };
  271. static int __init gpr_pci_init(void)
  272. {
  273. return platform_device_register(&gpr_pci_host_dev);
  274. }
  275. /* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */
  276. arch_initcall(gpr_pci_init);
  277. static int __init gpr_dev_init(void)
  278. {
  279. gpiod_add_lookup_table(&gpr_i2c_gpiod_table);
  280. i2c_register_board_info(0, gpr_i2c_info, ARRAY_SIZE(gpr_i2c_info));
  281. return platform_add_devices(gpr_devices, ARRAY_SIZE(gpr_devices));
  282. }
  283. device_initcall(gpr_dev_init);