ts78xx-setup.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. * arch/arm/mach-orion5x/ts78xx-setup.c
  3. *
  4. * Maintainer: Alexander Clouter <alex@digriz.org.uk>
  5. *
  6. * This file is licensed under the terms of the GNU General Public
  7. * License version 2. This program is licensed "as is" without any
  8. * warranty of any kind, whether express or implied.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/init.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/mv643xx_eth.h>
  14. #include <linux/ata_platform.h>
  15. #include <linux/m48t86.h>
  16. #include <asm/mach-types.h>
  17. #include <asm/mach/arch.h>
  18. #include <asm/mach/map.h>
  19. #include <mach/orion5x.h>
  20. #include "common.h"
  21. #include "mpp.h"
  22. /*****************************************************************************
  23. * TS-78xx Info
  24. ****************************************************************************/
  25. /*
  26. * FPGA - lives where the PCI bus would be at ORION5X_PCI_MEM_PHYS_BASE
  27. */
  28. #define TS78XX_FPGA_REGS_PHYS_BASE 0xe8000000
  29. #define TS78XX_FPGA_REGS_VIRT_BASE 0xff900000
  30. #define TS78XX_FPGA_REGS_SIZE SZ_1M
  31. #define TS78XX_FPGA_REGS_SYSCON_ID (TS78XX_FPGA_REGS_VIRT_BASE | 0x000)
  32. #define TS78XX_FPGA_REGS_SYSCON_LCDI (TS78XX_FPGA_REGS_VIRT_BASE | 0x004)
  33. #define TS78XX_FPGA_REGS_SYSCON_LCDO (TS78XX_FPGA_REGS_VIRT_BASE | 0x008)
  34. #define TS78XX_FPGA_REGS_RTC_CTRL (TS78XX_FPGA_REGS_VIRT_BASE | 0x808)
  35. #define TS78XX_FPGA_REGS_RTC_DATA (TS78XX_FPGA_REGS_VIRT_BASE | 0x80c)
  36. /*****************************************************************************
  37. * I/O Address Mapping
  38. ****************************************************************************/
  39. static struct map_desc ts78xx_io_desc[] __initdata = {
  40. {
  41. .virtual = TS78XX_FPGA_REGS_VIRT_BASE,
  42. .pfn = __phys_to_pfn(TS78XX_FPGA_REGS_PHYS_BASE),
  43. .length = TS78XX_FPGA_REGS_SIZE,
  44. .type = MT_DEVICE,
  45. },
  46. };
  47. void __init ts78xx_map_io(void)
  48. {
  49. orion5x_map_io();
  50. iotable_init(ts78xx_io_desc, ARRAY_SIZE(ts78xx_io_desc));
  51. }
  52. /*****************************************************************************
  53. * Ethernet
  54. ****************************************************************************/
  55. static struct mv643xx_eth_platform_data ts78xx_eth_data = {
  56. .phy_addr = MV643XX_ETH_PHY_ADDR(0),
  57. };
  58. /*****************************************************************************
  59. * RTC M48T86 - nicked^Wborrowed from arch/arm/mach-ep93xx/ts72xx.c
  60. ****************************************************************************/
  61. #ifdef CONFIG_RTC_DRV_M48T86
  62. static unsigned char ts78xx_rtc_readbyte(unsigned long addr)
  63. {
  64. writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL);
  65. return readb(TS78XX_FPGA_REGS_RTC_DATA);
  66. }
  67. static void ts78xx_rtc_writebyte(unsigned char value, unsigned long addr)
  68. {
  69. writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL);
  70. writeb(value, TS78XX_FPGA_REGS_RTC_DATA);
  71. }
  72. static struct m48t86_ops ts78xx_rtc_ops = {
  73. .readbyte = ts78xx_rtc_readbyte,
  74. .writebyte = ts78xx_rtc_writebyte,
  75. };
  76. static struct platform_device ts78xx_rtc_device = {
  77. .name = "rtc-m48t86",
  78. .id = -1,
  79. .dev = {
  80. .platform_data = &ts78xx_rtc_ops,
  81. },
  82. .num_resources = 0,
  83. };
  84. /*
  85. * TS uses some of the user storage space on the RTC chip so see if it is
  86. * present; as it's an optional feature at purchase time and not all boards
  87. * will have it present
  88. *
  89. * I've used the method TS use in their rtc7800.c example for the detection
  90. *
  91. * TODO: track down a guinea pig without an RTC to see if we can work out a
  92. * better RTC detection routine
  93. */
  94. static int __init ts78xx_rtc_init(void)
  95. {
  96. unsigned char tmp_rtc0, tmp_rtc1;
  97. tmp_rtc0 = ts78xx_rtc_readbyte(126);
  98. tmp_rtc1 = ts78xx_rtc_readbyte(127);
  99. ts78xx_rtc_writebyte(0x00, 126);
  100. ts78xx_rtc_writebyte(0x55, 127);
  101. if (ts78xx_rtc_readbyte(127) == 0x55) {
  102. ts78xx_rtc_writebyte(0xaa, 127);
  103. if (ts78xx_rtc_readbyte(127) == 0xaa
  104. && ts78xx_rtc_readbyte(126) == 0x00) {
  105. ts78xx_rtc_writebyte(tmp_rtc0, 126);
  106. ts78xx_rtc_writebyte(tmp_rtc1, 127);
  107. platform_device_register(&ts78xx_rtc_device);
  108. return 1;
  109. }
  110. }
  111. return 0;
  112. };
  113. #else
  114. static int __init ts78xx_rtc_init(void)
  115. {
  116. return 0;
  117. }
  118. #endif
  119. /*****************************************************************************
  120. * SATA
  121. ****************************************************************************/
  122. static struct mv_sata_platform_data ts78xx_sata_data = {
  123. .n_ports = 2,
  124. };
  125. /*****************************************************************************
  126. * print some information regarding the board
  127. ****************************************************************************/
  128. static void __init ts78xx_print_board_id(void)
  129. {
  130. unsigned int board_info;
  131. board_info = readl(TS78XX_FPGA_REGS_SYSCON_ID);
  132. printk(KERN_INFO "TS-78xx Info: FPGA rev=%.2x, Board Magic=%.6x, ",
  133. board_info & 0xff,
  134. (board_info >> 8) & 0xffffff);
  135. board_info = readl(TS78XX_FPGA_REGS_SYSCON_LCDI);
  136. printk("JP1=%d, JP2=%d\n",
  137. (board_info >> 30) & 0x1,
  138. (board_info >> 31) & 0x1);
  139. };
  140. /*****************************************************************************
  141. * General Setup
  142. ****************************************************************************/
  143. static struct orion5x_mpp_mode ts78xx_mpp_modes[] __initdata = {
  144. { 0, MPP_UNUSED },
  145. { 1, MPP_GPIO }, /* JTAG Clock */
  146. { 2, MPP_GPIO }, /* JTAG Data In */
  147. { 3, MPP_GPIO }, /* Lat ECP2 256 FPGA - PB2B */
  148. { 4, MPP_GPIO }, /* JTAG Data Out */
  149. { 5, MPP_GPIO }, /* JTAG TMS */
  150. { 6, MPP_GPIO }, /* Lat ECP2 256 FPGA - PB31A_CLK4+ */
  151. { 7, MPP_GPIO }, /* Lat ECP2 256 FPGA - PB22B */
  152. { 8, MPP_UNUSED },
  153. { 9, MPP_UNUSED },
  154. { 10, MPP_UNUSED },
  155. { 11, MPP_UNUSED },
  156. { 12, MPP_UNUSED },
  157. { 13, MPP_UNUSED },
  158. { 14, MPP_UNUSED },
  159. { 15, MPP_UNUSED },
  160. { 16, MPP_UART },
  161. { 17, MPP_UART },
  162. { 18, MPP_UART },
  163. { 19, MPP_UART },
  164. /*
  165. * MPP[20] PCI Clock Out 1
  166. * MPP[21] PCI Clock Out 0
  167. * MPP[22] Unused
  168. * MPP[23] Unused
  169. * MPP[24] Unused
  170. * MPP[25] Unused
  171. */
  172. { -1 },
  173. };
  174. static void __init ts78xx_init(void)
  175. {
  176. /*
  177. * Setup basic Orion functions. Need to be called early.
  178. */
  179. orion5x_init();
  180. ts78xx_print_board_id();
  181. orion5x_mpp_conf(ts78xx_mpp_modes);
  182. /*
  183. * Configure peripherals.
  184. */
  185. orion5x_ehci0_init();
  186. orion5x_ehci1_init();
  187. orion5x_eth_init(&ts78xx_eth_data);
  188. orion5x_sata_init(&ts78xx_sata_data);
  189. orion5x_uart0_init();
  190. orion5x_uart1_init();
  191. orion5x_xor_init();
  192. if (!ts78xx_rtc_init())
  193. printk(KERN_INFO "TS-78xx RTC not detected or enabled\n");
  194. }
  195. MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
  196. /* Maintainer: Alexander Clouter <alex@digriz.org.uk> */
  197. .phys_io = ORION5X_REGS_PHYS_BASE,
  198. .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
  199. .boot_params = 0x00000100,
  200. .init_machine = ts78xx_init,
  201. .map_io = ts78xx_map_io,
  202. .init_irq = orion5x_init_irq,
  203. .timer = &orion5x_timer,
  204. MACHINE_END