📄 core_titan.c
字号:
printk("%s: DChip registers:\n", __FUNCTION__); printk("%s: CSR_DSC 0x%lx\n", __FUNCTION__, TITAN_dchip->dsc.csr); printk("%s: CSR_STR 0x%lx\n", __FUNCTION__, TITAN_dchip->str.csr); printk("%s: CSR_DREV 0x%lx\n", __FUNCTION__, TITAN_dchip->drev.csr);#endif boot_cpuid = __hard_smp_processor_id(); /* With multiple PCI busses, we play with I/O as physical addrs. */ ioport_resource.end = ~0UL; /* PCI DMA Direct Mapping is 1GB at 2GB. */ __direct_map_base = 0x80000000; __direct_map_size = 0x40000000; /* Init the PA chip(s). */ titan_init_pachips(TITAN_pachip0, TITAN_pachip1); /* Check for graphic console location (if any). */ titan_init_vga_hose();}static voidtitan_kill_one_pachip_port(titan_pachip_port *port, int index){ port->wsba[0].csr = saved_config[index].wsba[0]; port->wsm[0].csr = saved_config[index].wsm[0]; port->tba[0].csr = saved_config[index].tba[0]; port->wsba[1].csr = saved_config[index].wsba[1]; port->wsm[1].csr = saved_config[index].wsm[1]; port->tba[1].csr = saved_config[index].tba[1]; port->wsba[2].csr = saved_config[index].wsba[2]; port->wsm[2].csr = saved_config[index].wsm[2]; port->tba[2].csr = saved_config[index].tba[2]; port->wsba[3].csr = saved_config[index].wsba[3]; port->wsm[3].csr = saved_config[index].wsm[3]; port->tba[3].csr = saved_config[index].tba[3];}static voidtitan_kill_pachips(titan_pachip *pachip0, titan_pachip *pachip1){ int pchip1_present = TITAN_cchip->csc.csr & 1L<<14; if (pchip1_present) { titan_kill_one_pachip_port(&pachip1->g_port, 1); titan_kill_one_pachip_port(&pachip1->a_port, 3); } titan_kill_one_pachip_port(&pachip0->g_port, 0); titan_kill_one_pachip_port(&pachip0->a_port, 2);}voidtitan_kill_arch(int mode){ titan_kill_pachips(TITAN_pachip0, TITAN_pachip1);}/* * IO map support. */unsigned longtitan_ioremap(unsigned long addr, unsigned long size){ int h = (addr & TITAN_HOSE_MASK) >> TITAN_HOSE_SHIFT; unsigned long baddr = addr & ~TITAN_HOSE_MASK; unsigned long last = baddr + size - 1; struct pci_controller *hose; struct vm_struct *area; unsigned long vaddr; unsigned long *ptes; unsigned long pfn; /* * Adjust the addr. */ #ifdef CONFIG_VGA_HOSE if (pci_vga_hose && __titan_is_mem_vga(addr)) { h = pci_vga_hose->index; addr += pci_vga_hose->mem_space->start; }#endif /* * Find the hose. */ for (hose = hose_head; hose; hose = hose->next) if (hose->index == h) break; if (!hose) return (unsigned long)NULL; /* * Is it direct-mapped? */ if ((baddr >= __direct_map_base) && ((baddr + size - 1) < __direct_map_base + __direct_map_size)) return addr - __direct_map_base + TITAN_MEM_BIAS; /* * Check the scatter-gather arena. */ if (hose->sg_pci && baddr >= (unsigned long)hose->sg_pci->dma_base && last < (unsigned long)hose->sg_pci->dma_base + hose->sg_pci->size){ /* * Adjust the limits (mappings must be page aligned) */ baddr -= hose->sg_pci->dma_base; last -= hose->sg_pci->dma_base; baddr &= PAGE_MASK; size = PAGE_ALIGN(last) - baddr; /* * Map it */ area = get_vm_area(size, VM_IOREMAP); if (!area) return (unsigned long)NULL; ptes = hose->sg_pci->ptes; for (vaddr = (unsigned long)area->addr; baddr <= last; baddr += PAGE_SIZE, vaddr += PAGE_SIZE) { pfn = ptes[baddr >> PAGE_SHIFT]; if (!(pfn & 1)) { printk("ioremap failed... pte not valid...\n"); vfree(area->addr); return (unsigned long)NULL; } pfn >>= 1; /* make it a true pfn */ if (__alpha_remap_area_pages(vaddr, pfn << PAGE_SHIFT, PAGE_SIZE, 0)) { printk("FAILED to map...\n"); vfree(area->addr); return (unsigned long)NULL; } } flush_tlb_all(); vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK); return vaddr; } /* * Not found - assume legacy ioremap. */ return addr + TITAN_MEM_BIAS;}voidtitan_iounmap(unsigned long addr){ if (((long)addr >> 41) == -2) return; /* kseg map, nothing to do */ if (addr) vfree((void *)(PAGE_MASK & addr)); }#ifndef CONFIG_ALPHA_GENERICEXPORT_SYMBOL(titan_ioremap);EXPORT_SYMBOL(titan_iounmap);#endif/* * AGP GART Support. */#include <linux/agp_backend.h>#include <asm/agp_backend.h>#include <linux/slab.h>#include <linux/delay.h>struct titan_agp_aperture { struct pci_iommu_arena *arena; long pg_start; long pg_count;};static inttitan_agp_setup(alpha_agp_info *agp){ struct titan_agp_aperture *aper; if (!alpha_agpgart_size) return -ENOMEM; aper = kmalloc(sizeof(struct titan_agp_aperture), GFP_KERNEL); if (aper == NULL) return -ENOMEM; aper->arena = agp->hose->sg_pci; aper->pg_count = alpha_agpgart_size / PAGE_SIZE; aper->pg_start = iommu_reserve(aper->arena, aper->pg_count, aper->pg_count - 1); if (aper->pg_start < 0) { printk(KERN_ERR "Failed to reserve AGP memory\n"); kfree(aper); return -ENOMEM; } agp->aperture.bus_base = aper->arena->dma_base + aper->pg_start * PAGE_SIZE; agp->aperture.size = aper->pg_count * PAGE_SIZE; agp->aperture.sysdata = aper; return 0;}static voidtitan_agp_cleanup(alpha_agp_info *agp){ struct titan_agp_aperture *aper = agp->aperture.sysdata; int status; status = iommu_release(aper->arena, aper->pg_start, aper->pg_count); if (status == -EBUSY) { printk(KERN_WARNING "Attempted to release bound AGP memory - unbinding\n"); iommu_unbind(aper->arena, aper->pg_start, aper->pg_count); status = iommu_release(aper->arena, aper->pg_start, aper->pg_count); } if (status < 0) printk(KERN_ERR "Failed to release AGP memory\n"); kfree(aper); kfree(agp);}static inttitan_agp_configure(alpha_agp_info *agp){ union TPAchipPCTL pctl; titan_pachip_port *port = agp->private; pctl.pctl_q_whole = port->pctl.csr; /* Side-Band Addressing? */ pctl.pctl_r_bits.apctl_v_agp_sba_en = agp->mode.bits.sba; /* AGP Rate? */ pctl.pctl_r_bits.apctl_v_agp_rate = 0; /* 1x */ if (agp->mode.bits.rate & 2) pctl.pctl_r_bits.apctl_v_agp_rate = 1; /* 2x */#if 0 if (agp->mode.bits.rate & 4) pctl.pctl_r_bits.apctl_v_agp_rate = 2; /* 4x */#endif /* RQ Depth? */ pctl.pctl_r_bits.apctl_v_agp_hp_rd = 2; pctl.pctl_r_bits.apctl_v_agp_lp_rd = 7; /* * AGP Enable. */ pctl.pctl_r_bits.apctl_v_agp_en = agp->mode.bits.enable; /* Tell the user. */ printk("Enabling AGP: %dX%s\n", 1 << pctl.pctl_r_bits.apctl_v_agp_rate, pctl.pctl_r_bits.apctl_v_agp_sba_en ? " - SBA" : ""); /* Write it. */ port->pctl.csr = pctl.pctl_q_whole; /* And wait at least 5000 66MHz cycles (per Titan spec). */ udelay(100); return 0;}static int titan_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *mem){ struct titan_agp_aperture *aper = agp->aperture.sysdata; return iommu_bind(aper->arena, aper->pg_start + pg_start, mem->page_count, mem->memory);}static int titan_agp_unbind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *mem){ struct titan_agp_aperture *aper = agp->aperture.sysdata; return iommu_unbind(aper->arena, aper->pg_start + pg_start, mem->page_count);}static unsigned longtitan_agp_translate(alpha_agp_info *agp, dma_addr_t addr){ struct titan_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", __FUNCTION__); return -EINVAL; } pte = aper->arena->ptes[baddr >> PAGE_SHIFT]; if (!(pte & 1)) { printk("%s: pte not valid\n", __FUNCTION__); return -EINVAL; } return (pte >> 1) << PAGE_SHIFT;}struct alpha_agp_ops titan_agp_ops ={ .setup = titan_agp_setup, .cleanup = titan_agp_cleanup, .configure = titan_agp_configure, .bind = titan_agp_bind_memory, .unbind = titan_agp_unbind_memory, .translate = titan_agp_translate};alpha_agp_info *titan_agp_info(void){ alpha_agp_info *agp; struct pci_controller *hose; titan_pachip_port *port; int hosenum = -1; union TPAchipPCTL pctl; /* * Find the AGP port. */ port = &TITAN_pachip0->a_port; if (titan_query_agp(port)) hosenum = 2; if (hosenum < 0 && titan_query_agp(port = &TITAN_pachip1->a_port)) hosenum = 3; /* * Find the hose the port is on. */ for (hose = hose_head; hose; hose = hose->next) if (hose->index == hosenum) break; if (!hose || !hose->sg_pci) return NULL; /* * Allocate the info structure. */ agp = kmalloc(sizeof(*agp), GFP_KERNEL); /* * Fill it in. */ agp->hose = hose; agp->private = port; agp->ops = &titan_agp_ops; /* * Aperture - not configured until ops.setup(). * * FIXME - should we go ahead and allocate it here? */ agp->aperture.bus_base = 0; agp->aperture.size = 0; agp->aperture.sysdata = NULL; /* * Capabilities. */ agp->capability.lw = 0; agp->capability.bits.rate = 3; /* 2x, 1x */ agp->capability.bits.sba = 1; agp->capability.bits.rq = 7; /* 8 - 1 */ /* * Mode. */ pctl.pctl_q_whole = port->pctl.csr; agp->mode.lw = 0; agp->mode.bits.rate = 1 << pctl.pctl_r_bits.apctl_v_agp_rate; agp->mode.bits.sba = pctl.pctl_r_bits.apctl_v_agp_sba_en; agp->mode.bits.rq = 7; /* RQ Depth? */ agp->mode.bits.enable = pctl.pctl_r_bits.apctl_v_agp_en; return agp;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -