mcpn765.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. /*
  2. * arch/ppc/platforms/mcpn765.c
  3. *
  4. * Board setup routines for the Motorola MCG MCPN765 cPCI Board.
  5. *
  6. * Author: Mark A. Greer
  7. * mgreer@mvista.com
  8. *
  9. * Modified by Randy Vinson (rvinson@mvista.com)
  10. *
  11. * 2001-2002 (c) MontaVista, Software, Inc. This file is licensed under
  12. * the terms of the GNU General Public License version 2. This program
  13. * is licensed "as is" without any warranty of any kind, whether express
  14. * or implied.
  15. */
  16. /*
  17. * This file adds support for the Motorola MCG MCPN765.
  18. */
  19. #include <linux/config.h>
  20. #include <linux/stddef.h>
  21. #include <linux/kernel.h>
  22. #include <linux/init.h>
  23. #include <linux/errno.h>
  24. #include <linux/reboot.h>
  25. #include <linux/pci.h>
  26. #include <linux/kdev_t.h>
  27. #include <linux/major.h>
  28. #include <linux/initrd.h>
  29. #include <linux/console.h>
  30. #include <linux/delay.h>
  31. #include <linux/irq.h>
  32. #include <linux/seq_file.h>
  33. #include <linux/root_dev.h>
  34. #include <linux/serial.h>
  35. #include <linux/tty.h> /* for linux/serial_core.h */
  36. #include <linux/serial_core.h>
  37. #include <linux/slab.h>
  38. #include <asm/system.h>
  39. #include <asm/pgtable.h>
  40. #include <asm/page.h>
  41. #include <asm/time.h>
  42. #include <asm/dma.h>
  43. #include <asm/byteorder.h>
  44. #include <asm/io.h>
  45. #include <asm/machdep.h>
  46. #include <asm/prom.h>
  47. #include <asm/smp.h>
  48. #include <asm/open_pic.h>
  49. #include <asm/i8259.h>
  50. #include <asm/todc.h>
  51. #include <asm/pci-bridge.h>
  52. #include <asm/irq.h>
  53. #include <asm/uaccess.h>
  54. #include <asm/bootinfo.h>
  55. #include <asm/hawk.h>
  56. #include <asm/kgdb.h>
  57. #include "mcpn765.h"
  58. static u_char mcpn765_openpic_initsenses[] __initdata = {
  59. (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE),/* 16: i8259 cascade */
  60. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 17: COM1,2,3,4 */
  61. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 18: Enet 1 (front) */
  62. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 19: HAWK WDT XXXX */
  63. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 20: 21554 bridge */
  64. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 21: cPCI INTA# */
  65. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 22: cPCI INTB# */
  66. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 23: cPCI INTC# */
  67. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 24: cPCI INTD# */
  68. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 25: PMC1 INTA#,PMC2 INTB#*/
  69. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 26: PMC1 INTB#,PMC2 INTC#*/
  70. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 27: PMC1 INTC#,PMC2 INTD#*/
  71. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 28: PMC1 INTD#,PMC2 INTA#*/
  72. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 29: Enet 2 (J3) */
  73. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 30: Abort Switch */
  74. (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 31: RTC Alarm */
  75. };
  76. extern void mcpn765_set_VIA_IDE_native(void);
  77. extern u_int openpic_irq(void);
  78. extern char cmd_line[];
  79. extern void gen550_progress(char *, unsigned short);
  80. extern void gen550_init(int, struct uart_port *);
  81. int use_of_interrupt_tree = 0;
  82. static void mcpn765_halt(void);
  83. TODC_ALLOC();
  84. /*
  85. * Motorola MCG MCPN765 interrupt routing.
  86. */
  87. static inline int
  88. mcpn765_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
  89. {
  90. static char pci_irq_table[][4] =
  91. /*
  92. * PCI IDSEL/INTPIN->INTLINE
  93. * A B C D
  94. */
  95. {
  96. { 14, 0, 0, 0 }, /* IDSEL 11 - have to manually set */
  97. { 0, 0, 0, 0 }, /* IDSEL 12 - unused */
  98. { 0, 0, 0, 0 }, /* IDSEL 13 - unused */
  99. { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 0 */
  100. { 0, 0, 0, 0 }, /* IDSEL 15 - unused */
  101. { 25, 26, 27, 28 }, /* IDSEL 16 - PMC Slot 1 */
  102. { 28, 25, 26, 27 }, /* IDSEL 17 - PMC Slot 2 */
  103. { 0, 0, 0, 0 }, /* IDSEL 18 - PMC 2B Connector XXXX */
  104. { 29, 0, 0, 0 }, /* IDSEL 19 - Enet 1 */
  105. { 20, 0, 0, 0 }, /* IDSEL 20 - 21554 cPCI bridge */
  106. };
  107. const long min_idsel = 11, max_idsel = 20, irqs_per_slot = 4;
  108. return PCI_IRQ_TABLE_LOOKUP;
  109. }
  110. void __init
  111. mcpn765_set_VIA_IDE_legacy(void)
  112. {
  113. unsigned short vend, dev;
  114. early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend);
  115. early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev);
  116. if ((vend == PCI_VENDOR_ID_VIA) &&
  117. (dev == PCI_DEVICE_ID_VIA_82C586_1)) {
  118. unsigned char temp;
  119. /* put back original "standard" port base addresses */
  120. early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
  121. PCI_BASE_ADDRESS_0, 0x1f1);
  122. early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
  123. PCI_BASE_ADDRESS_1, 0x3f5);
  124. early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
  125. PCI_BASE_ADDRESS_2, 0x171);
  126. early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
  127. PCI_BASE_ADDRESS_3, 0x375);
  128. early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
  129. PCI_BASE_ADDRESS_4, 0xcc01);
  130. /* put into legacy mode */
  131. early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
  132. &temp);
  133. temp &= ~0x05;
  134. early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
  135. temp);
  136. }
  137. }
  138. void
  139. mcpn765_set_VIA_IDE_native(void)
  140. {
  141. unsigned short vend, dev;
  142. early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend);
  143. early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev);
  144. if ((vend == PCI_VENDOR_ID_VIA) &&
  145. (dev == PCI_DEVICE_ID_VIA_82C586_1)) {
  146. unsigned char temp;
  147. /* put into native mode */
  148. early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
  149. &temp);
  150. temp |= 0x05;
  151. early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
  152. temp);
  153. }
  154. }
  155. /*
  156. * Initialize the VIA 82c586b.
  157. */
  158. static void __init
  159. mcpn765_setup_via_82c586b(void)
  160. {
  161. struct pci_dev *dev;
  162. u_char c;
  163. if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
  164. PCI_DEVICE_ID_VIA_82C586_0,
  165. NULL)) == NULL) {
  166. printk("No VIA ISA bridge found\n");
  167. mcpn765_halt();
  168. /* NOTREACHED */
  169. }
  170. /*
  171. * If the firmware left the EISA 4d0/4d1 ports enabled, make sure
  172. * IRQ 14 is set for edge.
  173. */
  174. pci_read_config_byte(dev, 0x47, &c);
  175. if (c & (1<<5)) {
  176. c = inb(0x4d1);
  177. c &= ~(1<<6);
  178. outb(c, 0x4d1);
  179. }
  180. /* Disable PNP IRQ routing since we use the Hawk's MPIC */
  181. pci_write_config_dword(dev, 0x54, 0);
  182. pci_write_config_byte(dev, 0x58, 0);
  183. pci_dev_put(dev);
  184. if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
  185. PCI_DEVICE_ID_VIA_82C586_1,
  186. NULL)) == NULL) {
  187. printk("No VIA ISA bridge found\n");
  188. mcpn765_halt();
  189. /* NOTREACHED */
  190. }
  191. /*
  192. * PPCBug doesn't set the enable bits for the IDE device.
  193. * Turn them on now.
  194. */
  195. pci_read_config_byte(dev, 0x40, &c);
  196. c |= 0x03;
  197. pci_write_config_byte(dev, 0x40, c);
  198. pci_dev_put(dev);
  199. return;
  200. }
  201. void __init
  202. mcpn765_pcibios_fixup(void)
  203. {
  204. /* Do MCPN765 board specific initialization. */
  205. mcpn765_setup_via_82c586b();
  206. }
  207. void __init
  208. mcpn765_find_bridges(void)
  209. {
  210. struct pci_controller *hose;
  211. hose = pcibios_alloc_controller();
  212. if (!hose)
  213. return;
  214. hose->first_busno = 0;
  215. hose->last_busno = 0xff;
  216. hose->pci_mem_offset = MCPN765_PCI_PHY_MEM_OFFSET;
  217. pci_init_resource(&hose->io_resource,
  218. MCPN765_PCI_IO_START,
  219. MCPN765_PCI_IO_END,
  220. IORESOURCE_IO,
  221. "PCI host bridge");
  222. pci_init_resource(&hose->mem_resources[0],
  223. MCPN765_PCI_MEM_START,
  224. MCPN765_PCI_MEM_END,
  225. IORESOURCE_MEM,
  226. "PCI host bridge");
  227. hose->io_space.start = MCPN765_PCI_IO_START;
  228. hose->io_space.end = MCPN765_PCI_IO_END;
  229. hose->mem_space.start = MCPN765_PCI_MEM_START;
  230. hose->mem_space.end = MCPN765_PCI_MEM_END - HAWK_MPIC_SIZE;
  231. if (hawk_init(hose,
  232. MCPN765_HAWK_PPC_REG_BASE,
  233. MCPN765_PROC_PCI_MEM_START,
  234. MCPN765_PROC_PCI_MEM_END - HAWK_MPIC_SIZE,
  235. MCPN765_PROC_PCI_IO_START,
  236. MCPN765_PROC_PCI_IO_END,
  237. MCPN765_PCI_MEM_END - HAWK_MPIC_SIZE + 1) != 0) {
  238. printk("Could not initialize HAWK bridge\n");
  239. }
  240. /* VIA IDE BAR decoders are only 16-bits wide. PCI Auto Config
  241. * will reassign the bars outside of 16-bit I/O space, which will
  242. * "break" things. To prevent this, we'll set the IDE chip into
  243. * legacy mode and seed the bars with their legacy addresses (in 16-bit
  244. * I/O space). The Auto Config code will skip the IDE contoller in
  245. * legacy mode, so our bar values will stick.
  246. */
  247. mcpn765_set_VIA_IDE_legacy();
  248. hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
  249. /* Now that we've got 16-bit addresses in the bars, we can switch the
  250. * IDE controller back into native mode so we can do "modern" resource
  251. * and interrupt management.
  252. */
  253. mcpn765_set_VIA_IDE_native();
  254. ppc_md.pcibios_fixup = mcpn765_pcibios_fixup;
  255. ppc_md.pcibios_fixup_bus = NULL;
  256. ppc_md.pci_swizzle = common_swizzle;
  257. ppc_md.pci_map_irq = mcpn765_map_irq;
  258. return;
  259. }
  260. static void __init
  261. mcpn765_setup_arch(void)
  262. {
  263. struct pci_controller *hose;
  264. if ( ppc_md.progress )
  265. ppc_md.progress("mcpn765_setup_arch: enter", 0);
  266. loops_per_jiffy = 50000000 / HZ;
  267. #ifdef CONFIG_BLK_DEV_INITRD
  268. if (initrd_start)
  269. ROOT_DEV = Root_RAM0;
  270. else
  271. #endif
  272. #ifdef CONFIG_ROOT_NFS
  273. ROOT_DEV = Root_NFS;
  274. #else
  275. ROOT_DEV = Root_SDA2;
  276. #endif
  277. if ( ppc_md.progress )
  278. ppc_md.progress("mcpn765_setup_arch: find_bridges", 0);
  279. /* Lookup PCI host bridges */
  280. mcpn765_find_bridges();
  281. hose = pci_bus_to_hose(0);
  282. isa_io_base = (ulong)hose->io_base_virt;
  283. TODC_INIT(TODC_TYPE_MK48T37,
  284. (MCPN765_PHYS_NVRAM_AS0 - isa_io_base),
  285. (MCPN765_PHYS_NVRAM_AS1 - isa_io_base),
  286. (MCPN765_PHYS_NVRAM_DATA - isa_io_base),
  287. 8);
  288. OpenPIC_InitSenses = mcpn765_openpic_initsenses;
  289. OpenPIC_NumInitSenses = sizeof(mcpn765_openpic_initsenses);
  290. printk("Motorola MCG MCPN765 cPCI Non-System Board\n");
  291. printk("MCPN765 port (MontaVista Software, Inc. (source@mvista.com))\n");
  292. if ( ppc_md.progress )
  293. ppc_md.progress("mcpn765_setup_arch: exit", 0);
  294. return;
  295. }
  296. static void __init
  297. mcpn765_init2(void)
  298. {
  299. request_region(0x00,0x20,"dma1");
  300. request_region(0x20,0x20,"pic1");
  301. request_region(0x40,0x20,"timer");
  302. request_region(0x80,0x10,"dma page reg");
  303. request_region(0xa0,0x20,"pic2");
  304. request_region(0xc0,0x20,"dma2");
  305. return;
  306. }
  307. /*
  308. * Interrupt setup and service.
  309. * Have MPIC on HAWK and cascaded 8259s on VIA 82586 cascaded to MPIC.
  310. */
  311. static void __init
  312. mcpn765_init_IRQ(void)
  313. {
  314. int i;
  315. if ( ppc_md.progress )
  316. ppc_md.progress("init_irq: enter", 0);
  317. openpic_init(NUM_8259_INTERRUPTS);
  318. openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
  319. i8259_irq);
  320. for(i=0; i < NUM_8259_INTERRUPTS; i++)
  321. irq_desc[i].handler = &i8259_pic;
  322. i8259_init(0);
  323. if ( ppc_md.progress )
  324. ppc_md.progress("init_irq: exit", 0);
  325. return;
  326. }
  327. static u32
  328. mcpn765_irq_canonicalize(u32 irq)
  329. {
  330. if (irq == 2)
  331. return 9;
  332. else
  333. return irq;
  334. }
  335. static unsigned long __init
  336. mcpn765_find_end_of_memory(void)
  337. {
  338. return hawk_get_mem_size(MCPN765_HAWK_SMC_BASE);
  339. }
  340. static void __init
  341. mcpn765_map_io(void)
  342. {
  343. io_block_mapping(0xfe800000, 0xfe800000, 0x00800000, _PAGE_IO);
  344. }
  345. static void
  346. mcpn765_reset_board(void)
  347. {
  348. local_irq_disable();
  349. /* set VIA IDE controller into native mode */
  350. mcpn765_set_VIA_IDE_native();
  351. /* Set exception prefix high - to the firmware */
  352. _nmask_and_or_msr(0, MSR_IP);
  353. out_8((u_char *)MCPN765_BOARD_MODRST_REG, 0x01);
  354. return;
  355. }
  356. static void
  357. mcpn765_restart(char *cmd)
  358. {
  359. volatile ulong i = 10000000;
  360. mcpn765_reset_board();
  361. while (i-- > 0);
  362. panic("restart failed\n");
  363. }
  364. static void
  365. mcpn765_power_off(void)
  366. {
  367. mcpn765_halt();
  368. /* NOTREACHED */
  369. }
  370. static void
  371. mcpn765_halt(void)
  372. {
  373. local_irq_disable();
  374. while (1);
  375. /* NOTREACHED */
  376. }
  377. static int
  378. mcpn765_show_cpuinfo(struct seq_file *m)
  379. {
  380. seq_printf(m, "vendor\t\t: Motorola MCG\n");
  381. seq_printf(m, "machine\t\t: MCPN765\n");
  382. return 0;
  383. }
  384. /*
  385. * Set BAT 3 to map 0xf0000000 to end of physical memory space.
  386. */
  387. static __inline__ void
  388. mcpn765_set_bat(void)
  389. {
  390. mb();
  391. mtspr(SPRN_DBAT1U, 0xfe8000fe);
  392. mtspr(SPRN_DBAT1L, 0xfe80002a);
  393. mb();
  394. }
  395. void __init
  396. platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
  397. unsigned long r6, unsigned long r7)
  398. {
  399. parse_bootinfo(find_bootinfo());
  400. /* Map in board regs, etc. */
  401. mcpn765_set_bat();
  402. isa_mem_base = MCPN765_ISA_MEM_BASE;
  403. pci_dram_offset = MCPN765_PCI_DRAM_OFFSET;
  404. ISA_DMA_THRESHOLD = 0x00ffffff;
  405. DMA_MODE_READ = 0x44;
  406. DMA_MODE_WRITE = 0x48;
  407. ppc_md.setup_arch = mcpn765_setup_arch;
  408. ppc_md.show_cpuinfo = mcpn765_show_cpuinfo;
  409. ppc_md.irq_canonicalize = mcpn765_irq_canonicalize;
  410. ppc_md.init_IRQ = mcpn765_init_IRQ;
  411. ppc_md.get_irq = openpic_get_irq;
  412. ppc_md.init = mcpn765_init2;
  413. ppc_md.restart = mcpn765_restart;
  414. ppc_md.power_off = mcpn765_power_off;
  415. ppc_md.halt = mcpn765_halt;
  416. ppc_md.find_end_of_memory = mcpn765_find_end_of_memory;
  417. ppc_md.setup_io_mappings = mcpn765_map_io;
  418. ppc_md.time_init = todc_time_init;
  419. ppc_md.set_rtc_time = todc_set_rtc_time;
  420. ppc_md.get_rtc_time = todc_get_rtc_time;
  421. ppc_md.calibrate_decr = todc_calibrate_decr;
  422. ppc_md.nvram_read_val = todc_m48txx_read_val;
  423. ppc_md.nvram_write_val = todc_m48txx_write_val;
  424. ppc_md.heartbeat = NULL;
  425. ppc_md.heartbeat_reset = 0;
  426. ppc_md.heartbeat_count = 0;
  427. #ifdef CONFIG_SERIAL_TEXT_DEBUG
  428. ppc_md.progress = gen550_progress;
  429. #endif
  430. #ifdef CONFIG_KGDB
  431. ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
  432. #endif
  433. return;
  434. }