FILE
panthor_hw.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/panthor/panthor_hw.c
1// SPDX-License-Identifier: GPL-2.0 or MIT 2/* Copyright 2025 ARM Limited. All rights reserved. */ 3 4#include <drm/drm_print.h> 5 6#include "panthor_device.h" 7#include "panthor_gpu.h" 8#include "panthor_hw.h" 9#include "panthor_pwr.h" 10#include "panthor_regs.h" 11 12#define GPU_PROD_ID_MAKE(arch_major, prod_major) \ 13 (((arch_major) << 24) | (prod_major)) 14 15/** struct panthor_hw_entry - HW arch major to panthor_hw binding entry */ 16struct panthor_hw_entry { 17 /** @arch_min: Minimum supported architecture major value (inclusive) */ 18 u8 arch_min; 19 20 /** @arch_max: Maximum supported architecture major value (inclusive) */ 21 u8 arch_max; 22 23 /** @hwdev: Pointer to panthor_hw structure */ 24 struct panthor_hw *hwdev; 25}; 26 27static struct panthor_hw panthor_hw_arch_v10 = { 28 .ops = { 29 .soft_reset = panthor_gpu_soft_reset, 30 .l2_power_off = panthor_gpu_l2_power_off, 31 .l2_power_on = panthor_gpu_l2_power_on, 32 }, 33}; 34 35static struct panthor_hw panthor_hw_arch_v14 = { 36 .ops = { 37 .soft_reset = panthor_pwr_reset_soft, 38 .l2_power_off = panthor_pwr_l2_power_off, 39 .l2_power_on = panthor_pwr_l2_power_on, 40 }, 41}; 42 43static struct panthor_hw_entry panthor_hw_match[] = { 44 { 45 .arch_min = 10, 46 .arch_max = 13, 47 .hwdev = &panthor_hw_arch_v10, 48 }, 49 { 50 .arch_min = 14, 51 .arch_max = 14, 52 .hwdev = &panthor_hw_arch_v14, 53 }, 54}; 55 56static char *get_gpu_model_name(struct panthor_device *ptdev) 57{ 58 const u32 gpu_id = ptdev->gpu_info.gpu_id; 59 const u32 product_id = GPU_PROD_ID_MAKE(GPU_ARCH_MAJOR(gpu_id), 60 GPU_PROD_MAJOR(gpu_id)); 61 const bool ray_intersection = !!(ptdev->gpu_info.gpu_features & 62 GPU_FEATURES_RAY_INTERSECTION); 63 const u8 shader_core_count = hweight64(ptdev->gpu_info.shader_present); 64 65 switch (product_id) { 66 case GPU_PROD_ID_MAKE(10, 2): 67 return "Mali-G710"; 68 case GPU_PROD_ID_MAKE(10, 3): 69 return "Mali-G510"; 70 case GPU_PROD_ID_MAKE(10, 4): 71 return "Mali-G310"; 72 case GPU_PROD_ID_MAKE(10, 7): 73 return "Mali-G610"; 74 case GPU_PROD_ID_MAKE(11, 2): 75 if (shader_core_count > 10 && ray_intersection) 76 return "Mali-G715-Immortalis"; 77 else if (shader_core_count >= 7) 78 return "Mali-G715"; 79 80 fallthrough; 81 case GPU_PROD_ID_MAKE(11, 3): 82 return "Mali-G615"; 83 case GPU_PROD_ID_MAKE(12, 0): 84 if (shader_core_count >= 10 && ray_intersection) 85 return "Mali-G720-Immortalis"; 86 else if (shader_core_count >= 6) 87 return "Mali-G720"; 88 89 fallthrough; 90 case GPU_PROD_ID_MAKE(12, 1): 91 return "Mali-G620"; 92 case GPU_PROD_ID_MAKE(13, 0): 93 if (shader_core_count >= 10 && ray_intersection) 94 return "Mali-G925-Immortalis"; 95 else if (shader_core_count >= 6) 96 return "Mali-G725"; 97 98 fallthrough; 99 case GPU_PROD_ID_MAKE(13, 1): 100 return "Mali-G625"; 101 case GPU_PROD_ID_MAKE(14, 0): 102 return "Mali-G1-Ultra"; 103 case GPU_PROD_ID_MAKE(14, 1): 104 return "Mali-G1-Premium"; 105 case GPU_PROD_ID_MAKE(14, 3): 106 return "Mali-G1-Pro"; 107 } 108 109 return "(Unknown Mali GPU)"; 110} 111 112static void panthor_gpu_info_init(struct panthor_device *ptdev) 113{ 114 unsigned int i; 115 116 ptdev->gpu_info.csf_id = gpu_read(ptdev, GPU_CSF_ID); 117 ptdev->gpu_info.gpu_rev = gpu_read(ptdev, GPU_REVID); 118 ptdev->gpu_info.core_features = gpu_read(ptdev, GPU_CORE_FEATURES); 119 ptdev->gpu_info.l2_features = gpu_read(ptdev, GPU_L2_FEATURES); 120 ptdev->gpu_info.tiler_features = gpu_read(ptdev, GPU_TILER_FEATURES); 121 ptdev->gpu_info.mem_features = gpu_read(ptdev, GPU_MEM_FEATURES); 122 ptdev->gpu_info.mmu_features = gpu_read(ptdev, GPU_MMU_FEATURES); 123 ptdev->gpu_info.thread_features = gpu_read(ptdev, GPU_THREAD_FEATURES); 124 ptdev->gpu_info.max_threads = gpu_read(ptdev, GPU_THREAD_MAX_THREADS); 125 ptdev->gpu_info.thread_max_workgroup_size = gpu_read(ptdev, GPU_THREAD_MAX_WORKGROUP_SIZE); 126 ptdev->gpu_info.thread_max_barrier_size = gpu_read(ptdev, GPU_THREAD_MAX_BARRIER_SIZE); 127 ptdev->gpu_info.coherency_features = gpu_read(ptdev, GPU_COHERENCY_FEATURES); 128 for (i = 0; i < 4; i++) 129 ptdev->gpu_info.texture_features[i] = gpu_read(ptdev, GPU_TEXTURE_FEATURES(i)); 130 131 ptdev->gpu_info.as_present = gpu_read(ptdev, GPU_AS_PRESENT); 132 133 /* Introduced in arch 11.x */ 134 ptdev->gpu_info.gpu_features = gpu_read64(ptdev, GPU_FEATURES); 135 136 if (panthor_hw_has_pwr_ctrl(ptdev)) { 137 /* Introduced in arch 14.x */ 138 ptdev->gpu_info.l2_present = gpu_read64(ptdev, PWR_L2_PRESENT); 139 ptdev->gpu_info.tiler_present = gpu_read64(ptdev, PWR_TILER_PRESENT); 140 ptdev->gpu_info.shader_present = gpu_read64(ptdev, PWR_SHADER_PRESENT); 141 } else { 142 ptdev->gpu_info.shader_present = gpu_read64(ptdev, GPU_SHADER_PRESENT); 143 ptdev->gpu_info.tiler_present = gpu_read64(ptdev, GPU_TILER_PRESENT); 144 ptdev->gpu_info.l2_present = gpu_read64(ptdev, GPU_L2_PRESENT); 145 } 146} 147 148static void panthor_hw_info_init(struct panthor_device *ptdev) 149{ 150 u32 major, minor, status; 151 152 panthor_gpu_info_init(ptdev); 153 154 major = GPU_VER_MAJOR(ptdev->gpu_info.gpu_id); 155 minor = GPU_VER_MINOR(ptdev->gpu_info.gpu_id); 156 status = GPU_VER_STATUS(ptdev->gpu_info.gpu_id); 157 158 drm_info(&ptdev->base, 159 "%s id 0x%x major 0x%x minor 0x%x status 0x%x", 160 get_gpu_model_name(ptdev), ptdev->gpu_info.gpu_id >> 16, 161 major, minor, status); 162 163 drm_info(&ptdev->base, 164 "Features: L2:%#x Tiler:%#x Mem:%#x MMU:%#x AS:%#x", 165 ptdev->gpu_info.l2_features, 166 ptdev->gpu_info.tiler_features, 167 ptdev->gpu_info.mem_features, 168 ptdev->gpu_info.mmu_features, 169 ptdev->gpu_info.as_present); 170 171 drm_info(&ptdev->base, 172 "shader_present=0x%0llx l2_present=0x%0llx tiler_present=0x%0llx", 173 ptdev->gpu_info.shader_present, ptdev->gpu_info.l2_present, 174 ptdev->gpu_info.tiler_present); 175} 176 177static int panthor_hw_bind_device(struct panthor_device *ptdev) 178{ 179 struct panthor_hw *hdev = NULL; 180 const u32 arch_major = GPU_ARCH_MAJOR(ptdev->gpu_info.gpu_id); 181 int i = 0; 182 183 for (i = 0; i < ARRAY_SIZE(panthor_hw_match); i++) { 184 struct panthor_hw_entry *entry = &panthor_hw_match[i]; 185 186 if (arch_major >= entry->arch_min && arch_major <= entry->arch_max) { 187 hdev = entry->hwdev; 188 break; 189 } 190 } 191 192 if (!hdev) 193 return -EOPNOTSUPP; 194 195 ptdev->hw = hdev; 196 197 return 0; 198} 199 200static int panthor_hw_gpu_id_init(struct panthor_device *ptdev) 201{ 202 ptdev->gpu_info.gpu_id = gpu_read(ptdev, GPU_ID); 203 if (!ptdev->gpu_info.gpu_id) 204 return -ENXIO; 205 206 return 0; 207} 208 209int panthor_hw_init(struct panthor_device *ptdev) 210{ 211 int ret = 0; 212 213 ret = panthor_hw_gpu_id_init(ptdev); 214 if (ret) 215 return ret; 216 217 ret = panthor_hw_bind_device(ptdev); 218 if (ret) 219 return ret; 220 221 panthor_hw_info_init(ptdev); 222 223 return 0; 224}
~/
Read-only file preview.