| 
					
				 | 
			
			
				@@ -960,3 +960,119 @@ marvel_agp_configure(alpha_agp_info *agp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * The agpgart_be code has not programmed the card yet, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * so we can still tweak mode here. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	agp_pll = io7->csrs->POx_RST[IO7_AGP_PORT].csr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch(IO7_PLL_RNGB(agp_pll)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case 0x4:				/* 2x only */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/*  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * The PLL is only programmed for 2x, so adjust the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * rate to 2x, if necessary. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (agp->mode.bits.rate != 2)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			new_rate = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case 0x6:				/* 1x / 4x */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * The PLL is programmed for 1x or 4x.  Don't go faster 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * than requested, so if the requested rate is 2x, use 1x. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (agp->mode.bits.rate == 2)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			new_rate = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	default:				/* ??????? */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * Don't know what this PLL setting is, take the requested 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * rate, but warn the user. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		printk("%s: unknown PLL setting RNGB=%lx (PLL6_CTL=%016lx)\n", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		       __func__, IO7_PLL_RNGB(agp_pll), agp_pll); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * Set the new rate, if necessary. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (new_rate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		printk("Requested AGP Rate %dX not compatible " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		       "with PLL setting - using %dX\n", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		       agp->mode.bits.rate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		       new_rate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		agp->mode.bits.rate = new_rate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	printk("Enabling AGP on hose %d: %dX%s RQ %d\n",  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	       agp->hose->index, agp->mode.bits.rate,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	       agp->mode.bits.sba ? " - SBA" : "", agp->mode.bits.rq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	csrs->AGP_CMD.csr = agp->mode.lw; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static int  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+marvel_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *mem) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct marvel_agp_aperture *aper = agp->aperture.sysdata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return iommu_bind(aper->arena, aper->pg_start + pg_start,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			  mem->page_count, mem->pages); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static int  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+marvel_agp_unbind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *mem) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct marvel_agp_aperture *aper = agp->aperture.sysdata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return iommu_unbind(aper->arena, aper->pg_start + pg_start, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			    mem->page_count); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static unsigned long 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+marvel_agp_translate(alpha_agp_info *agp, dma_addr_t addr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct marvel_agp_aperture *aper = agp->aperture.sysdata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unsigned long baddr = addr - aper->arena->dma_base; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unsigned long pte; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (addr < agp->aperture.bus_base || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	    addr >= agp->aperture.bus_base + agp->aperture.size) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		printk("%s: addr out of range\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	pte = aper->arena->ptes[baddr >> PAGE_SHIFT]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!(pte & 1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		printk("%s: pte not valid\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return (pte >> 1) << PAGE_SHIFT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct alpha_agp_ops marvel_agp_ops = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.setup		= marvel_agp_setup, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.cleanup	= marvel_agp_cleanup, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.configure	= marvel_agp_configure, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.bind		= marvel_agp_bind_memory, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.unbind		= marvel_agp_unbind_memory, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.translate	= marvel_agp_translate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+alpha_agp_info * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+marvel_agp_info(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct pci_controller *hose; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	io7_ioport_csrs *csrs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	alpha_agp_info *agp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct io7 *io7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * Find the first IO7 with an AGP card. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * FIXME -- there should be a better way (we want to be able to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * specify and what if the agp card is not video???) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	hose = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct pci_controller *h; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		vuip addr; 
			 |