diff options
Diffstat (limited to 'drivers/gpu/host1x/cdma.c')
-rw-r--r-- | drivers/gpu/host1x/cdma.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c index a18db4d5347c..c5d82a8a2ec9 100644 --- a/drivers/gpu/host1x/cdma.c +++ b/drivers/gpu/host1x/cdma.c | |||
@@ -96,12 +96,12 @@ fail: | |||
96 | */ | 96 | */ |
97 | static void host1x_pushbuffer_push(struct push_buffer *pb, u32 op1, u32 op2) | 97 | static void host1x_pushbuffer_push(struct push_buffer *pb, u32 op1, u32 op2) |
98 | { | 98 | { |
99 | u32 pos = pb->pos; | 99 | u32 *p = (u32 *)((void *)pb->mapped + pb->pos); |
100 | u32 *p = (u32 *)((void *)pb->mapped + pos); | 100 | |
101 | WARN_ON(pos == pb->fence); | 101 | WARN_ON(pb->pos == pb->fence); |
102 | *(p++) = op1; | 102 | *(p++) = op1; |
103 | *(p++) = op2; | 103 | *(p++) = op2; |
104 | pb->pos = (pos + 8) & (pb->size_bytes - 1); | 104 | pb->pos = (pb->pos + 8) & (pb->size_bytes - 1); |
105 | } | 105 | } |
106 | 106 | ||
107 | /* | 107 | /* |
@@ -134,14 +134,19 @@ unsigned int host1x_cdma_wait_locked(struct host1x_cdma *cdma, | |||
134 | enum cdma_event event) | 134 | enum cdma_event event) |
135 | { | 135 | { |
136 | for (;;) { | 136 | for (;;) { |
137 | struct push_buffer *pb = &cdma->push_buffer; | ||
137 | unsigned int space; | 138 | unsigned int space; |
138 | 139 | ||
139 | if (event == CDMA_EVENT_SYNC_QUEUE_EMPTY) | 140 | switch (event) { |
141 | case CDMA_EVENT_SYNC_QUEUE_EMPTY: | ||
140 | space = list_empty(&cdma->sync_queue) ? 1 : 0; | 142 | space = list_empty(&cdma->sync_queue) ? 1 : 0; |
141 | else if (event == CDMA_EVENT_PUSH_BUFFER_SPACE) { | 143 | break; |
142 | struct push_buffer *pb = &cdma->push_buffer; | 144 | |
145 | case CDMA_EVENT_PUSH_BUFFER_SPACE: | ||
143 | space = host1x_pushbuffer_space(pb); | 146 | space = host1x_pushbuffer_space(pb); |
144 | } else { | 147 | break; |
148 | |||
149 | default: | ||
145 | WARN_ON(1); | 150 | WARN_ON(1); |
146 | return -EINVAL; | 151 | return -EINVAL; |
147 | } | 152 | } |
@@ -159,12 +164,14 @@ unsigned int host1x_cdma_wait_locked(struct host1x_cdma *cdma, | |||
159 | mutex_lock(&cdma->lock); | 164 | mutex_lock(&cdma->lock); |
160 | continue; | 165 | continue; |
161 | } | 166 | } |
167 | |||
162 | cdma->event = event; | 168 | cdma->event = event; |
163 | 169 | ||
164 | mutex_unlock(&cdma->lock); | 170 | mutex_unlock(&cdma->lock); |
165 | down(&cdma->sem); | 171 | down(&cdma->sem); |
166 | mutex_lock(&cdma->lock); | 172 | mutex_lock(&cdma->lock); |
167 | } | 173 | } |
174 | |||
168 | return 0; | 175 | return 0; |
169 | } | 176 | } |
170 | 177 | ||
@@ -234,6 +241,7 @@ static void update_cdma_locked(struct host1x_cdma *cdma) | |||
234 | /* Start timer on next pending syncpt */ | 241 | /* Start timer on next pending syncpt */ |
235 | if (job->timeout) | 242 | if (job->timeout) |
236 | cdma_start_timer_locked(cdma, job); | 243 | cdma_start_timer_locked(cdma, job); |
244 | |||
237 | break; | 245 | break; |
238 | } | 246 | } |
239 | 247 | ||
@@ -247,7 +255,9 @@ static void update_cdma_locked(struct host1x_cdma *cdma) | |||
247 | /* Pop push buffer slots */ | 255 | /* Pop push buffer slots */ |
248 | if (job->num_slots) { | 256 | if (job->num_slots) { |
249 | struct push_buffer *pb = &cdma->push_buffer; | 257 | struct push_buffer *pb = &cdma->push_buffer; |
258 | |||
250 | host1x_pushbuffer_pop(pb, job->num_slots); | 259 | host1x_pushbuffer_pop(pb, job->num_slots); |
260 | |||
251 | if (cdma->event == CDMA_EVENT_PUSH_BUFFER_SPACE) | 261 | if (cdma->event == CDMA_EVENT_PUSH_BUFFER_SPACE) |
252 | signal = true; | 262 | signal = true; |
253 | } | 263 | } |
@@ -269,11 +279,9 @@ static void update_cdma_locked(struct host1x_cdma *cdma) | |||
269 | void host1x_cdma_update_sync_queue(struct host1x_cdma *cdma, | 279 | void host1x_cdma_update_sync_queue(struct host1x_cdma *cdma, |
270 | struct device *dev) | 280 | struct device *dev) |
271 | { | 281 | { |
272 | u32 restart_addr; | ||
273 | u32 syncpt_incrs; | ||
274 | struct host1x_job *job = NULL; | ||
275 | u32 syncpt_val; | ||
276 | struct host1x *host1x = cdma_to_host1x(cdma); | 282 | struct host1x *host1x = cdma_to_host1x(cdma); |
283 | u32 restart_addr, syncpt_incrs, syncpt_val; | ||
284 | struct host1x_job *job = NULL; | ||
277 | 285 | ||
278 | syncpt_val = host1x_syncpt_load(cdma->timeout.syncpt); | 286 | syncpt_val = host1x_syncpt_load(cdma->timeout.syncpt); |
279 | 287 | ||
@@ -342,9 +350,11 @@ void host1x_cdma_update_sync_queue(struct host1x_cdma *cdma, | |||
342 | syncpt_val += syncpt_incrs; | 350 | syncpt_val += syncpt_incrs; |
343 | } | 351 | } |
344 | 352 | ||
345 | /* The following sumbits from the same client may be dependent on the | 353 | /* |
354 | * The following sumbits from the same client may be dependent on the | ||
346 | * failed submit and therefore they may fail. Force a small timeout | 355 | * failed submit and therefore they may fail. Force a small timeout |
347 | * to make the queue cleanup faster */ | 356 | * to make the queue cleanup faster. |
357 | */ | ||
348 | 358 | ||
349 | list_for_each_entry_from(job, &cdma->sync_queue, list) | 359 | list_for_each_entry_from(job, &cdma->sync_queue, list) |
350 | if (job->client == cdma->timeout.client) | 360 | if (job->client == cdma->timeout.client) |
@@ -375,6 +385,7 @@ int host1x_cdma_init(struct host1x_cdma *cdma) | |||
375 | err = host1x_pushbuffer_init(&cdma->push_buffer); | 385 | err = host1x_pushbuffer_init(&cdma->push_buffer); |
376 | if (err) | 386 | if (err) |
377 | return err; | 387 | return err; |
388 | |||
378 | return 0; | 389 | return 0; |
379 | } | 390 | } |
380 | 391 | ||
@@ -410,6 +421,7 @@ int host1x_cdma_begin(struct host1x_cdma *cdma, struct host1x_job *job) | |||
410 | /* init state on first submit with timeout value */ | 421 | /* init state on first submit with timeout value */ |
411 | if (!cdma->timeout.initialized) { | 422 | if (!cdma->timeout.initialized) { |
412 | int err; | 423 | int err; |
424 | |||
413 | err = host1x_hw_cdma_timeout_init(host1x, cdma, | 425 | err = host1x_hw_cdma_timeout_init(host1x, cdma, |
414 | job->syncpt_id); | 426 | job->syncpt_id); |
415 | if (err) { | 427 | if (err) { |
@@ -418,6 +430,7 @@ int host1x_cdma_begin(struct host1x_cdma *cdma, struct host1x_job *job) | |||
418 | } | 430 | } |
419 | } | 431 | } |
420 | } | 432 | } |
433 | |||
421 | if (!cdma->running) | 434 | if (!cdma->running) |
422 | host1x_hw_cdma_start(host1x, cdma); | 435 | host1x_hw_cdma_start(host1x, cdma); |
423 | 436 | ||
@@ -448,6 +461,7 @@ void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, u32 op2) | |||
448 | slots_free = host1x_cdma_wait_locked(cdma, | 461 | slots_free = host1x_cdma_wait_locked(cdma, |
449 | CDMA_EVENT_PUSH_BUFFER_SPACE); | 462 | CDMA_EVENT_PUSH_BUFFER_SPACE); |
450 | } | 463 | } |
464 | |||
451 | cdma->slots_free = slots_free - 1; | 465 | cdma->slots_free = slots_free - 1; |
452 | cdma->slots_used++; | 466 | cdma->slots_used++; |
453 | host1x_pushbuffer_push(pb, op1, op2); | 467 | host1x_pushbuffer_push(pb, op1, op2); |