| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * MPC86xx HPCN board specific routines | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Recode: ZHANG WEI <wei.zhang@freescale.com> | 
					
						
							|  |  |  |  * Initial author: Xianghua Xiao <x.xiao@freescale.com> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright 2006 Freescale Semiconductor Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute  it and/or modify it | 
					
						
							|  |  |  |  * under  the terms of  the GNU General  Public License as published by the | 
					
						
							|  |  |  |  * Free Software Foundation;  either version 2 of the  License, or (at your | 
					
						
							|  |  |  |  * option) any later version. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/stddef.h>
 | 
					
						
							|  |  |  | #include <linux/kernel.h>
 | 
					
						
							|  |  |  | #include <linux/pci.h>
 | 
					
						
							|  |  |  | #include <linux/kdev_t.h>
 | 
					
						
							|  |  |  | #include <linux/delay.h>
 | 
					
						
							|  |  |  | #include <linux/seq_file.h>
 | 
					
						
							| 
									
										
										
										
											2008-01-22 13:17:45 -07:00
										 |  |  | #include <linux/of_platform.h>
 | 
					
						
							| 
									
										
										
										
											2009-05-14 17:42:29 -05:00
										 |  |  | #include <linux/lmb.h>
 | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <asm/system.h>
 | 
					
						
							|  |  |  | #include <asm/time.h>
 | 
					
						
							|  |  |  | #include <asm/machdep.h>
 | 
					
						
							|  |  |  | #include <asm/pci-bridge.h>
 | 
					
						
							|  |  |  | #include <asm/prom.h>
 | 
					
						
							|  |  |  | #include <mm/mmu_decl.h>
 | 
					
						
							|  |  |  | #include <asm/udbg.h>
 | 
					
						
							| 
									
										
										
										
											2009-05-14 17:42:29 -05:00
										 |  |  | #include <asm/swiotlb.h>
 | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <asm/mpic.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-10 18:46:35 +08:00
										 |  |  | #include <sysdev/fsl_pci.h>
 | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | #include <sysdev/fsl_soc.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "mpc86xx.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-31 15:35:41 -05:00
										 |  |  | #undef DEBUG
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG
 | 
					
						
							|  |  |  | #define DBG(fmt...) do { printk(KERN_ERR fmt); } while(0)
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define DBG(fmt...) do { } while(0)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | #ifdef CONFIG_PCI
 | 
					
						
							| 
									
										
										
										
											2007-08-16 23:55:55 -05:00
										 |  |  | extern int uli_exclude_device(struct pci_controller *hose, | 
					
						
							|  |  |  | 				u_char bus, u_char devfn); | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-16 23:55:55 -05:00
										 |  |  | static int mpc86xx_exclude_device(struct pci_controller *hose, | 
					
						
							|  |  |  | 				   u_char bus, u_char devfn) | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-08-16 23:55:55 -05:00
										 |  |  | 	struct device_node* node;	 | 
					
						
							|  |  |  | 	struct resource rsrc; | 
					
						
							| 
									
										
										
										
											2006-06-28 00:37:45 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-10 14:33:21 +11:00
										 |  |  | 	node = hose->dn; | 
					
						
							| 
									
										
										
										
											2007-08-16 23:55:55 -05:00
										 |  |  | 	of_address_to_resource(node, 0, &rsrc); | 
					
						
							| 
									
										
										
										
											2006-06-28 00:37:45 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-16 23:55:55 -05:00
										 |  |  | 	if ((rsrc.start & 0xfffff) == 0x8000) { | 
					
						
							|  |  |  | 		return uli_exclude_device(hose, bus, devfn); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-06-28 00:37:45 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-16 23:55:55 -05:00
										 |  |  | 	return PCIBIOS_SUCCESSFUL; | 
					
						
							| 
									
										
										
										
											2006-06-28 00:37:45 -05:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | #endif /* CONFIG_PCI */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void __init | 
					
						
							|  |  |  | mpc86xx_hpcn_setup_arch(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-07-27 13:24:36 -05:00
										 |  |  | #ifdef CONFIG_PCI
 | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | 	struct device_node *np; | 
					
						
							| 
									
										
										
										
											2009-05-14 17:42:29 -05:00
										 |  |  | 	struct pci_controller *hose; | 
					
						
							| 
									
										
										
										
											2007-07-27 13:24:36 -05:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-05-14 17:42:29 -05:00
										 |  |  | 	dma_addr_t max = 0xffffffff; | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (ppc_md.progress) | 
					
						
							|  |  |  | 		ppc_md.progress("mpc86xx_hpcn_setup_arch()", 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_PCI
 | 
					
						
							| 
									
										
										
										
											2007-10-04 00:28:43 -05:00
										 |  |  | 	for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") { | 
					
						
							| 
									
										
										
										
											2007-07-10 18:46:35 +08:00
										 |  |  | 		struct resource rsrc; | 
					
						
							|  |  |  | 		of_address_to_resource(np, 0, &rsrc); | 
					
						
							|  |  |  | 		if ((rsrc.start & 0xfffff) == 0x8000) | 
					
						
							|  |  |  | 			fsl_add_bridge(np, 1); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			fsl_add_bridge(np, 0); | 
					
						
							| 
									
										
										
										
											2009-05-14 17:42:29 -05:00
										 |  |  | 		hose = pci_find_hose_for_OF_device(np); | 
					
						
							|  |  |  | 		max = min(max, hose->dma_window_base_cur + | 
					
						
							|  |  |  | 			  hose->dma_window_size); | 
					
						
							| 
									
										
										
										
											2007-07-10 18:46:35 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-10-04 00:28:43 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-16 23:55:55 -05:00
										 |  |  | 	ppc_md.pci_exclude_device = mpc86xx_exclude_device; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	printk("MPC86xx HPCN board from Freescale Semiconductor\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_SMP
 | 
					
						
							|  |  |  | 	mpc86xx_smp_init(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-05-14 17:42:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_SWIOTLB
 | 
					
						
							|  |  |  | 	if (lmb_end_of_DRAM() > max) { | 
					
						
							|  |  |  | 		ppc_swiotlb_enable = 1; | 
					
						
							| 
									
										
										
										
											2009-08-04 19:08:23 +00:00
										 |  |  | 		set_pci_dma_ops(&swiotlb_dma_ops); | 
					
						
							| 
									
										
										
										
											2009-08-04 19:08:22 +00:00
										 |  |  | 		ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | 
					
						
							| 
									
										
										
										
											2009-05-14 17:42:29 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-16 13:53:06 -04:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | mpc86xx_hpcn_show_cpuinfo(struct seq_file *m) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	uint svid = mfspr(SPRN_SVR); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	seq_printf(m, "SVR\t\t: 0x%x\n", svid); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Called very early, device-tree isn't unflattened | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int __init mpc86xx_hpcn_probe(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long root = of_get_flat_dt_root(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-16 13:53:06 -04:00
										 |  |  | 	if (of_flat_dt_is_compatible(root, "fsl,mpc8641hpcn")) | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | 		return 1;	/* Looks good */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-16 13:53:07 -04:00
										 |  |  | 	/* Be nice and don't give silent boot death.  Delete this in 2.6.27 */ | 
					
						
							|  |  |  | 	if (of_flat_dt_is_compatible(root, "mpc86xx")) { | 
					
						
							|  |  |  | 		pr_warning("WARNING: your dts/dtb is old. You must update before the next kernel release\n"); | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-16 13:53:06 -04:00
										 |  |  | static long __init | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | mpc86xx_time_init(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned int temp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Set the time base to zero */ | 
					
						
							|  |  |  | 	mtspr(SPRN_TBWL, 0); | 
					
						
							|  |  |  | 	mtspr(SPRN_TBWU, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	temp = mfspr(SPRN_HID0); | 
					
						
							|  |  |  | 	temp |= HID0_TBEN; | 
					
						
							|  |  |  | 	mtspr(SPRN_HID0, temp); | 
					
						
							|  |  |  | 	asm volatile("isync"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-22 13:17:45 -07:00
										 |  |  | static __initdata struct of_device_id of_bus_ids[] = { | 
					
						
							|  |  |  | 	{ .compatible = "simple-bus", }, | 
					
						
							| 
									
										
										
										
											2008-04-18 13:33:43 -07:00
										 |  |  | 	{ .compatible = "fsl,rapidio-delta", }, | 
					
						
							| 
									
										
										
										
											2009-03-19 21:01:51 +03:00
										 |  |  | 	{ .compatible = "gianfar", }, | 
					
						
							| 
									
										
										
										
											2008-01-22 13:17:45 -07:00
										 |  |  | 	{}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int __init declare_of_platform_devices(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	of_platform_bus_probe(NULL, of_bus_ids, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | machine_device_initcall(mpc86xx_hpcn, declare_of_platform_devices); | 
					
						
							| 
									
										
										
										
											2009-05-14 17:42:29 -05:00
										 |  |  | machine_arch_initcall(mpc86xx_hpcn, swiotlb_setup_bus_notifier); | 
					
						
							| 
									
										
										
										
											2008-01-22 13:17:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | define_machine(mpc86xx_hpcn) { | 
					
						
							|  |  |  | 	.name			= "MPC86xx HPCN", | 
					
						
							|  |  |  | 	.probe			= mpc86xx_hpcn_probe, | 
					
						
							|  |  |  | 	.setup_arch		= mpc86xx_hpcn_setup_arch, | 
					
						
							| 
									
										
										
										
											2008-07-02 11:46:20 -05:00
										 |  |  | 	.init_IRQ		= mpc86xx_init_irq, | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | 	.show_cpuinfo		= mpc86xx_hpcn_show_cpuinfo, | 
					
						
							|  |  |  | 	.get_irq		= mpic_get_irq, | 
					
						
							| 
									
										
										
										
											2007-10-04 01:04:57 -05:00
										 |  |  | 	.restart		= fsl_rstcr_restart, | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | 	.time_init		= mpc86xx_time_init, | 
					
						
							|  |  |  | 	.calibrate_decr		= generic_calibrate_decr, | 
					
						
							|  |  |  | 	.progress		= udbg_progress, | 
					
						
							| 
									
										
										
										
											2007-09-10 14:30:33 -05:00
										 |  |  | #ifdef CONFIG_PCI
 | 
					
						
							| 
									
										
										
										
											2007-07-19 15:29:53 -05:00
										 |  |  | 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus, | 
					
						
							| 
									
										
										
										
											2007-09-10 14:30:33 -05:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-06-17 17:52:45 -05:00
										 |  |  | }; |