Merge tag 'drm-intel-next-fixes-2018-10-25' of git://anongit.freedesktop.org/drm...
authorDave Airlie <airlied@redhat.com>
Fri, 2 Nov 2018 05:17:56 +0000 (15:17 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 2 Nov 2018 05:17:57 +0000 (15:17 +1000)
- Fix to avoid link retraining workaround on eDP (the other is a comment change)

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181025131836.GA2296@jlahtine-desk.ger.corp.intel.com
26 files changed:
Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.txt [moved from Documentation/devicetree/bindings/display/panel/innolux,tv123wam.txt with 70% similarity]
Documentation/devicetree/bindings/display/panel/simple-panel.txt
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
drivers/gpu/drm/amd/powerplay/amd_powerplay.c
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c
drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h
drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c
drivers/gpu/drm/bridge/ti-sn65dsi86.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/panel/panel-simple.c

similarity index 70%
rename from Documentation/devicetree/bindings/display/panel/innolux,tv123wam.txt
rename to Documentation/devicetree/bindings/display/panel/innolux,p120zdg-bf1.txt
index a9b35265fa13a48e938348abc2054990713971ef..513f03466abac5d4f9aaebdc7a30b75486d96d67 100644 (file)
@@ -1,20 +1,22 @@
-Innolux TV123WAM 12.3 inch eDP 2K display panel
+Innolux P120ZDG-BF1 12.02 inch eDP 2K display panel
 
 This binding is compatible with the simple-panel binding, which is specified
 in simple-panel.txt in this directory.
 
 Required properties:
-- compatible: should be "innolux,tv123wam"
+- compatible: should be "innolux,p120zdg-bf1"
 - power-supply: regulator to provide the supply voltage
 
 Optional properties:
 - enable-gpios: GPIO pin to enable or disable the panel
 - backlight: phandle of the backlight device attached to the panel
+- no-hpd: If HPD isn't hooked up; add this property.
 
 Example:
        panel_edp: panel-edp {
-               compatible = "innolux,tv123wam";
+               compatible = "innolux,p120zdg-bf1";
                enable-gpios = <&msmgpio 31 GPIO_ACTIVE_LOW>;
                power-supply = <&pm8916_l2>;
                backlight = <&backlight>;
+               no-hpd;
        };
index 45a457ad38f0f078eed709424e1e237ebcfe420f..b2b872c710f24d69996eb3cb4922ba8dd3915a14 100644 (file)
@@ -11,6 +11,9 @@ Optional properties:
 - ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
 - enable-gpios: GPIO pin to enable or disable the panel
 - backlight: phandle of the backlight device attached to the panel
+- no-hpd: This panel is supposed to communicate that it's ready via HPD
+  (hot plug detect) signal, but the signal isn't hooked up so we should
+  hardcode the max delay from the panel spec when powering up the panel.
 
 Example:
 
index 297a5490ad8c0be64157364419ca6e2f5b1eab1a..0a4fba196b843e4fe27b48b94f478478d1281749 100644 (file)
@@ -135,7 +135,8 @@ static int acp_poweroff(struct generic_pm_domain *genpd)
         * 2. power off the acp tiles
         * 3. check and enter ulv state
         */
-               if (adev->powerplay.pp_funcs->set_powergating_by_smu)
+               if (adev->powerplay.pp_funcs &&
+                       adev->powerplay.pp_funcs->set_powergating_by_smu)
                        amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true);
        }
        return 0;
@@ -517,7 +518,8 @@ static int acp_set_powergating_state(void *handle,
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        bool enable = state == AMD_PG_STATE_GATE ? true : false;
 
-       if (adev->powerplay.pp_funcs->set_powergating_by_smu)
+       if (adev->powerplay.pp_funcs &&
+               adev->powerplay.pp_funcs->set_powergating_by_smu)
                amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, enable);
 
        return 0;
index 1e4dd09a50726646cf117a480ddabfa5f2aecc2c..30bc345d6fdf0d5827c2aa737d284da92787ea70 100644 (file)
@@ -1493,8 +1493,6 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
        }
 
        adev->powerplay.pp_feature = amdgpu_pp_feature_mask;
-       if (amdgpu_sriov_vf(adev))
-               adev->powerplay.pp_feature &= ~PP_GFXOFF_MASK;
 
        for (i = 0; i < adev->num_ip_blocks; i++) {
                if ((amdgpu_ip_block_mask & (1 << i)) == 0) {
@@ -1600,7 +1598,7 @@ static int amdgpu_device_fw_loading(struct amdgpu_device *adev)
                }
        }
 
-       if (adev->powerplay.pp_funcs->load_firmware) {
+       if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->load_firmware) {
                r = adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle);
                if (r) {
                        pr_err("firmware loading failed\n");
@@ -3341,7 +3339,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
 
                kthread_park(ring->sched.thread);
 
-               if (job && job->base.sched == &ring->sched)
+               if (job && job->base.sched != &ring->sched)
                        continue;
 
                drm_sched_hw_job_reset(&ring->sched, job ? &job->base : NULL);
index 28781414d71c85e4dc5657e7cbfb237a39f5a3c3..943dbf3c5da12ddb03439e3cc1ea002771e5ab14 100644 (file)
@@ -114,8 +114,8 @@ uint amdgpu_pg_mask = 0xffffffff;
 uint amdgpu_sdma_phase_quantum = 32;
 char *amdgpu_disable_cu = NULL;
 char *amdgpu_virtual_display = NULL;
-/* OverDrive(bit 14) disabled by default*/
-uint amdgpu_pp_feature_mask = 0xffffbfff;
+/* OverDrive(bit 14),gfxoff(bit 15),stutter mode(bit 17) disabled by default*/
+uint amdgpu_pp_feature_mask = 0xfffd3fff;
 int amdgpu_ngg = 0;
 int amdgpu_prim_buf_per_se = 0;
 int amdgpu_pos_buf_per_se = 0;
index 790fd5408ddff2dbb6aa349c988b40ebfaf82536..1a656b8657f736fa0385aba0c54c6548d72af819 100644 (file)
@@ -392,7 +392,7 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
        if (!(adev->powerplay.pp_feature & PP_GFXOFF_MASK))
                return;
 
-       if (!adev->powerplay.pp_funcs->set_powergating_by_smu)
+       if (!adev->powerplay.pp_funcs || !adev->powerplay.pp_funcs->set_powergating_by_smu)
                return;
 
 
index 94055a485e01300e5106fa261b6ce51b636360ab..59cc678de8c1570642afc2d488f63fbc179a1e99 100644 (file)
@@ -704,7 +704,10 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev,
                return ret;
 
        if (adev->powerplay.pp_funcs->force_clock_level)
-               amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask);
+               ret = amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask);
+
+       if (ret)
+               return -EINVAL;
 
        return count;
 }
