1/* 2 * Copyright 2014 Advanced Micro Devices, Inc. 3 * Copyright 2008 Red Hat Inc. 4 * Copyright 2009 Jerome Glisse. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 */ 25#include <drm/drmP.h> 26#include "amdgpu.h" 27 28/* 29 * GPU scratch registers helpers function. 30 */ 31/** 32 * amdgpu_gfx_scratch_get - Allocate a scratch register 33 * 34 * @adev: amdgpu_device pointer 35 * @reg: scratch register mmio offset 36 * 37 * Allocate a CP scratch register for use by the driver (all asics). 38 * Returns 0 on success or -EINVAL on failure. 39 */ 40int amdgpu_gfx_scratch_get(struct amdgpu_device *adev, uint32_t *reg) 41{ 42 int i; 43 44 for (i = 0; i < adev->gfx.scratch.num_reg; i++) { 45 if (adev->gfx.scratch.free[i]) { 46 adev->gfx.scratch.free[i] = false; 47 *reg = adev->gfx.scratch.reg[i]; 48 return 0; 49 } 50 } 51 return -EINVAL; 52} 53 54/** 55 * amdgpu_gfx_scratch_free - Free a scratch register 56 * 57 * @adev: amdgpu_device pointer 58 * @reg: scratch register mmio offset 59 * 60 * Free a CP scratch register allocated for use by the driver (all asics) 61 */ 62void amdgpu_gfx_scratch_free(struct amdgpu_device *adev, uint32_t reg) 63{ 64 int i; 65 66 for (i = 0; i < adev->gfx.scratch.num_reg; i++) { 67 if (adev->gfx.scratch.reg[i] == reg) { 68 adev->gfx.scratch.free[i] = true; 69 return; 70 } 71 } 72} 73 74/** 75 * amdgpu_gfx_parse_disable_cu - Parse the disable_cu module parameter 76 * 77 * @mask: array in which the per-shader array disable masks will be stored 78 * @max_se: number of SEs 79 * @max_sh: number of SHs 80 * 81 * The bitmask of CUs to be disabled in the shader array determined by se and 82 * sh is stored in mask[se * max_sh + sh]. 83 */ 84void amdgpu_gfx_parse_disable_cu(unsigned *mask, unsigned max_se, unsigned max_sh) 85{ 86 unsigned se, sh, cu; 87 const char *p; 88 89 memset(mask, 0, sizeof(*mask) * max_se * max_sh); 90 91 if (!amdgpu_disable_cu || !*amdgpu_disable_cu) 92 return; 93 94 p = amdgpu_disable_cu; 95 for (;;) { 96 char *next; 97 int ret = sscanf(p, "%u.%u.%u", &se, &sh, &cu); 98 if (ret < 3) { 99 DRM_ERROR("amdgpu: could not parse disable_cu\n"); 100 return; 101 } 102 103 if (se < max_se && sh < max_sh && cu < 16) { 104 DRM_INFO("amdgpu: disabling CU %u.%u.%u\n", se, sh, cu); 105 mask[se * max_sh + sh] |= 1u << cu; 106 } else { 107 DRM_ERROR("amdgpu: disable_cu %u.%u.%u is out of range\n", 108 se, sh, cu); 109 } 110 111 next = strchr(p, ','); 112 if (!next) 113 break; 114 p = next + 1; 115 } 116} 117