aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2019-02-10 23:04:05 -0500
committerDave Airlie <airlied@redhat.com>2019-02-10 23:04:20 -0500
commitf4bc54b532a62d8bee421ca06adb6d1b3e7ffaa9 (patch)
tree3b835f9bed6bd236fa1a6d5d0add836f25ca8262 /drivers/gpu
parent5ea3998d56346975c2701df18fb5b6e3ab5c8d9e (diff)
parent0461221316ec21e0a535a35fba3feb6ba75706e6 (diff)
Merge branch 'drm-next-5.1' of git://people.freedesktop.org/~agd5f/linux into drm-next
Updates for 5.1: - GDS fixes - Add AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES interface - GPUVM fixes - PCIE DPM switching fixes for vega20 - Vega10 uclk DPM regression fix - DC Freesync fixes - DC ABM fixes - Various DC cleanups Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190208210214.27666-1-alexander.deucher@amd.com
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c13
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c58
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gds.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.c16
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c33
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c19
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c21
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c40
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c198
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c189
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link.c66
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c39
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c56
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_vm_helper.c18
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_link.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_stream.h25
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_types.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_abm.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_aux.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c28
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c52
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c19
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c23
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c194
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c10
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c197
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h8
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c12
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c28
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h10
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/clock_source.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h13
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/vm_helper.h7
-rw-r--r--drivers/gpu/drm/amd/display/include/gpio_interface.h8
-rw-r--r--drivers/gpu/drm/amd/display/modules/color/color_gamma.c89
-rw-r--r--drivers/gpu/drm/amd/display/modules/power/power_helpers.c38
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c7
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c47
50 files changed, 1155 insertions, 486 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 1c49b8266d69..52a5e4fdc95b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -214,6 +214,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs
214 case AMDGPU_CHUNK_ID_DEPENDENCIES: 214 case AMDGPU_CHUNK_ID_DEPENDENCIES:
215 case AMDGPU_CHUNK_ID_SYNCOBJ_IN: 215 case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
216 case AMDGPU_CHUNK_ID_SYNCOBJ_OUT: 216 case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
217 case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES:
217 break; 218 break;
218 219
219 default: 220 default:
@@ -1090,6 +1091,15 @@ static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p,
1090 1091
1091 fence = amdgpu_ctx_get_fence(ctx, entity, 1092 fence = amdgpu_ctx_get_fence(ctx, entity,
1092 deps[i].handle); 1093 deps[i].handle);
1094
1095 if (chunk->chunk_id == AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES) {
1096 struct drm_sched_fence *s_fence = to_drm_sched_fence(fence);
1097 struct dma_fence *old = fence;
1098
1099 fence = dma_fence_get(&s_fence->scheduled);
1100 dma_fence_put(old);
1101 }
1102
1093 if (IS_ERR(fence)) { 1103 if (IS_ERR(fence)) {
1094 r = PTR_ERR(fence); 1104 r = PTR_ERR(fence);
1095 amdgpu_ctx_put(ctx); 1105 amdgpu_ctx_put(ctx);
@@ -1177,7 +1187,8 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev,
1177 1187
1178 chunk = &p->chunks[i]; 1188 chunk = &p->chunks[i];
1179 1189
1180 if (chunk->chunk_id == AMDGPU_CHUNK_ID_DEPENDENCIES) { 1190 if (chunk->chunk_id == AMDGPU_CHUNK_ID_DEPENDENCIES ||
1191 chunk->chunk_id == AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES) {
1181 r = amdgpu_cs_process_fence_dep(p, chunk); 1192 r = amdgpu_cs_process_fence_dep(p, chunk);
1182 if (r) 1193 if (r)
1183 return r; 1194 return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 384272603b21..4f8fb4ecde34 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3618,6 +3618,38 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */
3618 return r; 3618 return r;
3619} 3619}
3620 3620
3621static void amdgpu_device_get_min_pci_speed_width(struct amdgpu_device *adev,
3622 enum pci_bus_speed *speed,
3623 enum pcie_link_width *width)
3624{
3625 struct pci_dev *pdev = adev->pdev;
3626 enum pci_bus_speed cur_speed;
3627 enum pcie_link_width cur_width;
3628
3629 *speed = PCI_SPEED_UNKNOWN;
3630 *width = PCIE_LNK_WIDTH_UNKNOWN;
3631
3632 while (pdev) {
3633 cur_speed = pcie_get_speed_cap(pdev);
3634 cur_width = pcie_get_width_cap(pdev);
3635
3636 if (cur_speed != PCI_SPEED_UNKNOWN) {
3637 if (*speed == PCI_SPEED_UNKNOWN)
3638 *speed = cur_speed;
3639 else if (cur_speed < *speed)
3640 *speed = cur_speed;
3641 }
3642
3643 if (cur_width != PCIE_LNK_WIDTH_UNKNOWN) {
3644 if (*width == PCIE_LNK_WIDTH_UNKNOWN)
3645 *width = cur_width;
3646 else if (cur_width < *width)
3647 *width = cur_width;
3648 }
3649 pdev = pci_upstream_bridge(pdev);
3650 }
3651}
3652
3621/** 3653/**
3622 * amdgpu_device_get_pcie_info - fence pcie info about the PCIE slot 3654 * amdgpu_device_get_pcie_info - fence pcie info about the PCIE slot
3623 * 3655 *
@@ -3630,8 +3662,8 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */
3630static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev) 3662static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
3631{ 3663{
3632 struct pci_dev *pdev; 3664 struct pci_dev *pdev;
3633 enum pci_bus_speed speed_cap; 3665 enum pci_bus_speed speed_cap, platform_speed_cap;
3634 enum pcie_link_width link_width; 3666 enum pcie_link_width platform_link_width;
3635 3667
3636 if (amdgpu_pcie_gen_cap) 3668 if (amdgpu_pcie_gen_cap)
3637 adev->pm.pcie_gen_mask = amdgpu_pcie_gen_cap; 3669 adev->pm.pcie_gen_mask = amdgpu_pcie_gen_cap;
@@ -3648,6 +3680,12 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
3648 return; 3680 return;
3649 } 3681 }
3650 3682
3683 if (adev->pm.pcie_gen_mask && adev->pm.pcie_mlw_mask)
3684 return;
3685
3686 amdgpu_device_get_min_pci_speed_width(adev, &platform_speed_cap,
3687 &platform_link_width);
3688
3651 if (adev->pm.pcie_gen_mask == 0) { 3689 if (adev->pm.pcie_gen_mask == 0) {
3652 /* asic caps */ 3690 /* asic caps */
3653 pdev = adev->pdev; 3691 pdev = adev->pdev;
@@ -3673,22 +3711,20 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
3673 adev->pm.pcie_gen_mask |= CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1; 3711 adev->pm.pcie_gen_mask |= CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1;
3674 } 3712 }
3675 /* platform caps */ 3713 /* platform caps */
3676 pdev = adev->ddev->pdev->bus->self; 3714 if (platform_speed_cap == PCI_SPEED_UNKNOWN) {
3677 speed_cap = pcie_get_speed_cap(pdev);
3678 if (speed_cap == PCI_SPEED_UNKNOWN) {
3679 adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 | 3715 adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
3680 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2); 3716 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2);
3681 } else { 3717 } else {
3682 if (speed_cap == PCIE_SPEED_16_0GT) 3718 if (platform_speed_cap == PCIE_SPEED_16_0GT)
3683 adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 | 3719 adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
3684 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 | 3720 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
3685 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3 | 3721 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3 |
3686 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4); 3722 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4);
3687 else if (speed_cap == PCIE_SPEED_8_0GT) 3723 else if (platform_speed_cap == PCIE_SPEED_8_0GT)
3688 adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 | 3724 adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
3689 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 | 3725 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
3690 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3); 3726 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3);
3691 else if (speed_cap == PCIE_SPEED_5_0GT) 3727 else if (platform_speed_cap == PCIE_SPEED_5_0GT)
3692 adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 | 3728 adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
3693 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2); 3729 CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2);
3694 else 3730 else
@@ -3697,12 +3733,10 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
3697 } 3733 }
3698 } 3734 }
3699 if (adev->pm.pcie_mlw_mask == 0) { 3735 if (adev->pm.pcie_mlw_mask == 0) {
3700 pdev = adev->ddev->pdev->bus->self; 3736 if (platform_link_width == PCIE_LNK_WIDTH_UNKNOWN) {
3701 link_width = pcie_get_width_cap(pdev);
3702 if (link_width == PCIE_LNK_WIDTH_UNKNOWN) {
3703 adev->pm.pcie_mlw_mask |= AMDGPU_DEFAULT_PCIE_MLW_MASK; 3737 adev->pm.pcie_mlw_mask |= AMDGPU_DEFAULT_PCIE_MLW_MASK;
3704 } else { 3738 } else {
3705 switch (link_width) { 3739 switch (platform_link_width) {
3706 case PCIE_LNK_X32: 3740 case PCIE_LNK_X32:
3707 adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 | 3741 adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 |
3708 CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 | 3742 CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index a1bb3773087b..7f3aa7b7e1d8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -71,9 +71,11 @@
71 * - 3.25.0 - Add support for sensor query info (stable pstate sclk/mclk). 71 * - 3.25.0 - Add support for sensor query info (stable pstate sclk/mclk).
72 * - 3.26.0 - GFX9: Process AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE. 72 * - 3.26.0 - GFX9: Process AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE.
73 * - 3.27.0 - Add new chunk to to AMDGPU_CS to enable BO_LIST creation. 73 * - 3.27.0 - Add new chunk to to AMDGPU_CS to enable BO_LIST creation.
74 * - 3.28.0 - Add AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES
75 * - 3.29.0 - Add AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID
74 */ 76 */
75#define KMS_DRIVER_MAJOR 3 77#define KMS_DRIVER_MAJOR 3
76#define KMS_DRIVER_MINOR 27 78#define KMS_DRIVER_MINOR 29
77#define KMS_DRIVER_PATCHLEVEL 0 79#define KMS_DRIVER_PATCHLEVEL 0
78 80
79int amdgpu_vram_limit = 0; 81int amdgpu_vram_limit = 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gds.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gds.h
index ecbcefe49a98..f89f5734d985 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gds.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gds.h
@@ -37,6 +37,8 @@ struct amdgpu_gds {
37 struct amdgpu_gds_asic_info mem; 37 struct amdgpu_gds_asic_info mem;
38 struct amdgpu_gds_asic_info gws; 38 struct amdgpu_gds_asic_info gws;
39 struct amdgpu_gds_asic_info oa; 39 struct amdgpu_gds_asic_info oa;
40 uint32_t gds_compute_max_wave_id;
41
40 /* At present, GDS, GWS and OA resources for gfx (graphics) 42 /* At present, GDS, GWS and OA resources for gfx (graphics)
41 * is always pre-allocated and available for graphics operation. 43 * is always pre-allocated and available for graphics operation.
42 * Such resource is shared between all gfx clients. 44 * Such resource is shared between all gfx clients.
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index f4f00217546e..d21dd2f369da 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -54,10 +54,6 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
54 54
55 memset(&bp, 0, sizeof(bp)); 55 memset(&bp, 0, sizeof(bp));
56 *obj = NULL; 56 *obj = NULL;
57 /* At least align on page size */
58 if (alignment < PAGE_SIZE) {
59 alignment = PAGE_SIZE;
60 }
61 57
62 bp.size = size; 58 bp.size = size;
63 bp.byte_align = alignment; 59 bp.byte_align = alignment;
@@ -244,9 +240,6 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
244 return -EINVAL; 240 return -EINVAL;
245 } 241 }
246 flags |= AMDGPU_GEM_CREATE_NO_CPU_ACCESS; 242 flags |= AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
247 /* GDS allocations must be DW aligned */
248 if (args->in.domains & AMDGPU_GEM_DOMAIN_GDS)
249 size = ALIGN(size, 4);
250 } 243 }
251 244
252 if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) { 245 if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 728e15e5d68a..fd9c4beeaaa4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -426,12 +426,20 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
426 size_t acc_size; 426 size_t acc_size;
427 int r; 427 int r;
428 428
429 page_align = roundup(bp->byte_align, PAGE_SIZE) >> PAGE_SHIFT; 429 /* Note that GDS/GWS/OA allocates 1 page per byte/resource. */
430 if (bp->domain & (AMDGPU_GEM_DOMAIN_GDS | AMDGPU_GEM_DOMAIN_GWS | 430 if (bp->domain & (AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {
431 AMDGPU_GEM_DOMAIN_OA)) 431 /* GWS and OA don't need any alignment. */
432 page_align = bp->byte_align;
432 size <<= PAGE_SHIFT; 433 size <<= PAGE_SHIFT;
433 else 434 } else if (bp->domain & AMDGPU_GEM_DOMAIN_GDS) {
435 /* Both size and alignment must be a multiple of 4. */
436 page_align = ALIGN(bp->byte_align, 4);
437 size = ALIGN(size, 4) << PAGE_SHIFT;
438 } else {
439 /* Memory should be aligned at least to a page size. */
440 page_align = ALIGN(bp->byte_align, PAGE_SIZE) >> PAGE_SHIFT;
434 size = ALIGN(size, PAGE_SIZE); 441 size = ALIGN(size, PAGE_SIZE);
442 }
435 443
436 if (!amdgpu_bo_validate_size(adev, size, bp->domain)) 444 if (!amdgpu_bo_validate_size(adev, size, bp->domain))
437 return -ENOMEM; 445 return -ENOMEM;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index b852abb9db0f..73e71e61dc99 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1756,7 +1756,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
1756 } 1756 }
1757 1757
1758 r = amdgpu_bo_create_kernel(adev, adev->gds.mem.gfx_partition_size, 1758 r = amdgpu_bo_create_kernel(adev, adev->gds.mem.gfx_partition_size,
1759 PAGE_SIZE, AMDGPU_GEM_DOMAIN_GDS, 1759 4, AMDGPU_GEM_DOMAIN_GDS,
1760 &adev->gds.gds_gfx_bo, NULL, NULL); 1760 &adev->gds.gds_gfx_bo, NULL, NULL);
1761 if (r) 1761 if (r)
1762 return r; 1762 return r;
@@ -1769,7 +1769,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
1769 } 1769 }
1770 1770
1771 r = amdgpu_bo_create_kernel(adev, adev->gds.gws.gfx_partition_size, 1771 r = amdgpu_bo_create_kernel(adev, adev->gds.gws.gfx_partition_size,
1772 PAGE_SIZE, AMDGPU_GEM_DOMAIN_GWS, 1772 1, AMDGPU_GEM_DOMAIN_GWS,
1773 &adev->gds.gws_gfx_bo, NULL, NULL); 1773 &adev->gds.gws_gfx_bo, NULL, NULL);
1774 if (r) 1774 if (r)
1775 return r; 1775 return r;
@@ -1782,7 +1782,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
1782 } 1782 }
1783 1783
1784 r = amdgpu_bo_create_kernel(adev, adev->gds.oa.gfx_partition_size, 1784 r = amdgpu_bo_create_kernel(adev, adev->gds.oa.gfx_partition_size,
1785 PAGE_SIZE, AMDGPU_GEM_DOMAIN_OA, 1785 1, AMDGPU_GEM_DOMAIN_OA,
1786 &adev->gds.oa_gfx_bo, NULL, NULL); 1786 &adev->gds.oa_gfx_bo, NULL, NULL);
1787 if (r) 1787 if (r)
1788 return r; 1788 return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 0bc6f553dc08..75481cf3348f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -107,14 +107,6 @@ struct amdgpu_pte_update_params {
107 * DMA addresses to use for mapping, used during VM update by CPU 107 * DMA addresses to use for mapping, used during VM update by CPU
108 */ 108 */
109 dma_addr_t *pages_addr; 109 dma_addr_t *pages_addr;
110
111 /**
112 * @kptr:
113 *
114 * Kernel pointer of PD/PT BO that needs to be updated,
115 * used during VM update by CPU
116 */
117 void *kptr;
118}; 110};
119 111
120/** 112/**
@@ -1789,13 +1781,20 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
1789 if (pages_addr) 1781 if (pages_addr)
1790 params.src = ~0; 1782 params.src = ~0;
1791 1783
1792 /* Wait for PT BOs to be free. PTs share the same resv. object 1784 /* Wait for PT BOs to be idle. PTs share the same resv. object
1793 * as the root PD BO 1785 * as the root PD BO
1794 */ 1786 */
1795 r = amdgpu_vm_wait_pd(adev, vm, owner); 1787 r = amdgpu_vm_wait_pd(adev, vm, owner);
1796 if (unlikely(r)) 1788 if (unlikely(r))
1797 return r; 1789 return r;
1798 1790
1791 /* Wait for any BO move to be completed */
1792 if (exclusive) {
1793 r = dma_fence_wait(exclusive, true);
1794 if (unlikely(r))
1795 return r;
1796 }
1797
1799 params.func = amdgpu_vm_cpu_set_ptes; 1798 params.func = amdgpu_vm_cpu_set_ptes;
1800 params.pages_addr = pages_addr; 1799 params.pages_addr = pages_addr;
1801 return amdgpu_vm_update_ptes(&params, start, last + 1, 1800 return amdgpu_vm_update_ptes(&params, start, last + 1,
@@ -1809,13 +1808,12 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
1809 /* 1808 /*
1810 * reserve space for two commands every (1 << BLOCK_SIZE) 1809 * reserve space for two commands every (1 << BLOCK_SIZE)
1811 * entries or 2k dwords (whatever is smaller) 1810 * entries or 2k dwords (whatever is smaller)
1812 *
1813 * The second command is for the shadow pagetables.
1814 */ 1811 */
1812 ncmds = ((nptes >> min(adev->vm_manager.block_size, 11u)) + 1);
1813
1814 /* The second command is for the shadow pagetables. */
1815 if (vm->root.base.bo->shadow) 1815 if (vm->root.base.bo->shadow)
1816 ncmds = ((nptes >> min(adev->vm_manager.block_size, 11u)) + 1) * 2; 1816 ncmds *= 2;
1817 else
1818 ncmds = ((nptes >> min(adev->vm_manager.block_size, 11u)) + 1);
1819 1817
1820 /* padding, etc. */ 1818 /* padding, etc. */
1821 ndw = 64; 1819 ndw = 64;
@@ -1834,10 +1832,11 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
1834 ndw += ncmds * 10; 1832 ndw += ncmds * 10;
1835 1833
1836 /* extra commands for begin/end fragments */ 1834 /* extra commands for begin/end fragments */
1835 ncmds = 2 * adev->vm_manager.fragment_size;
1837 if (vm->root.base.bo->shadow) 1836 if (vm->root.base.bo->shadow)
1838 ndw += 2 * 10 * adev->vm_manager.fragment_size * 2; 1837 ncmds *= 2;
1839 else 1838
1840 ndw += 2 * 10 * adev->vm_manager.fragment_size; 1839 ndw += 10 * ncmds;
1841 1840
1842 params.func = amdgpu_vm_do_set_ptes; 1841 params.func = amdgpu_vm_do_set_ptes;
1843 } 1842 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
index 0d90672d0e58..407dd16cc35c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
@@ -125,7 +125,7 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev)
125 if (!hive) { 125 if (!hive) {
126 ret = -EINVAL; 126 ret = -EINVAL;
127 dev_err(adev->dev, 127 dev_err(adev->dev,
128 "XGMI: node 0x%llx, can not matech hive 0x%llx in the hive list.\n", 128 "XGMI: node 0x%llx, can not match hive 0x%llx in the hive list.\n",
129 adev->gmc.xgmi.node_id, adev->gmc.xgmi.hive_id); 129 adev->gmc.xgmi.node_id, adev->gmc.xgmi.hive_id);
130 goto exit; 130 goto exit;
131 } 131 }
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
index 7984292f9282..a59e0fdf5a97 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
@@ -2264,6 +2264,22 @@ static void gfx_v7_0_ring_emit_ib_compute(struct amdgpu_ring *ring,
2264 unsigned vmid = AMDGPU_JOB_GET_VMID(job); 2264 unsigned vmid = AMDGPU_JOB_GET_VMID(job);
2265 u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24); 2265 u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24);
2266 2266
2267 /* Currently, there is a high possibility to get wave ID mismatch
2268 * between ME and GDS, leading to a hw deadlock, because ME generates
2269 * different wave IDs than the GDS expects. This situation happens
2270 * randomly when at least 5 compute pipes use GDS ordered append.
2271 * The wave IDs generated by ME are also wrong after suspend/resume.
2272 * Those are probably bugs somewhere else in the kernel driver.
2273 *
2274 * Writing GDS_COMPUTE_MAX_WAVE_ID resets wave ID counters in ME and
2275 * GDS to 0 for this ring (me/pipe).
2276 */
2277 if (ib->flags & AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID) {
2278 amdgpu_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
2279 amdgpu_ring_write(ring, mmGDS_COMPUTE_MAX_WAVE_ID - PACKET3_SET_CONFIG_REG_START);
2280 amdgpu_ring_write(ring, ring->adev->gds.gds_compute_max_wave_id);
2281 }
2282
2267 amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); 2283 amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
2268 amdgpu_ring_write(ring, 2284 amdgpu_ring_write(ring,
2269#ifdef __BIG_ENDIAN 2285#ifdef __BIG_ENDIAN
@@ -5000,7 +5016,7 @@ static const struct amdgpu_ring_funcs gfx_v7_0_ring_funcs_compute = {
5000 7 + /* gfx_v7_0_ring_emit_pipeline_sync */ 5016 7 + /* gfx_v7_0_ring_emit_pipeline_sync */
5001 CIK_FLUSH_GPU_TLB_NUM_WREG * 5 + 7 + /* gfx_v7_0_ring_emit_vm_flush */ 5017 CIK_FLUSH_GPU_TLB_NUM_WREG * 5 + 7 + /* gfx_v7_0_ring_emit_vm_flush */
5002 7 + 7 + 7, /* gfx_v7_0_ring_emit_fence_compute x3 for user fence, vm fence */ 5018 7 + 7 + 7, /* gfx_v7_0_ring_emit_fence_compute x3 for user fence, vm fence */
5003 .emit_ib_size = 4, /* gfx_v7_0_ring_emit_ib_compute */ 5019 .emit_ib_size = 7, /* gfx_v7_0_ring_emit_ib_compute */
5004 .emit_ib = gfx_v7_0_ring_emit_ib_compute, 5020 .emit_ib = gfx_v7_0_ring_emit_ib_compute,
5005 .emit_fence = gfx_v7_0_ring_emit_fence_compute, 5021 .emit_fence = gfx_v7_0_ring_emit_fence_compute,
5006 .emit_pipeline_sync = gfx_v7_0_ring_emit_pipeline_sync, 5022 .emit_pipeline_sync = gfx_v7_0_ring_emit_pipeline_sync,
@@ -5057,6 +5073,7 @@ static void gfx_v7_0_set_gds_init(struct amdgpu_device *adev)
5057 adev->gds.mem.total_size = RREG32(mmGDS_VMID0_SIZE); 5073 adev->gds.mem.total_size = RREG32(mmGDS_VMID0_SIZE);
5058 adev->gds.gws.total_size = 64; 5074 adev->gds.gws.total_size = 64;
5059 adev->gds.oa.total_size = 16; 5075 adev->gds.oa.total_size = 16;
5076 adev->gds.gds_compute_max_wave_id = RREG32(mmGDS_COMPUTE_MAX_WAVE_ID);
5060 5077
5061 if (adev->gds.mem.total_size == 64 * 1024) { 5078 if (adev->gds.mem.total_size == 64 * 1024) {
5062 adev->gds.mem.gfx_partition_size = 4096; 5079 adev->gds.mem.gfx_partition_size = 4096;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index a26747681ed6..b8e50a34bdb3 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -6084,6 +6084,22 @@ static void gfx_v8_0_ring_emit_ib_compute(struct amdgpu_ring *ring,
6084 unsigned vmid = AMDGPU_JOB_GET_VMID(job); 6084 unsigned vmid = AMDGPU_JOB_GET_VMID(job);
6085 u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24); 6085 u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24);
6086 6086
6087 /* Currently, there is a high possibility to get wave ID mismatch
6088 * between ME and GDS, leading to a hw deadlock, because ME generates
6089 * different wave IDs than the GDS expects. This situation happens
6090 * randomly when at least 5 compute pipes use GDS ordered append.
6091 * The wave IDs generated by ME are also wrong after suspend/resume.
6092 * Those are probably bugs somewhere else in the kernel driver.
6093 *
6094 * Writing GDS_COMPUTE_MAX_WAVE_ID resets wave ID counters in ME and
6095 * GDS to 0 for this ring (me/pipe).
6096 */
6097 if (ib->flags & AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID) {
6098 amdgpu_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
6099 amdgpu_ring_write(ring, mmGDS_COMPUTE_MAX_WAVE_ID - PACKET3_SET_CONFIG_REG_START);
6100 amdgpu_ring_write(ring, ring->adev->gds.gds_compute_max_wave_id);
6101 }
6102
6087 amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); 6103 amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
6088 amdgpu_ring_write(ring, 6104 amdgpu_ring_write(ring,
6089#ifdef __BIG_ENDIAN 6105#ifdef __BIG_ENDIAN
@@ -6890,7 +6906,7 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_compute = {
6890 7 + /* gfx_v8_0_ring_emit_pipeline_sync */ 6906 7 + /* gfx_v8_0_ring_emit_pipeline_sync */
6891 VI_FLUSH_GPU_TLB_NUM_WREG * 5 + 7 + /* gfx_v8_0_ring_emit_vm_flush */ 6907 VI_FLUSH_GPU_TLB_NUM_WREG * 5 + 7 + /* gfx_v8_0_ring_emit_vm_flush */
6892 7 + 7 + 7, /* gfx_v8_0_ring_emit_fence_compute x3 for user fence, vm fence */ 6908 7 + 7 + 7, /* gfx_v8_0_ring_emit_fence_compute x3 for user fence, vm fence */
6893 .emit_ib_size = 4, /* gfx_v8_0_ring_emit_ib_compute */ 6909 .emit_ib_size = 7, /* gfx_v8_0_ring_emit_ib_compute */
6894 .emit_ib = gfx_v8_0_ring_emit_ib_compute, 6910 .emit_ib = gfx_v8_0_ring_emit_ib_compute,
6895 .emit_fence = gfx_v8_0_ring_emit_fence_compute, 6911 .emit_fence = gfx_v8_0_ring_emit_fence_compute,
6896 .emit_pipeline_sync = gfx_v8_0_ring_emit_pipeline_sync, 6912 .emit_pipeline_sync = gfx_v8_0_ring_emit_pipeline_sync,
@@ -6920,7 +6936,7 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_kiq = {
6920 7 + /* gfx_v8_0_ring_emit_pipeline_sync */ 6936 7 + /* gfx_v8_0_ring_emit_pipeline_sync */
6921 17 + /* gfx_v8_0_ring_emit_vm_flush */ 6937 17 + /* gfx_v8_0_ring_emit_vm_flush */
6922 7 + 7 + 7, /* gfx_v8_0_ring_emit_fence_kiq x3 for user fence, vm fence */ 6938 7 + 7 + 7, /* gfx_v8_0_ring_emit_fence_kiq x3 for user fence, vm fence */
6923 .emit_ib_size = 4, /* gfx_v8_0_ring_emit_ib_compute */ 6939 .emit_ib_size = 7, /* gfx_v8_0_ring_emit_ib_compute */
6924 .emit_fence = gfx_v8_0_ring_emit_fence_kiq, 6940 .emit_fence = gfx_v8_0_ring_emit_fence_kiq,
6925 .test_ring = gfx_v8_0_ring_test_ring, 6941 .test_ring = gfx_v8_0_ring_test_ring,
6926 .insert_nop = amdgpu_ring_insert_nop, 6942 .insert_nop = amdgpu_ring_insert_nop,
@@ -6996,6 +7012,7 @@ static void gfx_v8_0_set_gds_init(struct amdgpu_device *adev)
6996 adev->gds.mem.total_size = RREG32(mmGDS_VMID0_SIZE); 7012 adev->gds.mem.total_size = RREG32(mmGDS_VMID0_SIZE);
6997 adev->gds.gws.total_size = 64; 7013 adev->gds.gws.total_size = 64;
6998 adev->gds.oa.total_size = 16; 7014 adev->gds.oa.total_size = 16;
7015 adev->gds.gds_compute_max_wave_id = RREG32(mmGDS_COMPUTE_MAX_WAVE_ID);
6999 7016
7000 if (adev->gds.mem.total_size == 64 * 1024) { 7017 if (adev->gds.mem.total_size == 64 * 1024) {
7001 adev->gds.mem.gfx_partition_size = 4096; 7018 adev->gds.mem.gfx_partition_size = 4096;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 262ee3cf6f1c..5533f6e4f4a4 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -4010,6 +4010,22 @@ static void gfx_v9_0_ring_emit_ib_compute(struct amdgpu_ring *ring,
4010 unsigned vmid = AMDGPU_JOB_GET_VMID(job); 4010 unsigned vmid = AMDGPU_JOB_GET_VMID(job);
4011 u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24); 4011 u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24);
4012 4012
4013 /* Currently, there is a high possibility to get wave ID mismatch
4014 * between ME and GDS, leading to a hw deadlock, because ME generates
4015 * different wave IDs than the GDS expects. This situation happens
4016 * randomly when at least 5 compute pipes use GDS ordered append.
4017 * The wave IDs generated by ME are also wrong after suspend/resume.
4018 * Those are probably bugs somewhere else in the kernel driver.
4019 *
4020 * Writing GDS_COMPUTE_MAX_WAVE_ID resets wave ID counters in ME and
4021 * GDS to 0 for this ring (me/pipe).
4022 */
4023 if (ib->flags & AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID) {
4024 amdgpu_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
4025 amdgpu_ring_write(ring, mmGDS_COMPUTE_MAX_WAVE_ID);
4026 amdgpu_ring_write(ring, ring->adev->gds.gds_compute_max_wave_id);
4027 }
4028
4013 amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); 4029 amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
4014 BUG_ON(ib->gpu_addr & 0x3); /* Dword align */ 4030 BUG_ON(ib->gpu_addr & 0x3); /* Dword align */
4015 amdgpu_ring_write(ring, 4031 amdgpu_ring_write(ring,
@@ -4729,7 +4745,7 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_compute = {
4729 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 + 4745 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 +
4730 2 + /* gfx_v9_0_ring_emit_vm_flush */ 4746 2 + /* gfx_v9_0_ring_emit_vm_flush */
4731 8 + 8 + 8, /* gfx_v9_0_ring_emit_fence x3 for user fence, vm fence */ 4747 8 + 8 + 8, /* gfx_v9_0_ring_emit_fence x3 for user fence, vm fence */
4732 .emit_ib_size = 4, /* gfx_v9_0_ring_emit_ib_compute */ 4748 .emit_ib_size = 7, /* gfx_v9_0_ring_emit_ib_compute */
4733 .emit_ib = gfx_v9_0_ring_emit_ib_compute, 4749 .emit_ib = gfx_v9_0_ring_emit_ib_compute,
4734 .emit_fence = gfx_v9_0_ring_emit_fence, 4750 .emit_fence = gfx_v9_0_ring_emit_fence,
4735 .emit_pipeline_sync = gfx_v9_0_ring_emit_pipeline_sync, 4751 .emit_pipeline_sync = gfx_v9_0_ring_emit_pipeline_sync,
@@ -4764,7 +4780,7 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_kiq = {
4764 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 + 4780 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 +
4765 2 + /* gfx_v9_0_ring_emit_vm_flush */ 4781 2 + /* gfx_v9_0_ring_emit_vm_flush */
4766 8 + 8 + 8, /* gfx_v9_0_ring_emit_fence_kiq x3 for user fence, vm fence */ 4782 8 + 8 + 8, /* gfx_v9_0_ring_emit_fence_kiq x3 for user fence, vm fence */
4767 .emit_ib_size = 4, /* gfx_v9_0_ring_emit_ib_compute */ 4783 .emit_ib_size = 7, /* gfx_v9_0_ring_emit_ib_compute */
4768 .emit_fence = gfx_v9_0_ring_emit_fence_kiq, 4784 .emit_fence = gfx_v9_0_ring_emit_fence_kiq,
4769 .test_ring = gfx_v9_0_ring_test_ring, 4785 .test_ring = gfx_v9_0_ring_test_ring,
4770 .insert_nop = amdgpu_ring_insert_nop, 4786 .insert_nop = amdgpu_ring_insert_nop,
@@ -4846,6 +4862,26 @@ static void gfx_v9_0_set_gds_init(struct amdgpu_device *adev)
4846 break; 4862 break;
4847 } 4863 }
4848 4864
4865 switch (adev->asic_type) {
4866 case CHIP_VEGA10:
4867 case CHIP_VEGA20:
4868 adev->gds.gds_compute_max_wave_id = 0x7ff;
4869 break;
4870 case CHIP_VEGA12:
4871 adev->gds.gds_compute_max_wave_id = 0x27f;
4872 break;
4873 case CHIP_RAVEN:
4874 if (adev->rev_id >= 0x8)
4875 adev->gds.gds_compute_max_wave_id = 0x77; /* raven2 */
4876 else
4877 adev->gds.gds_compute_max_wave_id = 0x15f; /* raven1 */
4878 break;
4879 default:
4880 /* this really depends on the chip */
4881 adev->gds.gds_compute_max_wave_id = 0x7ff;
4882 break;
4883 }
4884
4849 adev->gds.gws.total_size = 64; 4885 adev->gds.gws.total_size = 64;
4850 adev->gds.oa.total_size = 16; 4886 adev->gds.oa.total_size = 16;
4851 4887
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1923f47d3dd6..ad31d7b9912f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2297,12 +2297,15 @@ static bool fill_plane_dcc_attributes(struct amdgpu_device *adev,
2297 uint64_t info) 2297 uint64_t info)
2298{ 2298{
2299 struct dc *dc = adev->dm.dc; 2299 struct dc *dc = adev->dm.dc;
2300 struct dc_dcc_surface_param input = {0}; 2300 struct dc_dcc_surface_param input;
2301 struct dc_surface_dcc_cap output = {0}; 2301 struct dc_surface_dcc_cap output;
2302 uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B); 2302 uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
2303 uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0; 2303 uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
2304 uint64_t dcc_address; 2304 uint64_t dcc_address;
2305 2305
2306 memset(&input, 0, sizeof(input));
2307 memset(&output, 0, sizeof(output));
2308
2306 if (!offset) 2309 if (!offset)
2307 return false; 2310 return false;
2308 2311
@@ -2956,11 +2959,9 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
2956 drm_connector = &aconnector->base; 2959 drm_connector = &aconnector->base;
2957 2960
2958 if (!aconnector->dc_sink) { 2961 if (!aconnector->dc_sink) {
2959 if (!aconnector->mst_port) { 2962 sink = create_fake_sink(aconnector);
2960 sink = create_fake_sink(aconnector); 2963 if (!sink)
2961 if (!sink) 2964 return stream;
2962 return stream;
2963 }
2964 } else { 2965 } else {
2965 sink = aconnector->dc_sink; 2966 sink = aconnector->dc_sink;
2966 } 2967 }
@@ -3027,9 +3028,6 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
3027 3028
3028 update_stream_signal(stream, sink); 3029 update_stream_signal(stream, sink);
3029 3030
3030 if (dm_state && dm_state->freesync_capable)
3031 stream->ignore_msa_timing_param = true;
3032
3033finish: 3031finish:
3034 if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL && aconnector->base.force != DRM_FORCE_ON) 3032 if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL && aconnector->base.force != DRM_FORCE_ON)
3035 dc_sink_release(sink); 3033 dc_sink_release(sink);
@@ -4610,12 +4608,6 @@ static void update_freesync_state_on_stream(
4610 new_crtc_state->base.crtc->base.id, 4608 new_crtc_state->base.crtc->base.id,
4611 (int)new_crtc_state->base.vrr_enabled, 4609 (int)new_crtc_state->base.vrr_enabled,
4612 (int)vrr_params.state); 4610 (int)vrr_params.state);
4613
4614 if (new_crtc_state->freesync_timing_changed)
4615 DRM_DEBUG_KMS("VRR timing update: crtc=%u min=%u max=%u\n",
4616 new_crtc_state->base.crtc->base.id,
4617 vrr_params.adjust.v_total_min,
4618 vrr_params.adjust.v_total_max);
4619} 4611}
4620 4612
4621static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, 4613static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
@@ -4639,7 +4631,6 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
4639 unsigned long flags; 4631 unsigned long flags;
4640 struct amdgpu_bo *abo; 4632 struct amdgpu_bo *abo;
4641 uint64_t tiling_flags, dcc_address; 4633 uint64_t tiling_flags, dcc_address;
4642 struct dc_stream_status *stream_status;
4643 uint32_t target, target_vblank; 4634 uint32_t target, target_vblank;
4644 4635
4645 struct { 4636 struct {
@@ -4670,7 +4661,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
4670 struct drm_framebuffer *fb = new_plane_state->fb; 4661 struct drm_framebuffer *fb = new_plane_state->fb;
4671 struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(fb); 4662 struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(fb);
4672 bool pflip_needed; 4663 bool pflip_needed;
4673 struct dc_plane_state *surface, *dc_plane; 4664 struct dc_plane_state *dc_plane;
4674 struct dm_plane_state *dm_new_plane_state = to_dm_plane_state(new_plane_state); 4665 struct dm_plane_state *dm_new_plane_state = to_dm_plane_state(new_plane_state);
4675 4666
4676 if (plane->type == DRM_PLANE_TYPE_CURSOR) { 4667 if (plane->type == DRM_PLANE_TYPE_CURSOR) {
@@ -4733,39 +4724,22 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
4733 timestamp_ns = ktime_get_ns(); 4724 timestamp_ns = ktime_get_ns();
4734 flip->flip_addrs[flip_count].flip_timestamp_in_us = div_u64(timestamp_ns, 1000); 4725 flip->flip_addrs[flip_count].flip_timestamp_in_us = div_u64(timestamp_ns, 1000);
4735 flip->surface_updates[flip_count].flip_addr = &flip->flip_addrs[flip_count]; 4726 flip->surface_updates[flip_count].flip_addr = &flip->flip_addrs[flip_count];
4727 flip->surface_updates[flip_count].surface = dc_plane;
4736 4728
4737 stream_status = dc_stream_get_status(acrtc_state->stream);
4738 if (!stream_status) {
4739 DRM_ERROR("No stream status for CRTC: id=%d\n",
4740 acrtc_attach->crtc_id);
4741 continue;
4742 }
4743
4744 surface = stream_status->plane_states[0];
4745 flip->surface_updates[flip_count].surface = surface;
4746 if (!flip->surface_updates[flip_count].surface) { 4729 if (!flip->surface_updates[flip_count].surface) {
4747 DRM_ERROR("No surface for CRTC: id=%d\n", 4730 DRM_ERROR("No surface for CRTC: id=%d\n",
4748 acrtc_attach->crtc_id); 4731 acrtc_attach->crtc_id);
4749 continue; 4732 continue;
4750 } 4733 }
4751 4734
4752 if (acrtc_state->stream) 4735 if (plane == pcrtc->primary)
4753 update_freesync_state_on_stream( 4736 update_freesync_state_on_stream(
4754 dm, 4737 dm,
4755 acrtc_state, 4738 acrtc_state,
4756 acrtc_state->stream, 4739 acrtc_state->stream,
4757 surface, 4740 dc_plane,
4758 flip->flip_addrs[flip_count].flip_timestamp_in_us); 4741 flip->flip_addrs[flip_count].flip_timestamp_in_us);
4759 4742
4760 /* Update surface timing information. */
4761 surface->time.time_elapsed_in_us[surface->time.index] =
4762 flip->flip_addrs[flip_count].flip_timestamp_in_us -
4763 surface->time.prev_update_time_in_us;
4764 surface->time.prev_update_time_in_us = flip->flip_addrs[flip_count].flip_timestamp_in_us;
4765 surface->time.index++;
4766 if (surface->time.index >= DC_PLANE_UPDATE_TIMES_MAX)
4767 surface->time.index = 0;
4768
4769 DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x\n", 4743 DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x\n",
4770 __func__, 4744 __func__,
4771 flip->flip_addrs[flip_count].address.grph.addr.high_part, 4745 flip->flip_addrs[flip_count].address.grph.addr.high_part,
@@ -4902,7 +4876,8 @@ cleanup:
4902static void amdgpu_dm_crtc_copy_transient_flags(struct drm_crtc_state *crtc_state, 4876static void amdgpu_dm_crtc_copy_transient_flags(struct drm_crtc_state *crtc_state,
4903 struct dc_stream_state *stream_state) 4877 struct dc_stream_state *stream_state)
4904{ 4878{
4905 stream_state->mode_changed = crtc_state->mode_changed; 4879 stream_state->mode_changed =
4880 crtc_state->mode_changed || crtc_state->active_changed;
4906} 4881}
4907 4882
4908static int amdgpu_dm_atomic_commit(struct drm_device *dev, 4883static int amdgpu_dm_atomic_commit(struct drm_device *dev,
@@ -5094,10 +5069,13 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
5094 struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state); 5069 struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
5095 struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state); 5070 struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state);
5096 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); 5071 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
5097 struct dc_surface_update dummy_updates[MAX_SURFACES] = { 0 }; 5072 struct dc_surface_update dummy_updates[MAX_SURFACES];
5098 struct dc_stream_update stream_update = { 0 }; 5073 struct dc_stream_update stream_update;
5099 struct dc_stream_status *status = NULL; 5074 struct dc_stream_status *status = NULL;
5100 5075
5076 memset(&dummy_updates, 0, sizeof(dummy_updates));
5077 memset(&stream_update, 0, sizeof(stream_update));
5078
5101 if (acrtc) { 5079 if (acrtc) {
5102 new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base); 5080 new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
5103 old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base); 5081 old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base);
@@ -5174,9 +5152,11 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
5174 5152
5175 manage_dm_interrupts(adev, acrtc, true); 5153 manage_dm_interrupts(adev, acrtc, true);
5176 5154
5155#ifdef CONFIG_DEBUG_FS
5177 /* The stream has changed so CRC capture needs to re-enabled. */ 5156 /* The stream has changed so CRC capture needs to re-enabled. */
5178 if (dm_new_crtc_state->crc_enabled) 5157 if (dm_new_crtc_state->crc_enabled)
5179 amdgpu_dm_crtc_set_crc_source(crtc, "auto"); 5158 amdgpu_dm_crtc_set_crc_source(crtc, "auto");
5159#endif
5180 } 5160 }
5181 5161
5182 /* update planes when needed per crtc*/ 5162 /* update planes when needed per crtc*/
@@ -5372,10 +5352,13 @@ static void get_freesync_config_for_crtc(
5372 struct mod_freesync_config config = {0}; 5352 struct mod_freesync_config config = {0};
5373 struct amdgpu_dm_connector *aconnector = 5353 struct amdgpu_dm_connector *aconnector =
5374 to_amdgpu_dm_connector(new_con_state->base.connector); 5354 to_amdgpu_dm_connector(new_con_state->base.connector);
5355 struct drm_display_mode *mode = &new_crtc_state->base.mode;
5375 5356
5376 new_crtc_state->vrr_supported = new_con_state->freesync_capable; 5357 new_crtc_state->vrr_supported = new_con_state->freesync_capable &&
5358 aconnector->min_vfreq <= drm_mode_vrefresh(mode);
5377 5359
5378 if (new_con_state->freesync_capable) { 5360 if (new_crtc_state->vrr_supported) {
5361 new_crtc_state->stream->ignore_msa_timing_param = true;
5379 config.state = new_crtc_state->base.vrr_enabled ? 5362 config.state = new_crtc_state->base.vrr_enabled ?
5380 VRR_STATE_ACTIVE_VARIABLE : 5363 VRR_STATE_ACTIVE_VARIABLE :
5381 VRR_STATE_INACTIVE; 5364 VRR_STATE_INACTIVE;
@@ -5783,7 +5766,6 @@ dm_determine_update_type_for_commit(struct dc *dc,
5783 5766
5784 struct dc_surface_update *updates; 5767 struct dc_surface_update *updates;
5785 struct dc_plane_state *surface; 5768 struct dc_plane_state *surface;
5786 struct dc_stream_update stream_update;
5787 enum surface_update_type update_type = UPDATE_TYPE_FAST; 5769 enum surface_update_type update_type = UPDATE_TYPE_FAST;
5788 5770
5789 updates = kcalloc(MAX_SURFACES, sizeof(*updates), GFP_KERNEL); 5771 updates = kcalloc(MAX_SURFACES, sizeof(*updates), GFP_KERNEL);
@@ -5797,79 +5779,85 @@ dm_determine_update_type_for_commit(struct dc *dc,
5797 } 5779 }
5798 5780
5799 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { 5781 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
5782 struct dc_stream_update stream_update = { 0 };
5783
5800 new_dm_crtc_state = to_dm_crtc_state(new_crtc_state); 5784 new_dm_crtc_state = to_dm_crtc_state(new_crtc_state);
5801 old_dm_crtc_state = to_dm_crtc_state(old_crtc_state); 5785 old_dm_crtc_state = to_dm_crtc_state(old_crtc_state);
5802 num_plane = 0; 5786 num_plane = 0;
5803 5787
5804 if (new_dm_crtc_state->stream) { 5788 if (!new_dm_crtc_state->stream) {
5805 5789 if (!new_dm_crtc_state->stream && old_dm_crtc_state->stream) {
5806 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, j) { 5790 update_type = UPDATE_TYPE_FULL;
5807 new_plane_crtc = new_plane_state->crtc; 5791 goto cleanup;
5808 old_plane_crtc = old_plane_state->crtc;
5809 new_dm_plane_state = to_dm_plane_state(new_plane_state);
5810 old_dm_plane_state = to_dm_plane_state(old_plane_state);
5811
5812 if (plane->type == DRM_PLANE_TYPE_CURSOR)
5813 continue;
5814
5815 if (!state->allow_modeset)
5816 continue;
5817
5818 if (crtc == new_plane_crtc) {
5819 updates[num_plane].surface = &surface[num_plane];
5820
5821 if (new_crtc_state->mode_changed) {
5822 updates[num_plane].surface->src_rect =
5823 new_dm_plane_state->dc_state->src_rect;
5824 updates[num_plane].surface->dst_rect =
5825 new_dm_plane_state->dc_state->dst_rect;
5826 updates[num_plane].surface->rotation =
5827 new_dm_plane_state->dc_state->rotation;
5828 updates[num_plane].surface->in_transfer_func =
5829 new_dm_plane_state->dc_state->in_transfer_func;
5830 stream_update.dst = new_dm_crtc_state->stream->dst;
5831 stream_update.src = new_dm_crtc_state->stream->src;
5832 }
5833
5834 if (new_crtc_state->color_mgmt_changed) {
5835 updates[num_plane].gamma =
5836 new_dm_plane_state->dc_state->gamma_correction;
5837 updates[num_plane].in_transfer_func =
5838 new_dm_plane_state->dc_state->in_transfer_func;
5839 stream_update.gamut_remap =
5840 &new_dm_crtc_state->stream->gamut_remap_matrix;
5841 stream_update.out_transfer_func =
5842 new_dm_crtc_state->stream->out_transfer_func;
5843 }
5844
5845 num_plane++;
5846 }
5847 } 5792 }
5848 5793
5849 if (num_plane > 0) { 5794 continue;
5850 ret = dm_atomic_get_state(state, &dm_state); 5795 }
5851 if (ret)
5852 goto cleanup;
5853 5796
5854 old_dm_state = dm_atomic_get_old_state(state); 5797 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, j) {
5855 if (!old_dm_state) { 5798 new_plane_crtc = new_plane_state->crtc;
5856 ret = -EINVAL; 5799 old_plane_crtc = old_plane_state->crtc;
5857 goto cleanup; 5800 new_dm_plane_state = to_dm_plane_state(new_plane_state);
5858 } 5801 old_dm_plane_state = to_dm_plane_state(old_plane_state);
5859 5802
5860 status = dc_stream_get_status_from_state(old_dm_state->context, 5803 if (plane->type == DRM_PLANE_TYPE_CURSOR)
5861 new_dm_crtc_state->stream); 5804 continue;
5862 5805
5863 update_type = dc_check_update_surfaces_for_stream(dc, updates, num_plane, 5806 if (!state->allow_modeset)
5864 &stream_update, status); 5807 continue;
5865 5808
5866 if (update_type > UPDATE_TYPE_MED) { 5809 if (crtc != new_plane_crtc)
5867 update_type = UPDATE_TYPE_FULL; 5810 continue;
5868 goto cleanup; 5811
5869 } 5812 updates[num_plane].surface = &surface[num_plane];
5813
5814 if (new_crtc_state->mode_changed) {
5815 updates[num_plane].surface->src_rect =
5816 new_dm_plane_state->dc_state->src_rect;
5817 updates[num_plane].surface->dst_rect =
5818 new_dm_plane_state->dc_state->dst_rect;
5819 updates[num_plane].surface->rotation =
5820 new_dm_plane_state->dc_state->rotation;
5821 updates[num_plane].surface->in_transfer_func =
5822 new_dm_plane_state->dc_state->in_transfer_func;
5823 stream_update.dst = new_dm_crtc_state->stream->dst;
5824 stream_update.src = new_dm_crtc_state->stream->src;
5825 }
5826
5827 if (new_crtc_state->color_mgmt_changed) {
5828 updates[num_plane].gamma =
5829 new_dm_plane_state->dc_state->gamma_correction;
5830 updates[num_plane].in_transfer_func =
5831 new_dm_plane_state->dc_state->in_transfer_func;
5832 stream_update.gamut_remap =
5833 &new_dm_crtc_state->stream->gamut_remap_matrix;
5834 stream_update.out_transfer_func =
5835 new_dm_crtc_state->stream->out_transfer_func;
5870 } 5836 }
5871 5837
5872 } else if (!new_dm_crtc_state->stream && old_dm_crtc_state->stream) { 5838 num_plane++;
5839 }
5840
5841 if (num_plane == 0)
5842 continue;
5843
5844 ret = dm_atomic_get_state(state, &dm_state);
5845 if (ret)
5846 goto cleanup;
5847
5848 old_dm_state = dm_atomic_get_old_state(state);
5849 if (!old_dm_state) {
5850 ret = -EINVAL;
5851 goto cleanup;
5852 }
5853
5854 status = dc_stream_get_status_from_state(old_dm_state->context,
5855 new_dm_crtc_state->stream);
5856
5857 update_type = dc_check_update_surfaces_for_stream(dc, updates, num_plane,
5858 &stream_update, status);
5859
5860 if (update_type > UPDATE_TYPE_MED) {
5873 update_type = UPDATE_TYPE_FULL; 5861 update_type = UPDATE_TYPE_FULL;
5874 goto cleanup; 5862 goto cleanup;
5875 } 5863 }
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 748d6ff3e4f3..f51d52eb52e6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -174,6 +174,11 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
174 aconnector->edid = edid; 174 aconnector->edid = edid;
175 } 175 }
176 176
177 if (aconnector->dc_sink && aconnector->dc_sink->sink_signal == SIGNAL_TYPE_VIRTUAL) {
178 dc_sink_release(aconnector->dc_sink);
179 aconnector->dc_sink = NULL;
180 }
181
177 if (!aconnector->dc_sink) { 182 if (!aconnector->dc_sink) {
178 struct dc_sink *dc_sink; 183 struct dc_sink *dc_sink;
179 struct dc_sink_init_data init_params = { 184 struct dc_sink_init_data init_params = {
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c
index 7d102ac0d61b..1ef0074302c5 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c
@@ -63,7 +63,7 @@ void scaler_settings_calculation(struct dcn_bw_internal_vars *v)
63 if (v->interlace_output[k] == 1.0) { 63 if (v->interlace_output[k] == 1.0) {
64 v->v_ratio[k] = 2.0 * v->v_ratio[k]; 64 v->v_ratio[k] = 2.0 * v->v_ratio[k];
65 } 65 }
66 if ((v->underscan_output[k] == 1.0)) { 66 if (v->underscan_output[k] == 1.0) {
67 v->h_ratio[k] = v->h_ratio[k] * v->under_scan_factor; 67 v->h_ratio[k] = v->h_ratio[k] * v->under_scan_factor;
68 v->v_ratio[k] = v->v_ratio[k] * v->under_scan_factor; 68 v->v_ratio[k] = v->v_ratio[k] * v->under_scan_factor;
69 } 69 }
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index e22be0aefd1b..52f838442e21 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -621,7 +621,6 @@ static bool construct(struct dc *dc,
621#endif 621#endif
622 622
623 enum dce_version dc_version = DCE_VERSION_UNKNOWN; 623 enum dce_version dc_version = DCE_VERSION_UNKNOWN;
624
625 dc_dceip = kzalloc(sizeof(*dc_dceip), GFP_KERNEL); 624 dc_dceip = kzalloc(sizeof(*dc_dceip), GFP_KERNEL);
626 if (!dc_dceip) { 625 if (!dc_dceip) {
627 dm_error("%s: failed to create dceip\n", __func__); 626 dm_error("%s: failed to create dceip\n", __func__);
@@ -869,8 +868,9 @@ static void program_timing_sync(
869 struct dc *dc, 868 struct dc *dc,
870 struct dc_state *ctx) 869 struct dc_state *ctx)
871{ 870{
872 int i, j; 871 int i, j, k;
873 int group_index = 0; 872 int group_index = 0;
873 int num_group = 0;
874 int pipe_count = dc->res_pool->pipe_count; 874 int pipe_count = dc->res_pool->pipe_count;
875 struct pipe_ctx *unsynced_pipes[MAX_PIPES] = { NULL }; 875 struct pipe_ctx *unsynced_pipes[MAX_PIPES] = { NULL };
876 876
@@ -907,11 +907,11 @@ static void program_timing_sync(
907 } 907 }
908 } 908 }
909 909
910 /* set first unblanked pipe as master */ 910 /* set first pipe with plane as master */
911 for (j = 0; j < group_size; j++) { 911 for (j = 0; j < group_size; j++) {
912 struct pipe_ctx *temp; 912 struct pipe_ctx *temp;
913 913
914 if (pipe_set[j]->stream_res.tg->funcs->is_blanked && !pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg)) { 914 if (pipe_set[j]->plane_state) {
915 if (j == 0) 915 if (j == 0)
916 break; 916 break;
917 917
@@ -922,9 +922,21 @@ static void program_timing_sync(
922 } 922 }
923 } 923 }
924 924
925 /* remove any other unblanked pipes as they have already been synced */ 925
926 for (k = 0; k < group_size; k++) {
927 struct dc_stream_status *status = dc_stream_get_status_from_state(ctx, pipe_set[k]->stream);
928
929 status->timing_sync_info.group_id = num_group;
930 status->timing_sync_info.group_size = group_size;
931 if (k == 0)
932 status->timing_sync_info.master = true;
933 else
934 status->timing_sync_info.master = false;
935
936 }
937 /* remove any other pipes with plane as they have already been synced */
926 for (j = j + 1; j < group_size; j++) { 938 for (j = j + 1; j < group_size; j++) {
927 if (pipe_set[j]->stream_res.tg->funcs->is_blanked && !pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg)) { 939 if (pipe_set[j]->plane_state) {
928 group_size--; 940 group_size--;
929 pipe_set[j] = pipe_set[group_size]; 941 pipe_set[j] = pipe_set[group_size];
930 j--; 942 j--;
@@ -936,6 +948,7 @@ static void program_timing_sync(
936 dc, group_index, group_size, pipe_set); 948 dc, group_index, group_size, pipe_set);
937 group_index++; 949 group_index++;
938 } 950 }
951 num_group++;
939 } 952 }
940} 953}
941 954
@@ -956,6 +969,52 @@ static bool context_changed(
956 return false; 969 return false;
957} 970}
958 971
972bool dc_validate_seamless_boot_timing(struct dc *dc,
973 const struct dc_sink *sink,
974 struct dc_crtc_timing *crtc_timing)
975{
976 struct timing_generator *tg;
977 struct dc_link *link = sink->link;
978 unsigned int inst;
979
980 /* Check for enabled DIG to identify enabled display */
981 if (!link->link_enc->funcs->is_dig_enabled(link->link_enc))
982 return false;
983
984 /* Check for which front end is used by this encoder.
985 * Note the inst is 1 indexed, where 0 is undefined.
986 * Note that DIG_FE can source from different OTG but our
987 * current implementation always map 1-to-1, so this code makes
988 * the same assumption and doesn't check OTG source.
989 */
990 inst = link->link_enc->funcs->get_dig_frontend(link->link_enc) - 1;
991
992 /* Instance should be within the range of the pool */
993 if (inst >= dc->res_pool->pipe_count)
994 return false;
995
996 tg = dc->res_pool->timing_generators[inst];
997
998 if (!tg->funcs->is_matching_timing)
999 return false;
1000
1001 if (!tg->funcs->is_matching_timing(tg, crtc_timing))
1002 return false;
1003
1004 if (dc_is_dp_signal(link->connector_signal)) {
1005 unsigned int pix_clk_100hz;
1006
1007 dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz(
1008 dc->res_pool->dp_clock_source,
1009 inst, &pix_clk_100hz);
1010
1011 if (crtc_timing->pix_clk_100hz != pix_clk_100hz)
1012 return false;
1013 }
1014
1015 return true;
1016}
1017
959bool dc_enable_stereo( 1018bool dc_enable_stereo(
960 struct dc *dc, 1019 struct dc *dc,
961 struct dc_state *context, 1020 struct dc_state *context,
@@ -1037,6 +1096,9 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
1037 const struct dc_link *link = context->streams[i]->link; 1096 const struct dc_link *link = context->streams[i]->link;
1038 struct dc_stream_status *status; 1097 struct dc_stream_status *status;
1039 1098
1099 if (context->streams[i]->apply_seamless_boot_optimization)
1100 context->streams[i]->apply_seamless_boot_optimization = false;
1101
1040 if (!context->streams[i]->mode_changed) 1102 if (!context->streams[i]->mode_changed)
1041 continue; 1103 continue;
1042 1104
@@ -1112,6 +1174,9 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
1112 int i; 1174 int i;
1113 struct dc_state *context = dc->current_state; 1175 struct dc_state *context = dc->current_state;
1114 1176
1177 if (dc->optimized_required == false)
1178 return true;
1179
1115 post_surface_trace(dc); 1180 post_surface_trace(dc);
1116 1181
1117 for (i = 0; i < dc->res_pool->pipe_count; i++) 1182 for (i = 0; i < dc->res_pool->pipe_count; i++)
@@ -1440,6 +1505,101 @@ static struct dc_stream_status *stream_get_status(
1440 1505
1441static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL; 1506static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
1442 1507
1508static void copy_surface_update_to_plane(
1509 struct dc_plane_state *surface,
1510 struct dc_surface_update *srf_update)
1511{
1512 if (srf_update->flip_addr) {
1513 surface->address = srf_update->flip_addr->address;
1514 surface->flip_immediate =
1515 srf_update->flip_addr->flip_immediate;
1516 surface->time.time_elapsed_in_us[surface->time.index] =
1517 srf_update->flip_addr->flip_timestamp_in_us -
1518 surface->time.prev_update_time_in_us;
1519 surface->time.prev_update_time_in_us =
1520 srf_update->flip_addr->flip_timestamp_in_us;
1521 surface->time.index++;
1522 if (surface->time.index >= DC_PLANE_UPDATE_TIMES_MAX)
1523 surface->time.index = 0;
1524 }
1525
1526 if (srf_update->scaling_info) {
1527 surface->scaling_quality =
1528 srf_update->scaling_info->scaling_quality;
1529 surface->dst_rect =
1530 srf_update->scaling_info->dst_rect;
1531 surface->src_rect =
1532 srf_update->scaling_info->src_rect;
1533 surface->clip_rect =
1534 srf_update->scaling_info->clip_rect;
1535 }
1536
1537 if (srf_update->plane_info) {
1538 surface->color_space =
1539 srf_update->plane_info->color_space;
1540 surface->format =
1541 srf_update->plane_info->format;
1542 surface->plane_size =
1543 srf_update->plane_info->plane_size;
1544 surface->rotation =
1545 srf_update->plane_info->rotation;
1546 surface->horizontal_mirror =
1547 srf_update->plane_info->horizontal_mirror;
1548 surface->stereo_format =
1549 srf_update->plane_info->stereo_format;
1550 surface->tiling_info =
1551 srf_update->plane_info->tiling_info;
1552 surface->visible =
1553 srf_update->plane_info->visible;
1554 surface->per_pixel_alpha =
1555 srf_update->plane_info->per_pixel_alpha;
1556 surface->global_alpha =
1557 srf_update->plane_info->global_alpha;
1558 surface->global_alpha_value =
1559 srf_update->plane_info->global_alpha_value;
1560 surface->dcc =
1561 srf_update->plane_info->dcc;
1562 surface->sdr_white_level =
1563 srf_update->plane_info->sdr_white_level;
1564 }
1565
1566 if (srf_update->gamma &&
1567 (surface->gamma_correction !=
1568 srf_update->gamma)) {
1569 memcpy(&surface->gamma_correction->entries,
1570 &srf_update->gamma->entries,
1571 sizeof(struct dc_gamma_entries));
1572 surface->gamma_correction->is_identity =
1573 srf_update->gamma->is_identity;
1574 surface->gamma_correction->num_entries =
1575 srf_update->gamma->num_entries;
1576 surface->gamma_correction->type =
1577 srf_update->gamma->type;
1578 }
1579
1580 if (srf_update->in_transfer_func &&
1581 (surface->in_transfer_func !=
1582 srf_update->in_transfer_func)) {
1583 surface->in_transfer_func->sdr_ref_white_level =
1584 srf_update->in_transfer_func->sdr_ref_white_level;
1585 surface->in_transfer_func->tf =
1586 srf_update->in_transfer_func->tf;
1587 surface->in_transfer_func->type =
1588 srf_update->in_transfer_func->type;
1589 memcpy(&surface->in_transfer_func->tf_pts,
1590 &srf_update->in_transfer_func->tf_pts,
1591 sizeof(struct dc_transfer_func_distributed_points));
1592 }
1593
1594 if (srf_update->input_csc_color_matrix)
1595 surface->input_csc_color_matrix =
1596 *srf_update->input_csc_color_matrix;
1597
1598 if (srf_update->coeff_reduction_factor)
1599 surface->coeff_reduction_factor =
1600 *srf_update->coeff_reduction_factor;
1601}
1602
1443static void commit_planes_do_stream_update(struct dc *dc, 1603static void commit_planes_do_stream_update(struct dc *dc,
1444 struct dc_stream_state *stream, 1604 struct dc_stream_state *stream,
1445 struct dc_stream_update *stream_update, 1605 struct dc_stream_update *stream_update,
@@ -1463,13 +1623,13 @@ static void commit_planes_do_stream_update(struct dc *dc,
1463 stream_update->adjust->v_total_min, 1623 stream_update->adjust->v_total_min,
1464 stream_update->adjust->v_total_max); 1624 stream_update->adjust->v_total_max);
1465 1625
1466 if (stream_update->vline0_config && pipe_ctx->stream_res.tg->funcs->program_vline_interrupt) 1626 if (stream_update->periodic_vsync_config && pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
1467 pipe_ctx->stream_res.tg->funcs->program_vline_interrupt( 1627 pipe_ctx->stream_res.tg->funcs->program_vline_interrupt(
1468 pipe_ctx->stream_res.tg, VLINE0, stream->vline0_config); 1628 pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, VLINE0, &stream->periodic_vsync_config);
1469 1629
1470 if (stream_update->vline1_config && pipe_ctx->stream_res.tg->funcs->program_vline_interrupt) 1630 if (stream_update->enhanced_sync_config && pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
1471 pipe_ctx->stream_res.tg->funcs->program_vline_interrupt( 1631 pipe_ctx->stream_res.tg->funcs->program_vline_interrupt(
1472 pipe_ctx->stream_res.tg, VLINE1, stream->vline1_config); 1632 pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, VLINE1, &stream->enhanced_sync_config);
1473 1633
1474 if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) || 1634 if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
1475 stream_update->vrr_infopacket || 1635 stream_update->vrr_infopacket ||
@@ -1645,14 +1805,7 @@ void dc_commit_updates_for_stream(struct dc *dc,
1645 for (i = 0; i < surface_count; i++) { 1805 for (i = 0; i < surface_count; i++) {
1646 struct dc_plane_state *surface = srf_updates[i].surface; 1806 struct dc_plane_state *surface = srf_updates[i].surface;
1647 1807
1648 /* TODO: On flip we don't build the state, so it still has the 1808 copy_surface_update_to_plane(surface, &srf_updates[i]);
1649 * old address. Which is why we are updating the address here
1650 */
1651 if (srf_updates[i].flip_addr) {
1652 surface->address = srf_updates[i].flip_addr->address;
1653 surface->flip_immediate = srf_updates[i].flip_addr->flip_immediate;
1654
1655 }
1656 1809
1657 if (update_type >= UPDATE_TYPE_MED) { 1810 if (update_type >= UPDATE_TYPE_MED) {
1658 for (j = 0; j < dc->res_pool->pipe_count; j++) { 1811 for (j = 0; j < dc->res_pool->pipe_count; j++) {
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 8ff5d42587c2..7f5a947ad31d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -76,6 +76,12 @@ static void destruct(struct dc_link *link)
76{ 76{
77 int i; 77 int i;
78 78
79 if (link->hpd_gpio != NULL) {
80 dal_gpio_close(link->hpd_gpio);
81 dal_gpio_destroy_irq(&link->hpd_gpio);
82 link->hpd_gpio = NULL;
83 }
84
79 if (link->ddc) 85 if (link->ddc)
80 dal_ddc_service_destroy(&link->ddc); 86 dal_ddc_service_destroy(&link->ddc);
81 87
@@ -931,18 +937,11 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
931 937
932bool dc_link_get_hpd_state(struct dc_link *dc_link) 938bool dc_link_get_hpd_state(struct dc_link *dc_link)
933{ 939{
934 struct gpio *hpd_pin;
935 uint32_t state; 940 uint32_t state;
936 941
937 hpd_pin = get_hpd_gpio(dc_link->ctx->dc_bios, 942 dal_gpio_lock_pin(dc_link->hpd_gpio);
938 dc_link->link_id, dc_link->ctx->gpio_service); 943 dal_gpio_get_value(dc_link->hpd_gpio, &state);
939 if (hpd_pin == NULL) 944 dal_gpio_unlock_pin(dc_link->hpd_gpio);
940 ASSERT(false);
941
942 dal_gpio_open(hpd_pin, GPIO_MODE_INTERRUPT);
943 dal_gpio_get_value(hpd_pin, &state);
944 dal_gpio_close(hpd_pin);
945 dal_gpio_destroy_irq(&hpd_pin);
946 945
947 return state; 946 return state;
948} 947}
@@ -1098,7 +1097,6 @@ static bool construct(
1098 const struct link_init_data *init_params) 1097 const struct link_init_data *init_params)
1099{ 1098{
1100 uint8_t i; 1099 uint8_t i;
1101 struct gpio *hpd_gpio = NULL;
1102 struct ddc_service_init_data ddc_service_init_data = { { 0 } }; 1100 struct ddc_service_init_data ddc_service_init_data = { { 0 } };
1103 struct dc_context *dc_ctx = init_params->ctx; 1101 struct dc_context *dc_ctx = init_params->ctx;
1104 struct encoder_init_data enc_init_data = { 0 }; 1102 struct encoder_init_data enc_init_data = { 0 };
@@ -1128,10 +1126,12 @@ static bool construct(
1128 if (link->dc->res_pool->funcs->link_init) 1126 if (link->dc->res_pool->funcs->link_init)
1129 link->dc->res_pool->funcs->link_init(link); 1127 link->dc->res_pool->funcs->link_init(link);
1130 1128
1131 hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service); 1129 link->hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
1132 1130 if (link->hpd_gpio != NULL) {
1133 if (hpd_gpio != NULL) 1131 dal_gpio_open(link->hpd_gpio, GPIO_MODE_INTERRUPT);
1134 link->irq_source_hpd = dal_irq_get_source(hpd_gpio); 1132 dal_gpio_unlock_pin(link->hpd_gpio);
1133 link->irq_source_hpd = dal_irq_get_source(link->hpd_gpio);
1134 }
1135 1135
1136 switch (link->link_id.id) { 1136 switch (link->link_id.id) {
1137 case CONNECTOR_ID_HDMI_TYPE_A: 1137 case CONNECTOR_ID_HDMI_TYPE_A:
@@ -1149,18 +1149,18 @@ static bool construct(
1149 case CONNECTOR_ID_DISPLAY_PORT: 1149 case CONNECTOR_ID_DISPLAY_PORT:
1150 link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT; 1150 link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
1151 1151
1152 if (hpd_gpio != NULL) 1152 if (link->hpd_gpio != NULL)
1153 link->irq_source_hpd_rx = 1153 link->irq_source_hpd_rx =
1154 dal_irq_get_rx_source(hpd_gpio); 1154 dal_irq_get_rx_source(link->hpd_gpio);
1155 1155
1156 break; 1156 break;
1157 case CONNECTOR_ID_EDP: 1157 case CONNECTOR_ID_EDP:
1158 link->connector_signal = SIGNAL_TYPE_EDP; 1158 link->connector_signal = SIGNAL_TYPE_EDP;
1159 1159
1160 if (hpd_gpio != NULL) { 1160 if (link->hpd_gpio != NULL) {
1161 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID; 1161 link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
1162 link->irq_source_hpd_rx = 1162 link->irq_source_hpd_rx =
1163 dal_irq_get_rx_source(hpd_gpio); 1163 dal_irq_get_rx_source(link->hpd_gpio);
1164 } 1164 }
1165 break; 1165 break;
1166 case CONNECTOR_ID_LVDS: 1166 case CONNECTOR_ID_LVDS:
@@ -1171,10 +1171,7 @@ static bool construct(
1171 goto create_fail; 1171 goto create_fail;
1172 } 1172 }
1173 1173
1174 if (hpd_gpio != NULL) { 1174
1175 dal_gpio_destroy_irq(&hpd_gpio);
1176 hpd_gpio = NULL;
1177 }
1178 1175
1179 /* TODO: #DAL3 Implement id to str function.*/ 1176 /* TODO: #DAL3 Implement id to str function.*/
1180 LINK_INFO("Connector[%d] description:" 1177 LINK_INFO("Connector[%d] description:"
@@ -1277,8 +1274,9 @@ link_enc_create_fail:
1277ddc_create_fail: 1274ddc_create_fail:
1278create_fail: 1275create_fail:
1279 1276
1280 if (hpd_gpio != NULL) { 1277 if (link->hpd_gpio != NULL) {
1281 dal_gpio_destroy_irq(&hpd_gpio); 1278 dal_gpio_destroy_irq(&link->hpd_gpio);
1279 link->hpd_gpio = NULL;
1282 } 1280 }
1283 1281
1284 return false; 1282 return false;
@@ -2582,13 +2580,23 @@ void core_link_enable_stream(
2582 &stream->timing); 2580 &stream->timing);
2583 2581
2584 if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) { 2582 if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
2583 bool apply_edp_fast_boot_optimization =
2584 pipe_ctx->stream->apply_edp_fast_boot_optimization;
2585
2586 pipe_ctx->stream->apply_edp_fast_boot_optimization = false;
2587
2585 resource_build_info_frame(pipe_ctx); 2588 resource_build_info_frame(pipe_ctx);
2586 core_dc->hwss.update_info_frame(pipe_ctx); 2589 core_dc->hwss.update_info_frame(pipe_ctx);
2587 2590
2591 /* Do not touch link on seamless boot optimization. */
2592 if (pipe_ctx->stream->apply_seamless_boot_optimization) {
2593 pipe_ctx->stream->dpms_off = false;
2594 return;
2595 }
2596
2588 /* eDP lit up by bios already, no need to enable again. */ 2597 /* eDP lit up by bios already, no need to enable again. */
2589 if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP && 2598 if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
2590 pipe_ctx->stream->apply_edp_fast_boot_optimization) { 2599 apply_edp_fast_boot_optimization) {
2591 pipe_ctx->stream->apply_edp_fast_boot_optimization = false;
2592 pipe_ctx->stream->dpms_off = false; 2600 pipe_ctx->stream->dpms_off = false;
2593 return; 2601 return;
2594 } 2602 }
@@ -2615,6 +2623,8 @@ void core_link_enable_stream(
2615 } 2623 }
2616 } 2624 }
2617 2625
2626 stream->link->link_status.link_active = true;
2627
2618 core_dc->hwss.enable_audio_stream(pipe_ctx); 2628 core_dc->hwss.enable_audio_stream(pipe_ctx);
2619 2629
2620 /* turn off otg test pattern if enable */ 2630 /* turn off otg test pattern if enable */
@@ -2649,6 +2659,8 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
2649 core_dc->hwss.disable_stream(pipe_ctx, option); 2659 core_dc->hwss.disable_stream(pipe_ctx, option);
2650 2660
2651 disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal); 2661 disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal);
2662
2663 pipe_ctx->stream->link->link_status.link_active = false;
2652} 2664}
2653 2665
2654void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) 2666void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 92f565ca1260..09d301216076 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -47,7 +47,9 @@ static void wait_for_training_aux_rd_interval(
47 struct dc_link *link, 47 struct dc_link *link,
48 uint32_t default_wait_in_micro_secs) 48 uint32_t default_wait_in_micro_secs)
49{ 49{
50 union training_aux_rd_interval training_rd_interval = {0}; 50 union training_aux_rd_interval training_rd_interval;
51
52 memset(&training_rd_interval, 0, sizeof(training_rd_interval));
51 53
52 /* overwrite the delay if rev > 1.1*/ 54 /* overwrite the delay if rev > 1.1*/
53 if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) { 55 if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
@@ -2538,7 +2540,6 @@ void detect_edp_sink_caps(struct dc_link *link)
2538 uint32_t entry; 2540 uint32_t entry;
2539 uint32_t link_rate_in_khz; 2541 uint32_t link_rate_in_khz;
2540 enum dc_link_rate link_rate = LINK_RATE_UNKNOWN; 2542 enum dc_link_rate link_rate = LINK_RATE_UNKNOWN;
2541 uint8_t link_rate_set = 0;
2542 2543
2543 retrieve_link_cap(link); 2544 retrieve_link_cap(link);
2544 2545
@@ -2558,39 +2559,7 @@ void detect_edp_sink_caps(struct dc_link *link)
2558 link_rate = linkRateInKHzToLinkRateMultiplier(link_rate_in_khz); 2559 link_rate = linkRateInKHzToLinkRateMultiplier(link_rate_in_khz);
2559 if (link->reported_link_cap.link_rate < link_rate) { 2560 if (link->reported_link_cap.link_rate < link_rate) {
2560 link->reported_link_cap.link_rate = link_rate; 2561 link->reported_link_cap.link_rate = link_rate;
2561 2562 link->dpcd_caps.link_rate_set = entry;
2562 switch (link_rate) {
2563 case LINK_RATE_LOW:
2564 link_rate_set = 1;
2565 break;
2566 case LINK_RATE_RATE_2:
2567 link_rate_set = 2;
2568 break;
2569 case LINK_RATE_RATE_3:
2570 link_rate_set = 3;
2571 break;
2572 case LINK_RATE_HIGH:
2573 link_rate_set = 4;
2574 break;
2575 case LINK_RATE_RBR2:
2576 link_rate_set = 5;
2577 break;
2578 case LINK_RATE_RATE_6:
2579 link_rate_set = 6;
2580 break;
2581 case LINK_RATE_HIGH2:
2582 link_rate_set = 7;
2583 break;
2584 case LINK_RATE_HIGH3:
2585 link_rate_set = 8;
2586 break;
2587 default:
2588 link_rate_set = 0;
2589 break;
2590 }
2591
2592 if (link->dpcd_caps.link_rate_set < link_rate_set)
2593 link->dpcd_caps.link_rate_set = link_rate_set;
2594 } 2563 }
2595 } 2564 }
2596 } 2565 }
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
index 16d441d3af8a..f7f7515f65f4 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -119,6 +119,10 @@ bool edp_receiver_ready_T9(struct dc_link *link)
119 break; 119 break;
120 udelay(100); //MAx T9 120 udelay(100); //MAx T9
121 } while (++tries < 50); 121 } while (++tries < 50);
122
123 if (link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off > 0)
124 udelay(link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off * 1000);
125
122 return result; 126 return result;
123} 127}
124bool edp_receiver_ready_T7(struct dc_link *link) 128bool edp_receiver_ready_T7(struct dc_link *link)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 9888bc7659f3..349ab8017776 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1800,6 +1800,51 @@ static void calculate_phy_pix_clks(struct dc_stream_state *stream)
1800 stream->phy_pix_clk *= 2; 1800 stream->phy_pix_clk *= 2;
1801} 1801}
1802 1802
1803static int acquire_resource_from_hw_enabled_state(
1804 struct resource_context *res_ctx,
1805 const struct resource_pool *pool,
1806 struct dc_stream_state *stream)
1807{
1808 struct dc_link *link = stream->link;
1809 unsigned int inst;
1810
1811 /* Check for enabled DIG to identify enabled display */
1812 if (!link->link_enc->funcs->is_dig_enabled(link->link_enc))
1813 return -1;
1814
1815 /* Check for which front end is used by this encoder.
1816 * Note the inst is 1 indexed, where 0 is undefined.
1817 * Note that DIG_FE can source from different OTG but our
1818 * current implementation always map 1-to-1, so this code makes
1819 * the same assumption and doesn't check OTG source.
1820 */
1821 inst = link->link_enc->funcs->get_dig_frontend(link->link_enc) - 1;
1822
1823 /* Instance should be within the range of the pool */
1824 if (inst >= pool->pipe_count)
1825 return -1;
1826
1827 if (!res_ctx->pipe_ctx[inst].stream) {
1828 struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[inst];
1829
1830 pipe_ctx->stream_res.tg = pool->timing_generators[inst];
1831 pipe_ctx->plane_res.mi = pool->mis[inst];
1832 pipe_ctx->plane_res.hubp = pool->hubps[inst];
1833 pipe_ctx->plane_res.ipp = pool->ipps[inst];
1834 pipe_ctx->plane_res.xfm = pool->transforms[inst];
1835 pipe_ctx->plane_res.dpp = pool->dpps[inst];
1836 pipe_ctx->stream_res.opp = pool->opps[inst];
1837 if (pool->dpps[inst])
1838 pipe_ctx->plane_res.mpcc_inst = pool->dpps[inst]->inst;
1839 pipe_ctx->pipe_idx = inst;
1840
1841 pipe_ctx->stream = stream;
1842 return inst;
1843 }
1844
1845 return -1;
1846}
1847
1803enum dc_status resource_map_pool_resources( 1848enum dc_status resource_map_pool_resources(
1804 const struct dc *dc, 1849 const struct dc *dc,
1805 struct dc_state *context, 1850 struct dc_state *context,
@@ -1824,8 +1869,15 @@ enum dc_status resource_map_pool_resources(
1824 1869
1825 calculate_phy_pix_clks(stream); 1870 calculate_phy_pix_clks(stream);
1826 1871
1827 /* acquire new resources */ 1872 if (stream->apply_seamless_boot_optimization)
1828 pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream); 1873 pipe_idx = acquire_resource_from_hw_enabled_state(
1874 &context->res_ctx,
1875 pool,
1876 stream);
1877
1878 if (pipe_idx < 0)
1879 /* acquire new resources */
1880 pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream);
1829 1881
1830#ifdef CONFIG_DRM_AMD_DC_DCN1_0 1882#ifdef CONFIG_DRM_AMD_DC_DCN1_0
1831 if (pipe_idx < 0) 1883 if (pipe_idx < 0)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_vm_helper.c b/drivers/gpu/drm/amd/display/dc/core/dc_vm_helper.c
index e54b8ac339b2..6ce87b682a32 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_vm_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_vm_helper.c
@@ -112,16 +112,12 @@ uint8_t get_vmid_for_ptb(struct vm_helper *vm_helper, int64_t ptb, uint8_t hubp_
112 return vmid; 112 return vmid;
113} 113}
114 114
115struct vm_helper init_vm_helper(unsigned int num_vmid, unsigned int num_hubp) 115void init_vm_helper(struct vm_helper *vm_helper, unsigned int num_vmid, unsigned int num_hubp)
116{ 116{
117 static uint64_t ptb_assigned_to_vmid[MAX_VMID]; 117 vm_helper->num_vmid = num_vmid;
118 static struct vmid_usage hubp_vmid_usage[MAX_HUBP]; 118 vm_helper->num_hubp = num_hubp;
119 119 vm_helper->num_vmids_available = num_vmid - 1;
120 return (struct vm_helper){ 120
121 .num_vmid = num_vmid, 121 memset(vm_helper->hubp_vmid_usage, 0, sizeof(vm_helper->hubp_vmid_usage[0]) * MAX_HUBP);
122 .num_hubp = num_hubp, 122 memset(vm_helper->ptb_assigned_to_vmid, 0, sizeof(vm_helper->ptb_assigned_to_vmid[0]) * MAX_VMID);
123 .num_vmids_available = num_vmid - 1,
124 .ptb_assigned_to_vmid = ptb_assigned_to_vmid,
125 .hubp_vmid_usage = hubp_vmid_usage
126 };
127} 123}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 8391bc39b7a9..1a7fd6aa77eb 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -39,7 +39,7 @@
39#include "inc/hw/dmcu.h" 39#include "inc/hw/dmcu.h"
40#include "dml/display_mode_lib.h" 40#include "dml/display_mode_lib.h"
41 41
42#define DC_VER "3.2.15" 42#define DC_VER "3.2.17"
43 43
44#define MAX_SURFACES 3 44#define MAX_SURFACES 3
45#define MAX_STREAMS 6 45#define MAX_STREAMS 6
@@ -255,6 +255,7 @@ struct dc_debug_options {
255 bool scl_reset_length10; 255 bool scl_reset_length10;
256 bool hdmi20_disable; 256 bool hdmi20_disable;
257 bool skip_detection_link_training; 257 bool skip_detection_link_training;
258 unsigned int force_odm_combine; //bit vector based on otg inst
258 unsigned int force_fclk_khz; 259 unsigned int force_fclk_khz;
259}; 260};
260 261
@@ -264,7 +265,6 @@ struct dc_debug_data {
264 uint32_t auxErrorCount; 265 uint32_t auxErrorCount;
265}; 266};
266 267
267
268struct dc_state; 268struct dc_state;
269struct resource_pool; 269struct resource_pool;
270struct dce_hwseq; 270struct dce_hwseq;
@@ -594,6 +594,10 @@ struct dc_validation_set {
594 uint8_t plane_count; 594 uint8_t plane_count;
595}; 595};
596 596
597bool dc_validate_seamless_boot_timing(struct dc *dc,
598 const struct dc_sink *sink,
599 struct dc_crtc_timing *crtc_timing);
600
597enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state); 601enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state);
598 602
599void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info); 603void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info);
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index f249ff9be2a7..8fc223defed4 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -30,6 +30,7 @@
30#include "grph_object_defs.h" 30#include "grph_object_defs.h"
31 31
32struct dc_link_status { 32struct dc_link_status {
33 bool link_active;
33 struct dpcd_caps *dpcd_caps; 34 struct dpcd_caps *dpcd_caps;
34}; 35};
35 36
@@ -125,6 +126,7 @@ struct dc_link {
125 struct dc_link_status link_status; 126 struct dc_link_status link_status;
126 127
127 struct link_trace link_trace; 128 struct link_trace link_trace;
129 struct gpio *hpd_gpio;
128}; 130};
129 131
130const struct dc_link_status *dc_link_get_status(const struct dc_link *dc_link); 132const struct dc_link_status *dc_link_get_status(const struct dc_link *dc_link);
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index 0de6d7f377a6..a798694992b9 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -32,11 +32,17 @@
32/******************************************************************************* 32/*******************************************************************************
33 * Stream Interfaces 33 * Stream Interfaces
34 ******************************************************************************/ 34 ******************************************************************************/
35struct timing_sync_info {
36 int group_id;
37 int group_size;
38 bool master;
39};
35 40
36struct dc_stream_status { 41struct dc_stream_status {
37 int primary_otg_inst; 42 int primary_otg_inst;
38 int stream_enc_inst; 43 int stream_enc_inst;
39 int plane_count; 44 int plane_count;
45 struct timing_sync_info timing_sync_info;
40 struct dc_plane_state *plane_states[MAX_SURFACE_NUM]; 46 struct dc_plane_state *plane_states[MAX_SURFACE_NUM];
41}; 47};
42 48
@@ -45,11 +51,12 @@ struct freesync_context {
45 bool dummy; 51 bool dummy;
46}; 52};
47 53
48struct vline_config { 54union vline_config {
49 unsigned int start_line; 55 unsigned int line_number;
50 unsigned int end_line; 56 unsigned long long delta_in_ns;
51}; 57};
52 58
59
53struct dc_stream_state { 60struct dc_stream_state {
54 // sink is deprecated, new code should not reference 61 // sink is deprecated, new code should not reference
55 // this pointer 62 // this pointer
@@ -99,8 +106,8 @@ struct dc_stream_state {
99 /* DMCU info */ 106 /* DMCU info */
100 unsigned int abm_level; 107 unsigned int abm_level;
101 108
102 struct vline_config vline0_config; 109 union vline_config periodic_vsync_config;
103 struct vline_config vline1_config; 110 union vline_config enhanced_sync_config;
104 111
105 /* from core_stream struct */ 112 /* from core_stream struct */
106 struct dc_context *ctx; 113 struct dc_context *ctx;
@@ -112,7 +119,6 @@ struct dc_stream_state {
112 int phy_pix_clk; 119 int phy_pix_clk;
113 enum signal_type signal; 120 enum signal_type signal;
114 bool dpms_off; 121 bool dpms_off;
115 bool apply_edp_fast_boot_optimization;
116 122
117 void *dm_stream_context; 123 void *dm_stream_context;
118 124
@@ -139,6 +145,9 @@ struct dc_stream_state {
139 uint8_t otg_offset; 145 uint8_t otg_offset;
140 } out; 146 } out;
141 147
148 bool apply_edp_fast_boot_optimization;
149 bool apply_seamless_boot_optimization;
150
142 uint32_t stream_id; 151 uint32_t stream_id;
143}; 152};
144 153
@@ -149,8 +158,8 @@ struct dc_stream_update {
149 struct dc_info_packet *hdr_static_metadata; 158 struct dc_info_packet *hdr_static_metadata;
150 unsigned int *abm_level; 159 unsigned int *abm_level;
151 160
152 struct vline_config *vline0_config; 161 union vline_config *periodic_vsync_config;
153 struct vline_config *vline1_config; 162 union vline_config *enhanced_sync_config;
154 163
155 struct dc_crtc_timing_adjust *adjust; 164 struct dc_crtc_timing_adjust *adjust;
156 struct dc_info_packet *vrr_infopacket; 165 struct dc_info_packet *vrr_infopacket;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 56e7f3dab15a..da2009a108cf 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -201,6 +201,7 @@ union display_content_support {
201struct dc_panel_patch { 201struct dc_panel_patch {
202 unsigned int dppowerup_delay; 202 unsigned int dppowerup_delay;
203 unsigned int extra_t12_ms; 203 unsigned int extra_t12_ms;
204 unsigned int extra_delay_backlight_off;
204}; 205};
205 206
206struct dc_edid_caps { 207struct dc_edid_caps {
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
index 2a342eae80fd..01e56f1a9f34 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
@@ -314,8 +314,8 @@ static bool dce_abm_immediate_disable(struct abm *abm)
314 314
315 /* setDMCUParam_ABMLevel */ 315 /* setDMCUParam_ABMLevel */
316 REG_UPDATE_2(MASTER_COMM_CMD_REG, 316 REG_UPDATE_2(MASTER_COMM_CMD_REG,
317 MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_LEVEL_SET, 317 MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_PIPE_SET,
318 MASTER_COMM_CMD_REG_BYTE2, MCP_DISABLE_ABM_IMMEDIATELY); 318 MASTER_COMM_CMD_REG_BYTE1, MCP_DISABLE_ABM_IMMEDIATELY);
319 319
320 /* notifyDMCUMsg */ 320 /* notifyDMCUMsg */
321 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); 321 REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
index adbb22224e1a..4febf4ef7240 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
@@ -516,7 +516,7 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
516 } 516 }
517 } 517 }
518 518
519 msleep(1); 519 udelay(1000);
520 } 520 }
521 return false; 521 return false;
522} 522}
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
index c67e90e5c339..71d5777de961 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
@@ -977,6 +977,28 @@ static bool dce110_clock_source_power_down(
977 return bp_result == BP_RESULT_OK; 977 return bp_result == BP_RESULT_OK;
978} 978}
979 979
980static bool get_pixel_clk_frequency_100hz(
981 struct clock_source *clock_source,
982 unsigned int inst,
983 unsigned int *pixel_clk_khz)
984{
985 struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source);
986 unsigned int clock_hz = 0;
987
988 if (clock_source->id == CLOCK_SOURCE_ID_DP_DTO) {
989 clock_hz = REG_READ(PHASE[inst]);
990
991 /* NOTE: There is agreement with VBIOS here that MODULO is
992 * programmed equal to DPREFCLK, in which case PHASE will be
993 * equivalent to pixel clock.
994 */
995 *pixel_clk_khz = clock_hz / 100;
996 return true;
997 }
998
999 return false;
1000}
1001
980/*****************************************/ 1002/*****************************************/
981/* Constructor */ 1003/* Constructor */
982/*****************************************/ 1004/*****************************************/
@@ -984,12 +1006,14 @@ static bool dce110_clock_source_power_down(
984static const struct clock_source_funcs dce112_clk_src_funcs = { 1006static const struct clock_source_funcs dce112_clk_src_funcs = {
985 .cs_power_down = dce110_clock_source_power_down, 1007 .cs_power_down = dce110_clock_source_power_down,
986 .program_pix_clk = dce112_program_pix_clk, 1008 .program_pix_clk = dce112_program_pix_clk,
987 .get_pix_clk_dividers = dce112_get_pix_clk_dividers 1009 .get_pix_clk_dividers = dce112_get_pix_clk_dividers,
1010 .get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz
988}; 1011};
989static const struct clock_source_funcs dce110_clk_src_funcs = { 1012static const struct clock_source_funcs dce110_clk_src_funcs = {
990 .cs_power_down = dce110_clock_source_power_down, 1013 .cs_power_down = dce110_clock_source_power_down,
991 .program_pix_clk = dce110_program_pix_clk, 1014 .program_pix_clk = dce110_program_pix_clk,
992 .get_pix_clk_dividers = dce110_get_pix_clk_dividers 1015 .get_pix_clk_dividers = dce110_get_pix_clk_dividers,
1016 .get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz
993}; 1017};
994 1018
995 1019
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index db0ef41eb91c..e1b285ea01ac 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -1032,8 +1032,7 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
1032 struct dc_link *link = stream->link; 1032 struct dc_link *link = stream->link;
1033 1033
1034 /* only 3 items below are used by unblank */ 1034 /* only 3 items below are used by unblank */
1035 params.pixel_clk_khz = 1035 params.pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10;
1036 pipe_ctx->stream->timing.pix_clk_100hz / 10;
1037 params.link_settings.link_rate = link_settings->link_rate; 1036 params.link_settings.link_rate = link_settings->link_rate;
1038 1037
1039 if (dc_is_dp_signal(pipe_ctx->stream->signal)) 1038 if (dc_is_dp_signal(pipe_ctx->stream->signal))
@@ -1043,6 +1042,7 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
1043 link->dc->hwss.edp_backlight_control(link, true); 1042 link->dc->hwss.edp_backlight_control(link, true);
1044 } 1043 }
1045} 1044}
1045
1046void dce110_blank_stream(struct pipe_ctx *pipe_ctx) 1046void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
1047{ 1047{
1048 struct dc_stream_state *stream = pipe_ctx->stream; 1048 struct dc_stream_state *stream = pipe_ctx->stream;
@@ -1250,8 +1250,6 @@ static enum dc_status dce110_enable_stream_timing(
1250 struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx. 1250 struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx.
1251 pipe_ctx[pipe_ctx->pipe_idx]; 1251 pipe_ctx[pipe_ctx->pipe_idx];
1252 struct tg_color black_color = {0}; 1252 struct tg_color black_color = {0};
1253 struct drr_params params = {0};
1254 unsigned int event_triggers = 0;
1255 1253
1256 if (!pipe_ctx_old->stream) { 1254 if (!pipe_ctx_old->stream) {
1257 1255
@@ -1280,20 +1278,6 @@ static enum dc_status dce110_enable_stream_timing(
1280 pipe_ctx->stream_res.tg, 1278 pipe_ctx->stream_res.tg,
1281 &stream->timing, 1279 &stream->timing,
1282 true); 1280 true);
1283
1284 params.vertical_total_min = stream->adjust.v_total_min;
1285 params.vertical_total_max = stream->adjust.v_total_max;
1286 if (pipe_ctx->stream_res.tg->funcs->set_drr)
1287 pipe_ctx->stream_res.tg->funcs->set_drr(
1288 pipe_ctx->stream_res.tg, &params);
1289
1290 // DRR should set trigger event to monitor surface update event
1291 if (stream->adjust.v_total_min != 0 &&
1292 stream->adjust.v_total_max != 0)
1293 event_triggers = 0x80;
1294 if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
1295 pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
1296 pipe_ctx->stream_res.tg, event_triggers);
1297 } 1281 }
1298 1282
1299 if (!pipe_ctx_old->stream) { 1283 if (!pipe_ctx_old->stream) {
@@ -1313,6 +1297,8 @@ static enum dc_status apply_single_controller_ctx_to_hw(
1313 struct dc *dc) 1297 struct dc *dc)
1314{ 1298{
1315 struct dc_stream_state *stream = pipe_ctx->stream; 1299 struct dc_stream_state *stream = pipe_ctx->stream;
1300 struct drr_params params = {0};
1301 unsigned int event_triggers = 0;
1316 1302
1317 if (pipe_ctx->stream_res.audio != NULL) { 1303 if (pipe_ctx->stream_res.audio != NULL) {
1318 struct audio_output audio_output; 1304 struct audio_output audio_output;
@@ -1339,7 +1325,27 @@ static enum dc_status apply_single_controller_ctx_to_hw(
1339 } 1325 }
1340 1326
1341 /* */ 1327 /* */
1342 dc->hwss.enable_stream_timing(pipe_ctx, context, dc); 1328 /* Do not touch stream timing on seamless boot optimization. */
1329 if (!pipe_ctx->stream->apply_seamless_boot_optimization)
1330 dc->hwss.enable_stream_timing(pipe_ctx, context, dc);
1331
1332 if (pipe_ctx->stream_res.tg->funcs->program_vupdate_interrupt)
1333 pipe_ctx->stream_res.tg->funcs->program_vupdate_interrupt(
1334 pipe_ctx->stream_res.tg,
1335 &stream->timing);
1336
1337 params.vertical_total_min = stream->adjust.v_total_min;
1338 params.vertical_total_max = stream->adjust.v_total_max;
1339 if (pipe_ctx->stream_res.tg->funcs->set_drr)
1340 pipe_ctx->stream_res.tg->funcs->set_drr(
1341 pipe_ctx->stream_res.tg, &params);
1342
1343 // DRR should set trigger event to monitor surface update event
1344 if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
1345 event_triggers = 0x80;
1346 if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
1347 pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
1348 pipe_ctx->stream_res.tg, event_triggers);
1343 1349
1344 if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) 1350 if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL)
1345 pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg( 1351 pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg(
@@ -2269,6 +2275,11 @@ static void dce110_enable_per_frame_crtc_position_reset(
2269 2275
2270} 2276}
2271 2277
2278static void init_pipes(struct dc *dc, struct dc_state *context)
2279{
2280 // Do nothing
2281}
2282
2272static void init_hw(struct dc *dc) 2283static void init_hw(struct dc *dc)
2273{ 2284{
2274 int i; 2285 int i;
@@ -2535,7 +2546,7 @@ static void dce110_apply_ctx_for_surface(
2535 } 2546 }
2536 2547
2537 if (dc->fbc_compressor) 2548 if (dc->fbc_compressor)
2538 enable_fbc(dc, dc->current_state); 2549 enable_fbc(dc, context);
2539} 2550}
2540 2551
2541static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx) 2552static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx)
@@ -2636,6 +2647,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
2636 .program_gamut_remap = program_gamut_remap, 2647 .program_gamut_remap = program_gamut_remap,
2637 .program_output_csc = program_output_csc, 2648 .program_output_csc = program_output_csc,
2638 .init_hw = init_hw, 2649 .init_hw = init_hw,
2650 .init_pipes = init_pipes,
2639 .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 2651 .apply_ctx_to_hw = dce110_apply_ctx_to_hw,
2640 .apply_ctx_for_surface = dce110_apply_ctx_for_surface, 2652 .apply_ctx_for_surface = dce110_apply_ctx_for_surface,
2641 .update_plane_addr = update_plane_addr, 2653 .update_plane_addr = update_plane_addr,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
index 5a4614c371bc..e161ad836812 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
@@ -88,11 +88,18 @@ void hubbub1_wm_read_state(struct hubbub *hubbub,
88 s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D); 88 s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D);
89} 89}
90 90
91void hubbub1_disable_allow_self_refresh(struct hubbub *hubbub) 91void hubbub1_allow_self_refresh_control(struct hubbub *hubbub, bool allow)
92{ 92{
93 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); 93 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
94 REG_UPDATE(DCHUBBUB_ARB_DRAM_STATE_CNTL, 94
95 DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, 0); 95 /*
96 * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 1 means do not allow stutter
97 * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0 means allow stutter
98 */
99
100 REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
101 DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0,
102 DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, !allow);
96} 103}
97 104
98bool hububu1_is_allow_self_refresh_enabled(struct hubbub *hubbub) 105bool hububu1_is_allow_self_refresh_enabled(struct hubbub *hubbub)
@@ -262,8 +269,6 @@ void hubbub1_program_watermarks(
262 bool safe_to_lower) 269 bool safe_to_lower)
263{ 270{
264 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); 271 struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
265
266 uint32_t force_en = hubbub1->base.ctx->dc->debug.disable_stutter ? 1 : 0;
267 /* 272 /*
268 * Need to clamp to max of the register values (i.e. no wrap) 273 * Need to clamp to max of the register values (i.e. no wrap)
269 * for dcn1, all wm registers are 21-bit wide 274 * for dcn1, all wm registers are 21-bit wide
@@ -537,9 +542,7 @@ void hubbub1_program_watermarks(
537 REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, 542 REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
538 DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68); 543 DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68);
539 544
540 REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, 545 hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
541 DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0,
542 DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, force_en);
543 546
544#if 0 547#if 0
545 REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 548 REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
index c681e1cc9290..9cd4a5194154 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
@@ -204,7 +204,7 @@ void hubbub1_program_watermarks(
204 unsigned int refclk_mhz, 204 unsigned int refclk_mhz,
205 bool safe_to_lower); 205 bool safe_to_lower);
206 206
207void hubbub1_disable_allow_self_refresh(struct hubbub *hubbub); 207void hubbub1_allow_self_refresh_control(struct hubbub *hubbub, bool allow);
208 208
209bool hububu1_is_allow_self_refresh_enabled(struct hubbub *hubub); 209bool hububu1_is_allow_self_refresh_enabled(struct hubbub *hubub);
210 210
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index 0ba68d41b9c3..683829466a44 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -1150,9 +1150,28 @@ void hubp1_cursor_set_position(
1150 REG_UPDATE(CURSOR_CONTROL, 1150 REG_UPDATE(CURSOR_CONTROL,
1151 CURSOR_ENABLE, cur_en); 1151 CURSOR_ENABLE, cur_en);
1152 1152
1153 REG_SET_2(CURSOR_POSITION, 0, 1153 //account for cases where we see negative offset relative to overlay plane
1154 CURSOR_X_POSITION, pos->x, 1154 if (src_x_offset < 0 && src_y_offset < 0) {
1155 REG_SET_2(CURSOR_POSITION, 0,
1156 CURSOR_X_POSITION, 0,
1157 CURSOR_Y_POSITION, 0);
1158 x_hotspot -= src_x_offset;
1159 y_hotspot -= src_y_offset;
1160 } else if (src_x_offset < 0) {
1161 REG_SET_2(CURSOR_POSITION, 0,
1162 CURSOR_X_POSITION, 0,
1155 CURSOR_Y_POSITION, pos->y); 1163 CURSOR_Y_POSITION, pos->y);
1164 x_hotspot -= src_x_offset;
1165 } else if (src_y_offset < 0) {
1166 REG_SET_2(CURSOR_POSITION, 0,
1167 CURSOR_X_POSITION, pos->x,
1168 CURSOR_Y_POSITION, 0);
1169 y_hotspot -= src_y_offset;
1170 } else {
1171 REG_SET_2(CURSOR_POSITION, 0,
1172 CURSOR_X_POSITION, pos->x,
1173 CURSOR_Y_POSITION, pos->y);
1174 }
1156 1175
1157 REG_SET_2(CURSOR_HOT_SPOT, 0, 1176 REG_SET_2(CURSOR_HOT_SPOT, 0,
1158 CURSOR_HOT_SPOT_X, x_hotspot, 1177 CURSOR_HOT_SPOT_X, x_hotspot,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 9cde24dbdac8..117d9d8227f7 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -636,8 +636,6 @@ static enum dc_status dcn10_enable_stream_timing(
636 struct dc_stream_state *stream = pipe_ctx->stream; 636 struct dc_stream_state *stream = pipe_ctx->stream;
637 enum dc_color_space color_space; 637 enum dc_color_space color_space;
638 struct tg_color black_color = {0}; 638 struct tg_color black_color = {0};
639 struct drr_params params = {0};
640 unsigned int event_triggers = 0;
641 639
642 /* by upper caller loop, pipe0 is parent pipe and be called first. 640 /* by upper caller loop, pipe0 is parent pipe and be called first.
643 * back end is set up by for pipe0. Other children pipe share back end 641 * back end is set up by for pipe0. Other children pipe share back end
@@ -705,19 +703,6 @@ static enum dc_status dcn10_enable_stream_timing(
705 return DC_ERROR_UNEXPECTED; 703 return DC_ERROR_UNEXPECTED;
706 } 704 }
707 705
708 params.vertical_total_min = stream->adjust.v_total_min;
709 params.vertical_total_max = stream->adjust.v_total_max;
710 if (pipe_ctx->stream_res.tg->funcs->set_drr)
711 pipe_ctx->stream_res.tg->funcs->set_drr(
712 pipe_ctx->stream_res.tg, &params);
713
714 // DRR should set trigger event to monitor surface update event
715 if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
716 event_triggers = 0x80;
717 if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
718 pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
719 pipe_ctx->stream_res.tg, event_triggers);
720
721 /* TODO program crtc source select for non-virtual signal*/ 706 /* TODO program crtc source select for non-virtual signal*/
722 /* TODO program FMT */ 707 /* TODO program FMT */
723 /* TODO setup link_enc */ 708 /* TODO setup link_enc */
@@ -971,92 +956,34 @@ static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
971 pipe_ctx->pipe_idx); 956 pipe_ctx->pipe_idx);
972} 957}
973 958
974static void dcn10_init_hw(struct dc *dc) 959static void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
975{ 960{
976 int i; 961 int i;
977 struct abm *abm = dc->res_pool->abm;
978 struct dmcu *dmcu = dc->res_pool->dmcu;
979 struct dce_hwseq *hws = dc->hwseq;
980 struct dc_bios *dcb = dc->ctx->dc_bios;
981 struct dc_state *context = dc->current_state;
982
983 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
984 REG_WRITE(REFCLK_CNTL, 0);
985 REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
986 REG_WRITE(DIO_MEM_PWR_CTRL, 0);
987
988 if (!dc->debug.disable_clock_gate) {
989 /* enable all DCN clock gating */
990 REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
991
992 REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
993
994 REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
995 }
996
997 enable_power_gating_plane(dc->hwseq, true);
998 } else {
999
1000 if (!dcb->funcs->is_accelerated_mode(dcb)) {
1001 bool allow_self_fresh_force_enable =
1002 hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub);
1003
1004 bios_golden_init(dc);
1005
1006 /* WA for making DF sleep when idle after resume from S0i3.
1007 * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE is set to 1 by
1008 * command table, if DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0
1009 * before calling command table and it changed to 1 after,
1010 * it should be set back to 0.
1011 */
1012 if (allow_self_fresh_force_enable == false &&
1013 hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub))
1014 hubbub1_disable_allow_self_refresh(dc->res_pool->hubbub);
1015
1016 disable_vga(dc->hwseq);
1017 }
1018
1019 for (i = 0; i < dc->link_count; i++) {
1020 /* Power up AND update implementation according to the
1021 * required signal (which may be different from the
1022 * default signal on connector).
1023 */
1024 struct dc_link *link = dc->links[i];
1025
1026 if (link->link_enc->connector.id == CONNECTOR_ID_EDP)
1027 dc->hwss.edp_power_control(link, true);
1028
1029 link->link_enc->funcs->hw_init(link->link_enc);
1030 }
1031 }
1032 962
1033 for (i = 0; i < dc->res_pool->pipe_count; i++) { 963 for (i = 0; i < dc->res_pool->pipe_count; i++) {
1034 struct timing_generator *tg = dc->res_pool->timing_generators[i]; 964 struct timing_generator *tg = dc->res_pool->timing_generators[i];
1035 965
1036 if (tg->funcs->is_tg_enabled(tg)) 966 if (tg->funcs->is_tg_enabled(tg))
1037 tg->funcs->lock(tg); 967 tg->funcs->lock(tg);
1038 }
1039
1040 /* Blank controller using driver code instead of
1041 * command table.
1042 */
1043 for (i = 0; i < dc->res_pool->pipe_count; i++) {
1044 struct timing_generator *tg = dc->res_pool->timing_generators[i];
1045 968
969 /* Blank controller using driver code instead of
970 * command table.
971 */
1046 if (tg->funcs->is_tg_enabled(tg)) { 972 if (tg->funcs->is_tg_enabled(tg)) {
1047 tg->funcs->set_blank(tg, true); 973 tg->funcs->set_blank(tg, true);
1048 hwss_wait_for_blank_complete(tg); 974 hwss_wait_for_blank_complete(tg);
1049 } 975 }
1050 } 976 }
1051 977
1052 /* Reset all MPCC muxes */
1053 dc->res_pool->mpc->funcs->mpc_init(dc->res_pool->mpc); 978 dc->res_pool->mpc->funcs->mpc_init(dc->res_pool->mpc);
1054 979
1055 for (i = 0; i < dc->res_pool->timing_generator_count; i++) { 980 for (i = 0; i < dc->res_pool->pipe_count; i++) {
1056 struct timing_generator *tg = dc->res_pool->timing_generators[i]; 981 struct timing_generator *tg = dc->res_pool->timing_generators[i];
1057 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
1058 struct hubp *hubp = dc->res_pool->hubps[i]; 982 struct hubp *hubp = dc->res_pool->hubps[i];
1059 struct dpp *dpp = dc->res_pool->dpps[i]; 983 struct dpp *dpp = dc->res_pool->dpps[i];
984 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
985
986 dpp->funcs->dpp_reset(dpp);
1060 987
1061 pipe_ctx->stream_res.tg = tg; 988 pipe_ctx->stream_res.tg = tg;
1062 pipe_ctx->pipe_idx = i; 989 pipe_ctx->pipe_idx = i;
@@ -1074,18 +1001,9 @@ static void dcn10_init_hw(struct dc *dc)
1074 pipe_ctx->stream_res.opp = dc->res_pool->opps[i]; 1001 pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
1075 1002
1076 hwss1_plane_atomic_disconnect(dc, pipe_ctx); 1003 hwss1_plane_atomic_disconnect(dc, pipe_ctx);
1077 }
1078
1079 for (i = 0; i < dc->res_pool->pipe_count; i++) {
1080 struct timing_generator *tg = dc->res_pool->timing_generators[i];
1081 1004
1082 if (tg->funcs->is_tg_enabled(tg)) 1005 if (tg->funcs->is_tg_enabled(tg))
1083 tg->funcs->unlock(tg); 1006 tg->funcs->unlock(tg);
1084 }
1085
1086 for (i = 0; i < dc->res_pool->pipe_count; i++) {
1087 struct timing_generator *tg = dc->res_pool->timing_generators[i];
1088 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
1089 1007
1090 dcn10_disable_plane(dc, pipe_ctx); 1008 dcn10_disable_plane(dc, pipe_ctx);
1091 1009
@@ -1094,10 +1012,73 @@ static void dcn10_init_hw(struct dc *dc)
1094 1012
1095 tg->funcs->tg_init(tg); 1013 tg->funcs->tg_init(tg);
1096 } 1014 }
1015}
1016
1017static void dcn10_init_hw(struct dc *dc)
1018{
1019 int i;
1020 struct abm *abm = dc->res_pool->abm;
1021 struct dmcu *dmcu = dc->res_pool->dmcu;
1022 struct dce_hwseq *hws = dc->hwseq;
1023 struct dc_bios *dcb = dc->ctx->dc_bios;
1024
1025 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
1026 REG_WRITE(REFCLK_CNTL, 0);
1027 REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
1028 REG_WRITE(DIO_MEM_PWR_CTRL, 0);
1029
1030 if (!dc->debug.disable_clock_gate) {
1031 /* enable all DCN clock gating */
1032 REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
1033
1034 REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
1035
1036 REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
1037 }
1038
1039 enable_power_gating_plane(dc->hwseq, true);
1097 1040
1098 /* end of FPGA. Below if real ASIC */ 1041 /* end of FPGA. Below if real ASIC */
1099 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
1100 return; 1042 return;
1043 }
1044
1045 if (!dcb->funcs->is_accelerated_mode(dcb)) {
1046 bool allow_self_fresh_force_enable =
1047 hububu1_is_allow_self_refresh_enabled(
1048 dc->res_pool->hubbub);
1049
1050 bios_golden_init(dc);
1051
1052 /* WA for making DF sleep when idle after resume from S0i3.
1053 * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE is set to 1 by
1054 * command table, if DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0
1055 * before calling command table and it changed to 1 after,
1056 * it should be set back to 0.
1057 */
1058 if (allow_self_fresh_force_enable == false &&
1059 hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub))
1060 hubbub1_allow_self_refresh_control(dc->res_pool->hubbub, true);
1061
1062 disable_vga(dc->hwseq);
1063 }
1064
1065 for (i = 0; i < dc->link_count; i++) {
1066 /* Power up AND update implementation according to the
1067 * required signal (which may be different from the
1068 * default signal on connector).
1069 */
1070 struct dc_link *link = dc->links[i];
1071
1072 if (link->link_enc->connector.id == CONNECTOR_ID_EDP)
1073 dc->hwss.edp_power_control(link, true);
1074
1075 link->link_enc->funcs->hw_init(link->link_enc);
1076
1077 /* Check for enabled DIG to identify enabled display */
1078 if (link->link_enc->funcs->is_dig_enabled &&
1079 link->link_enc->funcs->is_dig_enabled(link->link_enc))
1080 link->link_status.link_active = true;
1081 }
1101 1082
1102 for (i = 0; i < dc->res_pool->audio_count; i++) { 1083 for (i = 0; i < dc->res_pool->audio_count; i++) {
1103 struct audio *audio = dc->res_pool->audios[i]; 1084 struct audio *audio = dc->res_pool->audios[i];
@@ -1128,6 +1109,9 @@ static void dcn10_init_hw(struct dc *dc)
1128 enable_power_gating_plane(dc->hwseq, true); 1109 enable_power_gating_plane(dc->hwseq, true);
1129 1110
1130 memset(&dc->res_pool->clk_mgr->clks, 0, sizeof(dc->res_pool->clk_mgr->clks)); 1111 memset(&dc->res_pool->clk_mgr->clks, 0, sizeof(dc->res_pool->clk_mgr->clks));
1112
1113 if (dc->hwss.init_pipes)
1114 dc->hwss.init_pipes(dc, dc->current_state);
1131} 1115}
1132 1116
1133static void reset_hw_ctx_wrap( 1117static void reset_hw_ctx_wrap(
@@ -2334,9 +2318,10 @@ static void dcn10_apply_ctx_for_surface(
2334 } 2318 }
2335 } 2319 }
2336 2320
2337 if (!pipe_ctx->plane_state && 2321 if ((!pipe_ctx->plane_state ||
2338 old_pipe_ctx->plane_state && 2322 pipe_ctx->stream_res.tg != old_pipe_ctx->stream_res.tg) &&
2339 old_pipe_ctx->stream_res.tg == tg) { 2323 old_pipe_ctx->plane_state &&
2324 old_pipe_ctx->stream_res.tg == tg) {
2340 2325
2341 dc->hwss.plane_atomic_disconnect(dc, old_pipe_ctx); 2326 dc->hwss.plane_atomic_disconnect(dc, old_pipe_ctx);
2342 removed_pipe[i] = true; 2327 removed_pipe[i] = true;
@@ -2383,6 +2368,22 @@ static void dcn10_apply_ctx_for_surface(
2383 hubbub1_wm_change_req_wa(dc->res_pool->hubbub); 2368 hubbub1_wm_change_req_wa(dc->res_pool->hubbub);
2384} 2369}
2385 2370
2371static void dcn10_stereo_hw_frame_pack_wa(struct dc *dc, struct dc_state *context)
2372{
2373 uint8_t i;
2374
2375 for (i = 0; i < context->stream_count; i++) {
2376 if (context->streams[i]->timing.timing_3d_format
2377 == TIMING_3D_FORMAT_HW_FRAME_PACKING) {
2378 /*
2379 * Disable stutter
2380 */
2381 hubbub1_allow_self_refresh_control(dc->res_pool->hubbub, false);
2382 break;
2383 }
2384 }
2385}
2386
2386static void dcn10_prepare_bandwidth( 2387static void dcn10_prepare_bandwidth(
2387 struct dc *dc, 2388 struct dc *dc,
2388 struct dc_state *context) 2389 struct dc_state *context)
@@ -2404,6 +2405,7 @@ static void dcn10_prepare_bandwidth(
2404 &context->bw.dcn.watermarks, 2405 &context->bw.dcn.watermarks,
2405 dc->res_pool->ref_clock_inKhz / 1000, 2406 dc->res_pool->ref_clock_inKhz / 1000,
2406 true); 2407 true);
2408 dcn10_stereo_hw_frame_pack_wa(dc, context);
2407 2409
2408 if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) 2410 if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE)
2409 dcn_bw_notify_pplib_of_wm_ranges(dc); 2411 dcn_bw_notify_pplib_of_wm_ranges(dc);
@@ -2433,6 +2435,7 @@ static void dcn10_optimize_bandwidth(
2433 &context->bw.dcn.watermarks, 2435 &context->bw.dcn.watermarks,
2434 dc->res_pool->ref_clock_inKhz / 1000, 2436 dc->res_pool->ref_clock_inKhz / 1000,
2435 true); 2437 true);
2438 dcn10_stereo_hw_frame_pack_wa(dc, context);
2436 2439
2437 if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) 2440 if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE)
2438 dcn_bw_notify_pplib_of_wm_ranges(dc); 2441 dcn_bw_notify_pplib_of_wm_ranges(dc);
@@ -2709,6 +2712,7 @@ static void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx)
2709static const struct hw_sequencer_funcs dcn10_funcs = { 2712static const struct hw_sequencer_funcs dcn10_funcs = {
2710 .program_gamut_remap = program_gamut_remap, 2713 .program_gamut_remap = program_gamut_remap,
2711 .init_hw = dcn10_init_hw, 2714 .init_hw = dcn10_init_hw,
2715 .init_pipes = dcn10_init_pipes,
2712 .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 2716 .apply_ctx_to_hw = dce110_apply_ctx_to_hw,
2713 .apply_ctx_for_surface = dcn10_apply_ctx_for_surface, 2717 .apply_ctx_for_surface = dcn10_apply_ctx_for_surface,
2714 .update_plane_addr = dcn10_update_plane_addr, 2718 .update_plane_addr = dcn10_update_plane_addr,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
index 771449f8984f..a9db372688ff 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
@@ -85,6 +85,7 @@ static const struct link_encoder_funcs dcn10_lnk_enc_funcs = {
85 .enable_hpd = dcn10_link_encoder_enable_hpd, 85 .enable_hpd = dcn10_link_encoder_enable_hpd,
86 .disable_hpd = dcn10_link_encoder_disable_hpd, 86 .disable_hpd = dcn10_link_encoder_disable_hpd,
87 .is_dig_enabled = dcn10_is_dig_enabled, 87 .is_dig_enabled = dcn10_is_dig_enabled,
88 .get_dig_frontend = dcn10_get_dig_frontend,
88 .destroy = dcn10_link_encoder_destroy 89 .destroy = dcn10_link_encoder_destroy
89}; 90};
90 91
@@ -495,6 +496,15 @@ bool dcn10_is_dig_enabled(struct link_encoder *enc)
495 return value; 496 return value;
496} 497}
497 498
499unsigned int dcn10_get_dig_frontend(struct link_encoder *enc)
500{
501 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
502 uint32_t value;
503
504 REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &value);
505 return value;
506}
507
498static void link_encoder_disable(struct dcn10_link_encoder *enc10) 508static void link_encoder_disable(struct dcn10_link_encoder *enc10)
499{ 509{
500 /* reset training pattern */ 510 /* reset training pattern */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
index 670b46e887ed..b74b80a247ec 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
@@ -336,6 +336,8 @@ void dcn10_psr_program_secondary_packet(struct link_encoder *enc,
336 336
337bool dcn10_is_dig_enabled(struct link_encoder *enc); 337bool dcn10_is_dig_enabled(struct link_encoder *enc);
338 338
339unsigned int dcn10_get_dig_frontend(struct link_encoder *enc);
340
339void dcn10_aux_initialize(struct dcn10_link_encoder *enc10); 341void dcn10_aux_initialize(struct dcn10_link_encoder *enc10);
340 342
341#endif /* __DC_LINK_ENCODER__DCN10_H__ */ 343#endif /* __DC_LINK_ENCODER__DCN10_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
index 1d4f9b48ed7d..2f78a84f0dcb 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
@@ -92,28 +92,136 @@ static void optc1_disable_stereo(struct timing_generator *optc)
92 OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0); 92 OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0);
93} 93}
94 94
95static uint32_t get_start_vline(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing)
96{
97 struct dc_crtc_timing patched_crtc_timing;
98 int vesa_sync_start;
99 int asic_blank_end;
100 int interlace_factor;
101 int vertical_line_start;
102
103 patched_crtc_timing = *dc_crtc_timing;
104 optc1_apply_front_porch_workaround(optc, &patched_crtc_timing);
105
106 vesa_sync_start = patched_crtc_timing.h_addressable +
107 patched_crtc_timing.h_border_right +
108 patched_crtc_timing.h_front_porch;
109
110 asic_blank_end = patched_crtc_timing.h_total -
111 vesa_sync_start -
112 patched_crtc_timing.h_border_left;
113
114 interlace_factor = patched_crtc_timing.flags.INTERLACE ? 2 : 1;
115
116 vesa_sync_start = patched_crtc_timing.v_addressable +
117 patched_crtc_timing.v_border_bottom +
118 patched_crtc_timing.v_front_porch;
119
120 asic_blank_end = (patched_crtc_timing.v_total -
121 vesa_sync_start -
122 patched_crtc_timing.v_border_top)
123 * interlace_factor;
124
125 vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1;
126 if (vertical_line_start < 0) {
127 ASSERT(0);
128 vertical_line_start = 0;
129 }
130
131 return vertical_line_start;
132}
133
134static void calc_vline_position(
135 struct timing_generator *optc,
136 const struct dc_crtc_timing *dc_crtc_timing,
137 unsigned long long vsync_delta,
138 uint32_t *start_line,
139 uint32_t *end_line)
140{
141 unsigned long long req_delta_tens_of_usec = div64_u64((vsync_delta + 9999), 10000);
142 unsigned long long pix_clk_hundreds_khz = div64_u64((dc_crtc_timing->pix_clk_100hz + 999), 1000);
143 uint32_t req_delta_lines = (uint32_t) div64_u64(
144 (req_delta_tens_of_usec * pix_clk_hundreds_khz + dc_crtc_timing->h_total - 1),
145 dc_crtc_timing->h_total);
146
147 uint32_t vsync_line = get_start_vline(optc, dc_crtc_timing);
148
149 if (req_delta_lines != 0)
150 req_delta_lines--;
151
152 if (req_delta_lines > vsync_line)
153 *start_line = dc_crtc_timing->v_total - (req_delta_lines - vsync_line) - 1;
154 else
155 *start_line = vsync_line - req_delta_lines;
156
157 *end_line = *start_line + 2;
158
159 if (*end_line >= dc_crtc_timing->v_total)
160 *end_line = 2;
161}
162
95void optc1_program_vline_interrupt( 163void optc1_program_vline_interrupt(
96 struct timing_generator *optc, 164 struct timing_generator *optc,
165 const struct dc_crtc_timing *dc_crtc_timing,
97 enum vline_select vline, 166 enum vline_select vline,
98 struct vline_config vline_config) 167 const union vline_config *vline_config)
99{ 168{
100 struct optc *optc1 = DCN10TG_FROM_TG(optc); 169 struct optc *optc1 = DCN10TG_FROM_TG(optc);
170 uint32_t start_line = 0;
171 uint32_t end_line = 0;
101 172
102 switch (vline) { 173 switch (vline) {
103 case VLINE0: 174 case VLINE0:
175 calc_vline_position(optc, dc_crtc_timing, vline_config->delta_in_ns, &start_line, &end_line);
104 REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0, 176 REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0,
105 OTG_VERTICAL_INTERRUPT0_LINE_START, vline_config.start_line, 177 OTG_VERTICAL_INTERRUPT0_LINE_START, start_line,
106 OTG_VERTICAL_INTERRUPT0_LINE_END, vline_config.end_line); 178 OTG_VERTICAL_INTERRUPT0_LINE_END, end_line);
107 break; 179 break;
108 case VLINE1: 180 case VLINE1:
109 REG_SET(OTG_VERTICAL_INTERRUPT1_POSITION, 0, 181 REG_SET(OTG_VERTICAL_INTERRUPT1_POSITION, 0,
110 OTG_VERTICAL_INTERRUPT1_LINE_START, vline_config.start_line); 182 OTG_VERTICAL_INTERRUPT1_LINE_START, vline_config->line_number);
111 break; 183 break;
112 default: 184 default:
113 break; 185 break;
114 } 186 }
115} 187}
116 188
189void optc1_program_vupdate_interrupt(
190 struct timing_generator *optc,
191 const struct dc_crtc_timing *dc_crtc_timing)
192{
193 struct optc *optc1 = DCN10TG_FROM_TG(optc);
194 int32_t vertical_line_start;
195 uint32_t asic_blank_end;
196 uint32_t vesa_sync_start;
197 struct dc_crtc_timing patched_crtc_timing;
198
199 patched_crtc_timing = *dc_crtc_timing;
200 optc1_apply_front_porch_workaround(optc, &patched_crtc_timing);
201
202 /* asic_h_blank_end = HsyncWidth + HbackPorch =
203 * vesa. usHorizontalTotal - vesa. usHorizontalSyncStart -
204 * vesa.h_left_border
205 */
206 vesa_sync_start = patched_crtc_timing.h_addressable +
207 patched_crtc_timing.h_border_right +
208 patched_crtc_timing.h_front_porch;
209
210 asic_blank_end = patched_crtc_timing.h_total -
211 vesa_sync_start -
212 patched_crtc_timing.h_border_left;
213
214 /* Use OTG_VERTICAL_INTERRUPT2 replace VUPDATE interrupt,
215 * program the reg for interrupt postition.
216 */
217 vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1;
218 if (vertical_line_start < 0)
219 vertical_line_start = 0;
220
221 REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0,
222 OTG_VERTICAL_INTERRUPT2_LINE_START, vertical_line_start);
223}
224
117/** 225/**
118 * program_timing_generator used by mode timing set 226 * program_timing_generator used by mode timing set
119 * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition. 227 * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition.
@@ -216,22 +324,14 @@ void optc1_program_timing(
216 patched_crtc_timing.v_addressable + 324 patched_crtc_timing.v_addressable +
217 patched_crtc_timing.v_border_bottom); 325 patched_crtc_timing.v_border_bottom);
218 326
219 REG_UPDATE_2(OTG_V_BLANK_START_END,
220 OTG_V_BLANK_START, asic_blank_start,
221 OTG_V_BLANK_END, asic_blank_end);
222
223 /* Use OTG_VERTICAL_INTERRUPT2 replace VUPDATE interrupt,
224 * program the reg for interrupt postition.
225 */
226 vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1; 327 vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1;
227 v_fp2 = 0; 328 v_fp2 = 0;
228 if (vertical_line_start < 0) 329 if (vertical_line_start < 0)
229 v_fp2 = -vertical_line_start; 330 v_fp2 = -vertical_line_start;
230 if (vertical_line_start < 0)
231 vertical_line_start = 0;
232 331
233 REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0, 332 REG_UPDATE_2(OTG_V_BLANK_START_END,
234 OTG_VERTICAL_INTERRUPT2_LINE_START, vertical_line_start); 333 OTG_V_BLANK_START, asic_blank_start,
334 OTG_V_BLANK_END, asic_blank_end);
235 335
236 /* v_sync polarity */ 336 /* v_sync polarity */
237 v_sync_polarity = patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ? 337 v_sync_polarity = patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ?
@@ -290,7 +390,7 @@ void optc1_program_timing(
290 390
291 h_div_2 = optc1_is_two_pixels_per_containter(&patched_crtc_timing); 391 h_div_2 = optc1_is_two_pixels_per_containter(&patched_crtc_timing);
292 REG_UPDATE(OTG_H_TIMING_CNTL, 392 REG_UPDATE(OTG_H_TIMING_CNTL,
293 OTG_H_TIMING_DIV_BY2, h_div_2); 393 OTG_H_TIMING_DIV_BY2, h_div_2 || optc1->comb_opp_id != 0xf);
294 394
295} 395}
296 396
@@ -1136,6 +1236,64 @@ bool optc1_is_stereo_left_eye(struct timing_generator *optc)
1136 return ret; 1236 return ret;
1137} 1237}
1138 1238
1239bool optc1_is_matching_timing(struct timing_generator *tg,
1240 const struct dc_crtc_timing *otg_timing)
1241{
1242 struct dc_crtc_timing hw_crtc_timing = {0};
1243 struct dcn_otg_state s = {0};
1244
1245 if (tg == NULL || otg_timing == NULL)
1246 return false;
1247
1248 optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
1249
1250 hw_crtc_timing.h_total = s.h_total + 1;
1251 hw_crtc_timing.h_addressable = s.h_total - ((s.h_total - s.h_blank_start) + s.h_blank_end);
1252 hw_crtc_timing.h_front_porch = s.h_total + 1 - s.h_blank_start;
1253 hw_crtc_timing.h_sync_width = s.h_sync_a_end - s.h_sync_a_start;
1254
1255 hw_crtc_timing.v_total = s.v_total + 1;
1256 hw_crtc_timing.v_addressable = s.v_total - ((s.v_total - s.v_blank_start) + s.v_blank_end);
1257 hw_crtc_timing.v_front_porch = s.v_total + 1 - s.v_blank_start;
1258 hw_crtc_timing.v_sync_width = s.v_sync_a_end - s.v_sync_a_start;
1259
1260 if (otg_timing->h_total != hw_crtc_timing.h_total)
1261 return false;
1262
1263 if (otg_timing->h_border_left != hw_crtc_timing.h_border_left)
1264 return false;
1265
1266 if (otg_timing->h_addressable != hw_crtc_timing.h_addressable)
1267 return false;
1268
1269 if (otg_timing->h_border_right != hw_crtc_timing.h_border_right)
1270 return false;
1271
1272 if (otg_timing->h_front_porch != hw_crtc_timing.h_front_porch)
1273 return false;
1274
1275 if (otg_timing->h_sync_width != hw_crtc_timing.h_sync_width)
1276 return false;
1277
1278 if (otg_timing->v_total != hw_crtc_timing.v_total)
1279 return false;
1280
1281 if (otg_timing->v_border_top != hw_crtc_timing.v_border_top)
1282 return false;
1283
1284 if (otg_timing->v_addressable != hw_crtc_timing.v_addressable)
1285 return false;
1286
1287 if (otg_timing->v_border_bottom != hw_crtc_timing.v_border_bottom)
1288 return false;
1289
1290 if (otg_timing->v_sync_width != hw_crtc_timing.v_sync_width)
1291 return false;
1292
1293 return true;
1294}
1295
1296
1139void optc1_read_otg_state(struct optc *optc1, 1297void optc1_read_otg_state(struct optc *optc1,
1140 struct dcn_otg_state *s) 1298 struct dcn_otg_state *s)
1141{ 1299{
@@ -1323,6 +1481,7 @@ static const struct timing_generator_funcs dcn10_tg_funcs = {
1323 .validate_timing = optc1_validate_timing, 1481 .validate_timing = optc1_validate_timing,
1324 .program_timing = optc1_program_timing, 1482 .program_timing = optc1_program_timing,
1325 .program_vline_interrupt = optc1_program_vline_interrupt, 1483 .program_vline_interrupt = optc1_program_vline_interrupt,
1484 .program_vupdate_interrupt = optc1_program_vupdate_interrupt,
1326 .program_global_sync = optc1_program_global_sync, 1485 .program_global_sync = optc1_program_global_sync,
1327 .enable_crtc = optc1_enable_crtc, 1486 .enable_crtc = optc1_enable_crtc,
1328 .disable_crtc = optc1_disable_crtc, 1487 .disable_crtc = optc1_disable_crtc,
@@ -1332,6 +1491,7 @@ static const struct timing_generator_funcs dcn10_tg_funcs = {
1332 .get_frame_count = optc1_get_vblank_counter, 1491 .get_frame_count = optc1_get_vblank_counter,
1333 .get_scanoutpos = optc1_get_crtc_scanoutpos, 1492 .get_scanoutpos = optc1_get_crtc_scanoutpos,
1334 .get_otg_active_size = optc1_get_otg_active_size, 1493 .get_otg_active_size = optc1_get_otg_active_size,
1494 .is_matching_timing = optc1_is_matching_timing,
1335 .set_early_control = optc1_set_early_control, 1495 .set_early_control = optc1_set_early_control,
1336 /* used by enable_timing_synchronization. Not need for FPGA */ 1496 /* used by enable_timing_synchronization. Not need for FPGA */
1337 .wait_for_state = optc1_wait_for_state, 1497 .wait_for_state = optc1_wait_for_state,
@@ -1371,10 +1531,13 @@ void dcn10_timing_generator_init(struct optc *optc1)
1371 optc1->min_v_blank_interlace = 5; 1531 optc1->min_v_blank_interlace = 5;
1372 optc1->min_h_sync_width = 8; 1532 optc1->min_h_sync_width = 8;
1373 optc1->min_v_sync_width = 1; 1533 optc1->min_v_sync_width = 1;
1534 optc1->comb_opp_id = 0xf;
1374} 1535}
1375 1536
1376bool optc1_is_two_pixels_per_containter(const struct dc_crtc_timing *timing) 1537bool optc1_is_two_pixels_per_containter(const struct dc_crtc_timing *timing)
1377{ 1538{
1378 return timing->pixel_encoding == PIXEL_ENCODING_YCBCR420; 1539 bool two_pix = timing->pixel_encoding == PIXEL_ENCODING_YCBCR420;
1540
1541 return two_pix;
1379} 1542}
1380 1543
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
index 8eb71c0160a7..24452f11c598 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
@@ -435,7 +435,7 @@ struct optc {
435 const struct dcn_optc_shift *tg_shift; 435 const struct dcn_optc_shift *tg_shift;
436 const struct dcn_optc_mask *tg_mask; 436 const struct dcn_optc_mask *tg_mask;
437 437
438 enum controller_id controller_id; 438 int comb_opp_id;
439 439
440 uint32_t max_h_total; 440 uint32_t max_h_total;
441 uint32_t max_v_total; 441 uint32_t max_v_total;
@@ -483,9 +483,11 @@ void optc1_program_timing(
483 const struct dc_crtc_timing *dc_crtc_timing, 483 const struct dc_crtc_timing *dc_crtc_timing,
484 bool use_vbios); 484 bool use_vbios);
485 485
486void optc1_program_vline_interrupt(struct timing_generator *optc, 486void optc1_program_vline_interrupt(
487 struct timing_generator *optc,
488 const struct dc_crtc_timing *dc_crtc_timing,
487 enum vline_select vline, 489 enum vline_select vline,
488 struct vline_config vline_config); 490 const union vline_config *vline_config);
489 491
490void optc1_program_global_sync( 492void optc1_program_global_sync(
491 struct timing_generator *optc); 493 struct timing_generator *optc);
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c
index 1d1efd72b291..cf76ea2d9f5a 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c
@@ -101,6 +101,18 @@ enum gpio_mode dal_gpio_get_mode(
101 return gpio->mode; 101 return gpio->mode;
102} 102}
103 103
104enum gpio_result dal_gpio_lock_pin(
105 struct gpio *gpio)
106{
107 return dal_gpio_service_lock(gpio->service, gpio->id, gpio->en);
108}
109
110enum gpio_result dal_gpio_unlock_pin(
111 struct gpio *gpio)
112{
113 return dal_gpio_service_unlock(gpio->service, gpio->id, gpio->en);
114}
115
104enum gpio_result dal_gpio_change_mode( 116enum gpio_result dal_gpio_change_mode(
105 struct gpio *gpio, 117 struct gpio *gpio,
106 enum gpio_mode mode) 118 enum gpio_mode mode)
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
index dada04296025..3c63a3c04dbb 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
@@ -192,6 +192,34 @@ static void set_pin_free(
192 service->busyness[id][en] = false; 192 service->busyness[id][en] = false;
193} 193}
194 194
195enum gpio_result dal_gpio_service_lock(
196 struct gpio_service *service,
197 enum gpio_id id,
198 uint32_t en)
199{
200 if (!service->busyness[id]) {
201 ASSERT_CRITICAL(false);
202 return GPIO_RESULT_OPEN_FAILED;
203 }
204
205 set_pin_busy(service, id, en);
206 return GPIO_RESULT_OK;
207}
208
209enum gpio_result dal_gpio_service_unlock(
210 struct gpio_service *service,
211 enum gpio_id id,
212 uint32_t en)
213{
214 if (!service->busyness[id]) {
215 ASSERT_CRITICAL(false);
216 return GPIO_RESULT_OPEN_FAILED;
217 }
218
219 set_pin_free(service, id, en);
220 return GPIO_RESULT_OK;
221}
222
195enum gpio_result dal_gpio_service_open( 223enum gpio_result dal_gpio_service_open(
196 struct gpio_service *service, 224 struct gpio_service *service,
197 enum gpio_id id, 225 enum gpio_id id,
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h
index 1d501a43d13b..0c678af75331 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h
+++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h
@@ -52,4 +52,14 @@ void dal_gpio_service_close(
52 struct gpio_service *service, 52 struct gpio_service *service,
53 struct hw_gpio_pin **ptr); 53 struct hw_gpio_pin **ptr);
54 54
55enum gpio_result dal_gpio_service_lock(
56 struct gpio_service *service,
57 enum gpio_id id,
58 uint32_t en);
59
60enum gpio_result dal_gpio_service_unlock(
61 struct gpio_service *service,
62 enum gpio_id id,
63 uint32_t en);
64
55#endif 65#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/clock_source.h b/drivers/gpu/drm/amd/display/dc/inc/clock_source.h
index 43d1fbd8ace5..fe6301cb8681 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/clock_source.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/clock_source.h
@@ -166,6 +166,10 @@ struct clock_source_funcs {
166 struct clock_source *, 166 struct clock_source *,
167 struct pixel_clk_params *, 167 struct pixel_clk_params *,
168 struct pll_settings *); 168 struct pll_settings *);
169 bool (*get_pixel_clk_frequency_100hz)(
170 struct clock_source *clock_source,
171 unsigned int inst,
172 unsigned int *pixel_clk_khz);
169}; 173};
170 174
171struct clock_source { 175struct clock_source {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
index c20fdcaac53b..c9d3e37e9531 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
@@ -153,6 +153,7 @@ struct link_encoder_funcs {
153 void (*enable_hpd)(struct link_encoder *enc); 153 void (*enable_hpd)(struct link_encoder *enc);
154 void (*disable_hpd)(struct link_encoder *enc); 154 void (*disable_hpd)(struct link_encoder *enc);
155 bool (*is_dig_enabled)(struct link_encoder *enc); 155 bool (*is_dig_enabled)(struct link_encoder *enc);
156 unsigned int (*get_dig_frontend)(struct link_encoder *enc);
156 void (*destroy)(struct link_encoder **enc); 157 void (*destroy)(struct link_encoder **enc);
157}; 158};
158 159
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
index df64cf73ceb9..03ae941895f3 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
@@ -134,7 +134,7 @@ struct dc_crtc_timing;
134 134
135struct drr_params; 135struct drr_params;
136 136
137struct vline_config; 137union vline_config;
138 138
139 139
140enum vline_select { 140enum vline_select {
@@ -149,9 +149,14 @@ struct timing_generator_funcs {
149 void (*program_timing)(struct timing_generator *tg, 149 void (*program_timing)(struct timing_generator *tg,
150 const struct dc_crtc_timing *timing, 150 const struct dc_crtc_timing *timing,
151 bool use_vbios); 151 bool use_vbios);
152 void (*program_vline_interrupt)(struct timing_generator *optc, 152 void (*program_vline_interrupt)(
153 struct timing_generator *optc,
154 const struct dc_crtc_timing *dc_crtc_timing,
153 enum vline_select vline, 155 enum vline_select vline,
154 struct vline_config vline_config); 156 const union vline_config *vline_config);
157
158 void (*program_vupdate_interrupt)(struct timing_generator *optc,
159 const struct dc_crtc_timing *dc_crtc_timing);
155 bool (*enable_crtc)(struct timing_generator *tg); 160 bool (*enable_crtc)(struct timing_generator *tg);
156 bool (*disable_crtc)(struct timing_generator *tg); 161 bool (*disable_crtc)(struct timing_generator *tg);
157 bool (*is_counter_moving)(struct timing_generator *tg); 162 bool (*is_counter_moving)(struct timing_generator *tg);
@@ -168,6 +173,8 @@ struct timing_generator_funcs {
168 bool (*get_otg_active_size)(struct timing_generator *optc, 173 bool (*get_otg_active_size)(struct timing_generator *optc,
169 uint32_t *otg_active_width, 174 uint32_t *otg_active_width,
170 uint32_t *otg_active_height); 175 uint32_t *otg_active_height);
176 bool (*is_matching_timing)(struct timing_generator *tg,
177 const struct dc_crtc_timing *otg_timing);
171 void (*set_early_control)(struct timing_generator *tg, 178 void (*set_early_control)(struct timing_generator *tg,
172 uint32_t early_cntl); 179 uint32_t early_cntl);
173 void (*wait_for_state)(struct timing_generator *tg, 180 void (*wait_for_state)(struct timing_generator *tg,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
index d6a85f48b6d1..341b4810288c 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -70,6 +70,8 @@ struct hw_sequencer_funcs {
70 70
71 void (*init_hw)(struct dc *dc); 71 void (*init_hw)(struct dc *dc);
72 72
73 void (*init_pipes)(struct dc *dc, struct dc_state *context);
74
73 enum dc_status (*apply_ctx_to_hw)( 75 enum dc_status (*apply_ctx_to_hw)(
74 struct dc *dc, struct dc_state *context); 76 struct dc *dc, struct dc_state *context);
75 77
diff --git a/drivers/gpu/drm/amd/display/dc/inc/vm_helper.h b/drivers/gpu/drm/amd/display/dc/inc/vm_helper.h
index a202206e22a3..193407f76a80 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/vm_helper.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/vm_helper.h
@@ -39,8 +39,8 @@ struct vm_helper {
39 unsigned int num_vmid; 39 unsigned int num_vmid;
40 unsigned int num_hubp; 40 unsigned int num_hubp;
41 unsigned int num_vmids_available; 41 unsigned int num_vmids_available;
42 uint64_t *ptb_assigned_to_vmid; 42 uint64_t ptb_assigned_to_vmid[MAX_VMID];
43 struct vmid_usage *hubp_vmid_usage; 43 struct vmid_usage hubp_vmid_usage[MAX_HUBP];
44}; 44};
45 45
46uint8_t get_vmid_for_ptb( 46uint8_t get_vmid_for_ptb(
@@ -48,7 +48,8 @@ uint8_t get_vmid_for_ptb(
48 int64_t ptb, 48 int64_t ptb,
49 uint8_t pipe_idx); 49 uint8_t pipe_idx);
50 50
51struct vm_helper init_vm_helper( 51void init_vm_helper(
52 struct vm_helper *vm_helper,
52 unsigned int num_vmid, 53 unsigned int num_vmid,
53 unsigned int num_hubp); 54 unsigned int num_hubp);
54 55
diff --git a/drivers/gpu/drm/amd/display/include/gpio_interface.h b/drivers/gpu/drm/amd/display/include/gpio_interface.h
index e4fd31024b92..7de64195dc33 100644
--- a/drivers/gpu/drm/amd/display/include/gpio_interface.h
+++ b/drivers/gpu/drm/amd/display/include/gpio_interface.h
@@ -59,6 +59,14 @@ enum gpio_result dal_gpio_change_mode(
59 struct gpio *gpio, 59 struct gpio *gpio,
60 enum gpio_mode mode); 60 enum gpio_mode mode);
61 61
62/* Lock Pin */
63enum gpio_result dal_gpio_lock_pin(
64 struct gpio *gpio);
65
66/* Unlock Pin */
67enum gpio_result dal_gpio_unlock_pin(
68 struct gpio *gpio);
69
62/* Get the GPIO id */ 70/* Get the GPIO id */
63enum gpio_id dal_gpio_get_id( 71enum gpio_id dal_gpio_get_id(
64 const struct gpio *gpio); 72 const struct gpio *gpio);
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
index eefb85928298..0fbc8fbc3541 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
@@ -1765,68 +1765,85 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,
1765{ 1765{
1766 struct dc_transfer_func_distributed_points *tf_pts = &input_tf->tf_pts; 1766 struct dc_transfer_func_distributed_points *tf_pts = &input_tf->tf_pts;
1767 struct dividers dividers; 1767 struct dividers dividers;
1768
1769 struct pwl_float_data *rgb_user = NULL; 1768 struct pwl_float_data *rgb_user = NULL;
1770 struct pwl_float_data_ex *curve = NULL; 1769 struct pwl_float_data_ex *curve = NULL;
1771 struct gamma_pixel *axis_x = NULL; 1770 struct gamma_pixel *axis_x = NULL;
1772 struct pixel_gamma_point *coeff = NULL; 1771 struct pixel_gamma_point *coeff = NULL;
1773 enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB; 1772 enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
1773 uint32_t i;
1774 bool ret = false; 1774 bool ret = false;
1775 1775
1776 if (input_tf->type == TF_TYPE_BYPASS) 1776 if (input_tf->type == TF_TYPE_BYPASS)
1777 return false; 1777 return false;
1778 1778
1779 /* we can use hardcoded curve for plain SRGB TF */ 1779 /* we can use hardcoded curve for plain SRGB TF
1780 * If linear, it's bypass if on user ramp
1781 */
1780 if (input_tf->type == TF_TYPE_PREDEFINED && 1782 if (input_tf->type == TF_TYPE_PREDEFINED &&
1781 input_tf->tf == TRANSFER_FUNCTION_SRGB && 1783 (input_tf->tf == TRANSFER_FUNCTION_SRGB ||
1782 !mapUserRamp) 1784 input_tf->tf == TRANSFER_FUNCTION_LINEAR) &&
1785 !mapUserRamp)
1783 return true; 1786 return true;
1784 1787
1785 input_tf->type = TF_TYPE_DISTRIBUTED_POINTS; 1788 input_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
1786 1789
1787 rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS, 1790 if (mapUserRamp && ramp && ramp->type == GAMMA_RGB_256) {
1788 sizeof(*rgb_user), 1791 rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS,
1789 GFP_KERNEL); 1792 sizeof(*rgb_user),
1790 if (!rgb_user) 1793 GFP_KERNEL);
1791 goto rgb_user_alloc_fail; 1794 if (!rgb_user)
1795 goto rgb_user_alloc_fail;
1796
1797 axis_x = kvcalloc(ramp->num_entries + _EXTRA_POINTS, sizeof(*axis_x),
1798 GFP_KERNEL);
1799 if (!axis_x)
1800 goto axis_x_alloc_fail;
1801
1802 dividers.divider1 = dc_fixpt_from_fraction(3, 2);
1803 dividers.divider2 = dc_fixpt_from_int(2);
1804 dividers.divider3 = dc_fixpt_from_fraction(5, 2);
1805
1806 build_evenly_distributed_points(
1807 axis_x,
1808 ramp->num_entries,
1809 dividers);
1810
1811 scale_gamma(rgb_user, ramp, dividers);
1812 }
1813
1792 curve = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*curve), 1814 curve = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*curve),
1793 GFP_KERNEL); 1815 GFP_KERNEL);
1794 if (!curve) 1816 if (!curve)
1795 goto curve_alloc_fail; 1817 goto curve_alloc_fail;
1796 axis_x = kvcalloc(ramp->num_entries + _EXTRA_POINTS, sizeof(*axis_x), 1818
1797 GFP_KERNEL);
1798 if (!axis_x)
1799 goto axis_x_alloc_fail;
1800 coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff), 1819 coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff),
1801 GFP_KERNEL); 1820 GFP_KERNEL);
1802 if (!coeff) 1821 if (!coeff)
1803 goto coeff_alloc_fail; 1822 goto coeff_alloc_fail;
1804 1823
1805 dividers.divider1 = dc_fixpt_from_fraction(3, 2);
1806 dividers.divider2 = dc_fixpt_from_int(2);
1807 dividers.divider3 = dc_fixpt_from_fraction(5, 2);
1808
1809 tf = input_tf->tf; 1824 tf = input_tf->tf;
1810 1825
1811 build_evenly_distributed_points(
1812 axis_x,
1813 ramp->num_entries,
1814 dividers);
1815
1816 if (ramp->type == GAMMA_RGB_256 && mapUserRamp)
1817 scale_gamma(rgb_user, ramp, dividers);
1818 else if (ramp->type == GAMMA_RGB_FLOAT_1024)
1819 scale_gamma_dx(rgb_user, ramp, dividers);
1820
1821 if (tf == TRANSFER_FUNCTION_PQ) 1826 if (tf == TRANSFER_FUNCTION_PQ)
1822 build_de_pq(curve, 1827 build_de_pq(curve,
1823 MAX_HW_POINTS, 1828 MAX_HW_POINTS,
1824 coordinates_x); 1829 coordinates_x);
1825 else 1830 else if (tf == TRANSFER_FUNCTION_SRGB ||
1831 tf == TRANSFER_FUNCTION_BT709)
1826 build_degamma(curve, 1832 build_degamma(curve,
1827 MAX_HW_POINTS, 1833 MAX_HW_POINTS,
1828 coordinates_x, 1834 coordinates_x,
1829 tf == TRANSFER_FUNCTION_SRGB ? true:false); 1835 tf == TRANSFER_FUNCTION_SRGB ? true : false);
1836 else if (tf == TRANSFER_FUNCTION_LINEAR) {
1837 // just copy coordinates_x into curve
1838 i = 0;
1839 while (i != MAX_HW_POINTS + 1) {
1840 curve[i].r = coordinates_x[i].x;
1841 curve[i].g = curve[i].r;
1842 curve[i].b = curve[i].r;
1843 i++;
1844 }
1845 } else
1846 goto invalid_tf_fail;
1830 1847
1831 tf_pts->end_exponent = 0; 1848 tf_pts->end_exponent = 0;
1832 tf_pts->x_point_at_y1_red = 1; 1849 tf_pts->x_point_at_y1_red = 1;
@@ -1836,23 +1853,21 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,
1836 map_regamma_hw_to_x_user(ramp, coeff, rgb_user, 1853 map_regamma_hw_to_x_user(ramp, coeff, rgb_user,
1837 coordinates_x, axis_x, curve, 1854 coordinates_x, axis_x, curve,
1838 MAX_HW_POINTS, tf_pts, 1855 MAX_HW_POINTS, tf_pts,
1839 mapUserRamp && ramp->type != GAMMA_CUSTOM); 1856 mapUserRamp && ramp && ramp->type == GAMMA_RGB_256);
1840 if (ramp->type == GAMMA_CUSTOM)
1841 apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts);
1842 1857
1843 ret = true; 1858 ret = true;
1844 1859
1860invalid_tf_fail:
1845 kvfree(coeff); 1861 kvfree(coeff);
1846coeff_alloc_fail: 1862coeff_alloc_fail:
1847 kvfree(axis_x);
1848axis_x_alloc_fail:
1849 kvfree(curve); 1863 kvfree(curve);
1850curve_alloc_fail: 1864curve_alloc_fail:
1865 kvfree(axis_x);
1866axis_x_alloc_fail:
1851 kvfree(rgb_user); 1867 kvfree(rgb_user);
1852rgb_user_alloc_fail: 1868rgb_user_alloc_fail:
1853 1869
1854 return ret; 1870 return ret;
1855
1856} 1871}
1857 1872
1858 1873
diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
index baab6c4ae191..3ba87b076287 100644
--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
+++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
@@ -47,10 +47,10 @@ static const unsigned char min_reduction_table_v_2_2[13] = {
47 47
48/* Possible ABM 2.2 Max Reduction configs from least aggressive to most aggressive 48/* Possible ABM 2.2 Max Reduction configs from least aggressive to most aggressive
49 * 0 1 2 3 4 5 6 7 8 9 10 11 12 49 * 0 1 2 3 4 5 6 7 8 9 10 11 12
50 * 96.1 89.8 85.1 80.3 69.4 64.7 54.9 45.1 30.2 25.1 19.6 12.5 12.5 % 50 * 96.1 89.8 74.9 69.4 64.7 52.2 48.6 39.6 30.2 25.1 19.6 12.5 12.5 %
51 */ 51 */
52static const unsigned char max_reduction_table_v_2_2[13] = { 52static const unsigned char max_reduction_table_v_2_2[13] = {
530xf5, 0xe5, 0xd9, 0xcd, 0xb1, 0xa5, 0x8c, 0x73, 0x4d, 0x40, 0x32, 0x20, 0x20}; 530xf5, 0xe5, 0xbf, 0xb1, 0xa5, 0x85, 0x7c, 0x65, 0x4d, 0x40, 0x32, 0x20, 0x20};
54 54
55/* Predefined ABM configuration sets. We may have different configuration sets 55/* Predefined ABM configuration sets. We may have different configuration sets
56 * in order to satisfy different power/quality requirements. 56 * in order to satisfy different power/quality requirements.
@@ -67,9 +67,14 @@ static const unsigned char abm_config[abm_defines_max_config][abm_defines_max_le
67#define NUM_AGGR_LEVEL 4 67#define NUM_AGGR_LEVEL 4
68#define NUM_POWER_FN_SEGS 8 68#define NUM_POWER_FN_SEGS 8
69#define NUM_BL_CURVE_SEGS 16 69#define NUM_BL_CURVE_SEGS 16
70#define IRAM_RESERVE_AREA_START 0xF0 // reserve 0xF0~0xFF are write by DMCU only
71#define IRAM_SIZE 256 70#define IRAM_SIZE 256
72 71
72#define IRAM_RESERVE_AREA_START_V2 0xF0 // reserve 0xF0~0xF6 are write by DMCU only
73#define IRAM_RESERVE_AREA_END_V2 0xF6 // reserve 0xF0~0xF6 are write by DMCU only
74
75#define IRAM_RESERVE_AREA_START_V2_2 0xF0 // reserve 0xF0~0xFF are write by DMCU only
76#define IRAM_RESERVE_AREA_END_V2_2 0xFF // reserve 0xF0~0xFF are write by DMCU only
77
73#pragma pack(push, 1) 78#pragma pack(push, 1)
74/* NOTE: iRAM is 256B in size */ 79/* NOTE: iRAM is 256B in size */
75struct iram_table_v_2 { 80struct iram_table_v_2 {
@@ -148,8 +153,10 @@ struct iram_table_v_2_2 {
148 uint16_t dmcu_version; /* 0xf4 */ 153 uint16_t dmcu_version; /* 0xf4 */
149 uint8_t dmcu_state; /* 0xf6 */ 154 uint8_t dmcu_state; /* 0xf6 */
150 155
151 uint16_t blRampReduction; /* 0xf7 */ 156 uint8_t dummy1; /* 0xf7 */
152 uint16_t blRampStart; /* 0xf9 */ 157 uint8_t dummy2; /* 0xf8 */
158 uint8_t dummy3; /* 0xf9 */
159 uint8_t dummy4; /* 0xfa */
153 uint8_t dummy5; /* 0xfb */ 160 uint8_t dummy5; /* 0xfb */
154 uint8_t dummy6; /* 0xfc */ 161 uint8_t dummy6; /* 0xfc */
155 uint8_t dummy7; /* 0xfd */ 162 uint8_t dummy7; /* 0xfd */
@@ -420,11 +427,6 @@ void fill_iram_v_2_2(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parame
420 ram_table->deviation_gain[2] = 0xb3; 427 ram_table->deviation_gain[2] = 0xb3;
421 ram_table->deviation_gain[3] = 0xb3; 428 ram_table->deviation_gain[3] = 0xb3;
422 429
423 ram_table->blRampReduction =
424 cpu_to_be16(params.backlight_ramping_reduction);
425 ram_table->blRampStart =
426 cpu_to_be16(params.backlight_ramping_start);
427
428 ram_table->min_reduction[0][0] = min_reduction_table_v_2_2[abm_config[set][0]]; 430 ram_table->min_reduction[0][0] = min_reduction_table_v_2_2[abm_config[set][0]];
429 ram_table->min_reduction[1][0] = min_reduction_table_v_2_2[abm_config[set][0]]; 431 ram_table->min_reduction[1][0] = min_reduction_table_v_2_2[abm_config[set][0]];
430 ram_table->min_reduction[2][0] = min_reduction_table_v_2_2[abm_config[set][0]]; 432 ram_table->min_reduction[2][0] = min_reduction_table_v_2_2[abm_config[set][0]];
@@ -561,6 +563,7 @@ bool dmcu_load_iram(struct dmcu *dmcu,
561 struct dmcu_iram_parameters params) 563 struct dmcu_iram_parameters params)
562{ 564{
563 unsigned char ram_table[IRAM_SIZE]; 565 unsigned char ram_table[IRAM_SIZE];
566 bool result = false;
564 567
565 if (dmcu == NULL) 568 if (dmcu == NULL)
566 return false; 569 return false;
@@ -572,10 +575,21 @@ bool dmcu_load_iram(struct dmcu *dmcu,
572 575
573 if (dmcu->dmcu_version.abm_version == 0x22) { 576 if (dmcu->dmcu_version.abm_version == 0x22) {
574 fill_iram_v_2_2((struct iram_table_v_2_2 *)ram_table, params); 577 fill_iram_v_2_2((struct iram_table_v_2_2 *)ram_table, params);
578
579 result = dmcu->funcs->load_iram(
580 dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2);
575 } else { 581 } else {
576 fill_iram_v_2((struct iram_table_v_2 *)ram_table, params); 582 fill_iram_v_2((struct iram_table_v_2 *)ram_table, params);
583
584 result = dmcu->funcs->load_iram(
585 dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2);
586
587 if (result)
588 result = dmcu->funcs->load_iram(
589 dmcu, IRAM_RESERVE_AREA_END_V2 + 1,
590 (char *)(&ram_table) + IRAM_RESERVE_AREA_END_V2 + 1,
591 sizeof(ram_table) - IRAM_RESERVE_AREA_END_V2 - 1);
577 } 592 }
578 593
579 return dmcu->funcs->load_iram( 594 return result;
580 dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START);
581} 595}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
index 0d38ac2fdbf1..5479125ff4f6 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
@@ -3579,6 +3579,10 @@ static int vega10_generate_dpm_level_enable_mask(
3579 vega10_find_lowest_dpm_level(&(data->dpm_table.mem_table)); 3579 vega10_find_lowest_dpm_level(&(data->dpm_table.mem_table));
3580 data->smc_state_table.mem_max_level = 3580 data->smc_state_table.mem_max_level =
3581 vega10_find_highest_dpm_level(&(data->dpm_table.mem_table)); 3581 vega10_find_highest_dpm_level(&(data->dpm_table.mem_table));
3582 data->smc_state_table.soc_boot_level =
3583 vega10_find_lowest_dpm_level(&(data->dpm_table.soc_table));
3584 data->smc_state_table.soc_max_level =
3585 vega10_find_highest_dpm_level(&(data->dpm_table.soc_table));
3582 3586
3583 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr), 3587 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
3584 "Attempt to upload DPM Bootup Levels Failed!", 3588 "Attempt to upload DPM Bootup Levels Failed!",
@@ -3593,6 +3597,9 @@ static int vega10_generate_dpm_level_enable_mask(
3593 for(i = data->smc_state_table.mem_boot_level; i < data->smc_state_table.mem_max_level; i++) 3597 for(i = data->smc_state_table.mem_boot_level; i < data->smc_state_table.mem_max_level; i++)
3594 data->dpm_table.mem_table.dpm_levels[i].enabled = true; 3598 data->dpm_table.mem_table.dpm_levels[i].enabled = true;
3595 3599
3600 for (i = data->smc_state_table.soc_boot_level; i < data->smc_state_table.soc_max_level; i++)
3601 data->dpm_table.soc_table.dpm_levels[i].enabled = true;
3602
3596 return 0; 3603 return 0;
3597} 3604}
3598 3605
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
index da022ca79b56..0769b1ec562b 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
@@ -771,40 +771,47 @@ static int vega20_init_smc_table(struct pp_hwmgr *hwmgr)
771 return 0; 771 return 0;
772} 772}
773 773
774/*
775 * Override PCIe link speed and link width for DPM Level 1. PPTable entries
776 * reflect the ASIC capabilities and not the system capabilities. For e.g.
777 * Vega20 board in a PCI Gen3 system. In this case, when SMU's tries to switch
778 * to DPM1, it fails as system doesn't support Gen4.
779 */
774static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr) 780static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr)
775{ 781{
776 struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); 782 struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
777 uint32_t pcie_speed = 0, pcie_width = 0, pcie_arg; 783 uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg;
778 int ret; 784 int ret;
779 785
780 if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) 786 if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)
781 pcie_speed = 16; 787 pcie_gen = 3;
782 else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) 788 else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
783 pcie_speed = 8; 789 pcie_gen = 2;
784 else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) 790 else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
785 pcie_speed = 5; 791 pcie_gen = 1;
786 else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) 792 else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1)
787 pcie_speed = 2; 793 pcie_gen = 0;
788 794
789 if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X32) 795 if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16)
790 pcie_width = 32; 796 pcie_width = 6;
791 else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16)
792 pcie_width = 16;
793 else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) 797 else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12)
794 pcie_width = 12; 798 pcie_width = 5;
795 else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) 799 else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8)
796 pcie_width = 8;
797 else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4)
798 pcie_width = 4; 800 pcie_width = 4;
801 else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4)
802 pcie_width = 3;
799 else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) 803 else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2)
800 pcie_width = 2; 804 pcie_width = 2;
801 else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) 805 else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1)
802 pcie_width = 1; 806 pcie_width = 1;
803 807
804 pcie_arg = pcie_width | (pcie_speed << 8); 808 /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1
805 809 * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4
810 * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32
811 */
812 smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width;
806 ret = smum_send_msg_to_smc_with_parameter(hwmgr, 813 ret = smum_send_msg_to_smc_with_parameter(hwmgr,
807 PPSMC_MSG_OverridePcieParameters, pcie_arg); 814 PPSMC_MSG_OverridePcieParameters, smu_pcie_arg);
808 PP_ASSERT_WITH_CODE(!ret, 815 PP_ASSERT_WITH_CODE(!ret,
809 "[OverridePcieParameters] Attempt to override pcie params failed!", 816 "[OverridePcieParameters] Attempt to override pcie params failed!",
810 return ret); 817 return ret);
@@ -1611,11 +1618,6 @@ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
1611 "[EnableDPMTasks] Failed to initialize SMC table!", 1618 "[EnableDPMTasks] Failed to initialize SMC table!",
1612 return result); 1619 return result);
1613 1620
1614 result = vega20_override_pcie_parameters(hwmgr);
1615 PP_ASSERT_WITH_CODE(!result,
1616 "[EnableDPMTasks] Failed to override pcie parameters!",
1617 return result);
1618
1619 result = vega20_run_btc(hwmgr); 1621 result = vega20_run_btc(hwmgr);
1620 PP_ASSERT_WITH_CODE(!result, 1622 PP_ASSERT_WITH_CODE(!result,
1621 "[EnableDPMTasks] Failed to run btc!", 1623 "[EnableDPMTasks] Failed to run btc!",
@@ -1631,6 +1633,11 @@ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
1631 "[EnableDPMTasks] Failed to enable all smu features!", 1633 "[EnableDPMTasks] Failed to enable all smu features!",
1632 return result); 1634 return result);
1633 1635
1636 result = vega20_override_pcie_parameters(hwmgr);
1637 PP_ASSERT_WITH_CODE(!result,
1638 "[EnableDPMTasks] Failed to override pcie parameters!",
1639 return result);
1640
1634 result = vega20_notify_smc_display_change(hwmgr); 1641 result = vega20_notify_smc_display_change(hwmgr);
1635 PP_ASSERT_WITH_CODE(!result, 1642 PP_ASSERT_WITH_CODE(!result,
1636 "[EnableDPMTasks] Failed to notify smc display change!", 1643 "[EnableDPMTasks] Failed to notify smc display change!",