|  | @@ -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;
 |