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 #include "amdgpu_gfx.h" 28 29 /* 30 * GPU scratch registers helpers function. 31 */ 32 /** 33 * amdgpu_gfx_scratch_get - Allocate a scratch register 34 * 35 * @adev: amdgpu_device pointer 36 * @reg: scratch register mmio offset 37 * 38 * Allocate a CP scratch register for use by the driver (all asics). 39 * Returns 0 on success or -EINVAL on failure. 40 */ 41 int amdgpu_gfx_scratch_get(struct amdgpu_device *adev, uint32_t *reg) 42 { 43 int i; 44 45 for (i = 0; i < adev->gfx.scratch.num_reg; i++) { 46 if (adev->gfx.scratch.free[i]) { 47 adev->gfx.scratch.free[i] = false; 48 *reg = adev->gfx.scratch.reg[i]; 49 return 0; 50 } 51 } 52 return -EINVAL; 53 } 54 55 /** 56 * amdgpu_gfx_scratch_free - Free a scratch register 57 * 58 * @adev: amdgpu_device pointer 59 * @reg: scratch register mmio offset 60 * 61 * Free a CP scratch register allocated for use by the driver (all asics) 62 */ 63 void amdgpu_gfx_scratch_free(struct amdgpu_device *adev, uint32_t reg) 64 { 65 int i; 66 67 for (i = 0; i < adev->gfx.scratch.num_reg; i++) { 68 if (adev->gfx.scratch.reg[i] == reg) { 69 adev->gfx.scratch.free[i] = true; 70 return; 71 } 72 } 73 } 74 75 /** 76 * amdgpu_gfx_parse_disable_cu - Parse the disable_cu module parameter 77 * 78 * @mask: array in which the per-shader array disable masks will be stored 79 * @max_se: number of SEs 80 * @max_sh: number of SHs 81 * 82 * The bitmask of CUs to be disabled in the shader array determined by se and 83 * sh is stored in mask[se * max_sh + sh]. 84 */ 85 void amdgpu_gfx_parse_disable_cu(unsigned *mask, unsigned max_se, unsigned max_sh) 86 { 87 unsigned se, sh, cu; 88 const char *p; 89 90 memset(mask, 0, sizeof(*mask) * max_se * max_sh); 91 92 if (!amdgpu_disable_cu || !*amdgpu_disable_cu) 93 return; 94 95 p = amdgpu_disable_cu; 96 for (;;) { 97 char *next; 98 int ret = sscanf(p, "%u.%u.%u", &se, &sh, &cu); 99 if (ret < 3) { 100 DRM_ERROR("amdgpu: could not parse disable_cu\n"); 101 return; 102 } 103 104 if (se < max_se && sh < max_sh && cu < 16) { 105 DRM_INFO("amdgpu: disabling CU %u.%u.%u\n", se, sh, cu); 106 mask[se * max_sh + sh] |= 1u << cu; 107 } else { 108 DRM_ERROR("amdgpu: disable_cu %u.%u.%u is out of range\n", 109 se, sh, cu); 110 } 111 112 next = strchr(p, ','); 113 if (!next) 114 break; 115 p = next + 1; 116 } 117 } 118