| 
					
				 | 
			
			
				@@ -660,3 +660,169 @@ do_init_arch(int is_pyxis) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	*(vip)CIA_IOC_CFG = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	/* Zero the HAEs.  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*(vip)CIA_IOC_HAE_MEM = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*(vip)CIA_IOC_HAE_IO = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* For PYXIS, we always use BWX bus and i/o accesses.  To that end, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   make sure they're enabled on the controller.  At the same time, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   enable the monster window.  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (is_pyxis) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		temp = *(vip)CIA_IOC_CIA_CNFG; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		temp |= CIA_CNFG_IOA_BWEN | CIA_CNFG_PCI_MWEN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		*(vip)CIA_IOC_CIA_CNFG = temp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* Synchronize with all previous changes.  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	mb(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*(vip)CIA_IOC_CIA_REV; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * Create our single hose. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	pci_isa_hose = hose = alloc_pci_controller(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	hose->io_space = &ioport_resource; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	hose->mem_space = &iomem_resource; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	hose->index = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (! is_pyxis) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct resource *hae_mem = alloc_resource(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hose->mem_space = hae_mem; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hae_mem->start = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hae_mem->end = CIA_MEM_R1_MASK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hae_mem->name = pci_hae0_name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hae_mem->flags = IORESOURCE_MEM; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (request_resource(&iomem_resource, hae_mem) < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			printk(KERN_ERR "Failed to request HAE_MEM\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hose->sparse_mem_base = CIA_SPARSE_MEM - IDENT_ADDR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hose->dense_mem_base = CIA_DENSE_MEM - IDENT_ADDR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hose->sparse_io_base = CIA_IO - IDENT_ADDR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hose->dense_io_base = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hose->sparse_mem_base = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hose->dense_mem_base = CIA_BW_MEM - IDENT_ADDR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hose->sparse_io_base = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hose->dense_io_base = CIA_BW_IO - IDENT_ADDR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * Set up the PCI to main memory translation windows. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * Window 0 is S/G 8MB at 8MB (for isa) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * Window 1 is S/G 1MB at 768MB (for tbia) (unused for CIA rev 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * Window 2 is direct access 2GB at 2GB 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * Window 3 is DAC access 4GB at 8GB (or S/G for tbia if CIA rev 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * ??? NetBSD hints that page tables must be aligned to 32K, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * possibly due to a hardware bug.  This is over-aligned 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * from the 8K alignment one would expect for an 8MB window.  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * No description of what revisions affected. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	hose->sg_pci = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 32768); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__direct_map_base = 0x80000000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__direct_map_size = 0x80000000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*(vip)CIA_IOC_PCI_W0_BASE = hose->sg_isa->dma_base | 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*(vip)CIA_IOC_PCI_W0_MASK = (hose->sg_isa->size - 1) & 0xfff00000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*(vip)CIA_IOC_PCI_T0_BASE = virt_to_phys(hose->sg_isa->ptes) >> 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*(vip)CIA_IOC_PCI_W2_BASE = __direct_map_base | 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*(vip)CIA_IOC_PCI_W2_MASK = (__direct_map_size - 1) & 0xfff00000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*(vip)CIA_IOC_PCI_T2_BASE = 0 >> 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* On PYXIS we have the monster window, selected by bit 40, so 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   there is no need for window3 to be enabled. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   On CIA, we don't have true arbitrary addressing -- bits <39:32> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   are compared against W_DAC.  We can, however, directly map 4GB, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   which is better than before.  However, due to assumptions made 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   elsewhere, we should not claim that we support DAC unless that 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   4GB covers all of physical memory. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   On CIA rev 1, apparently W1 and W2 can't be used for SG.  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   At least, there are reports that it doesn't work for Alcor.  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   In that case, we have no choice but to use W3 for the TBIA  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   workaround, which means we can't use DAC at all. */  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	tbia_window = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (is_pyxis) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		*(vip)CIA_IOC_PCI_W3_BASE = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else if (cia_rev == 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		*(vip)CIA_IOC_PCI_W1_BASE = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		tbia_window = 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else if (max_low_pfn > (0x100000000UL >> PAGE_SHIFT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		*(vip)CIA_IOC_PCI_W3_BASE = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		*(vip)CIA_IOC_PCI_W3_BASE = 0x00000000 | 1 | 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		*(vip)CIA_IOC_PCI_W3_MASK = 0xfff00000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		*(vip)CIA_IOC_PCI_T3_BASE = 0 >> 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		alpha_mv.pci_dac_offset = 0x200000000UL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		*(vip)CIA_IOC_PCI_W_DAC = alpha_mv.pci_dac_offset >> 32; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* Prepare workaround for apparently broken tbia. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	cia_prepare_tbia_workaround(tbia_window); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void __init 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+cia_init_arch(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	do_init_arch(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void __init 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+pyxis_init_arch(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* On pyxis machines we can precisely calculate the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   CPU clock frequency using pyxis real time counter. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   It's especially useful for SX164 with broken RTC. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   Both CPU and chipset are driven by the single 16.666M 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   or 16.667M crystal oscillator. PYXIS_RT_COUNT clock is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	   66.66 MHz. -ink */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unsigned int cc0, cc1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unsigned long pyxis_cc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__asm__ __volatile__ ("rpcc %0" : "=r"(cc0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	pyxis_cc = *(vulp)PYXIS_RT_COUNT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	do { } while(*(vulp)PYXIS_RT_COUNT - pyxis_cc < 4096); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__asm__ __volatile__ ("rpcc %0" : "=r"(cc1)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	cc1 -= cc0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	hwrpb->cycle_freq = ((cc1 >> 11) * 100000000UL) / 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	hwrpb_update_checksum(hwrpb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	do_init_arch(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+cia_kill_arch(int mode) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (alpha_using_srm) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		cia_restore_srm_settings(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void __init 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+cia_init_pci(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* Must delay this from init_arch, as we need machine checks.  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	verify_tb_operation(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	common_init_pci(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+cia_pci_clr_err(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int jd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	jd = *(vip)CIA_IOC_CIA_ERR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*(vip)CIA_IOC_CIA_ERR = jd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	mb(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*(vip)CIA_IOC_CIA_ERR;		/* re-read to force write.  */ 
			 |