Skip to content

Commit 0844708

Browse files
committed
Merge tag 'amd-drm-fixes-5.13-2021-05-05' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-fixes-5.13-2021-05-05: amdgpu: - MPO hang workaround - Fix for concurrent VM flushes on vega/navi - dcefclk is not adjustable on navi1x and newer - MST HPD debugfs fix - Suspend/resumes fixes - Register VGA clients late in case driver fails to load - Fix GEM leak in user framebuffer create - Add support for polaris12 with 32 bit memory interface - Fix duplicate cursor issue when using overlay - Fix corruption with tiled surfaces on VCN3 - Add BO size and stride check to fix BO size verification radeon: - Fix off-by-one in power state parsing - Fix possible memory leak in power state parsing Signed-off-by: Dave Airlie <[email protected]> From: Alex Deucher <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 59e528c + 234055f commit 0844708

File tree

14 files changed

+328
-45
lines changed

14 files changed

+328
-45
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3410,19 +3410,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
34103410
/* doorbell bar mapping and doorbell index init*/
34113411
amdgpu_device_doorbell_init(adev);
34123412

3413-
/* if we have > 1 VGA cards, then disable the amdgpu VGA resources */
3414-
/* this will fail for cards that aren't VGA class devices, just
3415-
* ignore it */
3416-
if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
3417-
vga_client_register(adev->pdev, adev, NULL, amdgpu_device_vga_set_decode);
3418-
3419-
if (amdgpu_device_supports_px(ddev)) {
3420-
px = true;
3421-
vga_switcheroo_register_client(adev->pdev,
3422-
&amdgpu_switcheroo_ops, px);
3423-
vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain);
3424-
}
3425-
34263413
if (amdgpu_emu_mode == 1) {
34273414
/* post the asic on emulation mode */
34283415
emu_soc_asic_init(adev);
@@ -3619,6 +3606,19 @@ int amdgpu_device_init(struct amdgpu_device *adev,
36193606
if (amdgpu_device_cache_pci_state(adev->pdev))
36203607
pci_restore_state(pdev);
36213608

3609+
/* if we have > 1 VGA cards, then disable the amdgpu VGA resources */
3610+
/* this will fail for cards that aren't VGA class devices, just
3611+
* ignore it */
3612+
if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
3613+
vga_client_register(adev->pdev, adev, NULL, amdgpu_device_vga_set_decode);
3614+
3615+
if (amdgpu_device_supports_px(ddev)) {
3616+
px = true;
3617+
vga_switcheroo_register_client(adev->pdev,
3618+
&amdgpu_switcheroo_ops, px);
3619+
vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain);
3620+
}
3621+
36223622
if (adev->gmc.xgmi.pending_reset)
36233623
queue_delayed_work(system_wq, &mgpu_info.delayed_reset_work,
36243624
msecs_to_jiffies(AMDGPU_RESUME_MS));
@@ -3630,8 +3630,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
36303630

36313631
failed:
36323632
amdgpu_vf_error_trans_all(adev);
3633-
if (px)
3634-
vga_switcheroo_fini_domain_pm_ops(adev->dev);
36353633

36363634
failed_unmap:
36373635
iounmap(adev->rmmio);

drivers/gpu/drm/amd/amdgpu/amdgpu_display.c

Lines changed: 177 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,174 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
837837
return 0;
838838
}
839839

