ts72xx.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * arch/arm/mach-ep93xx/ts72xx.c
  3. * Technologic Systems TS72xx SBC support.
  4. *
  5. * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
  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 (at
  10. * your option) any later version.
  11. */
  12. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  13. #include <linux/kernel.h>
  14. #include <linux/init.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/io.h>
  17. #include <linux/mtd/nand.h>
  18. #include <linux/mtd/partitions.h>
  19. #include <mach/hardware.h>
  20. #include <asm/mach-types.h>
  21. #include <asm/mach/map.h>
  22. #include <asm/mach/arch.h>
  23. #include "soc.h"
  24. #include "ts72xx.h"
  25. static struct map_desc ts72xx_io_desc[] __initdata = {
  26. {
  27. .virtual = (unsigned long)TS72XX_MODEL_VIRT_BASE,
  28. .pfn = __phys_to_pfn(TS72XX_MODEL_PHYS_BASE),
  29. .length = TS72XX_MODEL_SIZE,
  30. .type = MT_DEVICE,
  31. }, {
  32. .virtual = (unsigned long)TS72XX_OPTIONS_VIRT_BASE,
  33. .pfn = __phys_to_pfn(TS72XX_OPTIONS_PHYS_BASE),
  34. .length = TS72XX_OPTIONS_SIZE,
  35. .type = MT_DEVICE,
  36. }, {
  37. .virtual = (unsigned long)TS72XX_OPTIONS2_VIRT_BASE,
  38. .pfn = __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE),
  39. .length = TS72XX_OPTIONS2_SIZE,
  40. .type = MT_DEVICE,
  41. }
  42. };
  43. static void __init ts72xx_map_io(void)
  44. {
  45. ep93xx_map_io();
  46. iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc));
  47. }
  48. /*************************************************************************
  49. * NAND flash
  50. *************************************************************************/
  51. #define TS72XX_NAND_CONTROL_ADDR_LINE 22 /* 0xN0400000 */
  52. #define TS72XX_NAND_BUSY_ADDR_LINE 23 /* 0xN0800000 */
  53. static void ts72xx_nand_hwcontrol(struct mtd_info *mtd,
  54. int cmd, unsigned int ctrl)
  55. {
  56. struct nand_chip *chip = mtd_to_nand(mtd);
  57. if (ctrl & NAND_CTRL_CHANGE) {
  58. void __iomem *addr = chip->IO_ADDR_R;
  59. unsigned char bits;
  60. addr += (1 << TS72XX_NAND_CONTROL_ADDR_LINE);
  61. bits = __raw_readb(addr) & ~0x07;
  62. bits |= (ctrl & NAND_NCE) << 2; /* bit 0 -> bit 2 */
  63. bits |= (ctrl & NAND_CLE); /* bit 1 -> bit 1 */
  64. bits |= (ctrl & NAND_ALE) >> 2; /* bit 2 -> bit 0 */
  65. __raw_writeb(bits, addr);
  66. }
  67. if (cmd != NAND_CMD_NONE)
  68. __raw_writeb(cmd, chip->IO_ADDR_W);
  69. }
  70. static int ts72xx_nand_device_ready(struct mtd_info *mtd)
  71. {
  72. struct nand_chip *chip = mtd_to_nand(mtd);
  73. void __iomem *addr = chip->IO_ADDR_R;
  74. addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE);
  75. return !!(__raw_readb(addr) & 0x20);
  76. }
  77. #define TS72XX_BOOTROM_PART_SIZE (SZ_16K)
  78. #define TS72XX_REDBOOT_PART_SIZE (SZ_2M + SZ_1M)
  79. static struct mtd_partition ts72xx_nand_parts[] = {
  80. {
  81. .name = "TS-BOOTROM",
  82. .offset = 0,
  83. .size = TS72XX_BOOTROM_PART_SIZE,
  84. .mask_flags = MTD_WRITEABLE, /* force read-only */
  85. }, {
  86. .name = "Linux",
  87. .offset = MTDPART_OFS_RETAIN,
  88. .size = TS72XX_REDBOOT_PART_SIZE,
  89. /* leave so much for last partition */
  90. }, {
  91. .name = "RedBoot",
  92. .offset = MTDPART_OFS_APPEND,
  93. .size = MTDPART_SIZ_FULL,
  94. .mask_flags = MTD_WRITEABLE, /* force read-only */
  95. },
  96. };
  97. static struct platform_nand_data ts72xx_nand_data = {
  98. .chip = {
  99. .nr_chips = 1,
  100. .chip_offset = 0,
  101. .chip_delay = 15,
  102. .partitions = ts72xx_nand_parts,
  103. .nr_partitions = ARRAY_SIZE(ts72xx_nand_parts),
  104. },
  105. .ctrl = {
  106. .cmd_ctrl = ts72xx_nand_hwcontrol,
  107. .dev_ready = ts72xx_nand_device_ready,
  108. },
  109. };
  110. static struct resource ts72xx_nand_resource[] = {
  111. {
  112. .start = 0, /* filled in later */
  113. .end = 0, /* filled in later */
  114. .flags = IORESOURCE_MEM,
  115. },
  116. };
  117. static struct platform_device ts72xx_nand_flash = {
  118. .name = "gen_nand",
  119. .id = -1,
  120. .dev.platform_data = &ts72xx_nand_data,
  121. .resource = ts72xx_nand_resource,
  122. .num_resources = ARRAY_SIZE(ts72xx_nand_resource),
  123. };
  124. static void __init ts72xx_register_flash(void)
  125. {
  126. /*
  127. * TS7200 has NOR flash all other TS72xx board have NAND flash.
  128. */
  129. if (board_is_ts7200()) {
  130. ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_16M);
  131. } else {
  132. resource_size_t start;
  133. if (is_ts9420_installed())
  134. start = EP93XX_CS7_PHYS_BASE;
  135. else
  136. start = EP93XX_CS6_PHYS_BASE;
  137. ts72xx_nand_resource[0].start = start;
  138. ts72xx_nand_resource[0].end = start + SZ_16M - 1;
  139. platform_device_register(&ts72xx_nand_flash);
  140. }
  141. }
  142. /*************************************************************************
  143. * RTC M48T86
  144. *************************************************************************/
  145. #define TS72XX_RTC_INDEX_PHYS_BASE (EP93XX_CS1_PHYS_BASE + 0x00800000)
  146. #define TS72XX_RTC_DATA_PHYS_BASE (EP93XX_CS1_PHYS_BASE + 0x01700000)
  147. static struct resource ts72xx_rtc_resources[] = {
  148. DEFINE_RES_MEM(TS72XX_RTC_INDEX_PHYS_BASE, 0x01),
  149. DEFINE_RES_MEM(TS72XX_RTC_DATA_PHYS_BASE, 0x01),
  150. };
  151. static struct platform_device ts72xx_rtc_device = {
  152. .name = "rtc-m48t86",
  153. .id = -1,
  154. .resource = ts72xx_rtc_resources,
  155. .num_resources = ARRAY_SIZE(ts72xx_rtc_resources),
  156. };
  157. static struct resource ts72xx_wdt_resources[] = {
  158. {
  159. .start = TS72XX_WDT_CONTROL_PHYS_BASE,
  160. .end = TS72XX_WDT_CONTROL_PHYS_BASE + SZ_4K - 1,
  161. .flags = IORESOURCE_MEM,
  162. },
  163. {
  164. .start = TS72XX_WDT_FEED_PHYS_BASE,
  165. .end = TS72XX_WDT_FEED_PHYS_BASE + SZ_4K - 1,
  166. .flags = IORESOURCE_MEM,
  167. },
  168. };
  169. static struct platform_device ts72xx_wdt_device = {
  170. .name = "ts72xx-wdt",
  171. .id = -1,
  172. .num_resources = ARRAY_SIZE(ts72xx_wdt_resources),
  173. .resource = ts72xx_wdt_resources,
  174. };
  175. static struct ep93xx_eth_data __initdata ts72xx_eth_data = {
  176. .phy_id = 1,
  177. };
  178. #if IS_ENABLED(CONFIG_FPGA_MGR_TS73XX)
  179. /* Relative to EP93XX_CS1_PHYS_BASE */
  180. #define TS73XX_FPGA_LOADER_BASE 0x03c00000
  181. static struct resource ts73xx_fpga_resources[] = {
  182. {
  183. .start = EP93XX_CS1_PHYS_BASE + TS73XX_FPGA_LOADER_BASE,
  184. .end = EP93XX_CS1_PHYS_BASE + TS73XX_FPGA_LOADER_BASE + 1,
  185. .flags = IORESOURCE_MEM,
  186. },
  187. };
  188. static struct platform_device ts73xx_fpga_device = {
  189. .name = "ts73xx-fpga-mgr",
  190. .id = -1,
  191. .resource = ts73xx_fpga_resources,
  192. .num_resources = ARRAY_SIZE(ts73xx_fpga_resources),
  193. };
  194. #endif
  195. static void __init ts72xx_init_machine(void)
  196. {
  197. ep93xx_init_devices();
  198. ts72xx_register_flash();
  199. platform_device_register(&ts72xx_rtc_device);
  200. platform_device_register(&ts72xx_wdt_device);
  201. ep93xx_register_eth(&ts72xx_eth_data, 1);
  202. #if IS_ENABLED(CONFIG_FPGA_MGR_TS73XX)
  203. if (board_is_ts7300())
  204. platform_device_register(&ts73xx_fpga_device);
  205. #endif
  206. }
  207. MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
  208. /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
  209. .atag_offset = 0x100,
  210. .map_io = ts72xx_map_io,
  211. .init_irq = ep93xx_init_irq,
  212. .init_time = ep93xx_timer_init,
  213. .init_machine = ts72xx_init_machine,
  214. .init_late = ep93xx_init_late,
  215. .restart = ep93xx_restart,
  216. MACHINE_END