Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Mikko Perttunen and committed by
Thierry Reding
24862547 8aa5bcb6

+76 -4
+48 -4
drivers/gpu/host1x/hw/channel_hw.c
··· 180 180 #endif 181 181 } 182 182 183 + static void host1x_channel_program_engine_streamid(struct host1x_job *job) 184 + { 185 + #if HOST1X_HW >= 6 186 + u32 fence; 187 + 188 + if (!job->memory_context) 189 + return; 190 + 191 + fence = host1x_syncpt_incr_max(job->syncpt, 1); 192 + 193 + /* First, increment a syncpoint on OP_DONE condition.. */ 194 + 195 + host1x_cdma_push(&job->channel->cdma, 196 + host1x_opcode_nonincr(HOST1X_UCLASS_INCR_SYNCPT, 1), 197 + HOST1X_UCLASS_INCR_SYNCPT_INDX_F(job->syncpt->id) | 198 + HOST1X_UCLASS_INCR_SYNCPT_COND_F(1)); 199 + 200 + /* Wait for syncpoint to increment */ 201 + 202 + host1x_cdma_push(&job->channel->cdma, 203 + host1x_opcode_setclass(HOST1X_CLASS_HOST1X, 204 + host1x_uclass_wait_syncpt_r(), 1), 205 + host1x_class_host_wait_syncpt(job->syncpt->id, fence)); 206 + 207 + /* 208 + * Now that we know the engine is idle, return to class and 209 + * change stream ID. 210 + */ 211 + 212 + host1x_cdma_push(&job->channel->cdma, 213 + host1x_opcode_setclass(job->class, 0, 0), 214 + HOST1X_OPCODE_NOP); 215 + 216 + host1x_cdma_push(&job->channel->cdma, 217 + host1x_opcode_setpayload(job->memory_context->stream_id), 218 + host1x_opcode_setstreamid(job->engine_streamid_offset / 4)); 219 + #endif 220 + } 221 + 183 222 static int channel_submit(struct host1x_job *job) 184 223 { 185 224 struct host1x_channel *ch = job->channel; ··· 275 236 if (sp->base) 276 237 synchronize_syncpt_base(job); 277 238 278 - syncval = host1x_syncpt_incr_max(sp, user_syncpt_incrs); 279 - 280 239 host1x_hw_syncpt_assign_to_channel(host, sp, ch); 281 - 282 - job->syncpt_end = syncval; 283 240 284 241 /* add a setclass for modules that require it */ 285 242 if (job->class) 286 243 host1x_cdma_push(&ch->cdma, 287 244 host1x_opcode_setclass(job->class, 0, 0), 288 245 HOST1X_OPCODE_NOP); 246 + 247 + /* 248 + * Ensure engine DMA is idle and set new stream ID. May increment 249 + * syncpt max. 250 + */ 251 + host1x_channel_program_engine_streamid(job); 252 + 253 + syncval = host1x_syncpt_incr_max(sp, user_syncpt_incrs); 254 + job->syncpt_end = syncval; 289 255 290 256 submit_gathers(job, syncval - user_syncpt_incrs); 291 257
+10
drivers/gpu/host1x/hw/host1x06_hardware.h
··· 127 127 return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count; 128 128 } 129 129 130 + static inline u32 host1x_opcode_setstreamid(unsigned streamid) 131 + { 132 + return (7 << 28) | streamid; 133 + } 134 + 135 + static inline u32 host1x_opcode_setpayload(unsigned payload) 136 + { 137 + return (9 << 28) | payload; 138 + } 139 + 130 140 static inline u32 host1x_opcode_gather_wide(unsigned count) 131 141 { 132 142 return (12 << 28) | count;
+10
drivers/gpu/host1x/hw/host1x07_hardware.h
··· 127 127 return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count; 128 128 } 129 129 130 + static inline u32 host1x_opcode_setstreamid(unsigned streamid) 131 + { 132 + return (7 << 28) | streamid; 133 + } 134 + 135 + static inline u32 host1x_opcode_setpayload(unsigned payload) 136 + { 137 + return (9 << 28) | payload; 138 + } 139 + 130 140 static inline u32 host1x_opcode_gather_wide(unsigned count) 131 141 { 132 142 return (12 << 28) | count;
+8
include/linux/host1x.h
··· 327 327 328 328 /* Whether host1x-side firewall should be ran for this job or not */ 329 329 bool enable_firewall; 330 + 331 + /* Options for configuring engine data stream ID */ 332 + /* Context device to use for job */ 333 + struct host1x_memory_context *memory_context; 334 + /* Stream ID to use if context isolation is disabled (!memory_context) */ 335 + u32 engine_fallback_streamid; 336 + /* Engine offset to program stream ID to */ 337 + u32 engine_streamid_offset; 330 338 }; 331 339 332 340 struct host1x_job *host1x_job_alloc(struct host1x_channel *ch,