@@ -737,7 +740,10 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev,
                return ret;
 
        if (adev->powerplay.pp_funcs->force_clock_level)
-               amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask);
+               ret = amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask);
+
+       if (ret)
+               return -EINVAL;
 
        return count;
 }
@@ -770,7 +776,10 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev,
                return ret;
 
        if (adev->powerplay.pp_funcs->force_clock_level)
-               amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask);
+               ret = amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask);
+
+       if (ret)
+               return -EINVAL;
 
        return count;
 }
index 6904d794d60a7a5c06057f74cf930db06a01e195..352b304090602e342ef6f584acab90edf126f51a 100644 (file)
@@ -542,7 +542,8 @@ static void amdgpu_vm_pt_next_leaf(struct amdgpu_device *adev,
                                   struct amdgpu_vm_pt_cursor *cursor)
 {
        amdgpu_vm_pt_next(adev, cursor);
-       while (amdgpu_vm_pt_descendant(adev, cursor));
+       if (cursor->pfn != ~0ll)
+               while (amdgpu_vm_pt_descendant(adev, cursor));
 }
 
 /**
@@ -3234,8 +3235,10 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
        }
        rbtree_postorder_for_each_entry_safe(mapping, tmp,
                                             &vm->va.rb_root, rb) {
+               /* Don't remove the mapping here, we don't want to trigger a
+                * rebalance and the tree is about to be destroyed anyway.
+                */
                list_del(&mapping->list);
-               amdgpu_vm_it_remove(mapping, &vm->va);
                kfree(mapping);
        }
        list_for_each_entry_safe(mapping, tmp, &vm->freed, list) {
index 3d0f277a6523f80a4e2ee7e66c94c494b94448bc..617b0c8908a375aa0d132af1868f3eaf9e2067b1 100644 (file)
@@ -4815,8 +4815,10 @@ static int gfx_v8_0_kcq_resume(struct amdgpu_device *adev)
        if (r)
                goto done;
 
-       /* Test KCQs */
-       for (i = 0; i < adev->gfx.num_compute_rings; i++) {
+       /* Test KCQs - reversing the order of rings seems to fix ring test failure
+        * after GPU reset
+        */
+       for (i = adev->gfx.num_compute_rings - 1; i >= 0; i--) {
                ring = &adev->gfx.compute_ring[i];
                ring->ready = true;
                r = amdgpu_ring_test_ring(ring);
index 14649f8475f3f68cfe9ebd2a816864cae1318e0f..fd23ba1226a57d9d3f1189db15f07daaab7e199d 100644 (file)
@@ -280,7 +280,7 @@ void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev,
                return;
 
        if (enable && adev->pg_flags & AMD_PG_SUPPORT_MMHUB) {
-               if (adev->powerplay.pp_funcs->set_powergating_by_smu)
+               if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->set_powergating_by_smu)
                        amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GMC, true);
 
        }
index 04fa3d972636bb9878191ec9789f36a9684f6b04..7a8c9172d30a946fd91d147f8c73267a51b1fb08 100644 (file)
@@ -1366,7 +1366,8 @@ static int sdma_v4_0_hw_init(void *handle)
        int r;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs->set_powergating_by_smu)
+       if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs &&
+                       adev->powerplay.pp_funcs->set_powergating_by_smu)
                amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false);
 
        sdma_v4_0_init_golden_registers(adev);
@@ -1386,7 +1387,8 @@ static int sdma_v4_0_hw_fini(void *handle)
        sdma_v4_0_ctx_switch_enable(adev, false);
        sdma_v4_0_enable(adev, false);
 
-       if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs->set_powergating_by_smu)
+       if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs
+                       && adev->powerplay.pp_funcs->set_powergating_by_smu)
                amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, true);
 
        return 0;
index e224f23e22155918a742bbd13e45131edc9463b0..b0df6dc9a775f061120fbad6837e92f483317aea 100644 (file)
@@ -1524,6 +1524,13 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
 {
        struct amdgpu_display_manager *dm = bl_get_data(bd);
 
+       /*
+        * PWM interperts 0 as 100% rather than 0% because of HW
+        * limitation for level 0.So limiting minimum brightness level
+        * to 1.
+        */
+       if (bd->props.brightness < 1)
+               return 1;
        if (dc_link_set_backlight_level(dm->backlight_link,
                        bd->props.brightness, 0, 0))
                return 0;
index 0fab64a2a9150f723422f8e3600174866b03cc1b..12001a006b2d8e1d0b5f3734c189e9faf23d94e5 100644 (file)
@@ -101,7 +101,7 @@ bool dm_pp_apply_display_requirements(
                        adev->pm.pm_display_cfg.displays[i].controller_id = dc_cfg->pipe_idx + 1;
                }
 
-               if (adev->powerplay.pp_funcs->display_configuration_change)
+               if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_configuration_change)
                        adev->powerplay.pp_funcs->display_configuration_change(
                                adev->powerplay.pp_handle,
                                &adev->pm.pm_display_cfg);
