aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.txt (renamed from Documentation/devicetree/bindings/display/panel/innolux,tv123wam.txt)8
-rw-r--r--Documentation/devicetree/bindings/display/panel/simple-panel.txt3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c6
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c7
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c16
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c2
-rw-r--r--drivers/gpu/drm/amd/powerplay/amd_powerplay.c33
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c10
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c2
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c43
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c8
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c85
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c56
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c4
-rw-r--r--drivers/gpu/drm/bridge/ti-sn65dsi86.c29
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c21
-rw-r--r--drivers/gpu/drm/drm_connector.c11
-rw-r--r--drivers/gpu/drm/drm_edid.c3
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c20
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c8
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/disp.c14
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c29
-rw-r--r--include/drm/drm_connector.h71
32 files changed, 364 insertions, 175 deletions
diff --git a/Documentation/devicetree/bindings/display/panel/innolux,tv123wam.txt b/Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.txt
index a9b35265fa13..513f03466aba 100644
--- a/Documentation/devicetree/bindings/display/panel/innolux,tv123wam.txt
+++ b/Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.txt
@@ -1,20 +1,22 @@
1Innolux TV123WAM 12.3 inch eDP 2K display panel 1Innolux P120ZDG-BF1 12.02 inch eDP 2K display panel
2 2
3This binding is compatible with the simple-panel binding, which is specified 3This binding is compatible with the simple-panel binding, which is specified
4in simple-panel.txt in this directory. 4in simple-panel.txt in this directory.
5 5
6Required properties: 6Required properties:
7- compatible: should be "innolux,tv123wam" 7- compatible: should be "innolux,p120zdg-bf1"
8- power-supply: regulator to provide the supply voltage 8- power-supply: regulator to provide the supply voltage
9 9
10Optional properties: 10Optional properties:
11- enable-gpios: GPIO pin to enable or disable the panel 11- enable-gpios: GPIO pin to enable or disable the panel
12- backlight: phandle of the backlight device attached to the panel 12- backlight: phandle of the backlight device attached to the panel
13- no-hpd: If HPD isn't hooked up; add this property.
13 14
14Example: 15Example:
15 panel_edp: panel-edp { 16 panel_edp: panel-edp {
16 compatible = "innolux,tv123wam"; 17 compatible = "innolux,p120zdg-bf1";
17 enable-gpios = <&msmgpio 31 GPIO_ACTIVE_LOW>; 18 enable-gpios = <&msmgpio 31 GPIO_ACTIVE_LOW>;
18 power-supply = <&pm8916_l2>; 19 power-supply = <&pm8916_l2>;
19 backlight = <&backlight>; 20 backlight = <&backlight>;
21 no-hpd;
20 }; 22 };
diff --git a/Documentation/devicetree/bindings/display/panel/simple-panel.txt b/Documentation/devicetree/bindings/display/panel/simple-panel.txt
index 45a457ad38f0..b2b872c710f2 100644
--- a/Documentation/devicetree/bindings/display/panel/simple-panel.txt
+++ b/Documentation/devicetree/bindings/display/panel/simple-panel.txt
@@ -11,6 +11,9 @@ Optional properties:
11- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing 11- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
12- enable-gpios: GPIO pin to enable or disable the panel 12- enable-gpios: GPIO pin to enable or disable the panel
13- backlight: phandle of the backlight device attached to the panel 13- backlight: phandle of the backlight device attached to the panel
14- no-hpd: This panel is supposed to communicate that it's ready via HPD
15 (hot plug detect) signal, but the signal isn't hooked up so we should
16 hardcode the max delay from the panel spec when powering up the panel.
14 17
15Example: 18Example:
16 19
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
index 297a5490ad8c..0a4fba196b84 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
@@ -135,7 +135,8 @@ static int acp_poweroff(struct generic_pm_domain *genpd)
135 * 2. power off the acp tiles 135 * 2. power off the acp tiles
136 * 3. check and enter ulv state 136 * 3. check and enter ulv state
137 */ 137 */
138 if (adev->powerplay.pp_funcs->set_powergating_by_smu) 138 if (adev->powerplay.pp_funcs &&
139 adev->powerplay.pp_funcs->set_powergating_by_smu)
139 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true); 140 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true);
140 } 141 }
141 return 0; 142 return 0;
@@ -517,7 +518,8 @@ static int acp_set_powergating_state(void *handle,
517 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 518 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
518 bool enable = state == AMD_PG_STATE_GATE ? true : false; 519 bool enable = state == AMD_PG_STATE_GATE ? true : false;
519 520
520 if (adev->powerplay.pp_funcs->set_powergating_by_smu) 521 if (adev->powerplay.pp_funcs &&
522 adev->powerplay.pp_funcs->set_powergating_by_smu)
521 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, enable); 523 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, enable);
522 524
523 return 0; 525 return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 1e4dd09a5072..30bc345d6fdf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1493,8 +1493,6 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
1493 } 1493 }
1494 1494
1495 adev->powerplay.pp_feature = amdgpu_pp_feature_mask; 1495 adev->powerplay.pp_feature = amdgpu_pp_feature_mask;
1496 if (amdgpu_sriov_vf(adev))
1497 adev->powerplay.pp_feature &= ~PP_GFXOFF_MASK;
1498 1496
1499 for (i = 0; i < adev->num_ip_blocks; i++) { 1497 for (i = 0; i < adev->num_ip_blocks; i++) {
1500 if ((amdgpu_ip_block_mask & (1 << i)) == 0) { 1498 if ((amdgpu_ip_block_mask & (1 << i)) == 0) {
@@ -1600,7 +1598,7 @@ static int amdgpu_device_fw_loading(struct amdgpu_device *adev)
1600 } 1598 }
1601 } 1599 }
1602 1600
1603 if (adev->powerplay.pp_funcs->load_firmware) { 1601 if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->load_firmware) {
1604 r = adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle); 1602 r = adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle);
1605 if (r) { 1603 if (r) {
1606 pr_err("firmware loading failed\n"); 1604 pr_err("firmware loading failed\n");
@@ -3341,7 +3339,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
3341 3339
3342 kthread_park(ring->sched.thread); 3340 kthread_park(ring->sched.thread);
3343 3341
3344 if (job && job->base.sched == &ring->sched) 3342 if (job && job->base.sched != &ring->sched)
3345 continue; 3343 continue;
3346 3344
3347 drm_sched_hw_job_reset(&ring->sched, job ? &job->base : NULL); 3345 drm_sched_hw_job_reset(&ring->sched, job ? &job->base : NULL);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 28781414d71c..943dbf3c5da1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -114,8 +114,8 @@ uint amdgpu_pg_mask = 0xffffffff;
114uint amdgpu_sdma_phase_quantum = 32; 114uint amdgpu_sdma_phase_quantum = 32;
115char *amdgpu_disable_cu = NULL; 115char *amdgpu_disable_cu = NULL;
116char *amdgpu_virtual_display = NULL; 116char *amdgpu_virtual_display = NULL;
117/* OverDrive(bit 14) disabled by default*/ 117/* OverDrive(bit 14),gfxoff(bit 15),stutter mode(bit 17) disabled by default*/
118uint amdgpu_pp_feature_mask = 0xffffbfff; 118uint amdgpu_pp_feature_mask = 0xfffd3fff;
119int amdgpu_ngg = 0; 119int amdgpu_ngg = 0;
120int amdgpu_prim_buf_per_se = 0; 120int amdgpu_prim_buf_per_se = 0;
121int amdgpu_pos_buf_per_se = 0; 121int amdgpu_pos_buf_per_se = 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index 790fd5408ddf..1a656b8657f7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -392,7 +392,7 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
392 if (!(adev->powerplay.pp_feature & PP_GFXOFF_MASK)) 392 if (!(adev->powerplay.pp_feature & PP_GFXOFF_MASK))
393 return; 393 return;
394 394
395 if (!adev->powerplay.pp_funcs->set_powergating_by_smu) 395 if (!adev->powerplay.pp_funcs || !adev->powerplay.pp_funcs->set_powergating_by_smu)
396 return; 396 return;
397 397
398 398
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 94055a485e01..59cc678de8c1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -704,7 +704,10 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev,
704 return ret; 704 return ret;
705 705
706 if (adev->powerplay.pp_funcs->force_clock_level) 706 if (adev->powerplay.pp_funcs->force_clock_level)
707 amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask); 707 ret = amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask);
708
709 if (ret)
710 return -EINVAL;
708 711
709 return count; 712 return count;
710} 713}
@@ -737,7 +740,10 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev,
737 return ret; 740 return ret;
738 741
739 if (adev->powerplay.pp_funcs->force_clock_level) 742 if (adev->powerplay.pp_funcs->force_clock_level)
740 amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask); 743 ret = amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask);
744
745 if (ret)
746 return -EINVAL;
741 747
742 return count; 748 return count;
743} 749}
@@ -770,7 +776,10 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev,
770 return ret; 776 return ret;
771 777
772 if (adev->powerplay.pp_funcs->force_clock_level) 778 if (adev->powerplay.pp_funcs->force_clock_level)
773 amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask); 779 ret = amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask);
780
781 if (ret)
782 return -EINVAL;
774 783
775 return count; 784 return count;
776} 785}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 6904d794d60a..352b30409060 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -542,7 +542,8 @@ static void amdgpu_vm_pt_next_leaf(struct amdgpu_device *adev,
542 struct amdgpu_vm_pt_cursor *cursor) 542 struct amdgpu_vm_pt_cursor *cursor)
543{ 543{
544 amdgpu_vm_pt_next(adev, cursor); 544 amdgpu_vm_pt_next(adev, cursor);
545 while (amdgpu_vm_pt_descendant(adev, cursor)); 545 if (cursor->pfn != ~0ll)
546 while (amdgpu_vm_pt_descendant(adev, cursor));
546} 547}
547 548
548/** 549/**
@@ -3234,8 +3235,10 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
3234 } 3235 }
3235 rbtree_postorder_for_each_entry_safe(mapping, tmp, 3236 rbtree_postorder_for_each_entry_safe(mapping, tmp,
3236 &vm->va.rb_root, rb) { 3237 &vm->va.rb_root, rb) {
3238 /* Don't remove the mapping here, we don't want to trigger a
3239 * rebalance and the tree is about to be destroyed anyway.
3240 */
3237 list_del(&mapping->list); 3241 list_del(&mapping->list);
3238 amdgpu_vm_it_remove(mapping, &vm->va);
3239 kfree(mapping); 3242 kfree(mapping);
3240 } 3243 }
3241 list_for_each_entry_safe(mapping, tmp, &vm->freed, list) { 3244 list_for_each_entry_safe(mapping, tmp, &vm->freed, list) {
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index 3d0f277a6523..617b0c8908a3 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -4815,8 +4815,10 @@ static int gfx_v8_0_kcq_resume(struct amdgpu_device *adev)
4815 if (r) 4815 if (r)
4816 goto done; 4816 goto done;
4817 4817
4818 /* Test KCQs */ 4818 /* Test KCQs - reversing the order of rings seems to fix ring test failure
4819 for (i = 0; i < adev->gfx.num_compute_rings; i++) { 4819 * after GPU reset
4820 */
4821 for (i = adev->gfx.num_compute_rings - 1; i >= 0; i--) {
4820 ring = &adev->gfx.compute_ring[i]; 4822 ring = &adev->gfx.compute_ring[i];
4821 ring->ready = true; 4823 ring->ready = true;
4822 r = amdgpu_ring_test_ring(ring); 4824 r = amdgpu_ring_test_ring(ring);
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
index 14649f8475f3..fd23ba1226a5 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
@@ -280,7 +280,7 @@ void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev,
280 return; 280 return;
281 281
282 if (enable && adev->pg_flags & AMD_PG_SUPPORT_MMHUB) { 282 if (enable && adev->pg_flags & AMD_PG_SUPPORT_MMHUB) {
283 if (adev->powerplay.pp_funcs->set_powergating_by_smu) 283 if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->set_powergating_by_smu)
284 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GMC, true); 284 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GMC, true);
285 285
286 } 286 }
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index 04fa3d972636..7a8c9172d30a 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -1366,7 +1366,8 @@ static int sdma_v4_0_hw_init(void *handle)
1366 int r; 1366 int r;
1367 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1367 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1368 1368
1369 if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs->set_powergating_by_smu) 1369 if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs &&
1370 adev->powerplay.pp_funcs->set_powergating_by_smu)
1370 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false); 1371 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false);
1371 1372
1372 sdma_v4_0_init_golden_registers(adev); 1373 sdma_v4_0_init_golden_registers(adev);
@@ -1386,7 +1387,8 @@ static int sdma_v4_0_hw_fini(void *handle)
1386 sdma_v4_0_ctx_switch_enable(adev, false); 1387 sdma_v4_0_ctx_switch_enable(adev, false);
1387 sdma_v4_0_enable(adev, false); 1388 sdma_v4_0_enable(adev, false);
1388 1389
1389 if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs->set_powergating_by_smu) 1390 if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs
1391 && adev->powerplay.pp_funcs->set_powergating_by_smu)
1390 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, true); 1392 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, true);
1391 1393
1392 return 0; 1394 return 0;
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 e224f23e2215..b0df6dc9a775 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1524,6 +1524,13 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
1524{ 1524{
1525 struct amdgpu_display_manager *dm = bl_get_data(bd); 1525 struct amdgpu_display_manager *dm = bl_get_data(bd);
1526 1526
1527 /*
1528 * PWM interperts 0 as 100% rather than 0% because of HW
1529 * limitation for level 0.So limiting minimum brightness level
1530 * to 1.
1531 */
1532 if (bd->props.brightness < 1)
1533 return 1;
1527 if (dc_link_set_backlight_level(dm->backlight_link, 1534 if (dc_link_set_backlight_level(dm->backlight_link,
1528 bd->props.brightness, 0, 0)) 1535 bd->props.brightness, 0, 0))
1529 return 0; 1536 return 0;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
index 0fab64a2a915..12001a006b2d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
@@ -101,7 +101,7 @@ bool dm_pp_apply_display_requirements(
101 adev->pm.pm_display_cfg.displays[i].controller_id = dc_cfg->pipe_idx + 1; 101 adev->pm.pm_display_cfg.displays[i].controller_id = dc_cfg->pipe_idx + 1;
102 } 102 }
103 103
104 if (adev->powerplay.pp_funcs->display_configuration_change) 104 if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_configuration_change)
105 adev->powerplay.pp_funcs->display_configuration_change( 105 adev->powerplay.pp_funcs->display_configuration_change(
106 adev->powerplay.pp_handle, 106 adev->powerplay.pp_handle,
107 &adev->pm.pm_display_cfg); 107 &adev->pm.pm_display_cfg);
@@ -304,7 +304,7 @@ bool dm_pp_get_clock_levels_by_type(
304 struct amd_pp_simple_clock_info validation_clks = { 0 }; 304 struct amd_pp_simple_clock_info validation_clks = { 0 };
305 uint32_t i; 305 uint32_t i;
306 306
307 if (adev->powerplay.pp_funcs->get_clock_by_type) { 307 if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_clock_by_type) {
308 if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle, 308 if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle,
309 dc_to_pp_clock_type(clk_type), &pp_clks)) { 309 dc_to_pp_clock_type(clk_type), &pp_clks)) {
310 /* Error in pplib. Provide default values. */ 310 /* Error in pplib. Provide default values. */
@@ -315,7 +315,7 @@ bool dm_pp_get_clock_levels_by_type(
315 315
316 pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type); 316 pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type);
317 317
318 if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks) { 318 if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_display_mode_validation_clocks) {
319 if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks( 319 if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks(
320 pp_handle, &validation_clks)) { 320 pp_handle, &validation_clks)) {
321 /* Error in pplib. Provide default values. */ 321 /* Error in pplib. Provide default values. */
@@ -398,6 +398,9 @@ bool dm_pp_get_clock_levels_by_type_with_voltage(
398 struct pp_clock_levels_with_voltage pp_clk_info = {0}; 398 struct pp_clock_levels_with_voltage pp_clk_info = {0};
399 const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; 399 const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
400 400
401 if (!pp_funcs || !pp_funcs->get_clock_by_type_with_voltage)
402 return false;
403
401 if (pp_funcs->get_clock_by_type_with_voltage(pp_handle, 404 if (pp_funcs->get_clock_by_type_with_voltage(pp_handle,
402 dc_to_pp_clock_type(clk_type), 405 dc_to_pp_clock_type(clk_type),
403 &pp_clk_info)) 406 &pp_clk_info))
@@ -438,7 +441,7 @@ bool dm_pp_apply_clock_for_voltage_request(
438 if (!pp_clock_request.clock_type) 441 if (!pp_clock_request.clock_type)
439 return false; 442 return false;
440 443
441 if (adev->powerplay.pp_funcs->display_clock_voltage_request) 444 if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_clock_voltage_request)
442 ret = adev->powerplay.pp_funcs->display_clock_voltage_request( 445 ret = adev->powerplay.pp_funcs->display_clock_voltage_request(
443 adev->powerplay.pp_handle, 446 adev->powerplay.pp_handle,
444 &pp_clock_request); 447 &pp_clock_request);
@@ -455,7 +458,7 @@ bool dm_pp_get_static_clocks(
455 struct amd_pp_clock_info pp_clk_info = {0}; 458 struct amd_pp_clock_info pp_clk_info = {0};
456 int ret = 0; 459 int ret = 0;
457 460
458 if (adev->powerplay.pp_funcs->get_current_clocks) 461 if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_current_clocks)
459 ret = adev->powerplay.pp_funcs->get_current_clocks( 462 ret = adev->powerplay.pp_funcs->get_current_clocks(
460 adev->powerplay.pp_handle, 463 adev->powerplay.pp_handle,
461 &pp_clk_info); 464 &pp_clk_info);
@@ -505,6 +508,9 @@ void pp_rv_set_wm_ranges(struct pp_smu *pp,
505 wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets; 508 wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets;
506 wm_with_clock_ranges.num_wm_mcif_sets = ranges->num_writer_wm_sets; 509 wm_with_clock_ranges.num_wm_mcif_sets = ranges->num_writer_wm_sets;
507 510
511 if (!pp_funcs || !pp_funcs->set_watermarks_for_clocks_ranges)
512 return;
513
508 for (i = 0; i < wm_with_clock_ranges.num_wm_dmif_sets; i++) { 514 for (i = 0; i < wm_with_clock_ranges.num_wm_dmif_sets; i++) {
509 if (ranges->reader_wm_sets[i].wm_inst > 3) 515 if (ranges->reader_wm_sets[i].wm_inst > 3)
510 wm_dce_clocks[i].wm_set_id = WM_SET_A; 516 wm_dce_clocks[i].wm_set_id = WM_SET_A;
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
index de190935f0a4..e3624ca24574 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
@@ -568,7 +568,7 @@ static struct input_pixel_processor *dce110_ipp_create(
568 568
569static const struct encoder_feature_support link_enc_feature = { 569static const struct encoder_feature_support link_enc_feature = {
570 .max_hdmi_deep_color = COLOR_DEPTH_121212, 570 .max_hdmi_deep_color = COLOR_DEPTH_121212,
571 .max_hdmi_pixel_clock = 594000, 571 .max_hdmi_pixel_clock = 300000,
572 .flags.bits.IS_HBR2_CAPABLE = true, 572 .flags.bits.IS_HBR2_CAPABLE = true,
573 .flags.bits.IS_TPS3_CAPABLE = true 573 .flags.bits.IS_TPS3_CAPABLE = true
574}; 574};
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
index e8964cae6b93..d6aa1d414320 100644
--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -723,11 +723,14 @@ static int pp_dpm_force_clock_level(void *handle,
723 pr_info("%s was not implemented.\n", __func__); 723 pr_info("%s was not implemented.\n", __func__);
724 return 0; 724 return 0;
725 } 725 }
726
727 if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {
728 pr_info("force clock level is for dpm manual mode only.\n");
729 return -EINVAL;
730 }
731
726 mutex_lock(&hwmgr->smu_lock); 732 mutex_lock(&hwmgr->smu_lock);
727 if (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) 733 ret = hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask);
728 ret = hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask);
729 else
730 ret = -EINVAL;
731 mutex_unlock(&hwmgr->smu_lock); 734 mutex_unlock(&hwmgr->smu_lock);
732 return ret; 735 return ret;
733} 736}
@@ -963,6 +966,7 @@ static int pp_dpm_switch_power_profile(void *handle,
963static int pp_set_power_limit(void *handle, uint32_t limit) 966static int pp_set_power_limit(void *handle, uint32_t limit)
964{ 967{
965 struct pp_hwmgr *hwmgr = handle; 968 struct pp_hwmgr *hwmgr = handle;
969 uint32_t max_power_limit;
966 970
967 if (!hwmgr || !hwmgr->pm_en) 971 if (!hwmgr || !hwmgr->pm_en)
968 return -EINVAL; 972 return -EINVAL;
@@ -975,7 +979,13 @@ static int pp_set_power_limit(void *handle, uint32_t limit)
975 if (limit == 0) 979 if (limit == 0)
976 limit = hwmgr->default_power_limit; 980 limit = hwmgr->default_power_limit;
977 981
978 if (limit > hwmgr->default_power_limit) 982 max_power_limit = hwmgr->default_power_limit;
983 if (hwmgr->od_enabled) {
984 max_power_limit *= (100 + hwmgr->platform_descriptor.TDPODLimit);
985 max_power_limit /= 100;
986 }
987
988 if (limit > max_power_limit)
979 return -EINVAL; 989 return -EINVAL;
980 990
981 mutex_lock(&hwmgr->smu_lock); 991 mutex_lock(&hwmgr->smu_lock);
@@ -994,8 +1004,13 @@ static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit)
994 1004
995 mutex_lock(&hwmgr->smu_lock); 1005 mutex_lock(&hwmgr->smu_lock);
996 1006
997 if (default_limit) 1007 if (default_limit) {
998 *limit = hwmgr->default_power_limit; 1008 *limit = hwmgr->default_power_limit;
1009 if (hwmgr->od_enabled) {
1010 *limit *= (100 + hwmgr->platform_descriptor.TDPODLimit);
1011 *limit /= 100;
1012 }
1013 }
999 else 1014 else
1000 *limit = hwmgr->power_limit; 1015 *limit = hwmgr->power_limit;
1001 1016
@@ -1303,12 +1318,12 @@ static int pp_enable_mgpu_fan_boost(void *handle)
1303{ 1318{
1304 struct pp_hwmgr *hwmgr = handle; 1319 struct pp_hwmgr *hwmgr = handle;
1305 1320
1306 if (!hwmgr || !hwmgr->pm_en) 1321 if (!hwmgr)
1307 return -EINVAL; 1322 return -EINVAL;
1308 1323
1309 if (hwmgr->hwmgr_func->enable_mgpu_fan_boost == NULL) { 1324 if (!hwmgr->pm_en ||
1325 hwmgr->hwmgr_func->enable_mgpu_fan_boost == NULL)
1310 return 0; 1326 return 0;
1311 }
1312 1327
1313 mutex_lock(&hwmgr->smu_lock); 1328 mutex_lock(&hwmgr->smu_lock);
1314 hwmgr->hwmgr_func->enable_mgpu_fan_boost(hwmgr); 1329 hwmgr->hwmgr_func->enable_mgpu_fan_boost(hwmgr);
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
index 6c99cbf51c08..ed35ec0341e6 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
@@ -3588,9 +3588,10 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons
3588 break; 3588 break;
3589 } 3589 }
3590 3590
3591 if (i >= sclk_table->count) 3591 if (i >= sclk_table->count) {
3592 data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; 3592 data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
3593 else { 3593 sclk_table->dpm_levels[i-1].value = sclk;
3594 } else {
3594 /* TODO: Check SCLK in DAL's minimum clocks 3595 /* TODO: Check SCLK in DAL's minimum clocks
3595 * in case DeepSleep divider update is required. 3596 * in case DeepSleep divider update is required.
3596 */ 3597 */
@@ -3605,9 +3606,10 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons
3605 break; 3606 break;
3606 } 3607 }
3607 3608
3608 if (i >= mclk_table->count) 3609 if (i >= mclk_table->count) {
3609 data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; 3610 data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
3610 3611 mclk_table->dpm_levels[i-1].value = mclk;
3612 }
3611 3613
3612 if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display) 3614 if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
3613 data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_MCLK; 3615 data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_MCLK;
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c
index 4714b5b59825..99a33c33a32c 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c
@@ -718,7 +718,7 @@ int smu_set_watermarks_for_clocks_ranges(void *wt_table,
718 table->WatermarkRow[1][i].MaxClock = 718 table->WatermarkRow[1][i].MaxClock =
719 cpu_to_le16((uint16_t) 719 cpu_to_le16((uint16_t)
720 (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz) / 720 (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz) /
721 100); 721 1000);
722 table->WatermarkRow[1][i].MinUclk = 722 table->WatermarkRow[1][i].MinUclk =
723 cpu_to_le16((uint16_t) 723 cpu_to_le16((uint16_t)
724 (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz) / 724 (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz) /
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
index 419a1d77d661..8c4db86bb4b7 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
@@ -1333,7 +1333,6 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
1333 if (hwmgr->platform_descriptor.overdriveLimit.memoryClock == 0) 1333 if (hwmgr->platform_descriptor.overdriveLimit.memoryClock == 0)
1334 hwmgr->platform_descriptor.overdriveLimit.memoryClock = 1334 hwmgr->platform_descriptor.overdriveLimit.memoryClock =
1335 dpm_table->dpm_levels[dpm_table->count-1].value; 1335 dpm_table->dpm_levels[dpm_table->count-1].value;
1336
1337 vega10_init_dpm_state(&(dpm_table->dpm_state)); 1336 vega10_init_dpm_state(&(dpm_table->dpm_state));
1338 1337
1339 data->dpm_table.eclk_table.count = 0; 1338 data->dpm_table.eclk_table.count = 0;
@@ -3249,6 +3248,37 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
3249static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input) 3248static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input)
3250{ 3249{
3251 struct vega10_hwmgr *data = hwmgr->backend; 3250 struct vega10_hwmgr *data = hwmgr->backend;
3251 const struct phm_set_power_state_input *states =
3252 (const struct phm_set_power_state_input *)input;
3253 const struct vega10_power_state *vega10_ps =
3254 cast_const_phw_vega10_power_state(states->pnew_state);
3255 struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
3256 uint32_t sclk = vega10_ps->performance_levels
3257 [vega10_ps->performance_level_count - 1].gfx_clock;
3258 struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
3259 uint32_t mclk = vega10_ps->performance_levels
3260 [vega10_ps->performance_level_count - 1].mem_clock;
3261 uint32_t i;
3262
3263 for (i = 0; i < sclk_table->count; i++) {
3264 if (sclk == sclk_table->dpm_levels[i].value)
3265 break;
3266 }
3267
3268 if (i >= sclk_table->count) {
3269 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
3270 sclk_table->dpm_levels[i-1].value = sclk;
3271 }
3272
3273 for (i = 0; i < mclk_table->count; i++) {
3274 if (mclk == mclk_table->dpm_levels[i].value)
3275 break;
3276 }
3277
3278 if (i >= mclk_table->count) {
3279 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
3280 mclk_table->dpm_levels[i-1].value = mclk;
3281 }
3252 3282
3253 if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display) 3283 if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
3254 data->need_update_dpm_table |= DPMTABLE_UPDATE_MCLK; 3284 data->need_update_dpm_table |= DPMTABLE_UPDATE_MCLK;
@@ -4529,11 +4559,13 @@ static int vega10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
4529 4559
4530 if (vega10_ps->performance_levels 4560 if (vega10_ps->performance_levels
4531 [vega10_ps->performance_level_count - 1].gfx_clock > 4561 [vega10_ps->performance_level_count - 1].gfx_clock >
4532 hwmgr->platform_descriptor.overdriveLimit.engineClock) 4562 hwmgr->platform_descriptor.overdriveLimit.engineClock) {
4533 vega10_ps->performance_levels 4563 vega10_ps->performance_levels
4534 [vega10_ps->performance_level_count - 1].gfx_clock = 4564 [vega10_ps->performance_level_count - 1].gfx_clock =
4535 hwmgr->platform_descriptor.overdriveLimit.engineClock; 4565 hwmgr->platform_descriptor.overdriveLimit.engineClock;
4536 4566 pr_warn("max sclk supported by vbios is %d\n",
4567 hwmgr->platform_descriptor.overdriveLimit.engineClock);
4568 }
4537 return 0; 4569 return 0;
4538} 4570}
4539 4571
@@ -4581,10 +4613,13 @@ static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
4581 4613
4582 if (vega10_ps->performance_levels 4614 if (vega10_ps->performance_levels
4583 [vega10_ps->performance_level_count - 1].mem_clock > 4615 [vega10_ps->performance_level_count - 1].mem_clock >
4584 hwmgr->platform_descriptor.overdriveLimit.memoryClock) 4616 hwmgr->platform_descriptor.overdriveLimit.memoryClock) {
4585 vega10_ps->performance_levels 4617 vega10_ps->performance_levels
4586 [vega10_ps->performance_level_count - 1].mem_clock = 4618 [vega10_ps->performance_level_count - 1].mem_clock =
4587 hwmgr->platform_descriptor.overdriveLimit.memoryClock; 4619 hwmgr->platform_descriptor.overdriveLimit.memoryClock;
4620 pr_warn("max mclk supported by vbios is %d\n",
4621 hwmgr->platform_descriptor.overdriveLimit.memoryClock);
4622 }
4588 4623
4589 return 0; 4624 return 0;
4590} 4625}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
index 9600e2f226e9..74bc37308dc0 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
@@ -2356,6 +2356,13 @@ static int vega12_gfx_off_control(struct pp_hwmgr *hwmgr, bool enable)
2356 return vega12_disable_gfx_off(hwmgr); 2356 return vega12_disable_gfx_off(hwmgr);
2357} 2357}
2358 2358
2359static int vega12_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state,
2360 PHM_PerformanceLevelDesignation designation, uint32_t index,
2361 PHM_PerformanceLevel *level)
2362{
2363 return 0;
2364}
2365
2359static const struct pp_hwmgr_func vega12_hwmgr_funcs = { 2366static const struct pp_hwmgr_func vega12_hwmgr_funcs = {
2360 .backend_init = vega12_hwmgr_backend_init, 2367 .backend_init = vega12_hwmgr_backend_init,
2361 .backend_fini = vega12_hwmgr_backend_fini, 2368 .backend_fini = vega12_hwmgr_backend_fini,
@@ -2406,6 +2413,7 @@ static const struct pp_hwmgr_func vega12_hwmgr_funcs = {
2406 .register_irq_handlers = smu9_register_irq_handlers, 2413 .register_irq_handlers = smu9_register_irq_handlers,
2407 .start_thermal_controller = vega12_start_thermal_controller, 2414 .start_thermal_controller = vega12_start_thermal_controller,
2408 .powergate_gfx = vega12_gfx_off_control, 2415 .powergate_gfx = vega12_gfx_off_control,
2416 .get_performance_level = vega12_get_performance_level,
2409}; 2417};
2410 2418
2411int vega12_hwmgr_init(struct pp_hwmgr *hwmgr) 2419int vega12_hwmgr_init(struct pp_hwmgr *hwmgr)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
index b4dbbb7c334c..57143d51e3ee 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
@@ -1875,38 +1875,20 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr,
1875 return ret; 1875 return ret;
1876} 1876}
1877 1877
1878static int vega20_get_current_gfx_clk_freq(struct pp_hwmgr *hwmgr, uint32_t *gfx_freq) 1878static int vega20_get_current_clk_freq(struct pp_hwmgr *hwmgr,
1879 PPCLK_e clk_id, uint32_t *clk_freq)
1879{ 1880{
1880 uint32_t gfx_clk = 0;
1881 int ret = 0; 1881 int ret = 0;
1882 1882
1883 *gfx_freq = 0; 1883 *clk_freq = 0;
1884 1884
1885 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr, 1885 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
1886 PPSMC_MSG_GetDpmClockFreq, (PPCLK_GFXCLK << 16))) == 0, 1886 PPSMC_MSG_GetDpmClockFreq, (clk_id << 16))) == 0,
1887 "[GetCurrentGfxClkFreq] Attempt to get Current GFXCLK Frequency Failed!", 1887 "[GetCurrentClkFreq] Attempt to get Current Frequency Failed!",
1888 return ret); 1888 return ret);
1889 gfx_clk = smum_get_argument(hwmgr); 1889 *clk_freq = smum_get_argument(hwmgr);
1890 1890
1891 *gfx_freq = gfx_clk * 100; 1891 *clk_freq = *clk_freq * 100;
1892
1893 return 0;
1894}
1895
1896static int vega20_get_current_mclk_freq(struct pp_hwmgr *hwmgr, uint32_t *mclk_freq)
1897{
1898 uint32_t mem_clk = 0;
1899 int ret = 0;
1900
1901 *mclk_freq = 0;
1902
1903 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
1904 PPSMC_MSG_GetDpmClockFreq, (PPCLK_UCLK << 16))) == 0,
1905 "[GetCurrentMClkFreq] Attempt to get Current MCLK Frequency Failed!",
1906 return ret);
1907 mem_clk = smum_get_argument(hwmgr);
1908
1909 *mclk_freq = mem_clk * 100;
1910 1892
1911 return 0; 1893 return 0;
1912} 1894}
@@ -1937,12 +1919,16 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx,
1937 1919
1938 switch (idx) { 1920 switch (idx) {
1939 case AMDGPU_PP_SENSOR_GFX_SCLK: 1921 case AMDGPU_PP_SENSOR_GFX_SCLK:
1940 ret = vega20_get_current_gfx_clk_freq(hwmgr, (uint32_t *)value); 1922 ret = vega20_get_current_clk_freq(hwmgr,
1923 PPCLK_GFXCLK,
1924 (uint32_t *)value);
1941 if (!ret) 1925 if (!ret)
1942 *size = 4; 1926 *size = 4;
1943 break; 1927 break;
1944 case AMDGPU_PP_SENSOR_GFX_MCLK: 1928 case AMDGPU_PP_SENSOR_GFX_MCLK:
1945 ret = vega20_get_current_mclk_freq(hwmgr, (uint32_t *)value); 1929 ret = vega20_get_current_clk_freq(hwmgr,
1930 PPCLK_UCLK,
1931 (uint32_t *)value);
1946 if (!ret) 1932 if (!ret)
1947 *size = 4; 1933 *size = 4;
1948 break; 1934 break;
@@ -2012,7 +1998,6 @@ int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
2012 if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) { 1998 if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) {
2013 switch (clk_type) { 1999 switch (clk_type) {
2014 case amd_pp_dcef_clock: 2000 case amd_pp_dcef_clock:
2015 clk_freq = clock_req->clock_freq_in_khz / 100;
2016 clk_select = PPCLK_DCEFCLK; 2001 clk_select = PPCLK_DCEFCLK;
2017 break; 2002 break;
2018 case amd_pp_disp_clock: 2003 case amd_pp_disp_clock:
@@ -2041,11 +2026,20 @@ int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
2041 return result; 2026 return result;
2042} 2027}
2043 2028
2029static int vega20_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state,
2030 PHM_PerformanceLevelDesignation designation, uint32_t index,
2031 PHM_PerformanceLevel *level)
2032{
2033 return 0;
2034}
2035
2044static int vega20_notify_smc_display_config_after_ps_adjustment( 2036static int vega20_notify_smc_display_config_after_ps_adjustment(
2045 struct pp_hwmgr *hwmgr) 2037 struct pp_hwmgr *hwmgr)
2046{ 2038{
2047 struct vega20_hwmgr *data = 2039 struct vega20_hwmgr *data =
2048 (struct vega20_hwmgr *)(hwmgr->backend); 2040 (struct vega20_hwmgr *)(hwmgr->backend);
2041 struct vega20_single_dpm_table *dpm_table =
2042 &data->dpm_table.mem_table;
2049 struct PP_Clocks min_clocks = {0}; 2043 struct PP_Clocks min_clocks = {0};
2050 struct pp_display_clock_request clock_req; 2044 struct pp_display_clock_request clock_req;
2051 int ret = 0; 2045 int ret = 0;
@@ -2063,7 +2057,7 @@ static int vega20_notify_smc_display_config_after_ps_adjustment(
2063 2057
2064 if (data->smu_features[GNLD_DPM_DCEFCLK].supported) { 2058 if (data->smu_features[GNLD_DPM_DCEFCLK].supported) {
2065 clock_req.clock_type = amd_pp_dcef_clock; 2059 clock_req.clock_type = amd_pp_dcef_clock;
2066 clock_req.clock_freq_in_khz = min_clocks.dcefClock; 2060 clock_req.clock_freq_in_khz = min_clocks.dcefClock * 10;
2067 if (!vega20_display_clock_voltage_request(hwmgr, &clock_req)) { 2061 if (!vega20_display_clock_voltage_request(hwmgr, &clock_req)) {
2068 if (data->smu_features[GNLD_DS_DCEFCLK].supported) 2062 if (data->smu_features[GNLD_DS_DCEFCLK].supported)
2069 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter( 2063 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(
@@ -2076,6 +2070,15 @@ static int vega20_notify_smc_display_config_after_ps_adjustment(
2076 } 2070 }
2077 } 2071 }
2078 2072
2073 if (data->smu_features[GNLD_DPM_UCLK].enabled) {
2074 dpm_table->dpm_state.hard_min_level = min_clocks.memoryClock / 100;
2075 PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr,
2076 PPSMC_MSG_SetHardMinByFreq,
2077 (PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level)),
2078 "[SetHardMinFreq] Set hard min uclk failed!",
2079 return ret);
2080 }
2081
2079 return 0; 2082 return 0;
2080} 2083}
2081 2084
@@ -2353,7 +2356,7 @@ static int vega20_get_sclks(struct pp_hwmgr *hwmgr,
2353 2356
2354 for (i = 0; i < count; i++) { 2357 for (i = 0; i < count; i++) {
2355 clocks->data[i].clocks_in_khz = 2358 clocks->data[i].clocks_in_khz =
2356 dpm_table->dpm_levels[i].value * 100; 2359 dpm_table->dpm_levels[i].value * 1000;
2357 clocks->data[i].latency_in_us = 0; 2360 clocks->data[i].latency_in_us = 0;
2358 } 2361 }
2359 2362
@@ -2383,7 +2386,7 @@ static int vega20_get_memclocks(struct pp_hwmgr *hwmgr,
2383 for (i = 0; i < count; i++) { 2386 for (i = 0; i < count; i++) {
2384 clocks->data[i].clocks_in_khz = 2387 clocks->data[i].clocks_in_khz =
2385 data->mclk_latency_table.entries[i].frequency = 2388 data->mclk_latency_table.entries[i].frequency =
2386 dpm_table->dpm_levels[i].value * 100; 2389 dpm_table->dpm_levels[i].value * 1000;
2387 clocks->data[i].latency_in_us = 2390 clocks->data[i].latency_in_us =
2388 data->mclk_latency_table.entries[i].latency = 2391 data->mclk_latency_table.entries[i].latency =
2389 vega20_get_mem_latency(hwmgr, dpm_table->dpm_levels[i].value); 2392 vega20_get_mem_latency(hwmgr, dpm_table->dpm_levels[i].value);
@@ -2408,7 +2411,7 @@ static int vega20_get_dcefclocks(struct pp_hwmgr *hwmgr,
2408 2411
2409 for (i = 0; i < count; i++) { 2412 for (i = 0; i < count; i++) {
2410 clocks->data[i].clocks_in_khz = 2413 clocks->data[i].clocks_in_khz =
2411 dpm_table->dpm_levels[i].value * 100; 2414 dpm_table->dpm_levels[i].value * 1000;
2412 clocks->data[i].latency_in_us = 0; 2415 clocks->data[i].latency_in_us = 0;
2413 } 2416 }
2414 2417
@@ -2431,7 +2434,7 @@ static int vega20_get_socclocks(struct pp_hwmgr *hwmgr,
2431 2434
2432 for (i = 0; i < count; i++) { 2435 for (i = 0; i < count; i++) {
2433 clocks->data[i].clocks_in_khz = 2436 clocks->data[i].clocks_in_khz =
2434 dpm_table->dpm_levels[i].value * 100; 2437 dpm_table->dpm_levels[i].value * 1000;
2435 clocks->data[i].latency_in_us = 0; 2438 clocks->data[i].latency_in_us = 0;
2436 } 2439 }
2437 2440
@@ -2582,11 +2585,11 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
2582 return -EINVAL; 2585 return -EINVAL;
2583 } 2586 }
2584 2587
2585 if (input_clk < clocks.data[0].clocks_in_khz / 100 || 2588 if (input_clk < clocks.data[0].clocks_in_khz / 1000 ||
2586 input_clk > od8_settings[OD8_SETTING_UCLK_FMAX].max_value) { 2589 input_clk > od8_settings[OD8_SETTING_UCLK_FMAX].max_value) {
2587 pr_info("clock freq %d is not within allowed range [%d - %d]\n", 2590 pr_info("clock freq %d is not within allowed range [%d - %d]\n",
2588 input_clk, 2591 input_clk,
2589 clocks.data[0].clocks_in_khz / 100, 2592 clocks.data[0].clocks_in_khz / 1000,
2590 od8_settings[OD8_SETTING_UCLK_FMAX].max_value); 2593 od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
2591 return -EINVAL; 2594 return -EINVAL;
2592 } 2595 }
@@ -2726,7 +2729,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
2726 2729
2727 switch (type) { 2730 switch (type) {
2728 case PP_SCLK: 2731 case PP_SCLK:
2729 ret = vega20_get_current_gfx_clk_freq(hwmgr, &now); 2732 ret = vega20_get_current_clk_freq(hwmgr, PPCLK_GFXCLK, &now);
2730 PP_ASSERT_WITH_CODE(!ret, 2733 PP_ASSERT_WITH_CODE(!ret,
2731 "Attempt to get current gfx clk Failed!", 2734 "Attempt to get current gfx clk Failed!",
2732 return ret); 2735 return ret);
@@ -2738,12 +2741,12 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
2738 2741
2739 for (i = 0; i < clocks.num_levels; i++) 2742 for (i = 0; i < clocks.num_levels; i++)
2740 size += sprintf(buf + size, "%d: %uMhz %s\n", 2743 size += sprintf(buf + size, "%d: %uMhz %s\n",
2741 i, clocks.data[i].clocks_in_khz / 100, 2744 i, clocks.data[i].clocks_in_khz / 1000,
2742 (clocks.data[i].clocks_in_khz == now) ? "*" : ""); 2745 (clocks.data[i].clocks_in_khz == now) ? "*" : "");
2743 break; 2746 break;
2744 2747
2745 case PP_MCLK: 2748 case PP_MCLK:
2746 ret = vega20_get_current_mclk_freq(hwmgr, &now); 2749 ret = vega20_get_current_clk_freq(hwmgr, PPCLK_UCLK, &now);
2747 PP_ASSERT_WITH_CODE(!ret, 2750 PP_ASSERT_WITH_CODE(!ret,
2748 "Attempt to get current mclk freq Failed!", 2751 "Attempt to get current mclk freq Failed!",
2749 return ret); 2752 return ret);
@@ -2755,7 +2758,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
2755 2758
2756 for (i = 0; i < clocks.num_levels; i++) 2759 for (i = 0; i < clocks.num_levels; i++)
2757 size += sprintf(buf + size, "%d: %uMhz %s\n", 2760 size += sprintf(buf + size, "%d: %uMhz %s\n",
2758 i, clocks.data[i].clocks_in_khz / 100, 2761 i, clocks.data[i].clocks_in_khz / 1000,
2759 (clocks.data[i].clocks_in_khz == now) ? "*" : ""); 2762 (clocks.data[i].clocks_in_khz == now) ? "*" : "");
2760 break; 2763 break;
2761 2764
@@ -2820,7 +2823,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
2820 return ret); 2823 return ret);
2821 2824
2822 size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n", 2825 size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n",
2823 clocks.data[0].clocks_in_khz / 100, 2826 clocks.data[0].clocks_in_khz / 1000,
2824 od8_settings[OD8_SETTING_UCLK_FMAX].max_value); 2827 od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
2825 } 2828 }
2826 2829
@@ -3476,6 +3479,8 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
3476 vega20_set_watermarks_for_clocks_ranges, 3479 vega20_set_watermarks_for_clocks_ranges,
3477 .display_clock_voltage_request = 3480 .display_clock_voltage_request =
3478 vega20_display_clock_voltage_request, 3481 vega20_display_clock_voltage_request,
3482 .get_performance_level =
3483 vega20_get_performance_level,
3479 /* UMD pstate, profile related */ 3484 /* UMD pstate, profile related */
3480 .force_dpm_level = 3485 .force_dpm_level =
3481 vega20_dpm_force_dpm_level, 3486 vega20_dpm_force_dpm_level,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c
index e5f7f8230065..97f8a1a970c3 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c
@@ -642,8 +642,14 @@ static int check_powerplay_tables(
642 "Unsupported PPTable format!", return -1); 642 "Unsupported PPTable format!", return -1);
643 PP_ASSERT_WITH_CODE(powerplay_table->sHeader.structuresize > 0, 643 PP_ASSERT_WITH_CODE(powerplay_table->sHeader.structuresize > 0,
644 "Invalid PowerPlay Table!", return -1); 644 "Invalid PowerPlay Table!", return -1);
645 PP_ASSERT_WITH_CODE(powerplay_table->smcPPTable.Version == PPTABLE_V20_SMU_VERSION, 645
646 "Unmatch PPTable version, vbios update may be needed!", return -1); 646 if (powerplay_table->smcPPTable.Version != PPTABLE_V20_SMU_VERSION) {
647 pr_info("Unmatch PPTable version: "
648 "pptable from VBIOS is V%d while driver supported is V%d!",
649 powerplay_table->smcPPTable.Version,
650 PPTABLE_V20_SMU_VERSION);
651 return -EINVAL;
652 }
647 653
648 //dump_pptable(&powerplay_table->smcPPTable); 654 //dump_pptable(&powerplay_table->smcPPTable);
649 655
@@ -716,10 +722,6 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable
716 "[appendVbiosPPTable] Failed to retrieve Smc Dpm Table from VBIOS!", 722 "[appendVbiosPPTable] Failed to retrieve Smc Dpm Table from VBIOS!",
717 return -1); 723 return -1);
718 724
719 memset(ppsmc_pptable->Padding32,
720 0,
721 sizeof(struct atom_smc_dpm_info_v4_4) -
722 sizeof(struct atom_common_table_header));
723 ppsmc_pptable->MaxVoltageStepGfx = smc_dpm_table->maxvoltagestepgfx; 725 ppsmc_pptable->MaxVoltageStepGfx = smc_dpm_table->maxvoltagestepgfx;
724 ppsmc_pptable->MaxVoltageStepSoc = smc_dpm_table->maxvoltagestepsoc; 726 ppsmc_pptable->MaxVoltageStepSoc = smc_dpm_table->maxvoltagestepsoc;
725 727
@@ -778,22 +780,19 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable
778 ppsmc_pptable->FllGfxclkSpreadPercent = smc_dpm_table->fllgfxclkspreadpercent; 780 ppsmc_pptable->FllGfxclkSpreadPercent = smc_dpm_table->fllgfxclkspreadpercent;
779 ppsmc_pptable->FllGfxclkSpreadFreq = smc_dpm_table->fllgfxclkspreadfreq; 781 ppsmc_pptable->FllGfxclkSpreadFreq = smc_dpm_table->fllgfxclkspreadfreq;
780 782
781 if ((smc_dpm_table->table_header.format_revision == 4) && 783 for (i = 0; i < I2C_CONTROLLER_NAME_COUNT; i++) {
782 (smc_dpm_table->table_header.content_revision == 4)) { 784 ppsmc_pptable->I2cControllers[i].Enabled =
783 for (i = 0; i < I2C_CONTROLLER_NAME_COUNT; i++) { 785 smc_dpm_table->i2ccontrollers[i].enabled;
784 ppsmc_pptable->I2cControllers[i].Enabled = 786 ppsmc_pptable->I2cControllers[i].SlaveAddress =
785 smc_dpm_table->i2ccontrollers[i].enabled; 787 smc_dpm_table->i2ccontrollers[i].slaveaddress;
786 ppsmc_pptable->I2cControllers[i].SlaveAddress = 788 ppsmc_pptable->I2cControllers[i].ControllerPort =
787 smc_dpm_table->i2ccontrollers[i].slaveaddress; 789 smc_dpm_table->i2ccontrollers[i].controllerport;
788 ppsmc_pptable->I2cControllers[i].ControllerPort = 790 ppsmc_pptable->I2cControllers[i].ThermalThrottler =
789 smc_dpm_table->i2ccontrollers[i].controllerport; 791 smc_dpm_table->i2ccontrollers[i].thermalthrottler;
790 ppsmc_pptable->I2cControllers[i].ThermalThrottler = 792 ppsmc_pptable->I2cControllers[i].I2cProtocol =
791 smc_dpm_table->i2ccontrollers[i].thermalthrottler; 793 smc_dpm_table->i2ccontrollers[i].i2cprotocol;
792 ppsmc_pptable->I2cControllers[i].I2cProtocol = 794 ppsmc_pptable->I2cControllers[i].I2cSpeed =
793 smc_dpm_table->i2ccontrollers[i].i2cprotocol; 795 smc_dpm_table->i2ccontrollers[i].i2cspeed;
794 ppsmc_pptable->I2cControllers[i].I2cSpeed =
795 smc_dpm_table->i2ccontrollers[i].i2cspeed;
796 }
797 } 796 }
798 797
799 return 0; 798 return 0;
@@ -882,15 +881,10 @@ static int init_powerplay_table_information(
882 if (pptable_information->smc_pptable == NULL) 881 if (pptable_information->smc_pptable == NULL)
883 return -ENOMEM; 882 return -ENOMEM;
884 883
885 if (powerplay_table->smcPPTable.Version <= 2) 884 memcpy(pptable_information->smc_pptable,
886 memcpy(pptable_information->smc_pptable, 885 &(powerplay_table->smcPPTable),
887 &(powerplay_table->smcPPTable), 886 sizeof(PPTable_t));
888 sizeof(PPTable_t) - 887
889 sizeof(I2cControllerConfig_t) * I2C_CONTROLLER_NAME_COUNT);
890 else
891 memcpy(pptable_information->smc_pptable,
892 &(powerplay_table->smcPPTable),
893 sizeof(PPTable_t));
894 888
895 result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable)); 889 result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable));
896 890
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h b/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h
index 2998a49960ed..63d5cf691549 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h
@@ -29,7 +29,7 @@
29// any structure is changed in this file 29// any structure is changed in this file
30#define SMU11_DRIVER_IF_VERSION 0x12 30#define SMU11_DRIVER_IF_VERSION 0x12
31 31
32#define PPTABLE_V20_SMU_VERSION 2 32#define PPTABLE_V20_SMU_VERSION 3
33 33
34#define NUM_GFXCLK_DPM_LEVELS 16 34#define NUM_GFXCLK_DPM_LEVELS 16
35#define NUM_VCLK_DPM_LEVELS 8 35#define NUM_VCLK_DPM_LEVELS 8
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c
index f836d30fdd44..09b844ec3eab 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c
@@ -71,7 +71,11 @@ static int smu8_send_msg_to_smc_async(struct pp_hwmgr *hwmgr, uint16_t msg)
71 result = PHM_WAIT_FIELD_UNEQUAL(hwmgr, 71 result = PHM_WAIT_FIELD_UNEQUAL(hwmgr,
72 SMU_MP1_SRBM2P_RESP_0, CONTENT, 0); 72 SMU_MP1_SRBM2P_RESP_0, CONTENT, 0);
73 if (result != 0) { 73 if (result != 0) {
74 /* Read the last message to SMU, to report actual cause */
75 uint32_t val = cgs_read_register(hwmgr->device,
76 mmSMU_MP1_SRBM2P_MSG_0);
74 pr_err("smu8_send_msg_to_smc_async (0x%04x) failed\n", msg); 77 pr_err("smu8_send_msg_to_smc_async (0x%04x) failed\n", msg);
78 pr_err("SMU still servicing msg (0x%04x)\n", val);
75 return result; 79 return result;
76 } 80 }
77 81
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
index f8a931cf3665..680566d97adc 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -458,18 +458,6 @@ static void ti_sn_bridge_enable(struct drm_bridge *bridge)
458 unsigned int val; 458 unsigned int val;
459 int ret; 459 int ret;
460 460
461 /*
462 * FIXME:
463 * This 70ms was found necessary by experimentation. If it's not
464 * present, link training fails. It seems like it can go anywhere from
465 * pre_enable() up to semi-auto link training initiation below.
466 *
467 * Neither the datasheet for the bridge nor the panel tested mention a
468 * delay of this magnitude in the timing requirements. So for now, add
469 * the mystery delay until someone figures out a better fix.
470 */
471 msleep(70);
472
473 /* DSI_A lane config */ 461 /* DSI_A lane config */
474 val = CHA_DSI_LANES(4 - pdata->dsi->lanes); 462 val = CHA_DSI_LANES(4 - pdata->dsi->lanes);
475 regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG, 463 regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG,
@@ -536,7 +524,22 @@ static void ti_sn_bridge_pre_enable(struct drm_bridge *bridge)
536 /* configure bridge ref_clk */ 524 /* configure bridge ref_clk */
537 ti_sn_bridge_set_refclk_freq(pdata); 525 ti_sn_bridge_set_refclk_freq(pdata);
538 526
539 /* in case drm_panel is connected then HPD is not supported */ 527 /*
528 * HPD on this bridge chip is a bit useless. This is an eDP bridge
529 * so the HPD is an internal signal that's only there to signal that
530 * the panel is done powering up. ...but the bridge chip debounces
531 * this signal by between 100 ms and 400 ms (depending on process,
532 * voltage, and temperate--I measured it at about 200 ms). One
533 * particular panel asserted HPD 84 ms after it was powered on meaning
534 * that we saw HPD 284 ms after power on. ...but the same panel said
535 * that instead of looking at HPD you could just hardcode a delay of
536 * 200 ms. We'll assume that the panel driver will have the hardcoded
537 * delay in its prepare and always disable HPD.
538 *
539 * If HPD somehow makes sense on some future panel we'll have to
540 * change this to be conditional on someone specifying that HPD should
541 * be used.
542 */
540 regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE, 543 regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE,
541 HPD_DISABLE); 544 HPD_DISABLE);
542 545
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 701cb334e1ea..d8b526b7932c 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -308,6 +308,26 @@ update_connector_routing(struct drm_atomic_state *state,
308 return 0; 308 return 0;
309 } 309 }
310 310
311 crtc_state = drm_atomic_get_new_crtc_state(state,
312 new_connector_state->crtc);
313 /*
314 * For compatibility with legacy users, we want to make sure that
315 * we allow DPMS On->Off modesets on unregistered connectors. Modesets
316 * which would result in anything else must be considered invalid, to
317 * avoid turning on new displays on dead connectors.
318 *
319 * Since the connector can be unregistered at any point during an
320 * atomic check or commit, this is racy. But that's OK: all we care
321 * about is ensuring that userspace can't do anything but shut off the
322 * display on a connector that was destroyed after its been notified,
323 * not before.
324 */
325 if (drm_connector_is_unregistered(connector) && crtc_state->active) {
326 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] is not registered\n",
327 connector->base.id, connector->name);
328 return -EINVAL;
329 }
330
311 funcs = connector->helper_private; 331 funcs = connector->helper_private;
312 332
313 if (funcs->atomic_best_encoder) 333 if (funcs->atomic_best_encoder)
@@ -352,7 +372,6 @@ update_connector_routing(struct drm_atomic_state *state,
352 372
353 set_best_encoder(state, new_connector_state, new_encoder); 373 set_best_encoder(state, new_connector_state, new_encoder);
354 374
355 crtc_state = drm_atomic_get_new_crtc_state(state, new_connector_state->crtc);
356 crtc_state->connectors_changed = true; 375 crtc_state->connectors_changed = true;
357 376
358 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d:%s]\n", 377 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d:%s]\n",
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 1e40e5decbe9..4943cef178be 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -379,7 +379,8 @@ void drm_connector_cleanup(struct drm_connector *connector)
379 /* The connector should have been removed from userspace long before 379 /* The connector should have been removed from userspace long before
380 * it is finally destroyed. 380 * it is finally destroyed.
381 */ 381 */
382 if (WARN_ON(connector->registered)) 382 if (WARN_ON(connector->registration_state ==
383 DRM_CONNECTOR_REGISTERED))
383 drm_connector_unregister(connector); 384 drm_connector_unregister(connector);
384 385
385 if (connector->tile_group) { 386 if (connector->tile_group) {
@@ -436,7 +437,7 @@ int drm_connector_register(struct drm_connector *connector)
436 return 0; 437 return 0;
437 438
438 mutex_lock(&connector->mutex); 439 mutex_lock(&connector->mutex);
439 if (connector->registered) 440 if (connector->registration_state != DRM_CONNECTOR_INITIALIZING)
440 goto unlock; 441 goto unlock;
441 442
442 ret = drm_sysfs_connector_add(connector); 443 ret = drm_sysfs_connector_add(connector);
@@ -456,7 +457,7 @@ int drm_connector_register(struct drm_connector *connector)
456 457
457 drm_mode_object_register(connector->dev, &connector->base); 458 drm_mode_object_register(connector->dev, &connector->base);
458 459
459 connector->registered = true; 460 connector->registration_state = DRM_CONNECTOR_REGISTERED;
460 goto unlock; 461 goto unlock;
461 462
462err_debugfs: 463err_debugfs:
@@ -478,7 +479,7 @@ EXPORT_SYMBOL(drm_connector_register);
478void drm_connector_unregister(struct drm_connector *connector) 479void drm_connector_unregister(struct drm_connector *connector)
479{ 480{
480 mutex_lock(&connector->mutex); 481 mutex_lock(&connector->mutex);
481 if (!connector->registered) { 482 if (connector->registration_state != DRM_CONNECTOR_REGISTERED) {
482 mutex_unlock(&connector->mutex); 483 mutex_unlock(&connector->mutex);
483 return; 484 return;
484 } 485 }
@@ -489,7 +490,7 @@ void drm_connector_unregister(struct drm_connector *connector)
489 drm_sysfs_connector_remove(connector); 490 drm_sysfs_connector_remove(connector);
490 drm_debugfs_connector_remove(connector); 491 drm_debugfs_connector_remove(connector);
491 492
492 connector->registered = false; 493 connector->registration_state = DRM_CONNECTOR_UNREGISTERED;
493 mutex_unlock(&connector->mutex); 494 mutex_unlock(&connector->mutex);
494} 495}
495EXPORT_SYMBOL(drm_connector_unregister); 496EXPORT_SYMBOL(drm_connector_unregister);
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index ff0bfc65a8c1..b506e3622b08 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -122,6 +122,9 @@ static const struct edid_quirk {
122 /* SDC panel of Lenovo B50-80 reports 8 bpc, but is a 6 bpc panel */ 122 /* SDC panel of Lenovo B50-80 reports 8 bpc, but is a 6 bpc panel */
123 { "SDC", 0x3652, EDID_QUIRK_FORCE_6BPC }, 123 { "SDC", 0x3652, EDID_QUIRK_FORCE_6BPC },
124 124
125 /* BOE model 0x0771 reports 8 bpc, but is a 6 bpc panel */
126 { "BOE", 0x0771, EDID_QUIRK_FORCE_6BPC },
127
125 /* Belinea 10 15 55 */ 128 /* Belinea 10 15 55 */
126 { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 }, 129 { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
127 { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 }, 130 { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 3fae4dab295f..13f9b56a9ce7 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5102,19 +5102,13 @@ intel_dp_long_pulse(struct intel_connector *connector,
5102 */ 5102 */
5103 status = connector_status_disconnected; 5103 status = connector_status_disconnected;
5104 goto out; 5104 goto out;
5105 } else { 5105 }
5106 /* 5106
5107 * If display is now connected check links status, 5107 /*
5108 * there has been known issues of link loss triggering 5108 * Some external monitors do not signal loss of link synchronization
5109 * long pulse. 5109 * with an IRQ_HPD, so force a link status check.
5110 * 5110 */
5111 * Some sinks (eg. ASUS PB287Q) seem to perform some 5111 if (!intel_dp_is_edp(intel_dp)) {
5112 * weird HPD ping pong during modesets. So we can apparently
5113 * end up with HPD going low during a modeset, and then
5114 * going back up soon after. And once that happens we must
5115 * retrain the link to get a picture. That's in case no
5116 * userspace component reacted to intermittent HPD dip.
5117 */
5118 struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; 5112 struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
5119 5113
5120 intel_dp_retrain_link(encoder, ctx); 5114 intel_dp_retrain_link(encoder, ctx);
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 7f155b4f1a7d..1b00f8ea145b 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -77,7 +77,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
77 pipe_config->pbn = mst_pbn; 77 pipe_config->pbn = mst_pbn;
78 78
79 /* Zombie connectors can't have VCPI slots */ 79 /* Zombie connectors can't have VCPI slots */
80 if (READ_ONCE(connector->registered)) { 80 if (!drm_connector_is_unregistered(connector)) {
81 slots = drm_dp_atomic_find_vcpi_slots(state, 81 slots = drm_dp_atomic_find_vcpi_slots(state,
82 &intel_dp->mst_mgr, 82 &intel_dp->mst_mgr,
83 port, 83 port,
@@ -313,7 +313,7 @@ static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
313 struct edid *edid; 313 struct edid *edid;
314 int ret; 314 int ret;
315 315
316 if (!READ_ONCE(connector->registered)) 316 if (drm_connector_is_unregistered(connector))
317 return intel_connector_update_modes(connector, NULL); 317 return intel_connector_update_modes(connector, NULL);
318 318
319 edid = drm_dp_mst_get_edid(connector, &intel_dp->mst_mgr, intel_connector->port); 319 edid = drm_dp_mst_get_edid(connector, &intel_dp->mst_mgr, intel_connector->port);
@@ -329,7 +329,7 @@ intel_dp_mst_detect(struct drm_connector *connector, bool force)
329 struct intel_connector *intel_connector = to_intel_connector(connector); 329 struct intel_connector *intel_connector = to_intel_connector(connector);
330 struct intel_dp *intel_dp = intel_connector->mst_port; 330 struct intel_dp *intel_dp = intel_connector->mst_port;
331 331
332 if (!READ_ONCE(connector->registered)) 332 if (drm_connector_is_unregistered(connector))
333 return connector_status_disconnected; 333 return connector_status_disconnected;
334 return drm_dp_mst_detect_port(connector, &intel_dp->mst_mgr, 334 return drm_dp_mst_detect_port(connector, &intel_dp->mst_mgr,
335 intel_connector->port); 335 intel_connector->port);
@@ -372,7 +372,7 @@ intel_dp_mst_mode_valid(struct drm_connector *connector,
372 int bpp = 24; /* MST uses fixed bpp */ 372 int bpp = 24; /* MST uses fixed bpp */
373 int max_rate, mode_rate, max_lanes, max_link_clock; 373 int max_rate, mode_rate, max_lanes, max_link_clock;
374 374
375 if (!READ_ONCE(connector->registered)) 375 if (drm_connector_is_unregistered(connector))
376 return MODE_ERROR; 376 return MODE_ERROR;
377 377
378 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 378 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 6bb78076b5b5..6cbbae3f438b 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -881,22 +881,16 @@ nv50_mstc_atomic_best_encoder(struct drm_connector *connector,
881{ 881{
882 struct nv50_head *head = nv50_head(connector_state->crtc); 882 struct nv50_head *head = nv50_head(connector_state->crtc);
883 struct nv50_mstc *mstc = nv50_mstc(connector); 883 struct nv50_mstc *mstc = nv50_mstc(connector);
884 if (mstc->port) { 884
885 struct nv50_mstm *mstm = mstc->mstm; 885 return &mstc->mstm->msto[head->base.index]->encoder;
886 return &mstm->msto[head->base.index]->encoder;
887 }
888 return NULL;
889} 886}
890 887
891static struct drm_encoder * 888static struct drm_encoder *
892nv50_mstc_best_encoder(struct drm_connector *connector) 889nv50_mstc_best_encoder(struct drm_connector *connector)
893{ 890{
894 struct nv50_mstc *mstc = nv50_mstc(connector); 891 struct nv50_mstc *mstc = nv50_mstc(connector);
895 if (mstc->port) { 892
896 struct nv50_mstm *mstm = mstc->mstm; 893 return &mstc->mstm->msto[0]->encoder;
897 return &mstm->msto[0]->encoder;
898 }
899 return NULL;
900} 894}
901 895
902static enum drm_mode_status 896static enum drm_mode_status
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 97964f7f2ace..a04ffb3b2174 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -56,6 +56,8 @@ struct panel_desc {
56 /** 56 /**
57 * @prepare: the time (in milliseconds) that it takes for the panel to 57 * @prepare: the time (in milliseconds) that it takes for the panel to
58 * become ready and start receiving video data 58 * become ready and start receiving video data
59 * @hpd_absent_delay: Add this to the prepare delay if we know Hot
60 * Plug Detect isn't used.
59 * @enable: the time (in milliseconds) that it takes for the panel to 61 * @enable: the time (in milliseconds) that it takes for the panel to
60 * display the first valid frame after starting to receive 62 * display the first valid frame after starting to receive
61 * video data 63 * video data
@@ -66,6 +68,7 @@ struct panel_desc {
66 */ 68 */
67 struct { 69 struct {
68 unsigned int prepare; 70 unsigned int prepare;
71 unsigned int hpd_absent_delay;
69 unsigned int enable; 72 unsigned int enable;
70 unsigned int disable; 73 unsigned int disable;
71 unsigned int unprepare; 74 unsigned int unprepare;
@@ -79,6 +82,7 @@ struct panel_simple {
79 struct drm_panel base; 82 struct drm_panel base;
80 bool prepared; 83 bool prepared;
81 bool enabled; 84 bool enabled;
85 bool no_hpd;
82 86
83 const struct panel_desc *desc; 87 const struct panel_desc *desc;
84 88
@@ -202,6 +206,7 @@ static int panel_simple_unprepare(struct drm_panel *panel)
202static int panel_simple_prepare(struct drm_panel *panel) 206static int panel_simple_prepare(struct drm_panel *panel)
203{ 207{
204 struct panel_simple *p = to_panel_simple(panel); 208 struct panel_simple *p = to_panel_simple(panel);
209 unsigned int delay;
205 int err; 210 int err;
206 211
207 if (p->prepared) 212 if (p->prepared)
@@ -215,8 +220,11 @@ static int panel_simple_prepare(struct drm_panel *panel)
215 220
216 gpiod_set_value_cansleep(p->enable_gpio, 1); 221 gpiod_set_value_cansleep(p->enable_gpio, 1);
217 222
218 if (p->desc->delay.prepare) 223 delay = p->desc->delay.prepare;
219 msleep(p->desc->delay.prepare); 224 if (p->no_hpd)
225 delay += p->desc->delay.hpd_absent_delay;
226 if (delay)
227 msleep(delay);
220 228
221 p->prepared = true; 229 p->prepared = true;
222 230
@@ -305,6 +313,8 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
305 panel->prepared = false; 313 panel->prepared = false;
306 panel->desc = desc; 314 panel->desc = desc;
307 315
316 panel->no_hpd = of_property_read_bool(dev->of_node, "no-hpd");
317
308 panel->supply = devm_regulator_get(dev, "power"); 318 panel->supply = devm_regulator_get(dev, "power");
309 if (IS_ERR(panel->supply)) 319 if (IS_ERR(panel->supply))
310 return PTR_ERR(panel->supply); 320 return PTR_ERR(panel->supply);
@@ -1363,7 +1373,7 @@ static const struct panel_desc innolux_n156bge_l21 = {
1363 }, 1373 },
1364}; 1374};
1365 1375
1366static const struct drm_display_mode innolux_tv123wam_mode = { 1376static const struct drm_display_mode innolux_p120zdg_bf1_mode = {
1367 .clock = 206016, 1377 .clock = 206016,
1368 .hdisplay = 2160, 1378 .hdisplay = 2160,
1369 .hsync_start = 2160 + 48, 1379 .hsync_start = 2160 + 48,
@@ -1377,15 +1387,16 @@ static const struct drm_display_mode innolux_tv123wam_mode = {
1377 .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, 1387 .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
1378}; 1388};
1379 1389
1380static const struct panel_desc innolux_tv123wam = { 1390static const struct panel_desc innolux_p120zdg_bf1 = {
1381 .modes = &innolux_tv123wam_mode, 1391 .modes = &innolux_p120zdg_bf1_mode,
1382 .num_modes = 1, 1392 .num_modes = 1,
1383 .bpc = 8, 1393 .bpc = 8,
1384 .size = { 1394 .size = {
1385 .width = 259, 1395 .width = 254,
1386 .height = 173, 1396 .height = 169,
1387 }, 1397 },
1388 .delay = { 1398 .delay = {
1399 .hpd_absent_delay = 200,
1389 .unprepare = 500, 1400 .unprepare = 500,
1390 }, 1401 },
1391}; 1402};
@@ -2445,8 +2456,8 @@ static const struct of_device_id platform_of_match[] = {
2445 .compatible = "innolux,n156bge-l21", 2456 .compatible = "innolux,n156bge-l21",
2446 .data = &innolux_n156bge_l21, 2457 .data = &innolux_n156bge_l21,
2447 }, { 2458 }, {
2448 .compatible = "innolux,tv123wam", 2459 .compatible = "innolux,p120zdg-bf1",
2449 .data = &innolux_tv123wam, 2460 .data = &innolux_p120zdg_bf1,
2450 }, { 2461 }, {
2451 .compatible = "innolux,zj070na-01p", 2462 .compatible = "innolux,zj070na-01p",
2452 .data = &innolux_zj070na_01p, 2463 .data = &innolux_zj070na_01p,
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 91a877fa00cb..9ccad6b062f2 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -82,6 +82,53 @@ enum drm_connector_status {
82 connector_status_unknown = 3, 82 connector_status_unknown = 3,
83}; 83};
84 84
85/**
86 * enum drm_connector_registration_status - userspace registration status for
87 * a &drm_connector
88 *
89 * This enum is used to track the status of initializing a connector and
90 * registering it with userspace, so that DRM can prevent bogus modesets on
91 * connectors that no longer exist.
92 */
93enum drm_connector_registration_state {
94 /**
95 * @DRM_CONNECTOR_INITIALIZING: The connector has just been created,
96 * but has yet to be exposed to userspace. There should be no
97 * additional restrictions to how the state of this connector may be
98 * modified.
99 */
100 DRM_CONNECTOR_INITIALIZING = 0,
101
102 /**
103 * @DRM_CONNECTOR_REGISTERED: The connector has been fully initialized
104 * and registered with sysfs, as such it has been exposed to
105 * userspace. There should be no additional restrictions to how the
106 * state of this connector may be modified.
107 */
108 DRM_CONNECTOR_REGISTERED = 1,
109
110 /**
111 * @DRM_CONNECTOR_UNREGISTERED: The connector has either been exposed
112 * to userspace and has since been unregistered and removed from
113 * userspace, or the connector was unregistered before it had a chance
114 * to be exposed to userspace (e.g. still in the
115 * @DRM_CONNECTOR_INITIALIZING state). When a connector is
116 * unregistered, there are additional restrictions to how its state
117 * may be modified:
118 *
119 * - An unregistered connector may only have its DPMS changed from
120 * On->Off. Once DPMS is changed to Off, it may not be switched back
121 * to On.
122 * - Modesets are not allowed on unregistered connectors, unless they
123 * would result in disabling its assigned CRTCs. This means
124 * disabling a CRTC on an unregistered connector is OK, but enabling
125 * one is not.
126 * - Removing a CRTC from an unregistered connector is OK, but new
127 * CRTCs may never be assigned to an unregistered connector.
128 */
129 DRM_CONNECTOR_UNREGISTERED = 2,
130};
131
85enum subpixel_order { 132enum subpixel_order {
86 SubPixelUnknown = 0, 133 SubPixelUnknown = 0,
87 SubPixelHorizontalRGB, 134 SubPixelHorizontalRGB,
@@ -853,10 +900,12 @@ struct drm_connector {
853 bool ycbcr_420_allowed; 900 bool ycbcr_420_allowed;
854 901
855 /** 902 /**
856 * @registered: Is this connector exposed (registered) with userspace? 903 * @registration_state: Is this connector initializing, exposed
904 * (registered) with userspace, or unregistered?
905 *
857 * Protected by @mutex. 906 * Protected by @mutex.
858 */ 907 */
859 bool registered; 908 enum drm_connector_registration_state registration_state;
860 909
861 /** 910 /**
862 * @modes: 911 * @modes:
@@ -1166,6 +1215,24 @@ static inline void drm_connector_unreference(struct drm_connector *connector)
1166 drm_connector_put(connector); 1215 drm_connector_put(connector);
1167} 1216}
1168 1217
1218/**
1219 * drm_connector_is_unregistered - has the connector been unregistered from
1220 * userspace?
1221 * @connector: DRM connector
1222 *
1223 * Checks whether or not @connector has been unregistered from userspace.
1224 *
1225 * Returns:
1226 * True if the connector was unregistered, false if the connector is
1227 * registered or has not yet been registered with userspace.
1228 */
1229static inline bool
1230drm_connector_is_unregistered(struct drm_connector *connector)
1231{
1232 return READ_ONCE(connector->registration_state) ==
1233 DRM_CONNECTOR_UNREGISTERED;
1234}
1235
1169const char *drm_get_connector_status_name(enum drm_connector_status status); 1236const char *drm_get_connector_status_name(enum drm_connector_status status);
1170const char *drm_get_subpixel_order_name(enum subpixel_order order); 1237const char *drm_get_subpixel_order_name(enum subpixel_order order);
1171const char *drm_get_dpms_name(int val); 1238const char *drm_get_dpms_name(int val);