1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2013 Red Hat
4 * Author: Rob Clark <robdclark@gmail.com>
10 #include "msm_fence.h"
11 #include "msm_gpu_trace.h"
12 #include "adreno/adreno_gpu.h"
14 #include <generated/utsrelease.h>
15 #include <linux/string_helpers.h>
16 #include <linux/pm_opp.h>
17 #include <linux/devfreq.h>
18 #include <linux/devcoredump.h>
19 #include <linux/sched/task.h>
25 static int msm_devfreq_target(struct device
*dev
, unsigned long *freq
,
28 struct msm_gpu
*gpu
= platform_get_drvdata(to_platform_device(dev
));
29 struct dev_pm_opp
*opp
;
31 opp
= devfreq_recommended_opp(dev
, freq
, flags
);
36 if (gpu
->funcs
->gpu_set_freq
)
37 gpu
->funcs
->gpu_set_freq(gpu
, (u64
)*freq
);
39 clk_set_rate(gpu
->core_clk
, *freq
);
46 static int msm_devfreq_get_dev_status(struct device
*dev
,
47 struct devfreq_dev_status
*status
)
49 struct msm_gpu
*gpu
= platform_get_drvdata(to_platform_device(dev
));
52 if (gpu
->funcs
->gpu_get_freq
)
53 status
->current_frequency
= gpu
->funcs
->gpu_get_freq(gpu
);
55 status
->current_frequency
= clk_get_rate(gpu
->core_clk
);
57 status
->busy_time
= gpu
->funcs
->gpu_busy(gpu
);
60 status
->total_time
= ktime_us_delta(time
, gpu
->devfreq
.time
);
61 gpu
->devfreq
.time
= time
;
66 static int msm_devfreq_get_cur_freq(struct device
*dev
, unsigned long *freq
)
68 struct msm_gpu
*gpu
= platform_get_drvdata(to_platform_device(dev
));
70 if (gpu
->funcs
->gpu_get_freq
)
71 *freq
= gpu
->funcs
->gpu_get_freq(gpu
);
73 *freq
= clk_get_rate(gpu
->core_clk
);
78 static struct devfreq_dev_profile msm_devfreq_profile
= {
80 .target
= msm_devfreq_target
,
81 .get_dev_status
= msm_devfreq_get_dev_status
,
82 .get_cur_freq
= msm_devfreq_get_cur_freq
,
85 static void msm_devfreq_init(struct msm_gpu
*gpu
)
87 /* We need target support to do devfreq */
88 if (!gpu
->funcs
->gpu_busy
)
91 msm_devfreq_profile
.initial_freq
= gpu
->fast_rate
;
94 * Don't set the freq_table or max_state and let devfreq build the table
98 gpu
->devfreq
.devfreq
= devm_devfreq_add_device(&gpu
->pdev
->dev
,
99 &msm_devfreq_profile
, DEVFREQ_GOV_SIMPLE_ONDEMAND
,
102 if (IS_ERR(gpu
->devfreq
.devfreq
)) {
103 DRM_DEV_ERROR(&gpu
->pdev
->dev
, "Couldn't initialize GPU devfreq\n");
104 gpu
->devfreq
.devfreq
= NULL
;
107 devfreq_suspend_device(gpu
->devfreq
.devfreq
);
110 static int enable_pwrrail(struct msm_gpu
*gpu
)
112 struct drm_device
*dev
= gpu
->dev
;
116 ret
= regulator_enable(gpu
->gpu_reg
);
118 DRM_DEV_ERROR(dev
->dev
, "failed to enable 'gpu_reg': %d\n", ret
);
124 ret
= regulator_enable(gpu
->gpu_cx
);
126 DRM_DEV_ERROR(dev
->dev
, "failed to enable 'gpu_cx': %d\n", ret
);
134 static int disable_pwrrail(struct msm_gpu
*gpu
)
137 regulator_disable(gpu
->gpu_cx
);
139 regulator_disable(gpu
->gpu_reg
);
143 static int enable_clk(struct msm_gpu
*gpu
)
145 if (gpu
->core_clk
&& gpu
->fast_rate
)
146 clk_set_rate(gpu
->core_clk
, gpu
->fast_rate
);
148 /* Set the RBBM timer rate to 19.2Mhz */
149 if (gpu
->rbbmtimer_clk
)
150 clk_set_rate(gpu
->rbbmtimer_clk
, 19200000);
152 return clk_bulk_prepare_enable(gpu
->nr_clocks
, gpu
->grp_clks
);
155 static int disable_clk(struct msm_gpu
*gpu
)
157 clk_bulk_disable_unprepare(gpu
->nr_clocks
, gpu
->grp_clks
);
160 * Set the clock to a deliberately low rate. On older targets the clock
161 * speed had to be non zero to avoid problems. On newer targets this
162 * will be rounded down to zero anyway so it all works out.
165 clk_set_rate(gpu
->core_clk
, 27000000);
167 if (gpu
->rbbmtimer_clk
)
168 clk_set_rate(gpu
->rbbmtimer_clk
, 0);
173 static int enable_axi(struct msm_gpu
*gpu
)
176 clk_prepare_enable(gpu
->ebi1_clk
);
180 static int disable_axi(struct msm_gpu
*gpu
)
183 clk_disable_unprepare(gpu
->ebi1_clk
);
187 void msm_gpu_resume_devfreq(struct msm_gpu
*gpu
)
189 gpu
->devfreq
.busy_cycles
= 0;
190 gpu
->devfreq
.time
= ktime_get();
192 devfreq_resume_device(gpu
->devfreq
.devfreq
);
195 int msm_gpu_pm_resume(struct msm_gpu
*gpu
)
199 DBG("%s", gpu
->name
);
201 ret
= enable_pwrrail(gpu
);
205 ret
= enable_clk(gpu
);
209 ret
= enable_axi(gpu
);
213 msm_gpu_resume_devfreq(gpu
);
215 gpu
->needs_hw_init
= true;
220 int msm_gpu_pm_suspend(struct msm_gpu
*gpu
)
224 DBG("%s", gpu
->name
);
226 devfreq_suspend_device(gpu
->devfreq
.devfreq
);
228 ret
= disable_axi(gpu
);
232 ret
= disable_clk(gpu
);
236 ret
= disable_pwrrail(gpu
);
243 int msm_gpu_hw_init(struct msm_gpu
*gpu
)
247 WARN_ON(!mutex_is_locked(&gpu
->dev
->struct_mutex
));
249 if (!gpu
->needs_hw_init
)
252 disable_irq(gpu
->irq
);
253 ret
= gpu
->funcs
->hw_init(gpu
);
255 gpu
->needs_hw_init
= false;
256 enable_irq(gpu
->irq
);
261 #ifdef CONFIG_DEV_COREDUMP
262 static ssize_t
msm_gpu_devcoredump_read(char *buffer
, loff_t offset
,
263 size_t count
, void *data
, size_t datalen
)
265 struct msm_gpu
*gpu
= data
;
266 struct drm_print_iterator iter
;
267 struct drm_printer p
;
268 struct msm_gpu_state
*state
;
270 state
= msm_gpu_crashstate_get(gpu
);
279 p
= drm_coredump_printer(&iter
);
281 drm_printf(&p
, "---\n");
282 drm_printf(&p
, "kernel: " UTS_RELEASE
"\n");
283 drm_printf(&p
, "module: " KBUILD_MODNAME
"\n");
284 drm_printf(&p
, "time: %lld.%09ld\n",
285 state
->time
.tv_sec
, state
->time
.tv_nsec
);
287 drm_printf(&p
, "comm: %s\n", state
->comm
);
289 drm_printf(&p
, "cmdline: %s\n", state
->cmd
);
291 gpu
->funcs
->show(gpu
, state
, &p
);
293 msm_gpu_crashstate_put(gpu
);
295 return count
- iter
.remain
;
298 static void msm_gpu_devcoredump_free(void *data
)
300 struct msm_gpu
*gpu
= data
;
302 msm_gpu_crashstate_put(gpu
);
305 static void msm_gpu_crashstate_get_bo(struct msm_gpu_state
*state
,
306 struct msm_gem_object
*obj
, u64 iova
, u32 flags
)
308 struct msm_gpu_state_bo
*state_bo
= &state
->bos
[state
->nr_bos
];
310 /* Don't record write only objects */
311 state_bo
->size
= obj
->base
.size
;
312 state_bo
->iova
= iova
;
314 /* Only store data for non imported buffer objects marked for read */
315 if ((flags
& MSM_SUBMIT_BO_READ
) && !obj
->base
.import_attach
) {
318 state_bo
->data
= kvmalloc(obj
->base
.size
, GFP_KERNEL
);
322 ptr
= msm_gem_get_vaddr_active(&obj
->base
);
324 kvfree(state_bo
->data
);
325 state_bo
->data
= NULL
;
329 memcpy(state_bo
->data
, ptr
, obj
->base
.size
);
330 msm_gem_put_vaddr(&obj
->base
);
336 static void msm_gpu_crashstate_capture(struct msm_gpu
*gpu
,
337 struct msm_gem_submit
*submit
, char *comm
, char *cmd
)
339 struct msm_gpu_state
*state
;
341 /* Check if the target supports capturing crash state */
342 if (!gpu
->funcs
->gpu_state_get
)
345 /* Only save one crash state at a time */
349 state
= gpu
->funcs
->gpu_state_get(gpu
);
350 if (IS_ERR_OR_NULL(state
))
353 /* Fill in the additional crash state information */
354 state
->comm
= kstrdup(comm
, GFP_KERNEL
);
355 state
->cmd
= kstrdup(cmd
, GFP_KERNEL
);
360 state
->bos
= kcalloc(submit
->nr_cmds
,
361 sizeof(struct msm_gpu_state_bo
), GFP_KERNEL
);
363 for (i
= 0; state
->bos
&& i
< submit
->nr_cmds
; i
++) {
364 int idx
= submit
->cmd
[i
].idx
;
366 msm_gpu_crashstate_get_bo(state
, submit
->bos
[idx
].obj
,
367 submit
->bos
[idx
].iova
, submit
->bos
[idx
].flags
);
371 /* Set the active crash state to be dumped on failure */
372 gpu
->crashstate
= state
;
374 /* FIXME: Release the crashstate if this errors out? */
375 dev_coredumpm(gpu
->dev
->dev
, THIS_MODULE
, gpu
, 0, GFP_KERNEL
,
376 msm_gpu_devcoredump_read
, msm_gpu_devcoredump_free
);
379 static void msm_gpu_crashstate_capture(struct msm_gpu
*gpu
,
380 struct msm_gem_submit
*submit
, char *comm
, char *cmd
)
386 * Hangcheck detection for locked gpu:
389 static void update_fences(struct msm_gpu
*gpu
, struct msm_ringbuffer
*ring
,
392 struct msm_gem_submit
*submit
;
394 list_for_each_entry(submit
, &ring
->submits
, node
) {
395 if (submit
->seqno
> fence
)
398 msm_update_fence(submit
->ring
->fctx
,
399 submit
->fence
->seqno
);
403 static struct msm_gem_submit
*
404 find_submit(struct msm_ringbuffer
*ring
, uint32_t fence
)
406 struct msm_gem_submit
*submit
;
408 WARN_ON(!mutex_is_locked(&ring
->gpu
->dev
->struct_mutex
));
410 list_for_each_entry(submit
, &ring
->submits
, node
)
411 if (submit
->seqno
== fence
)
417 static void retire_submits(struct msm_gpu
*gpu
);
419 static void recover_worker(struct work_struct
*work
)
421 struct msm_gpu
*gpu
= container_of(work
, struct msm_gpu
, recover_work
);
422 struct drm_device
*dev
= gpu
->dev
;
423 struct msm_drm_private
*priv
= dev
->dev_private
;
424 struct msm_gem_submit
*submit
;
425 struct msm_ringbuffer
*cur_ring
= gpu
->funcs
->active_ring(gpu
);
426 char *comm
= NULL
, *cmd
= NULL
;
429 mutex_lock(&dev
->struct_mutex
);
431 DRM_DEV_ERROR(dev
->dev
, "%s: hangcheck recover!\n", gpu
->name
);
433 submit
= find_submit(cur_ring
, cur_ring
->memptrs
->fence
+ 1);
435 struct task_struct
*task
;
437 /* Increment the fault counts */
438 gpu
->global_faults
++;
439 submit
->queue
->faults
++;
441 task
= get_pid_task(submit
->pid
, PIDTYPE_PID
);
443 comm
= kstrdup(task
->comm
, GFP_KERNEL
);
444 cmd
= kstrdup_quotable_cmdline(task
, GFP_KERNEL
);
445 put_task_struct(task
);
449 DRM_DEV_ERROR(dev
->dev
, "%s: offending task: %s (%s)\n",
450 gpu
->name
, comm
, cmd
);
452 msm_rd_dump_submit(priv
->hangrd
, submit
,
453 "offending task: %s (%s)", comm
, cmd
);
455 msm_rd_dump_submit(priv
->hangrd
, submit
, NULL
);
458 /* Record the crash state */
459 pm_runtime_get_sync(&gpu
->pdev
->dev
);
460 msm_gpu_crashstate_capture(gpu
, submit
, comm
, cmd
);
461 pm_runtime_put_sync(&gpu
->pdev
->dev
);
467 * Update all the rings with the latest and greatest fence.. this
468 * needs to happen after msm_rd_dump_submit() to ensure that the
469 * bo's referenced by the offending submit are still around.
471 for (i
= 0; i
< gpu
->nr_rings
; i
++) {
472 struct msm_ringbuffer
*ring
= gpu
->rb
[i
];
474 uint32_t fence
= ring
->memptrs
->fence
;
477 * For the current (faulting?) ring/submit advance the fence by
478 * one more to clear the faulting submit
480 if (ring
== cur_ring
)
483 update_fences(gpu
, ring
, fence
);
486 if (msm_gpu_active(gpu
)) {
487 /* retire completed submits, plus the one that hung: */
490 pm_runtime_get_sync(&gpu
->pdev
->dev
);
491 gpu
->funcs
->recover(gpu
);
492 pm_runtime_put_sync(&gpu
->pdev
->dev
);
495 * Replay all remaining submits starting with highest priority
498 for (i
= 0; i
< gpu
->nr_rings
; i
++) {
499 struct msm_ringbuffer
*ring
= gpu
->rb
[i
];
501 list_for_each_entry(submit
, &ring
->submits
, node
)
502 gpu
->funcs
->submit(gpu
, submit
, NULL
);
506 mutex_unlock(&dev
->struct_mutex
);
511 static void hangcheck_timer_reset(struct msm_gpu
*gpu
)
513 DBG("%s", gpu
->name
);
514 mod_timer(&gpu
->hangcheck_timer
,
515 round_jiffies_up(jiffies
+ DRM_MSM_HANGCHECK_JIFFIES
));
518 static void hangcheck_handler(struct timer_list
*t
)
520 struct msm_gpu
*gpu
= from_timer(gpu
, t
, hangcheck_timer
);
521 struct drm_device
*dev
= gpu
->dev
;
522 struct msm_drm_private
*priv
= dev
->dev_private
;
523 struct msm_ringbuffer
*ring
= gpu
->funcs
->active_ring(gpu
);
524 uint32_t fence
= ring
->memptrs
->fence
;
526 if (fence
!= ring
->hangcheck_fence
) {
527 /* some progress has been made.. ya! */
528 ring
->hangcheck_fence
= fence
;
529 } else if (fence
< ring
->seqno
) {
530 /* no progress and not done.. hung! */
531 ring
->hangcheck_fence
= fence
;
532 DRM_DEV_ERROR(dev
->dev
, "%s: hangcheck detected gpu lockup rb %d!\n",
533 gpu
->name
, ring
->id
);
534 DRM_DEV_ERROR(dev
->dev
, "%s: completed fence: %u\n",
536 DRM_DEV_ERROR(dev
->dev
, "%s: submitted fence: %u\n",
537 gpu
->name
, ring
->seqno
);
539 queue_work(priv
->wq
, &gpu
->recover_work
);
542 /* if still more pending work, reset the hangcheck timer: */
543 if (ring
->seqno
> ring
->hangcheck_fence
)
544 hangcheck_timer_reset(gpu
);
546 /* workaround for missing irq: */
547 queue_work(priv
->wq
, &gpu
->retire_work
);
551 * Performance Counters:
554 /* called under perf_lock */
555 static int update_hw_cntrs(struct msm_gpu
*gpu
, uint32_t ncntrs
, uint32_t *cntrs
)
557 uint32_t current_cntrs
[ARRAY_SIZE(gpu
->last_cntrs
)];
558 int i
, n
= min(ncntrs
, gpu
->num_perfcntrs
);
560 /* read current values: */
561 for (i
= 0; i
< gpu
->num_perfcntrs
; i
++)
562 current_cntrs
[i
] = gpu_read(gpu
, gpu
->perfcntrs
[i
].sample_reg
);
565 for (i
= 0; i
< n
; i
++)
566 cntrs
[i
] = current_cntrs
[i
] - gpu
->last_cntrs
[i
];
568 /* save current values: */
569 for (i
= 0; i
< gpu
->num_perfcntrs
; i
++)
570 gpu
->last_cntrs
[i
] = current_cntrs
[i
];
575 static void update_sw_cntrs(struct msm_gpu
*gpu
)
581 spin_lock_irqsave(&gpu
->perf_lock
, flags
);
582 if (!gpu
->perfcntr_active
)
586 elapsed
= ktime_to_us(ktime_sub(time
, gpu
->last_sample
.time
));
588 gpu
->totaltime
+= elapsed
;
589 if (gpu
->last_sample
.active
)
590 gpu
->activetime
+= elapsed
;
592 gpu
->last_sample
.active
= msm_gpu_active(gpu
);
593 gpu
->last_sample
.time
= time
;
596 spin_unlock_irqrestore(&gpu
->perf_lock
, flags
);
599 void msm_gpu_perfcntr_start(struct msm_gpu
*gpu
)
603 pm_runtime_get_sync(&gpu
->pdev
->dev
);
605 spin_lock_irqsave(&gpu
->perf_lock
, flags
);
606 /* we could dynamically enable/disable perfcntr registers too.. */
607 gpu
->last_sample
.active
= msm_gpu_active(gpu
);
608 gpu
->last_sample
.time
= ktime_get();
609 gpu
->activetime
= gpu
->totaltime
= 0;
610 gpu
->perfcntr_active
= true;
611 update_hw_cntrs(gpu
, 0, NULL
);
612 spin_unlock_irqrestore(&gpu
->perf_lock
, flags
);
615 void msm_gpu_perfcntr_stop(struct msm_gpu
*gpu
)
617 gpu
->perfcntr_active
= false;
618 pm_runtime_put_sync(&gpu
->pdev
->dev
);
621 /* returns -errno or # of cntrs sampled */
622 int msm_gpu_perfcntr_sample(struct msm_gpu
*gpu
, uint32_t *activetime
,
623 uint32_t *totaltime
, uint32_t ncntrs
, uint32_t *cntrs
)
628 spin_lock_irqsave(&gpu
->perf_lock
, flags
);
630 if (!gpu
->perfcntr_active
) {
635 *activetime
= gpu
->activetime
;
636 *totaltime
= gpu
->totaltime
;
638 gpu
->activetime
= gpu
->totaltime
= 0;
640 ret
= update_hw_cntrs(gpu
, ncntrs
, cntrs
);
643 spin_unlock_irqrestore(&gpu
->perf_lock
, flags
);
649 * Cmdstream submission/retirement:
652 static void retire_submit(struct msm_gpu
*gpu
, struct msm_ringbuffer
*ring
,
653 struct msm_gem_submit
*submit
)
655 int index
= submit
->seqno
% MSM_GPU_SUBMIT_STATS_COUNT
;
656 volatile struct msm_gpu_submit_stats
*stats
;
657 u64 elapsed
, clock
= 0;
660 stats
= &ring
->memptrs
->stats
[index
];
661 /* Convert 19.2Mhz alwayson ticks to nanoseconds for elapsed time */
662 elapsed
= (stats
->alwayson_end
- stats
->alwayson_start
) * 10000;
663 do_div(elapsed
, 192);
665 /* Calculate the clock frequency from the number of CP cycles */
667 clock
= (stats
->cpcycles_end
- stats
->cpcycles_start
) * 1000;
668 do_div(clock
, elapsed
);
671 trace_msm_gpu_submit_retired(submit
, elapsed
, clock
,
672 stats
->alwayson_start
, stats
->alwayson_end
);
674 for (i
= 0; i
< submit
->nr_bos
; i
++) {
675 struct msm_gem_object
*msm_obj
= submit
->bos
[i
].obj
;
676 /* move to inactive: */
677 msm_gem_move_to_inactive(&msm_obj
->base
);
678 msm_gem_unpin_iova(&msm_obj
->base
, submit
->aspace
);
679 drm_gem_object_put(&msm_obj
->base
);
682 pm_runtime_mark_last_busy(&gpu
->pdev
->dev
);
683 pm_runtime_put_autosuspend(&gpu
->pdev
->dev
);
684 msm_gem_submit_free(submit
);
687 static void retire_submits(struct msm_gpu
*gpu
)
689 struct drm_device
*dev
= gpu
->dev
;
690 struct msm_gem_submit
*submit
, *tmp
;
693 WARN_ON(!mutex_is_locked(&dev
->struct_mutex
));
695 /* Retire the commits starting with highest priority */
696 for (i
= 0; i
< gpu
->nr_rings
; i
++) {
697 struct msm_ringbuffer
*ring
= gpu
->rb
[i
];
699 list_for_each_entry_safe(submit
, tmp
, &ring
->submits
, node
) {
700 if (dma_fence_is_signaled(submit
->fence
))
701 retire_submit(gpu
, ring
, submit
);
706 static void retire_worker(struct work_struct
*work
)
708 struct msm_gpu
*gpu
= container_of(work
, struct msm_gpu
, retire_work
);
709 struct drm_device
*dev
= gpu
->dev
;
712 for (i
= 0; i
< gpu
->nr_rings
; i
++)
713 update_fences(gpu
, gpu
->rb
[i
], gpu
->rb
[i
]->memptrs
->fence
);
715 mutex_lock(&dev
->struct_mutex
);
717 mutex_unlock(&dev
->struct_mutex
);
720 /* call from irq handler to schedule work to retire bo's */
721 void msm_gpu_retire(struct msm_gpu
*gpu
)
723 struct msm_drm_private
*priv
= gpu
->dev
->dev_private
;
724 queue_work(priv
->wq
, &gpu
->retire_work
);
725 update_sw_cntrs(gpu
);
728 /* add bo's to gpu's ring, and kick gpu: */
729 void msm_gpu_submit(struct msm_gpu
*gpu
, struct msm_gem_submit
*submit
,
730 struct msm_file_private
*ctx
)
732 struct drm_device
*dev
= gpu
->dev
;
733 struct msm_drm_private
*priv
= dev
->dev_private
;
734 struct msm_ringbuffer
*ring
= submit
->ring
;
737 WARN_ON(!mutex_is_locked(&dev
->struct_mutex
));
739 pm_runtime_get_sync(&gpu
->pdev
->dev
);
741 msm_gpu_hw_init(gpu
);
743 submit
->seqno
= ++ring
->seqno
;
745 list_add_tail(&submit
->node
, &ring
->submits
);
747 msm_rd_dump_submit(priv
->rd
, submit
, NULL
);
749 update_sw_cntrs(gpu
);
751 for (i
= 0; i
< submit
->nr_bos
; i
++) {
752 struct msm_gem_object
*msm_obj
= submit
->bos
[i
].obj
;
755 /* can't happen yet.. but when we add 2d support we'll have
756 * to deal w/ cross-ring synchronization:
758 WARN_ON(is_active(msm_obj
) && (msm_obj
->gpu
!= gpu
));
760 /* submit takes a reference to the bo and iova until retired: */
761 drm_gem_object_get(&msm_obj
->base
);
762 msm_gem_get_and_pin_iova(&msm_obj
->base
, submit
->aspace
, &iova
);
764 if (submit
->bos
[i
].flags
& MSM_SUBMIT_BO_WRITE
)
765 msm_gem_move_to_active(&msm_obj
->base
, gpu
, true, submit
->fence
);
766 else if (submit
->bos
[i
].flags
& MSM_SUBMIT_BO_READ
)
767 msm_gem_move_to_active(&msm_obj
->base
, gpu
, false, submit
->fence
);
770 gpu
->funcs
->submit(gpu
, submit
, ctx
);
773 hangcheck_timer_reset(gpu
);
780 static irqreturn_t
irq_handler(int irq
, void *data
)
782 struct msm_gpu
*gpu
= data
;
783 return gpu
->funcs
->irq(gpu
);
786 static int get_clocks(struct platform_device
*pdev
, struct msm_gpu
*gpu
)
788 int ret
= devm_clk_bulk_get_all(&pdev
->dev
, &gpu
->grp_clks
);
795 gpu
->nr_clocks
= ret
;
797 gpu
->core_clk
= msm_clk_bulk_get_clock(gpu
->grp_clks
,
798 gpu
->nr_clocks
, "core");
800 gpu
->rbbmtimer_clk
= msm_clk_bulk_get_clock(gpu
->grp_clks
,
801 gpu
->nr_clocks
, "rbbmtimer");
806 static struct msm_gem_address_space
*
807 msm_gpu_create_address_space(struct msm_gpu
*gpu
, struct platform_device
*pdev
,
808 uint64_t va_start
, uint64_t va_end
)
810 struct msm_gem_address_space
*aspace
;
814 * Setup IOMMU.. eventually we will (I think) do this once per context
815 * and have separate page tables per context. For now, to keep things
816 * simple and to get something working, just use a single address space:
818 if (!adreno_is_a2xx(to_adreno_gpu(gpu
))) {
819 struct iommu_domain
*iommu
= iommu_domain_alloc(&platform_bus_type
);
823 iommu
->geometry
.aperture_start
= va_start
;
824 iommu
->geometry
.aperture_end
= va_end
;
826 DRM_DEV_INFO(gpu
->dev
->dev
, "%s: using IOMMU\n", gpu
->name
);
828 aspace
= msm_gem_address_space_create(&pdev
->dev
, iommu
, "gpu");
830 iommu_domain_free(iommu
);
832 aspace
= msm_gem_address_space_create_a2xx(&pdev
->dev
, gpu
, "gpu",
836 if (IS_ERR(aspace
)) {
837 DRM_DEV_ERROR(gpu
->dev
->dev
, "failed to init mmu: %ld\n",
839 return ERR_CAST(aspace
);
842 ret
= aspace
->mmu
->funcs
->attach(aspace
->mmu
);
844 msm_gem_address_space_put(aspace
);
851 int msm_gpu_init(struct drm_device
*drm
, struct platform_device
*pdev
,
852 struct msm_gpu
*gpu
, const struct msm_gpu_funcs
*funcs
,
853 const char *name
, struct msm_gpu_config
*config
)
855 int i
, ret
, nr_rings
= config
->nr_rings
;
857 uint64_t memptrs_iova
;
859 if (WARN_ON(gpu
->num_perfcntrs
> ARRAY_SIZE(gpu
->last_cntrs
)))
860 gpu
->num_perfcntrs
= ARRAY_SIZE(gpu
->last_cntrs
);
866 INIT_LIST_HEAD(&gpu
->active_list
);
867 INIT_WORK(&gpu
->retire_work
, retire_worker
);
868 INIT_WORK(&gpu
->recover_work
, recover_worker
);
871 timer_setup(&gpu
->hangcheck_timer
, hangcheck_handler
, 0);
873 spin_lock_init(&gpu
->perf_lock
);
877 gpu
->mmio
= msm_ioremap(pdev
, config
->ioname
, name
);
878 if (IS_ERR(gpu
->mmio
)) {
879 ret
= PTR_ERR(gpu
->mmio
);
884 gpu
->irq
= platform_get_irq(pdev
, 0);
887 DRM_DEV_ERROR(drm
->dev
, "failed to get irq: %d\n", ret
);
891 ret
= devm_request_irq(&pdev
->dev
, gpu
->irq
, irq_handler
,
892 IRQF_TRIGGER_HIGH
, gpu
->name
, gpu
);
894 DRM_DEV_ERROR(drm
->dev
, "failed to request IRQ%u: %d\n", gpu
->irq
, ret
);
898 ret
= get_clocks(pdev
, gpu
);
902 gpu
->ebi1_clk
= msm_clk_get(pdev
, "bus");
903 DBG("ebi1_clk: %p", gpu
->ebi1_clk
);
904 if (IS_ERR(gpu
->ebi1_clk
))
905 gpu
->ebi1_clk
= NULL
;
907 /* Acquire regulators: */
908 gpu
->gpu_reg
= devm_regulator_get(&pdev
->dev
, "vdd");
909 DBG("gpu_reg: %p", gpu
->gpu_reg
);
910 if (IS_ERR(gpu
->gpu_reg
))
913 gpu
->gpu_cx
= devm_regulator_get(&pdev
->dev
, "vddcx");
914 DBG("gpu_cx: %p", gpu
->gpu_cx
);
915 if (IS_ERR(gpu
->gpu_cx
))
919 platform_set_drvdata(pdev
, gpu
);
921 msm_devfreq_init(gpu
);
923 gpu
->aspace
= msm_gpu_create_address_space(gpu
, pdev
,
924 config
->va_start
, config
->va_end
);
926 if (gpu
->aspace
== NULL
)
927 DRM_DEV_INFO(drm
->dev
, "%s: no IOMMU, fallback to VRAM carveout!\n", name
);
928 else if (IS_ERR(gpu
->aspace
)) {
929 ret
= PTR_ERR(gpu
->aspace
);
933 memptrs
= msm_gem_kernel_new(drm
,
934 sizeof(struct msm_rbmemptrs
) * nr_rings
,
935 MSM_BO_UNCACHED
, gpu
->aspace
, &gpu
->memptrs_bo
,
938 if (IS_ERR(memptrs
)) {
939 ret
= PTR_ERR(memptrs
);
940 DRM_DEV_ERROR(drm
->dev
, "could not allocate memptrs: %d\n", ret
);
944 msm_gem_object_set_name(gpu
->memptrs_bo
, "memptrs");
946 if (nr_rings
> ARRAY_SIZE(gpu
->rb
)) {
947 DRM_DEV_INFO_ONCE(drm
->dev
, "Only creating %zu ringbuffers\n",
948 ARRAY_SIZE(gpu
->rb
));
949 nr_rings
= ARRAY_SIZE(gpu
->rb
);
952 /* Create ringbuffer(s): */
953 for (i
= 0; i
< nr_rings
; i
++) {
954 gpu
->rb
[i
] = msm_ringbuffer_new(gpu
, i
, memptrs
, memptrs_iova
);
956 if (IS_ERR(gpu
->rb
[i
])) {
957 ret
= PTR_ERR(gpu
->rb
[i
]);
958 DRM_DEV_ERROR(drm
->dev
,
959 "could not create ringbuffer %d: %d\n", i
, ret
);
963 memptrs
+= sizeof(struct msm_rbmemptrs
);
964 memptrs_iova
+= sizeof(struct msm_rbmemptrs
);
967 gpu
->nr_rings
= nr_rings
;
972 for (i
= 0; i
< ARRAY_SIZE(gpu
->rb
); i
++) {
973 msm_ringbuffer_destroy(gpu
->rb
[i
]);
977 msm_gem_kernel_put(gpu
->memptrs_bo
, gpu
->aspace
, false);
979 platform_set_drvdata(pdev
, NULL
);
983 void msm_gpu_cleanup(struct msm_gpu
*gpu
)
987 DBG("%s", gpu
->name
);
989 WARN_ON(!list_empty(&gpu
->active_list
));
991 for (i
= 0; i
< ARRAY_SIZE(gpu
->rb
); i
++) {
992 msm_ringbuffer_destroy(gpu
->rb
[i
]);
996 msm_gem_kernel_put(gpu
->memptrs_bo
, gpu
->aspace
, false);
998 if (!IS_ERR_OR_NULL(gpu
->aspace
)) {
999 gpu
->aspace
->mmu
->funcs
->detach(gpu
->aspace
->mmu
);
1000 msm_gem_address_space_put(gpu
->aspace
);