diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 149 | 
1 files changed, 147 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 7fcdbbbf297..8f8b8fa1435 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -68,6 +68,108 @@ MODULE_FIRMWARE(FIRMWARE_R520);   * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280   */ +int r100_reloc_pitch_offset(struct radeon_cs_parser *p, +			    struct radeon_cs_packet *pkt, +			    unsigned idx, +			    unsigned reg) +{ +	int r; +	u32 tile_flags = 0; +	u32 tmp; +	struct radeon_cs_reloc *reloc; +	u32 value; + +	r = r100_cs_packet_next_reloc(p, &reloc); +	if (r) { +		DRM_ERROR("No reloc for ib[%d]=0x%04X\n", +			  idx, reg); +		r100_cs_dump_packet(p, pkt); +		return r; +	} +	value = radeon_get_ib_value(p, idx); +	tmp = value & 0x003fffff; +	tmp += (((u32)reloc->lobj.gpu_offset) >> 10); + +	if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) +		tile_flags |= RADEON_DST_TILE_MACRO; +	if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { +		if (reg == RADEON_SRC_PITCH_OFFSET) { +			DRM_ERROR("Cannot src blit from microtiled surface\n"); +			r100_cs_dump_packet(p, pkt); +			return -EINVAL; +		} +		tile_flags |= RADEON_DST_TILE_MICRO; +	} + +	tmp |= tile_flags; +	p->ib->ptr[idx] = (value & 0x3fc00000) | tmp; +	return 0; +} + +int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, +			     struct radeon_cs_packet *pkt, +			     int idx) +{ +	unsigned c, i; +	struct radeon_cs_reloc *reloc; +	struct r100_cs_track *track; +	int r = 0; +	volatile uint32_t *ib; +	u32 idx_value; + +	ib = p->ib->ptr; +	track = (struct r100_cs_track *)p->track; +	c = radeon_get_ib_value(p, idx++) & 0x1F; +	if (c > 16) { +	    DRM_ERROR("Only 16 vertex buffers are allowed %d\n", +		      pkt->opcode); +	    r100_cs_dump_packet(p, pkt); +	    return -EINVAL; +	} +	track->num_arrays = c; +	for (i = 0; i < (c - 1); i+=2, idx+=3) { +		r = r100_cs_packet_next_reloc(p, &reloc); +		if (r) { +			DRM_ERROR("No reloc for packet3 %d\n", +				  pkt->opcode); +			r100_cs_dump_packet(p, pkt); +			return r; +		} +		idx_value = radeon_get_ib_value(p, idx); +		ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); + +		track->arrays[i + 0].esize = idx_value >> 8; +		track->arrays[i + 0].robj = reloc->robj; +		track->arrays[i + 0].esize &= 0x7F; +		r = r100_cs_packet_next_reloc(p, &reloc); +		if (r) { +			DRM_ERROR("No reloc for packet3 %d\n", +				  pkt->opcode); +			r100_cs_dump_packet(p, pkt); +			return r; +		} +		ib[idx+2] = radeon_get_ib_value(p, idx + 2) + ((u32)reloc->lobj.gpu_offset); +		track->arrays[i + 1].robj = reloc->robj; +		track->arrays[i + 1].esize = idx_value >> 24; +		track->arrays[i + 1].esize &= 0x7F; +	} +	if (c & 1) { +		r = r100_cs_packet_next_reloc(p, &reloc); +		if (r) { +			DRM_ERROR("No reloc for packet3 %d\n", +					  pkt->opcode); +			r100_cs_dump_packet(p, pkt); +			return r; +		} +		idx_value = radeon_get_ib_value(p, idx); +		ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); +		track->arrays[i + 0].robj = reloc->robj; +		track->arrays[i + 0].esize = idx_value >> 8; +		track->arrays[i + 0].esize &= 0x7F; +	} +	return r; +} +  void r100_pre_page_flip(struct radeon_device *rdev, int crtc)  {  	/* enable the pflip int */ @@ -513,6 +615,9 @@ int r100_pci_gart_enable(struct radeon_device *rdev)  	tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;  	WREG32(RADEON_AIC_CNTL, tmp);  	r100_pci_gart_tlb_flush(rdev); +	DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", +		 (unsigned)(rdev->mc.gtt_size >> 20), +		 (unsigned long long)rdev->gart.table_addr);  	rdev->gart.ready = true;  	return 0;  } @@ -588,7 +693,7 @@ void r100_irq_disable(struct radeon_device *rdev)  	WREG32(R_000044_GEN_INT_STATUS, tmp);  } -static inline uint32_t r100_irq_ack(struct radeon_device *rdev) +static uint32_t r100_irq_ack(struct radeon_device *rdev)  {  	uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS);  	uint32_t irq_mask = RADEON_SW_INT_TEST | @@ -3147,7 +3252,7 @@ void r100_bandwidth_update(struct radeon_device *rdev)  	}  } -static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t) +static void r100_cs_track_texture_print(struct r100_cs_track_texture *t)  {  	DRM_ERROR("pitch                      %d\n", t->pitch);  	DRM_ERROR("use_pitch                  %d\n", t->use_pitch); @@ -3965,3 +4070,43 @@ int r100_init(struct radeon_device *rdev)  	}  	return 0;  } + +uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) +{ +	if (reg < rdev->rmmio_size) +		return readl(((void __iomem *)rdev->rmmio) + reg); +	else { +		writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); +		return readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); +	} +} + +void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) +{ +	if (reg < rdev->rmmio_size) +		writel(v, ((void __iomem *)rdev->rmmio) + reg); +	else { +		writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); +		writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); +	} +} + +u32 r100_io_rreg(struct radeon_device *rdev, u32 reg) +{ +	if (reg < rdev->rio_mem_size) +		return ioread32(rdev->rio_mem + reg); +	else { +		iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX); +		return ioread32(rdev->rio_mem + RADEON_MM_DATA); +	} +} + +void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v) +{ +	if (reg < rdev->rio_mem_size) +		iowrite32(v, rdev->rio_mem + reg); +	else { +		iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX); +		iowrite32(v, rdev->rio_mem + RADEON_MM_DATA); +	} +}  |