mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 12:57:53 +00:00
gpu: host1x: Program context stream ID on submission
Add code to do stream ID switching at the beginning of a job. The stream ID is switched to the stream ID specified by the context passed in the job structure. Before switching the stream ID, an OP_DONE wait is done on the channel's engine to ensure that there is no residual ongoing work that might do DMA using the new stream ID. Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
8aa5bcb616
commit
2486254781
4 changed files with 76 additions and 4 deletions
|
@ -180,6 +180,45 @@ static void host1x_enable_gather_filter(struct host1x_channel *ch)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void host1x_channel_program_engine_streamid(struct host1x_job *job)
|
||||
{
|
||||
#if HOST1X_HW >= 6
|
||||
u32 fence;
|
||||
|
||||
if (!job->memory_context)
|
||||
return;
|
||||
|
||||
fence = host1x_syncpt_incr_max(job->syncpt, 1);
|
||||
|
||||
/* First, increment a syncpoint on OP_DONE condition.. */
|
||||
|
||||
host1x_cdma_push(&job->channel->cdma,
|
||||
host1x_opcode_nonincr(HOST1X_UCLASS_INCR_SYNCPT, 1),
|
||||
HOST1X_UCLASS_INCR_SYNCPT_INDX_F(job->syncpt->id) |
|
||||
HOST1X_UCLASS_INCR_SYNCPT_COND_F(1));
|
||||
|
||||
/* Wait for syncpoint to increment */
|
||||
|
||||
host1x_cdma_push(&job->channel->cdma,
|
||||
host1x_opcode_setclass(HOST1X_CLASS_HOST1X,
|
||||
host1x_uclass_wait_syncpt_r(), 1),
|
||||
host1x_class_host_wait_syncpt(job->syncpt->id, fence));
|
||||
|
||||
/*
|
||||
* Now that we know the engine is idle, return to class and
|
||||
* change stream ID.
|
||||
*/
|
||||
|
||||
host1x_cdma_push(&job->channel->cdma,
|
||||
host1x_opcode_setclass(job->class, 0, 0),
|
||||
HOST1X_OPCODE_NOP);
|
||||
|
||||
host1x_cdma_push(&job->channel->cdma,
|
||||
host1x_opcode_setpayload(job->memory_context->stream_id),
|
||||
host1x_opcode_setstreamid(job->engine_streamid_offset / 4));
|
||||
#endif
|
||||
}
|
||||
|
||||
static int channel_submit(struct host1x_job *job)
|
||||
{
|
||||
struct host1x_channel *ch = job->channel;
|
||||
|
@ -236,18 +275,23 @@ static int channel_submit(struct host1x_job *job)
|
|||
if (sp->base)
|
||||
synchronize_syncpt_base(job);
|
||||
|
||||
syncval = host1x_syncpt_incr_max(sp, user_syncpt_incrs);
|
||||
|
||||
host1x_hw_syncpt_assign_to_channel(host, sp, ch);
|
||||
|
||||
job->syncpt_end = syncval;
|
||||
|
||||
/* add a setclass for modules that require it */
|
||||
if (job->class)
|
||||
host1x_cdma_push(&ch->cdma,
|
||||
host1x_opcode_setclass(job->class, 0, 0),
|
||||
HOST1X_OPCODE_NOP);
|
||||
|
||||
/*
|
||||
* Ensure engine DMA is idle and set new stream ID. May increment
|
||||
* syncpt max.
|
||||
*/
|
||||
host1x_channel_program_engine_streamid(job);
|
||||
|
||||
syncval = host1x_syncpt_incr_max(sp, user_syncpt_incrs);
|
||||
job->syncpt_end = syncval;
|
||||
|
||||
submit_gathers(job, syncval - user_syncpt_incrs);
|
||||
|
||||
/* end CDMA submit & stash pinned hMems into sync queue */
|
||||
|
|
|
@ -127,6 +127,16 @@ static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
|
|||
return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_setstreamid(unsigned streamid)
|
||||
{
|
||||
return (7 << 28) | streamid;
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_setpayload(unsigned payload)
|
||||
{
|
||||
return (9 << 28) | payload;
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_gather_wide(unsigned count)
|
||||
{
|
||||
return (12 << 28) | count;
|
||||
|
|
|
@ -127,6 +127,16 @@ static inline u32 host1x_opcode_gather_incr(unsigned offset, unsigned count)
|
|||
return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_setstreamid(unsigned streamid)
|
||||
{
|
||||
return (7 << 28) | streamid;
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_setpayload(unsigned payload)
|
||||
{
|
||||
return (9 << 28) | payload;
|
||||
}
|
||||
|
||||
static inline u32 host1x_opcode_gather_wide(unsigned count)
|
||||
{
|
||||
return (12 << 28) | count;
|
||||
|
|
|
@ -327,6 +327,14 @@ struct host1x_job {
|
|||
|
||||
/* Whether host1x-side firewall should be ran for this job or not */
|
||||
bool enable_firewall;
|
||||
|
||||
/* Options for configuring engine data stream ID */
|
||||
/* Context device to use for job */
|
||||
struct host1x_memory_context *memory_context;
|
||||
/* Stream ID to use if context isolation is disabled (!memory_context) */
|
||||
u32 engine_fallback_streamid;
|
||||
/* Engine offset to program stream ID to */
|
||||
u32 engine_streamid_offset;
|
||||
};
|
||||
|
||||
struct host1x_job *host1x_job_alloc(struct host1x_channel *ch,
|
||||
|
|
Loading…
Reference in a new issue