diff options
Diffstat (limited to 'drivers/gpu/drm/amd')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 38 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 4 |
3 files changed, 31 insertions, 19 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index e9fde72cf038..31b00f91cfcd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
| @@ -1866,6 +1866,12 @@ typedef void (*amdgpu_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t); | |||
| 1866 | typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t); | 1866 | typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t); |
| 1867 | typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t); | 1867 | typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t); |
| 1868 | 1868 | ||
| 1869 | struct amdgpu_ip_block_status { | ||
| 1870 | bool valid; | ||
| 1871 | bool sw; | ||
| 1872 | bool hw; | ||
| 1873 | }; | ||
| 1874 | |||
| 1869 | struct amdgpu_device { | 1875 | struct amdgpu_device { |
| 1870 | struct device *dev; | 1876 | struct device *dev; |
| 1871 | struct drm_device *ddev; | 1877 | struct drm_device *ddev; |
| @@ -2008,7 +2014,7 @@ struct amdgpu_device { | |||
| 2008 | 2014 | ||
| 2009 | const struct amdgpu_ip_block_version *ip_blocks; | 2015 | const struct amdgpu_ip_block_version *ip_blocks; |
| 2010 | int num_ip_blocks; | 2016 | int num_ip_blocks; |
| 2011 | bool *ip_block_enabled; | 2017 | struct amdgpu_ip_block_status *ip_block_status; |
| 2012 | struct mutex mn_lock; | 2018 | struct mutex mn_lock; |
| 2013 | DECLARE_HASHTABLE(mn_hash, 7); | 2019 | DECLARE_HASHTABLE(mn_hash, 7); |
| 2014 | 2020 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index d79009b65867..99f158e1baff 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
| @@ -1191,8 +1191,9 @@ static int amdgpu_early_init(struct amdgpu_device *adev) | |||
| 1191 | return -EINVAL; | 1191 | return -EINVAL; |
| 1192 | } | 1192 | } |
| 1193 | 1193 | ||
| 1194 | adev->ip_block_enabled = kcalloc(adev->num_ip_blocks, sizeof(bool), GFP_KERNEL); | 1194 | adev->ip_block_status = kcalloc(adev->num_ip_blocks, |
| 1195 | if (adev->ip_block_enabled == NULL) | 1195 | sizeof(struct amdgpu_ip_block_status), GFP_KERNEL); |
| 1196 | if (adev->ip_block_status == NULL) | ||
| 1196 | return -ENOMEM; | 1197 | return -ENOMEM; |
| 1197 | 1198 | ||
| 1198 | if (adev->ip_blocks == NULL) { | 1199 | if (adev->ip_blocks == NULL) { |
| @@ -1203,18 +1204,18 @@ static int amdgpu_early_init(struct amdgpu_device *adev) | |||
| 1203 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1204 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 1204 | if ((amdgpu_ip_block_mask & (1 << i)) == 0) { | 1205 | if ((amdgpu_ip_block_mask & (1 << i)) == 0) { |
| 1205 | DRM_ERROR("disabled ip block: %d\n", i); | 1206 | DRM_ERROR("disabled ip block: %d\n", i); |
| 1206 | adev->ip_block_enabled[i] = false; | 1207 | adev->ip_block_status[i].valid = false; |
| 1207 | } else { | 1208 | } else { |
| 1208 | if (adev->ip_blocks[i].funcs->early_init) { | 1209 | if (adev->ip_blocks[i].funcs->early_init) { |
| 1209 | r = adev->ip_blocks[i].funcs->early_init((void *)adev); | 1210 | r = adev->ip_blocks[i].funcs->early_init((void *)adev); |
| 1210 | if (r == -ENOENT) | 1211 | if (r == -ENOENT) |
| 1211 | adev->ip_block_enabled[i] = false; | 1212 | adev->ip_block_status[i].valid = false; |
| 1212 | else if (r) | 1213 | else if (r) |
| 1213 | return r; | 1214 | return r; |
| 1214 | else | 1215 | else |
| 1215 | adev->ip_block_enabled[i] = true; | 1216 | adev->ip_block_status[i].valid = true; |
| 1216 | } else { | 1217 | } else { |
| 1217 | adev->ip_block_enabled[i] = true; | 1218 | adev->ip_block_status[i].valid = true; |
| 1218 | } | 1219 | } |
| 1219 | } | 1220 | } |
| 1220 | } | 1221 | } |
| @@ -1227,11 +1228,12 @@ static int amdgpu_init(struct amdgpu_device *adev) | |||
| 1227 | int i, r; | 1228 | int i, r; |
| 1228 | 1229 | ||
| 1229 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1230 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 1230 | if (!adev->ip_block_enabled[i]) | 1231 | if (!adev->ip_block_status[i].valid) |
| 1231 | continue; | 1232 | continue; |
| 1232 | r = adev->ip_blocks[i].funcs->sw_init((void *)adev); | 1233 | r = adev->ip_blocks[i].funcs->sw_init((void *)adev); |
| 1233 | if (r) | 1234 | if (r) |
| 1234 | return r; | 1235 | return r; |
| 1236 | adev->ip_block_status[i].sw = true; | ||
| 1235 | /* need to do gmc hw init early so we can allocate gpu mem */ | 1237 | /* need to do gmc hw init early so we can allocate gpu mem */ |
| 1236 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) { | 1238 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) { |
| 1237 | r = amdgpu_vram_scratch_init(adev); | 1239 | r = amdgpu_vram_scratch_init(adev); |
| @@ -1243,11 +1245,12 @@ static int amdgpu_init(struct amdgpu_device *adev) | |||
| 1243 | r = amdgpu_wb_init(adev); | 1245 | r = amdgpu_wb_init(adev); |
| 1244 | if (r) | 1246 | if (r) |
| 1245 | return r; | 1247 | return r; |
| 1248 | adev->ip_block_status[i].hw = true; | ||
| 1246 | } | 1249 | } |
| 1247 | } | 1250 | } |
| 1248 | 1251 | ||
| 1249 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1252 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 1250 | if (!adev->ip_block_enabled[i]) | 1253 | if (!adev->ip_block_status[i].sw) |
| 1251 | continue; | 1254 | continue; |
| 1252 | /* gmc hw init is done early */ | 1255 | /* gmc hw init is done early */ |
| 1253 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) | 1256 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) |
| @@ -1255,6 +1258,7 @@ static int amdgpu_init(struct amdgpu_device *adev) | |||
| 1255 | r = adev->ip_blocks[i].funcs->hw_init((void *)adev); | 1258 | r = adev->ip_blocks[i].funcs->hw_init((void *)adev); |
| 1256 | if (r) | 1259 | if (r) |
| 1257 | return r; | 1260 | return r; |
| 1261 | adev->ip_block_status[i].hw = true; | ||
| 1258 | } | 1262 | } |
| 1259 | 1263 | ||
| 1260 | return 0; | 1264 | return 0; |
| @@ -1265,7 +1269,7 @@ static int amdgpu_late_init(struct amdgpu_device *adev) | |||
| 1265 | int i = 0, r; | 1269 | int i = 0, r; |
| 1266 | 1270 | ||
| 1267 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1271 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 1268 | if (!adev->ip_block_enabled[i]) | 1272 | if (!adev->ip_block_status[i].valid) |
| 1269 | continue; | 1273 | continue; |
| 1270 | /* enable clockgating to save power */ | 1274 | /* enable clockgating to save power */ |
| 1271 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, | 1275 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, |
| @@ -1287,7 +1291,7 @@ static int amdgpu_fini(struct amdgpu_device *adev) | |||
| 1287 | int i, r; | 1291 | int i, r; |
| 1288 | 1292 | ||
| 1289 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | 1293 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { |
| 1290 | if (!adev->ip_block_enabled[i]) | 1294 | if (!adev->ip_block_status[i].hw) |
| 1291 | continue; | 1295 | continue; |
| 1292 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) { | 1296 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) { |
| 1293 | amdgpu_wb_fini(adev); | 1297 | amdgpu_wb_fini(adev); |
| @@ -1300,14 +1304,16 @@ static int amdgpu_fini(struct amdgpu_device *adev) | |||
| 1300 | return r; | 1304 | return r; |
| 1301 | r = adev->ip_blocks[i].funcs->hw_fini((void *)adev); | 1305 | r = adev->ip_blocks[i].funcs->hw_fini((void *)adev); |
| 1302 | /* XXX handle errors */ | 1306 | /* XXX handle errors */ |
| 1307 | adev->ip_block_status[i].hw = false; | ||
| 1303 | } | 1308 | } |
| 1304 | 1309 | ||
| 1305 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | 1310 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { |
| 1306 | if (!adev->ip_block_enabled[i]) | 1311 | if (!adev->ip_block_status[i].sw) |
| 1307 | continue; | 1312 | continue; |
| 1308 | r = adev->ip_blocks[i].funcs->sw_fini((void *)adev); | 1313 | r = adev->ip_blocks[i].funcs->sw_fini((void *)adev); |
| 1309 | /* XXX handle errors */ | 1314 | /* XXX handle errors */ |
| 1310 | adev->ip_block_enabled[i] = false; | 1315 | adev->ip_block_status[i].sw = false; |
| 1316 | adev->ip_block_status[i].valid = false; | ||
| 1311 | } | 1317 | } |
| 1312 | 1318 | ||
| 1313 | return 0; | 1319 | return 0; |
| @@ -1318,7 +1324,7 @@ static int amdgpu_suspend(struct amdgpu_device *adev) | |||
| 1318 | int i, r; | 1324 | int i, r; |
| 1319 | 1325 | ||
| 1320 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | 1326 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { |
| 1321 | if (!adev->ip_block_enabled[i]) | 1327 | if (!adev->ip_block_status[i].valid) |
| 1322 | continue; | 1328 | continue; |
| 1323 | /* ungate blocks so that suspend can properly shut them down */ | 1329 | /* ungate blocks so that suspend can properly shut them down */ |
| 1324 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, | 1330 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, |
| @@ -1336,7 +1342,7 @@ static int amdgpu_resume(struct amdgpu_device *adev) | |||
| 1336 | int i, r; | 1342 | int i, r; |
| 1337 | 1343 | ||
| 1338 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1344 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 1339 | if (!adev->ip_block_enabled[i]) | 1345 | if (!adev->ip_block_status[i].valid) |
| 1340 | continue; | 1346 | continue; |
| 1341 | r = adev->ip_blocks[i].funcs->resume(adev); | 1347 | r = adev->ip_blocks[i].funcs->resume(adev); |
| 1342 | if (r) | 1348 | if (r) |
| @@ -1582,8 +1588,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev) | |||
| 1582 | amdgpu_fence_driver_fini(adev); | 1588 | amdgpu_fence_driver_fini(adev); |
| 1583 | amdgpu_fbdev_fini(adev); | 1589 | amdgpu_fbdev_fini(adev); |
| 1584 | r = amdgpu_fini(adev); | 1590 | r = amdgpu_fini(adev); |
| 1585 | kfree(adev->ip_block_enabled); | 1591 | kfree(adev->ip_block_status); |
| 1586 | adev->ip_block_enabled = NULL; | 1592 | adev->ip_block_status = NULL; |
| 1587 | adev->accel_working = false; | 1593 | adev->accel_working = false; |
| 1588 | /* free i2c buses */ | 1594 | /* free i2c buses */ |
| 1589 | amdgpu_i2c_fini(adev); | 1595 | amdgpu_i2c_fini(adev); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 31ad444c6386..d316bda3d7ae 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
| @@ -235,7 +235,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
| 235 | 235 | ||
| 236 | for (i = 0; i < adev->num_ip_blocks; i++) { | 236 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 237 | if (adev->ip_blocks[i].type == type && | 237 | if (adev->ip_blocks[i].type == type && |
| 238 | adev->ip_block_enabled[i]) { | 238 | adev->ip_block_status[i].valid) { |
| 239 | ip.hw_ip_version_major = adev->ip_blocks[i].major; | 239 | ip.hw_ip_version_major = adev->ip_blocks[i].major; |
| 240 | ip.hw_ip_version_minor = adev->ip_blocks[i].minor; | 240 | ip.hw_ip_version_minor = adev->ip_blocks[i].minor; |
| 241 | ip.capabilities_flags = 0; | 241 | ip.capabilities_flags = 0; |
| @@ -274,7 +274,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
| 274 | 274 | ||
| 275 | for (i = 0; i < adev->num_ip_blocks; i++) | 275 | for (i = 0; i < adev->num_ip_blocks; i++) |
| 276 | if (adev->ip_blocks[i].type == type && | 276 | if (adev->ip_blocks[i].type == type && |
| 277 | adev->ip_block_enabled[i] && | 277 | adev->ip_block_status[i].valid && |
| 278 | count < AMDGPU_HW_IP_INSTANCE_MAX_COUNT) | 278 | count < AMDGPU_HW_IP_INSTANCE_MAX_COUNT) |
| 279 | count++; | 279 | count++; |
| 280 | 280 | ||
