diff options
Diffstat (limited to 'bsd-core')
| -rw-r--r-- | bsd-core/ati_pcigart.c | 91 | 
1 files changed, 73 insertions, 18 deletions
diff --git a/bsd-core/ati_pcigart.c b/bsd-core/ati_pcigart.c index c4453ed5..5feeeba8 100644 --- a/bsd-core/ati_pcigart.c +++ b/bsd-core/ati_pcigart.c @@ -39,31 +39,86 @@  #define ATI_PCIE_WRITE 0x4  #define ATI_PCIE_READ 0x8 -static int drm_ati_alloc_pcigart_table(struct drm_device *dev, -				       struct drm_ati_pcigart_info *gart_info) +static void +drm_ati_alloc_pcigart_table_cb(void *arg, bus_dma_segment_t *segs, +			       int nsegs, int error)  { -	drm_dma_handle_t *dmah; +	struct drm_dma_handle *dmah = arg; + +	if (error != 0) +		return; + +	KASSERT(nsegs == 1, +	    ("drm_ati_alloc_pcigart_table_cb: bad dma segment count")); + +	dmah->busaddr = segs[0].ds_addr; +} + +static int +drm_ati_alloc_pcigart_table(struct drm_device *dev, +			    struct drm_ati_pcigart_info *gart_info) +{ +	struct drm_dma_handle *dmah; +	int flags, ret; + +	dmah = malloc(sizeof(struct drm_dma_handle), M_DRM, M_ZERO | M_NOWAIT); +	if (dmah == NULL) +		return ENOMEM;  	DRM_UNLOCK(); -	dmah = drm_pci_alloc(dev, gart_info->table_size, PAGE_SIZE, -	    gart_info->table_mask); +	ret = bus_dma_tag_create(NULL, PAGE_SIZE, 0, /* tag, align, boundary */ +	    gart_info->table_mask, BUS_SPACE_MAXADDR, /* lowaddr, highaddr */ +	    NULL, NULL, /* filtfunc, filtfuncargs */ +	    gart_info->table_size, 1, /* maxsize, nsegs */ +	    gart_info->table_size, /* maxsegsize */ +	    BUS_DMA_ALLOCNOW, NULL, NULL, /* flags, lockfunc, lockfuncargs */ +	    &dmah->tag); +	if (ret != 0) { +		free(dmah, M_DRM); +		return ENOMEM; +	} + +	flags = BUS_DMA_NOWAIT | BUS_DMA_ZERO; +	if (gart_info->gart_reg_if == DRM_ATI_GART_IGP) +	    flags |= BUS_DMA_NOCACHE; +	 +	ret = bus_dmamem_alloc(dmah->tag, &dmah->vaddr, flags, &dmah->map); +	if (ret != 0) { +		bus_dma_tag_destroy(dmah->tag); +		free(dmah, M_DRM); +		return ENOMEM; +	}  	DRM_LOCK(); -	if (dmah == NULL) + +	ret = bus_dmamap_load(dmah->tag, dmah->map, dmah->vaddr, +	    gart_info->table_size, drm_ati_alloc_pcigart_table_cb, dmah, 0); +	if (ret != 0) { +		bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map); +		bus_dma_tag_destroy(dmah->tag); +		free(dmah, M_DRM);  		return ENOMEM; +	}  	dev->sg->dmah = dmah;  	return 0;  } -static void drm_ati_free_pcigart_table(struct drm_device *dev, -				       struct drm_ati_pcigart_info *gart_info) +static void +drm_ati_free_pcigart_table(struct drm_device *dev, +			   struct drm_ati_pcigart_info *gart_info)  { -	drm_pci_free(dev, dev->sg->dmah); +	struct drm_dma_handle *dmah = dev->sg->dmah; + +	bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map); +	bus_dma_tag_destroy(dmah->tag); +	free(dmah, M_DRM);  	dev->sg->dmah = NULL;  } -int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) +int +drm_ati_pcigart_cleanup(struct drm_device *dev, +			struct drm_ati_pcigart_info *gart_info)  {  	/* we need to support large memory configurations */  	if (dev->sg == NULL) { @@ -82,17 +137,17 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info  	return 1;  } -int drm_ati_pcigart_init(struct drm_device *dev, -			 struct drm_ati_pcigart_info *gart_info) +int +drm_ati_pcigart_init(struct drm_device *dev, +		     struct drm_ati_pcigart_info *gart_info)  { -  	void *address = NULL;  	unsigned long pages;  	u32 *pci_gart, page_base;  	dma_addr_t bus_address = 0; +	dma_addr_t entry_addr;  	int i, j, ret = 0;  	int max_pages; -	dma_addr_t entry_addr;  	/* we need to support large memory configurations */  	if (dev->sg == NULL) { @@ -134,12 +189,14 @@ int drm_ati_pcigart_init(struct drm_device *dev,  			page_base = (u32) entry_addr & ATI_PCIGART_PAGE_MASK;  			switch(gart_info->gart_reg_if) {  			case DRM_ATI_GART_IGP: -				page_base |= (upper_32_bits(entry_addr) & 0xff) << 4; +				page_base |= +				    (upper_32_bits(entry_addr) & 0xff) << 4;  				page_base |= 0xc;  				break;  			case DRM_ATI_GART_PCIE:  				page_base >>= 8; -				page_base |= (upper_32_bits(entry_addr) & 0xff) << 24; +				page_base |= +				    (upper_32_bits(entry_addr) & 0xff) << 24;  				page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE;  				break;  			default: @@ -152,8 +209,6 @@ int drm_ati_pcigart_init(struct drm_device *dev,  		}  	} -	DRM_MEMORYBARRIER(); -  	ret = 1;      done:  | 