@@ -304,7 +304,7 @@ bool dm_pp_get_clock_levels_by_type(
        struct amd_pp_simple_clock_info validation_clks = { 0 };
        uint32_t i;
 
-       if (adev->powerplay.pp_funcs->get_clock_by_type) {
+       if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_clock_by_type) {
                if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle,
                        dc_to_pp_clock_type(clk_type), &pp_clks)) {
                /* Error in pplib. Provide default values. */
@@ -315,7 +315,7 @@ bool dm_pp_get_clock_levels_by_type(
 
        pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type);
 
-       if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks) {
+       if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_display_mode_validation_clocks) {
                if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks(
                                                pp_handle, &validation_clks)) {
                        /* Error in pplib. Provide default values. */
@@ -398,6 +398,9 @@ bool dm_pp_get_clock_levels_by_type_with_voltage(
        struct pp_clock_levels_with_voltage pp_clk_info = {0};
        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
 
+       if (!pp_funcs || !pp_funcs->get_clock_by_type_with_voltage)
+               return false;
+
        if (pp_funcs->get_clock_by_type_with_voltage(pp_handle,
                                                     dc_to_pp_clock_type(clk_type),
                                                     &pp_clk_info))
@@ -438,7 +441,7 @@ bool dm_pp_apply_clock_for_voltage_request(
        if (!pp_clock_request.clock_type)
                return false;
 
-       if (adev->powerplay.pp_funcs->display_clock_voltage_request)
+       if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_clock_voltage_request)
                ret = adev->powerplay.pp_funcs->display_clock_voltage_request(
                        adev->powerplay.pp_handle,
                        &pp_clock_request);
@@ -455,7 +458,7 @@ bool dm_pp_get_static_clocks(
        struct amd_pp_clock_info pp_clk_info = {0};
        int ret = 0;
 
-       if (adev->powerplay.pp_funcs->get_current_clocks)
+       if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_current_clocks)
                ret = adev->powerplay.pp_funcs->get_current_clocks(
                        adev->powerplay.pp_handle,
                        &pp_clk_info);
@@ -505,6 +508,9 @@ void pp_rv_set_wm_ranges(struct pp_smu *pp,
        wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets;
        wm_with_clock_ranges.num_wm_mcif_sets = ranges->num_writer_wm_sets;
 
+       if (!pp_funcs || !pp_funcs->set_watermarks_for_clocks_ranges)
+               return;
+
        for (i = 0; i < wm_with_clock_ranges.num_wm_dmif_sets; i++) {
                if (ranges->reader_wm_sets[i].wm_inst > 3)
                        wm_dce_clocks[i].wm_set_id = WM_SET_A;
index de190935f0a456000cbabbdcc723b7c1a43667b7..e3624ca24574827a684a3c96dc257b2a4c19f215 100644 (file)
@@ -568,7 +568,7 @@ static struct input_pixel_processor *dce110_ipp_create(
 
 static const struct encoder_feature_support link_enc_feature = {
                .max_hdmi_deep_color = COLOR_DEPTH_121212,
-               .max_hdmi_pixel_clock = 594000,
+               .max_hdmi_pixel_clock = 300000,
                .flags.bits.IS_HBR2_CAPABLE = true,
                .flags.bits.IS_TPS3_CAPABLE = true
 };
index e8964cae6b93dba0c3d183dcc5383fa12734fca3..d6aa1d414320bf1d63bb84ffb490ac8e8b6417e6 100644 (file)
@@ -723,11 +723,14 @@ static int pp_dpm_force_clock_level(void *handle,
                pr_info("%s was not implemented.\n", __func__);
                return 0;
        }
+
+       if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {
+               pr_info("force clock level is for dpm manual mode only.\n");
+               return -EINVAL;
+       }
+
        mutex_lock(&hwmgr->smu_lock);
-       if (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL)
-               ret = hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask);
-       else
-               ret = -EINVAL;
+       ret = hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask);
        mutex_unlock(&hwmgr->smu_lock);
        return ret;
 }
@@ -963,6 +966,7 @@ static int pp_dpm_switch_power_profile(void *handle,
 static int pp_set_power_limit(void *handle, uint32_t limit)
 {
        struct pp_hwmgr *hwmgr = handle;
+       uint32_t max_power_limit;
 
        if (!hwmgr || !hwmgr->pm_en)
                return -EINVAL;
@@ -975,7 +979,13 @@ static int pp_set_power_limit(void *handle, uint32_t limit)
        if (limit == 0)
                limit = hwmgr->default_power_limit;
 
-       if (limit > hwmgr->default_power_limit)
+       max_power_limit = hwmgr->default_power_limit;
+       if (hwmgr->od_enabled) {
+               max_power_limit *= (100 + hwmgr->platform_descriptor.TDPODLimit);
+               max_power_limit /= 100;
+       }
+
+       if (limit > max_power_limit)
                return -EINVAL;
 
        mutex_lock(&hwmgr->smu_lock);
@@ -994,8 +1004,13 @@ static int pp_get_power_limit(void *handle, uint32_t *limit, bool default_limit)
 
        mutex_lock(&hwmgr->smu_lock);
 
-       if (default_limit)
+       if (default_limit) {
                *limit = hwmgr->default_power_limit;
+               if (hwmgr->od_enabled) {
+                       *limit *= (100 + hwmgr->platform_descriptor.TDPODLimit);
+                       *limit /= 100;
+               }
+       }
        else
                *limit = hwmgr->power_limit;
 
@@ -1303,12 +1318,12 @@ static int pp_enable_mgpu_fan_boost(void *handle)
 {
        struct pp_hwmgr *hwmgr = handle;
 
-       if (!hwmgr || !hwmgr->pm_en)
+       if (!hwmgr)
                return -EINVAL;
 
-       if (hwmgr->hwmgr_func->enable_mgpu_fan_boost == NULL) {
+       if (!hwmgr->pm_en ||
+            hwmgr->hwmgr_func->enable_mgpu_fan_boost == NULL)
                return 0;
-       }
 
        mutex_lock(&hwmgr->smu_lock);
        hwmgr->hwmgr_func->enable_mgpu_fan_boost(hwmgr);
index 6c99cbf51c08fd035fa3da585c06b8b7074bdb29..ed35ec0341e671ab8f5cee4d89d2417283147bf3 100644 (file)
@@ -3588,9 +3588,10 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons
                        break;
        }
 
-       if (i >= sclk_table->count)
+       if (i >= sclk_table->count) {
                data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
-       else {
+               sclk_table->dpm_levels[i-1].value = sclk;
+       } else {
        /* TODO: Check SCLK in DAL's minimum clocks
         * in case DeepSleep divider update is required.
         */
@@ -3605,9 +3606,10 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons
                        break;
        }
 
-       if (i >= mclk_table->count)
+       if (i >= mclk_table->count) {
                data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
-
+               mclk_table->dpm_levels[i-1].value = mclk;
+       }
 
        if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
                data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_MCLK;
index 4714b5b598255b1cad2790b76011f02e98afd704..99a33c33a32c9e47fb8bbaf455d8f44efe69c18f 100644 (file)
@@ -718,7 +718,7 @@ int smu_set_watermarks_for_clocks_ranges(void *wt_table,
                table->WatermarkRow[1][i].MaxClock =
                        cpu_to_le16((uint16_t)
                        (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz) /
-                       100);
+                       1000);
                table->WatermarkRow[1][i].MinUclk =
                        cpu_to_le16((uint16_t)
                        (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz) /
index 419a1d77d661e3708fded47180ce2b532592a087..8c4db86bb4b770b345575564ad335d48e2681835 100644 (file)
@@ -1333,7 +1333,6 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
        if (hwmgr->platform_descriptor.overdriveLimit.memoryClock == 0)
                hwmgr->platform_descriptor.overdriveLimit.memoryClock =
                                        dpm_table->dpm_levels[dpm_table->count-1].value;
-
        vega10_init_dpm_state(&(dpm_table->dpm_state));
 
        data->dpm_table.eclk_table.count = 0;
@@ -3249,6 +3248,37 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
 static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input)
 {
        struct vega10_hwmgr *data = hwmgr->backend;
+       const struct phm_set_power_state_input *states =
+                       (const struct phm_set_power_state_input *)input;
+       const struct vega10_power_state *vega10_ps =
+                       cast_const_phw_vega10_power_state(states->pnew_state);
+       struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
+       uint32_t sclk = vega10_ps->performance_levels
+                       [vega10_ps->performance_level_count - 1].gfx_clock;
+       struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
+       uint32_t mclk = vega10_ps->performance_levels
+                       [vega10_ps->performance_level_count - 1].mem_clock;
+       uint32_t i;
+
+       for (i = 0; i < sclk_table->count; i++) {
+               if (sclk == sclk_table->dpm_levels[i].value)
+                       break;
+       }
+
+       if (i >= sclk_table->count) {
+               data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
+               sclk_table->dpm_levels[i-1].value = sclk;
+       }
+
+       for (i = 0; i < mclk_table->count; i++) {
+               if (mclk == mclk_table->dpm_levels[i].value)
+                       break;
+       }
+
+       if (i >= mclk_table->count) {
+               data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
+               mclk_table->dpm_levels[i-1].value = mclk;
+       }
 
        if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
                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)
 
        if (vega10_ps->performance_levels
                        [vega10_ps->performance_level_count - 1].gfx_clock >
-                       hwmgr->platform_descriptor.overdriveLimit.engineClock)
+                       hwmgr->platform_descriptor.overdriveLimit.engineClock) {
                vega10_ps->performance_levels
                [vega10_ps->performance_level_count - 1].gfx_clock =
                                hwmgr->platform_descriptor.overdriveLimit.engineClock;
-
+               pr_warn("max sclk supported by vbios is %d\n",
+                               hwmgr->platform_descriptor.overdriveLimit.engineClock);
+       }
        return 0;
 }
 
@@ -4581,10 +4613,13 @@ static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
 
        if (vega10_ps->performance_levels
                        [vega10_ps->performance_level_count - 1].mem_clock >
-                       hwmgr->platform_descriptor.overdriveLimit.memoryClock)
+                       hwmgr->platform_descriptor.overdriveLimit.memoryClock) {
                vega10_ps->performance_levels
                [vega10_ps->performance_level_count - 1].mem_clock =
                                hwmgr->platform_descriptor.overdriveLimit.memoryClock;
+               pr_warn("max mclk supported by vbios is %d\n",
+                               hwmgr->platform_descriptor.overdriveLimit.memoryClock);
+       }
 
        return 0;
 }
index 9600e2f226e98e2be4d647d839bd98aef883de30..74bc37308dc09cb8303cd42146c7d88af3a27c58 100644 (file)
@@ -2356,6 +2356,13 @@ static int vega12_gfx_off_control(struct pp_hwmgr *hwmgr, bool enable)
                return vega12_disable_gfx_off(hwmgr);
 }
 
