diff options
Diffstat (limited to 'drivers/gpu/host1x/hw/channel_hw.c')
| -rw-r--r-- | drivers/gpu/host1x/hw/channel_hw.c | 43 | 
1 files changed, 39 insertions, 4 deletions
| diff --git a/drivers/gpu/host1x/hw/channel_hw.c b/drivers/gpu/host1x/hw/channel_hw.c index 95ea81172a83..27101c04a827 100644 --- a/drivers/gpu/host1x/hw/channel_hw.c +++ b/drivers/gpu/host1x/hw/channel_hw.c @@ -17,6 +17,7 @@   */  #include <linux/host1x.h> +#include <linux/iommu.h>  #include <linux/slab.h>  #include <trace/events/host1x.h> @@ -60,15 +61,37 @@ static void trace_write_gather(struct host1x_cdma *cdma, struct host1x_bo *bo,  static void submit_gathers(struct host1x_job *job)  {  	struct host1x_cdma *cdma = &job->channel->cdma; +#if HOST1X_HW < 6 +	struct device *dev = job->channel->dev; +#endif  	unsigned int i;  	for (i = 0; i < job->num_gathers; i++) {  		struct host1x_job_gather *g = &job->gathers[i]; -		u32 op1 = host1x_opcode_gather(g->words); -		u32 op2 = g->base + g->offset; +		dma_addr_t addr = g->base + g->offset; +		u32 op2, op3; + +		op2 = lower_32_bits(addr); +		op3 = upper_32_bits(addr); + +		trace_write_gather(cdma, g->bo, g->offset, g->words); + +		if (op3 != 0) { +#if HOST1X_HW >= 6 +			u32 op1 = host1x_opcode_gather_wide(g->words); +			u32 op4 = HOST1X_OPCODE_NOP; + +			host1x_cdma_push_wide(cdma, op1, op2, op3, op4); +#else +			dev_err(dev, "invalid gather for push buffer %pad\n", +				&addr); +			continue; +#endif +		} else { +			u32 op1 = host1x_opcode_gather(g->words); -		trace_write_gather(cdma, g->bo, g->offset, op1 & 0xffff); -		host1x_cdma_push(cdma, op1, op2); +			host1x_cdma_push(cdma, op1, op2); +		}  	}  } @@ -89,6 +112,16 @@ static inline void synchronize_syncpt_base(struct host1x_job *job)  			 HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(value));  } +static void host1x_channel_set_streamid(struct host1x_channel *channel) +{ +#if HOST1X_HW >= 6 +	struct iommu_fwspec *spec = dev_iommu_fwspec_get(channel->dev->parent); +	u32 sid = spec ? spec->ids[0] & 0xffff : 0x7f; + +	host1x_ch_writel(channel, sid, HOST1X_CHANNEL_SMMU_STREAMID); +#endif +} +  static int channel_submit(struct host1x_job *job)  {  	struct host1x_channel *ch = job->channel; @@ -120,6 +153,8 @@ static int channel_submit(struct host1x_job *job)  		goto error;  	} +	host1x_channel_set_streamid(ch); +  	/* begin a CDMA submit */  	err = host1x_cdma_begin(&ch->cdma, job);  	if (err) { | 