840+
static void get_block_dimensions(unsigned int block_log2, unsigned int cpp,
841+
unsigned int *width, unsigned int *height)
842+
{
843+
unsigned int cpp_log2 = ilog2(cpp);
844+
unsigned int pixel_log2 = block_log2 - cpp_log2;
845+
unsigned int width_log2 = (pixel_log2 + 1) / 2;
846+
unsigned int height_log2 = pixel_log2 - width_log2;
847+
848+
*width = 1 << width_log2;
849+
*height = 1 << height_log2;
850+
}
851+
852+
static unsigned int get_dcc_block_size(uint64_t modifier, bool rb_aligned,
853+
bool pipe_aligned)
854+
{
855+
unsigned int ver = AMD_FMT_MOD_GET(TILE_VERSION, modifier);
856+
857+
switch (ver) {
858+
case AMD_FMT_MOD_TILE_VER_GFX9: {
859+
/*
860+
* TODO: for pipe aligned we may need to check the alignment of the
861+
* total size of the surface, which may need to be bigger than the
862+
* natural alignment due to some HW workarounds
863+
*/
864+
return max(10 + (rb_aligned ? (int)AMD_FMT_MOD_GET(RB, modifier) : 0), 12);
865+
}
866+
case AMD_FMT_MOD_TILE_VER_GFX10:
867+
case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS: {
868+
int pipes_log2 = AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier);
869+
870+
if (ver == AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS && pipes_log2 > 1 &&
871+
AMD_FMT_MOD_GET(PACKERS, modifier) == pipes_log2)
872+
++pipes_log2;
873+
874+
return max(8 + (pipe_aligned ? pipes_log2 : 0), 12);
875+
}
876+
default:
877+
return 0;
878+
}
879+
}
880+
881+
static int amdgpu_display_verify_plane(struct amdgpu_framebuffer *rfb, int plane,
882+
const struct drm_format_info *format,
883+
unsigned int block_width, unsigned int block_height,
884+
unsigned int block_size_log2)
885+
{
886+
unsigned int width = rfb->base.width /
887+
((plane && plane < format->num_planes) ? format->hsub : 1);
888+
unsigned int height = rfb->base.height /
889+
((plane && plane < format->num_planes) ? format->vsub : 1);
890+
unsigned int cpp = plane < format->num_planes ? format->cpp[plane] : 1;
891+
unsigned int block_pitch = block_width * cpp;
892+
unsigned int min_pitch = ALIGN(width * cpp, block_pitch);
893+
unsigned int block_size = 1 << block_size_log2;
894+
uint64_t size;
895+
896+
if (rfb->base.pitches[plane] % block_pitch) {
897+
drm_dbg_kms(rfb->base.dev,
898+
"pitch %d for plane %d is not a multiple of block pitch %d\n",
899+
rfb->base.pitches[plane], plane, block_pitch);
900+
return -EINVAL;
901+
}
902+
if (rfb->base.pitches[plane] < min_pitch) {
903+
drm_dbg_kms(rfb->base.dev,
904+
"pitch %d for plane %d is less than minimum pitch %d\n",
905+
rfb->base.pitches[plane], plane, min_pitch);
906+
return -EINVAL;
907+
}
908+
909+
/* Force at least natural alignment. */
910+
if (rfb->base.offsets[plane] % block_size) {
911+
drm_dbg_kms(rfb->base.dev,
912+
"offset 0x%x for plane %d is not a multiple of block pitch 0x%x\n",
913+
rfb->base.offsets[plane], plane, block_size);
914+
return -EINVAL;
915+
}
916+
917+
size = rfb->base.offsets[plane] +
918+
(uint64_t)rfb->base.pitches[plane] / block_pitch *
919+
block_size * DIV_ROUND_UP(height, block_height);
920+
921+
if (rfb->base.obj[0]->size < size) {
922+
drm_dbg_kms(rfb->base.dev,
923+
"BO size 0x%zx is less than 0x%llx required for plane %d\n",
924+
rfb->base.obj[0]->size, size, plane);
925+
return -EINVAL;
926+
}
927+
928+
return 0;
929+
}
930+
931+
932+
static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb)
933+
{
934+
const struct drm_format_info *format_info = drm_format_info(rfb->base.format->format);
935+
uint64_t modifier = rfb->base.modifier;
936+
int ret;
937+
unsigned int i, block_width, block_height, block_size_log2;
938+
939+
if (!rfb->base.dev->mode_config.allow_fb_modifiers)
940+
return 0;
941+
942+
for (i = 0; i < format_info->num_planes; ++i) {
943+
if (modifier == DRM_FORMAT_MOD_LINEAR) {
944+
block_width = 256 / format_info->cpp[i];
945+
block_height = 1;
946+
block_size_log2 = 8;
947+
} else {
948+
int swizzle = AMD_FMT_MOD_GET(TILE, modifier);
949+
950+
switch ((swizzle & ~3) + 1) {
951+
case DC_SW_256B_S:
952+
block_size_log2 = 8;
953+
break;
954+
case DC_SW_4KB_S:
955+
case DC_SW_4KB_S_X:
956+
block_size_log2 = 12;
957+
break;
958+
case DC_SW_64KB_S:
959+
case DC_SW_64KB_S_T:
960+
case DC_SW_64KB_S_X:
961+
block_size_log2 = 16;
962+
break;
963+
default:
964+
drm_dbg_kms(rfb->base.dev,
965+
"Swizzle mode with unknown block size: %d\n", swizzle);
966+
return -EINVAL;
967+
}
968+
969+
get_block_dimensions(block_size_log2, format_info->cpp[i],
970+
&block_width, &block_height);
971+
}
972+
973+
ret = amdgpu_display_verify_plane(rfb, i, format_info,
974+
block_width, block_height, block_size_log2);
975+
if (ret)
976+
return ret;
977+
}
978+
979+
if (AMD_FMT_MOD_GET(DCC, modifier)) {
980+
if (AMD_FMT_MOD_GET(DCC_RETILE, modifier)) {
981+
block_size_log2 = get_dcc_block_size(modifier, false, false);
982+
get_block_dimensions(block_size_log2 + 8, format_info->cpp[0],
983+
&block_width, &block_height);
984+
ret = amdgpu_display_verify_plane(rfb, i, format_info,
985+
block_width, block_height,
986+
block_size_log2);
987+
if (ret)
988+
return ret;
989+
990+
++i;
991+
block_size_log2 = get_dcc_block_size(modifier, true, true);
992+
} else {
993+
bool pipe_aligned = AMD_FMT_MOD_GET(DCC_PIPE_ALIGN, modifier);
994+
995+
block_size_log2 = get_dcc_block_size(modifier, true, pipe_aligned);
996+
}
997+
get_block_dimensions(block_size_log2 + 8, format_info->cpp[0],
998+
&block_width, &block_height);
999+
ret = amdgpu_display_verify_plane(rfb, i, format_info,
1000+
block_width, block_height, block_size_log2);
1001+
if (ret)
1002+
return ret;
1003+
}
1004+
1005+
return 0;
1006+
}
1007+
8401008
static int amdgpu_display_get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
8411009
uint64_t *tiling_flags, bool *tmz_surface)
8421010
{
@@ -902,10 +1070,8 @@ int amdgpu_display_gem_fb_verify_and_init(
9021070
int ret;
9031071

9041072
rfb->base.obj[0] = obj;
905-
906-
/* Verify that bo size can fit the fb size. */
907-
ret = drm_gem_fb_init_with_funcs(dev, &rfb->base, file_priv, mode_cmd,
908-
&amdgpu_fb_funcs);
1073+
drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
1074+
ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
9091075
if (ret)
9101076
goto err;
9111077
/* Verify that the modifier is supported. */
@@ -967,9 +1133,12 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
9671133
}
9681134
}
9691135