+static int vega12_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state,
+                               PHM_PerformanceLevelDesignation designation, uint32_t index,
+                               PHM_PerformanceLevel *level)
+{
+       return 0;
+}
+
 static const struct pp_hwmgr_func vega12_hwmgr_funcs = {
        .backend_init = vega12_hwmgr_backend_init,
        .backend_fini = vega12_hwmgr_backend_fini,
@@ -2406,6 +2413,7 @@ static const struct pp_hwmgr_func vega12_hwmgr_funcs = {
        .register_irq_handlers = smu9_register_irq_handlers,
        .start_thermal_controller = vega12_start_thermal_controller,
        .powergate_gfx = vega12_gfx_off_control,
+       .get_performance_level = vega12_get_performance_level,
 };
 
 int vega12_hwmgr_init(struct pp_hwmgr *hwmgr)
index b4dbbb7c334ce04c9760f0114825cbdc0ba5ee88..57143d51e3eed6b1dce0011748345cfece4c7165 100644 (file)
@@ -1875,38 +1875,20 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr,
        return ret;
 }
 
-static int vega20_get_current_gfx_clk_freq(struct pp_hwmgr *hwmgr, uint32_t *gfx_freq)
+static int vega20_get_current_clk_freq(struct pp_hwmgr *hwmgr,
+               PPCLK_e clk_id, uint32_t *clk_freq)
 {
-       uint32_t gfx_clk = 0;
        int ret = 0;
 
-       *gfx_freq = 0;
+       *clk_freq = 0;
 
        PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
-                       PPSMC_MSG_GetDpmClockFreq, (PPCLK_GFXCLK << 16))) == 0,
-                       "[GetCurrentGfxClkFreq] Attempt to get Current GFXCLK Frequency Failed!",
+                       PPSMC_MSG_GetDpmClockFreq, (clk_id << 16))) == 0,
+                       "[GetCurrentClkFreq] Attempt to get Current Frequency Failed!",
                        return ret);
