aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/msm_gpu.c
AgeCommit message (Collapse)AuthorFilesLines
2019-04-19drm/msm: Stop dropping struct_mutex in recover_worker()Kristian H. Kristensen1-13/+0
Now that we don't have the mmap_sem lock inversion, we don't need to jump through this particular hoop anymore. Signed-off-by: Kristian H. Kristensen <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2019-04-19drm/msm/gpu: Add submit queue queriesJordan Crouse1-1/+2
Add the capability to query information from a submit queue. The first available parameter is for querying the number of GPU faults (hangs) that can be attributed to the queue. This is useful for implementing context robustness. A user context can regularly query the number of faults to see if it is responsible for any and if so it can invalidate itself. This is also helpful for testing by confirming to the user driver if a particular command stream caused a fault (or not as the case may be). Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2019-04-19drm/msm: add param to retrieve # of GPU faults (global)Rob Clark1-0/+3
For KHR_robustness, userspace wants to know two things, the count of GPU faults globally, and the count of faults attributed to a given context. This patch providees the former, and the next patch provides the latter. Signed-off-by: Rob Clark <[email protected]> Reviewed-by: Jordan Crouse <[email protected]>
2019-01-25Merge tag 'drm-msm-fixes-2019-01-24' of ↵Dave Airlie1-1/+1
git://people.freedesktop.org/~robclark/linux into drm-fixes A few fixes for v5.0.. the opp-level fix and removal of hard-coded irq name is partially to make things smoother in v5.1 merge window to avoid dependency on drm vs dt trees, but are otherwise sane changes. Signed-off-by: Dave Airlie <[email protected]> From: Rob Clark <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGsAEHd2tGRQxRTs+A-8y_tthPs2iUgCCCEwR5vDMXab4A@mail.gmail.com
2019-01-24drm/msm/gpu: Remove hardcoded interrupt nameJordan Crouse1-1/+1
Every GPU core only has one interrupt so there isn't any value in looking up the interrupt by name. Remove the name (which is legacy anyway) and use platform_get_irq() instead. Signed-off-by: Jordan Crouse <[email protected]> Reviewed-by: Douglas Anderson <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-12-25Merge tag 'drm-next-2018-12-14' of git://anongit.freedesktop.org/drm/drmLinus Torvalds1-50/+74
Pull drm updates from Dave Airlie: "Core: - shared fencing staging removal - drop transactional atomic helpers and move helpers to new location - DP/MST atomic cleanup - Leasing cleanups and drop EXPORT_SYMBOL - Convert drivers to atomic helpers and generic fbdev. - removed deprecated obj_ref/unref in favour of get/put - Improve dumb callback documentation - MODESET_LOCK_BEGIN/END helpers panels: - CDTech panels, Banana Pi Panel, DLC1010GIG, - Olimex LCD-O-LinuXino, Samsung S6D16D0, Truly NT35597 WQXGA, - Himax HX8357D, simulated RTSM AEMv8. - GPD Win2 panel - AUO G101EVN010 vgem: - render node support ttm: - move global init out of drivers - fix LRU handling for ghost objects - Support for simultaneous submissions to multiple engines scheduler: - timeout/fault handling changes to help GPU recovery - helpers for hw with preemption support i915: - Scaler/Watermark fixes - DP MST + powerwell fixes - PSR fixes - Break long get/put shmemfs pages - Icelake fixes - Icelake DSI video mode enablement - Engine workaround improvements amdgpu: - freesync support - GPU reset enabled on CI, VI, SOC15 dGPUs - ABM support in DC - KFD support for vega12/polaris12 - SDMA paging queue on vega - More amdkfd code sharing - DCC scanout on GFX9 - DC kerneldoc - Updated SMU firmware for GFX8 chips - XGMI PSP + hive reset support - GPU reset - DC trace support - Powerplay updates for newer Polaris - Cursor plane update fast path - kfd dma-buf support virtio-gpu: - add EDID support vmwgfx: - pageflip with damage support nouveau: - Initial Turing TU104/TU106 modesetting support msm: - a2xx gpu support for apq8060 and imx5 - a2xx gpummu support - mdp4 display support for apq8060 - DPU fixes and cleanups - enhanced profiling support - debug object naming interface - get_iova/page pinning decoupling tegra: - Tegra194 host1x, VIC and display support enabled - Audio over HDMI for Tegra186 and Tegra194 exynos: - DMA/IOMMU refactoring - plane alpha + blend mode support - Color format fixes for mixer driver rcar-du: - R8A7744 and R8A77470 support - R8A77965 LVDS support imx: - fbdev emulation fix - multi-tiled scalling fixes - SPDX identifiers rockchip - dw_hdmi support - dw-mipi-dsi + dual dsi support - mailbox read size fix qxl: - fix cursor pinning vc4: - YUV support (scaling + cursor) v3d: - enable TFU (Texture Formatting Unit) mali-dp: - add support for linear tiled formats sun4i: - Display Engine 3 support - H6 DE3 mixer 0 support - H6 display engine support - dw-hdmi support - H6 HDMI phy support - implicit fence waiting - BGRX8888 support meson: - Overlay plane support - implicit fence waiting - HDMI 1.4 4k modes bridge: - i2c fixes for sii902x" * tag 'drm-next-2018-12-14' of git://anongit.freedesktop.org/drm/drm: (1403 commits) drm/amd/display: Add fast path for cursor plane updates drm/amdgpu: Enable GPU recovery by default for CI drm/amd/display: Fix duplicating scaling/underscan connector state drm/amd/display: Fix unintialized max_bpc state values Revert "drm/amd/display: Set RMX_ASPECT as default" drm/amdgpu: Fix stub function name drm/msm/dpu: Fix clock issue after bind failure drm/msm/dpu: Clean up dpu_media_info.h static inline functions drm/msm/dpu: Further cleanups for static inline functions drm/msm/dpu: Cleanup the debugfs functions drm/msm/dpu: Remove dpu_irq and unused functions drm/msm: Make irq_postinstall optional drm/msm/dpu: Cleanup callers of dpu_hw_blk_init drm/msm/dpu: Remove unused functions drm/msm/dpu: Remove dpu_crtc_is_enabled() drm/msm/dpu: Remove dpu_crtc_get_mixer_height drm/msm/dpu: Remove dpu_dbg drm/msm: dpu: Remove crtc_lock drm/msm: dpu: Remove vblank_requested flag from dpu_crtc drm/msm: dpu: Separate crtc assignment from vblank enable ...
2018-12-11drm/msm: implement a2xx mmuJonathan Marek1-12/+19
A2XX has its own very simple MMU. Added a msm_use_mmu() function because we can't rely on iommu_present to decide to use MMU or not. Signed-off-by: Jonathan Marek <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-12-11drm/msm: Add a name field for gem objectsJordan Crouse1-0/+2
For debugging purposes it is useful to assign descriptions to buffers so that we know what they are used for. Add a field to the buffer object and use that to name the various kernel side allocations which ends up looking like like this in /d/dri/X/gem: flags id ref offset kaddr size madv name 00040000: I 0 ( 1) 00000000 0000000070b79eca 00004096 memptrs vmas: [gpu: 01000000,mapped,inuse=1] 00020000: I 0 ( 1) 00000000 0000000031ed4074 00032768 ring0 Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-12-11drm/msm: Count how many times iova memory is pinnedJordan Crouse1-1/+1
Add a reference count to track how many times a particular chunk of iova memory is pinned (mapped) in the iomu and add msm_gem_unpin_iova to give up references. It is important to note that msm_gem_unpin_iova replaces msm_gem_put_iova because the new implicit behavior that an assigned iova in a given vma is now valid for the life of the buffer and what we are really focusing on is the use of that iova. For now the unmappings are lazy; once the reference counts go to zero they *COULD* be unmapped dynamically but that will require an outside force such as a shrinker or mm_notifiers. For now, we're just focusing on getting the counting right and setting ourselves up to be ready for the future. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-12-11drm/msm: Add msm_gem_get_and_pin_iova()Jordan Crouse1-1/+1
Add a new function to get and pin the iova memory in one step (basically renaming the old msm_gem_get_iova function) and switch msm_gem_get_iova() to only allocate an iova but not map it in the IOMMU. This is only currently used by msm_ioctl_gem_info() since all other users of of the iova expect that the memory be immediately available. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-12-11drm/msm: Add a common function to free kernel buffer objectsJordan Crouse1-10/+2
Buffer objects allocated with msm_gem_kernel_new() are mostly freed the same way so we can save a few lines of code with a common function. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-12-11drm/msm/gpu: Only store local command buffers in the GPU stateJordan Crouse1-10/+13
Instead of trying to store all the tagged buffers from a hanging submit only store the command buffers that were not imported. This cuts down on the amount of data stored in the GPU state to the base minimum of useful information. The downside is that this will make it more difficult to successfully replay a hang with just the GPU state but there isn't any reason why that functionality can't be added back in later once we've figured out how to better communicate such massive amounts of data. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-12-11drm/msm/gpu: Add trace events for tracking GPU submissionsJordan Crouse1-2/+21
Add trace events to track the progress of a GPU submission msm_gpu_submit occurs at the beginning of the submissions, msm_gpu_submit_flush happens when the submission is put on the ringbuffer and msm_submit_flush_retired is sent when the operation is retired. To make it easier to track the operations a unique sequence number is assigned to each submission and displayed in each event output so a human or a script can easily associate the events related to a specific submission. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-12-11drm/msm/gpu: Allocate the correct size for the GPU memptrsJordan Crouse1-1/+2
Allocate the correct buffer size for the GPU memptrs. The incorrect size hasn't affected us thus far since the incorrect size was larger than the intended size and we're still stuck on page sized granularity anyway but technically correct is the best kind of correct. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-12-11drm: msm: Use DRM_DEV_* instead of dev_*Mamta Shukla1-15/+15
Use DRM_DEV_INFO/ERROR/WARN instead of dev_info/err/debug to generate drm-formatted specific log messages so that it will be easy to differentiate in case of multiple instances of driver. Signed-off-by: Mamta Shukla <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-11-30drm/msm: Fix task dump in gpu recoverySharat Masetty1-5/+4
The current recovery code gets a pointer to the task struct and does a few things all within the rcu_read_lock. This puts constraints on the types of gfp flags that can be used within the rcu lock. This patch instead gets a reference to the task within the rcu lock and releases the lock immediately, this way the task stays afloat until we need it and we also get to use the desired gfp flags. Signed-off-by: Sharat Masetty <[email protected]> Signed-off-by: Rob Clark <[email protected]> Signed-off-by: Sean Paul <[email protected]>
2018-11-30drm/msm: Check if target supports crash dump captureSharat Masetty1-0/+4
This patch simply checks first to see if the target can support crash dump capture before proceeding. Signed-off-by: Sharat Masetty <[email protected]> Signed-off-by: Rob Clark <[email protected]> Signed-off-by: Sean Paul <[email protected]>
2018-10-04drm/msm: re-factor devfreq codeSharat Masetty1-18/+25
The devfreq framework requires the drivers to provide busy time estimations. The GPU driver relies on the hardware performance counteres for the busy time estimations, but different hardware revisions have counters which can be sourced from different clocks. So the busy time estimation will be target dependent. Additionally on targets where the clocks are completely controlled by the on chip microcontroller, fetching and setting the current GPU frequency will be different. This patch aims to embrace these differences by re-factoring the devfreq code a bit. Signed-off-by: Sharat Masetty <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-10-04drm/msm: suspend devfreq on initSharat Masetty1-0/+2
Devfreq turns on and starts recommending power level as soon as it is initialized. The GPU is still not powered on by the time the devfreq init happens and this leads to problems on GPU's where register access is needed to get/set power levels. So we start suspended and only restart devfreq when GPU is powered on. Signed-off-by: Sharat Masetty <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-10-03drm/msm/gpu: fix parameters in function msm_gpu_crashstate_captureAnders Roxell1-2/+2
When CONFIG_DEV_COREDUMP isn't defined msm_gpu_crashstate_capture doesn't pass the correct parameters. drivers/gpu/drm/msm/msm_gpu.c: In function ‘recover_worker’: drivers/gpu/drm/msm/msm_gpu.c:479:34: error: passing argument 2 of ‘msm_gpu_crashstate_capture’ from incompatible pointer type [-Werror=incompatible-pointer-types] msm_gpu_crashstate_capture(gpu, submit, comm, cmd); ^~~~~~ drivers/gpu/drm/msm/msm_gpu.c:388:13: note: expected ‘char *’ but argument is of type ‘struct msm_gem_submit *’ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, char *comm, ^~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/msm/msm_gpu.c:479:2: error: too many arguments to function ‘msm_gpu_crashstate_capture’ msm_gpu_crashstate_capture(gpu, submit, comm, cmd); ^~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/msm/msm_gpu.c:388:13: note: declared here static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, char *comm, In current code the function msm_gpu_crashstate_capture parameters. Fixes: cdb95931dea3 ("drm/msm/gpu: Add the buffer objects from the submit to the crash dump") Signed-off-by: Anders Roxell <[email protected]> Reviewed-By: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-08-10drm/msm: Add A6XX device supportJordan Crouse1-1/+1
Add support for the A6XX family of Adreno GPUs. The biggest addition is the GMU (Graphics Management Unit) which takes over most of the power management of the GPU itself but in a ironic twist of fate needs a goodly amount of management itself. Add support for the A6XX core code, the GMU and the HFI (hardware firmware interface) queue that the CPU uses to communicate with the GMU. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-08-10drm/msm: Add a helper function to parse clock namesJordan Crouse1-50/+10
Add a helper function to parse the clock names and set up the bulk data so we can take advantage of the bulk clock functions instead of rolling our own. This is added as a helper function so the upcoming a6xx GMU code can also take advantage of it. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-07-30drm/msm/gpu: avoid deprecated do_gettimeofdayArnd Bergmann1-2/+2
All users of do_gettimeofday() have been removed, but this one recently crept in, along with an incorrect printing of the microseconds portion. This converts it to using ktime_get_real_timespec64() as a direct replacement, and adds the leading zeroes. I considered using monotonic times (ktime_get()) instead, but as this timestamp appears to only be used for humans rather than compared with other timestamps, the real time domain is probably good enough. Fixes: e43b045e2c82 ("drm/msm/gpu: Capture the state of the GPU") Signed-off-by: Arnd Bergmann <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-07-30drm/msm/gpu: Add the buffer objects from the submit to the crash dumpJordan Crouse1-3/+45
For hangs, dump copy out the contents of the buffer objects attached to the guilty submission and print them in the crash dump report. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-07-30drm/msm/gpu: Capture the GPU state on a GPU hangJordan Crouse1-1/+82
Capture the GPU state on a GPU hang and store it for later playback via the devcoredump facility. Only one crash state is stored at a time on the assumption that the first hang is usually the most interesting. The existing crash state can be cleared after capturing it and then a new one will be captured on the next hang. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-07-30drm/msm/gpu: Rearrange the code that collects the task during a hangJordan Crouse1-9/+11
Do a bit of cleanup to prepare for upcoming changes to pass the hanging task comm and cmdline to the crash dump function. v2: Use GFP_ATOMIC while holding the rcu lock per Chris Wilson Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-02-20drm/msm/gpu: Set number of clocks to 0 if the list allocation failsJordan Crouse1-1/+3
If we fail to allocate gpu->grp_clks reset the number of available clocks to zero to avoid referencing the missing array later. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-02-20drm/msm: Replace gem_object deprecated functionsSteve Kowalik1-4/+4
drm_gem_object_{reference,unreference,unreference_unlocked} are deprecated functions, and merely alias to the get/put functions. Switch to the new names. Signed-off-by: Steve Kowalik <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-01-10drm/msm: Add devfreq support for the GPUJordan Crouse1-0/+91
Add support for devfreq to dynamically control the GPU frequency. By default try to use the 'simple_ondemand' governor which can adjust the frequency based on GPU load. v2: Fix __aeabi_uldivmod issue from the 0 day bot and use devfreq_recommended_opp() as suggested by Rob. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2018-01-10drm/msm/gpu: Remove unused bus scaling codeJordan Crouse1-39/+0
Remove the downstream bus scaling code. It isn't needed for for compatibility with a downstream or vendor kernel. Get it out of the way to clear space for devfreq support. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2017-12-13drm/msm: gpu: Only sync fences on rings that existJordan Crouse1-1/+1
The fault recovery code tries to sync fences on all possible rings instead of only the rings that actually exist which will fault the kernel when the number of rings are less than the maximum amount. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2017-12-13drm/msm: free kstrdup'd cmdlineRob Clark1-0/+2
Fixes: 18bb8a6 'drm/msm: show task cmdline in gpu recovery messages' Signed-off-by: Rob Clark <[email protected]>
2017-11-21treewide: setup_timer() -> timer_setup()Kees Cook1-4/+3
This converts all remaining cases of the old setup_timer() API into using timer_setup(), where the callback argument is the structure already holding the struct timer_list. These should have no behavioral changes, since they just change which pointer is passed into the callback with the same available pointers after conversion. It handles the following examples, in addition to some other variations. Casting from unsigned long: void my_callback(unsigned long data) { struct something *ptr = (struct something *)data; ... } ... setup_timer(&ptr->my_timer, my_callback, ptr); and forced object casts: void my_callback(struct something *ptr) { ... } ... setup_timer(&ptr->my_timer, my_callback, (unsigned long)ptr); become: void my_callback(struct timer_list *t) { struct something *ptr = from_timer(ptr, t, my_timer); ... } ... timer_setup(&ptr->my_timer, my_callback, 0); Direct function assignments: void my_callback(unsigned long data) { struct something *ptr = (struct something *)data; ... } ... ptr->my_timer.function = my_callback; have a temporary cast added, along with converting the args: void my_callback(struct timer_list *t) { struct something *ptr = from_timer(ptr, t, my_timer); ... } ... ptr->my_timer.function = (TIMER_FUNC_TYPE)my_callback; And finally, callbacks without a data assignment: void my_callback(unsigned long data) { ... } ... setup_timer(&ptr->my_timer, my_callback, 0); have their argument renamed to verify they're unused during conversion: void my_callback(struct timer_list *unused) { ... } ... timer_setup(&ptr->my_timer, my_callback, 0); The conversion is done with the following Coccinelle script: spatch --very-quiet --all-includes --include-headers \ -I ./arch/x86/include -I ./arch/x86/include/generated \ -I ./include -I ./arch/x86/include/uapi \ -I ./arch/x86/include/generated/uapi -I ./include/uapi \ -I ./include/generated/uapi --include ./include/linux/kconfig.h \ --dir . \ --cocci-file ~/src/data/timer_setup.cocci @fix_address_of@ expression e; @@ setup_timer( -&(e) +&e , ...) // Update any raw setup_timer() usages that have a NULL callback, but // would otherwise match change_timer_function_usage, since the latter // will update all function assignments done in the face of a NULL // function initialization in setup_timer(). @change_timer_function_usage_NULL@ expression _E; identifier _timer; type _cast_data; @@ ( -setup_timer(&_E->_timer, NULL, _E); +timer_setup(&_E->_timer, NULL, 0); | -setup_timer(&_E->_timer, NULL, (_cast_data)_E); +timer_setup(&_E->_timer, NULL, 0); | -setup_timer(&_E._timer, NULL, &_E); +timer_setup(&_E._timer, NULL, 0); | -setup_timer(&_E._timer, NULL, (_cast_data)&_E); +timer_setup(&_E._timer, NULL, 0); ) @change_timer_function_usage@ expression _E; identifier _timer; struct timer_list _stl; identifier _callback; type _cast_func, _cast_data; @@ ( -setup_timer(&_E->_timer, _callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, &_callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, _callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, &_callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)_callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)&_callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)_callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)&_callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E._timer, _callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, _callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, &_callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, &_callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | _E->_timer@_stl.function = _callback; | _E->_timer@_stl.function = &_callback; | _E->_timer@_stl.function = (_cast_func)_callback; | _E->_timer@_stl.function = (_cast_func)&_callback; | _E._timer@_stl.function = _callback; | _E._timer@_stl.function = &_callback; | _E._timer@_stl.function = (_cast_func)_callback; | _E._timer@_stl.function = (_cast_func)&_callback; ) // callback(unsigned long arg) @change_callback_handle_cast depends on change_timer_function_usage@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _origtype; identifier _origarg; type _handletype; identifier _handle; @@ void _callback( -_origtype _origarg +struct timer_list *t ) { ( ... when != _origarg _handletype *_handle = -(_handletype *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg | ... when != _origarg _handletype *_handle = -(void *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg | ... when != _origarg _handletype *_handle; ... when != _handle _handle = -(_handletype *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg | ... when != _origarg _handletype *_handle; ... when != _handle _handle = -(void *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg ) } // callback(unsigned long arg) without existing variable @change_callback_handle_cast_no_arg depends on change_timer_function_usage && !change_callback_handle_cast@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _origtype; identifier _origarg; type _handletype; @@ void _callback( -_origtype _origarg +struct timer_list *t ) { + _handletype *_origarg = from_timer(_origarg, t, _timer); + ... when != _origarg - (_handletype *)_origarg + _origarg ... when != _origarg } // Avoid already converted callbacks. @match_callback_converted depends on change_timer_function_usage && !change_callback_handle_cast && !change_callback_handle_cast_no_arg@ identifier change_timer_function_usage._callback; identifier t; @@ void _callback(struct timer_list *t) { ... } // callback(struct something *handle) @change_callback_handle_arg depends on change_timer_function_usage && !match_callback_converted && !change_callback_handle_cast && !change_callback_handle_cast_no_arg@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _handletype; identifier _handle; @@ void _callback( -_handletype *_handle +struct timer_list *t ) { + _handletype *_handle = from_timer(_handle, t, _timer); ... } // If change_callback_handle_arg ran on an empty function, remove // the added handler. @unchange_callback_handle_arg depends on change_timer_function_usage && change_callback_handle_arg@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _handletype; identifier _handle; identifier t; @@ void _callback(struct timer_list *t) { - _handletype *_handle = from_timer(_handle, t, _timer); } // We only want to refactor the setup_timer() data argument if we've found // the matching callback. This undoes changes in change_timer_function_usage. @unchange_timer_function_usage depends on change_timer_function_usage && !change_callback_handle_cast && !change_callback_handle_cast_no_arg && !change_callback_handle_arg@ expression change_timer_function_usage._E; identifier change_timer_function_usage._timer; identifier change_timer_function_usage._callback; type change_timer_function_usage._cast_data; @@ ( -timer_setup(&_E->_timer, _callback, 0); +setup_timer(&_E->_timer, _callback, (_cast_data)_E); | -timer_setup(&_E._timer, _callback, 0); +setup_timer(&_E._timer, _callback, (_cast_data)&_E); ) // If we fixed a callback from a .function assignment, fix the // assignment cast now. @change_timer_function_assignment depends on change_timer_function_usage && (change_callback_handle_cast || change_callback_handle_cast_no_arg || change_callback_handle_arg)@ expression change_timer_function_usage._E; identifier change_timer_function_usage._timer; identifier change_timer_function_usage._callback; type _cast_func; typedef TIMER_FUNC_TYPE; @@ ( _E->_timer.function = -_callback +(TIMER_FUNC_TYPE)_callback ; | _E->_timer.function = -&_callback +(TIMER_FUNC_TYPE)_callback ; | _E->_timer.function = -(_cast_func)_callback; +(TIMER_FUNC_TYPE)_callback ; | _E->_timer.function = -(_cast_func)&_callback +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -_callback +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -&_callback; +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -(_cast_func)_callback +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -(_cast_func)&_callback +(TIMER_FUNC_TYPE)_callback ; ) // Sometimes timer functions are called directly. Replace matched args. @change_timer_function_calls depends on change_timer_function_usage && (change_callback_handle_cast || change_callback_handle_cast_no_arg || change_callback_handle_arg)@ expression _E; identifier change_timer_function_usage._timer; identifier change_timer_function_usage._callback; type _cast_data; @@ _callback( ( -(_cast_data)_E +&_E->_timer | -(_cast_data)&_E +&_E._timer | -_E +&_E->_timer ) ) // If a timer has been configured without a data argument, it can be // converted without regard to the callback argument, since it is unused. @match_timer_function_unused_data@ expression _E; identifier _timer; identifier _callback; @@ ( -setup_timer(&_E->_timer, _callback, 0); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, _callback, 0L); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, _callback, 0UL); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E._timer, _callback, 0); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, _callback, 0L); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, _callback, 0UL); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_timer, _callback, 0); +timer_setup(&_timer, _callback, 0); | -setup_timer(&_timer, _callback, 0L); +timer_setup(&_timer, _callback, 0); | -setup_timer(&_timer, _callback, 0UL); +timer_setup(&_timer, _callback, 0); | -setup_timer(_timer, _callback, 0); +timer_setup(_timer, _callback, 0); | -setup_timer(_timer, _callback, 0L); +timer_setup(_timer, _callback, 0); | -setup_timer(_timer, _callback, 0UL); +timer_setup(_timer, _callback, 0); ) @change_callback_unused_data depends on match_timer_function_unused_data@ identifier match_timer_function_unused_data._callback; type _origtype; identifier _origarg; @@ void _callback( -_origtype _origarg +struct timer_list *unused ) { ... when != _origarg } Signed-off-by: Kees Cook <[email protected]>
2017-11-01drm/msm: use %z format modifier for printing size_tArnd Bergmann1-1/+1
The return type of ARRAY_SIZE() is size_t, so we have to use %zu instead of %lu to avoid this warning: drivers/gpu/drm/msm/msm_gpu.c: In function 'msm_gpu_init': drivers/gpu/drm/msm/msm_gpu.c:742:31: error: format '%lu' expects argument of type 'long unsigned int', but argument 7 has type 'unsigned int' [-Werror=format=] The warning it otherwise harmless as size_t is always the same size as unsigned long in all supported architectures, but gcc doesn't know that. Fixes: c2fceabca6d5 ("drm/msm: Support multiple ringbuffers") Signed-off-by: Arnd Bergmann <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2017-10-28drm/msm: dump submits which triggered gpu hangRob Clark1-20/+27
Note we need to move update_fences() to after msm_rd_dump_submit(), otherwise the bo's referenced by the submit may no longer be valid. Signed-off-by: Rob Clark <[email protected]>
2017-10-28drm/msm/rd: allow adding addition msg to top of dumpRob Clark1-1/+1
For faults or hangs, it is nice to be able to include a bit more information. Signed-off-by: Rob Clark <[email protected]>
2017-10-28drm/msm: split rd debugfs fileRob Clark1-1/+1
Split into two instances, the existing $debugfs/rd which continues to dump all submits, and $debugfs/hangrd which will be used to dump just submits that cause gpu hangs (and eventually faults, but that will require some iommu framework enhancements). Signed-off-by: Rob Clark <[email protected]>
2017-10-28drm/msm: show task cmdline in gpu recovery messagesRob Clark1-12/+43
Now that freedreno gallium driver defaults to using submit_queue task (render reordering), just showing task->comm is not so useful (ie. it is always "flush_queue:0"), so also dump the cmdline. This should also be more useful for piglit/shader_runner. Signed-off-by: Rob Clark <[email protected]>
2017-10-28drm/msm: Implement preemption for A5XX targetsJordan Crouse1-3/+2
Implement preemption for A5XX targets - this allows multiple ringbuffers for different priorities with automatic preemption of a lower priority ringbuffer if a higher one is ready. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2017-10-28drm/msm: Support multiple ringbuffersJordan Crouse1-52/+111
Add the infrastructure to support the idea of multiple ringbuffers. Assign each ringbuffer an id and use that as an index for the various ring specific operations. The biggest delta is to support legacy fences. Each fence gets its own sequence number but the legacy functions expect to use a unique integer. To handle this we return a unique identifier for each submission but map it to a specific ring/sequence under the covers. Newer users use a dma_fence pointer anyway so they don't care about the actual sequence ID or ring. The actual mechanics for multiple ringbuffers are very target specific so this code just allows for the possibility but still only defines one ringbuffer for each target family. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2017-10-28drm/msm: Move memptrs to msm_gpuJordan Crouse1-4/+28
When we move to multiple ringbuffers we're going to store the data in the memptrs on a per-ring basis. In order to prepare for that move the current memptrs from the adreno namespace into msm_gpu. This is way cleaner and immediately lets us kill off some sub functions so there is much less cost later when we do move to per-ring structs. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2017-08-22drm/msm: Attach the GPU MMU when it is createdJordan Crouse1-29/+56
Currently the GPU MMU is attached in the adreno_gpu code but as more and more of the GPU initialization moves to the generic GPU path we have a need to map and use GPU memory earlier and earlier. There isn't any reason to defer attaching the MMU until later so attach it right after the address space is created so it can be used immediately. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2017-06-17drm/msm: Separate locking of buffer resources from struct_mutexSushmita Susheelendra1-3/+1
Buffer object specific resources like pages, domains, sg list need not be protected with struct_mutex. They can be protected with a buffer object level lock. This simplifies locking and makes it easier to avoid potential recursive locking scenarios for SVM involving mmap_sem and struct_mutex. This also removes unnecessary serialization when creating buffer objects, and also between buffer object creation and GPU command submission. Signed-off-by: Sushmita Susheelendra <[email protected]> [robclark: squash in handling new locking for shrinker] Signed-off-by: Rob Clark <[email protected]>
2017-06-16drm/msm: remove address-space idRob Clark1-2/+0
Now that the msm_gem supports an arbitrary number of vma's, we no longer need to assign an id (index) to each address space. So rip out the associated code. Signed-off-by: Rob Clark <[email protected]>
2017-06-16drm/msm: pass address-space to _get_iova() and friendsRob Clark1-3/+3
No functional change, that will come later. But this will make it easier to deal with dynamically created address spaces (ie. per- process pagetables for gpu). Signed-off-by: Rob Clark <[email protected]>
2017-06-16drm/msm: fix locking inconsistency for gpu->hw_init()Rob Clark1-0/+2
Most, but not all, paths where calling the with struct_mutex held. The fast-path in msm_gem_get_iova() (plus some sub-code-paths that only run the first time) was masking this issue. So lets just always hold struct_mutex for hw_init(). And sprinkle some WARN_ON()'s and might_lock() to avoid this sort of problem in the future. Signed-off-by: Rob Clark <[email protected]>
2017-06-16drm/msm: Add a struct to pass configuration to msm_gpu_init()Jordan Crouse1-7/+6
The amount of information that we need to pass into msm_gpu_init() is steadily increasing, so add a new struct to stabilize the function call and make it easier to add new configuration down the line. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2017-05-27drm/msm/gpu: check legacy clk names in get_clocks()Rob Clark1-2/+2
Otherwise if someone was using old bindings with "core_clk" instead of "core" as the clock name, we'd never find it and gpu would be stuck at 27MHz (or whatever it's slowest rate is). Fixes: 98db803 ("msm/drm: gpu: Dynamically locate the clocks from the device tree") Signed-off-by: Rob Clark <[email protected]>
2017-04-08msm/drm: gpu: Dynamically locate the clocks from the device treeJordan Crouse1-23/+55
Instead of using a fixed list of clock names use the clock-names list in the device tree to discover and get the list of clocks that we need. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>
2017-04-08drm/msm: Hard code the GPU "slow frequency"Jordan Crouse1-2/+6
Some A3XX and A4XX GPU targets required that the GPU clock be programmed to a non zero value when it was disabled so 27Mhz was chosen as the "invalid" frequency. Even though newer targets do not have the same clock restrictions we still write 27Mhz on clock disable and expect the clock subsystem to round down to zero. For unknown reasons even though the slow clock speed is always 27Mhz and it isn't actually a functional level the legacy device tree frequency tables always defined it and then did gymnastics to work around it. Instead of playing the same silly games just hard code the "slow" clock speed in the code as 27MHz and save ourselves a bit of infrastructure. Signed-off-by: Jordan Crouse <[email protected]> Signed-off-by: Rob Clark <[email protected]>