970-
for (i = 1; i < rfb->base.format->num_planes; ++i) {
1136+
ret = amdgpu_display_verify_sizes(rfb);
1137+
if (ret)
1138+
return ret;
1139+
1140+
for (i = 0; i < rfb->base.format->num_planes; ++i) {
9711141
drm_gem_object_get(rfb->base.obj[0]);
972-
drm_gem_object_put(rfb->base.obj[i]);
9731142
rfb->base.obj[i] = rfb->base.obj[0];
9741143
}
9751144

@@ -999,6 +1168,7 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
9991168
domains = amdgpu_display_supported_domains(drm_to_adev(dev), bo->flags);
10001169
if (obj->import_attach && !(domains & AMDGPU_GEM_DOMAIN_GTT)) {
10011170
drm_dbg_kms(dev, "Cannot create framebuffer from imported dma_buf\n");
1171+
drm_gem_object_put(obj);
10021172
return ERR_PTR(-EINVAL);
10031173
}
10041174

@@ -1412,7 +1582,7 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
14121582
}
14131583
}
14141584
}
1415-
return r;
1585+
return 0;
14161586
}
14171587

14181588
int amdgpu_display_resume_helper(struct amdgpu_device *adev)

drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,6 +1573,9 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
15731573
amdgpu_device_baco_exit(drm_dev);
15741574
}
15751575
ret = amdgpu_device_resume(drm_dev, false);
1576+
if (ret)
1577+
return ret;
1578+
15761579
if (amdgpu_device_supports_px(drm_dev))
15771580
drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
15781581
adev->in_runpm = false;

drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,11 @@ static int amdgpu_vmid_grab_idle(struct amdgpu_vm *vm,
215215
/* Check if we have an idle VMID */
216216
i = 0;
217217
list_for_each_entry((*idle), &id_mgr->ids_lru, list) {
218-
fences[i] = amdgpu_sync_peek_fence(&(*idle)->active, ring);
218+
/* Don't use per engine and per process VMID at the same time */
219+
struct amdgpu_ring *r = adev->vm_manager.concurrent_flush ?
220+
NULL : ring;
221+
222+
fences[i] = amdgpu_sync_peek_fence(&(*idle)->active, r);
219223
if (!fences[i])
220224
break;
221225
++i;
@@ -281,7 +285,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
281285
if (updates && (*id)->flushed_updates &&
282286
updates->context == (*id)->flushed_updates->context &&
283287
!dma_fence_is_later(updates, (*id)->flushed_updates))
284-
updates = NULL;
288+
updates = NULL;
285289

286290
if ((*id)->owner != vm->immediate.fence_context ||
287291
job->vm_pd_addr != (*id)->pd_gpu_addr ||
@@ -290,6 +294,10 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
290294
!dma_fence_is_signaled((*id)->last_flush))) {
291295
struct dma_fence *tmp;
292296

297+
/* Don't use per engine and per process VMID at the same time */
298+
if (adev->vm_manager.concurrent_flush)
299+
ring = NULL;
300+
293301
/* to prevent one context starved by another context */
294302
(*id)->pd_gpu_addr = 0;
295303
tmp = amdgpu_sync_peek_fence(&(*id)->active, ring);
@@ -365,12 +373,7 @@ static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
365373
if (updates && (!flushed || dma_fence_is_later(updates, flushed)))
366374
needs_flush = true;
367375

368-
/* Concurrent flushes are only possible starting with Vega10 and
369-
* are broken on Navi10 and Navi14.
370-
*/
371-
if (needs_flush && (adev->asic_type < CHIP_VEGA10 ||
372-
adev->asic_type == CHIP_NAVI10 ||
373-
adev->asic_type == CHIP_NAVI14))
376+
if (needs_flush && !adev->vm_manager.concurrent_flush)
374377
continue;
375378

376379
/* Good, we can use this VMID. Remember this submission as

drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3148,6 +3148,12 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev)
31483148
{
31493149
unsigned i;
31503150

3151+
/* Concurrent flushes are only possible starting with Vega10 and
3152+
* are broken on Navi10 and Navi14.
3153+
*/
3154+
adev->vm_manager.concurrent_flush = !(adev->asic_type < CHIP_VEGA10 ||
3155+
adev->asic_type == CHIP_NAVI10 ||
3156+
adev->asic_type == CHIP_NAVI14);
31513157
amdgpu_vmid_mgr_init(adev);
31523158

31533159
adev->vm_manager.fence_context =

drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ struct amdgpu_vm_manager {
331331
/* Handling of VMIDs */
332332
struct amdgpu_vmid_mgr id_mgr[AMDGPU_MAX_VMHUBS];
333333
unsigned int first_kfd_vmid;
334+
bool concurrent_flush;
334335

335336
/* Handling of VM fences */
336337
u64 fence_context;

drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ MODULE_FIRMWARE("amdgpu/tonga_mc.bin");
5959
MODULE_FIRMWARE("amdgpu/polaris11_mc.bin");
6060
MODULE_FIRMWARE("amdgpu/polaris10_mc.bin");
6161
MODULE_FIRMWARE("amdgpu/polaris12_mc.bin");
62+
MODULE_FIRMWARE("amdgpu/polaris12_32_mc.bin");
6263
MODULE_FIRMWARE("amdgpu/polaris11_k_mc.bin");
6364
MODULE_FIRMWARE("amdgpu/polaris10_k_mc.bin");
6465
MODULE_FIRMWARE("amdgpu/polaris12_k_mc.bin");
@@ -243,10 +244,16 @@ static int gmc_v8_0_init_microcode(struct amdgpu_device *adev)
243244
chip_name = "polaris10";
244245
break;
245246
case CHIP_POLARIS12:
246-
if (ASICID_IS_P23(adev->pdev->device, adev->pdev->revision))
247+
if (ASICID_IS_P23(adev->pdev->device, adev->pdev->revision)) {
247248
chip_name = "polaris12_k";
248-
else
249-
chip_name = "polaris12";
249+
} else {
250+
WREG32(mmMC_SEQ_IO_DEBUG_INDEX, ixMC_IO_DEBUG_UP_159);
251+
/* Polaris12 32bit ASIC needs a special MC firmware */
252+
if (RREG32(mmMC_SEQ_IO_DEBUG_DATA) == 0x05b4dc40)
253+
chip_name = "polaris12_32";
254+
else
255+
chip_name = "polaris12";
256+
}
250257
break;
251258
case CHIP_FIJI:
252259
case CHIP_CARRIZO:

drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,10 @@ static void vcn_v3_0_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx
589589
WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
590590
VCN, inst_idx, mmUVD_VCPU_NONCACHE_SIZE0),
591591
AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)), 0, indirect);
592+
593+
/* VCN global tiling registers */
594+
WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET(
595+
UVD, 0, mmUVD_GFX10_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
592596
}
593597

594598
static void vcn_v3_0_disable_static_power_gating(struct amdgpu_device *adev, int inst)

0 commit comments

Comments
 (0)