-       gfx_clk = smum_get_argument(hwmgr);
+       *clk_freq = smum_get_argument(hwmgr);
 
-       *gfx_freq = gfx_clk * 100;
-
-       return 0;
-}
-
-static int vega20_get_current_mclk_freq(struct pp_hwmgr *hwmgr, uint32_t *mclk_freq)
-{
-       uint32_t mem_clk = 0;
-       int ret = 0;
-
-       *mclk_freq = 0;
-
-       PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
-                       PPSMC_MSG_GetDpmClockFreq, (PPCLK_UCLK << 16))) == 0,
-                       "[GetCurrentMClkFreq] Attempt to get Current MCLK Frequency Failed!",
-                       return ret);
-       mem_clk = smum_get_argument(hwmgr);
-
-       *mclk_freq = mem_clk * 100;
+       *clk_freq = *clk_freq * 100;
 
        return 0;
 }
@@ -1937,12 +1919,16 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx,
 
        switch (idx) {
        case AMDGPU_PP_SENSOR_GFX_SCLK:
-               ret = vega20_get_current_gfx_clk_freq(hwmgr, (uint32_t *)value);
+               ret = vega20_get_current_clk_freq(hwmgr,
+                               PPCLK_GFXCLK,
+                               (uint32_t *)value);
                if (!ret)
                        *size = 4;
                break;
        case AMDGPU_PP_SENSOR_GFX_MCLK:
-               ret = vega20_get_current_mclk_freq(hwmgr, (uint32_t *)value);
+               ret = vega20_get_current_clk_freq(hwmgr,
+                               PPCLK_UCLK,
+                               (uint32_t *)value);
                if (!ret)
                        *size = 4;
                break;
@@ -2012,7 +1998,6 @@ int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
        if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) {
                switch (clk_type) {
                case amd_pp_dcef_clock:
-                       clk_freq = clock_req->clock_freq_in_khz / 100;
                        clk_select = PPCLK_DCEFCLK;
                        break;
                case amd_pp_disp_clock:
@@ -2041,11 +2026,20 @@ int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
        return result;
 }
 
+static int vega20_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state,
+                               PHM_PerformanceLevelDesignation designation, uint32_t index,
+                               PHM_PerformanceLevel *level)
+{
+       return 0;
+}
+
 static int vega20_notify_smc_display_config_after_ps_adjustment(
                struct pp_hwmgr *hwmgr)
 {
        struct vega20_hwmgr *data =
                        (struct vega20_hwmgr *)(hwmgr->backend);
+       struct vega20_single_dpm_table *dpm_table =
+                       &data->dpm_table.mem_table;
        struct PP_Clocks min_clocks = {0};
        struct pp_display_clock_request clock_req;
        int ret = 0;
@@ -2063,7 +2057,7 @@ static int vega20_notify_smc_display_config_after_ps_adjustment(
 
        if (data->smu_features[GNLD_DPM_DCEFCLK].supported) {
                clock_req.clock_type = amd_pp_dcef_clock;
-               clock_req.clock_freq_in_khz = min_clocks.dcefClock;
+               clock_req.clock_freq_in_khz = min_clocks.dcefClock * 10;
                if (!vega20_display_clock_voltage_request(hwmgr, &clock_req)) {
                        if (data->smu_features[GNLD_DS_DCEFCLK].supported)
                                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(
                }
        }
 
+       if (data->smu_features[GNLD_DPM_UCLK].enabled) {
+               dpm_table->dpm_state.hard_min_level = min_clocks.memoryClock / 100;
+               PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+                               PPSMC_MSG_SetHardMinByFreq,
+                               (PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level)),
+                               "[SetHardMinFreq] Set hard min uclk failed!",
+                               return ret);
+       }
+
        return 0;
 }
 
