mvme5100.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * Board setup routines for the Motorola/Emerson MVME5100.
  3. *
  4. * Copyright 2013 CSC Australia Pty. Ltd.
  5. *
  6. * Based on earlier code by:
  7. *
  8. * Matt Porter, MontaVista Software Inc.
  9. * Copyright 2001 MontaVista Software Inc.
  10. *
  11. * This program is free software; you can redistribute it and/or modify it
  12. * under the terms of the GNU General Public License as published by the
  13. * Free Software Foundation; either version 2 of the License, or (at your
  14. * option) any later version.
  15. *
  16. * Author: Stephen Chivers <schivers@csc.com>
  17. *
  18. */
  19. #include <linux/of_platform.h>
  20. #include <asm/i8259.h>
  21. #include <asm/pci-bridge.h>
  22. #include <asm/mpic.h>
  23. #include <asm/prom.h>
  24. #include <mm/mmu_decl.h>
  25. #include <asm/udbg.h>
  26. #define HAWK_MPIC_SIZE 0x00040000U
  27. #define MVME5100_PCI_MEM_OFFSET 0x00000000
  28. /* Board register addresses. */
  29. #define BOARD_STATUS_REG 0xfef88080
  30. #define BOARD_MODFAIL_REG 0xfef88090
  31. #define BOARD_MODRST_REG 0xfef880a0
  32. #define BOARD_TBEN_REG 0xfef880c0
  33. #define BOARD_SW_READ_REG 0xfef880e0
  34. #define BOARD_GEO_ADDR_REG 0xfef880e8
  35. #define BOARD_EXT_FEATURE1_REG 0xfef880f0
  36. #define BOARD_EXT_FEATURE2_REG 0xfef88100
  37. static phys_addr_t pci_membase;
  38. static u_char *restart;
  39. static void mvme5100_8259_cascade(struct irq_desc *desc)
  40. {
  41. struct irq_chip *chip = irq_desc_get_chip(desc);
  42. unsigned int cascade_irq = i8259_irq();
  43. if (cascade_irq)
  44. generic_handle_irq(cascade_irq);
  45. chip->irq_eoi(&desc->irq_data);
  46. }
  47. static void __init mvme5100_pic_init(void)
  48. {
  49. struct mpic *mpic;
  50. struct device_node *np;
  51. struct device_node *cp = NULL;
  52. unsigned int cirq;
  53. unsigned long intack = 0;
  54. const u32 *prop = NULL;
  55. np = of_find_node_by_type(NULL, "open-pic");
  56. if (!np) {
  57. pr_err("Could not find open-pic node\n");
  58. return;
  59. }
  60. mpic = mpic_alloc(np, pci_membase, 0, 16, 256, " OpenPIC ");
  61. BUG_ON(mpic == NULL);
  62. of_node_put(np);
  63. mpic_assign_isu(mpic, 0, pci_membase + 0x10000);
  64. mpic_init(mpic);
  65. cp = of_find_compatible_node(NULL, NULL, "chrp,iic");
  66. if (cp == NULL) {
  67. pr_warn("mvme5100_pic_init: couldn't find i8259\n");
  68. return;
  69. }
  70. cirq = irq_of_parse_and_map(cp, 0);
  71. if (!cirq) {
  72. pr_warn("mvme5100_pic_init: no cascade interrupt?\n");
  73. return;
  74. }
  75. np = of_find_compatible_node(NULL, "pci", "mpc10x-pci");
  76. if (np) {
  77. prop = of_get_property(np, "8259-interrupt-acknowledge", NULL);
  78. if (prop)
  79. intack = prop[0];
  80. of_node_put(np);
  81. }
  82. if (intack)
  83. pr_debug("mvme5100_pic_init: PCI 8259 intack at 0x%016lx\n",
  84. intack);
  85. i8259_init(cp, intack);
  86. of_node_put(cp);
  87. irq_set_chained_handler(cirq, mvme5100_8259_cascade);
  88. }
  89. static int __init mvme5100_add_bridge(struct device_node *dev)
  90. {
  91. const int *bus_range;
  92. int len;
  93. struct pci_controller *hose;
  94. unsigned short devid;
  95. pr_info("Adding PCI host bridge %s\n", dev->full_name);
  96. bus_range = of_get_property(dev, "bus-range", &len);
  97. hose = pcibios_alloc_controller(dev);
  98. if (hose == NULL)
  99. return -ENOMEM;
  100. hose->first_busno = bus_range ? bus_range[0] : 0;
  101. hose->last_busno = bus_range ? bus_range[1] : 0xff;
  102. setup_indirect_pci(hose, 0xfe000cf8, 0xfe000cfc, 0);
  103. pci_process_bridge_OF_ranges(hose, dev, 1);
  104. early_read_config_word(hose, 0, 0, PCI_DEVICE_ID, &devid);
  105. if (devid != PCI_DEVICE_ID_MOTOROLA_HAWK) {
  106. pr_err("HAWK PHB not present?\n");
  107. return 0;
  108. }
  109. early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase);
  110. if (pci_membase == 0) {
  111. pr_err("HAWK PHB mibar not correctly set?\n");
  112. return 0;
  113. }
  114. pr_info("mvme5100_pic_init: pci_membase: %x\n", pci_membase);
  115. return 0;
  116. }
  117. static const struct of_device_id mvme5100_of_bus_ids[] __initconst = {
  118. { .compatible = "hawk-bridge", },
  119. {},
  120. };
  121. /*
  122. * Setup the architecture
  123. */
  124. static void __init mvme5100_setup_arch(void)
  125. {
  126. struct device_node *np;
  127. if (ppc_md.progress)
  128. ppc_md.progress("mvme5100_setup_arch()", 0);
  129. for_each_compatible_node(np, "pci", "hawk-pci")
  130. mvme5100_add_bridge(np);
  131. restart = ioremap(BOARD_MODRST_REG, 4);
  132. }
  133. static void mvme5100_show_cpuinfo(struct seq_file *m)
  134. {
  135. seq_puts(m, "Vendor\t\t: Motorola/Emerson\n");
  136. seq_puts(m, "Machine\t\t: MVME5100\n");
  137. }
  138. static void __noreturn mvme5100_restart(char *cmd)
  139. {
  140. local_irq_disable();
  141. mtmsr(mfmsr() | MSR_IP);
  142. out_8((u_char *) restart, 0x01);
  143. while (1)
  144. ;
  145. }
  146. /*
  147. * Called very early, device-tree isn't unflattened
  148. */
  149. static int __init mvme5100_probe(void)
  150. {
  151. return of_machine_is_compatible("MVME5100");
  152. }
  153. static int __init probe_of_platform_devices(void)
  154. {
  155. of_platform_bus_probe(NULL, mvme5100_of_bus_ids, NULL);
  156. return 0;
  157. }
  158. machine_device_initcall(mvme5100, probe_of_platform_devices);
  159. define_machine(mvme5100) {
  160. .name = "MVME5100",
  161. .probe = mvme5100_probe,
  162. .setup_arch = mvme5100_setup_arch,
  163. .init_IRQ = mvme5100_pic_init,
  164. .show_cpuinfo = mvme5100_show_cpuinfo,
  165. .get_irq = mpic_get_irq,
  166. .restart = mvme5100_restart,
  167. .calibrate_decr = generic_calibrate_decr,
  168. .progress = udbg_progress,
  169. };