ge_imp3a.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * GE IMP3A Board Setup
  4. *
  5. * Author Martyn Welch <martyn.welch@ge.com>
  6. *
  7. * Copyright 2010 GE Intelligent Platforms Embedded Systems, Inc.
  8. *
  9. * Based on: mpc85xx_ds.c (MPC85xx DS Board Setup)
  10. * Copyright 2007 Freescale Semiconductor Inc.
  11. */
  12. #include <linux/stddef.h>
  13. #include <linux/kernel.h>
  14. #include <linux/pci.h>
  15. #include <linux/kdev_t.h>
  16. #include <linux/delay.h>
  17. #include <linux/seq_file.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/of.h>
  20. #include <linux/of_address.h>
  21. #include <asm/time.h>
  22. #include <asm/machdep.h>
  23. #include <asm/pci-bridge.h>
  24. #include <mm/mmu_decl.h>
  25. #include <asm/udbg.h>
  26. #include <asm/mpic.h>
  27. #include <asm/swiotlb.h>
  28. #include <asm/nvram.h>
  29. #include <sysdev/fsl_soc.h>
  30. #include <sysdev/fsl_pci.h>
  31. #include "smp.h"
  32. #include "mpc85xx.h"
  33. #include <sysdev/ge/ge_pic.h>
  34. void __iomem *imp3a_regs;
  35. static void __init ge_imp3a_pic_init(void)
  36. {
  37. struct mpic *mpic;
  38. struct device_node *np;
  39. struct device_node *cascade_node = NULL;
  40. if (of_machine_is_compatible("fsl,MPC8572DS-CAMP")) {
  41. mpic = mpic_alloc(NULL, 0,
  42. MPIC_NO_RESET |
  43. MPIC_BIG_ENDIAN |
  44. MPIC_SINGLE_DEST_CPU,
  45. 0, 256, " OpenPIC ");
  46. } else {
  47. mpic = mpic_alloc(NULL, 0,
  48. MPIC_BIG_ENDIAN |
  49. MPIC_SINGLE_DEST_CPU,
  50. 0, 256, " OpenPIC ");
  51. }
  52. BUG_ON(mpic == NULL);
  53. mpic_init(mpic);
  54. /*
  55. * There is a simple interrupt handler in the main FPGA, this needs
  56. * to be cascaded into the MPIC
  57. */
  58. for_each_node_by_type(np, "interrupt-controller")
  59. if (of_device_is_compatible(np, "gef,fpga-pic-1.00")) {
  60. cascade_node = np;
  61. break;
  62. }
  63. if (cascade_node == NULL) {
  64. printk(KERN_WARNING "IMP3A: No FPGA PIC\n");
  65. return;
  66. }
  67. gef_pic_init(cascade_node);
  68. of_node_put(cascade_node);
  69. }
  70. static void __init ge_imp3a_pci_assign_primary(void)
  71. {
  72. #ifdef CONFIG_PCI
  73. struct device_node *np;
  74. struct resource rsrc;
  75. for_each_node_by_type(np, "pci") {
  76. if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
  77. of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
  78. of_device_is_compatible(np, "fsl,p2020-pcie")) {
  79. of_address_to_resource(np, 0, &rsrc);
  80. if ((rsrc.start & 0xfffff) == 0x9000) {
  81. of_node_put(fsl_pci_primary);
  82. fsl_pci_primary = of_node_get(np);
  83. }
  84. }
  85. }
  86. #endif
  87. }
  88. /*
  89. * Setup the architecture
  90. */
  91. static void __init ge_imp3a_setup_arch(void)
  92. {
  93. struct device_node *regs;
  94. if (ppc_md.progress)
  95. ppc_md.progress("ge_imp3a_setup_arch()", 0);
  96. mpc85xx_smp_init();
  97. ge_imp3a_pci_assign_primary();
  98. swiotlb_detect_4g();
  99. /* Remap basic board registers */
  100. regs = of_find_compatible_node(NULL, NULL, "ge,imp3a-fpga-regs");
  101. if (regs) {
  102. imp3a_regs = of_iomap(regs, 0);
  103. if (imp3a_regs == NULL)
  104. printk(KERN_WARNING "Unable to map board registers\n");
  105. of_node_put(regs);
  106. }
  107. #if defined(CONFIG_MMIO_NVRAM)
  108. mmio_nvram_init();
  109. #endif
  110. printk(KERN_INFO "GE Intelligent Platforms IMP3A 3U cPCI SBC\n");
  111. }
  112. /* Return the PCB revision */
  113. static unsigned int ge_imp3a_get_pcb_rev(void)
  114. {
  115. unsigned int reg;
  116. reg = ioread16(imp3a_regs);
  117. return (reg >> 8) & 0xff;
  118. }
  119. /* Return the board (software) revision */
  120. static unsigned int ge_imp3a_get_board_rev(void)
  121. {
  122. unsigned int reg;
  123. reg = ioread16(imp3a_regs + 0x2);
  124. return reg & 0xff;
  125. }
  126. /* Return the FPGA revision */
  127. static unsigned int ge_imp3a_get_fpga_rev(void)
  128. {
  129. unsigned int reg;
  130. reg = ioread16(imp3a_regs + 0x2);
  131. return (reg >> 8) & 0xff;
  132. }
  133. /* Return compactPCI Geographical Address */
  134. static unsigned int ge_imp3a_get_cpci_geo_addr(void)
  135. {
  136. unsigned int reg;
  137. reg = ioread16(imp3a_regs + 0x6);
  138. return (reg & 0x0f00) >> 8;
  139. }
  140. /* Return compactPCI System Controller Status */
  141. static unsigned int ge_imp3a_get_cpci_is_syscon(void)
  142. {
  143. unsigned int reg;
  144. reg = ioread16(imp3a_regs + 0x6);
  145. return reg & (1 << 12);
  146. }
  147. static void ge_imp3a_show_cpuinfo(struct seq_file *m)
  148. {
  149. seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
  150. seq_printf(m, "Revision\t: %u%c\n", ge_imp3a_get_pcb_rev(),
  151. ('A' + ge_imp3a_get_board_rev() - 1));
  152. seq_printf(m, "FPGA Revision\t: %u\n", ge_imp3a_get_fpga_rev());
  153. seq_printf(m, "cPCI geo. addr\t: %u\n", ge_imp3a_get_cpci_geo_addr());
  154. seq_printf(m, "cPCI syscon\t: %s\n",
  155. ge_imp3a_get_cpci_is_syscon() ? "yes" : "no");
  156. }
  157. machine_arch_initcall(ge_imp3a, mpc85xx_common_publish_devices);
  158. define_machine(ge_imp3a) {
  159. .name = "GE_IMP3A",
  160. .compatible = "ge,IMP3A",
  161. .setup_arch = ge_imp3a_setup_arch,
  162. .init_IRQ = ge_imp3a_pic_init,
  163. .show_cpuinfo = ge_imp3a_show_cpuinfo,
  164. #ifdef CONFIG_PCI
  165. .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
  166. .pcibios_fixup_phb = fsl_pcibios_fixup_phb,
  167. #endif
  168. .get_irq = mpic_get_irq,
  169. .progress = udbg_progress,
  170. };