@@ -2353,7 +2356,7 @@ static int vega20_get_sclks(struct pp_hwmgr *hwmgr,
 
        for (i = 0; i < count; i++) {
                clocks->data[i].clocks_in_khz =
-                       dpm_table->dpm_levels[i].value * 100;
+                       dpm_table->dpm_levels[i].value * 1000;
                clocks->data[i].latency_in_us = 0;
        }
 
@@ -2383,7 +2386,7 @@ static int vega20_get_memclocks(struct pp_hwmgr *hwmgr,
        for (i = 0; i < count; i++) {
                clocks->data[i].clocks_in_khz =
                        data->mclk_latency_table.entries[i].frequency =
-                       dpm_table->dpm_levels[i].value * 100;
+                       dpm_table->dpm_levels[i].value * 1000;
                clocks->data[i].latency_in_us =
                        data->mclk_latency_table.entries[i].latency =
                        vega20_get_mem_latency(hwmgr, dpm_table->dpm_levels[i].value);
@@ -2408,7 +2411,7 @@ static int vega20_get_dcefclocks(struct pp_hwmgr *hwmgr,
 
        for (i = 0; i < count; i++) {
                clocks->data[i].clocks_in_khz =
-                       dpm_table->dpm_levels[i].value * 100;
+                       dpm_table->dpm_levels[i].value * 1000;
                clocks->data[i].latency_in_us = 0;
        }
 
@@ -2431,7 +2434,7 @@ static int vega20_get_socclocks(struct pp_hwmgr *hwmgr,
 
        for (i = 0; i < count; i++) {
                clocks->data[i].clocks_in_khz =
-                       dpm_table->dpm_levels[i].value * 100;
+                       dpm_table->dpm_levels[i].value * 1000;
                clocks->data[i].latency_in_us = 0;
        }
 
@@ -2582,11 +2585,11 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
                                return -EINVAL;
                        }
 
-                       if (input_clk < clocks.data[0].clocks_in_khz / 100 ||
+                       if (input_clk < clocks.data[0].clocks_in_khz / 1000 ||
                            input_clk > od8_settings[OD8_SETTING_UCLK_FMAX].max_value) {
                                pr_info("clock freq %d is not within allowed range [%d - %d]\n",
                                        input_clk,
-                                       clocks.data[0].clocks_in_khz / 100,
+                                       clocks.data[0].clocks_in_khz / 1000,
                                        od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
                                return -EINVAL;
                        }
@@ -2726,7 +2729,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
 
        switch (type) {
        case PP_SCLK:
-               ret = vega20_get_current_gfx_clk_freq(hwmgr, &now);
+               ret = vega20_get_current_clk_freq(hwmgr, PPCLK_GFXCLK, &now);
                PP_ASSERT_WITH_CODE(!ret,
                                "Attempt to get current gfx clk Failed!",
                                return ret);
@@ -2738,12 +2741,12 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
 
                for (i = 0; i < clocks.num_levels; i++)
                        size += sprintf(buf + size, "%d: %uMhz %s\n",
-                               i, clocks.data[i].clocks_in_khz / 100,
+                               i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz == now) ? "*" : "");
                break;
 
        case PP_MCLK:
-               ret = vega20_get_current_mclk_freq(hwmgr, &now);
+               ret = vega20_get_current_clk_freq(hwmgr, PPCLK_UCLK, &now);
                PP_ASSERT_WITH_CODE(!ret,
                                "Attempt to get current mclk freq Failed!",
                                return ret);
@@ -2755,7 +2758,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
 
                for (i = 0; i < clocks.num_levels; i++)
                        size += sprintf(buf + size, "%d: %uMhz %s\n",
-                               i, clocks.data[i].clocks_in_khz / 100,
+                               i, clocks.data[i].clocks_in_khz / 1000,
                                (clocks.data[i].clocks_in_khz == now) ? "*" : "");
                break;
 
@@ -2820,7 +2823,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
                                        return ret);
 
                        size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n",
-                               clocks.data[0].clocks_in_khz / 100,
+                               clocks.data[0].clocks_in_khz / 1000,
                                od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
                }
 
@@ -3476,6 +3479,8 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
                vega20_set_watermarks_for_clocks_ranges,
        .display_clock_voltage_request =
                vega20_display_clock_voltage_request,
+       .get_performance_level =
+               vega20_get_performance_level,
        /* UMD pstate, profile related */
        .force_dpm_level =
                vega20_dpm_force_dpm_level,
index e5f7f82300659f18999a29442166442be071010a..97f8a1a970c37e124c8e5b07727f7ce6e32e8849 100644 (file)
@@ -642,8 +642,14 @@ static int check_powerplay_tables(
                "Unsupported PPTable format!", return -1);
        PP_ASSERT_WITH_CODE(powerplay_table->sHeader.structuresize > 0,
                "Invalid PowerPlay Table!", return -1);
-       PP_ASSERT_WITH_CODE(powerplay_table->smcPPTable.Version == PPTABLE_V20_SMU_VERSION,
-               "Unmatch PPTable version, vbios update may be needed!", return -1);
+
+       if (powerplay_table->smcPPTable.Version != PPTABLE_V20_SMU_VERSION) {
+               pr_info("Unmatch PPTable version: "
+                       "pptable from VBIOS is V%d while driver supported is V%d!",
+                       powerplay_table->smcPPTable.Version,
+                       PPTABLE_V20_SMU_VERSION);
+               return -EINVAL;
+       }
 
        //dump_pptable(&powerplay_table->smcPPTable);
 
@@ -716,10 +722,6 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable
                "[appendVbiosPPTable] Failed to retrieve Smc Dpm Table from VBIOS!",
                return -1);
 
-       memset(ppsmc_pptable->Padding32,
-                       0,
-                       sizeof(struct atom_smc_dpm_info_v4_4) -
-                       sizeof(struct atom_common_table_header));
        ppsmc_pptable->MaxVoltageStepGfx = smc_dpm_table->maxvoltagestepgfx;
        ppsmc_pptable->MaxVoltageStepSoc = smc_dpm_table->maxvoltagestepsoc;
 
@@ -778,22 +780,19 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable
        ppsmc_pptable->FllGfxclkSpreadPercent = smc_dpm_table->fllgfxclkspreadpercent;
        ppsmc_pptable->FllGfxclkSpreadFreq = smc_dpm_table->fllgfxclkspreadfreq;
 
-       if ((smc_dpm_table->table_header.format_revision == 4) &&
-           (smc_dpm_table->table_header.content_revision == 4)) {
-               for (i = 0; i < I2C_CONTROLLER_NAME_COUNT; i++) {
-                       ppsmc_pptable->I2cControllers[i].Enabled =
-                               smc_dpm_table->i2ccontrollers[i].enabled;
-                       ppsmc_pptable->I2cControllers[i].SlaveAddress =
-                               smc_dpm_table->i2ccontrollers[i].slaveaddress;
-                       ppsmc_pptable->I2cControllers[i].ControllerPort =
-                               smc_dpm_table->i2ccontrollers[i].controllerport;
-                       ppsmc_pptable->I2cControllers[i].ThermalThrottler =
-                               smc_dpm_table->i2ccontrollers[i].thermalthrottler;
-                       ppsmc_pptable->I2cControllers[i].I2cProtocol =
-                               smc_dpm_table->i2ccontrollers[i].i2cprotocol;
-                       ppsmc_pptable->I2cControllers[i].I2cSpeed =
-                               smc_dpm_table->i2ccontrollers[i].i2cspeed;
-               }
+       for (i = 0; i < I2C_CONTROLLER_NAME_COUNT; i++) {
+               ppsmc_pptable->I2cControllers[i].Enabled =
+                       smc_dpm_table->i2ccontrollers[i].enabled;
+               ppsmc_pptable->I2cControllers[i].SlaveAddress =
+                       smc_dpm_table->i2ccontrollers[i].slaveaddress;
+               ppsmc_pptable->I2cControllers[i].ControllerPort =
+                       smc_dpm_table->i2ccontrollers[i].controllerport;
+               ppsmc_pptable->I2cControllers[i].ThermalThrottler =
+                       smc_dpm_table->i2ccontrollers[i].thermalthrottler;
+               ppsmc_pptable->I2cControllers[i].I2cProtocol =
+                       smc_dpm_table->i2ccontrollers[i].i2cprotocol;
+               ppsmc_pptable->I2cControllers[i].I2cSpeed =
+                       smc_dpm_table->i2ccontrollers[i].i2cspeed;
        }
 
        return 0;
@@ -882,15 +881,10 @@ static int init_powerplay_table_information(
        if (pptable_information->smc_pptable == NULL)
                return -ENOMEM;
 
-       if (powerplay_table->smcPPTable.Version <= 2)
-               memcpy(pptable_information->smc_pptable,
-                               &(powerplay_table->smcPPTable),
-                               sizeof(PPTable_t) -
-                               sizeof(I2cControllerConfig_t) * I2C_CONTROLLER_NAME_COUNT);
-       else
-               memcpy(pptable_information->smc_pptable,
-                               &(powerplay_table->smcPPTable),
-                               sizeof(PPTable_t));
+       memcpy(pptable_information->smc_pptable,
+                       &(powerplay_table->smcPPTable),
+                       sizeof(PPTable_t));
+
 
        result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable));
 
index 2998a49960ede1d47975675afa8c1a290d0461c9..63d5cf69154967b90aa696de2ae5c1d407bd579f 100644 (file)
@@ -29,7 +29,7 @@
 // any structure is changed in this file
 #define SMU11_DRIVER_IF_VERSION 0x12
 
-#define PPTABLE_V20_SMU_VERSION 2
+#define PPTABLE_V20_SMU_VERSION 3
 
 #define NUM_GFXCLK_DPM_LEVELS  16
 #define NUM_VCLK_DPM_LEVELS    8
index f836d30fdd4428b166591676f69f588f43f852fb..09b844ec3eabae4f09f8c0d10ed84d53fcc75ee2 100644 (file)
@@ -71,7 +71,11 @@ static int smu8_send_msg_to_smc_async(struct pp_hwmgr *hwmgr, uint16_t msg)
        result = PHM_WAIT_FIELD_UNEQUAL(hwmgr,
                                        SMU_MP1_SRBM2P_RESP_0, CONTENT, 0);
        if (result != 0) {
+               /* Read the last message to SMU, to report actual cause */
+               uint32_t val = cgs_read_register(hwmgr->device,
+                                                mmSMU_MP1_SRBM2P_MSG_0);
                pr_err("smu8_send_msg_to_smc_async (0x%04x) failed\n", msg);
+               pr_err("SMU still servicing msg (0x%04x)\n", val);
                return result;
        }
 
index f8a931cf3665e8bac6a02017760c33d790d530a0..680566d97adcf652b52eb886fe54326d95817d01 100644 (file)
@@ -458,18 +458,6 @@ static void ti_sn_bridge_enable(struct drm_bridge *bridge)
        unsigned int val;
        int ret;
 
-       /*
-        * FIXME:
-        * This 70ms was found necessary by experimentation. If it's not
-        * present, link training fails. It seems like it can go anywhere from
-        * pre_enable() up to semi-auto link training initiation below.
-        *
-        * Neither the datasheet for the bridge nor the panel tested mention a
-        * delay of this magnitude in the timing requirements. So for now, add
-        * the mystery delay until someone figures out a better fix.
-        */
-       msleep(70);
-
        /* DSI_A lane config */
        val = CHA_DSI_LANES(4 - pdata->dsi->lanes);
        regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG,
@@ -536,7 +524,22 @@ static void ti_sn_bridge_pre_enable(struct drm_bridge *bridge)
        /* configure bridge ref_clk */
        ti_sn_bridge_set_refclk_freq(pdata);
 
-       /* in case drm_panel is connected then HPD is not supported */
+       /*
+        * HPD on this bridge chip is a bit useless.  This is an eDP bridge
+        * so the HPD is an internal signal that's only there to signal that
+        * the panel is done powering up.  ...but the bridge chip debounces
+        * this signal by between 100 ms and 400 ms (depending on process,
+        * voltage, and temperate--I measured it at about 200 ms).  One
+        * particular panel asserted HPD 84 ms after it was powered on meaning
+        * that we saw HPD 284 ms after power on.  ...but the same panel said
+        * that instead of looking at HPD you could just hardcode a delay of
+        * 200 ms.  We'll assume that the panel driver will have the hardcoded
+        * delay in its prepare and always disable HPD.
+        *
+        * If HPD somehow makes sense on some future panel we'll have to
+        * change this to be conditional on someone specifying that HPD should
+        * be used.
+        */
        regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE,
                           HPD_DISABLE);
 
index 3c9fc99648b7c912a4b9fa686798d8fe8d23b651..08821dfa3327ce3d2aa4bd792f9dc32bb547086e 100644 (file)
@@ -119,6 +119,9 @@ static const struct edid_quirk {
        /* SDC panel of Lenovo B50-80 reports 8 bpc, but is a 6 bpc panel */
        { "SDC", 0x3652, EDID_QUIRK_FORCE_6BPC },
 
+       /* BOE model 0x0771 reports 8 bpc, but is a 6 bpc panel */
+       { "BOE", 0x0771, EDID_QUIRK_FORCE_6BPC },
+
        /* Belinea 10 15 55 */
        { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
        { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
index 97964f7f2acee08350101947a4ccd9a717f5f199..a04ffb3b21742a834c44c4770e2760f8139053dd 100644 (file)
@@ -56,6 +56,8 @@ struct panel_desc {
        /**
         * @prepare: the time (in milliseconds) that it takes for the panel to
         *           become ready and start receiving video data
+        * @hpd_absent_delay: Add this to the prepare delay if we know Hot
+        *                    Plug Detect isn't used.
         * @enable: the time (in milliseconds) that it takes for the panel to
         *          display the first valid frame after starting to receive
         *          video data
@@ -66,6 +68,7 @@ struct panel_desc {
         */
        struct {
                unsigned int prepare;
+               unsigned int hpd_absent_delay;
                unsigned int enable;
                unsigned int disable;
                unsigned int unprepare;
@@ -79,6 +82,7 @@ struct panel_simple {
        struct drm_panel base;
        bool prepared;
        bool enabled;
+       bool no_hpd;
 
        const struct panel_desc *desc;
 
@@ -202,6 +206,7 @@ static int panel_simple_unprepare(struct drm_panel *panel)
 static int panel_simple_prepare(struct drm_panel *panel)
 {
        struct panel_simple *p = to_panel_simple(panel);
+       unsigned int delay;
        int err;
 
        if (p->prepared)
@@ -215,8 +220,11 @@ static int panel_simple_prepare(struct drm_panel *panel)
 
        gpiod_set_value_cansleep(p->enable_gpio, 1);
 
-       if (p->desc->delay.prepare)
-               msleep(p->desc->delay.prepare);
+       delay = p->desc->delay.prepare;
+       if (p->no_hpd)
+               delay += p->desc->delay.hpd_absent_delay;
+       if (delay)
+               msleep(delay);
 
        p->prepared = true;
 
@@ -305,6 +313,8 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
        panel->prepared = false;
        panel->desc = desc;
 
+       panel->no_hpd = of_property_read_bool(dev->of_node, "no-hpd");
+
        panel->supply = devm_regulator_get(dev, "power");
        if (IS_ERR(panel->supply))
                return PTR_ERR(panel->supply);
@@ -1363,7 +1373,7 @@ static const struct panel_desc innolux_n156bge_l21 = {
        },
 };
 
-static const struct drm_display_mode innolux_tv123wam_mode = {
+static const struct drm_display_mode innolux_p120zdg_bf1_mode = {
        .clock = 206016,
        .hdisplay = 2160,
        .hsync_start = 2160 + 48,
@@ -1377,15 +1387,16 @@ static const struct drm_display_mode innolux_tv123wam_mode = {
        .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
 };
 
-static const struct panel_desc innolux_tv123wam = {
-       .modes = &innolux_tv123wam_mode,
+static const struct panel_desc innolux_p120zdg_bf1 = {
+       .modes = &innolux_p120zdg_bf1_mode,
        .num_modes = 1,
        .bpc = 8,
        .size = {
-               .width = 259,
-               .height = 173,
+               .width = 254,
+               .height = 169,
        },
        .delay = {
+               .hpd_absent_delay = 200,
                .unprepare = 500,
        },
 };
@@ -2445,8 +2456,8 @@ static const struct of_device_id platform_of_match[] = {
                .compatible = "innolux,n156bge-l21",
                .data = &innolux_n156bge_l21,
        }, {
-               .compatible = "innolux,tv123wam",
-               .data = &innolux_tv123wam,
+               .compatible = "innolux,p120zdg-bf1",
+               .data = &innolux_p120zdg_bf1,
        }, {
                .compatible = "innolux,zj070na-01p",
                .data = &innolux_zj070na_01p,