From a315f232f44e685397639649fe559325424d32d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 19 Jun 2018 10:45:03 +0200 Subject: [PATCH 001/133] drm/amdgpu: band aid validating VM PTs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Always validating the VM PTs takes to much time. Only always validate the per VM BOs for now. Signed-off-by: Christian König Reviewed-by: Junwei Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 422d1a434db4..590db78b8c72 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1082,7 +1082,7 @@ int amdgpu_vm_update_directories(struct amdgpu_device *adev, struct amdgpu_vm_bo_base, vm_status); bo_base->moved = false; - list_move(&bo_base->vm_status, &vm->idle); + list_del_init(&bo_base->vm_status); bo = bo_base->bo->parent; if (!bo) From b374d82dca4721c534eb940b599dd4d45ba3a18f Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Wed, 20 Jun 2018 07:55:39 -0400 Subject: [PATCH 002/133] drm/amd/amdgpu: Add a GPU_LOAD entry to sysfs (v3) This adds what should be a stable interface to read GPU load from userspace. (v2): Fix comments and name of file per recommendations. (v3): Add chapter to amdgpu.rst as well. Signed-off-by: Tom St Denis Acked-by: Slava Abramov Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- Documentation/gpu/amdgpu.rst | 5 ++++ drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 40 ++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/Documentation/gpu/amdgpu.rst b/Documentation/gpu/amdgpu.rst index e52d0ce186fe..765c2a32938f 100644 --- a/Documentation/gpu/amdgpu.rst +++ b/Documentation/gpu/amdgpu.rst @@ -115,3 +115,8 @@ pp_power_profile_mode .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c :doc: pp_power_profile_mode +busy_percent +~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c + :doc: busy_percent diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 113edffb5960..fdb399821915 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -918,6 +918,36 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, return -EINVAL; } +/** + * DOC: busy_percent + * + * The amdgpu driver provides a sysfs API for reading how busy the GPU + * is as a percentage. The file gpu_busy_percent is used for this. + * The SMU firmware computes a percentage of load based on the + * aggregate activity level in the IP cores. + */ +static ssize_t amdgpu_get_busy_percent(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + int r, value, size = sizeof(value); + + /* sanity check PP is enabled */ + if (!(adev->powerplay.pp_funcs && + adev->powerplay.pp_funcs->read_sensor)) + return -EINVAL; + + /* read the IP busy sensor */ + r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_LOAD, + (void *)&value, &size); + if (r) + return r; + + return snprintf(buf, PAGE_SIZE, "%d\n", value); +} + static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state); static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, amdgpu_get_dpm_forced_performance_level, @@ -951,6 +981,8 @@ static DEVICE_ATTR(pp_power_profile_mode, S_IRUGO | S_IWUSR, static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR, amdgpu_get_pp_od_clk_voltage, amdgpu_set_pp_od_clk_voltage); +static DEVICE_ATTR(gpu_busy_percent, S_IRUGO, + amdgpu_get_busy_percent, NULL); static ssize_t amdgpu_hwmon_show_temp(struct device *dev, struct device_attribute *attr, @@ -1854,6 +1886,13 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) "pp_od_clk_voltage\n"); return ret; } + ret = device_create_file(adev->dev, + &dev_attr_gpu_busy_percent); + if (ret) { + DRM_ERROR("failed to create device file " + "gpu_busy_level\n"); + return ret; + } ret = amdgpu_debugfs_pm_init(adev); if (ret) { DRM_ERROR("Failed to register debugfs file for dpm!\n"); @@ -1889,6 +1928,7 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) &dev_attr_pp_power_profile_mode); device_remove_file(adev->dev, &dev_attr_pp_od_clk_voltage); + device_remove_file(adev->dev, &dev_attr_gpu_busy_percent); } void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) From d9e222b460b195a47b30fd9057fbb131fcbd7bac Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Mon, 18 Jun 2018 11:15:10 -0400 Subject: [PATCH 003/133] drm/amdgpu: Polish SQ IH. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch to using reg fields defines istead of magic values. Add SH_ID and PRIV fields reading for instr. and err cases. Signed-off-by: Andrey Grodzovsky Acked-by: Christian König Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 36 +++++++++++++++------------ 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 807ee0dd623c..1d99a4205958 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -6961,10 +6961,11 @@ static int gfx_v8_0_sq_irq(struct amdgpu_device *adev, { u8 enc, se_id; char type[20]; + unsigned ih_data = entry->src_data[0]; - /* Parse all fields according to SQ_INTERRUPT* registers */ - enc = (entry->src_data[0] >> 26) & 0x3; - se_id = (entry->src_data[0] >> 24) & 0x3; + + enc = REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_CMN, ENCODING); + se_id = REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_CMN, SE_ID); switch (enc) { case 0: @@ -6974,14 +6975,14 @@ static int gfx_v8_0_sq_irq(struct amdgpu_device *adev, "reg_timestamp %d, thread_trace_buff_full %d," "wlt %d, thread_trace %d.\n", se_id, - (entry->src_data[0] >> 7) & 0x1, - (entry->src_data[0] >> 6) & 0x1, - (entry->src_data[0] >> 5) & 0x1, - (entry->src_data[0] >> 4) & 0x1, - (entry->src_data[0] >> 3) & 0x1, - (entry->src_data[0] >> 2) & 0x1, - (entry->src_data[0] >> 1) & 0x1, - entry->src_data[0] & 0x1 + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_AUTO, IMMED_OVERFLOW), + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_AUTO, HOST_REG_OVERFLOW), + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_AUTO, HOST_CMD_OVERFLOW), + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_AUTO, CMD_TIMESTAMP), + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_AUTO, REG_TIMESTAMP), + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_AUTO, THREAD_TRACE_BUF_FULL), + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_AUTO, WLT), + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_AUTO, THREAD_TRACE) ); break; case 1: @@ -6994,12 +6995,15 @@ static int gfx_v8_0_sq_irq(struct amdgpu_device *adev, DRM_INFO( "SQ %s detected: " - "se_id %d, cu_id %d, simd_id %d, wave_id %d, vm_id %d\n", + "se_id %d, cu_id %d, simd_id %d, wave_id %d, vm_id %d\n" + "trap %s, sh_id %d. ", type, se_id, - (entry->src_data[0] >> 20) & 0xf, - (entry->src_data[0] >> 18) & 0x3, - (entry->src_data[0] >> 14) & 0xf, - (entry->src_data[0] >> 10) & 0xf + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, CU_ID), + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, SIMD_ID), + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, WAVE_ID), + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, VM_ID), + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, PRIV) ? "true" : "false", + REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, SH_ID) ); break; default: From 9bdc2092b488bc81aa5409b4d6fc931c5bea1094 Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Tue, 19 Jun 2018 10:27:53 -0400 Subject: [PATCH 004/133] drm/amdgpu: Add parsing SQ_EDC_INFO to SQ IH v3. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Access to SQ_EDC_INFO requires selecting register instance and hence mutex lock when accessing GRBM_GFX_INDEX for which a work is schedueled from IH. But SQ interrupt can be raised on many instances at once which means queuing work will usually succeed for the first one but fail for the rest since the work takes time to process. To avoid losing info about other interrupt instances call the parsing function directly from high IRQ when current work hasn't finished and avoid accessing SQ_EDC_INFO in that case. v2: Simplify high IRQ and BH handlers synchronization using work_pending. Remove {READ,WRITE}_ONCE notations since smp_{r,w}mb are implicit compiler barriers. v3: Remove exlicit memory barriers as scedule_work has r/w barriers. Signed-off-by: Andrey Grodzovsky Acked-by: Christian König Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 7 +++ drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 82 ++++++++++++++++++++++----- 2 files changed, 76 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 71b9b861f60e..fb17838114c3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -930,6 +930,11 @@ struct amdgpu_ngg { bool init; }; +struct sq_work { + struct work_struct work; + unsigned ih_data; +}; + struct amdgpu_gfx { struct mutex gpu_clock_mutex; struct amdgpu_gfx_config config; @@ -970,6 +975,8 @@ struct amdgpu_gfx { struct amdgpu_irq_src priv_inst_irq; struct amdgpu_irq_src cp_ecc_error_irq; struct amdgpu_irq_src sq_irq; + struct sq_work sq_work; + /* gfx status */ uint32_t gfx_current_status; /* ce ram size*/ diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 1d99a4205958..4201f3dfaece 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -704,6 +704,17 @@ static const u32 stoney_mgcg_cgcg_init[] = mmCGTS_SM_CTRL_REG, 0xffffffff, 0x96940200, }; + +static const char * const sq_edc_source_names[] = { + "SQ_EDC_INFO_SOURCE_INVALID: No EDC error has occurred", + "SQ_EDC_INFO_SOURCE_INST: EDC source is Instruction Fetch", + "SQ_EDC_INFO_SOURCE_SGPR: EDC source is SGPR or SQC data return", + "SQ_EDC_INFO_SOURCE_VGPR: EDC source is VGPR", + "SQ_EDC_INFO_SOURCE_LDS: EDC source is LDS", + "SQ_EDC_INFO_SOURCE_GDS: EDC source is GDS", + "SQ_EDC_INFO_SOURCE_TA: EDC source is TA", +}; + static void gfx_v8_0_set_ring_funcs(struct amdgpu_device *adev); static void gfx_v8_0_set_irq_funcs(struct amdgpu_device *adev); static void gfx_v8_0_set_gds_init(struct amdgpu_device *adev); @@ -2006,6 +2017,8 @@ static int gfx_v8_0_compute_ring_init(struct amdgpu_device *adev, int ring_id, return 0; } +static void gfx_v8_0_sq_irq_work_func(struct work_struct *work); + static int gfx_v8_0_sw_init(void *handle) { int i, j, k, r, ring_id; @@ -2069,6 +2082,8 @@ static int gfx_v8_0_sw_init(void *handle) return r; } + INIT_WORK(&adev->gfx.sq_work.work, gfx_v8_0_sq_irq_work_func); + adev->gfx.gfx_current_status = AMDGPU_GFX_NORMAL_MODE; gfx_v8_0_scratch_init(adev); @@ -6955,14 +6970,11 @@ static int gfx_v8_0_cp_ecc_error_irq(struct amdgpu_device *adev, return 0; } -static int gfx_v8_0_sq_irq(struct amdgpu_device *adev, - struct amdgpu_irq_src *source, - struct amdgpu_iv_entry *entry) +static void gfx_v8_0_parse_sq_irq(struct amdgpu_device *adev, unsigned ih_data) { - u8 enc, se_id; + u32 enc, se_id, sh_id, cu_id; char type[20]; - unsigned ih_data = entry->src_data[0]; - + int sq_edc_source = -1; enc = REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_CMN, ENCODING); se_id = REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_CMN, SE_ID); @@ -6988,6 +7000,24 @@ static int gfx_v8_0_sq_irq(struct amdgpu_device *adev, case 1: case 2: + cu_id = REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, CU_ID); + sh_id = REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, SH_ID); + + /* + * This function can be called either directly from ISR + * or from BH in which case we can access SQ_EDC_INFO + * instance + */ + if (in_task()) { + mutex_lock(&adev->grbm_idx_mutex); + gfx_v8_0_select_se_sh(adev, se_id, sh_id, cu_id); + + sq_edc_source = REG_GET_FIELD(RREG32(mmSQ_EDC_INFO), SQ_EDC_INFO, SOURCE); + + gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); + mutex_unlock(&adev->grbm_idx_mutex); + } + if (enc == 1) sprintf(type, "instruction intr"); else @@ -6995,20 +7025,46 @@ static int gfx_v8_0_sq_irq(struct amdgpu_device *adev, DRM_INFO( "SQ %s detected: " - "se_id %d, cu_id %d, simd_id %d, wave_id %d, vm_id %d\n" - "trap %s, sh_id %d. ", - type, se_id, - REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, CU_ID), + "se_id %d, sh_id %d, cu_id %d, simd_id %d, wave_id %d, vm_id %d " + "trap %s, sq_ed_info.source %s.\n", + type, se_id, sh_id, cu_id, REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, SIMD_ID), REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, WAVE_ID), REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, VM_ID), REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, PRIV) ? "true" : "false", - REG_GET_FIELD(ih_data, SQ_INTERRUPT_WORD_WAVE, SH_ID) - ); + (sq_edc_source != -1) ? sq_edc_source_names[sq_edc_source] : "unavailable" + ); break; default: DRM_ERROR("SQ invalid encoding type\n."); - return -EINVAL; + } +} + +static void gfx_v8_0_sq_irq_work_func(struct work_struct *work) +{ + + struct amdgpu_device *adev = container_of(work, struct amdgpu_device, gfx.sq_work.work); + struct sq_work *sq_work = container_of(work, struct sq_work, work); + + gfx_v8_0_parse_sq_irq(adev, sq_work->ih_data); +} + +static int gfx_v8_0_sq_irq(struct amdgpu_device *adev, + struct amdgpu_irq_src *source, + struct amdgpu_iv_entry *entry) +{ + unsigned ih_data = entry->src_data[0]; + + /* + * Try to submit work so SQ_EDC_INFO can be accessed from + * BH. If previous work submission hasn't finished yet + * just print whatever info is possible directly from the ISR. + */ + if (work_pending(&adev->gfx.sq_work.work)) { + gfx_v8_0_parse_sq_irq(adev, ih_data); + } else { + adev->gfx.sq_work.ih_data = ih_data; + schedule_work(&adev->gfx.sq_work.work); } return 0; From a25ca1625dd4ecc89c20bb9082b325490f3f78f2 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 22 Jun 2018 15:00:26 -0500 Subject: [PATCH 005/133] Revert "drm/amdgpu: avoid sleep while executing atombios table (V2)" This reverts commit 8f4805a265fd710a2827b2c0e10c08ef2b526870. This change was mistakenly committed and should have been dropped with the rest of the series. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/atom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c index b18c31a701e2..e9934de1b9cf 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.c +++ b/drivers/gpu/drm/amd/amdgpu/atom.c @@ -1221,7 +1221,7 @@ static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, ectx.abort = false; ectx.last_jump = 0; if (ws) - ectx.ws = kcalloc(4, ws, GFP_ATOMIC); + ectx.ws = kcalloc(4, ws, GFP_KERNEL); else ectx.ws = NULL; From 765b26836430e9d9ebef95fced42dd167b4ccad6 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 23 May 2018 13:16:50 -0400 Subject: [PATCH 006/133] drm/amd/display: replace clocks_value struct with dc_clocks This will avoid structs with duplicate information. Also removes pixel clock voltage request. This has no effect since pixel clock does not affect dcn voltage and this function only matters for dcn. Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 34 +++++++------- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 8 ++-- drivers/gpu/drm/amd/display/dc/dc.h | 5 ++ .../gpu/drm/amd/display/dc/dce/dce_clocks.c | 46 +++++++------------ .../display/dc/dce110/dce110_hw_sequencer.c | 18 +------- .../gpu/drm/amd/display/dc/inc/dcn_calcs.h | 2 +- .../drm/amd/display/dc/inc/hw/display_clock.h | 22 ++------- 7 files changed, 49 insertions(+), 86 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 49a4ea45466d..d8a31650e856 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -1145,10 +1145,10 @@ static unsigned int dcn_find_normalized_clock_vdd_Level( switch (clocks_type) { case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - if (clocks_in_khz > dc->dcn_soc->max_dispclk_vmax0p9*1000) { + /*if (clocks_in_khz > dc->dcn_soc->max_dispclk_vmax0p9*1000) { vdd_level = dcn_bw_v_max0p91; - BREAK_TO_DEBUGGER(); - } else if (clocks_in_khz > dc->dcn_soc->max_dispclk_vnom0p8*1000) { + //BREAK_TO_DEBUGGER(); + } else*/ if (clocks_in_khz > dc->dcn_soc->max_dispclk_vnom0p8*1000) { vdd_level = dcn_bw_v_max0p9; } else if (clocks_in_khz > dc->dcn_soc->max_dispclk_vmid0p72*1000) { vdd_level = dcn_bw_v_nom0p8; @@ -1158,10 +1158,10 @@ static unsigned int dcn_find_normalized_clock_vdd_Level( vdd_level = dcn_bw_v_min0p65; break; case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: - if (clocks_in_khz > dc->dcn_soc->phyclkv_max0p9*1000) { + /*if (clocks_in_khz > dc->dcn_soc->phyclkv_max0p9*1000) { vdd_level = dcn_bw_v_max0p91; BREAK_TO_DEBUGGER(); - } else if (clocks_in_khz > dc->dcn_soc->phyclkv_nom0p8*1000) { + } else*/ if (clocks_in_khz > dc->dcn_soc->phyclkv_nom0p8*1000) { vdd_level = dcn_bw_v_max0p9; } else if (clocks_in_khz > dc->dcn_soc->phyclkv_mid0p72*1000) { vdd_level = dcn_bw_v_nom0p8; @@ -1172,10 +1172,10 @@ static unsigned int dcn_find_normalized_clock_vdd_Level( break; case DM_PP_CLOCK_TYPE_DPPCLK: - if (clocks_in_khz > dc->dcn_soc->max_dppclk_vmax0p9*1000) { + /*if (clocks_in_khz > dc->dcn_soc->max_dppclk_vmax0p9*1000) { vdd_level = dcn_bw_v_max0p91; BREAK_TO_DEBUGGER(); - } else if (clocks_in_khz > dc->dcn_soc->max_dppclk_vnom0p8*1000) { + } else*/ if (clocks_in_khz > dc->dcn_soc->max_dppclk_vnom0p8*1000) { vdd_level = dcn_bw_v_max0p9; } else if (clocks_in_khz > dc->dcn_soc->max_dppclk_vmid0p72*1000) { vdd_level = dcn_bw_v_nom0p8; @@ -1189,10 +1189,10 @@ static unsigned int dcn_find_normalized_clock_vdd_Level( { unsigned factor = (ddr4_dram_factor_single_Channel * dc->dcn_soc->number_of_channels); - if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9*1000000/factor) { + /*if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9*1000000/factor) { vdd_level = dcn_bw_v_max0p91; BREAK_TO_DEBUGGER(); - } else if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8*1000000/factor) { + } else */if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8*1000000/factor) { vdd_level = dcn_bw_v_max0p9; } else if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72*1000000/factor) { vdd_level = dcn_bw_v_nom0p8; @@ -1204,10 +1204,10 @@ static unsigned int dcn_find_normalized_clock_vdd_Level( break; case DM_PP_CLOCK_TYPE_DCFCLK: - if (clocks_in_khz > dc->dcn_soc->dcfclkv_max0p9*1000) { + /*if (clocks_in_khz > dc->dcn_soc->dcfclkv_max0p9*1000) { vdd_level = dcn_bw_v_max0p91; BREAK_TO_DEBUGGER(); - } else if (clocks_in_khz > dc->dcn_soc->dcfclkv_nom0p8*1000) { + } else */if (clocks_in_khz > dc->dcn_soc->dcfclkv_nom0p8*1000) { vdd_level = dcn_bw_v_max0p9; } else if (clocks_in_khz > dc->dcn_soc->dcfclkv_mid0p72*1000) { vdd_level = dcn_bw_v_nom0p8; @@ -1225,27 +1225,27 @@ static unsigned int dcn_find_normalized_clock_vdd_Level( unsigned int dcn_find_dcfclk_suits_all( const struct dc *dc, - struct clocks_value *clocks) + struct dc_clocks *clocks) { unsigned vdd_level, vdd_level_temp; unsigned dcf_clk; /*find a common supported voltage level*/ vdd_level = dcn_find_normalized_clock_vdd_Level( - dc, DM_PP_CLOCK_TYPE_DISPLAY_CLK, clocks->dispclk_in_khz); + dc, DM_PP_CLOCK_TYPE_DISPLAY_CLK, clocks->dispclk_khz); vdd_level_temp = dcn_find_normalized_clock_vdd_Level( - dc, DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, clocks->phyclk_in_khz); + dc, DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, clocks->phyclk_khz); vdd_level = dcn_bw_max(vdd_level, vdd_level_temp); vdd_level_temp = dcn_find_normalized_clock_vdd_Level( - dc, DM_PP_CLOCK_TYPE_DPPCLK, clocks->dppclk_in_khz); + dc, DM_PP_CLOCK_TYPE_DPPCLK, clocks->dppclk_khz); vdd_level = dcn_bw_max(vdd_level, vdd_level_temp); vdd_level_temp = dcn_find_normalized_clock_vdd_Level( - dc, DM_PP_CLOCK_TYPE_MEMORY_CLK, clocks->dcfclock_in_khz); + dc, DM_PP_CLOCK_TYPE_MEMORY_CLK, clocks->fclk_khz); vdd_level = dcn_bw_max(vdd_level, vdd_level_temp); vdd_level_temp = dcn_find_normalized_clock_vdd_Level( - dc, DM_PP_CLOCK_TYPE_DCFCLK, clocks->dcfclock_in_khz); + dc, DM_PP_CLOCK_TYPE_DCFCLK, clocks->dcfclk_khz); /*find that level conresponding dcfclk*/ vdd_level = dcn_bw_max(vdd_level, vdd_level_temp); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 08b7ee526f0f..6155a5c7bd36 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -1290,15 +1290,13 @@ static enum dc_status enable_link_dp( state->dis_clk, DM_PP_CLOCKS_STATE_NOMINAL); } else { uint32_t dp_phyclk_in_khz; - const struct clocks_value clocks_value = - state->dis_clk->cur_clocks_value; + const struct dc_clocks clocks_value = + state->dis_clk->clks; /* 27mhz = 27000000hz= 27000khz */ dp_phyclk_in_khz = link_settings.link_rate * 27000; - if (((clocks_value.max_non_dp_phyclk_in_khz != 0) && - (dp_phyclk_in_khz > clocks_value.max_non_dp_phyclk_in_khz)) || - (dp_phyclk_in_khz > clocks_value.max_dp_phyclk_in_khz)) { + if (dp_phyclk_in_khz > clocks_value.phyclk_khz) { state->dis_clk->funcs->apply_clock_voltage_request( state->dis_clk, DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 7ebce7669eea..8ba90a75d128 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -186,6 +186,10 @@ enum wm_report_mode { WM_REPORT_OVERRIDE = 1, }; +/* + * For any clocks that may differ per pipe + * only the max is stored in this structure + */ struct dc_clocks { int dispclk_khz; int max_supported_dppclk_khz; @@ -194,6 +198,7 @@ struct dc_clocks { int socclk_khz; int dcfclk_deep_sleep_khz; int fclk_khz; + int phyclk_khz; }; struct dc_debug { diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index 8a581c67bf2d..b749a20a0c3d 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -560,11 +560,9 @@ static bool dce_apply_clock_voltage_request( switch (clocks_type) { case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - case DM_PP_CLOCK_TYPE_PIXELCLK: case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: break; default: - BREAK_TO_DEBUGGER(); return false; } @@ -575,31 +573,22 @@ static bool dce_apply_clock_voltage_request( if (pre_mode_set) { switch (clocks_type) { case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - if (clocks_in_khz > clk->cur_clocks_value.dispclk_in_khz) { - clk->cur_clocks_value.dispclk_notify_pplib_done = true; + if (clocks_in_khz > clk->clks.dispclk_khz) { + clk->dispclk_notify_pplib_done = true; send_request = true; } else - clk->cur_clocks_value.dispclk_notify_pplib_done = false; + clk->dispclk_notify_pplib_done = false; /* no matter incrase or decrase clock, update current clock value */ - clk->cur_clocks_value.dispclk_in_khz = clocks_in_khz; - break; - case DM_PP_CLOCK_TYPE_PIXELCLK: - if (clocks_in_khz > clk->cur_clocks_value.max_pixelclk_in_khz) { - clk->cur_clocks_value.pixelclk_notify_pplib_done = true; - send_request = true; - } else - clk->cur_clocks_value.pixelclk_notify_pplib_done = false; - /* no matter incrase or decrase clock, update current clock value */ - clk->cur_clocks_value.max_pixelclk_in_khz = clocks_in_khz; + clk->clks.dispclk_khz = clocks_in_khz; break; case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: - if (clocks_in_khz > clk->cur_clocks_value.max_non_dp_phyclk_in_khz) { - clk->cur_clocks_value.phyclk_notigy_pplib_done = true; + if (clocks_in_khz > clk->clks.phyclk_khz) { + clk->phyclk_notify_pplib_done = true; send_request = true; } else - clk->cur_clocks_value.phyclk_notigy_pplib_done = false; + clk->phyclk_notify_pplib_done = false; /* no matter incrase or decrase clock, update current clock value */ - clk->cur_clocks_value.max_non_dp_phyclk_in_khz = clocks_in_khz; + clk->clks.phyclk_khz = clocks_in_khz; break; default: ASSERT(0); @@ -609,16 +598,14 @@ static bool dce_apply_clock_voltage_request( } else { switch (clocks_type) { case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - if (!clk->cur_clocks_value.dispclk_notify_pplib_done) - send_request = true; - break; - case DM_PP_CLOCK_TYPE_PIXELCLK: - if (!clk->cur_clocks_value.pixelclk_notify_pplib_done) + if (!clk->dispclk_notify_pplib_done) send_request = true; + clk->dispclk_notify_pplib_done = true; break; case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: - if (!clk->cur_clocks_value.phyclk_notigy_pplib_done) + if (!clk->phyclk_notify_pplib_done) send_request = true; + clk->phyclk_notify_pplib_done = true; break; default: ASSERT(0); @@ -627,20 +614,21 @@ static bool dce_apply_clock_voltage_request( } if (send_request) { #if defined(CONFIG_DRM_AMD_DC_DCN1_0) - if (clk->ctx->dce_version >= DCN_VERSION_1_0) { + if (clk->ctx->dce_version >= DCN_VERSION_1_0 + ) { struct dc *core_dc = clk->ctx->dc; /*use dcfclk request voltage*/ clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; clock_voltage_req.clocks_in_khz = - dcn_find_dcfclk_suits_all(core_dc, &clk->cur_clocks_value); + dcn_find_dcfclk_suits_all(core_dc, &clk->clks); } #endif dm_pp_apply_clock_for_voltage_request( clk->ctx, &clock_voltage_req); } if (update_dp_phyclk && (clocks_in_khz > - clk->cur_clocks_value.max_dp_phyclk_in_khz)) - clk->cur_clocks_value.max_dp_phyclk_in_khz = clocks_in_khz; + clk->clks.phyclk_khz)) + clk->clks.phyclk_khz = clocks_in_khz; return true; } diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 353ffcbdf5ba..ddc8ffda9067 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1818,21 +1818,14 @@ static void apply_min_clocks( context->dis_clk->funcs->apply_clock_voltage_request( context->dis_clk, DM_PP_CLOCK_TYPE_DISPLAY_CLK, - context->dis_clk->cur_clocks_value.dispclk_in_khz, - pre_mode_set, - false); - - context->dis_clk->funcs->apply_clock_voltage_request( - context->dis_clk, - DM_PP_CLOCK_TYPE_PIXELCLK, - context->dis_clk->cur_clocks_value.max_pixelclk_in_khz, + context->dis_clk->clks.dispclk_khz, pre_mode_set, false); context->dis_clk->funcs->apply_clock_voltage_request( context->dis_clk, DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, - context->dis_clk->cur_clocks_value.max_non_dp_phyclk_in_khz, + context->dis_clk->clks.phyclk_khz, pre_mode_set, false); return; @@ -1859,13 +1852,6 @@ static void apply_min_clocks( pre_mode_set, false); - context->dis_clk->funcs->apply_clock_voltage_request( - context->dis_clk, - DM_PP_CLOCK_TYPE_PIXELCLK, - req_clocks.pixel_clk_khz, - pre_mode_set, - false); - context->dis_clk->funcs->apply_clock_voltage_request( context->dis_clk, DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, diff --git a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h index 132d18d4b293..ddbb673caa08 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h @@ -625,7 +625,7 @@ bool dcn_validate_bandwidth( unsigned int dcn_find_dcfclk_suits_all( const struct dc *dc, - struct clocks_value *clocks); + struct dc_clocks *clocks); void dcn_bw_update_from_pplib(struct dc *dc); void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h b/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h index f5f69cd81f6f..6b9ca5562de9 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h @@ -27,23 +27,7 @@ #define __DISPLAY_CLOCK_H__ #include "dm_services_types.h" - - -struct clocks_value { - int dispclk_in_khz; - int max_pixelclk_in_khz; - int max_non_dp_phyclk_in_khz; - int max_dp_phyclk_in_khz; - bool dispclk_notify_pplib_done; - bool pixelclk_notify_pplib_done; - bool phyclk_notigy_pplib_done; - int dcfclock_in_khz; - int dppclk_in_khz; - int mclk_in_khz; - int phyclk_in_khz; - int common_vdd_level; -}; - +#include "dc.h" /* Structure containing all state-dependent clocks * (dependent on "enum clocks_state") */ @@ -56,9 +40,11 @@ struct display_clock { struct dc_context *ctx; const struct display_clock_funcs *funcs; + bool dispclk_notify_pplib_done; + bool phyclk_notify_pplib_done; enum dm_pp_clocks_state max_clks_state; enum dm_pp_clocks_state cur_min_clks_state; - struct clocks_value cur_clocks_value; + struct dc_clocks clks; }; struct display_clock_funcs { From fab55d61b9f04693abc6fdbc92e3fdf3872915b1 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 23 May 2018 16:21:54 -0400 Subject: [PATCH 007/133] drm/amd/display: redesign dce/dcn clock voltage update request The goal of this change is to move clock programming and voltage requests to a single function. As of this change only dce is affected. Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 22 +- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 26 +- .../gpu/drm/amd/display/dc/dce/dce_clocks.c | 287 ++++++++++-------- .../gpu/drm/amd/display/dc/dce/dce_clocks.h | 6 +- .../display/dc/dce100/dce100_hw_sequencer.c | 49 ++- .../display/dc/dce110/dce110_hw_sequencer.c | 150 ++------- .../display/dc/dce110/dce110_hw_sequencer.h | 4 + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 9 +- .../drm/amd/display/dc/dcn10/dcn10_resource.c | 2 +- .../drm/amd/display/dc/inc/hw/display_clock.h | 21 +- 10 files changed, 252 insertions(+), 324 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index d8a31650e856..2b70ac67e6c2 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -1145,10 +1145,10 @@ static unsigned int dcn_find_normalized_clock_vdd_Level( switch (clocks_type) { case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - /*if (clocks_in_khz > dc->dcn_soc->max_dispclk_vmax0p9*1000) { + if (clocks_in_khz > dc->dcn_soc->max_dispclk_vmax0p9*1000) { vdd_level = dcn_bw_v_max0p91; - //BREAK_TO_DEBUGGER(); - } else*/ if (clocks_in_khz > dc->dcn_soc->max_dispclk_vnom0p8*1000) { + BREAK_TO_DEBUGGER(); + } else if (clocks_in_khz > dc->dcn_soc->max_dispclk_vnom0p8*1000) { vdd_level = dcn_bw_v_max0p9; } else if (clocks_in_khz > dc->dcn_soc->max_dispclk_vmid0p72*1000) { vdd_level = dcn_bw_v_nom0p8; @@ -1158,10 +1158,10 @@ static unsigned int dcn_find_normalized_clock_vdd_Level( vdd_level = dcn_bw_v_min0p65; break; case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: - /*if (clocks_in_khz > dc->dcn_soc->phyclkv_max0p9*1000) { + if (clocks_in_khz > dc->dcn_soc->phyclkv_max0p9*1000) { vdd_level = dcn_bw_v_max0p91; BREAK_TO_DEBUGGER(); - } else*/ if (clocks_in_khz > dc->dcn_soc->phyclkv_nom0p8*1000) { + } else if (clocks_in_khz > dc->dcn_soc->phyclkv_nom0p8*1000) { vdd_level = dcn_bw_v_max0p9; } else if (clocks_in_khz > dc->dcn_soc->phyclkv_mid0p72*1000) { vdd_level = dcn_bw_v_nom0p8; @@ -1172,10 +1172,10 @@ static unsigned int dcn_find_normalized_clock_vdd_Level( break; case DM_PP_CLOCK_TYPE_DPPCLK: - /*if (clocks_in_khz > dc->dcn_soc->max_dppclk_vmax0p9*1000) { + if (clocks_in_khz > dc->dcn_soc->max_dppclk_vmax0p9*1000) { vdd_level = dcn_bw_v_max0p91; BREAK_TO_DEBUGGER(); - } else*/ if (clocks_in_khz > dc->dcn_soc->max_dppclk_vnom0p8*1000) { + } else if (clocks_in_khz > dc->dcn_soc->max_dppclk_vnom0p8*1000) { vdd_level = dcn_bw_v_max0p9; } else if (clocks_in_khz > dc->dcn_soc->max_dppclk_vmid0p72*1000) { vdd_level = dcn_bw_v_nom0p8; @@ -1189,10 +1189,10 @@ static unsigned int dcn_find_normalized_clock_vdd_Level( { unsigned factor = (ddr4_dram_factor_single_Channel * dc->dcn_soc->number_of_channels); - /*if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9*1000000/factor) { + if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9*1000000/factor) { vdd_level = dcn_bw_v_max0p91; BREAK_TO_DEBUGGER(); - } else */if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8*1000000/factor) { + } else if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8*1000000/factor) { vdd_level = dcn_bw_v_max0p9; } else if (clocks_in_khz > dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72*1000000/factor) { vdd_level = dcn_bw_v_nom0p8; @@ -1204,10 +1204,10 @@ static unsigned int dcn_find_normalized_clock_vdd_Level( break; case DM_PP_CLOCK_TYPE_DCFCLK: - /*if (clocks_in_khz > dc->dcn_soc->dcfclkv_max0p9*1000) { + if (clocks_in_khz > dc->dcn_soc->dcfclkv_max0p9*1000) { vdd_level = dcn_bw_v_max0p91; BREAK_TO_DEBUGGER(); - } else */if (clocks_in_khz > dc->dcn_soc->dcfclkv_nom0p8*1000) { + } else if (clocks_in_khz > dc->dcn_soc->dcfclkv_nom0p8*1000) { vdd_level = dcn_bw_v_max0p9; } else if (clocks_in_khz > dc->dcn_soc->dcfclkv_mid0p72*1000) { vdd_level = dcn_bw_v_nom0p8; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 6155a5c7bd36..779d1926a756 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -1284,27 +1284,15 @@ static enum dc_status enable_link_dp( max_link_rate = LINK_RATE_HIGH3; if (link_settings.link_rate == max_link_rate) { - if (state->dis_clk->funcs->set_min_clocks_state) { - if (state->dis_clk->cur_min_clks_state < DM_PP_CLOCKS_STATE_NOMINAL) - state->dis_clk->funcs->set_min_clocks_state( - state->dis_clk, DM_PP_CLOCKS_STATE_NOMINAL); - } else { - uint32_t dp_phyclk_in_khz; - const struct dc_clocks clocks_value = - state->dis_clk->clks; + struct dc_clocks clocks = state->bw.dcn.calc_clk; - /* 27mhz = 27000000hz= 27000khz */ - dp_phyclk_in_khz = link_settings.link_rate * 27000; + /* dce/dcn compat, do not update dispclk */ + clocks.dispclk_khz = 0; + /* 27mhz = 27000000hz= 27000khz */ + clocks.phyclk_khz = link_settings.link_rate * 27000; - if (dp_phyclk_in_khz > clocks_value.phyclk_khz) { - state->dis_clk->funcs->apply_clock_voltage_request( - state->dis_clk, - DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, - dp_phyclk_in_khz, - false, - true); - } - } + state->dis_clk->funcs->update_clocks( + state->dis_clk, &clocks, false); } dp_enable_link_phy( diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index b749a20a0c3d..d3bbac85dff1 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -275,7 +275,7 @@ static int dce_clocks_get_dp_ref_freq_wrkaround(struct display_clock *clk) } static enum dm_pp_clocks_state dce_get_required_clocks_state( struct display_clock *clk, - struct state_dependent_clocks *req_clocks) + struct dc_clocks *req_clocks) { struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); int i; @@ -286,48 +286,25 @@ static enum dm_pp_clocks_state dce_get_required_clocks_state( * all required clocks */ for (i = clk->max_clks_state; i >= DM_PP_CLOCKS_STATE_ULTRA_LOW; i--) - if (req_clocks->display_clk_khz > + if (req_clocks->dispclk_khz > clk_dce->max_clks_by_state[i].display_clk_khz - || req_clocks->pixel_clk_khz > + || req_clocks->phyclk_khz > clk_dce->max_clks_by_state[i].pixel_clk_khz) break; low_req_clk = i + 1; if (low_req_clk > clk->max_clks_state) { - DC_LOG_WARNING("%s: clocks unsupported disp_clk %d pix_clk %d", - __func__, - req_clocks->display_clk_khz, - req_clocks->pixel_clk_khz); - low_req_clk = DM_PP_CLOCKS_STATE_INVALID; + /* set max clock state for high phyclock, invalid on exceeding display clock */ + if (clk_dce->max_clks_by_state[clk->max_clks_state].display_clk_khz + < req_clocks->dispclk_khz) + low_req_clk = DM_PP_CLOCKS_STATE_INVALID; + else + low_req_clk = clk->max_clks_state; } return low_req_clk; } -static bool dce_clock_set_min_clocks_state( - struct display_clock *clk, - enum dm_pp_clocks_state clocks_state) -{ - struct dm_pp_power_level_change_request level_change_req = { - clocks_state }; - - if (clocks_state > clk->max_clks_state) { - /*Requested state exceeds max supported state.*/ - DC_LOG_WARNING("Requested state exceeds max supported state"); - return false; - } else if (clocks_state == clk->cur_min_clks_state) { - /*if we're trying to set the same state, we can just return - * since nothing needs to be done*/ - return true; - } - - /* get max clock state from PPLIB */ - if (dm_pp_apply_power_level_change_request(clk->ctx, &level_change_req)) - clk->cur_min_clks_state = clocks_state; - - return true; -} - static int dce_set_clock( struct display_clock *clk, int requested_clk_khz) @@ -488,8 +465,6 @@ static void dce_clock_read_integrated_info(struct dce_disp_clk *clk_dce) if (!debug->disable_dfs_bypass && bp->integrated_info) if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) clk_dce->dfs_bypass_enabled = true; - - clk_dce->use_max_disp_clk = debug->max_disp_clk; } static void dce_clock_read_ss_info(struct dce_disp_clk *clk_dce) @@ -548,117 +523,160 @@ static void dce_clock_read_ss_info(struct dce_disp_clk *clk_dce) } } -static bool dce_apply_clock_voltage_request( - struct display_clock *clk, - enum dm_pp_clock_type clocks_type, - int clocks_in_khz, - bool pre_mode_set, - bool update_dp_phyclk) +static void dce12_update_clocks(struct display_clock *dccg, + struct dc_clocks *new_clocks, + bool safe_to_lower) { - bool send_request = false; struct dm_pp_clock_for_voltage_req clock_voltage_req = {0}; - switch (clocks_type) { - case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: - break; - default: - return false; + if ((new_clocks->dispclk_khz < dccg->clks.dispclk_khz && safe_to_lower) + || new_clocks->dispclk_khz > dccg->clks.dispclk_khz) { + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK; + clock_voltage_req.clocks_in_khz = new_clocks->dispclk_khz; + dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); + dccg->clks.dispclk_khz = new_clocks->dispclk_khz; + + dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); } - clock_voltage_req.clk_type = clocks_type; - clock_voltage_req.clocks_in_khz = clocks_in_khz; + if ((new_clocks->phyclk_khz < dccg->clks.phyclk_khz && safe_to_lower) + || new_clocks->phyclk_khz > dccg->clks.phyclk_khz) { + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAYPHYCLK; + clock_voltage_req.clocks_in_khz = new_clocks->phyclk_khz; + dccg->clks.phyclk_khz = new_clocks->phyclk_khz; - /* to pplib */ - if (pre_mode_set) { - switch (clocks_type) { - case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - if (clocks_in_khz > clk->clks.dispclk_khz) { - clk->dispclk_notify_pplib_done = true; - send_request = true; - } else - clk->dispclk_notify_pplib_done = false; - /* no matter incrase or decrase clock, update current clock value */ - clk->clks.dispclk_khz = clocks_in_khz; - break; - case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: - if (clocks_in_khz > clk->clks.phyclk_khz) { - clk->phyclk_notify_pplib_done = true; - send_request = true; - } else - clk->phyclk_notify_pplib_done = false; - /* no matter incrase or decrase clock, update current clock value */ - clk->clks.phyclk_khz = clocks_in_khz; - break; - default: - ASSERT(0); - break; - } - - } else { - switch (clocks_type) { - case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - if (!clk->dispclk_notify_pplib_done) - send_request = true; - clk->dispclk_notify_pplib_done = true; - break; - case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: - if (!clk->phyclk_notify_pplib_done) - send_request = true; - clk->phyclk_notify_pplib_done = true; - break; - default: - ASSERT(0); - break; - } + dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); } - if (send_request) { -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) - if (clk->ctx->dce_version >= DCN_VERSION_1_0 - ) { - struct dc *core_dc = clk->ctx->dc; - /*use dcfclk request voltage*/ - clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; - clock_voltage_req.clocks_in_khz = - dcn_find_dcfclk_suits_all(core_dc, &clk->clks); - } -#endif - dm_pp_apply_clock_for_voltage_request( - clk->ctx, &clock_voltage_req); - } - if (update_dp_phyclk && (clocks_in_khz > - clk->clks.phyclk_khz)) - clk->clks.phyclk_khz = clocks_in_khz; - - return true; } +static void dcn_update_clocks(struct display_clock *dccg, + struct dc_clocks *new_clocks, + bool safe_to_lower) +{ + struct dm_pp_clock_for_voltage_req clock_voltage_req = {0}; + bool send_request_to_increase = false; + bool send_request_to_lower = false; + + if (new_clocks->dispclk_khz > dccg->clks.dispclk_khz + || new_clocks->phyclk_khz > dccg->clks.phyclk_khz + || new_clocks->fclk_khz > dccg->clks.fclk_khz + || new_clocks->dcfclk_khz > dccg->clks.dcfclk_khz) + send_request_to_increase = true; + +#ifdef CONFIG_DRM_AMD_DC_DCN1_0 + if (send_request_to_increase + ) { + struct dc *core_dc = dccg->ctx->dc; + + /*use dcfclk to request voltage*/ + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; + clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(core_dc, new_clocks); + dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); + } +#endif + + if ((new_clocks->dispclk_khz < dccg->clks.dispclk_khz && safe_to_lower) + || new_clocks->dispclk_khz > dccg->clks.dispclk_khz) { + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK; + clock_voltage_req.clocks_in_khz = new_clocks->dispclk_khz; + /* TODO: ramp up - dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz);*/ + dccg->clks.dispclk_khz = new_clocks->dispclk_khz; + + dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); + send_request_to_lower = true; + } + + if ((new_clocks->phyclk_khz < dccg->clks.phyclk_khz && safe_to_lower) + || new_clocks->phyclk_khz > dccg->clks.phyclk_khz) { + dccg->clks.phyclk_khz = new_clocks->phyclk_khz; + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAYPHYCLK; + clock_voltage_req.clocks_in_khz = new_clocks->phyclk_khz; + + dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); + send_request_to_lower = true; + } + + if ((new_clocks->fclk_khz < dccg->clks.fclk_khz && safe_to_lower) + || new_clocks->fclk_khz > dccg->clks.fclk_khz) { + dccg->clks.phyclk_khz = new_clocks->fclk_khz; + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_FCLK; + clock_voltage_req.clocks_in_khz = new_clocks->fclk_khz; + + dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); + send_request_to_lower = true; + } + + if ((new_clocks->dcfclk_khz < dccg->clks.dcfclk_khz && safe_to_lower) + || new_clocks->dcfclk_khz > dccg->clks.dcfclk_khz) { + dccg->clks.phyclk_khz = new_clocks->dcfclk_khz; + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; + clock_voltage_req.clocks_in_khz = new_clocks->dcfclk_khz; + + send_request_to_lower = true; + } + +#ifdef CONFIG_DRM_AMD_DC_DCN1_0 + if (!send_request_to_increase && send_request_to_lower + ) { + struct dc *core_dc = dccg->ctx->dc; + + /*use dcfclk to request voltage*/ + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; + clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(core_dc, new_clocks); + dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); + } +#endif +} + +static void dce_update_clocks(struct display_clock *dccg, + struct dc_clocks *new_clocks, + bool safe_to_lower) +{ + struct dm_pp_power_level_change_request level_change_req; + + level_change_req.power_level = dce_get_required_clocks_state(dccg, new_clocks); + /* get max clock state from PPLIB */ + if ((level_change_req.power_level < dccg->cur_min_clks_state && safe_to_lower) + || level_change_req.power_level > dccg->cur_min_clks_state) { + if (dm_pp_apply_power_level_change_request(dccg->ctx, &level_change_req)) + dccg->cur_min_clks_state = level_change_req.power_level; + } + + if ((new_clocks->dispclk_khz < dccg->clks.dispclk_khz && safe_to_lower) + || new_clocks->dispclk_khz > dccg->clks.dispclk_khz) { + dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); + dccg->clks.dispclk_khz = new_clocks->dispclk_khz; + } +} + +static const struct display_clock_funcs dcn_funcs = { + .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq_wrkaround, + .set_dispclk = dce112_set_clock, + .update_clocks = dcn_update_clocks +}; static const struct display_clock_funcs dce120_funcs = { .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq_wrkaround, - .apply_clock_voltage_request = dce_apply_clock_voltage_request, - .set_clock = dce112_set_clock + .set_dispclk = dce112_set_clock, + .update_clocks = dce12_update_clocks }; static const struct display_clock_funcs dce112_funcs = { .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq, - .get_required_clocks_state = dce_get_required_clocks_state, - .set_min_clocks_state = dce_clock_set_min_clocks_state, - .set_clock = dce112_set_clock + .set_dispclk = dce112_set_clock, + .update_clocks = dce_update_clocks }; static const struct display_clock_funcs dce110_funcs = { .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq, - .get_required_clocks_state = dce_get_required_clocks_state, - .set_min_clocks_state = dce_clock_set_min_clocks_state, - .set_clock = dce_psr_set_clock + .set_dispclk = dce_psr_set_clock, + .update_clocks = dce_update_clocks }; static const struct display_clock_funcs dce_funcs = { .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq, - .get_required_clocks_state = dce_get_required_clocks_state, - .set_min_clocks_state = dce_clock_set_min_clocks_state, - .set_clock = dce_set_clock + .set_dispclk = dce_set_clock, + .update_clocks = dce_update_clocks }; static void dce_disp_clk_construct( @@ -785,7 +803,6 @@ struct display_clock *dce112_disp_clk_create( struct display_clock *dce120_disp_clk_create(struct dc_context *ctx) { struct dce_disp_clk *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); - struct dm_pp_clock_levels_with_voltage clk_level_info = {0}; if (clk_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -801,15 +818,23 @@ struct display_clock *dce120_disp_clk_create(struct dc_context *ctx) clk_dce->base.funcs = &dce120_funcs; - /* new in dce120 */ - if (!ctx->dc->debug.disable_pplib_clock_request && - dm_pp_get_clock_levels_by_type_with_voltage( - ctx, DM_PP_CLOCK_TYPE_DISPLAY_CLK, &clk_level_info) - && clk_level_info.num_levels) - clk_dce->max_displ_clk_in_khz = - clk_level_info.data[clk_level_info.num_levels - 1].clocks_in_khz; - else - clk_dce->max_displ_clk_in_khz = 1133000; + return &clk_dce->base; +} + +struct display_clock *dcn_disp_clk_create(struct dc_context *ctx) +{ + struct dce_disp_clk *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); + + if (clk_dce == NULL) { + BREAK_TO_DEBUGGER(); + return NULL; + } + + /* TODO strip out useful stuff out of dce constructor */ + dce_disp_clk_construct( + clk_dce, ctx, NULL, NULL, NULL); + + clk_dce->base.funcs = &dcn_funcs; return &clk_dce->base; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h index 0e717e0dc8f0..f9b002015255 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h @@ -91,7 +91,6 @@ struct dce_disp_clk { struct state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES]; struct dce_divider_range divider_ranges[DIVIDER_RANGE_MAX]; - bool use_max_disp_clk; int dentist_vco_freq_khz; /* Cache the status of DFS-bypass feature*/ @@ -106,9 +105,6 @@ struct dce_disp_clk { int dprefclk_ss_percentage; /* DPREFCLK SS percentage Divider (100 or 1000) */ int dprefclk_ss_divider; - - /* max disp_clk from PPLIB for max validation display clock*/ - int max_displ_clk_in_khz; }; @@ -132,6 +128,8 @@ struct display_clock *dce112_disp_clk_create( struct display_clock *dce120_disp_clk_create(struct dc_context *ctx); +struct display_clock *dcn_disp_clk_create(struct dc_context *ctx); + void dce_disp_clk_destroy(struct display_clock **disp_clk); #endif /* _DCE_CLOCKS_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c index 41f83ecd7469..aabf7ca9b241 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c @@ -125,17 +125,54 @@ static void dce100_pplib_apply_display_requirements( dc->prev_display_config = *pp_display_cfg; } +/* unit: in_khz before mode set, get pixel clock from context. ASIC register + * may not be programmed yet + */ +static uint32_t get_max_pixel_clock_for_all_paths( + struct dc *dc, + struct dc_state *context) +{ + uint32_t max_pix_clk = 0; + int i; + + for (i = 0; i < MAX_PIPES; i++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; + + if (pipe_ctx->stream == NULL) + continue; + + /* do not check under lay */ + if (pipe_ctx->top_pipe) + continue; + + if (pipe_ctx->stream_res.pix_clk_params.requested_pix_clk > max_pix_clk) + max_pix_clk = + pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; + } + + if (max_pix_clk == 0) + ASSERT(0); + + return max_pix_clk; +} + void dce100_set_bandwidth( struct dc *dc, struct dc_state *context, bool decrease_allowed) { - if (decrease_allowed || context->bw.dce.dispclk_khz > dc->current_state->bw.dce.dispclk_khz) { - dc->res_pool->display_clock->funcs->set_clock( - dc->res_pool->display_clock, - context->bw.dce.dispclk_khz * 115 / 100); - dc->current_state->bw.dce.dispclk_khz = context->bw.dce.dispclk_khz; - } + struct dc_clocks req_clks; + + req_clks.dispclk_khz = context->bw.dce.dispclk_khz * 115 / 100; + req_clks.phyclk_khz = get_max_pixel_clock_for_all_paths(dc, context); + + dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); + + dc->res_pool->display_clock->funcs->update_clocks( + dc->res_pool->display_clock, + &req_clks, + decrease_allowed); + dce100_pplib_apply_display_requirements(dc, context); } diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index ddc8ffda9067..02aa0a2ec875 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1663,7 +1663,7 @@ static void dce110_set_displaymarks( } } -static void set_safe_displaymarks( +void dce110_set_safe_displaymarks( struct resource_context *res_ctx, const struct resource_pool *pool) { @@ -1755,23 +1755,15 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx, } /* unit: in_khz before mode set, get pixel clock from context. ASIC register - * may not be programmed yet. - * TODO: after mode set, pre_mode_set = false, - * may read PLL register to get pixel clock + * may not be programmed yet */ static uint32_t get_max_pixel_clock_for_all_paths( struct dc *dc, - struct dc_state *context, - bool pre_mode_set) + struct dc_state *context) { uint32_t max_pix_clk = 0; int i; - if (!pre_mode_set) { - /* TODO: read ASIC register to get pixel clock */ - ASSERT(0); - } - for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; @@ -1793,74 +1785,6 @@ static uint32_t get_max_pixel_clock_for_all_paths( return max_pix_clk; } -/* - * Find clock state based on clock requested. if clock value is 0, simply - * set clock state as requested without finding clock state by clock value - */ - -static void apply_min_clocks( - struct dc *dc, - struct dc_state *context, - enum dm_pp_clocks_state *clocks_state, - bool pre_mode_set) -{ - struct state_dependent_clocks req_clocks = {0}; - - if (!pre_mode_set) { - /* set clock_state without verification */ - if (context->dis_clk->funcs->set_min_clocks_state) { - context->dis_clk->funcs->set_min_clocks_state( - context->dis_clk, *clocks_state); - return; - } - - /* TODO: This is incorrect. Figure out how to fix. */ - context->dis_clk->funcs->apply_clock_voltage_request( - context->dis_clk, - DM_PP_CLOCK_TYPE_DISPLAY_CLK, - context->dis_clk->clks.dispclk_khz, - pre_mode_set, - false); - - context->dis_clk->funcs->apply_clock_voltage_request( - context->dis_clk, - DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, - context->dis_clk->clks.phyclk_khz, - pre_mode_set, - false); - return; - } - - /* get the required state based on state dependent clocks: - * display clock and pixel clock - */ - req_clocks.display_clk_khz = context->bw.dce.dispclk_khz; - - req_clocks.pixel_clk_khz = get_max_pixel_clock_for_all_paths( - dc, context, true); - - if (context->dis_clk->funcs->get_required_clocks_state) { - *clocks_state = context->dis_clk->funcs->get_required_clocks_state( - context->dis_clk, &req_clocks); - context->dis_clk->funcs->set_min_clocks_state( - context->dis_clk, *clocks_state); - } else { - context->dis_clk->funcs->apply_clock_voltage_request( - context->dis_clk, - DM_PP_CLOCK_TYPE_DISPLAY_CLK, - req_clocks.display_clk_khz, - pre_mode_set, - false); - - context->dis_clk->funcs->apply_clock_voltage_request( - context->dis_clk, - DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, - req_clocks.pixel_clk_khz, - pre_mode_set, - false); - } -} - /* * Check if FBC can be enabled */ @@ -2079,7 +2003,6 @@ enum dc_status dce110_apply_ctx_to_hw( struct dc_bios *dcb = dc->ctx->dc_bios; enum dc_status status; int i; - enum dm_pp_clocks_state clocks_state = DM_PP_CLOCKS_STATE_INVALID; /* Reset old context */ /* look up the targets that have been removed since last commit */ @@ -2113,54 +2036,10 @@ enum dc_status dce110_apply_ctx_to_hw( PIPE_GATING_CONTROL_DISABLE); } - set_safe_displaymarks(&context->res_ctx, dc->res_pool); - if (dc->fbc_compressor) dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); - /*TODO: when pplib works*/ - apply_min_clocks(dc, context, &clocks_state, true); - -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) - if (dc->ctx->dce_version >= DCN_VERSION_1_0) { - if (context->bw.dcn.calc_clk.fclk_khz - > dc->current_state->bw.dcn.cur_clk.fclk_khz) { - struct dm_pp_clock_for_voltage_req clock; - - clock.clk_type = DM_PP_CLOCK_TYPE_FCLK; - clock.clocks_in_khz = context->bw.dcn.calc_clk.fclk_khz; - dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); - dc->current_state->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz; - context->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz; - } - if (context->bw.dcn.calc_clk.dcfclk_khz - > dc->current_state->bw.dcn.cur_clk.dcfclk_khz) { - struct dm_pp_clock_for_voltage_req clock; - - clock.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; - clock.clocks_in_khz = context->bw.dcn.calc_clk.dcfclk_khz; - dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); - dc->current_state->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz; - context->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz; - } - if (context->bw.dcn.calc_clk.dispclk_khz - > dc->current_state->bw.dcn.cur_clk.dispclk_khz) { - dc->res_pool->display_clock->funcs->set_clock( - dc->res_pool->display_clock, - context->bw.dcn.calc_clk.dispclk_khz); - dc->current_state->bw.dcn.cur_clk.dispclk_khz = - context->bw.dcn.calc_clk.dispclk_khz; - context->bw.dcn.cur_clk.dispclk_khz = - context->bw.dcn.calc_clk.dispclk_khz; - } - } else -#endif - if (context->bw.dce.dispclk_khz - > dc->current_state->bw.dce.dispclk_khz) { - dc->res_pool->display_clock->funcs->set_clock( - dc->res_pool->display_clock, - context->bw.dce.dispclk_khz * 115 / 100); - } + dc->hwss.set_bandwidth(dc, context, false); dce110_setup_audio_dto(dc, context); @@ -2191,7 +2070,7 @@ enum dc_status dce110_apply_ctx_to_hw( } /* to save power */ - apply_min_clocks(dc, context, &clocks_state, false); + dc->hwss.set_bandwidth(dc, context, true); dcb->funcs->set_scratch_critical_state(dcb, false); @@ -2680,15 +2559,20 @@ static void dce110_set_bandwidth( struct dc_state *context, bool decrease_allowed) { - dce110_set_displaymarks(dc, context); + struct dc_clocks req_clks; - if (decrease_allowed || context->bw.dce.dispclk_khz > dc->current_state->bw.dce.dispclk_khz) { - dc->res_pool->display_clock->funcs->set_clock( - dc->res_pool->display_clock, - context->bw.dce.dispclk_khz * 115 / 100); - dc->current_state->bw.dce.dispclk_khz = context->bw.dce.dispclk_khz; - } + req_clks.dispclk_khz = context->bw.dce.dispclk_khz * 115 / 100; + req_clks.phyclk_khz = get_max_pixel_clock_for_all_paths(dc, context); + if (decrease_allowed) + dce110_set_displaymarks(dc, context); + else + dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); + + dc->res_pool->display_clock->funcs->update_clocks( + dc->res_pool->display_clock, + &req_clks, + decrease_allowed); pplib_apply_display_requirements(dc, context); } diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h index f48d5a68d238..d6db3dbd9015 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h @@ -60,6 +60,10 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context); void dce110_power_down(struct dc *dc); +void dce110_set_safe_displaymarks( + struct resource_context *res_ctx, + const struct resource_pool *pool); + void dce110_fill_display_configs( const struct dc_state *context, struct dm_pp_display_configuration *pp_display_cfg); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 03eb736a312f..7f1a7ec9ff5f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2424,7 +2424,7 @@ static void ramp_up_dispclk_with_dpp(struct dc *dc, struct dc_state *context) int dispclk_to_dpp_threshold = determine_dppclk_threshold(dc, context); /* set disp clk to dpp clk threshold */ - dc->res_pool->display_clock->funcs->set_clock( + dc->res_pool->display_clock->funcs->set_dispclk( dc->res_pool->display_clock, dispclk_to_dpp_threshold); @@ -2443,7 +2443,7 @@ static void ramp_up_dispclk_with_dpp(struct dc *dc, struct dc_state *context) /* If target clk not same as dppclk threshold, set to target clock */ if (dispclk_to_dpp_threshold != context->bw.dcn.calc_clk.dispclk_khz) { - dc->res_pool->display_clock->funcs->set_clock( + dc->res_pool->display_clock->funcs->set_dispclk( dc->res_pool->display_clock, context->bw.dcn.calc_clk.dispclk_khz); } @@ -2473,6 +2473,11 @@ static void dcn10_set_bandwidth( if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) return; + dc->res_pool->display_clock->funcs->update_clocks( + dc->res_pool->display_clock, + &context->bw.dcn.calc_clk, + decrease_allowed); + if (should_set_clock( decrease_allowed, context->bw.dcn.calc_clk.dcfclk_khz, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 2da325ce781b..870eb0aabcc9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1072,7 +1072,7 @@ static bool construct( } } - pool->base.display_clock = dce120_disp_clk_create(ctx); + pool->base.display_clock = dcn_disp_clk_create(ctx); if (pool->base.display_clock == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h b/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h index 6b9ca5562de9..8ce106f15647 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h @@ -40,32 +40,19 @@ struct display_clock { struct dc_context *ctx; const struct display_clock_funcs *funcs; - bool dispclk_notify_pplib_done; - bool phyclk_notify_pplib_done; enum dm_pp_clocks_state max_clks_state; enum dm_pp_clocks_state cur_min_clks_state; struct dc_clocks clks; }; struct display_clock_funcs { - int (*set_clock)(struct display_clock *disp_clk, + void (*update_clocks)(struct display_clock *dccg, + struct dc_clocks *new_clocks, + bool safe_to_lower); + int (*set_dispclk)(struct display_clock *disp_clk, int requested_clock_khz); - enum dm_pp_clocks_state (*get_required_clocks_state)( - struct display_clock *disp_clk, - struct state_dependent_clocks *req_clocks); - - bool (*set_min_clocks_state)(struct display_clock *disp_clk, - enum dm_pp_clocks_state dm_pp_clocks_state); - int (*get_dp_ref_clk_frequency)(struct display_clock *disp_clk); - - bool (*apply_clock_voltage_request)( - struct display_clock *disp_clk, - enum dm_pp_clock_type clocks_type, - int clocks_in_khz, - bool pre_mode_set, - bool update_dp_phyclk); }; #endif /* __DISPLAY_CLOCK_H__ */ From 6ca11246180a6e5e6b5b668545c2575b304c9f7f Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 23 May 2018 16:44:26 -0400 Subject: [PATCH 008/133] drm/amd/display: rename display clock block to dccg Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/core/dc_resource.c | 2 +- .../gpu/drm/amd/display/dc/dce/dce_clocks.c | 78 +++++++++---------- .../gpu/drm/amd/display/dc/dce/dce_clocks.h | 16 ++-- .../display/dc/dce100/dce100_hw_sequencer.c | 4 +- .../amd/display/dc/dce100/dce100_resource.c | 10 +-- .../display/dc/dce110/dce110_hw_sequencer.c | 4 +- .../amd/display/dc/dce110/dce110_resource.c | 10 +-- .../amd/display/dc/dce112/dce112_resource.c | 10 +-- .../amd/display/dc/dce120/dce120_resource.c | 12 +-- .../drm/amd/display/dc/dce80/dce80_resource.c | 22 +++--- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 12 +-- .../drm/amd/display/dc/dcn10/dcn10_resource.c | 8 +- .../gpu/drm/amd/display/dc/inc/core_types.h | 4 +- .../drm/amd/display/dc/inc/hw/display_clock.h | 8 +- 14 files changed, 100 insertions(+), 100 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index fca22550417a..c5fc5250e2bf 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1948,7 +1948,7 @@ void dc_resource_state_construct( const struct dc *dc, struct dc_state *dst_ctx) { - dst_ctx->dis_clk = dc->res_pool->display_clock; + dst_ctx->dis_clk = dc->res_pool->dccg; } enum dc_status dc_validate_global_state( diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index d3bbac85dff1..890a3ec68d49 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -38,7 +38,7 @@ #include "dal_asic_id.h" #define TO_DCE_CLOCKS(clocks)\ - container_of(clocks, struct dce_disp_clk, base) + container_of(clocks, struct dce_dccg, base) #define REG(reg) \ (clk_dce->regs->reg) @@ -187,9 +187,9 @@ static int dce_divider_range_get_divider( return div; } -static int dce_clocks_get_dp_ref_freq(struct display_clock *clk) +static int dce_clocks_get_dp_ref_freq(struct dccg *clk) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); int dprefclk_wdivider; int dprefclk_src_sel; int dp_ref_clk_khz = 600000; @@ -250,9 +250,9 @@ static int dce_clocks_get_dp_ref_freq(struct display_clock *clk) * or CLK0_CLK11 by SMU. For DCE120, it is wlays 600Mhz. Will re-visit * clock implementation */ -static int dce_clocks_get_dp_ref_freq_wrkaround(struct display_clock *clk) +static int dce_clocks_get_dp_ref_freq_wrkaround(struct dccg *clk) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); int dp_ref_clk_khz = 600000; if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) { @@ -274,10 +274,10 @@ static int dce_clocks_get_dp_ref_freq_wrkaround(struct display_clock *clk) return dp_ref_clk_khz; } static enum dm_pp_clocks_state dce_get_required_clocks_state( - struct display_clock *clk, + struct dccg *clk, struct dc_clocks *req_clocks) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); int i; enum dm_pp_clocks_state low_req_clk; @@ -306,10 +306,10 @@ static enum dm_pp_clocks_state dce_get_required_clocks_state( } static int dce_set_clock( - struct display_clock *clk, + struct dccg *clk, int requested_clk_khz) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); struct bp_pixel_clock_parameters pxl_clk_params = { 0 }; struct dc_bios *bp = clk->ctx->dc_bios; int actual_clock = requested_clk_khz; @@ -341,10 +341,10 @@ static int dce_set_clock( } static int dce_psr_set_clock( - struct display_clock *clk, + struct dccg *clk, int requested_clk_khz) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); struct dc_context *ctx = clk_dce->base.ctx; struct dc *core_dc = ctx->dc; struct dmcu *dmcu = core_dc->res_pool->dmcu; @@ -357,10 +357,10 @@ static int dce_psr_set_clock( } static int dce112_set_clock( - struct display_clock *clk, + struct dccg *clk, int requested_clk_khz) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); struct bp_set_dce_clock_parameters dce_clk_params; struct dc_bios *bp = clk->ctx->dc_bios; struct dc *core_dc = clk->ctx->dc; @@ -409,7 +409,7 @@ static int dce112_set_clock( return actual_clock; } -static void dce_clock_read_integrated_info(struct dce_disp_clk *clk_dce) +static void dce_clock_read_integrated_info(struct dce_dccg *clk_dce) { struct dc_debug *debug = &clk_dce->base.ctx->dc->debug; struct dc_bios *bp = clk_dce->base.ctx->dc_bios; @@ -467,7 +467,7 @@ static void dce_clock_read_integrated_info(struct dce_disp_clk *clk_dce) clk_dce->dfs_bypass_enabled = true; } -static void dce_clock_read_ss_info(struct dce_disp_clk *clk_dce) +static void dce_clock_read_ss_info(struct dce_dccg *clk_dce) { struct dc_bios *bp = clk_dce->base.ctx->dc_bios; int ss_info_num = bp->funcs->get_ss_entry_number( @@ -523,7 +523,7 @@ static void dce_clock_read_ss_info(struct dce_disp_clk *clk_dce) } } -static void dce12_update_clocks(struct display_clock *dccg, +static void dce12_update_clocks(struct dccg *dccg, struct dc_clocks *new_clocks, bool safe_to_lower) { @@ -549,7 +549,7 @@ static void dce12_update_clocks(struct display_clock *dccg, } } -static void dcn_update_clocks(struct display_clock *dccg, +static void dcn_update_clocks(struct dccg *dccg, struct dc_clocks *new_clocks, bool safe_to_lower) { @@ -628,7 +628,7 @@ static void dcn_update_clocks(struct display_clock *dccg, #endif } -static void dce_update_clocks(struct display_clock *dccg, +static void dce_update_clocks(struct dccg *dccg, struct dc_clocks *new_clocks, bool safe_to_lower) { @@ -679,14 +679,14 @@ static const struct display_clock_funcs dce_funcs = { .update_clocks = dce_update_clocks }; -static void dce_disp_clk_construct( - struct dce_disp_clk *clk_dce, +static void dce_dccg_construct( + struct dce_dccg *clk_dce, struct dc_context *ctx, const struct dce_disp_clk_registers *regs, const struct dce_disp_clk_shift *clk_shift, const struct dce_disp_clk_mask *clk_mask) { - struct display_clock *base = &clk_dce->base; + struct dccg *base = &clk_dce->base; base->ctx = ctx; base->funcs = &dce_funcs; @@ -727,13 +727,13 @@ static void dce_disp_clk_construct( DIVIDER_RANGE_MAX_DIVIDER_ID); } -struct display_clock *dce_disp_clk_create( +struct dccg *dce_dccg_create( struct dc_context *ctx, const struct dce_disp_clk_registers *regs, const struct dce_disp_clk_shift *clk_shift, const struct dce_disp_clk_mask *clk_mask) { - struct dce_disp_clk *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); + struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); if (clk_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -744,19 +744,19 @@ struct display_clock *dce_disp_clk_create( dce80_max_clks_by_state, sizeof(dce80_max_clks_by_state)); - dce_disp_clk_construct( + dce_dccg_construct( clk_dce, ctx, regs, clk_shift, clk_mask); return &clk_dce->base; } -struct display_clock *dce110_disp_clk_create( +struct dccg *dce110_dccg_create( struct dc_context *ctx, const struct dce_disp_clk_registers *regs, const struct dce_disp_clk_shift *clk_shift, const struct dce_disp_clk_mask *clk_mask) { - struct dce_disp_clk *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); + struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); if (clk_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -767,7 +767,7 @@ struct display_clock *dce110_disp_clk_create( dce110_max_clks_by_state, sizeof(dce110_max_clks_by_state)); - dce_disp_clk_construct( + dce_dccg_construct( clk_dce, ctx, regs, clk_shift, clk_mask); clk_dce->base.funcs = &dce110_funcs; @@ -775,13 +775,13 @@ struct display_clock *dce110_disp_clk_create( return &clk_dce->base; } -struct display_clock *dce112_disp_clk_create( +struct dccg *dce112_dccg_create( struct dc_context *ctx, const struct dce_disp_clk_registers *regs, const struct dce_disp_clk_shift *clk_shift, const struct dce_disp_clk_mask *clk_mask) { - struct dce_disp_clk *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); + struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); if (clk_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -792,7 +792,7 @@ struct display_clock *dce112_disp_clk_create( dce112_max_clks_by_state, sizeof(dce112_max_clks_by_state)); - dce_disp_clk_construct( + dce_dccg_construct( clk_dce, ctx, regs, clk_shift, clk_mask); clk_dce->base.funcs = &dce112_funcs; @@ -800,9 +800,9 @@ struct display_clock *dce112_disp_clk_create( return &clk_dce->base; } -struct display_clock *dce120_disp_clk_create(struct dc_context *ctx) +struct dccg *dce120_dccg_create(struct dc_context *ctx) { - struct dce_disp_clk *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); + struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); if (clk_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -813,7 +813,7 @@ struct display_clock *dce120_disp_clk_create(struct dc_context *ctx) dce120_max_clks_by_state, sizeof(dce120_max_clks_by_state)); - dce_disp_clk_construct( + dce_dccg_construct( clk_dce, ctx, NULL, NULL, NULL); clk_dce->base.funcs = &dce120_funcs; @@ -821,9 +821,9 @@ struct display_clock *dce120_disp_clk_create(struct dc_context *ctx) return &clk_dce->base; } -struct display_clock *dcn_disp_clk_create(struct dc_context *ctx) +struct dccg *dcn_dccg_create(struct dc_context *ctx) { - struct dce_disp_clk *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); + struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); if (clk_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -831,7 +831,7 @@ struct display_clock *dcn_disp_clk_create(struct dc_context *ctx) } /* TODO strip out useful stuff out of dce constructor */ - dce_disp_clk_construct( + dce_dccg_construct( clk_dce, ctx, NULL, NULL, NULL); clk_dce->base.funcs = &dcn_funcs; @@ -839,10 +839,10 @@ struct display_clock *dcn_disp_clk_create(struct dc_context *ctx) return &clk_dce->base; } -void dce_disp_clk_destroy(struct display_clock **disp_clk) +void dce_dccg_destroy(struct dccg **dccg) { - struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(*disp_clk); + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(*dccg); kfree(clk_dce); - *disp_clk = NULL; + *dccg = NULL; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h index f9b002015255..c695b9c9bcb5 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h @@ -82,8 +82,8 @@ struct dce_divider_range { int did_max; }; -struct dce_disp_clk { - struct display_clock base; +struct dce_dccg { + struct dccg base; const struct dce_disp_clk_registers *regs; const struct dce_disp_clk_shift *clk_shift; const struct dce_disp_clk_mask *clk_mask; @@ -108,28 +108,28 @@ struct dce_disp_clk { }; -struct display_clock *dce_disp_clk_create( +struct dccg *dce_dccg_create( struct dc_context *ctx, const struct dce_disp_clk_registers *regs, const struct dce_disp_clk_shift *clk_shift, const struct dce_disp_clk_mask *clk_mask); -struct display_clock *dce110_disp_clk_create( +struct dccg *dce110_dccg_create( struct dc_context *ctx, const struct dce_disp_clk_registers *regs, const struct dce_disp_clk_shift *clk_shift, const struct dce_disp_clk_mask *clk_mask); -struct display_clock *dce112_disp_clk_create( +struct dccg *dce112_dccg_create( struct dc_context *ctx, const struct dce_disp_clk_registers *regs, const struct dce_disp_clk_shift *clk_shift, const struct dce_disp_clk_mask *clk_mask); -struct display_clock *dce120_disp_clk_create(struct dc_context *ctx); +struct dccg *dce120_dccg_create(struct dc_context *ctx); -struct display_clock *dcn_disp_clk_create(struct dc_context *ctx); +struct dccg *dcn_dccg_create(struct dc_context *ctx); -void dce_disp_clk_destroy(struct display_clock **disp_clk); +void dce_dccg_destroy(struct dccg **dccg); #endif /* _DCE_CLOCKS_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c index aabf7ca9b241..ec3221333011 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c @@ -168,8 +168,8 @@ void dce100_set_bandwidth( dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); - dc->res_pool->display_clock->funcs->update_clocks( - dc->res_pool->display_clock, + dc->res_pool->dccg->funcs->update_clocks( + dc->res_pool->dccg, &req_clks, decrease_allowed); diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index 38ec0d609297..856d3fe8e6a0 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c @@ -644,8 +644,8 @@ static void destruct(struct dce110_resource_pool *pool) dce_aud_destroy(&pool->base.audios[i]); } - if (pool->base.display_clock != NULL) - dce_disp_clk_destroy(&pool->base.display_clock); + if (pool->base.dccg != NULL) + dce_dccg_destroy(&pool->base.dccg); if (pool->base.abm != NULL) dce_abm_destroy(&pool->base.abm); @@ -817,11 +817,11 @@ static bool construct( } } - pool->base.display_clock = dce_disp_clk_create(ctx, + pool->base.dccg = dce_dccg_create(ctx, &disp_clk_regs, &disp_clk_shift, &disp_clk_mask); - if (pool->base.display_clock == NULL) { + if (pool->base.dccg == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; @@ -851,7 +851,7 @@ static bool construct( * max_clock_state */ if (dm_pp_get_static_clocks(ctx, &static_clk_info)) - pool->base.display_clock->max_clks_state = + pool->base.dccg->max_clks_state = static_clk_info.max_clocks_state; { struct irq_service_init_data init_data; diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 02aa0a2ec875..34eb7a33851b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -2569,8 +2569,8 @@ static void dce110_set_bandwidth( else dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); - dc->res_pool->display_clock->funcs->update_clocks( - dc->res_pool->display_clock, + dc->res_pool->dccg->funcs->update_clocks( + dc->res_pool->dccg, &req_clks, decrease_allowed); pplib_apply_display_requirements(dc, context); 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 20c029089551..71a401f73a58 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -679,8 +679,8 @@ static void destruct(struct dce110_resource_pool *pool) if (pool->base.dmcu != NULL) dce_dmcu_destroy(&pool->base.dmcu); - if (pool->base.display_clock != NULL) - dce_disp_clk_destroy(&pool->base.display_clock); + if (pool->base.dccg != NULL) + dce_dccg_destroy(&pool->base.dccg); if (pool->base.irqs != NULL) { dal_irq_service_destroy(&pool->base.irqs); @@ -1179,11 +1179,11 @@ static bool construct( } } - pool->base.display_clock = dce110_disp_clk_create(ctx, + pool->base.dccg = dce110_dccg_create(ctx, &disp_clk_regs, &disp_clk_shift, &disp_clk_mask); - if (pool->base.display_clock == NULL) { + if (pool->base.dccg == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; @@ -1213,7 +1213,7 @@ static bool construct( * max_clock_state */ if (dm_pp_get_static_clocks(ctx, &static_clk_info)) - pool->base.display_clock->max_clks_state = + pool->base.dccg->max_clks_state = static_clk_info.max_clocks_state; { diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index 00c0a1ef15eb..ae5b19de559c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c @@ -668,8 +668,8 @@ static void destruct(struct dce110_resource_pool *pool) if (pool->base.dmcu != NULL) dce_dmcu_destroy(&pool->base.dmcu); - if (pool->base.display_clock != NULL) - dce_disp_clk_destroy(&pool->base.display_clock); + if (pool->base.dccg != NULL) + dce_dccg_destroy(&pool->base.dccg); if (pool->base.irqs != NULL) { dal_irq_service_destroy(&pool->base.irqs); @@ -1124,11 +1124,11 @@ static bool construct( } } - pool->base.display_clock = dce112_disp_clk_create(ctx, + pool->base.dccg = dce112_dccg_create(ctx, &disp_clk_regs, &disp_clk_shift, &disp_clk_mask); - if (pool->base.display_clock == NULL) { + if (pool->base.dccg == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; @@ -1158,7 +1158,7 @@ static bool construct( * max_clock_state */ if (dm_pp_get_static_clocks(ctx, &static_clk_info)) - pool->base.display_clock->max_clks_state = + pool->base.dccg->max_clks_state = static_clk_info.max_clocks_state; { diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c index 2d58daccc005..13c388a608c4 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c @@ -494,8 +494,8 @@ static void destruct(struct dce110_resource_pool *pool) if (pool->base.dmcu != NULL) dce_dmcu_destroy(&pool->base.dmcu); - if (pool->base.display_clock != NULL) - dce_disp_clk_destroy(&pool->base.display_clock); + if (pool->base.dccg != NULL) + dce_dccg_destroy(&pool->base.dccg); } static void read_dce_straps( @@ -894,11 +894,11 @@ static bool construct( } } - pool->base.display_clock = dce120_disp_clk_create(ctx); - if (pool->base.display_clock == NULL) { + pool->base.dccg = dce120_dccg_create(ctx); + if (pool->base.dccg == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); - goto disp_clk_create_fail; + goto dccg_create_fail; } pool->base.dmcu = dce_dmcu_create(ctx, @@ -1011,7 +1011,7 @@ static bool construct( irqs_create_fail: controller_create_fail: -disp_clk_create_fail: +dccg_create_fail: clk_src_create_fail: res_create_fail: diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c index 48a068964722..70700530aec2 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c @@ -683,8 +683,8 @@ static void destruct(struct dce110_resource_pool *pool) } } - if (pool->base.display_clock != NULL) - dce_disp_clk_destroy(&pool->base.display_clock); + if (pool->base.dccg != NULL) + dce_dccg_destroy(&pool->base.dccg); if (pool->base.irqs != NULL) { dal_irq_service_destroy(&pool->base.irqs); @@ -822,11 +822,11 @@ static bool dce80_construct( } } - pool->base.display_clock = dce_disp_clk_create(ctx, + pool->base.dccg = dce_dccg_create(ctx, &disp_clk_regs, &disp_clk_shift, &disp_clk_mask); - if (pool->base.display_clock == NULL) { + if (pool->base.dccg == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; @@ -852,7 +852,7 @@ static bool dce80_construct( goto res_create_fail; } if (dm_pp_get_static_clocks(ctx, &static_clk_info)) - pool->base.display_clock->max_clks_state = + pool->base.dccg->max_clks_state = static_clk_info.max_clocks_state; { @@ -1006,11 +1006,11 @@ static bool dce81_construct( } } - pool->base.display_clock = dce_disp_clk_create(ctx, + pool->base.dccg = dce_dccg_create(ctx, &disp_clk_regs, &disp_clk_shift, &disp_clk_mask); - if (pool->base.display_clock == NULL) { + if (pool->base.dccg == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; @@ -1037,7 +1037,7 @@ static bool dce81_construct( } if (dm_pp_get_static_clocks(ctx, &static_clk_info)) - pool->base.display_clock->max_clks_state = + pool->base.dccg->max_clks_state = static_clk_info.max_clocks_state; { @@ -1187,11 +1187,11 @@ static bool dce83_construct( } } - pool->base.display_clock = dce_disp_clk_create(ctx, + pool->base.dccg = dce_dccg_create(ctx, &disp_clk_regs, &disp_clk_shift, &disp_clk_mask); - if (pool->base.display_clock == NULL) { + if (pool->base.dccg == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); goto res_create_fail; @@ -1218,7 +1218,7 @@ static bool dce83_construct( } if (dm_pp_get_static_clocks(ctx, &static_clk_info)) - pool->base.display_clock->max_clks_state = + pool->base.dccg->max_clks_state = static_clk_info.max_clocks_state; { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 7f1a7ec9ff5f..f519b98f4b23 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2424,8 +2424,8 @@ static void ramp_up_dispclk_with_dpp(struct dc *dc, struct dc_state *context) int dispclk_to_dpp_threshold = determine_dppclk_threshold(dc, context); /* set disp clk to dpp clk threshold */ - dc->res_pool->display_clock->funcs->set_dispclk( - dc->res_pool->display_clock, + dc->res_pool->dccg->funcs->set_dispclk( + dc->res_pool->dccg, dispclk_to_dpp_threshold); /* update request dpp clk division option */ @@ -2443,8 +2443,8 @@ static void ramp_up_dispclk_with_dpp(struct dc *dc, struct dc_state *context) /* If target clk not same as dppclk threshold, set to target clock */ if (dispclk_to_dpp_threshold != context->bw.dcn.calc_clk.dispclk_khz) { - dc->res_pool->display_clock->funcs->set_dispclk( - dc->res_pool->display_clock, + dc->res_pool->dccg->funcs->set_dispclk( + dc->res_pool->dccg, context->bw.dcn.calc_clk.dispclk_khz); } @@ -2473,8 +2473,8 @@ static void dcn10_set_bandwidth( if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) return; - dc->res_pool->display_clock->funcs->update_clocks( - dc->res_pool->display_clock, + dc->res_pool->dccg->funcs->update_clocks( + dc->res_pool->dccg, &context->bw.dcn.calc_clk, decrease_allowed); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 870eb0aabcc9..8f1ceffa809b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -791,8 +791,8 @@ static void destruct(struct dcn10_resource_pool *pool) if (pool->base.dmcu != NULL) dce_dmcu_destroy(&pool->base.dmcu); - if (pool->base.display_clock != NULL) - dce_disp_clk_destroy(&pool->base.display_clock); + if (pool->base.dccg != NULL) + dce_dccg_destroy(&pool->base.dccg); kfree(pool->base.pp_smu); } @@ -1072,8 +1072,8 @@ static bool construct( } } - pool->base.display_clock = dcn_disp_clk_create(ctx); - if (pool->base.display_clock == NULL) { + pool->base.dccg = dcn_dccg_create(ctx); + if (pool->base.dccg == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); goto fail; diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 4beddca0180c..44c48f3d0a1d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -163,7 +163,7 @@ struct resource_pool { unsigned int audio_count; struct audio_support audio_support; - struct display_clock *display_clock; + struct dccg *dccg; struct irq_service *irqs; struct abm *abm; @@ -282,7 +282,7 @@ struct dc_state { struct dcn_bw_internal_vars dcn_bw_vars; #endif - struct display_clock *dis_clk; + struct dccg *dis_clk; struct kref refcount; }; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h b/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h index 8ce106f15647..3c7ccb68ecdb 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h @@ -36,7 +36,7 @@ struct state_dependent_clocks { int pixel_clk_khz; }; -struct display_clock { +struct dccg { struct dc_context *ctx; const struct display_clock_funcs *funcs; @@ -46,13 +46,13 @@ struct display_clock { }; struct display_clock_funcs { - void (*update_clocks)(struct display_clock *dccg, + void (*update_clocks)(struct dccg *dccg, struct dc_clocks *new_clocks, bool safe_to_lower); - int (*set_dispclk)(struct display_clock *disp_clk, + int (*set_dispclk)(struct dccg *dccg, int requested_clock_khz); - int (*get_dp_ref_clk_frequency)(struct display_clock *disp_clk); + int (*get_dp_ref_clk_frequency)(struct dccg *dccg); }; #endif /* __DISPLAY_CLOCK_H__ */ From e2e0a1dcd3229eec32ded439f69438a25ec817d6 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 23 May 2018 17:52:04 -0400 Subject: [PATCH 009/133] drm/amd/display: move clock programming from set_bandwidth to dccg This change moves dcn clock programming(with exception of dispclk) into dccg. This should have no functional effect. Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 2 +- .../gpu/drm/amd/display/dc/dce/dce_clocks.c | 57 +++++++++++------ .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 62 ++++--------------- 3 files changed, 51 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 2b70ac67e6c2..9acdd9da740e 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -997,7 +997,7 @@ bool dcn_validate_bandwidth( } context->bw.dcn.calc_clk.dppclk_khz = context->bw.dcn.calc_clk.dispclk_khz / v->dispclk_dppclk_ratio; - + context->bw.dcn.calc_clk.phyclk_khz = v->phyclk_per_state[v->voltage_level]; switch (v->voltage_level) { case 0: context->bw.dcn.calc_clk.max_supported_dppclk_khz = diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index 890a3ec68d49..93e6063c4b97 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -523,14 +523,18 @@ static void dce_clock_read_ss_info(struct dce_dccg *clk_dce) } } +static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_clk) +{ + return ((safe_to_lower && calc_clk < cur_clk) || calc_clk > cur_clk); +} + static void dce12_update_clocks(struct dccg *dccg, struct dc_clocks *new_clocks, bool safe_to_lower) { struct dm_pp_clock_for_voltage_req clock_voltage_req = {0}; - if ((new_clocks->dispclk_khz < dccg->clks.dispclk_khz && safe_to_lower) - || new_clocks->dispclk_khz > dccg->clks.dispclk_khz) { + if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK; clock_voltage_req.clocks_in_khz = new_clocks->dispclk_khz; dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); @@ -539,8 +543,7 @@ static void dce12_update_clocks(struct dccg *dccg, dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); } - if ((new_clocks->phyclk_khz < dccg->clks.phyclk_khz && safe_to_lower) - || new_clocks->phyclk_khz > dccg->clks.phyclk_khz) { + if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, dccg->clks.phyclk_khz)) { clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAYPHYCLK; clock_voltage_req.clocks_in_khz = new_clocks->phyclk_khz; dccg->clks.phyclk_khz = new_clocks->phyclk_khz; @@ -553,6 +556,11 @@ static void dcn_update_clocks(struct dccg *dccg, struct dc_clocks *new_clocks, bool safe_to_lower) { + struct dc *dc = dccg->ctx->dc; + struct pp_smu_display_requirement_rv *smu_req_cur = + &dc->res_pool->pp_smu_req; + struct pp_smu_display_requirement_rv smu_req = *smu_req_cur; + struct pp_smu_funcs_rv *pp_smu = dc->res_pool->pp_smu; struct dm_pp_clock_for_voltage_req clock_voltage_req = {0}; bool send_request_to_increase = false; bool send_request_to_lower = false; @@ -566,17 +574,14 @@ static void dcn_update_clocks(struct dccg *dccg, #ifdef CONFIG_DRM_AMD_DC_DCN1_0 if (send_request_to_increase ) { - struct dc *core_dc = dccg->ctx->dc; - /*use dcfclk to request voltage*/ clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; - clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(core_dc, new_clocks); + clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); } #endif - if ((new_clocks->dispclk_khz < dccg->clks.dispclk_khz && safe_to_lower) - || new_clocks->dispclk_khz > dccg->clks.dispclk_khz) { + if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK; clock_voltage_req.clocks_in_khz = new_clocks->dispclk_khz; /* TODO: ramp up - dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz);*/ @@ -586,8 +591,7 @@ static void dcn_update_clocks(struct dccg *dccg, send_request_to_lower = true; } - if ((new_clocks->phyclk_khz < dccg->clks.phyclk_khz && safe_to_lower) - || new_clocks->phyclk_khz > dccg->clks.phyclk_khz) { + if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, dccg->clks.phyclk_khz)) { dccg->clks.phyclk_khz = new_clocks->phyclk_khz; clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAYPHYCLK; clock_voltage_req.clocks_in_khz = new_clocks->phyclk_khz; @@ -596,36 +600,50 @@ static void dcn_update_clocks(struct dccg *dccg, send_request_to_lower = true; } - if ((new_clocks->fclk_khz < dccg->clks.fclk_khz && safe_to_lower) - || new_clocks->fclk_khz > dccg->clks.fclk_khz) { + if (should_set_clock(safe_to_lower, new_clocks->fclk_khz, dccg->clks.fclk_khz)) { dccg->clks.phyclk_khz = new_clocks->fclk_khz; clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_FCLK; clock_voltage_req.clocks_in_khz = new_clocks->fclk_khz; + smu_req.hard_min_fclk_khz = new_clocks->fclk_khz; dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); send_request_to_lower = true; } - if ((new_clocks->dcfclk_khz < dccg->clks.dcfclk_khz && safe_to_lower) - || new_clocks->dcfclk_khz > dccg->clks.dcfclk_khz) { + if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, dccg->clks.dcfclk_khz)) { dccg->clks.phyclk_khz = new_clocks->dcfclk_khz; clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; clock_voltage_req.clocks_in_khz = new_clocks->dcfclk_khz; + smu_req.hard_min_dcefclk_khz = new_clocks->dcfclk_khz; send_request_to_lower = true; } + if (should_set_clock(safe_to_lower, + new_clocks->dcfclk_deep_sleep_khz, dccg->clks.dcfclk_deep_sleep_khz)) { + dccg->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz; + smu_req.min_deep_sleep_dcefclk_mhz = new_clocks->dcfclk_deep_sleep_khz; + } + #ifdef CONFIG_DRM_AMD_DC_DCN1_0 if (!send_request_to_increase && send_request_to_lower ) { - struct dc *core_dc = dccg->ctx->dc; - /*use dcfclk to request voltage*/ clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; - clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(core_dc, new_clocks); + clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); } #endif + + if (new_clocks->phyclk_khz) + smu_req.display_count = 1; + else + smu_req.display_count = 0; + + if (pp_smu->set_display_requirement) + pp_smu->set_display_requirement(&pp_smu->pp_smu, &smu_req); + + *smu_req_cur = smu_req; } static void dce_update_clocks(struct dccg *dccg, @@ -642,8 +660,7 @@ static void dce_update_clocks(struct dccg *dccg, dccg->cur_min_clks_state = level_change_req.power_level; } - if ((new_clocks->dispclk_khz < dccg->clks.dispclk_khz && safe_to_lower) - || new_clocks->dispclk_khz > dccg->clks.dispclk_khz) { + if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); dccg->clks.dispclk_khz = new_clocks->dispclk_khz; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index f519b98f4b23..09c7007868e8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2153,11 +2153,11 @@ static void dcn10_pplib_apply_display_requirements( { struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; - pp_display_cfg->min_engine_clock_khz = context->bw.dcn.cur_clk.dcfclk_khz; - pp_display_cfg->min_memory_clock_khz = context->bw.dcn.cur_clk.fclk_khz; - pp_display_cfg->min_engine_clock_deep_sleep_khz = context->bw.dcn.cur_clk.dcfclk_deep_sleep_khz; - pp_display_cfg->min_dcfc_deep_sleep_clock_khz = context->bw.dcn.cur_clk.dcfclk_deep_sleep_khz; - pp_display_cfg->min_dcfclock_khz = context->bw.dcn.cur_clk.dcfclk_khz; + pp_display_cfg->min_engine_clock_khz = dc->res_pool->dccg->clks.dcfclk_khz; + pp_display_cfg->min_memory_clock_khz = dc->res_pool->dccg->clks.fclk_khz; + pp_display_cfg->min_engine_clock_deep_sleep_khz = dc->res_pool->dccg->clks.dcfclk_deep_sleep_khz; + pp_display_cfg->min_dcfc_deep_sleep_clock_khz = dc->res_pool->dccg->clks.dcfclk_deep_sleep_khz; + pp_display_cfg->min_dcfclock_khz = dc->res_pool->dccg->clks.dcfclk_khz; pp_display_cfg->disp_clk_khz = context->bw.dcn.cur_clk.dispclk_khz; dce110_fill_display_configs(context, pp_display_cfg); @@ -2361,11 +2361,6 @@ static void dcn10_apply_ctx_for_surface( */ } -static inline bool should_set_clock(bool decrease_allowed, int calc_clk, int cur_clk) -{ - return ((decrease_allowed && calc_clk < cur_clk) || calc_clk > cur_clk); -} - static int determine_dppclk_threshold(struct dc *dc, struct dc_state *context) { bool request_dpp_div = context->bw.dcn.calc_clk.dispclk_khz > @@ -2456,16 +2451,16 @@ static void ramp_up_dispclk_with_dpp(struct dc *dc, struct dc_state *context) context->bw.dcn.calc_clk.max_supported_dppclk_khz; } +static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_clk) +{ + return ((safe_to_lower && calc_clk < cur_clk) || calc_clk > cur_clk); +} + static void dcn10_set_bandwidth( struct dc *dc, struct dc_state *context, bool decrease_allowed) { - struct pp_smu_display_requirement_rv *smu_req_cur = - &dc->res_pool->pp_smu_req; - struct pp_smu_display_requirement_rv smu_req = *smu_req_cur; - struct pp_smu_funcs_rv *pp_smu = dc->res_pool->pp_smu; - if (dc->debug.sanity_checks) { dcn10_verify_allow_pstate_change_high(dc); } @@ -2473,45 +2468,14 @@ static void dcn10_set_bandwidth( if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) return; + if (context->stream_count == 0) + context->bw.dcn.calc_clk.phyclk_khz = 0; + dc->res_pool->dccg->funcs->update_clocks( dc->res_pool->dccg, &context->bw.dcn.calc_clk, decrease_allowed); - if (should_set_clock( - decrease_allowed, - context->bw.dcn.calc_clk.dcfclk_khz, - dc->current_state->bw.dcn.cur_clk.dcfclk_khz)) { - context->bw.dcn.cur_clk.dcfclk_khz = - context->bw.dcn.calc_clk.dcfclk_khz; - smu_req.hard_min_dcefclk_khz = - context->bw.dcn.calc_clk.dcfclk_khz; - } - - if (should_set_clock( - decrease_allowed, - context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz, - dc->current_state->bw.dcn.cur_clk.dcfclk_deep_sleep_khz)) { - context->bw.dcn.cur_clk.dcfclk_deep_sleep_khz = - context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz; - } - - if (should_set_clock( - decrease_allowed, - context->bw.dcn.calc_clk.fclk_khz, - dc->current_state->bw.dcn.cur_clk.fclk_khz)) { - context->bw.dcn.cur_clk.fclk_khz = - context->bw.dcn.calc_clk.fclk_khz; - smu_req.hard_min_fclk_khz = context->bw.dcn.calc_clk.fclk_khz; - } - - smu_req.display_count = context->stream_count; - - if (pp_smu->set_display_requirement) - pp_smu->set_display_requirement(&pp_smu->pp_smu, &smu_req); - - *smu_req_cur = smu_req; - /* make sure dcf clk is before dpp clk to * make sure we have enough voltage to run dpp clk */ From 734b096096ac860b5a72c52e8a6a8b81fa9e016c Mon Sep 17 00:00:00 2001 From: Mikita Lipski Date: Mon, 9 Apr 2018 09:48:15 -0400 Subject: [PATCH 010/133] drm/amd/display: Adding dm-pp clocks getting by voltage Function to get clock levels by voltage from PPLib Signed-off-by: Mikita Lipski Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../display/amdgpu_dm/amdgpu_dm_services.c | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c index e861929dd981..bc15ee692d37 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c @@ -253,6 +253,34 @@ static void pp_to_dc_clock_levels_with_latency( } } +static void pp_to_dc_clock_levels_with_voltage( + const struct pp_clock_levels_with_voltage *pp_clks, + struct dm_pp_clock_levels_with_voltage *clk_level_info, + enum dm_pp_clock_type dc_clk_type) +{ + uint32_t i; + + if (pp_clks->num_levels > DM_PP_MAX_CLOCK_LEVELS) { + DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n", + DC_DECODE_PP_CLOCK_TYPE(dc_clk_type), + pp_clks->num_levels, + DM_PP_MAX_CLOCK_LEVELS); + + clk_level_info->num_levels = DM_PP_MAX_CLOCK_LEVELS; + } else + clk_level_info->num_levels = pp_clks->num_levels; + + DRM_INFO("DM_PPLIB: values for %s clock\n", + DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); + + for (i = 0; i < clk_level_info->num_levels; i++) { + DRM_INFO("DM_PPLIB:\t %d\n", pp_clks->data[i].clocks_in_khz); + clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz; + clk_level_info->data[i].voltage_in_mv = pp_clks->data[i].voltage_in_mv; + } +} + + bool dm_pp_get_clock_levels_by_type( const struct dc_context *ctx, enum dm_pp_clock_type clk_type, @@ -353,8 +381,19 @@ bool dm_pp_get_clock_levels_by_type_with_voltage( enum dm_pp_clock_type clk_type, struct dm_pp_clock_levels_with_voltage *clk_level_info) { - /* TODO: to be implemented */ - return false; + struct amdgpu_device *adev = ctx->driver_context; + void *pp_handle = adev->powerplay.pp_handle; + struct pp_clock_levels_with_voltage pp_clk_info = {0}; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; + + if (pp_funcs->get_clock_by_type_with_voltage(pp_handle, + dc_to_pp_clock_type(clk_type), + &pp_clk_info)) + return false; + + pp_to_dc_clock_levels_with_voltage(&pp_clk_info, clk_level_info, clk_type); + + return true; } bool dm_pp_notify_wm_clock_changes( From 28825c841bfd993bbe5c9466533baca8520f08c3 Mon Sep 17 00:00:00 2001 From: Mikita Lipski Date: Mon, 9 Apr 2018 13:40:00 -0400 Subject: [PATCH 011/133] drm/amd/display: Apply clock for voltage request Translate dm_pp tructure to pp type Call PP lib to apply clock voltage request for display Signed-off-by: Mikita Lipski Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../display/amdgpu_dm/amdgpu_dm_services.c | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c index bc15ee692d37..2eef154accf9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c @@ -416,8 +416,35 @@ bool dm_pp_apply_clock_for_voltage_request( const struct dc_context *ctx, struct dm_pp_clock_for_voltage_req *clock_for_voltage_req) { - /* TODO: to be implemented */ - return false; + struct amdgpu_device *adev = ctx->driver_context; + struct pp_display_clock_request *pp_clock_request = {0}; + int ret = 0; + switch (clock_for_voltage_req->clk_type) { + case DM_PP_CLOCK_TYPE_DISPLAY_CLK: + pp_clock_request->clock_type = amd_pp_disp_clock; + break; + + case DM_PP_CLOCK_TYPE_DCEFCLK: + pp_clock_request->clock_type = amd_pp_dcef_clock; + break; + + case DM_PP_CLOCK_TYPE_PIXELCLK: + pp_clock_request->clock_type = amd_pp_pixel_clock; + break; + + default: + return false; + } + + pp_clock_request->clock_freq_in_khz = clock_for_voltage_req->clocks_in_khz; + + if (adev->powerplay.pp_funcs->display_clock_voltage_request) + ret = adev->powerplay.pp_funcs->display_clock_voltage_request( + adev->powerplay.pp_handle, + pp_clock_request); + if (ret) + return false; + return true; } bool dm_pp_get_static_clocks( From db4e525304ddf272e45542cbfd820840cf6ac874 Mon Sep 17 00:00:00 2001 From: Mikita Lipski Date: Wed, 18 Apr 2018 17:19:23 -0400 Subject: [PATCH 012/133] drm/amd/display: Adding Get static clocks for dm_pp interface Adding a call to powerplay to get system clocks and translate to dm structure Signed-off-by: Mikita Lipski Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../amd/display/amdgpu_dm/amdgpu_dm_services.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c index 2eef154accf9..dbd714d0936e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c @@ -451,8 +451,22 @@ bool dm_pp_get_static_clocks( const struct dc_context *ctx, struct dm_pp_static_clock_info *static_clk_info) { - /* TODO: to be implemented */ - return false; + struct amdgpu_device *adev = ctx->driver_context; + struct amd_pp_clock_info *pp_clk_info = {0}; + int ret = 0; + + if (adev->powerplay.pp_funcs->get_current_clocks) + ret = adev->powerplay.pp_funcs->get_current_clocks( + adev->powerplay.pp_handle, + pp_clk_info); + if (ret) + return false; + + static_clk_info->max_clocks_state = pp_clk_info->max_clocks_state; + static_clk_info->max_mclk_khz = pp_clk_info->max_memory_clock; + static_clk_info->max_sclk_khz = pp_clk_info->max_engine_clock; + + return true; } void dm_pp_get_funcs_rv( From 30f0ea6d0901c1ff9e7a4d986959e3e4008ee8e1 Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Tue, 8 May 2018 12:25:15 -0400 Subject: [PATCH 013/133] drm/amd/display: dal 3.1.48 Signed-off-by: Tony Cheng Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 8ba90a75d128..82e0f55bc3e4 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,7 +38,7 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.47" +#define DC_VER "3.1.48" #define MAX_SURFACES 3 #define MAX_STREAMS 6 From 92276a06f9c3d29183c7bdf46a6dbbc9c00f7acf Mon Sep 17 00:00:00 2001 From: Mikita Lipski Date: Wed, 11 Apr 2018 14:52:41 -0400 Subject: [PATCH 014/133] drm/amd/display: Introduce pp-smu raven functions DM powerplay calls for DCN10 allowing to bypass PPLib and call directly to the SMU functions. Signed-off-by: Mikita Lipski Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../display/amdgpu_dm/amdgpu_dm_services.c | 88 ++++++++++++++++++- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 4 +- drivers/gpu/drm/amd/display/dc/dm_pp_smu.h | 6 +- 3 files changed, 92 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c index dbd714d0936e..e3a9bad4b404 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c @@ -34,6 +34,11 @@ #include "amdgpu_dm.h" #include "amdgpu_dm_irq.h" #include "amdgpu_pm.h" +#include "dm_pp_smu.h" +#include "../../powerplay/inc/hwmgr.h" +#include "../../powerplay/hwmgr/smu10_hwmgr.h" + + unsigned long long dm_get_elapse_time_in_ns(struct dc_context *ctx, unsigned long long current_time_stamp, @@ -469,9 +474,90 @@ bool dm_pp_get_static_clocks( return true; } +void pp_rv_set_display_requirement(struct pp_smu *pp, + struct pp_smu_display_requirement_rv *req) +{ + struct amdgpu_device *adev = pp->ctx->driver_context; + struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; + int ret = 0; + if (hwmgr->hwmgr_func->set_deep_sleep_dcefclk) + ret = hwmgr->hwmgr_func->set_deep_sleep_dcefclk(hwmgr, req->hard_min_dcefclk_khz/10); + if (hwmgr->hwmgr_func->set_active_display_count) + ret = hwmgr->hwmgr_func->set_active_display_count(hwmgr, req->display_count); + + //store_cc6 is not yet implemented in SMU level +} + +void pp_rv_set_wm_ranges(struct pp_smu *pp, + struct pp_smu_wm_range_sets *ranges) +{ + struct amdgpu_device *adev = pp->ctx->driver_context; + struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; + struct pp_wm_sets_with_clock_ranges_soc15 ranges_soc15 = {0}; + int i = 0; + + if (!hwmgr->hwmgr_func->set_watermarks_for_clocks_ranges || + !pp || !ranges) + return; + + //not entirely sure if thats a correct assignment + ranges_soc15.num_wm_sets_dmif = ranges->num_reader_wm_sets; + ranges_soc15.num_wm_sets_mcif = ranges->num_writer_wm_sets; + + for (i = 0; i < ranges_soc15.num_wm_sets_dmif; i++) { + if (ranges->reader_wm_sets[i].wm_inst > 3) + ranges_soc15.wm_sets_dmif[i].wm_set_id = DC_WM_SET_A; + else + ranges_soc15.wm_sets_dmif[i].wm_set_id = + ranges->reader_wm_sets[i].wm_inst; + ranges_soc15.wm_sets_dmif[i].wm_max_dcefclk_in_khz = + ranges->reader_wm_sets[i].max_drain_clk_khz; + ranges_soc15.wm_sets_dmif[i].wm_min_dcefclk_in_khz = + ranges->reader_wm_sets[i].min_drain_clk_khz; + ranges_soc15.wm_sets_dmif[i].wm_max_memclk_in_khz = + ranges->reader_wm_sets[i].max_fill_clk_khz; + ranges_soc15.wm_sets_dmif[i].wm_min_memclk_in_khz = + ranges->reader_wm_sets[i].min_fill_clk_khz; + } + + for (i = 0; i < ranges_soc15.num_wm_sets_mcif; i++) { + if (ranges->writer_wm_sets[i].wm_inst > 3) + ranges_soc15.wm_sets_dmif[i].wm_set_id = DC_WM_SET_A; + else + ranges_soc15.wm_sets_mcif[i].wm_set_id = + ranges->writer_wm_sets[i].wm_inst; + ranges_soc15.wm_sets_mcif[i].wm_max_socclk_in_khz = + ranges->writer_wm_sets[i].max_fill_clk_khz; + ranges_soc15.wm_sets_mcif[i].wm_min_socclk_in_khz = + ranges->writer_wm_sets[i].min_fill_clk_khz; + ranges_soc15.wm_sets_mcif[i].wm_max_memclk_in_khz = + ranges->writer_wm_sets[i].max_fill_clk_khz; + ranges_soc15.wm_sets_mcif[i].wm_min_memclk_in_khz = + ranges->writer_wm_sets[i].min_fill_clk_khz; + } + + hwmgr->hwmgr_func->set_watermarks_for_clocks_ranges(hwmgr, &ranges_soc15); + +} + +void pp_rv_set_pme_wa_enable(struct pp_smu *pp) +{ + struct amdgpu_device *adev = pp->ctx->driver_context; + struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; + + if (hwmgr->hwmgr_func->smus_notify_pwe) + hwmgr->hwmgr_func->smus_notify_pwe(hwmgr); +} + void dm_pp_get_funcs_rv( struct dc_context *ctx, struct pp_smu_funcs_rv *funcs) -{} +{ + funcs->pp_smu.ctx = ctx; + funcs->set_display_requirement = pp_rv_set_display_requirement; + funcs->set_wm_ranges = pp_rv_set_wm_ranges; + funcs->set_pme_wa_enable = pp_rv_set_pme_wa_enable; +} + /**** end of power component interfaces ****/ diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 9acdd9da740e..9ce329e8f287 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -1358,8 +1358,8 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc) /* SOCCLK does not affect anytihng but writeback for DCN so for now we dont * care what the value is, hence min to overdrive level */ - ranges.num_reader_wm_sets = WM_COUNT; - ranges.num_writer_wm_sets = WM_COUNT; + ranges.num_reader_wm_sets = WM_SET_COUNT; + ranges.num_writer_wm_sets = WM_SET_COUNT; ranges.reader_wm_sets[0].wm_inst = WM_A; ranges.reader_wm_sets[0].min_drain_clk_khz = min_dcfclk_khz; ranges.reader_wm_sets[0].max_drain_clk_khz = max_dcfclk_khz; diff --git a/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h b/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h index eac4bfe12257..58ed2055ef9f 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h +++ b/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h @@ -40,7 +40,7 @@ enum wm_set_id { WM_B, WM_C, WM_D, - WM_COUNT, + WM_SET_COUNT, }; struct pp_smu_wm_set_range { @@ -53,10 +53,10 @@ struct pp_smu_wm_set_range { struct pp_smu_wm_range_sets { uint32_t num_reader_wm_sets; - struct pp_smu_wm_set_range reader_wm_sets[WM_COUNT]; + struct pp_smu_wm_set_range reader_wm_sets[WM_SET_COUNT]; uint32_t num_writer_wm_sets; - struct pp_smu_wm_set_range writer_wm_sets[WM_COUNT]; + struct pp_smu_wm_set_range writer_wm_sets[WM_SET_COUNT]; }; struct pp_smu_display_requirement_rv { From 2dfa76d328630de3dd4fc09b296ee9771ba13e39 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Mon, 28 May 2018 18:09:52 -0400 Subject: [PATCH 015/133] drm/amd/display: remove invalid assert when no max_pixel_clk is found Signed-off-by: Dmytro Laktyushkin Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 34eb7a33851b..4cdf86690d19 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1779,9 +1779,6 @@ static uint32_t get_max_pixel_clock_for_all_paths( pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; } - if (max_pix_clk == 0) - ASSERT(0); - return max_pix_clk; } From 0d8be24134eddaf5acc937f59d58e62d869f0a6f Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Tue, 29 May 2018 07:18:27 -0700 Subject: [PATCH 016/133] drm/amd/display: Use tg count for opp init. In case of tg count not equal to FE pipe count, if use pipe count to iterate the tgs, it will cause BSOD. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 09c7007868e8..64ca503cab42 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1010,7 +1010,7 @@ static void dcn10_init_hw(struct dc *dc) /* Reset all MPCC muxes */ dc->res_pool->mpc->funcs->mpc_init(dc->res_pool->mpc); - for (i = 0; i < dc->res_pool->pipe_count; i++) { + for (i = 0; i < dc->res_pool->timing_generator_count; i++) { struct timing_generator *tg = dc->res_pool->timing_generators[i]; struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; struct hubp *hubp = dc->res_pool->hubps[i]; From 9654a28b3ac075f2454d5867d490b0c2f7cde9fd Mon Sep 17 00:00:00 2001 From: Mikita Lipski Date: Tue, 29 May 2018 16:15:12 -0400 Subject: [PATCH 017/133] drm/amd/display: Use local structs instead of struct pointers Change struct pointers to creating structs on a stack. Thats fixing a mistake in a previous patch introducing dm_pplib functions Signed-off-by: Mikita Lipski Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../display/amdgpu_dm/amdgpu_dm_services.c | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c index e3a9bad4b404..f5d626e8bf51 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c @@ -422,31 +422,31 @@ bool dm_pp_apply_clock_for_voltage_request( struct dm_pp_clock_for_voltage_req *clock_for_voltage_req) { struct amdgpu_device *adev = ctx->driver_context; - struct pp_display_clock_request *pp_clock_request = {0}; + struct pp_display_clock_request pp_clock_request = {0}; int ret = 0; switch (clock_for_voltage_req->clk_type) { case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - pp_clock_request->clock_type = amd_pp_disp_clock; + pp_clock_request.clock_type = amd_pp_disp_clock; break; case DM_PP_CLOCK_TYPE_DCEFCLK: - pp_clock_request->clock_type = amd_pp_dcef_clock; + pp_clock_request.clock_type = amd_pp_dcef_clock; break; case DM_PP_CLOCK_TYPE_PIXELCLK: - pp_clock_request->clock_type = amd_pp_pixel_clock; + pp_clock_request.clock_type = amd_pp_pixel_clock; break; default: return false; } - pp_clock_request->clock_freq_in_khz = clock_for_voltage_req->clocks_in_khz; + pp_clock_request.clock_freq_in_khz = clock_for_voltage_req->clocks_in_khz; if (adev->powerplay.pp_funcs->display_clock_voltage_request) ret = adev->powerplay.pp_funcs->display_clock_voltage_request( adev->powerplay.pp_handle, - pp_clock_request); + &pp_clock_request); if (ret) return false; return true; @@ -457,19 +457,19 @@ bool dm_pp_get_static_clocks( struct dm_pp_static_clock_info *static_clk_info) { struct amdgpu_device *adev = ctx->driver_context; - struct amd_pp_clock_info *pp_clk_info = {0}; + struct amd_pp_clock_info pp_clk_info = {0}; int ret = 0; if (adev->powerplay.pp_funcs->get_current_clocks) ret = adev->powerplay.pp_funcs->get_current_clocks( adev->powerplay.pp_handle, - pp_clk_info); + &pp_clk_info); if (ret) return false; - static_clk_info->max_clocks_state = pp_clk_info->max_clocks_state; - static_clk_info->max_mclk_khz = pp_clk_info->max_memory_clock; - static_clk_info->max_sclk_khz = pp_clk_info->max_engine_clock; + static_clk_info->max_clocks_state = pp_clk_info.max_clocks_state; + static_clk_info->max_mclk_khz = pp_clk_info.max_memory_clock; + static_clk_info->max_sclk_khz = pp_clk_info.max_engine_clock; return true; } From 25684c59aff5147d48cc7ce04d4d75a15c5a3a71 Mon Sep 17 00:00:00 2001 From: Mikita Lipski Date: Tue, 29 May 2018 16:20:37 -0400 Subject: [PATCH 018/133] drm/amd/display: Add clock types to applying clk for voltage Add DCF and FCLK clock case statements for changing raven's clocks for voltage request. Also maintain DCEF clock for DCE120 calls. Signed-off-by: Mikita Lipski Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c index f5d626e8bf51..0ac428299f5f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c @@ -433,10 +433,18 @@ bool dm_pp_apply_clock_for_voltage_request( pp_clock_request.clock_type = amd_pp_dcef_clock; break; + case DM_PP_CLOCK_TYPE_DCFCLK: + pp_clock_request.clock_type = amd_pp_dcf_clock; + break; + case DM_PP_CLOCK_TYPE_PIXELCLK: pp_clock_request.clock_type = amd_pp_pixel_clock; break; + case DM_PP_CLOCK_TYPE_FCLK: + pp_clock_request.clock_type = amd_pp_f_clock; + break; + default: return false; } From d578839ca014e5f4e6d540caadc0b84d50a8977f Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 23 May 2018 18:02:27 -0400 Subject: [PATCH 019/133] drm/amd/display: get rid of cur_clks from dcn_bw_output Cleans up dcn_bw_output to only contain calculated info, actual programmed values will now be stored in respective blocks. Signed-off-by: Dmytro Laktyushkin Reviewed-by: Nikola Cornij Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 28 +++--- .../gpu/drm/amd/display/dc/core/dc_debug.c | 24 +++--- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 +- .../gpu/drm/amd/display/dc/dce/dce_clocks.c | 4 +- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 85 +++++++++---------- .../gpu/drm/amd/display/dc/inc/core_types.h | 3 +- 6 files changed, 72 insertions(+), 74 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 9ce329e8f287..b8195e5a0676 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -977,42 +977,42 @@ bool dcn_validate_bandwidth( display_pipe_configuration(v); calc_wm_sets_and_perf_params(context, v); - context->bw.dcn.calc_clk.fclk_khz = (int)(bw_consumed * 1000000 / + context->bw.dcn.clk.fclk_khz = (int)(bw_consumed * 1000000 / (ddr4_dram_factor_single_Channel * v->number_of_channels)); if (bw_consumed == v->fabric_and_dram_bandwidth_vmin0p65) { - context->bw.dcn.calc_clk.fclk_khz = (int)(bw_consumed * 1000000 / 32); + context->bw.dcn.clk.fclk_khz = (int)(bw_consumed * 1000000 / 32); } - context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000); - context->bw.dcn.calc_clk.dcfclk_khz = (int)(v->dcfclk * 1000); + context->bw.dcn.clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000); + context->bw.dcn.clk.dcfclk_khz = (int)(v->dcfclk * 1000); - context->bw.dcn.calc_clk.dispclk_khz = (int)(v->dispclk * 1000); + context->bw.dcn.clk.dispclk_khz = (int)(v->dispclk * 1000); if (dc->debug.max_disp_clk == true) - context->bw.dcn.calc_clk.dispclk_khz = (int)(dc->dcn_soc->max_dispclk_vmax0p9 * 1000); + context->bw.dcn.clk.dispclk_khz = (int)(dc->dcn_soc->max_dispclk_vmax0p9 * 1000); - if (context->bw.dcn.calc_clk.dispclk_khz < + if (context->bw.dcn.clk.dispclk_khz < dc->debug.min_disp_clk_khz) { - context->bw.dcn.calc_clk.dispclk_khz = + context->bw.dcn.clk.dispclk_khz = dc->debug.min_disp_clk_khz; } - context->bw.dcn.calc_clk.dppclk_khz = context->bw.dcn.calc_clk.dispclk_khz / v->dispclk_dppclk_ratio; - context->bw.dcn.calc_clk.phyclk_khz = v->phyclk_per_state[v->voltage_level]; + context->bw.dcn.clk.dppclk_khz = context->bw.dcn.clk.dispclk_khz / v->dispclk_dppclk_ratio; + context->bw.dcn.clk.phyclk_khz = v->phyclk_per_state[v->voltage_level]; switch (v->voltage_level) { case 0: - context->bw.dcn.calc_clk.max_supported_dppclk_khz = + context->bw.dcn.clk.max_supported_dppclk_khz = (int)(dc->dcn_soc->max_dppclk_vmin0p65 * 1000); break; case 1: - context->bw.dcn.calc_clk.max_supported_dppclk_khz = + context->bw.dcn.clk.max_supported_dppclk_khz = (int)(dc->dcn_soc->max_dppclk_vmid0p72 * 1000); break; case 2: - context->bw.dcn.calc_clk.max_supported_dppclk_khz = + context->bw.dcn.clk.max_supported_dppclk_khz = (int)(dc->dcn_soc->max_dppclk_vnom0p8 * 1000); break; default: - context->bw.dcn.calc_clk.max_supported_dppclk_khz = + context->bw.dcn.clk.max_supported_dppclk_khz = (int)(dc->dcn_soc->max_dppclk_vmax0p9 * 1000); break; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c index 267c76766dea..e1ebdf7b5eaf 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c @@ -352,19 +352,19 @@ void context_clock_trace( DC_LOGGER_INIT(dc->ctx->logger); CLOCK_TRACE("Current: dispclk_khz:%d max_dppclk_khz:%d dcfclk_khz:%d\n" "dcfclk_deep_sleep_khz:%d fclk_khz:%d socclk_khz:%d\n", - context->bw.dcn.calc_clk.dispclk_khz, - context->bw.dcn.calc_clk.dppclk_khz, - context->bw.dcn.calc_clk.dcfclk_khz, - context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz, - context->bw.dcn.calc_clk.fclk_khz, - context->bw.dcn.calc_clk.socclk_khz); + context->bw.dcn.clk.dispclk_khz, + context->bw.dcn.clk.dppclk_khz, + context->bw.dcn.clk.dcfclk_khz, + context->bw.dcn.clk.dcfclk_deep_sleep_khz, + context->bw.dcn.clk.fclk_khz, + context->bw.dcn.clk.socclk_khz); CLOCK_TRACE("Calculated: dispclk_khz:%d max_dppclk_khz:%d dcfclk_khz:%d\n" "dcfclk_deep_sleep_khz:%d fclk_khz:%d socclk_khz:%d\n", - context->bw.dcn.calc_clk.dispclk_khz, - context->bw.dcn.calc_clk.dppclk_khz, - context->bw.dcn.calc_clk.dcfclk_khz, - context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz, - context->bw.dcn.calc_clk.fclk_khz, - context->bw.dcn.calc_clk.socclk_khz); + context->bw.dcn.clk.dispclk_khz, + context->bw.dcn.clk.dppclk_khz, + context->bw.dcn.clk.dcfclk_khz, + context->bw.dcn.clk.dcfclk_deep_sleep_khz, + context->bw.dcn.clk.fclk_khz, + context->bw.dcn.clk.socclk_khz); #endif } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 779d1926a756..8eb8b8768465 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -1284,7 +1284,7 @@ static enum dc_status enable_link_dp( max_link_rate = LINK_RATE_HIGH3; if (link_settings.link_rate == max_link_rate) { - struct dc_clocks clocks = state->bw.dcn.calc_clk; + struct dc_clocks clocks = state->bw.dcn.clk; /* dce/dcn compat, do not update dispclk */ clocks.dispclk_khz = 0; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index 93e6063c4b97..6b6570ea998d 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -584,8 +584,8 @@ static void dcn_update_clocks(struct dccg *dccg, if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK; clock_voltage_req.clocks_in_khz = new_clocks->dispclk_khz; - /* TODO: ramp up - dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz);*/ - dccg->clks.dispclk_khz = new_clocks->dispclk_khz; + /* TODO: ramp up - dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); + dccg->clks.dispclk_khz = new_clocks->dispclk_khz;*/ dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); send_request_to_lower = true; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 64ca503cab42..6ab00615c4c5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -337,13 +337,13 @@ void dcn10_log_hw_state(struct dc *dc) DTN_INFO("\nCALCULATED Clocks: dcfclk_khz:%d dcfclk_deep_sleep_khz:%d dispclk_khz:%d\n" "dppclk_khz:%d max_supported_dppclk_khz:%d fclk_khz:%d socclk_khz:%d\n\n", - dc->current_state->bw.dcn.calc_clk.dcfclk_khz, - dc->current_state->bw.dcn.calc_clk.dcfclk_deep_sleep_khz, - dc->current_state->bw.dcn.calc_clk.dispclk_khz, - dc->current_state->bw.dcn.calc_clk.dppclk_khz, - dc->current_state->bw.dcn.calc_clk.max_supported_dppclk_khz, - dc->current_state->bw.dcn.calc_clk.fclk_khz, - dc->current_state->bw.dcn.calc_clk.socclk_khz); + dc->current_state->bw.dcn.clk.dcfclk_khz, + dc->current_state->bw.dcn.clk.dcfclk_deep_sleep_khz, + dc->current_state->bw.dcn.clk.dispclk_khz, + dc->current_state->bw.dcn.clk.dppclk_khz, + dc->current_state->bw.dcn.clk.max_supported_dppclk_khz, + dc->current_state->bw.dcn.clk.fclk_khz, + dc->current_state->bw.dcn.clk.socclk_khz); log_mpc_crc(dc); @@ -1952,18 +1952,17 @@ static void update_dchubp_dpp( * divided by 2 */ if (plane_state->update_flags.bits.full_update) { - bool should_divided_by_2 = context->bw.dcn.calc_clk.dppclk_khz <= - context->bw.dcn.cur_clk.dispclk_khz / 2; + bool should_divided_by_2 = context->bw.dcn.clk.dppclk_khz <= + dc->res_pool->dccg->clks.dispclk_khz / 2; dpp->funcs->dpp_dppclk_control( dpp, should_divided_by_2, true); - dc->current_state->bw.dcn.cur_clk.dppclk_khz = - should_divided_by_2 ? - context->bw.dcn.cur_clk.dispclk_khz / 2 : - context->bw.dcn.cur_clk.dispclk_khz; + dc->res_pool->dccg->clks.dppclk_khz = should_divided_by_2 ? + dc->res_pool->dccg->clks.dispclk_khz / 2 : + dc->res_pool->dccg->clks.dispclk_khz; } /* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG @@ -2158,7 +2157,7 @@ static void dcn10_pplib_apply_display_requirements( pp_display_cfg->min_engine_clock_deep_sleep_khz = dc->res_pool->dccg->clks.dcfclk_deep_sleep_khz; pp_display_cfg->min_dcfc_deep_sleep_clock_khz = dc->res_pool->dccg->clks.dcfclk_deep_sleep_khz; pp_display_cfg->min_dcfclock_khz = dc->res_pool->dccg->clks.dcfclk_khz; - pp_display_cfg->disp_clk_khz = context->bw.dcn.cur_clk.dispclk_khz; + pp_display_cfg->disp_clk_khz = dc->res_pool->dccg->clks.dispclk_khz; dce110_fill_display_configs(context, pp_display_cfg); if (memcmp(&dc->prev_display_config, pp_display_cfg, sizeof( @@ -2363,29 +2362,29 @@ static void dcn10_apply_ctx_for_surface( static int determine_dppclk_threshold(struct dc *dc, struct dc_state *context) { - bool request_dpp_div = context->bw.dcn.calc_clk.dispclk_khz > - context->bw.dcn.calc_clk.dppclk_khz; - bool dispclk_increase = context->bw.dcn.calc_clk.dispclk_khz > - context->bw.dcn.cur_clk.dispclk_khz; - int disp_clk_threshold = context->bw.dcn.calc_clk.max_supported_dppclk_khz; - bool cur_dpp_div = context->bw.dcn.cur_clk.dispclk_khz > - context->bw.dcn.cur_clk.dppclk_khz; + bool request_dpp_div = context->bw.dcn.clk.dispclk_khz > + context->bw.dcn.clk.dppclk_khz; + bool dispclk_increase = context->bw.dcn.clk.dispclk_khz > + dc->res_pool->dccg->clks.dispclk_khz; + int disp_clk_threshold = context->bw.dcn.clk.max_supported_dppclk_khz; + bool cur_dpp_div = dc->res_pool->dccg->clks.dispclk_khz > + dc->res_pool->dccg->clks.dppclk_khz; /* increase clock, looking for div is 0 for current, request div is 1*/ if (dispclk_increase) { /* already divided by 2, no need to reach target clk with 2 steps*/ if (cur_dpp_div) - return context->bw.dcn.calc_clk.dispclk_khz; + return context->bw.dcn.clk.dispclk_khz; /* request disp clk is lower than maximum supported dpp clk, * no need to reach target clk with two steps. */ - if (context->bw.dcn.calc_clk.dispclk_khz <= disp_clk_threshold) - return context->bw.dcn.calc_clk.dispclk_khz; + if (context->bw.dcn.clk.dispclk_khz <= disp_clk_threshold) + return context->bw.dcn.clk.dispclk_khz; /* target dpp clk not request divided by 2, still within threshold */ if (!request_dpp_div) - return context->bw.dcn.calc_clk.dispclk_khz; + return context->bw.dcn.clk.dispclk_khz; } else { /* decrease clock, looking for current dppclk divided by 2, @@ -2394,17 +2393,17 @@ static int determine_dppclk_threshold(struct dc *dc, struct dc_state *context) /* current dpp clk not divided by 2, no need to ramp*/ if (!cur_dpp_div) - return context->bw.dcn.calc_clk.dispclk_khz; + return context->bw.dcn.clk.dispclk_khz; /* current disp clk is lower than current maximum dpp clk, * no need to ramp */ - if (context->bw.dcn.cur_clk.dispclk_khz <= disp_clk_threshold) - return context->bw.dcn.calc_clk.dispclk_khz; + if (dc->res_pool->dccg->clks.dispclk_khz <= disp_clk_threshold) + return context->bw.dcn.clk.dispclk_khz; /* request dpp clk need to be divided by 2 */ if (request_dpp_div) - return context->bw.dcn.calc_clk.dispclk_khz; + return context->bw.dcn.clk.dispclk_khz; } return disp_clk_threshold; @@ -2413,8 +2412,8 @@ static int determine_dppclk_threshold(struct dc *dc, struct dc_state *context) static void ramp_up_dispclk_with_dpp(struct dc *dc, struct dc_state *context) { int i; - bool request_dpp_div = context->bw.dcn.calc_clk.dispclk_khz > - context->bw.dcn.calc_clk.dppclk_khz; + bool request_dpp_div = context->bw.dcn.clk.dispclk_khz > + context->bw.dcn.clk.dppclk_khz; int dispclk_to_dpp_threshold = determine_dppclk_threshold(dc, context); @@ -2437,18 +2436,18 @@ static void ramp_up_dispclk_with_dpp(struct dc *dc, struct dc_state *context) } /* If target clk not same as dppclk threshold, set to target clock */ - if (dispclk_to_dpp_threshold != context->bw.dcn.calc_clk.dispclk_khz) { + if (dispclk_to_dpp_threshold != context->bw.dcn.clk.dispclk_khz) { dc->res_pool->dccg->funcs->set_dispclk( dc->res_pool->dccg, - context->bw.dcn.calc_clk.dispclk_khz); + context->bw.dcn.clk.dispclk_khz); } - context->bw.dcn.cur_clk.dispclk_khz = - context->bw.dcn.calc_clk.dispclk_khz; - context->bw.dcn.cur_clk.dppclk_khz = - context->bw.dcn.calc_clk.dppclk_khz; - context->bw.dcn.cur_clk.max_supported_dppclk_khz = - context->bw.dcn.calc_clk.max_supported_dppclk_khz; + dc->res_pool->dccg->clks.dispclk_khz = + context->bw.dcn.clk.dispclk_khz; + dc->res_pool->dccg->clks.dppclk_khz = + context->bw.dcn.clk.dppclk_khz; + dc->res_pool->dccg->clks.max_supported_dppclk_khz = + context->bw.dcn.clk.max_supported_dppclk_khz; } static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_clk) @@ -2469,11 +2468,11 @@ static void dcn10_set_bandwidth( return; if (context->stream_count == 0) - context->bw.dcn.calc_clk.phyclk_khz = 0; + context->bw.dcn.clk.phyclk_khz = 0; dc->res_pool->dccg->funcs->update_clocks( dc->res_pool->dccg, - &context->bw.dcn.calc_clk, + &context->bw.dcn.clk, decrease_allowed); /* make sure dcf clk is before dpp clk to @@ -2481,8 +2480,8 @@ static void dcn10_set_bandwidth( */ if (should_set_clock( decrease_allowed, - context->bw.dcn.calc_clk.dispclk_khz, - dc->current_state->bw.dcn.cur_clk.dispclk_khz)) { + context->bw.dcn.clk.dispclk_khz, + dc->res_pool->dccg->clks.dispclk_khz)) { ramp_up_dispclk_with_dpp(dc, context); } diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 44c48f3d0a1d..00d728e629fa 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -256,8 +256,7 @@ struct dce_bw_output { }; struct dcn_bw_output { - struct dc_clocks cur_clk; - struct dc_clocks calc_clk; + struct dc_clocks clk; struct dcn_watermark_set watermarks; }; From 12c3130dd6f391437a60c765912a30b4cbb77247 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 23 May 2018 18:18:50 -0400 Subject: [PATCH 020/133] drm/amd/display: move dcn1 dispclk programming to dccg No functional change. Signed-off-by: Dmytro Laktyushkin Reviewed-by: Nikola Cornij Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dce/dce_clocks.c | 95 ++++++++++++++-- .../gpu/drm/amd/display/dc/dce/dce_clocks.h | 2 +- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 106 ------------------ .../drm/amd/display/dc/dcn10/dcn10_resource.c | 2 +- 4 files changed, 90 insertions(+), 115 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index 6b6570ea998d..55f533cf55ba 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -552,7 +552,85 @@ static void dce12_update_clocks(struct dccg *dccg, } } -static void dcn_update_clocks(struct dccg *dccg, +static int dcn1_determine_dppclk_threshold(struct dccg *dccg, struct dc_clocks *new_clocks) +{ + bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; + bool dispclk_increase = new_clocks->dispclk_khz > dccg->clks.dispclk_khz; + int disp_clk_threshold = new_clocks->max_supported_dppclk_khz; + bool cur_dpp_div = dccg->clks.dispclk_khz > dccg->clks.dppclk_khz; + + /* increase clock, looking for div is 0 for current, request div is 1*/ + if (dispclk_increase) { + /* already divided by 2, no need to reach target clk with 2 steps*/ + if (cur_dpp_div) + return new_clocks->dispclk_khz; + + /* request disp clk is lower than maximum supported dpp clk, + * no need to reach target clk with two steps. + */ + if (new_clocks->dispclk_khz <= disp_clk_threshold) + return new_clocks->dispclk_khz; + + /* target dpp clk not request divided by 2, still within threshold */ + if (!request_dpp_div) + return new_clocks->dispclk_khz; + + } else { + /* decrease clock, looking for current dppclk divided by 2, + * request dppclk not divided by 2. + */ + + /* current dpp clk not divided by 2, no need to ramp*/ + if (!cur_dpp_div) + return new_clocks->dispclk_khz; + + /* current disp clk is lower than current maximum dpp clk, + * no need to ramp + */ + if (dccg->clks.dispclk_khz <= disp_clk_threshold) + return new_clocks->dispclk_khz; + + /* request dpp clk need to be divided by 2 */ + if (request_dpp_div) + return new_clocks->dispclk_khz; + } + + return disp_clk_threshold; +} + +static void dcn1_ramp_up_dispclk_with_dpp(struct dccg *dccg, struct dc_clocks *new_clocks) +{ + struct dc *dc = dccg->ctx->dc; + int dispclk_to_dpp_threshold = dcn1_determine_dppclk_threshold(dccg, new_clocks); + bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; + int i; + + /* set disp clk to dpp clk threshold */ + dccg->funcs->set_dispclk(dccg, dispclk_to_dpp_threshold); + + /* update request dpp clk division option */ + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; + + if (!pipe_ctx->plane_state) + continue; + + pipe_ctx->plane_res.dpp->funcs->dpp_dppclk_control( + pipe_ctx->plane_res.dpp, + request_dpp_div, + true); + } + + /* If target clk not same as dppclk threshold, set to target clock */ + if (dispclk_to_dpp_threshold != new_clocks->dispclk_khz) + dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); + + dccg->clks.dispclk_khz = new_clocks->dispclk_khz; + dccg->clks.dppclk_khz = new_clocks->dppclk_khz; + dccg->clks.max_supported_dppclk_khz = new_clocks->max_supported_dppclk_khz; +} + +static void dcn1_update_clocks(struct dccg *dccg, struct dc_clocks *new_clocks, bool safe_to_lower) { @@ -572,6 +650,9 @@ static void dcn_update_clocks(struct dccg *dccg, send_request_to_increase = true; #ifdef CONFIG_DRM_AMD_DC_DCN1_0 + /* make sure dcf clk is before dpp clk to + * make sure we have enough voltage to run dpp clk + */ if (send_request_to_increase ) { /*use dcfclk to request voltage*/ @@ -584,8 +665,8 @@ static void dcn_update_clocks(struct dccg *dccg, if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK; clock_voltage_req.clocks_in_khz = new_clocks->dispclk_khz; - /* TODO: ramp up - dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); - dccg->clks.dispclk_khz = new_clocks->dispclk_khz;*/ + dcn1_ramp_up_dispclk_with_dpp(dccg, new_clocks); + dccg->clks.dispclk_khz = new_clocks->dispclk_khz; dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); send_request_to_lower = true; @@ -666,10 +747,10 @@ static void dce_update_clocks(struct dccg *dccg, } } -static const struct display_clock_funcs dcn_funcs = { +static const struct display_clock_funcs dcn1_funcs = { .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq_wrkaround, .set_dispclk = dce112_set_clock, - .update_clocks = dcn_update_clocks + .update_clocks = dcn1_update_clocks }; static const struct display_clock_funcs dce120_funcs = { @@ -838,7 +919,7 @@ struct dccg *dce120_dccg_create(struct dc_context *ctx) return &clk_dce->base; } -struct dccg *dcn_dccg_create(struct dc_context *ctx) +struct dccg *dcn1_dccg_create(struct dc_context *ctx) { struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); @@ -851,7 +932,7 @@ struct dccg *dcn_dccg_create(struct dc_context *ctx) dce_dccg_construct( clk_dce, ctx, NULL, NULL, NULL); - clk_dce->base.funcs = &dcn_funcs; + clk_dce->base.funcs = &dcn1_funcs; return &clk_dce->base; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h index c695b9c9bcb5..7907c3c4b1c1 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h @@ -128,7 +128,7 @@ struct dccg *dce112_dccg_create( struct dccg *dce120_dccg_create(struct dc_context *ctx); -struct dccg *dcn_dccg_create(struct dc_context *ctx); +struct dccg *dcn1_dccg_create(struct dc_context *ctx); void dce_dccg_destroy(struct dccg **dccg); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 6ab00615c4c5..60e99477930b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2360,101 +2360,6 @@ static void dcn10_apply_ctx_for_surface( */ } -static int determine_dppclk_threshold(struct dc *dc, struct dc_state *context) -{ - bool request_dpp_div = context->bw.dcn.clk.dispclk_khz > - context->bw.dcn.clk.dppclk_khz; - bool dispclk_increase = context->bw.dcn.clk.dispclk_khz > - dc->res_pool->dccg->clks.dispclk_khz; - int disp_clk_threshold = context->bw.dcn.clk.max_supported_dppclk_khz; - bool cur_dpp_div = dc->res_pool->dccg->clks.dispclk_khz > - dc->res_pool->dccg->clks.dppclk_khz; - - /* increase clock, looking for div is 0 for current, request div is 1*/ - if (dispclk_increase) { - /* already divided by 2, no need to reach target clk with 2 steps*/ - if (cur_dpp_div) - return context->bw.dcn.clk.dispclk_khz; - - /* request disp clk is lower than maximum supported dpp clk, - * no need to reach target clk with two steps. - */ - if (context->bw.dcn.clk.dispclk_khz <= disp_clk_threshold) - return context->bw.dcn.clk.dispclk_khz; - - /* target dpp clk not request divided by 2, still within threshold */ - if (!request_dpp_div) - return context->bw.dcn.clk.dispclk_khz; - - } else { - /* decrease clock, looking for current dppclk divided by 2, - * request dppclk not divided by 2. - */ - - /* current dpp clk not divided by 2, no need to ramp*/ - if (!cur_dpp_div) - return context->bw.dcn.clk.dispclk_khz; - - /* current disp clk is lower than current maximum dpp clk, - * no need to ramp - */ - if (dc->res_pool->dccg->clks.dispclk_khz <= disp_clk_threshold) - return context->bw.dcn.clk.dispclk_khz; - - /* request dpp clk need to be divided by 2 */ - if (request_dpp_div) - return context->bw.dcn.clk.dispclk_khz; - } - - return disp_clk_threshold; -} - -static void ramp_up_dispclk_with_dpp(struct dc *dc, struct dc_state *context) -{ - int i; - bool request_dpp_div = context->bw.dcn.clk.dispclk_khz > - context->bw.dcn.clk.dppclk_khz; - - int dispclk_to_dpp_threshold = determine_dppclk_threshold(dc, context); - - /* set disp clk to dpp clk threshold */ - dc->res_pool->dccg->funcs->set_dispclk( - dc->res_pool->dccg, - dispclk_to_dpp_threshold); - - /* update request dpp clk division option */ - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; - - if (!pipe_ctx->plane_state) - continue; - - pipe_ctx->plane_res.dpp->funcs->dpp_dppclk_control( - pipe_ctx->plane_res.dpp, - request_dpp_div, - true); - } - - /* If target clk not same as dppclk threshold, set to target clock */ - if (dispclk_to_dpp_threshold != context->bw.dcn.clk.dispclk_khz) { - dc->res_pool->dccg->funcs->set_dispclk( - dc->res_pool->dccg, - context->bw.dcn.clk.dispclk_khz); - } - - dc->res_pool->dccg->clks.dispclk_khz = - context->bw.dcn.clk.dispclk_khz; - dc->res_pool->dccg->clks.dppclk_khz = - context->bw.dcn.clk.dppclk_khz; - dc->res_pool->dccg->clks.max_supported_dppclk_khz = - context->bw.dcn.clk.max_supported_dppclk_khz; -} - -static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_clk) -{ - return ((safe_to_lower && calc_clk < cur_clk) || calc_clk > cur_clk); -} - static void dcn10_set_bandwidth( struct dc *dc, struct dc_state *context, @@ -2475,17 +2380,6 @@ static void dcn10_set_bandwidth( &context->bw.dcn.clk, decrease_allowed); - /* make sure dcf clk is before dpp clk to - * make sure we have enough voltage to run dpp clk - */ - if (should_set_clock( - decrease_allowed, - context->bw.dcn.clk.dispclk_khz, - dc->res_pool->dccg->clks.dispclk_khz)) { - - ramp_up_dispclk_with_dpp(dc, context); - } - dcn10_pplib_apply_display_requirements(dc, context); if (dc->debug.sanity_checks) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 8f1ceffa809b..b5a727f7e880 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1072,7 +1072,7 @@ static bool construct( } } - pool->base.dccg = dcn_dccg_create(ctx); + pool->base.dccg = dcn1_dccg_create(ctx); if (pool->base.dccg == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); From 472800a0a0c84e224a7d4d5a4cfcd8dd6a4dd2b1 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Thu, 24 May 2018 15:50:18 -0400 Subject: [PATCH 021/133] drm/amd/display: clean up dccg divider calc and dcn constructor No functional change. Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dce/dce_clocks.c | 193 ++++++------------ .../gpu/drm/amd/display/dc/dce/dce_clocks.h | 26 --- 2 files changed, 66 insertions(+), 153 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index 55f533cf55ba..6e3bfdf8a9e7 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -101,90 +101,42 @@ static const struct state_dependent_clocks dce120_max_clks_by_state[] = { /*ClocksStatePerformance*/ { .display_clk_khz = 1133000, .pixel_clk_khz = 600000 } }; -/* Starting point for each divider range.*/ -enum dce_divider_range_start { - DIVIDER_RANGE_01_START = 200, /* 2.00*/ - DIVIDER_RANGE_02_START = 1600, /* 16.00*/ - DIVIDER_RANGE_03_START = 3200, /* 32.00*/ - DIVIDER_RANGE_SCALE_FACTOR = 100 /* Results are scaled up by 100.*/ +/* Starting DID for each range */ +enum dentist_base_divider_id { + dentist_base_divider_id_1 = 0x08, + dentist_base_divider_id_2 = 0x40, + dentist_base_divider_id_3 = 0x60, + dentist_max_divider_id = 0x80 }; -/* Ranges for divider identifiers (Divider ID or DID) - mmDENTIST_DISPCLK_CNTL.DENTIST_DISPCLK_WDIVIDER*/ -enum dce_divider_id_register_setting { - DIVIDER_RANGE_01_BASE_DIVIDER_ID = 0X08, - DIVIDER_RANGE_02_BASE_DIVIDER_ID = 0X40, - DIVIDER_RANGE_03_BASE_DIVIDER_ID = 0X60, - DIVIDER_RANGE_MAX_DIVIDER_ID = 0X80 +/* Starting point and step size for each divider range.*/ +enum dentist_divider_range { + dentist_divider_range_1_start = 8, /* 2.00 */ + dentist_divider_range_1_step = 1, /* 0.25 */ + dentist_divider_range_2_start = 64, /* 16.00 */ + dentist_divider_range_2_step = 2, /* 0.50 */ + dentist_divider_range_3_start = 128, /* 32.00 */ + dentist_divider_range_3_step = 4, /* 1.00 */ + dentist_divider_range_scale_factor = 4 }; -/* Step size between each divider within a range. - Incrementing the DENTIST_DISPCLK_WDIVIDER by one - will increment the divider by this much.*/ -enum dce_divider_range_step_size { - DIVIDER_RANGE_01_STEP_SIZE = 25, /* 0.25*/ - DIVIDER_RANGE_02_STEP_SIZE = 50, /* 0.50*/ - DIVIDER_RANGE_03_STEP_SIZE = 100 /* 1.00 */ -}; - -static bool dce_divider_range_construct( - struct dce_divider_range *div_range, - int range_start, - int range_step, - int did_min, - int did_max) +static int dentist_get_divider_from_did(int did) { - div_range->div_range_start = range_start; - div_range->div_range_step = range_step; - div_range->did_min = did_min; - div_range->did_max = did_max; + if (did < dentist_base_divider_id_1) + did = dentist_base_divider_id_1; + if (did > dentist_max_divider_id) + did = dentist_max_divider_id; - if (div_range->div_range_step == 0) { - div_range->div_range_step = 1; - /*div_range_step cannot be zero*/ - BREAK_TO_DEBUGGER(); + if (did < dentist_base_divider_id_2) { + return dentist_divider_range_1_start + dentist_divider_range_1_step + * (did - dentist_base_divider_id_1); + } else if (did < dentist_base_divider_id_3) { + return dentist_divider_range_2_start + dentist_divider_range_2_step + * (did - dentist_base_divider_id_2); + } else { + return dentist_divider_range_3_start + dentist_divider_range_3_step + * (did - dentist_base_divider_id_3); } - /* Calculate this based on the other inputs.*/ - /* See DividerRange.h for explanation of */ - /* the relationship between divider id (DID) and a divider.*/ - /* Number of Divider IDs = (Maximum Divider ID - Minimum Divider ID)*/ - /* Maximum divider identified in this range = - * (Number of Divider IDs)*Step size between dividers - * + The start of this range.*/ - div_range->div_range_end = (did_max - did_min) * range_step - + range_start; - return true; -} - -static int dce_divider_range_calc_divider( - struct dce_divider_range *div_range, - int did) -{ - /* Is this DID within our range?*/ - if ((did < div_range->did_min) || (did >= div_range->did_max)) - return INVALID_DIVIDER; - - return ((did - div_range->did_min) * div_range->div_range_step) - + div_range->div_range_start; - -} - -static int dce_divider_range_get_divider( - struct dce_divider_range *div_range, - int ranges_num, - int did) -{ - int div = INVALID_DIVIDER; - int i; - - for (i = 0; i < ranges_num; i++) { - /* Calculate divider with given divider ID*/ - div = dce_divider_range_calc_divider(&div_range[i], did); - /* Found a valid return divider*/ - if (div != INVALID_DIVIDER) - break; - } - return div; } static int dce_clocks_get_dp_ref_freq(struct dccg *clk) @@ -193,7 +145,7 @@ static int dce_clocks_get_dp_ref_freq(struct dccg *clk) int dprefclk_wdivider; int dprefclk_src_sel; int dp_ref_clk_khz = 600000; - int target_div = INVALID_DIVIDER; + int target_div; /* ASSERT DP Reference Clock source is from DFS*/ REG_GET(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, &dprefclk_src_sel); @@ -204,16 +156,11 @@ static int dce_clocks_get_dp_ref_freq(struct dccg *clk) REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, &dprefclk_wdivider); /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ - target_div = dce_divider_range_get_divider( - clk_dce->divider_ranges, - DIVIDER_RANGE_MAX, - dprefclk_wdivider); + target_div = dentist_get_divider_from_did(dprefclk_wdivider); - if (target_div != INVALID_DIVIDER) { - /* Calculate the current DFS clock, in kHz.*/ - dp_ref_clk_khz = (DIVIDER_RANGE_SCALE_FACTOR - * clk_dce->dentist_vco_freq_khz) / target_div; - } + /* Calculate the current DFS clock, in kHz.*/ + dp_ref_clk_khz = (dentist_divider_range_scale_factor + * clk_dce->dentist_vco_freq_khz) / target_div; /* SW will adjust DP REF Clock average value for all purposes * (DP DTO / DP Audio DTO and DP GTC) @@ -229,17 +176,12 @@ static int dce_clocks_get_dp_ref_freq(struct dccg *clk) */ if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) { struct fixed31_32 ss_percentage = dc_fixpt_div_int( - dc_fixpt_from_fraction( - clk_dce->dprefclk_ss_percentage, - clk_dce->dprefclk_ss_divider), 200); + dc_fixpt_from_fraction(clk_dce->dprefclk_ss_percentage, + clk_dce->dprefclk_ss_divider), 200); struct fixed31_32 adj_dp_ref_clk_khz; - ss_percentage = dc_fixpt_sub(dc_fixpt_one, - ss_percentage); - adj_dp_ref_clk_khz = - dc_fixpt_mul_int( - ss_percentage, - dp_ref_clk_khz); + ss_percentage = dc_fixpt_sub(dc_fixpt_one, ss_percentage); + adj_dp_ref_clk_khz = dc_fixpt_mul_int(ss_percentage, dp_ref_clk_khz); dp_ref_clk_khz = dc_fixpt_floor(adj_dp_ref_clk_khz); } @@ -257,17 +199,12 @@ static int dce_clocks_get_dp_ref_freq_wrkaround(struct dccg *clk) if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) { struct fixed31_32 ss_percentage = dc_fixpt_div_int( - dc_fixpt_from_fraction( - clk_dce->dprefclk_ss_percentage, + dc_fixpt_from_fraction(clk_dce->dprefclk_ss_percentage, clk_dce->dprefclk_ss_divider), 200); struct fixed31_32 adj_dp_ref_clk_khz; - ss_percentage = dc_fixpt_sub(dc_fixpt_one, - ss_percentage); - adj_dp_ref_clk_khz = - dc_fixpt_mul_int( - ss_percentage, - dp_ref_clk_khz); + ss_percentage = dc_fixpt_sub(dc_fixpt_one, ss_percentage); + adj_dp_ref_clk_khz = dc_fixpt_mul_int(ss_percentage, dp_ref_clk_khz); dp_ref_clk_khz = dc_fixpt_floor(adj_dp_ref_clk_khz); } @@ -804,25 +741,6 @@ static void dce_dccg_construct( dce_clock_read_integrated_info(clk_dce); dce_clock_read_ss_info(clk_dce); - - dce_divider_range_construct( - &clk_dce->divider_ranges[DIVIDER_RANGE_01], - DIVIDER_RANGE_01_START, - DIVIDER_RANGE_01_STEP_SIZE, - DIVIDER_RANGE_01_BASE_DIVIDER_ID, - DIVIDER_RANGE_02_BASE_DIVIDER_ID); - dce_divider_range_construct( - &clk_dce->divider_ranges[DIVIDER_RANGE_02], - DIVIDER_RANGE_02_START, - DIVIDER_RANGE_02_STEP_SIZE, - DIVIDER_RANGE_02_BASE_DIVIDER_ID, - DIVIDER_RANGE_03_BASE_DIVIDER_ID); - dce_divider_range_construct( - &clk_dce->divider_ranges[DIVIDER_RANGE_03], - DIVIDER_RANGE_03_START, - DIVIDER_RANGE_03_STEP_SIZE, - DIVIDER_RANGE_03_BASE_DIVIDER_ID, - DIVIDER_RANGE_MAX_DIVIDER_ID); } struct dccg *dce_dccg_create( @@ -921,6 +839,9 @@ struct dccg *dce120_dccg_create(struct dc_context *ctx) struct dccg *dcn1_dccg_create(struct dc_context *ctx) { + struct dc_debug *debug = &ctx->dc->debug; + struct dc_bios *bp = ctx->dc_bios; + struct dc_firmware_info fw_info = { { 0 } }; struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); if (clk_dce == NULL) { @@ -928,12 +849,30 @@ struct dccg *dcn1_dccg_create(struct dc_context *ctx) return NULL; } - /* TODO strip out useful stuff out of dce constructor */ - dce_dccg_construct( - clk_dce, ctx, NULL, NULL, NULL); - + clk_dce->base.ctx = ctx; clk_dce->base.funcs = &dcn1_funcs; + clk_dce->dfs_bypass_disp_clk = 0; + + clk_dce->dprefclk_ss_percentage = 0; + clk_dce->dprefclk_ss_divider = 1000; + clk_dce->ss_on_dprefclk = false; + + if (bp->integrated_info) + clk_dce->dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq; + if (clk_dce->dentist_vco_freq_khz == 0) { + bp->funcs->get_firmware_info(bp, &fw_info); + clk_dce->dentist_vco_freq_khz = fw_info.smu_gpu_pll_output_freq; + if (clk_dce->dentist_vco_freq_khz == 0) + clk_dce->dentist_vco_freq_khz = 3600000; + } + + if (!debug->disable_dfs_bypass && bp->integrated_info) + if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) + clk_dce->dfs_bypass_enabled = true; + + dce_clock_read_ss_info(clk_dce); + return &clk_dce->base; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h index 7907c3c4b1c1..04a9e3c04aa7 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h @@ -57,31 +57,6 @@ struct dce_disp_clk_registers { uint32_t DENTIST_DISPCLK_CNTL; }; -/* Array identifiers and count for the divider ranges.*/ -enum dce_divider_range_count { - DIVIDER_RANGE_01 = 0, - DIVIDER_RANGE_02, - DIVIDER_RANGE_03, - DIVIDER_RANGE_MAX /* == 3*/ -}; - -enum dce_divider_error_types { - INVALID_DID = 0, - INVALID_DIVIDER = 1 -}; - -struct dce_divider_range { - int div_range_start; - /* The end of this range of dividers.*/ - int div_range_end; - /* The distance between each divider in this range.*/ - int div_range_step; - /* The divider id for the lowest divider.*/ - int did_min; - /* The divider id for the highest divider.*/ - int did_max; -}; - struct dce_dccg { struct dccg base; const struct dce_disp_clk_registers *regs; @@ -89,7 +64,6 @@ struct dce_dccg { const struct dce_disp_clk_mask *clk_mask; struct state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES]; - struct dce_divider_range divider_ranges[DIVIDER_RANGE_MAX]; int dentist_vco_freq_khz; From 3cdecd4513d57993aaddc03ccdf4539add772aa4 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Thu, 24 May 2018 16:48:38 -0400 Subject: [PATCH 022/133] drm/amd/display: rename dce_disp_clk to dccg No functional change. Signed-off-by: Dmytro Laktyushkin Reviewed-by: Nikola Cornij Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dce/dce_clocks.c | 115 ++++++++---------- .../gpu/drm/amd/display/dc/dce/dce_clocks.h | 41 ++++--- .../gpu/drm/amd/display/dc/dce/dce_hwseq.h | 3 - .../amd/display/dc/dce100/dce100_resource.c | 6 +- .../amd/display/dc/dce110/dce110_resource.c | 6 +- .../amd/display/dc/dce112/dce112_resource.c | 6 +- .../drm/amd/display/dc/dce80/dce80_resource.c | 6 +- 7 files changed, 88 insertions(+), 95 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index 6e3bfdf8a9e7..242e8ae56025 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -139,7 +139,34 @@ static int dentist_get_divider_from_did(int did) } } -static int dce_clocks_get_dp_ref_freq(struct dccg *clk) +/* SW will adjust DP REF Clock average value for all purposes + * (DP DTO / DP Audio DTO and DP GTC) + if clock is spread for all cases: + -if SS enabled on DP Ref clock and HW de-spreading enabled with SW + calculations for DS_INCR/DS_MODULO (this is planned to be default case) + -if SS enabled on DP Ref clock and HW de-spreading enabled with HW + calculations (not planned to be used, but average clock should still + be valid) + -if SS enabled on DP Ref clock and HW de-spreading disabled + (should not be case with CIK) then SW should program all rates + generated according to average value (case as with previous ASICs) + */ +static int dccg_adjust_dp_ref_freq_for_ss(struct dce_dccg *clk_dce, int dp_ref_clk_khz) +{ + if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) { + struct fixed31_32 ss_percentage = dc_fixpt_div_int( + dc_fixpt_from_fraction(clk_dce->dprefclk_ss_percentage, + clk_dce->dprefclk_ss_divider), 200); + struct fixed31_32 adj_dp_ref_clk_khz; + + ss_percentage = dc_fixpt_sub(dc_fixpt_one, ss_percentage); + adj_dp_ref_clk_khz = dc_fixpt_mul_int(ss_percentage, dp_ref_clk_khz); + dp_ref_clk_khz = dc_fixpt_floor(adj_dp_ref_clk_khz); + } + return dp_ref_clk_khz; +} + +static int dce_get_dp_ref_freq_khz(struct dccg *clk) { struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); int dprefclk_wdivider; @@ -162,54 +189,16 @@ static int dce_clocks_get_dp_ref_freq(struct dccg *clk) dp_ref_clk_khz = (dentist_divider_range_scale_factor * clk_dce->dentist_vco_freq_khz) / target_div; - /* SW will adjust DP REF Clock average value for all purposes - * (DP DTO / DP Audio DTO and DP GTC) - if clock is spread for all cases: - -if SS enabled on DP Ref clock and HW de-spreading enabled with SW - calculations for DS_INCR/DS_MODULO (this is planned to be default case) - -if SS enabled on DP Ref clock and HW de-spreading enabled with HW - calculations (not planned to be used, but average clock should still - be valid) - -if SS enabled on DP Ref clock and HW de-spreading disabled - (should not be case with CIK) then SW should program all rates - generated according to average value (case as with previous ASICs) - */ - if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) { - struct fixed31_32 ss_percentage = dc_fixpt_div_int( - dc_fixpt_from_fraction(clk_dce->dprefclk_ss_percentage, - clk_dce->dprefclk_ss_divider), 200); - struct fixed31_32 adj_dp_ref_clk_khz; - - ss_percentage = dc_fixpt_sub(dc_fixpt_one, ss_percentage); - adj_dp_ref_clk_khz = dc_fixpt_mul_int(ss_percentage, dp_ref_clk_khz); - dp_ref_clk_khz = dc_fixpt_floor(adj_dp_ref_clk_khz); - } - - return dp_ref_clk_khz; + return dccg_adjust_dp_ref_freq_for_ss(clk_dce, dp_ref_clk_khz); } -/* TODO: This is DCN DPREFCLK: it could be program by DENTIST by VBIOS - * or CLK0_CLK11 by SMU. For DCE120, it is wlays 600Mhz. Will re-visit - * clock implementation - */ -static int dce_clocks_get_dp_ref_freq_wrkaround(struct dccg *clk) +static int dce12_get_dp_ref_freq_khz(struct dccg *clk) { struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); - int dp_ref_clk_khz = 600000; - if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) { - struct fixed31_32 ss_percentage = dc_fixpt_div_int( - dc_fixpt_from_fraction(clk_dce->dprefclk_ss_percentage, - clk_dce->dprefclk_ss_divider), 200); - struct fixed31_32 adj_dp_ref_clk_khz; - - ss_percentage = dc_fixpt_sub(dc_fixpt_one, ss_percentage); - adj_dp_ref_clk_khz = dc_fixpt_mul_int(ss_percentage, dp_ref_clk_khz); - dp_ref_clk_khz = dc_fixpt_floor(adj_dp_ref_clk_khz); - } - - return dp_ref_clk_khz; + return dccg_adjust_dp_ref_freq_for_ss(clk_dce, 600000); } + static enum dm_pp_clocks_state dce_get_required_clocks_state( struct dccg *clk, struct dc_clocks *req_clocks) @@ -590,8 +579,7 @@ static void dcn1_update_clocks(struct dccg *dccg, /* make sure dcf clk is before dpp clk to * make sure we have enough voltage to run dpp clk */ - if (send_request_to_increase - ) { + if (send_request_to_increase) { /*use dcfclk to request voltage*/ clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); @@ -644,8 +632,7 @@ static void dcn1_update_clocks(struct dccg *dccg, } #ifdef CONFIG_DRM_AMD_DC_DCN1_0 - if (!send_request_to_increase && send_request_to_lower - ) { + if (!send_request_to_increase && send_request_to_lower) { /*use dcfclk to request voltage*/ clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); @@ -685,31 +672,31 @@ static void dce_update_clocks(struct dccg *dccg, } static const struct display_clock_funcs dcn1_funcs = { - .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq_wrkaround, + .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, .set_dispclk = dce112_set_clock, .update_clocks = dcn1_update_clocks }; static const struct display_clock_funcs dce120_funcs = { - .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq_wrkaround, + .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, .set_dispclk = dce112_set_clock, .update_clocks = dce12_update_clocks }; static const struct display_clock_funcs dce112_funcs = { - .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq, + .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, .set_dispclk = dce112_set_clock, .update_clocks = dce_update_clocks }; static const struct display_clock_funcs dce110_funcs = { - .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq, + .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, .set_dispclk = dce_psr_set_clock, .update_clocks = dce_update_clocks }; static const struct display_clock_funcs dce_funcs = { - .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq, + .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, .set_dispclk = dce_set_clock, .update_clocks = dce_update_clocks }; @@ -717,9 +704,9 @@ static const struct display_clock_funcs dce_funcs = { static void dce_dccg_construct( struct dce_dccg *clk_dce, struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask) + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask) { struct dccg *base = &clk_dce->base; @@ -745,9 +732,9 @@ static void dce_dccg_construct( struct dccg *dce_dccg_create( struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask) + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask) { struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); @@ -768,9 +755,9 @@ struct dccg *dce_dccg_create( struct dccg *dce110_dccg_create( struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask) + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask) { struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); @@ -793,9 +780,9 @@ struct dccg *dce110_dccg_create( struct dccg *dce112_dccg_create( struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask) + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask) { struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h index 04a9e3c04aa7..be5b68d7c3c0 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h @@ -33,6 +33,9 @@ .DPREFCLK_CNTL = mmDPREFCLK_CNTL, \ .DENTIST_DISPCLK_CNTL = mmDENTIST_DISPCLK_CNTL +#define CLK_COMMON_REG_LIST_DCN_BASE() \ + SR(DENTIST_DISPCLK_CNTL) + #define CLK_SF(reg_name, field_name, post_fix)\ .field_name = reg_name ## __ ## field_name ## post_fix @@ -40,28 +43,34 @@ CLK_SF(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, mask_sh), \ CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, mask_sh) +#define CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh) \ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, mask_sh),\ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh) + #define CLK_REG_FIELD_LIST(type) \ type DPREFCLK_SRC_SEL; \ - type DENTIST_DPREFCLK_WDIVIDER; + type DENTIST_DPREFCLK_WDIVIDER; \ + type DENTIST_DISPCLK_WDIVIDER; \ + type DENTIST_DPPCLK_WDIVIDER; -struct dce_disp_clk_shift { +struct dccg_shift { CLK_REG_FIELD_LIST(uint8_t) }; -struct dce_disp_clk_mask { +struct dccg_mask { CLK_REG_FIELD_LIST(uint32_t) }; -struct dce_disp_clk_registers { +struct dccg_registers { uint32_t DPREFCLK_CNTL; uint32_t DENTIST_DISPCLK_CNTL; }; struct dce_dccg { struct dccg base; - const struct dce_disp_clk_registers *regs; - const struct dce_disp_clk_shift *clk_shift; - const struct dce_disp_clk_mask *clk_mask; + const struct dccg_registers *regs; + const struct dccg_shift *clk_shift; + const struct dccg_mask *clk_mask; struct state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES]; @@ -84,21 +93,21 @@ struct dce_dccg { struct dccg *dce_dccg_create( struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask); + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask); struct dccg *dce110_dccg_create( struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask); + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask); struct dccg *dce112_dccg_create( struct dc_context *ctx, - const struct dce_disp_clk_registers *regs, - const struct dce_disp_clk_shift *clk_shift, - const struct dce_disp_clk_mask *clk_mask); + const struct dccg_registers *regs, + const struct dccg_shift *clk_shift, + const struct dccg_mask *clk_mask); struct dccg *dce120_dccg_create(struct dc_context *ctx); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index 057b8afd74bc..057407892618 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h @@ -249,7 +249,6 @@ struct dce_hwseq_registers { uint32_t DISPCLK_FREQ_CHANGE_CNTL; uint32_t RBBMIF_TIMEOUT_DIS; uint32_t RBBMIF_TIMEOUT_DIS_2; - uint32_t DENTIST_DISPCLK_CNTL; uint32_t DCHUBBUB_CRC_CTRL; uint32_t DPP_TOP0_DPP_CRC_CTRL; uint32_t DPP_TOP0_DPP_CRC_VAL_R_G; @@ -496,8 +495,6 @@ struct dce_hwseq_registers { type DOMAIN7_PGFSM_PWR_STATUS; \ type DCFCLK_GATE_DIS; \ type DCHUBBUB_GLOBAL_TIMER_REFDIV; \ - type DENTIST_DPPCLK_WDIVIDER; \ - type DENTIST_DISPCLK_WDIVIDER; \ type VGA_TEST_ENABLE; \ type VGA_TEST_RENDER_START; \ type D1VGA_MODE_ENABLE; \ diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index 856d3fe8e6a0..8ed8eace42be 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c @@ -135,15 +135,15 @@ static const struct dce110_timing_generator_offsets dce100_tg_offsets[] = { .reg_name = mm ## block ## id ## _ ## reg_name -static const struct dce_disp_clk_registers disp_clk_regs = { +static const struct dccg_registers disp_clk_regs = { CLK_COMMON_REG_LIST_DCE_BASE() }; -static const struct dce_disp_clk_shift disp_clk_shift = { +static const struct dccg_shift disp_clk_shift = { CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) }; -static const struct dce_disp_clk_mask disp_clk_mask = { +static const struct dccg_mask disp_clk_mask = { CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) }; 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 71a401f73a58..3edaa006bd57 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -146,15 +146,15 @@ static const struct dce110_timing_generator_offsets dce110_tg_offsets[] = { #define SRI(reg_name, block, id)\ .reg_name = mm ## block ## id ## _ ## reg_name -static const struct dce_disp_clk_registers disp_clk_regs = { +static const struct dccg_registers disp_clk_regs = { CLK_COMMON_REG_LIST_DCE_BASE() }; -static const struct dce_disp_clk_shift disp_clk_shift = { +static const struct dccg_shift disp_clk_shift = { CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) }; -static const struct dce_disp_clk_mask disp_clk_mask = { +static const struct dccg_mask disp_clk_mask = { CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) }; diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index ae5b19de559c..752910035e81 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c @@ -146,15 +146,15 @@ static const struct dce110_timing_generator_offsets dce112_tg_offsets[] = { .reg_name = mm ## block ## id ## _ ## reg_name -static const struct dce_disp_clk_registers disp_clk_regs = { +static const struct dccg_registers disp_clk_regs = { CLK_COMMON_REG_LIST_DCE_BASE() }; -static const struct dce_disp_clk_shift disp_clk_shift = { +static const struct dccg_shift disp_clk_shift = { CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) }; -static const struct dce_disp_clk_mask disp_clk_mask = { +static const struct dccg_mask disp_clk_mask = { CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) }; diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c index 70700530aec2..2ac95ec2bf96 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c @@ -153,15 +153,15 @@ static const struct dce110_timing_generator_offsets dce80_tg_offsets[] = { .reg_name = mm ## block ## id ## _ ## reg_name -static const struct dce_disp_clk_registers disp_clk_regs = { +static const struct dccg_registers disp_clk_regs = { CLK_COMMON_REG_LIST_DCE_BASE() }; -static const struct dce_disp_clk_shift disp_clk_shift = { +static const struct dccg_shift disp_clk_shift = { CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) }; -static const struct dce_disp_clk_mask disp_clk_mask = { +static const struct dccg_mask disp_clk_mask = { CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) }; From c910a717dac6540a636a57c1a34261c6d84fc0eb Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 23 May 2018 18:39:21 -0400 Subject: [PATCH 023/133] drm/amd/display: clean up set_bandwidth usage This removes redundant set_bandwidth calls as well as fixes a bug in post_set_address_update where dcn1 would never get to lower clocks. Signed-off-by: Dmytro Laktyushkin Reviewed-by: Nikola Cornij Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 5 ----- .../drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 5 ----- .../gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 11 +++-------- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 53ce7fa864b4..2a785bbf2b8f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -944,12 +944,7 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) dc->optimized_required = false; - /* 3rd param should be true, temp w/a for RV*/ -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) - dc->hwss.set_bandwidth(dc, context, dc->ctx->dce_version < DCN_VERSION_1_0); -#else dc->hwss.set_bandwidth(dc, context, true); -#endif return true; } diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 4cdf86690d19..3b983b3f3423 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -2036,8 +2036,6 @@ enum dc_status dce110_apply_ctx_to_hw( if (dc->fbc_compressor) dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); - dc->hwss.set_bandwidth(dc, context, false); - dce110_setup_audio_dto(dc, context); for (i = 0; i < dc->res_pool->pipe_count; i++) { @@ -2066,9 +2064,6 @@ enum dc_status dce110_apply_ctx_to_hw( return status; } - /* to save power */ - dc->hwss.set_bandwidth(dc, context, true); - dcb->funcs->set_scratch_critical_state(dcb, false); if (dc->fbc_compressor) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 60e99477930b..08809b0ff6bf 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2268,8 +2268,7 @@ static void dcn10_apply_ctx_for_surface( hwss1_plane_atomic_disconnect(dc, old_pipe_ctx); removed_pipe[i] = true; - DC_LOG_DC( - "Reset mpcc for pipe %d\n", + DC_LOG_DC("Reset mpcc for pipe %d\n", old_pipe_ctx->pipe_idx); } } @@ -2365,9 +2364,8 @@ static void dcn10_set_bandwidth( struct dc_state *context, bool decrease_allowed) { - if (dc->debug.sanity_checks) { + if (dc->debug.sanity_checks) dcn10_verify_allow_pstate_change_high(dc); - } if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) return; @@ -2382,11 +2380,8 @@ static void dcn10_set_bandwidth( dcn10_pplib_apply_display_requirements(dc, context); - if (dc->debug.sanity_checks) { + if (dc->debug.sanity_checks) dcn10_verify_allow_pstate_change_high(dc); - } - - /* need to fix this function. not doing the right thing here */ } static void set_drr(struct pipe_ctx **pipe_ctx, From aa162e2727254262a79509ec3e99ace33b3232b6 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Thu, 31 May 2018 13:28:00 -0400 Subject: [PATCH 024/133] drm/amd/display: remove unnecessary pplib volage requests that are asserting Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index 242e8ae56025..df6a37b7b769 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -588,21 +588,15 @@ static void dcn1_update_clocks(struct dccg *dccg, #endif if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { - clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK; - clock_voltage_req.clocks_in_khz = new_clocks->dispclk_khz; dcn1_ramp_up_dispclk_with_dpp(dccg, new_clocks); dccg->clks.dispclk_khz = new_clocks->dispclk_khz; - dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); send_request_to_lower = true; } if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, dccg->clks.phyclk_khz)) { - dccg->clks.phyclk_khz = new_clocks->phyclk_khz; - clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAYPHYCLK; clock_voltage_req.clocks_in_khz = new_clocks->phyclk_khz; - dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); send_request_to_lower = true; } @@ -618,8 +612,6 @@ static void dcn1_update_clocks(struct dccg *dccg, if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, dccg->clks.dcfclk_khz)) { dccg->clks.phyclk_khz = new_clocks->dcfclk_khz; - clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; - clock_voltage_req.clocks_in_khz = new_clocks->dcfclk_khz; smu_req.hard_min_dcefclk_khz = new_clocks->dcfclk_khz; send_request_to_lower = true; From 0eebf8ca18b647024fc9a3ccc88c0184d02db534 Mon Sep 17 00:00:00 2001 From: Wesley Chalmers Date: Fri, 1 Jun 2018 10:54:53 -0400 Subject: [PATCH 025/133] drm/amd/display: Temporarily remove Chroma logs To ensure tests continue to pass Signed-off-by: Wesley Chalmers Reviewed-by: Shahin Khayyer Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 08809b0ff6bf..5b40c1c4d9e6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -151,23 +151,19 @@ static void dcn10_log_hubp_states(struct dc *dc) DTN_INFO("\n=========RQ========\n"); DTN_INFO("HUBP: drq_exp_m prq_exp_m mrq_exp_m crq_exp_m plane1_ba L:chunk_s min_chu_s meta_ch_s" - " min_m_c_s dpte_gr_s mpte_gr_s swath_hei pte_row_h C:chunk_s min_chu_s meta_ch_s" " min_m_c_s dpte_gr_s mpte_gr_s swath_hei pte_row_h\n"); for (i = 0; i < pool->pipe_count; i++) { struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state); struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs; if (!s->blank_en) - DTN_INFO("[%2d]: %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh\n", + DTN_INFO("[%2d]: %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh\n", pool->hubps[i]->inst, rq_regs->drq_expansion_mode, rq_regs->prq_expansion_mode, rq_regs->mrq_expansion_mode, rq_regs->crq_expansion_mode, rq_regs->plane1_base_address, rq_regs->rq_regs_l.chunk_size, rq_regs->rq_regs_l.min_chunk_size, rq_regs->rq_regs_l.meta_chunk_size, rq_regs->rq_regs_l.min_meta_chunk_size, rq_regs->rq_regs_l.dpte_group_size, rq_regs->rq_regs_l.mpte_group_size, rq_regs->rq_regs_l.swath_height, - rq_regs->rq_regs_l.pte_row_height_linear, rq_regs->rq_regs_c.chunk_size, rq_regs->rq_regs_c.min_chunk_size, - rq_regs->rq_regs_c.meta_chunk_size, rq_regs->rq_regs_c.min_meta_chunk_size, - rq_regs->rq_regs_c.dpte_group_size, rq_regs->rq_regs_c.mpte_group_size, - rq_regs->rq_regs_c.swath_height, rq_regs->rq_regs_c.pte_row_height_linear); + rq_regs->rq_regs_l.pte_row_height_linear); } DTN_INFO("========DLG========\n"); From 7e17cb4ba90cf2ab51e65427092fdc878cc956bc Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Wed, 30 May 2018 15:58:08 -0400 Subject: [PATCH 026/133] drm/amd/display: Define dp_alt_mode Also cleanup command_table2.c. No need for a lot of forward declarations. Signed-off-by: Charlene Liu Reviewed-by: Krunoslav Kovac Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/bios/command_table2.c | 46 +++++++------------ .../amd/display/dc/dcn10/dcn10_link_encoder.c | 2 + .../drm/amd/display/include/grph_object_id.h | 5 ++ 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c index 752b08a42d3e..2b5dc499a35e 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c @@ -59,36 +59,7 @@ bios_cmd_table_para_revision(bp->base.ctx->driver_context, \ GET_INDEX_INTO_MASTER_TABLE(command, fname)) -static void init_dig_encoder_control(struct bios_parser *bp); -static void init_transmitter_control(struct bios_parser *bp); -static void init_set_pixel_clock(struct bios_parser *bp); -static void init_set_crtc_timing(struct bios_parser *bp); - -static void init_select_crtc_source(struct bios_parser *bp); -static void init_enable_crtc(struct bios_parser *bp); - -static void init_external_encoder_control(struct bios_parser *bp); -static void init_enable_disp_power_gating(struct bios_parser *bp); -static void init_set_dce_clock(struct bios_parser *bp); -static void init_get_smu_clock_info(struct bios_parser *bp); - -void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp) -{ - init_dig_encoder_control(bp); - init_transmitter_control(bp); - init_set_pixel_clock(bp); - - init_set_crtc_timing(bp); - - init_select_crtc_source(bp); - init_enable_crtc(bp); - - init_external_encoder_control(bp); - init_enable_disp_power_gating(bp); - init_set_dce_clock(bp); - init_get_smu_clock_info(bp); -} static uint32_t bios_cmd_table_para_revision(void *dev, uint32_t index) @@ -829,3 +800,20 @@ static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id) return 0; } +void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp) +{ + init_dig_encoder_control(bp); + init_transmitter_control(bp); + init_set_pixel_clock(bp); + + init_set_crtc_timing(bp); + + init_select_crtc_source(bp); + init_enable_crtc(bp); + + init_external_encoder_control(bp); + init_enable_disp_power_gating(bp); + init_set_dce_clock(bp); + init_get_smu_clock_info(bp); + +} diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c index 21fa40ac0786..fd9dc70190a8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c @@ -995,6 +995,8 @@ void dcn10_link_encoder_disable_output( if (!dcn10_is_dig_enabled(enc)) { /* OF_SKIP_POWER_DOWN_INACTIVE_ENCODER */ + /*in DP_Alt_No_Connect case, we turn off the dig already, + after excuation the PHY w/a sequence, not allow touch PHY any more*/ return; } /* Power-down RX and disable GPU PHY should be paired. diff --git a/drivers/gpu/drm/amd/display/include/grph_object_id.h b/drivers/gpu/drm/amd/display/include/grph_object_id.h index c4197432eb7c..92cc6c112ea6 100644 --- a/drivers/gpu/drm/amd/display/include/grph_object_id.h +++ b/drivers/gpu/drm/amd/display/include/grph_object_id.h @@ -197,6 +197,11 @@ enum transmitter_color_depth { TRANSMITTER_COLOR_DEPTH_48 /* 16 bits */ }; +enum dp_alt_mode { + DP_Alt_mode__Unknown = 0, + DP_Alt_mode__Connect, + DP_Alt_mode__NoConnect, +}; /* ***************************************************************************** * graphics_object_id struct From 89af301e21b53317f1d0c5ed6f8e935f65e877d0 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Fri, 1 Jun 2018 14:13:40 -0400 Subject: [PATCH 027/133] drm/amd/display: fix dccg dcn1 ifdef Signed-off-by: Dmytro Laktyushkin Reviewed-by: Eric Yang Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c | 10 ++++++---- drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index df6a37b7b769..e62a21f55064 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -478,6 +478,7 @@ static void dce12_update_clocks(struct dccg *dccg, } } +#ifdef CONFIG_DRM_AMD_DC_DCN1_0 static int dcn1_determine_dppclk_threshold(struct dccg *dccg, struct dc_clocks *new_clocks) { bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; @@ -575,7 +576,6 @@ static void dcn1_update_clocks(struct dccg *dccg, || new_clocks->dcfclk_khz > dccg->clks.dcfclk_khz) send_request_to_increase = true; -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 /* make sure dcf clk is before dpp clk to * make sure we have enough voltage to run dpp clk */ @@ -585,7 +585,6 @@ static void dcn1_update_clocks(struct dccg *dccg, clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); } -#endif if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { dcn1_ramp_up_dispclk_with_dpp(dccg, new_clocks); @@ -623,14 +622,12 @@ static void dcn1_update_clocks(struct dccg *dccg, smu_req.min_deep_sleep_dcefclk_mhz = new_clocks->dcfclk_deep_sleep_khz; } -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 if (!send_request_to_increase && send_request_to_lower) { /*use dcfclk to request voltage*/ clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); } -#endif if (new_clocks->phyclk_khz) smu_req.display_count = 1; @@ -642,6 +639,7 @@ static void dcn1_update_clocks(struct dccg *dccg, *smu_req_cur = smu_req; } +#endif static void dce_update_clocks(struct dccg *dccg, struct dc_clocks *new_clocks, @@ -663,11 +661,13 @@ static void dce_update_clocks(struct dccg *dccg, } } +#ifdef CONFIG_DRM_AMD_DC_DCN1_0 static const struct display_clock_funcs dcn1_funcs = { .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, .set_dispclk = dce112_set_clock, .update_clocks = dcn1_update_clocks }; +#endif static const struct display_clock_funcs dce120_funcs = { .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, @@ -816,6 +816,7 @@ struct dccg *dce120_dccg_create(struct dc_context *ctx) return &clk_dce->base; } +#ifdef CONFIG_DRM_AMD_DC_DCN1_0 struct dccg *dcn1_dccg_create(struct dc_context *ctx) { struct dc_debug *debug = &ctx->dc->debug; @@ -854,6 +855,7 @@ struct dccg *dcn1_dccg_create(struct dc_context *ctx) return &clk_dce->base; } +#endif void dce_dccg_destroy(struct dccg **dccg) { diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h index be5b68d7c3c0..1f1899ef773a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h @@ -111,7 +111,9 @@ struct dccg *dce112_dccg_create( struct dccg *dce120_dccg_create(struct dc_context *ctx); +#ifdef CONFIG_DRM_AMD_DC_DCN1_0 struct dccg *dcn1_dccg_create(struct dc_context *ctx); +#endif void dce_dccg_destroy(struct dccg **dccg); From 5b0ec710dadd4569c1ed76dc175b94abb594b977 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Fri, 1 Jun 2018 15:01:32 -0400 Subject: [PATCH 028/133] drm/amd/display: fix pplib voltage request This fixes incorrect clock caching and by extension fixes the clock reporting. Signed-off-by: Dmytro Laktyushkin Reviewed-by: Eric Yang Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dce/dce_clocks.c | 59 ++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index e62a21f55064..0a4ae0f49f99 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -570,37 +570,25 @@ static void dcn1_update_clocks(struct dccg *dccg, bool send_request_to_increase = false; bool send_request_to_lower = false; + if (new_clocks->phyclk_khz) + smu_req.display_count = 1; + else + smu_req.display_count = 0; + if (new_clocks->dispclk_khz > dccg->clks.dispclk_khz || new_clocks->phyclk_khz > dccg->clks.phyclk_khz || new_clocks->fclk_khz > dccg->clks.fclk_khz || new_clocks->dcfclk_khz > dccg->clks.dcfclk_khz) send_request_to_increase = true; - /* make sure dcf clk is before dpp clk to - * make sure we have enough voltage to run dpp clk - */ - if (send_request_to_increase) { - /*use dcfclk to request voltage*/ - clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; - clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); - dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); - } - - if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { - dcn1_ramp_up_dispclk_with_dpp(dccg, new_clocks); - dccg->clks.dispclk_khz = new_clocks->dispclk_khz; - - send_request_to_lower = true; - } - if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, dccg->clks.phyclk_khz)) { - clock_voltage_req.clocks_in_khz = new_clocks->phyclk_khz; + dccg->clks.phyclk_khz = new_clocks->phyclk_khz; send_request_to_lower = true; } if (should_set_clock(safe_to_lower, new_clocks->fclk_khz, dccg->clks.fclk_khz)) { - dccg->clks.phyclk_khz = new_clocks->fclk_khz; + dccg->clks.fclk_khz = new_clocks->fclk_khz; clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_FCLK; clock_voltage_req.clocks_in_khz = new_clocks->fclk_khz; smu_req.hard_min_fclk_khz = new_clocks->fclk_khz; @@ -610,7 +598,7 @@ static void dcn1_update_clocks(struct dccg *dccg, } if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, dccg->clks.dcfclk_khz)) { - dccg->clks.phyclk_khz = new_clocks->dcfclk_khz; + dccg->clks.dcfclk_khz = new_clocks->dcfclk_khz; smu_req.hard_min_dcefclk_khz = new_clocks->dcfclk_khz; send_request_to_lower = true; @@ -620,6 +608,28 @@ static void dcn1_update_clocks(struct dccg *dccg, new_clocks->dcfclk_deep_sleep_khz, dccg->clks.dcfclk_deep_sleep_khz)) { dccg->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz; smu_req.min_deep_sleep_dcefclk_mhz = new_clocks->dcfclk_deep_sleep_khz; + + send_request_to_lower = true; + } + + /* make sure dcf clk is before dpp clk to + * make sure we have enough voltage to run dpp clk + */ + if (send_request_to_increase) { + /*use dcfclk to request voltage*/ + clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; + clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); + dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); + if (pp_smu->set_display_requirement) + pp_smu->set_display_requirement(&pp_smu->pp_smu, &smu_req); + } + + /* dcn1 dppclk is tied to dispclk */ + if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { + dcn1_ramp_up_dispclk_with_dpp(dccg, new_clocks); + dccg->clks.dispclk_khz = new_clocks->dispclk_khz; + + send_request_to_lower = true; } if (!send_request_to_increase && send_request_to_lower) { @@ -627,15 +637,10 @@ static void dcn1_update_clocks(struct dccg *dccg, clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); + if (pp_smu->set_display_requirement) + pp_smu->set_display_requirement(&pp_smu->pp_smu, &smu_req); } - if (new_clocks->phyclk_khz) - smu_req.display_count = 1; - else - smu_req.display_count = 0; - - if (pp_smu->set_display_requirement) - pp_smu->set_display_requirement(&pp_smu->pp_smu, &smu_req); *smu_req_cur = smu_req; } From 5f8d084939d0a94d21c32adf2a4e9249e6ce5654 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 30 May 2018 17:12:16 -0400 Subject: [PATCH 029/133] drm/amd/display: add CHG_DONE mash/sh defines for dentist Signed-off-by: Dmytro Laktyushkin Reviewed-by: Charlene Liu Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h index 1f1899ef773a..7ce0a54e548f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h @@ -45,13 +45,17 @@ #define CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh) \ CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, mask_sh),\ - CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh) + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh),\ + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, mask_sh) #define CLK_REG_FIELD_LIST(type) \ type DPREFCLK_SRC_SEL; \ type DENTIST_DPREFCLK_WDIVIDER; \ type DENTIST_DISPCLK_WDIVIDER; \ - type DENTIST_DPPCLK_WDIVIDER; + type DENTIST_DPPCLK_WDIVIDER; \ + type DENTIST_DISPCLK_CHG_DONE; \ + type DENTIST_DPPCLK_CHG_DONE; struct dccg_shift { CLK_REG_FIELD_LIST(uint8_t) From 294c7e7347d400b2f2d9f09898e8c462f752f500 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 30 May 2018 17:17:27 -0400 Subject: [PATCH 030/133] drm/amd/display: change dentist DID enum values to uppercase Signed-off-by: Dmytro Laktyushkin Reviewed-by: Charlene Liu Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dce/dce_clocks.c | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index 0a4ae0f49f99..6882dc953a2c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -103,39 +103,39 @@ static const struct state_dependent_clocks dce120_max_clks_by_state[] = { /* Starting DID for each range */ enum dentist_base_divider_id { - dentist_base_divider_id_1 = 0x08, - dentist_base_divider_id_2 = 0x40, - dentist_base_divider_id_3 = 0x60, - dentist_max_divider_id = 0x80 + DENTIST_BASE_DID_1 = 0x08, + DENTIST_BASE_DID_2 = 0x40, + DENTIST_BASE_DID_3 = 0x60, + DENTIST_MAX_DID = 0x80 }; /* Starting point and step size for each divider range.*/ enum dentist_divider_range { - dentist_divider_range_1_start = 8, /* 2.00 */ - dentist_divider_range_1_step = 1, /* 0.25 */ - dentist_divider_range_2_start = 64, /* 16.00 */ - dentist_divider_range_2_step = 2, /* 0.50 */ - dentist_divider_range_3_start = 128, /* 32.00 */ - dentist_divider_range_3_step = 4, /* 1.00 */ - dentist_divider_range_scale_factor = 4 + DENTIST_DIVIDER_RANGE_1_START = 8, /* 2.00 */ + DENTIST_DIVIDER_RANGE_1_STEP = 1, /* 0.25 */ + DENTIST_DIVIDER_RANGE_2_START = 64, /* 16.00 */ + DENTIST_DIVIDER_RANGE_2_STEP = 2, /* 0.50 */ + DENTIST_DIVIDER_RANGE_3_START = 128, /* 32.00 */ + DENTIST_DIVIDER_RANGE_3_STEP = 4, /* 1.00 */ + DENTIST_DIVIDER_RANGE_SCALE_FACTOR = 4 }; static int dentist_get_divider_from_did(int did) { - if (did < dentist_base_divider_id_1) - did = dentist_base_divider_id_1; - if (did > dentist_max_divider_id) - did = dentist_max_divider_id; + if (did < DENTIST_BASE_DID_1) + did = DENTIST_BASE_DID_1; + if (did > DENTIST_MAX_DID) + did = DENTIST_MAX_DID; - if (did < dentist_base_divider_id_2) { - return dentist_divider_range_1_start + dentist_divider_range_1_step - * (did - dentist_base_divider_id_1); - } else if (did < dentist_base_divider_id_3) { - return dentist_divider_range_2_start + dentist_divider_range_2_step - * (did - dentist_base_divider_id_2); + if (did < DENTIST_BASE_DID_2) { + return DENTIST_DIVIDER_RANGE_1_START + DENTIST_DIVIDER_RANGE_1_STEP + * (did - DENTIST_BASE_DID_1); + } else if (did < DENTIST_BASE_DID_3) { + return DENTIST_DIVIDER_RANGE_2_START + DENTIST_DIVIDER_RANGE_2_STEP + * (did - DENTIST_BASE_DID_2); } else { - return dentist_divider_range_3_start + dentist_divider_range_3_step - * (did - dentist_base_divider_id_3); + return DENTIST_DIVIDER_RANGE_3_START + DENTIST_DIVIDER_RANGE_3_STEP + * (did - DENTIST_BASE_DID_3); } } @@ -186,7 +186,7 @@ static int dce_get_dp_ref_freq_khz(struct dccg *clk) target_div = dentist_get_divider_from_did(dprefclk_wdivider); /* Calculate the current DFS clock, in kHz.*/ - dp_ref_clk_khz = (dentist_divider_range_scale_factor + dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR * clk_dce->dentist_vco_freq_khz) / target_div; return dccg_adjust_dp_ref_freq_for_ss(clk_dce, dp_ref_clk_khz); From d7b539d34acea44ee555a4fe35e77c23b8dc4bc4 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Thu, 24 May 2018 15:09:40 -0400 Subject: [PATCH 031/133] drm/amd/display: add safe_to_lower support to dcn wm programming This will prevent watermarks from lowering when unsafe to do so. Signed-off-by: Dmytro Laktyushkin Reviewed-by: Charlene Liu Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dcn10/dcn10_hubbub.c | 364 +++++++++++------- .../drm/amd/display/dc/dcn10/dcn10_hubbub.h | 4 +- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- 3 files changed, 223 insertions(+), 147 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c index 943143efbb82..63b75ac4a1d5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c @@ -193,7 +193,8 @@ static uint32_t convert_and_clamp( void hubbub1_program_watermarks( struct hubbub *hubbub, struct dcn_watermark_set *watermarks, - unsigned int refclk_mhz) + unsigned int refclk_mhz, + bool safe_to_lower) { uint32_t force_en = hubbub->ctx->dc->debug.disable_stutter ? 1 : 0; /* @@ -207,183 +208,256 @@ void hubbub1_program_watermarks( /* Repeat for water mark set A, B, C and D. */ /* clock state A */ - prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); + if (safe_to_lower || watermarks->a.urgent_ns > hubbub->watermarks.a.urgent_ns) { + hubbub->watermarks.a.urgent_ns = watermarks->a.urgent_ns; + prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->a.urgent_ns, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->a.urgent_ns, prog_wm_value); + } - prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->a.pte_meta_urgent_ns, prog_wm_value); + if (safe_to_lower || watermarks->a.pte_meta_urgent_ns > hubbub->watermarks.a.pte_meta_urgent_ns) { + hubbub->watermarks.a.pte_meta_urgent_ns = watermarks->a.pte_meta_urgent_ns; + prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->a.pte_meta_urgent_ns, prog_wm_value); + } if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) { - prog_wm_value = convert_and_clamp( - watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); + if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns + > hubbub->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) { + hubbub->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = + watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns; + prog_wm_value = convert_and_clamp( + watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); + } - - prog_wm_value = convert_and_clamp( - watermarks->a.cstate_pstate.cstate_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); + if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns + > hubbub->watermarks.a.cstate_pstate.cstate_exit_ns) { + hubbub->watermarks.a.cstate_pstate.cstate_exit_ns = + watermarks->a.cstate_pstate.cstate_exit_ns; + prog_wm_value = convert_and_clamp( + watermarks->a.cstate_pstate.cstate_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); + } } - prog_wm_value = convert_and_clamp( - watermarks->a.cstate_pstate.pstate_change_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" - "HW register value = 0x%x\n\n", - watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); - + if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns + > hubbub->watermarks.a.cstate_pstate.pstate_change_ns) { + hubbub->watermarks.a.cstate_pstate.pstate_change_ns = + watermarks->a.cstate_pstate.pstate_change_ns; + prog_wm_value = convert_and_clamp( + watermarks->a.cstate_pstate.pstate_change_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" + "HW register value = 0x%x\n\n", + watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); + } /* clock state B */ - prog_wm_value = convert_and_clamp( - watermarks->b.urgent_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->b.urgent_ns, prog_wm_value); + if (safe_to_lower || watermarks->b.urgent_ns > hubbub->watermarks.b.urgent_ns) { + hubbub->watermarks.b.urgent_ns = watermarks->b.urgent_ns; + prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->b.urgent_ns, prog_wm_value); + } - prog_wm_value = convert_and_clamp( - watermarks->b.pte_meta_urgent_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->b.pte_meta_urgent_ns, prog_wm_value); - + if (safe_to_lower || watermarks->b.pte_meta_urgent_ns > hubbub->watermarks.b.pte_meta_urgent_ns) { + hubbub->watermarks.b.pte_meta_urgent_ns = watermarks->b.pte_meta_urgent_ns; + prog_wm_value = convert_and_clamp(watermarks->b.pte_meta_urgent_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->b.pte_meta_urgent_ns, prog_wm_value); + } if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) { - prog_wm_value = convert_and_clamp( - watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_B calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); + if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns + > hubbub->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) { + hubbub->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = + watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns; + prog_wm_value = convert_and_clamp( + watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); + } - - prog_wm_value = convert_and_clamp( - watermarks->b.cstate_pstate.cstate_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); + if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns + > hubbub->watermarks.b.cstate_pstate.cstate_exit_ns) { + hubbub->watermarks.b.cstate_pstate.cstate_exit_ns = + watermarks->b.cstate_pstate.cstate_exit_ns; + prog_wm_value = convert_and_clamp( + watermarks->b.cstate_pstate.cstate_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); + } } - prog_wm_value = convert_and_clamp( - watermarks->b.cstate_pstate.pstate_change_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n" - "HW register value = 0x%x\n", - watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); + if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns + > hubbub->watermarks.b.cstate_pstate.pstate_change_ns) { + hubbub->watermarks.b.cstate_pstate.pstate_change_ns = + watermarks->b.cstate_pstate.pstate_change_ns; + prog_wm_value = convert_and_clamp( + watermarks->b.cstate_pstate.pstate_change_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n" + "HW register value = 0x%x\n\n", + watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); + } /* clock state C */ - prog_wm_value = convert_and_clamp( - watermarks->c.urgent_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->c.urgent_ns, prog_wm_value); + if (safe_to_lower || watermarks->c.urgent_ns > hubbub->watermarks.c.urgent_ns) { + hubbub->watermarks.c.urgent_ns = watermarks->c.urgent_ns; + prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->c.urgent_ns, prog_wm_value); + } - prog_wm_value = convert_and_clamp( - watermarks->c.pte_meta_urgent_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->c.pte_meta_urgent_ns, prog_wm_value); - + if (safe_to_lower || watermarks->c.pte_meta_urgent_ns > hubbub->watermarks.c.pte_meta_urgent_ns) { + hubbub->watermarks.c.pte_meta_urgent_ns = watermarks->c.pte_meta_urgent_ns; + prog_wm_value = convert_and_clamp(watermarks->c.pte_meta_urgent_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->c.pte_meta_urgent_ns, prog_wm_value); + } if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) { - prog_wm_value = convert_and_clamp( - watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_C calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); + if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns + > hubbub->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) { + hubbub->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = + watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns; + prog_wm_value = convert_and_clamp( + watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); + } - - prog_wm_value = convert_and_clamp( - watermarks->c.cstate_pstate.cstate_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); + if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns + > hubbub->watermarks.c.cstate_pstate.cstate_exit_ns) { + hubbub->watermarks.c.cstate_pstate.cstate_exit_ns = + watermarks->c.cstate_pstate.cstate_exit_ns; + prog_wm_value = convert_and_clamp( + watermarks->c.cstate_pstate.cstate_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); + } } - prog_wm_value = convert_and_clamp( - watermarks->c.cstate_pstate.pstate_change_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n" - "HW register value = 0x%x\n", - watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); + if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns + > hubbub->watermarks.c.cstate_pstate.pstate_change_ns) { + hubbub->watermarks.c.cstate_pstate.pstate_change_ns = + watermarks->c.cstate_pstate.pstate_change_ns; + prog_wm_value = convert_and_clamp( + watermarks->c.cstate_pstate.pstate_change_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n" + "HW register value = 0x%x\n\n", + watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); + } /* clock state D */ - prog_wm_value = convert_and_clamp( - watermarks->d.urgent_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->d.urgent_ns, prog_wm_value); - - prog_wm_value = convert_and_clamp( - watermarks->d.pte_meta_urgent_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->d.pte_meta_urgent_ns, prog_wm_value); - - - if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) { - prog_wm_value = convert_and_clamp( - watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, + if (safe_to_lower || watermarks->d.urgent_ns > hubbub->watermarks.d.urgent_ns) { + hubbub->watermarks.d.urgent_ns = watermarks->d.urgent_ns; + prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_D calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); + REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); - - prog_wm_value = convert_and_clamp( - watermarks->d.cstate_pstate.cstate_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" + DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n", - watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); + watermarks->d.urgent_ns, prog_wm_value); } + if (safe_to_lower || watermarks->d.pte_meta_urgent_ns > hubbub->watermarks.d.pte_meta_urgent_ns) { + hubbub->watermarks.d.pte_meta_urgent_ns = watermarks->d.pte_meta_urgent_ns; + prog_wm_value = convert_and_clamp(watermarks->d.pte_meta_urgent_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->d.pte_meta_urgent_ns, prog_wm_value); + } - prog_wm_value = convert_and_clamp( - watermarks->d.cstate_pstate.pstate_change_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); - DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" - "HW register value = 0x%x\n\n", - watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); + if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) { + if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns + > hubbub->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) { + hubbub->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = + watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns; + prog_wm_value = convert_and_clamp( + watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); + } + + if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns + > hubbub->watermarks.d.cstate_pstate.cstate_exit_ns) { + hubbub->watermarks.d.cstate_pstate.cstate_exit_ns = + watermarks->d.cstate_pstate.cstate_exit_ns; + prog_wm_value = convert_and_clamp( + watermarks->d.cstate_pstate.cstate_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); + } + } + + if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns + > hubbub->watermarks.d.cstate_pstate.pstate_change_ns) { + hubbub->watermarks.d.cstate_pstate.pstate_change_ns = + watermarks->d.cstate_pstate.pstate_change_ns; + prog_wm_value = convert_and_clamp( + watermarks->d.cstate_pstate.pstate_change_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); + DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" + "HW register value = 0x%x\n\n", + watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); + } REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h index 6315a0e6b0d6..0ca39cb71968 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h @@ -185,6 +185,7 @@ struct hubbub { const struct dcn_hubbub_shift *shifts; const struct dcn_hubbub_mask *masks; unsigned int debug_test_index_pstate; + struct dcn_watermark_set watermarks; }; void hubbub1_update_dchub( @@ -197,7 +198,8 @@ bool hubbub1_verify_allow_pstate_change_high( void hubbub1_program_watermarks( struct hubbub *hubbub, struct dcn_watermark_set *watermarks, - unsigned int refclk_mhz); + unsigned int refclk_mhz, + bool safe_to_lower); void hubbub1_toggle_watermark_change_req( struct hubbub *hubbub); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 5b40c1c4d9e6..7d9c10b6d99b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2299,7 +2299,7 @@ static void dcn10_apply_ctx_for_surface( /* watermark is for all pipes */ hubbub1_program_watermarks(dc->res_pool->hubbub, - &context->bw.dcn.watermarks, ref_clk_mhz); + &context->bw.dcn.watermarks, ref_clk_mhz, true); if (dc->debug.sanity_checks) { /* pstate stuck check after watermark update */ From 836758ffe78a7bc45af9484e34cba2b685f2a0b2 Mon Sep 17 00:00:00 2001 From: "Zheng, XueLai(Eric)" Date: Tue, 8 May 2018 12:25:15 -0400 Subject: [PATCH 032/133] drm/amd/display: support ACrYCb2101010 Signed-off-by: XueLai(Eric), Zheng Reviewed-by: Charlene Liu Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 1 + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h index d31023d57b58..14afbc5c0a62 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -199,6 +199,7 @@ enum surface_pixel_format { SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb, SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr, SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb, + SURFACE_PIXEL_FORMAT_SUBSAMPLE_END, SURFACE_PIXEL_FORMAT_INVALID /*grow 444 video here if necessary */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c index c28085be39ff..93f52c58bc69 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c @@ -166,7 +166,7 @@ void hubp1_program_size_and_rotation( /* Program data and meta surface pitch (calculation from addrlib) * 444 or 420 luma */ - if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { + if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN && format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END) { ASSERT(plane_size->video.chroma_pitch != 0); /* Chroma pitch zero can cause system hang! */ From f3e077d95ca0a016fdf3d6b1e97a9910dfdaff17 Mon Sep 17 00:00:00 2001 From: Wesley Chalmers Date: Tue, 29 May 2018 17:45:05 -0400 Subject: [PATCH 033/133] drm/amd/display: fix use of uninitialized memory DML does not calculate chroma values for RQ when surface is not YUV, but DC will unconditionally use the uninitialized values for HW programming. This does not cause visual corruption since HW will ignore garbage chroma values when surface is not YUV, but causes presubmission tests to fail golden value comparison. Signed-off-by: Wesley Chalmers Signed-off-by: Eryk Brol Reviewed-by: Wenjing Liu Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c index c2037daa8e66..0efbf411667a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c @@ -239,6 +239,8 @@ void dml1_extract_rq_regs( extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l); if (rq_param.yuv420) extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c); + else + memset(&(rq_regs->rq_regs_c), 0, sizeof(rq_regs->rq_regs_c)); rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height); rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height); From 0176e8c4c0f35555f7554ec3097283187b33ccbd Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Tue, 8 May 2018 12:25:29 -0400 Subject: [PATCH 034/133] drm/amd/display: dal 3.1.49 Signed-off-by: Tony Cheng Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 82e0f55bc3e4..d1ac9676a539 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,7 +38,7 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.48" +#define DC_VER "3.1.49" #define MAX_SURFACES 3 #define MAX_STREAMS 6 From dc38fd9dac3e15538c7c238c4dfb98ceb408fa19 Mon Sep 17 00:00:00 2001 From: David Francis Date: Fri, 1 Jun 2018 09:49:06 -0400 Subject: [PATCH 035/133] drm/amd/display: Add front end for dp debugfs files As part of hardware certification, read-write access to the link rate, lane count, voltage swing, pre-emphasis, and PHY test pattern of DP connectors is required. This commit adds debugfs files that will correspond to these values. The file operations are not yet implemented: currently writing or reading them does nothing. Signed-off-by: David Francis Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/Makefile | 2 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++ .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 170 ++++++++++++++++++ .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.h | 34 ++++ 4 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.h diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile index af16973f2c41..589c60ec59bd 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile @@ -32,7 +32,7 @@ AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o endif ifneq ($(CONFIG_DEBUG_FS),) -AMDGPUDM += amdgpu_dm_crc.o +AMDGPUDM += amdgpu_dm_crc.o amdgpu_dm_debugfs.o endif subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc 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 66bd3cc3e387..356ac27d0180 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -39,6 +39,9 @@ #include "dm_helpers.h" #include "dm_services_types.h" #include "amdgpu_dm_mst_types.h" +#if defined(CONFIG_DEBUG_FS) +#include "amdgpu_dm_debugfs.h" +#endif #include "ivsrcid/ivsrcid_vislands30.h" @@ -3619,6 +3622,13 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, &aconnector->base, &aencoder->base); drm_connector_register(&aconnector->base); +#if defined(CONFIG_DEBUG_FS) + res = connector_debugfs_init(aconnector); + if (res) { + DRM_ERROR("Failed to create debugfs for connector"); + goto out_free; + } +#endif if (connector_type == DRM_MODE_CONNECTOR_DisplayPort || connector_type == DRM_MODE_CONNECTOR_eDP) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c new file mode 100644 index 000000000000..cf5ea69e46ad --- /dev/null +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -0,0 +1,170 @@ +/* + * Copyright 2018 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include + +#include "dc.h" +#include "dc_link.h" + +#include "amdgpu.h" +#include "amdgpu_dm.h" +#include "amdgpu_dm_debugfs.h" + +static ssize_t dp_link_rate_debugfs_read(struct file *f, char __user *buf, + size_t size, loff_t *pos) +{ + /* TODO: create method to read link rate */ + return 1; +} + +static ssize_t dp_link_rate_debugfs_write(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + /* TODO: create method to write link rate */ + return 1; +} + +static ssize_t dp_lane_count_debugfs_read(struct file *f, char __user *buf, + size_t size, loff_t *pos) +{ + /* TODO: create method to read lane count */ + return 1; +} + +static ssize_t dp_lane_count_debugfs_write(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + /* TODO: create method to write lane count */ + return 1; +} + +static ssize_t dp_voltage_swing_debugfs_read(struct file *f, char __user *buf, + size_t size, loff_t *pos) +{ + /* TODO: create method to read voltage swing */ + return 1; +} + +static ssize_t dp_voltage_swing_debugfs_write(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + /* TODO: create method to write voltage swing */ + return 1; +} + +static ssize_t dp_pre_emphasis_debugfs_read(struct file *f, char __user *buf, + size_t size, loff_t *pos) +{ + /* TODO: create method to read pre-emphasis */ + return 1; +} + +static ssize_t dp_pre_emphasis_debugfs_write(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + /* TODO: create method to write pre-emphasis */ + return 1; +} + +static ssize_t dp_phy_test_pattern_debugfs_read(struct file *f, char __user *buf, + size_t size, loff_t *pos) +{ + /* TODO: create method to read PHY test pattern */ + return 1; +} + +static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + /* TODO: create method to write PHY test pattern */ + return 1; +} + +static const struct file_operations dp_link_rate_fops = { + .owner = THIS_MODULE, + .read = dp_link_rate_debugfs_read, + .write = dp_link_rate_debugfs_write, + .llseek = default_llseek +}; + +static const struct file_operations dp_lane_count_fops = { + .owner = THIS_MODULE, + .read = dp_lane_count_debugfs_read, + .write = dp_lane_count_debugfs_write, + .llseek = default_llseek +}; + +static const struct file_operations dp_voltage_swing_fops = { + .owner = THIS_MODULE, + .read = dp_voltage_swing_debugfs_read, + .write = dp_voltage_swing_debugfs_write, + .llseek = default_llseek +}; + +static const struct file_operations dp_pre_emphasis_fops = { + .owner = THIS_MODULE, + .read = dp_pre_emphasis_debugfs_read, + .write = dp_pre_emphasis_debugfs_write, + .llseek = default_llseek +}; + +static const struct file_operations dp_phy_test_pattern_fops = { + .owner = THIS_MODULE, + .read = dp_phy_test_pattern_debugfs_read, + .write = dp_phy_test_pattern_debugfs_write, + .llseek = default_llseek +}; + +static const struct { + char *name; + const struct file_operations *fops; +} dp_debugfs_entries[] = { + {"link_rate", &dp_link_rate_fops}, + {"lane_count", &dp_lane_count_fops}, + {"voltage_swing", &dp_voltage_swing_fops}, + {"pre_emphasis", &dp_pre_emphasis_fops}, + {"phy_test_pattern", &dp_phy_test_pattern_fops} +}; + +int connector_debugfs_init(struct amdgpu_dm_connector *connector) +{ + int i; + struct dentry *ent, *dir = connector->base.debugfs_entry; + + if (connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) { + for (i = 0; i < ARRAY_SIZE(dp_debugfs_entries); i++) { + ent = debugfs_create_file(dp_debugfs_entries[i].name, + 0644, + dir, + connector, + dp_debugfs_entries[i].fops); + if (IS_ERR(ent)) + return PTR_ERR(ent); + } + } + + return 0; +} + diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.h new file mode 100644 index 000000000000..d9ed1b2aa811 --- /dev/null +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.h @@ -0,0 +1,34 @@ +/* + * Copyright 2018 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __AMDGPU_DM_DEBUGFS_H__ +#define __AMDGPU_DM_DEBUGFS_H__ + +#include "amdgpu.h" +#include "amdgpu_dm.h" + +int connector_debugfs_init(struct amdgpu_dm_connector *connector); + +#endif From 9f6e2842d0681a9a6579618a301c8ae06e20a6cd Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Tue, 5 Jun 2018 09:13:56 -0400 Subject: [PATCH 036/133] drm/amd/display: dal 3.1.50 Signed-off-by: Tony Cheng Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index d1ac9676a539..cdab7b0453c5 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,7 +38,7 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.49" +#define DC_VER "3.1.50" #define MAX_SURFACES 3 #define MAX_STREAMS 6 From b9c1c67aeb8805015f02efb0a6a6ddf68ea8a4b4 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Tue, 5 Jun 2018 12:54:38 -0400 Subject: [PATCH 037/133] drm/amd/display: clean rq/dlg/ttu reg structs before calculations Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 4 ++++ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 8 ++++++-- .../gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c | 2 -- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index b8195e5a0676..ac4451adeec9 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -423,6 +423,10 @@ static void dcn_bw_calc_rq_dlg_ttu( int total_flip_bytes = 0; int i; + memset(dlg_regs, 0, sizeof(*dlg_regs)); + memset(ttu_regs, 0, sizeof(*ttu_regs)); + memset(rq_regs, 0, sizeof(*rq_regs)); + for (i = 0; i < number_of_planes; i++) { total_active_bw += v->read_bandwidth[i]; total_prefetch_bw += v->prefetch_bandwidth[i]; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 7d9c10b6d99b..cc12c4757f8b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -151,19 +151,23 @@ static void dcn10_log_hubp_states(struct dc *dc) DTN_INFO("\n=========RQ========\n"); DTN_INFO("HUBP: drq_exp_m prq_exp_m mrq_exp_m crq_exp_m plane1_ba L:chunk_s min_chu_s meta_ch_s" + " min_m_c_s dpte_gr_s mpte_gr_s swath_hei pte_row_h C:chunk_s min_chu_s meta_ch_s" " min_m_c_s dpte_gr_s mpte_gr_s swath_hei pte_row_h\n"); for (i = 0; i < pool->pipe_count; i++) { struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state); struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs; if (!s->blank_en) - DTN_INFO("[%2d]: %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh\n", + DTN_INFO("[%2d]: %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh\n", pool->hubps[i]->inst, rq_regs->drq_expansion_mode, rq_regs->prq_expansion_mode, rq_regs->mrq_expansion_mode, rq_regs->crq_expansion_mode, rq_regs->plane1_base_address, rq_regs->rq_regs_l.chunk_size, rq_regs->rq_regs_l.min_chunk_size, rq_regs->rq_regs_l.meta_chunk_size, rq_regs->rq_regs_l.min_meta_chunk_size, rq_regs->rq_regs_l.dpte_group_size, rq_regs->rq_regs_l.mpte_group_size, rq_regs->rq_regs_l.swath_height, - rq_regs->rq_regs_l.pte_row_height_linear); + rq_regs->rq_regs_l.pte_row_height_linear, rq_regs->rq_regs_c.chunk_size, rq_regs->rq_regs_c.min_chunk_size, + rq_regs->rq_regs_c.meta_chunk_size, rq_regs->rq_regs_c.min_meta_chunk_size, + rq_regs->rq_regs_c.dpte_group_size, rq_regs->rq_regs_c.mpte_group_size, + rq_regs->rq_regs_c.swath_height, rq_regs->rq_regs_c.pte_row_height_linear); } DTN_INFO("========DLG========\n"); diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c index 0efbf411667a..c2037daa8e66 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c @@ -239,8 +239,6 @@ void dml1_extract_rq_regs( extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l); if (rq_param.yuv420) extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c); - else - memset(&(rq_regs->rq_regs_c), 0, sizeof(rq_regs->rq_regs_c)); rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height); rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height); From d4fa93e03839c3e4e9d16020f1a3c78ae36c646a Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Tue, 5 Jun 2018 09:14:22 -0400 Subject: [PATCH 038/133] drm/amd/display: dal 3.1.51 Signed-off-by: Tony Cheng Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index cdab7b0453c5..cbcdbd9b9910 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,7 +38,7 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.50" +#define DC_VER "3.1.51" #define MAX_SURFACES 3 #define MAX_STREAMS 6 From 6f66ccf0aa8f6d430d161a1ac2bc43e665d2fc59 Mon Sep 17 00:00:00 2001 From: Roman Li Date: Tue, 5 Jun 2018 14:24:53 -0400 Subject: [PATCH 039/133] drm/amd/display: fix potential infinite loop in fbc path - Fixing integer overflow bug in wait_for_fbc_state_changed() - Correct the max value of retries for the corresponding warning Signed-off-by: Roman Li Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c index df027013e50c..1f7f25013217 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c @@ -143,7 +143,7 @@ static void wait_for_fbc_state_changed( struct dce110_compressor *cp110, bool enabled) { - uint16_t counter = 0; + uint32_t counter = 0; uint32_t addr = mmFBC_STATUS; uint32_t value; @@ -158,7 +158,7 @@ static void wait_for_fbc_state_changed( counter++; } - if (counter == 10) { + if (counter == 1000) { DC_LOG_WARNING("%s: wait counter exceeded, changes to HW not applied", __func__); } else { From 5094ffac6bd265130f735dd500532cef39f0d72f Mon Sep 17 00:00:00 2001 From: Mikita Lipski Date: Thu, 31 May 2018 14:49:00 -0400 Subject: [PATCH 040/133] drm/amd/display: Enable PPLib calls from DC on linux Set the powerplay debug flag to false for both Windows and Linux to allow the calls to pplib. So we can retrieve the clock values from powerplay instead of using default hardcoded values. Signed-off-by: Mikita Lipski Reviewed-by: Charlene Liu Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index b5a727f7e880..1761e1a40dad 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -437,7 +437,7 @@ static const struct dc_debug debug_defaults_drv = { */ .min_disp_clk_khz = 100000, - .disable_pplib_clock_request = true, + .disable_pplib_clock_request = false, .disable_pplib_wm_range = false, .pplib_wm_report_mode = WM_REPORT_DEFAULT, .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, From 015ec75918698e63f770c9bee0752ce802ed55e2 Mon Sep 17 00:00:00 2001 From: Mikita Lipski Date: Thu, 31 May 2018 17:31:14 -0400 Subject: [PATCH 041/133] drm/amd/display: Add dmpp clks types for conversion Add more cases for dm_pp clks translator into pp clks so we can pass the right structures to the powerplay. Use clks translator instead of massive switch statement. Signed-off-by: Mikita Lipski Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../display/amdgpu_dm/amdgpu_dm_services.c | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c index 0ac428299f5f..a87a5946798c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c @@ -195,6 +195,21 @@ static enum amd_pp_clock_type dc_to_pp_clock_type( case DM_PP_CLOCK_TYPE_MEMORY_CLK: amd_pp_clk_type = amd_pp_mem_clock; break; + case DM_PP_CLOCK_TYPE_DCEFCLK: + amd_pp_clk_type = amd_pp_dcef_clock; + break; + case DM_PP_CLOCK_TYPE_DCFCLK: + amd_pp_clk_type = amd_pp_dcf_clock; + break; + case DM_PP_CLOCK_TYPE_PIXELCLK: + amd_pp_clk_type = amd_pp_pixel_clock; + break; + case DM_PP_CLOCK_TYPE_FCLK: + amd_pp_clk_type = amd_pp_f_clock; + break; + case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: + amd_pp_clk_type = amd_pp_dpp_clock; + break; default: DRM_ERROR("DM_PPLIB: invalid clock type: %d!\n", dm_pp_clk_type); @@ -424,33 +439,13 @@ bool dm_pp_apply_clock_for_voltage_request( struct amdgpu_device *adev = ctx->driver_context; struct pp_display_clock_request pp_clock_request = {0}; int ret = 0; - switch (clock_for_voltage_req->clk_type) { - case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - pp_clock_request.clock_type = amd_pp_disp_clock; - break; - - case DM_PP_CLOCK_TYPE_DCEFCLK: - pp_clock_request.clock_type = amd_pp_dcef_clock; - break; - - case DM_PP_CLOCK_TYPE_DCFCLK: - pp_clock_request.clock_type = amd_pp_dcf_clock; - break; - - case DM_PP_CLOCK_TYPE_PIXELCLK: - pp_clock_request.clock_type = amd_pp_pixel_clock; - break; - - case DM_PP_CLOCK_TYPE_FCLK: - pp_clock_request.clock_type = amd_pp_f_clock; - break; - - default: - return false; - } + pp_clock_request.clock_type = dc_to_pp_clock_type(clock_for_voltage_req->clk_type); pp_clock_request.clock_freq_in_khz = clock_for_voltage_req->clocks_in_khz; + if (!pp_clock_request.clock_type) + return false; + if (adev->powerplay.pp_funcs->display_clock_voltage_request) ret = adev->powerplay.pp_funcs->display_clock_voltage_request( adev->powerplay.pp_handle, From 724a75524b1c77ea8abb96c21cdba05385b22b39 Mon Sep 17 00:00:00 2001 From: Mikita Lipski Date: Thu, 31 May 2018 14:44:18 -0400 Subject: [PATCH 042/133] drm/amd/display: Convert 10kHz clks from PPLib into kHz The driver is expecting clock frequency in kHz, while SMU returns the values in 10kHz, which causes the bandwidth validation to fail Signed-off-by: Mikita Lipski Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../amd/display/amdgpu_dm/amdgpu_dm_services.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c index a87a5946798c..a19df20b557b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c @@ -267,8 +267,9 @@ static void pp_to_dc_clock_levels_with_latency( DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); for (i = 0; i < clk_level_info->num_levels; i++) { - DRM_DEBUG("DM_PPLIB:\t %d\n", pp_clks->data[i].clocks_in_khz); - clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz; + DRM_DEBUG("DM_PPLIB:\t %d in 10kHz\n", pp_clks->data[i].clocks_in_khz); + /* translate 10kHz to kHz */ + clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz * 10; clk_level_info->data[i].latency_in_us = pp_clks->data[i].latency_in_us; } } @@ -294,8 +295,9 @@ static void pp_to_dc_clock_levels_with_voltage( DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); for (i = 0; i < clk_level_info->num_levels; i++) { - DRM_INFO("DM_PPLIB:\t %d\n", pp_clks->data[i].clocks_in_khz); - clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz; + DRM_INFO("DM_PPLIB:\t %d in 10kHz\n", pp_clks->data[i].clocks_in_khz); + /* translate 10kHz to kHz */ + clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz * 10; clk_level_info->data[i].voltage_in_mv = pp_clks->data[i].voltage_in_mv; } } @@ -471,8 +473,9 @@ bool dm_pp_get_static_clocks( return false; static_clk_info->max_clocks_state = pp_clk_info.max_clocks_state; - static_clk_info->max_mclk_khz = pp_clk_info.max_memory_clock; - static_clk_info->max_sclk_khz = pp_clk_info.max_engine_clock; + /* translate 10kHz to kHz */ + static_clk_info->max_mclk_khz = pp_clk_info.max_memory_clock * 10; + static_clk_info->max_sclk_khz = pp_clk_info.max_engine_clock * 10; return true; } From 746c58ed225b9439a8272f755a1c60f795de9a3c Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Tue, 5 Jun 2018 07:40:04 -0400 Subject: [PATCH 043/133] drm/amd/display: move dml defaults to respective dcn resource files Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dcn10/dcn10_resource.c | 62 ++++++++++++++++++ .../drm/amd/display/dc/dml/display_mode_lib.c | 63 +------------------ 2 files changed, 64 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 1761e1a40dad..2db08b99db56 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -65,6 +65,68 @@ #include "dce/dce_abm.h" #include "dce/dce_dmcu.h" +const struct _vcs_dpi_ip_params_st dcn1_0_ip = { + .rob_buffer_size_kbytes = 64, + .det_buffer_size_kbytes = 164, + .dpte_buffer_size_in_pte_reqs = 42, + .dpp_output_buffer_pixels = 2560, + .opp_output_buffer_lines = 1, + .pixel_chunk_size_kbytes = 8, + .pte_enable = 1, + .pte_chunk_size_kbytes = 2, + .meta_chunk_size_kbytes = 2, + .writeback_chunk_size_kbytes = 2, + .line_buffer_size_bits = 589824, + .max_line_buffer_lines = 12, + .IsLineBufferBppFixed = 0, + .LineBufferFixedBpp = -1, + .writeback_luma_buffer_size_kbytes = 12, + .writeback_chroma_buffer_size_kbytes = 8, + .max_num_dpp = 4, + .max_num_wb = 2, + .max_dchub_pscl_bw_pix_per_clk = 4, + .max_pscl_lb_bw_pix_per_clk = 2, + .max_lb_vscl_bw_pix_per_clk = 4, + .max_vscl_hscl_bw_pix_per_clk = 4, + .max_hscl_ratio = 4, + .max_vscl_ratio = 4, + .hscl_mults = 4, + .vscl_mults = 4, + .max_hscl_taps = 8, + .max_vscl_taps = 8, + .dispclk_ramp_margin_percent = 1, + .underscan_factor = 1.10, + .min_vblank_lines = 14, + .dppclk_delay_subtotal = 90, + .dispclk_delay_subtotal = 42, + .dcfclk_cstate_latency = 10, + .max_inter_dcn_tile_repeaters = 8, + .can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = 0, + .bug_forcing_LC_req_same_size_fixed = 0, +}; + +const struct _vcs_dpi_soc_bounding_box_st dcn1_0_soc = { + .sr_exit_time_us = 9.0, + .sr_enter_plus_exit_time_us = 11.0, + .urgent_latency_us = 4.0, + .writeback_latency_us = 12.0, + .ideal_dram_bw_after_urgent_percent = 80.0, + .max_request_size_bytes = 256, + .downspread_percent = 0.5, + .dram_page_open_time_ns = 50.0, + .dram_rw_turnaround_time_ns = 17.5, + .dram_return_buffer_per_channel_bytes = 8192, + .round_trip_ping_latency_dcfclk_cycles = 128, + .urgent_out_of_order_return_per_channel_bytes = 256, + .channel_interleave_bytes = 256, + .num_banks = 8, + .num_chans = 2, + .vmm_page_size_bytes = 4096, + .dram_clock_change_latency_us = 17.0, + .writeback_dram_clock_change_latency_us = 23.0, + .return_bus_width_bytes = 64, +}; + #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f #define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c index fd9d97aab071..dddeb0d4db8f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c @@ -26,67 +26,8 @@ #include "display_mode_lib.h" #include "dc_features.h" -static const struct _vcs_dpi_ip_params_st dcn1_0_ip = { - .rob_buffer_size_kbytes = 64, - .det_buffer_size_kbytes = 164, - .dpte_buffer_size_in_pte_reqs = 42, - .dpp_output_buffer_pixels = 2560, - .opp_output_buffer_lines = 1, - .pixel_chunk_size_kbytes = 8, - .pte_enable = 1, - .pte_chunk_size_kbytes = 2, - .meta_chunk_size_kbytes = 2, - .writeback_chunk_size_kbytes = 2, - .line_buffer_size_bits = 589824, - .max_line_buffer_lines = 12, - .IsLineBufferBppFixed = 0, - .LineBufferFixedBpp = -1, - .writeback_luma_buffer_size_kbytes = 12, - .writeback_chroma_buffer_size_kbytes = 8, - .max_num_dpp = 4, - .max_num_wb = 2, - .max_dchub_pscl_bw_pix_per_clk = 4, - .max_pscl_lb_bw_pix_per_clk = 2, - .max_lb_vscl_bw_pix_per_clk = 4, - .max_vscl_hscl_bw_pix_per_clk = 4, - .max_hscl_ratio = 4, - .max_vscl_ratio = 4, - .hscl_mults = 4, - .vscl_mults = 4, - .max_hscl_taps = 8, - .max_vscl_taps = 8, - .dispclk_ramp_margin_percent = 1, - .underscan_factor = 1.10, - .min_vblank_lines = 14, - .dppclk_delay_subtotal = 90, - .dispclk_delay_subtotal = 42, - .dcfclk_cstate_latency = 10, - .max_inter_dcn_tile_repeaters = 8, - .can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = 0, - .bug_forcing_LC_req_same_size_fixed = 0, -}; - -static const struct _vcs_dpi_soc_bounding_box_st dcn1_0_soc = { - .sr_exit_time_us = 9.0, - .sr_enter_plus_exit_time_us = 11.0, - .urgent_latency_us = 4.0, - .writeback_latency_us = 12.0, - .ideal_dram_bw_after_urgent_percent = 80.0, - .max_request_size_bytes = 256, - .downspread_percent = 0.5, - .dram_page_open_time_ns = 50.0, - .dram_rw_turnaround_time_ns = 17.5, - .dram_return_buffer_per_channel_bytes = 8192, - .round_trip_ping_latency_dcfclk_cycles = 128, - .urgent_out_of_order_return_per_channel_bytes = 256, - .channel_interleave_bytes = 256, - .num_banks = 8, - .num_chans = 2, - .vmm_page_size_bytes = 4096, - .dram_clock_change_latency_us = 17.0, - .writeback_dram_clock_change_latency_us = 23.0, - .return_bus_width_bytes = 64, -}; +extern const struct _vcs_dpi_ip_params_st dcn1_0_ip; +extern const struct _vcs_dpi_soc_bounding_box_st dcn1_0_soc; static void set_soc_bounding_box(struct _vcs_dpi_soc_bounding_box_st *soc, enum dml_project project) { From f7c1ed341ae0807e55fc583fbd5582ff4ef35a98 Mon Sep 17 00:00:00 2001 From: Mikita Lipski Date: Fri, 1 Jun 2018 15:02:55 -0400 Subject: [PATCH 044/133] drm/amd/display: Moving powerplay functions to a separate class Moving powerplay functions to a new amdgpu_dm_pp_smu class and cleaning dm_services class from unused headers. Signed-off-by: Mikita Lipski Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/Makefile | 2 +- .../amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 525 ++++++++++++++++++ .../display/amdgpu_dm/amdgpu_dm_services.c | 492 ---------------- 3 files changed, 526 insertions(+), 493 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile index 589c60ec59bd..94911871eb9b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile @@ -28,7 +28,7 @@ AMDGPUDM = amdgpu_dm.o amdgpu_dm_irq.o amdgpu_dm_mst_types.o amdgpu_dm_color.o ifneq ($(CONFIG_DRM_AMD_DC),) -AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o +AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o amdgpu_dm_pp_smu.o endif ifneq ($(CONFIG_DEBUG_FS),) 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 new file mode 100644 index 000000000000..ad96e2a2b3cf --- /dev/null +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c @@ -0,0 +1,525 @@ +/* + * Copyright 2018 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + */ +#include +#include + +#include +#include +#include +#include "dm_services.h" +#include "amdgpu.h" +#include "amdgpu_dm.h" +#include "amdgpu_dm_irq.h" +#include "amdgpu_pm.h" +#include "dm_pp_smu.h" +#include "../../powerplay/inc/hwmgr.h" +#include "../../powerplay/hwmgr/smu10_hwmgr.h" + + +bool dm_pp_apply_display_requirements( + const struct dc_context *ctx, + const struct dm_pp_display_configuration *pp_display_cfg) +{ + struct amdgpu_device *adev = ctx->driver_context; + + if (adev->pm.dpm_enabled) { + + memset(&adev->pm.pm_display_cfg, 0, + sizeof(adev->pm.pm_display_cfg)); + + adev->pm.pm_display_cfg.cpu_cc6_disable = + pp_display_cfg->cpu_cc6_disable; + + adev->pm.pm_display_cfg.cpu_pstate_disable = + pp_display_cfg->cpu_pstate_disable; + + adev->pm.pm_display_cfg.cpu_pstate_separation_time = + pp_display_cfg->cpu_pstate_separation_time; + + adev->pm.pm_display_cfg.nb_pstate_switch_disable = + pp_display_cfg->nb_pstate_switch_disable; + + adev->pm.pm_display_cfg.num_display = + pp_display_cfg->display_count; + adev->pm.pm_display_cfg.num_path_including_non_display = + pp_display_cfg->display_count; + + adev->pm.pm_display_cfg.min_core_set_clock = + pp_display_cfg->min_engine_clock_khz/10; + adev->pm.pm_display_cfg.min_core_set_clock_in_sr = + pp_display_cfg->min_engine_clock_deep_sleep_khz/10; + adev->pm.pm_display_cfg.min_mem_set_clock = + pp_display_cfg->min_memory_clock_khz/10; + + adev->pm.pm_display_cfg.multi_monitor_in_sync = + pp_display_cfg->all_displays_in_sync; + adev->pm.pm_display_cfg.min_vblank_time = + pp_display_cfg->avail_mclk_switch_time_us; + + adev->pm.pm_display_cfg.display_clk = + pp_display_cfg->disp_clk_khz/10; + + adev->pm.pm_display_cfg.dce_tolerable_mclk_in_active_latency = + pp_display_cfg->avail_mclk_switch_time_in_disp_active_us; + + adev->pm.pm_display_cfg.crtc_index = pp_display_cfg->crtc_index; + adev->pm.pm_display_cfg.line_time_in_us = + pp_display_cfg->line_time_in_us; + + adev->pm.pm_display_cfg.vrefresh = pp_display_cfg->disp_configs[0].v_refresh; + adev->pm.pm_display_cfg.crossfire_display_index = -1; + adev->pm.pm_display_cfg.min_bus_bandwidth = 0; + + /* TODO: complete implementation of + * pp_display_configuration_change(). + * Follow example of: + * PHM_StoreDALConfigurationData - powerplay\hwmgr\hardwaremanager.c + * PP_IRI_DisplayConfigurationChange - powerplay\eventmgr\iri.c */ + if (adev->powerplay.pp_funcs->display_configuration_change) + adev->powerplay.pp_funcs->display_configuration_change( + adev->powerplay.pp_handle, + &adev->pm.pm_display_cfg); + + /* TODO: replace by a separate call to 'apply display cfg'? */ + amdgpu_pm_compute_clocks(adev); + } + + return true; +} + +static void get_default_clock_levels( + enum dm_pp_clock_type clk_type, + struct dm_pp_clock_levels *clks) +{ + uint32_t disp_clks_in_khz[6] = { + 300000, 400000, 496560, 626090, 685720, 757900 }; + uint32_t sclks_in_khz[6] = { + 300000, 360000, 423530, 514290, 626090, 720000 }; + uint32_t mclks_in_khz[2] = { 333000, 800000 }; + + switch (clk_type) { + case DM_PP_CLOCK_TYPE_DISPLAY_CLK: + clks->num_levels = 6; + memmove(clks->clocks_in_khz, disp_clks_in_khz, + sizeof(disp_clks_in_khz)); + break; + case DM_PP_CLOCK_TYPE_ENGINE_CLK: + clks->num_levels = 6; + memmove(clks->clocks_in_khz, sclks_in_khz, + sizeof(sclks_in_khz)); + break; + case DM_PP_CLOCK_TYPE_MEMORY_CLK: + clks->num_levels = 2; + memmove(clks->clocks_in_khz, mclks_in_khz, + sizeof(mclks_in_khz)); + break; + default: + clks->num_levels = 0; + break; + } +} + +static enum amd_pp_clock_type dc_to_pp_clock_type( + enum dm_pp_clock_type dm_pp_clk_type) +{ + enum amd_pp_clock_type amd_pp_clk_type = 0; + + switch (dm_pp_clk_type) { + case DM_PP_CLOCK_TYPE_DISPLAY_CLK: + amd_pp_clk_type = amd_pp_disp_clock; + break; + case DM_PP_CLOCK_TYPE_ENGINE_CLK: + amd_pp_clk_type = amd_pp_sys_clock; + break; + case DM_PP_CLOCK_TYPE_MEMORY_CLK: + amd_pp_clk_type = amd_pp_mem_clock; + break; + case DM_PP_CLOCK_TYPE_DCEFCLK: + amd_pp_clk_type = amd_pp_dcef_clock; + break; + case DM_PP_CLOCK_TYPE_DCFCLK: + amd_pp_clk_type = amd_pp_dcf_clock; + break; + case DM_PP_CLOCK_TYPE_PIXELCLK: + amd_pp_clk_type = amd_pp_pixel_clock; + break; + case DM_PP_CLOCK_TYPE_FCLK: + amd_pp_clk_type = amd_pp_f_clock; + break; + case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: + amd_pp_clk_type = amd_pp_dpp_clock; + break; + default: + DRM_ERROR("DM_PPLIB: invalid clock type: %d!\n", + dm_pp_clk_type); + break; + } + + return amd_pp_clk_type; +} + +static void pp_to_dc_clock_levels( + const struct amd_pp_clocks *pp_clks, + struct dm_pp_clock_levels *dc_clks, + enum dm_pp_clock_type dc_clk_type) +{ + uint32_t i; + + if (pp_clks->count > DM_PP_MAX_CLOCK_LEVELS) { + DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n", + DC_DECODE_PP_CLOCK_TYPE(dc_clk_type), + pp_clks->count, + DM_PP_MAX_CLOCK_LEVELS); + + dc_clks->num_levels = DM_PP_MAX_CLOCK_LEVELS; + } else + dc_clks->num_levels = pp_clks->count; + + DRM_INFO("DM_PPLIB: values for %s clock\n", + DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); + + for (i = 0; i < dc_clks->num_levels; i++) { + DRM_INFO("DM_PPLIB:\t %d\n", pp_clks->clock[i]); + /* translate 10kHz to kHz */ + dc_clks->clocks_in_khz[i] = pp_clks->clock[i] * 10; + } +} + +static void pp_to_dc_clock_levels_with_latency( + const struct pp_clock_levels_with_latency *pp_clks, + struct dm_pp_clock_levels_with_latency *clk_level_info, + enum dm_pp_clock_type dc_clk_type) +{ + uint32_t i; + + if (pp_clks->num_levels > DM_PP_MAX_CLOCK_LEVELS) { + DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n", + DC_DECODE_PP_CLOCK_TYPE(dc_clk_type), + pp_clks->num_levels, + DM_PP_MAX_CLOCK_LEVELS); + + clk_level_info->num_levels = DM_PP_MAX_CLOCK_LEVELS; + } else + clk_level_info->num_levels = pp_clks->num_levels; + + DRM_DEBUG("DM_PPLIB: values for %s clock\n", + DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); + + for (i = 0; i < clk_level_info->num_levels; i++) { + DRM_DEBUG("DM_PPLIB:\t %d in 10kHz\n", pp_clks->data[i].clocks_in_khz); + /* translate 10kHz to kHz */ + clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz * 10; + clk_level_info->data[i].latency_in_us = pp_clks->data[i].latency_in_us; + } +} + +static void pp_to_dc_clock_levels_with_voltage( + const struct pp_clock_levels_with_voltage *pp_clks, + struct dm_pp_clock_levels_with_voltage *clk_level_info, + enum dm_pp_clock_type dc_clk_type) +{ + uint32_t i; + + if (pp_clks->num_levels > DM_PP_MAX_CLOCK_LEVELS) { + DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n", + DC_DECODE_PP_CLOCK_TYPE(dc_clk_type), + pp_clks->num_levels, + DM_PP_MAX_CLOCK_LEVELS); + + clk_level_info->num_levels = DM_PP_MAX_CLOCK_LEVELS; + } else + clk_level_info->num_levels = pp_clks->num_levels; + + DRM_INFO("DM_PPLIB: values for %s clock\n", + DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); + + for (i = 0; i < clk_level_info->num_levels; i++) { + DRM_INFO("DM_PPLIB:\t %d in 10kHz\n", pp_clks->data[i].clocks_in_khz); + /* translate 10kHz to kHz */ + clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz * 10; + clk_level_info->data[i].voltage_in_mv = pp_clks->data[i].voltage_in_mv; + } +} + +bool dm_pp_get_clock_levels_by_type( + const struct dc_context *ctx, + enum dm_pp_clock_type clk_type, + struct dm_pp_clock_levels *dc_clks) +{ + struct amdgpu_device *adev = ctx->driver_context; + void *pp_handle = adev->powerplay.pp_handle; + struct amd_pp_clocks pp_clks = { 0 }; + 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->get_clock_by_type(pp_handle, + dc_to_pp_clock_type(clk_type), &pp_clks)) { + /* Error in pplib. Provide default values. */ + get_default_clock_levels(clk_type, dc_clks); + return true; + } + } + + 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->get_display_mode_validation_clocks( + pp_handle, &validation_clks)) { + /* Error in pplib. Provide default values. */ + DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n"); + validation_clks.engine_max_clock = 72000; + validation_clks.memory_max_clock = 80000; + validation_clks.level = 0; + } + } + + DRM_INFO("DM_PPLIB: Validation clocks:\n"); + DRM_INFO("DM_PPLIB: engine_max_clock: %d\n", + validation_clks.engine_max_clock); + DRM_INFO("DM_PPLIB: memory_max_clock: %d\n", + validation_clks.memory_max_clock); + DRM_INFO("DM_PPLIB: level : %d\n", + validation_clks.level); + + /* Translate 10 kHz to kHz. */ + validation_clks.engine_max_clock *= 10; + validation_clks.memory_max_clock *= 10; + + /* Determine the highest non-boosted level from the Validation Clocks */ + if (clk_type == DM_PP_CLOCK_TYPE_ENGINE_CLK) { + for (i = 0; i < dc_clks->num_levels; i++) { + if (dc_clks->clocks_in_khz[i] > validation_clks.engine_max_clock) { + /* This clock is higher the validation clock. + * Than means the previous one is the highest + * non-boosted one. */ + DRM_INFO("DM_PPLIB: reducing engine clock level from %d to %d\n", + dc_clks->num_levels, i); + dc_clks->num_levels = i > 0 ? i : 1; + break; + } + } + } else if (clk_type == DM_PP_CLOCK_TYPE_MEMORY_CLK) { + for (i = 0; i < dc_clks->num_levels; i++) { + if (dc_clks->clocks_in_khz[i] > validation_clks.memory_max_clock) { + DRM_INFO("DM_PPLIB: reducing memory clock level from %d to %d\n", + dc_clks->num_levels, i); + dc_clks->num_levels = i > 0 ? i : 1; + break; + } + } + } + + return true; +} + +bool dm_pp_get_clock_levels_by_type_with_latency( + const struct dc_context *ctx, + enum dm_pp_clock_type clk_type, + struct dm_pp_clock_levels_with_latency *clk_level_info) +{ + struct amdgpu_device *adev = ctx->driver_context; + void *pp_handle = adev->powerplay.pp_handle; + struct pp_clock_levels_with_latency pp_clks = { 0 }; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; + + if (!pp_funcs || !pp_funcs->get_clock_by_type_with_latency) + return false; + + if (pp_funcs->get_clock_by_type_with_latency(pp_handle, + dc_to_pp_clock_type(clk_type), + &pp_clks)) + return false; + + pp_to_dc_clock_levels_with_latency(&pp_clks, clk_level_info, clk_type); + + return true; +} + +bool dm_pp_get_clock_levels_by_type_with_voltage( + const struct dc_context *ctx, + enum dm_pp_clock_type clk_type, + struct dm_pp_clock_levels_with_voltage *clk_level_info) +{ + struct amdgpu_device *adev = ctx->driver_context; + void *pp_handle = adev->powerplay.pp_handle; + struct pp_clock_levels_with_voltage pp_clk_info = {0}; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; + + if (pp_funcs->get_clock_by_type_with_voltage(pp_handle, + dc_to_pp_clock_type(clk_type), + &pp_clk_info)) + return false; + + pp_to_dc_clock_levels_with_voltage(&pp_clk_info, clk_level_info, clk_type); + + return true; +} + +bool dm_pp_notify_wm_clock_changes( + const struct dc_context *ctx, + struct dm_pp_wm_sets_with_clock_ranges *wm_with_clock_ranges) +{ + /* TODO: to be implemented */ + return false; +} + +bool dm_pp_apply_power_level_change_request( + const struct dc_context *ctx, + struct dm_pp_power_level_change_request *level_change_req) +{ + /* TODO: to be implemented */ + return false; +} + +bool dm_pp_apply_clock_for_voltage_request( + const struct dc_context *ctx, + struct dm_pp_clock_for_voltage_req *clock_for_voltage_req) +{ + struct amdgpu_device *adev = ctx->driver_context; + struct pp_display_clock_request pp_clock_request = {0}; + int ret = 0; + + pp_clock_request.clock_type = dc_to_pp_clock_type(clock_for_voltage_req->clk_type); + pp_clock_request.clock_freq_in_khz = clock_for_voltage_req->clocks_in_khz; + + if (!pp_clock_request.clock_type) + return false; + + if (adev->powerplay.pp_funcs->display_clock_voltage_request) + ret = adev->powerplay.pp_funcs->display_clock_voltage_request( + adev->powerplay.pp_handle, + &pp_clock_request); + if (ret) + return false; + return true; +} + +bool dm_pp_get_static_clocks( + const struct dc_context *ctx, + struct dm_pp_static_clock_info *static_clk_info) +{ + struct amdgpu_device *adev = ctx->driver_context; + struct amd_pp_clock_info pp_clk_info = {0}; + int ret = 0; + + if (adev->powerplay.pp_funcs->get_current_clocks) + ret = adev->powerplay.pp_funcs->get_current_clocks( + adev->powerplay.pp_handle, + &pp_clk_info); + if (ret) + return false; + + static_clk_info->max_clocks_state = pp_clk_info.max_clocks_state; + /* translate 10kHz to kHz */ + static_clk_info->max_mclk_khz = pp_clk_info.max_memory_clock * 10; + static_clk_info->max_sclk_khz = pp_clk_info.max_engine_clock * 10; + + return true; +} + +void pp_rv_set_display_requirement(struct pp_smu *pp, + struct pp_smu_display_requirement_rv *req) +{ + struct amdgpu_device *adev = pp->ctx->driver_context; + struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; + int ret = 0; + if (hwmgr->hwmgr_func->set_deep_sleep_dcefclk) + ret = hwmgr->hwmgr_func->set_deep_sleep_dcefclk(hwmgr, req->hard_min_dcefclk_khz/10); + if (hwmgr->hwmgr_func->set_active_display_count) + ret = hwmgr->hwmgr_func->set_active_display_count(hwmgr, req->display_count); + + //store_cc6 is not yet implemented in SMU level +} + +void pp_rv_set_wm_ranges(struct pp_smu *pp, + struct pp_smu_wm_range_sets *ranges) +{ + struct amdgpu_device *adev = pp->ctx->driver_context; + struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; + struct pp_wm_sets_with_clock_ranges_soc15 ranges_soc15 = {0}; + int i = 0; + + if (!hwmgr->hwmgr_func->set_watermarks_for_clocks_ranges || + !pp || !ranges) + return; + + //not entirely sure if thats a correct assignment + ranges_soc15.num_wm_sets_dmif = ranges->num_reader_wm_sets; + ranges_soc15.num_wm_sets_mcif = ranges->num_writer_wm_sets; + + for (i = 0; i < ranges_soc15.num_wm_sets_dmif; i++) { + if (ranges->reader_wm_sets[i].wm_inst > 3) + ranges_soc15.wm_sets_dmif[i].wm_set_id = DC_WM_SET_A; + else + ranges_soc15.wm_sets_dmif[i].wm_set_id = + ranges->reader_wm_sets[i].wm_inst; + ranges_soc15.wm_sets_dmif[i].wm_max_dcefclk_in_khz = + ranges->reader_wm_sets[i].max_drain_clk_khz; + ranges_soc15.wm_sets_dmif[i].wm_min_dcefclk_in_khz = + ranges->reader_wm_sets[i].min_drain_clk_khz; + ranges_soc15.wm_sets_dmif[i].wm_max_memclk_in_khz = + ranges->reader_wm_sets[i].max_fill_clk_khz; + ranges_soc15.wm_sets_dmif[i].wm_min_memclk_in_khz = + ranges->reader_wm_sets[i].min_fill_clk_khz; + } + + for (i = 0; i < ranges_soc15.num_wm_sets_mcif; i++) { + if (ranges->writer_wm_sets[i].wm_inst > 3) + ranges_soc15.wm_sets_dmif[i].wm_set_id = DC_WM_SET_A; + else + ranges_soc15.wm_sets_mcif[i].wm_set_id = + ranges->writer_wm_sets[i].wm_inst; + ranges_soc15.wm_sets_mcif[i].wm_max_socclk_in_khz = + ranges->writer_wm_sets[i].max_fill_clk_khz; + ranges_soc15.wm_sets_mcif[i].wm_min_socclk_in_khz = + ranges->writer_wm_sets[i].min_fill_clk_khz; + ranges_soc15.wm_sets_mcif[i].wm_max_memclk_in_khz = + ranges->writer_wm_sets[i].max_fill_clk_khz; + ranges_soc15.wm_sets_mcif[i].wm_min_memclk_in_khz = + ranges->writer_wm_sets[i].min_fill_clk_khz; + } + + hwmgr->hwmgr_func->set_watermarks_for_clocks_ranges(hwmgr, &ranges_soc15); + +} + +void pp_rv_set_pme_wa_enable(struct pp_smu *pp) +{ + struct amdgpu_device *adev = pp->ctx->driver_context; + struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; + + if (hwmgr->hwmgr_func->smus_notify_pwe) + hwmgr->hwmgr_func->smus_notify_pwe(hwmgr); +} + +void dm_pp_get_funcs_rv( + struct dc_context *ctx, + struct pp_smu_funcs_rv *funcs) +{ + funcs->pp_smu.ctx = ctx; + funcs->set_display_requirement = pp_rv_set_display_requirement; + funcs->set_wm_ranges = pp_rv_set_wm_ranges; + funcs->set_pme_wa_enable = pp_rv_set_pme_wa_enable; +} diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c index a19df20b557b..9f0a217603ad 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c @@ -34,9 +34,6 @@ #include "amdgpu_dm.h" #include "amdgpu_dm_irq.h" #include "amdgpu_pm.h" -#include "dm_pp_smu.h" -#include "../../powerplay/inc/hwmgr.h" -#include "../../powerplay/hwmgr/smu10_hwmgr.h" @@ -77,493 +74,4 @@ bool dm_read_persistent_data(struct dc_context *ctx, /**** power component interfaces ****/ -bool dm_pp_apply_display_requirements( - const struct dc_context *ctx, - const struct dm_pp_display_configuration *pp_display_cfg) -{ - struct amdgpu_device *adev = ctx->driver_context; - if (adev->pm.dpm_enabled) { - - memset(&adev->pm.pm_display_cfg, 0, - sizeof(adev->pm.pm_display_cfg)); - - adev->pm.pm_display_cfg.cpu_cc6_disable = - pp_display_cfg->cpu_cc6_disable; - - adev->pm.pm_display_cfg.cpu_pstate_disable = - pp_display_cfg->cpu_pstate_disable; - - adev->pm.pm_display_cfg.cpu_pstate_separation_time = - pp_display_cfg->cpu_pstate_separation_time; - - adev->pm.pm_display_cfg.nb_pstate_switch_disable = - pp_display_cfg->nb_pstate_switch_disable; - - adev->pm.pm_display_cfg.num_display = - pp_display_cfg->display_count; - adev->pm.pm_display_cfg.num_path_including_non_display = - pp_display_cfg->display_count; - - adev->pm.pm_display_cfg.min_core_set_clock = - pp_display_cfg->min_engine_clock_khz/10; - adev->pm.pm_display_cfg.min_core_set_clock_in_sr = - pp_display_cfg->min_engine_clock_deep_sleep_khz/10; - adev->pm.pm_display_cfg.min_mem_set_clock = - pp_display_cfg->min_memory_clock_khz/10; - - adev->pm.pm_display_cfg.multi_monitor_in_sync = - pp_display_cfg->all_displays_in_sync; - adev->pm.pm_display_cfg.min_vblank_time = - pp_display_cfg->avail_mclk_switch_time_us; - - adev->pm.pm_display_cfg.display_clk = - pp_display_cfg->disp_clk_khz/10; - - adev->pm.pm_display_cfg.dce_tolerable_mclk_in_active_latency = - pp_display_cfg->avail_mclk_switch_time_in_disp_active_us; - - adev->pm.pm_display_cfg.crtc_index = pp_display_cfg->crtc_index; - adev->pm.pm_display_cfg.line_time_in_us = - pp_display_cfg->line_time_in_us; - - adev->pm.pm_display_cfg.vrefresh = pp_display_cfg->disp_configs[0].v_refresh; - adev->pm.pm_display_cfg.crossfire_display_index = -1; - adev->pm.pm_display_cfg.min_bus_bandwidth = 0; - - /* TODO: complete implementation of - * pp_display_configuration_change(). - * Follow example of: - * PHM_StoreDALConfigurationData - powerplay\hwmgr\hardwaremanager.c - * PP_IRI_DisplayConfigurationChange - powerplay\eventmgr\iri.c */ - if (adev->powerplay.pp_funcs->display_configuration_change) - adev->powerplay.pp_funcs->display_configuration_change( - adev->powerplay.pp_handle, - &adev->pm.pm_display_cfg); - - /* TODO: replace by a separate call to 'apply display cfg'? */ - amdgpu_pm_compute_clocks(adev); - } - - return true; -} - -static void get_default_clock_levels( - enum dm_pp_clock_type clk_type, - struct dm_pp_clock_levels *clks) -{ - uint32_t disp_clks_in_khz[6] = { - 300000, 400000, 496560, 626090, 685720, 757900 }; - uint32_t sclks_in_khz[6] = { - 300000, 360000, 423530, 514290, 626090, 720000 }; - uint32_t mclks_in_khz[2] = { 333000, 800000 }; - - switch (clk_type) { - case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - clks->num_levels = 6; - memmove(clks->clocks_in_khz, disp_clks_in_khz, - sizeof(disp_clks_in_khz)); - break; - case DM_PP_CLOCK_TYPE_ENGINE_CLK: - clks->num_levels = 6; - memmove(clks->clocks_in_khz, sclks_in_khz, - sizeof(sclks_in_khz)); - break; - case DM_PP_CLOCK_TYPE_MEMORY_CLK: - clks->num_levels = 2; - memmove(clks->clocks_in_khz, mclks_in_khz, - sizeof(mclks_in_khz)); - break; - default: - clks->num_levels = 0; - break; - } -} - -static enum amd_pp_clock_type dc_to_pp_clock_type( - enum dm_pp_clock_type dm_pp_clk_type) -{ - enum amd_pp_clock_type amd_pp_clk_type = 0; - - switch (dm_pp_clk_type) { - case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - amd_pp_clk_type = amd_pp_disp_clock; - break; - case DM_PP_CLOCK_TYPE_ENGINE_CLK: - amd_pp_clk_type = amd_pp_sys_clock; - break; - case DM_PP_CLOCK_TYPE_MEMORY_CLK: - amd_pp_clk_type = amd_pp_mem_clock; - break; - case DM_PP_CLOCK_TYPE_DCEFCLK: - amd_pp_clk_type = amd_pp_dcef_clock; - break; - case DM_PP_CLOCK_TYPE_DCFCLK: - amd_pp_clk_type = amd_pp_dcf_clock; - break; - case DM_PP_CLOCK_TYPE_PIXELCLK: - amd_pp_clk_type = amd_pp_pixel_clock; - break; - case DM_PP_CLOCK_TYPE_FCLK: - amd_pp_clk_type = amd_pp_f_clock; - break; - case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: - amd_pp_clk_type = amd_pp_dpp_clock; - break; - default: - DRM_ERROR("DM_PPLIB: invalid clock type: %d!\n", - dm_pp_clk_type); - break; - } - - return amd_pp_clk_type; -} - -static void pp_to_dc_clock_levels( - const struct amd_pp_clocks *pp_clks, - struct dm_pp_clock_levels *dc_clks, - enum dm_pp_clock_type dc_clk_type) -{ - uint32_t i; - - if (pp_clks->count > DM_PP_MAX_CLOCK_LEVELS) { - DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n", - DC_DECODE_PP_CLOCK_TYPE(dc_clk_type), - pp_clks->count, - DM_PP_MAX_CLOCK_LEVELS); - - dc_clks->num_levels = DM_PP_MAX_CLOCK_LEVELS; - } else - dc_clks->num_levels = pp_clks->count; - - DRM_INFO("DM_PPLIB: values for %s clock\n", - DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); - - for (i = 0; i < dc_clks->num_levels; i++) { - DRM_INFO("DM_PPLIB:\t %d\n", pp_clks->clock[i]); - /* translate 10kHz to kHz */ - dc_clks->clocks_in_khz[i] = pp_clks->clock[i] * 10; - } -} - -static void pp_to_dc_clock_levels_with_latency( - const struct pp_clock_levels_with_latency *pp_clks, - struct dm_pp_clock_levels_with_latency *clk_level_info, - enum dm_pp_clock_type dc_clk_type) -{ - uint32_t i; - - if (pp_clks->num_levels > DM_PP_MAX_CLOCK_LEVELS) { - DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n", - DC_DECODE_PP_CLOCK_TYPE(dc_clk_type), - pp_clks->num_levels, - DM_PP_MAX_CLOCK_LEVELS); - - clk_level_info->num_levels = DM_PP_MAX_CLOCK_LEVELS; - } else - clk_level_info->num_levels = pp_clks->num_levels; - - DRM_DEBUG("DM_PPLIB: values for %s clock\n", - DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); - - for (i = 0; i < clk_level_info->num_levels; i++) { - DRM_DEBUG("DM_PPLIB:\t %d in 10kHz\n", pp_clks->data[i].clocks_in_khz); - /* translate 10kHz to kHz */ - clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz * 10; - clk_level_info->data[i].latency_in_us = pp_clks->data[i].latency_in_us; - } -} - -static void pp_to_dc_clock_levels_with_voltage( - const struct pp_clock_levels_with_voltage *pp_clks, - struct dm_pp_clock_levels_with_voltage *clk_level_info, - enum dm_pp_clock_type dc_clk_type) -{ - uint32_t i; - - if (pp_clks->num_levels > DM_PP_MAX_CLOCK_LEVELS) { - DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n", - DC_DECODE_PP_CLOCK_TYPE(dc_clk_type), - pp_clks->num_levels, - DM_PP_MAX_CLOCK_LEVELS); - - clk_level_info->num_levels = DM_PP_MAX_CLOCK_LEVELS; - } else - clk_level_info->num_levels = pp_clks->num_levels; - - DRM_INFO("DM_PPLIB: values for %s clock\n", - DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); - - for (i = 0; i < clk_level_info->num_levels; i++) { - DRM_INFO("DM_PPLIB:\t %d in 10kHz\n", pp_clks->data[i].clocks_in_khz); - /* translate 10kHz to kHz */ - clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz * 10; - clk_level_info->data[i].voltage_in_mv = pp_clks->data[i].voltage_in_mv; - } -} - - -bool dm_pp_get_clock_levels_by_type( - const struct dc_context *ctx, - enum dm_pp_clock_type clk_type, - struct dm_pp_clock_levels *dc_clks) -{ - struct amdgpu_device *adev = ctx->driver_context; - void *pp_handle = adev->powerplay.pp_handle; - struct amd_pp_clocks pp_clks = { 0 }; - 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->get_clock_by_type(pp_handle, - dc_to_pp_clock_type(clk_type), &pp_clks)) { - /* Error in pplib. Provide default values. */ - get_default_clock_levels(clk_type, dc_clks); - return true; - } - } - - 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->get_display_mode_validation_clocks( - pp_handle, &validation_clks)) { - /* Error in pplib. Provide default values. */ - DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n"); - validation_clks.engine_max_clock = 72000; - validation_clks.memory_max_clock = 80000; - validation_clks.level = 0; - } - } - - DRM_INFO("DM_PPLIB: Validation clocks:\n"); - DRM_INFO("DM_PPLIB: engine_max_clock: %d\n", - validation_clks.engine_max_clock); - DRM_INFO("DM_PPLIB: memory_max_clock: %d\n", - validation_clks.memory_max_clock); - DRM_INFO("DM_PPLIB: level : %d\n", - validation_clks.level); - - /* Translate 10 kHz to kHz. */ - validation_clks.engine_max_clock *= 10; - validation_clks.memory_max_clock *= 10; - - /* Determine the highest non-boosted level from the Validation Clocks */ - if (clk_type == DM_PP_CLOCK_TYPE_ENGINE_CLK) { - for (i = 0; i < dc_clks->num_levels; i++) { - if (dc_clks->clocks_in_khz[i] > validation_clks.engine_max_clock) { - /* This clock is higher the validation clock. - * Than means the previous one is the highest - * non-boosted one. */ - DRM_INFO("DM_PPLIB: reducing engine clock level from %d to %d\n", - dc_clks->num_levels, i); - dc_clks->num_levels = i > 0 ? i : 1; - break; - } - } - } else if (clk_type == DM_PP_CLOCK_TYPE_MEMORY_CLK) { - for (i = 0; i < dc_clks->num_levels; i++) { - if (dc_clks->clocks_in_khz[i] > validation_clks.memory_max_clock) { - DRM_INFO("DM_PPLIB: reducing memory clock level from %d to %d\n", - dc_clks->num_levels, i); - dc_clks->num_levels = i > 0 ? i : 1; - break; - } - } - } - - return true; -} - -bool dm_pp_get_clock_levels_by_type_with_latency( - const struct dc_context *ctx, - enum dm_pp_clock_type clk_type, - struct dm_pp_clock_levels_with_latency *clk_level_info) -{ - struct amdgpu_device *adev = ctx->driver_context; - void *pp_handle = adev->powerplay.pp_handle; - struct pp_clock_levels_with_latency pp_clks = { 0 }; - const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - - if (!pp_funcs || !pp_funcs->get_clock_by_type_with_latency) - return false; - - if (pp_funcs->get_clock_by_type_with_latency(pp_handle, - dc_to_pp_clock_type(clk_type), - &pp_clks)) - return false; - - pp_to_dc_clock_levels_with_latency(&pp_clks, clk_level_info, clk_type); - - return true; -} - -bool dm_pp_get_clock_levels_by_type_with_voltage( - const struct dc_context *ctx, - enum dm_pp_clock_type clk_type, - struct dm_pp_clock_levels_with_voltage *clk_level_info) -{ - struct amdgpu_device *adev = ctx->driver_context; - void *pp_handle = adev->powerplay.pp_handle; - struct pp_clock_levels_with_voltage pp_clk_info = {0}; - const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - - if (pp_funcs->get_clock_by_type_with_voltage(pp_handle, - dc_to_pp_clock_type(clk_type), - &pp_clk_info)) - return false; - - pp_to_dc_clock_levels_with_voltage(&pp_clk_info, clk_level_info, clk_type); - - return true; -} - -bool dm_pp_notify_wm_clock_changes( - const struct dc_context *ctx, - struct dm_pp_wm_sets_with_clock_ranges *wm_with_clock_ranges) -{ - /* TODO: to be implemented */ - return false; -} - -bool dm_pp_apply_power_level_change_request( - const struct dc_context *ctx, - struct dm_pp_power_level_change_request *level_change_req) -{ - /* TODO: to be implemented */ - return false; -} - -bool dm_pp_apply_clock_for_voltage_request( - const struct dc_context *ctx, - struct dm_pp_clock_for_voltage_req *clock_for_voltage_req) -{ - struct amdgpu_device *adev = ctx->driver_context; - struct pp_display_clock_request pp_clock_request = {0}; - int ret = 0; - - pp_clock_request.clock_type = dc_to_pp_clock_type(clock_for_voltage_req->clk_type); - pp_clock_request.clock_freq_in_khz = clock_for_voltage_req->clocks_in_khz; - - if (!pp_clock_request.clock_type) - return false; - - if (adev->powerplay.pp_funcs->display_clock_voltage_request) - ret = adev->powerplay.pp_funcs->display_clock_voltage_request( - adev->powerplay.pp_handle, - &pp_clock_request); - if (ret) - return false; - return true; -} - -bool dm_pp_get_static_clocks( - const struct dc_context *ctx, - struct dm_pp_static_clock_info *static_clk_info) -{ - struct amdgpu_device *adev = ctx->driver_context; - struct amd_pp_clock_info pp_clk_info = {0}; - int ret = 0; - - if (adev->powerplay.pp_funcs->get_current_clocks) - ret = adev->powerplay.pp_funcs->get_current_clocks( - adev->powerplay.pp_handle, - &pp_clk_info); - if (ret) - return false; - - static_clk_info->max_clocks_state = pp_clk_info.max_clocks_state; - /* translate 10kHz to kHz */ - static_clk_info->max_mclk_khz = pp_clk_info.max_memory_clock * 10; - static_clk_info->max_sclk_khz = pp_clk_info.max_engine_clock * 10; - - return true; -} - -void pp_rv_set_display_requirement(struct pp_smu *pp, - struct pp_smu_display_requirement_rv *req) -{ - struct amdgpu_device *adev = pp->ctx->driver_context; - struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; - int ret = 0; - if (hwmgr->hwmgr_func->set_deep_sleep_dcefclk) - ret = hwmgr->hwmgr_func->set_deep_sleep_dcefclk(hwmgr, req->hard_min_dcefclk_khz/10); - if (hwmgr->hwmgr_func->set_active_display_count) - ret = hwmgr->hwmgr_func->set_active_display_count(hwmgr, req->display_count); - - //store_cc6 is not yet implemented in SMU level -} - -void pp_rv_set_wm_ranges(struct pp_smu *pp, - struct pp_smu_wm_range_sets *ranges) -{ - struct amdgpu_device *adev = pp->ctx->driver_context; - struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; - struct pp_wm_sets_with_clock_ranges_soc15 ranges_soc15 = {0}; - int i = 0; - - if (!hwmgr->hwmgr_func->set_watermarks_for_clocks_ranges || - !pp || !ranges) - return; - - //not entirely sure if thats a correct assignment - ranges_soc15.num_wm_sets_dmif = ranges->num_reader_wm_sets; - ranges_soc15.num_wm_sets_mcif = ranges->num_writer_wm_sets; - - for (i = 0; i < ranges_soc15.num_wm_sets_dmif; i++) { - if (ranges->reader_wm_sets[i].wm_inst > 3) - ranges_soc15.wm_sets_dmif[i].wm_set_id = DC_WM_SET_A; - else - ranges_soc15.wm_sets_dmif[i].wm_set_id = - ranges->reader_wm_sets[i].wm_inst; - ranges_soc15.wm_sets_dmif[i].wm_max_dcefclk_in_khz = - ranges->reader_wm_sets[i].max_drain_clk_khz; - ranges_soc15.wm_sets_dmif[i].wm_min_dcefclk_in_khz = - ranges->reader_wm_sets[i].min_drain_clk_khz; - ranges_soc15.wm_sets_dmif[i].wm_max_memclk_in_khz = - ranges->reader_wm_sets[i].max_fill_clk_khz; - ranges_soc15.wm_sets_dmif[i].wm_min_memclk_in_khz = - ranges->reader_wm_sets[i].min_fill_clk_khz; - } - - for (i = 0; i < ranges_soc15.num_wm_sets_mcif; i++) { - if (ranges->writer_wm_sets[i].wm_inst > 3) - ranges_soc15.wm_sets_dmif[i].wm_set_id = DC_WM_SET_A; - else - ranges_soc15.wm_sets_mcif[i].wm_set_id = - ranges->writer_wm_sets[i].wm_inst; - ranges_soc15.wm_sets_mcif[i].wm_max_socclk_in_khz = - ranges->writer_wm_sets[i].max_fill_clk_khz; - ranges_soc15.wm_sets_mcif[i].wm_min_socclk_in_khz = - ranges->writer_wm_sets[i].min_fill_clk_khz; - ranges_soc15.wm_sets_mcif[i].wm_max_memclk_in_khz = - ranges->writer_wm_sets[i].max_fill_clk_khz; - ranges_soc15.wm_sets_mcif[i].wm_min_memclk_in_khz = - ranges->writer_wm_sets[i].min_fill_clk_khz; - } - - hwmgr->hwmgr_func->set_watermarks_for_clocks_ranges(hwmgr, &ranges_soc15); - -} - -void pp_rv_set_pme_wa_enable(struct pp_smu *pp) -{ - struct amdgpu_device *adev = pp->ctx->driver_context; - struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; - - if (hwmgr->hwmgr_func->smus_notify_pwe) - hwmgr->hwmgr_func->smus_notify_pwe(hwmgr); -} - -void dm_pp_get_funcs_rv( - struct dc_context *ctx, - struct pp_smu_funcs_rv *funcs) -{ - funcs->pp_smu.ctx = ctx; - funcs->set_display_requirement = pp_rv_set_display_requirement; - funcs->set_wm_ranges = pp_rv_set_wm_ranges; - funcs->set_pme_wa_enable = pp_rv_set_pme_wa_enable; -} - - -/**** end of power component interfaces ****/ From 33a6a7eb8014cb7089570534ef4d502efe4372ed Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 6 Jun 2018 13:19:39 -0400 Subject: [PATCH 045/133] drm/amd/display: fix dcn1 watermark range reporting Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 102 ++++-------------- 1 file changed, 18 insertions(+), 84 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index ac4451adeec9..8dc0773b285e 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -1335,21 +1335,14 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc) { struct pp_smu_funcs_rv *pp = dc->res_pool->pp_smu; struct pp_smu_wm_range_sets ranges = {0}; - int max_fclk_khz, nom_fclk_khz, mid_fclk_khz, min_fclk_khz; - int max_dcfclk_khz, min_dcfclk_khz; - int socclk_khz; + int min_fclk_khz, min_dcfclk_khz, socclk_khz; const int overdrive = 5000000; /* 5 GHz to cover Overdrive */ - unsigned factor = (ddr4_dram_factor_single_Channel * dc->dcn_soc->number_of_channels); if (!pp->set_wm_ranges) return; kernel_fpu_begin(); - max_fclk_khz = dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 * 1000000 / factor; - nom_fclk_khz = dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 * 1000000 / factor; - mid_fclk_khz = dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 * 1000000 / factor; min_fclk_khz = dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 * 1000000 / 32; - max_dcfclk_khz = dc->dcn_soc->dcfclkv_max0p9 * 1000; min_dcfclk_khz = dc->dcn_soc->dcfclkv_min0p65 * 1000; socclk_khz = dc->dcn_soc->socclk * 1000; kernel_fpu_end(); @@ -1357,7 +1350,7 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc) /* Now notify PPLib/SMU about which Watermarks sets they should select * depending on DPM state they are in. And update BW MGR GFX Engine and * Memory clock member variables for Watermarks calculations for each - * Watermark Set + * Watermark Set. Only one watermark set for dcn1 due to hw bug DEGVIDCN10-254. */ /* SOCCLK does not affect anytihng but writeback for DCN so for now we dont * care what the value is, hence min to overdrive level @@ -1366,96 +1359,37 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc) ranges.num_writer_wm_sets = WM_SET_COUNT; ranges.reader_wm_sets[0].wm_inst = WM_A; ranges.reader_wm_sets[0].min_drain_clk_khz = min_dcfclk_khz; - ranges.reader_wm_sets[0].max_drain_clk_khz = max_dcfclk_khz; + ranges.reader_wm_sets[0].max_drain_clk_khz = overdrive; ranges.reader_wm_sets[0].min_fill_clk_khz = min_fclk_khz; - ranges.reader_wm_sets[0].max_fill_clk_khz = min_fclk_khz; + ranges.reader_wm_sets[0].max_fill_clk_khz = overdrive; ranges.writer_wm_sets[0].wm_inst = WM_A; ranges.writer_wm_sets[0].min_fill_clk_khz = socclk_khz; ranges.writer_wm_sets[0].max_fill_clk_khz = overdrive; ranges.writer_wm_sets[0].min_drain_clk_khz = min_fclk_khz; - ranges.writer_wm_sets[0].max_drain_clk_khz = min_fclk_khz; - - ranges.reader_wm_sets[1].wm_inst = WM_B; - ranges.reader_wm_sets[1].min_drain_clk_khz = min_fclk_khz; - ranges.reader_wm_sets[1].max_drain_clk_khz = max_dcfclk_khz; - ranges.reader_wm_sets[1].min_fill_clk_khz = mid_fclk_khz; - ranges.reader_wm_sets[1].max_fill_clk_khz = mid_fclk_khz; - ranges.writer_wm_sets[1].wm_inst = WM_B; - ranges.writer_wm_sets[1].min_fill_clk_khz = socclk_khz; - ranges.writer_wm_sets[1].max_fill_clk_khz = overdrive; - ranges.writer_wm_sets[1].min_drain_clk_khz = mid_fclk_khz; - ranges.writer_wm_sets[1].max_drain_clk_khz = mid_fclk_khz; - - - ranges.reader_wm_sets[2].wm_inst = WM_C; - ranges.reader_wm_sets[2].min_drain_clk_khz = min_fclk_khz; - ranges.reader_wm_sets[2].max_drain_clk_khz = max_dcfclk_khz; - ranges.reader_wm_sets[2].min_fill_clk_khz = nom_fclk_khz; - ranges.reader_wm_sets[2].max_fill_clk_khz = nom_fclk_khz; - ranges.writer_wm_sets[2].wm_inst = WM_C; - ranges.writer_wm_sets[2].min_fill_clk_khz = socclk_khz; - ranges.writer_wm_sets[2].max_fill_clk_khz = overdrive; - ranges.writer_wm_sets[2].min_drain_clk_khz = nom_fclk_khz; - ranges.writer_wm_sets[2].max_drain_clk_khz = nom_fclk_khz; - - ranges.reader_wm_sets[3].wm_inst = WM_D; - ranges.reader_wm_sets[3].min_drain_clk_khz = min_fclk_khz; - ranges.reader_wm_sets[3].max_drain_clk_khz = max_dcfclk_khz; - ranges.reader_wm_sets[3].min_fill_clk_khz = max_fclk_khz; - ranges.reader_wm_sets[3].max_fill_clk_khz = max_fclk_khz; - ranges.writer_wm_sets[3].wm_inst = WM_D; - ranges.writer_wm_sets[3].min_fill_clk_khz = socclk_khz; - ranges.writer_wm_sets[3].max_fill_clk_khz = overdrive; - ranges.writer_wm_sets[3].min_drain_clk_khz = max_fclk_khz; - ranges.writer_wm_sets[3].max_drain_clk_khz = max_fclk_khz; + ranges.writer_wm_sets[0].max_drain_clk_khz = overdrive; if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) { ranges.reader_wm_sets[0].wm_inst = WM_A; ranges.reader_wm_sets[0].min_drain_clk_khz = 300000; - ranges.reader_wm_sets[0].max_drain_clk_khz = 654000; + ranges.reader_wm_sets[0].max_drain_clk_khz = 5000000; ranges.reader_wm_sets[0].min_fill_clk_khz = 800000; - ranges.reader_wm_sets[0].max_fill_clk_khz = 800000; + ranges.reader_wm_sets[0].max_fill_clk_khz = 5000000; ranges.writer_wm_sets[0].wm_inst = WM_A; ranges.writer_wm_sets[0].min_fill_clk_khz = 200000; - ranges.writer_wm_sets[0].max_fill_clk_khz = 757000; + ranges.writer_wm_sets[0].max_fill_clk_khz = 5000000; ranges.writer_wm_sets[0].min_drain_clk_khz = 800000; - ranges.writer_wm_sets[0].max_drain_clk_khz = 800000; - - ranges.reader_wm_sets[1].wm_inst = WM_B; - ranges.reader_wm_sets[1].min_drain_clk_khz = 300000; - ranges.reader_wm_sets[1].max_drain_clk_khz = 654000; - ranges.reader_wm_sets[1].min_fill_clk_khz = 933000; - ranges.reader_wm_sets[1].max_fill_clk_khz = 933000; - ranges.writer_wm_sets[1].wm_inst = WM_B; - ranges.writer_wm_sets[1].min_fill_clk_khz = 200000; - ranges.writer_wm_sets[1].max_fill_clk_khz = 757000; - ranges.writer_wm_sets[1].min_drain_clk_khz = 933000; - ranges.writer_wm_sets[1].max_drain_clk_khz = 933000; - - - ranges.reader_wm_sets[2].wm_inst = WM_C; - ranges.reader_wm_sets[2].min_drain_clk_khz = 300000; - ranges.reader_wm_sets[2].max_drain_clk_khz = 654000; - ranges.reader_wm_sets[2].min_fill_clk_khz = 1067000; - ranges.reader_wm_sets[2].max_fill_clk_khz = 1067000; - ranges.writer_wm_sets[2].wm_inst = WM_C; - ranges.writer_wm_sets[2].min_fill_clk_khz = 200000; - ranges.writer_wm_sets[2].max_fill_clk_khz = 757000; - ranges.writer_wm_sets[2].min_drain_clk_khz = 1067000; - ranges.writer_wm_sets[2].max_drain_clk_khz = 1067000; - - ranges.reader_wm_sets[3].wm_inst = WM_D; - ranges.reader_wm_sets[3].min_drain_clk_khz = 300000; - ranges.reader_wm_sets[3].max_drain_clk_khz = 654000; - ranges.reader_wm_sets[3].min_fill_clk_khz = 1200000; - ranges.reader_wm_sets[3].max_fill_clk_khz = 1200000; - ranges.writer_wm_sets[3].wm_inst = WM_D; - ranges.writer_wm_sets[3].min_fill_clk_khz = 200000; - ranges.writer_wm_sets[3].max_fill_clk_khz = 757000; - ranges.writer_wm_sets[3].min_drain_clk_khz = 1200000; - ranges.writer_wm_sets[3].max_drain_clk_khz = 1200000; + ranges.writer_wm_sets[0].max_drain_clk_khz = 5000000; } + ranges.reader_wm_sets[1] = ranges.writer_wm_sets[0]; + ranges.reader_wm_sets[1].wm_inst = WM_B; + + ranges.reader_wm_sets[2] = ranges.writer_wm_sets[0]; + ranges.reader_wm_sets[2].wm_inst = WM_C; + + ranges.reader_wm_sets[3] = ranges.writer_wm_sets[0]; + ranges.reader_wm_sets[3].wm_inst = WM_D; + /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */ pp->set_wm_ranges(&pp->pp_smu, &ranges); } From 69d6bb171fe15f564adfbc485e77dd8c5ca953d5 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Tue, 5 Jun 2018 07:19:08 -0400 Subject: [PATCH 046/133] drm/amd/display: remove dcn1 watermark sets b, c and d Currently dcn1 will not switch between watermark sets so we can save time by not calculating 3 extra sets. Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 8dc0773b285e..12261fbc25e0 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -505,6 +505,7 @@ static void split_stream_across_pipes( resource_build_scaling_params(secondary_pipe); } +#if 0 static void calc_wm_sets_and_perf_params( struct dc_state *context, struct dcn_bw_internal_vars *v) @@ -586,6 +587,7 @@ static void calc_wm_sets_and_perf_params( if (v->voltage_level >= 3) context->bw.dcn.watermarks.d = context->bw.dcn.watermarks.a; } +#endif static bool dcn_bw_apply_registry_override(struct dc *dc) { @@ -980,7 +982,24 @@ bool dcn_validate_bandwidth( bw_consumed = v->fabric_and_dram_bandwidth; display_pipe_configuration(v); - calc_wm_sets_and_perf_params(context, v); + /*calc_wm_sets_and_perf_params(context, v);*/ + /* Only 1 set is used by dcn since no noticeable + * performance improvement was measured and due to hw bug DEGVIDCN10-254 + */ + dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); + + context->bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = + v->stutter_exit_watermark * 1000; + context->bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = + v->stutter_enter_plus_exit_watermark * 1000; + context->bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = + v->dram_clock_change_watermark * 1000; + context->bw.dcn.watermarks.a.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; + context->bw.dcn.watermarks.a.urgent_ns = v->urgent_watermark * 1000; + context->bw.dcn.watermarks.b = context->bw.dcn.watermarks.a; + context->bw.dcn.watermarks.c = context->bw.dcn.watermarks.a; + context->bw.dcn.watermarks.d = context->bw.dcn.watermarks.a; + context->bw.dcn.clk.fclk_khz = (int)(bw_consumed * 1000000 / (ddr4_dram_factor_single_Channel * v->number_of_channels)); if (bw_consumed == v->fabric_and_dram_bandwidth_vmin0p65) { From 7144d3cfff7d8b0d98d9d25ee42c674491e31bc9 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Tue, 5 Jun 2018 13:14:13 -0400 Subject: [PATCH 047/133] drm/amd/display: separate out wm change request dcn workaround Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c | 11 ++++++----- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h | 2 ++ .../gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 3 +++ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 1 + drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | 1 + 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c index 63b75ac4a1d5..623db09389b5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c @@ -190,6 +190,12 @@ static uint32_t convert_and_clamp( } +void hubbub1_wm_change_req_wa(struct hubbub *hubbub) +{ + REG_UPDATE_SEQ(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, + DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0, 1); +} + void hubbub1_program_watermarks( struct hubbub *hubbub, struct dcn_watermark_set *watermarks, @@ -203,8 +209,6 @@ void hubbub1_program_watermarks( */ uint32_t prog_wm_value; - REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, - DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0); /* Repeat for water mark set A, B, C and D. */ /* clock state A */ @@ -459,9 +463,6 @@ void hubbub1_program_watermarks( watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); } - REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, - DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1); - REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h index 0ca39cb71968..d6e596eef4c5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h @@ -195,6 +195,8 @@ void hubbub1_update_dchub( bool hubbub1_verify_allow_pstate_change_high( struct hubbub *hubbub); +void hubbub1_wm_change_req_wa(struct hubbub *hubbub); + void hubbub1_program_watermarks( struct hubbub *hubbub, struct dcn_watermark_set *watermarks, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index cc12c4757f8b..378bb19b98de 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2305,6 +2305,9 @@ static void dcn10_apply_ctx_for_surface( hubbub1_program_watermarks(dc->res_pool->hubbub, &context->bw.dcn.watermarks, ref_clk_mhz, true); + if (dc->hwseq->wa.DEGVIDCN10_254) + hubbub1_wm_change_req_wa(dc->res_pool->hubbub); + if (dc->debug.sanity_checks) { /* pstate stuck check after watermark update */ dcn10_verify_allow_pstate_change_high(dc); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 2db08b99db56..68be66eabc40 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -743,6 +743,7 @@ static struct dce_hwseq *dcn10_hwseq_create( hws->masks = &hwseq_mask; hws->wa.DEGVIDCN10_253 = true; hws->wa.false_optc_underflow = true; + hws->wa.DEGVIDCN10_254 = true; } return hws; } diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index a71770ed4b9f..1c94dae6bbde 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -44,6 +44,7 @@ struct dce_hwseq_wa { bool blnd_crtc_trigger; bool DEGVIDCN10_253; bool false_optc_underflow; + bool DEGVIDCN10_254; }; struct hwseq_wa_state { From e21db6dbdf4327f620c5a203f7801b59dad9942e Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Thu, 24 May 2018 14:39:01 -0400 Subject: [PATCH 048/133] drm/amd/display: move dcn watermark programming to set_bandwidth Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 107 +++--------------- .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 2 +- 2 files changed, 19 insertions(+), 90 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 378bb19b98de..21b45e8d49f7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2219,8 +2219,6 @@ static void dcn10_apply_ctx_for_surface( int i; struct timing_generator *tg; bool removed_pipe[4] = { false }; - unsigned int ref_clk_mhz = dc->res_pool->ref_clock_inKhz/1000; - bool program_water_mark = false; struct pipe_ctx *top_pipe_to_program = find_top_pipe_for_stream(dc, context, stream); DC_LOGGER_INIT(dc->ctx->logger); @@ -2281,107 +2279,38 @@ static void dcn10_apply_ctx_for_surface( if (num_planes == 0) false_optc_underflow_wa(dc, stream, tg); - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *old_pipe_ctx = - &dc->current_state->res_ctx.pipe_ctx[i]; - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; - - if (pipe_ctx->stream == stream && - pipe_ctx->plane_state && - pipe_ctx->plane_state->update_flags.bits.full_update) - program_water_mark = true; - + for (i = 0; i < dc->res_pool->pipe_count; i++) if (removed_pipe[i]) - dcn10_disable_plane(dc, old_pipe_ctx); - } + dcn10_disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]); - if (program_water_mark) { - if (dc->debug.sanity_checks) { - /* pstate stuck check after watermark update */ - dcn10_verify_allow_pstate_change_high(dc); - } - - /* watermark is for all pipes */ - hubbub1_program_watermarks(dc->res_pool->hubbub, - &context->bw.dcn.watermarks, ref_clk_mhz, true); - - if (dc->hwseq->wa.DEGVIDCN10_254) - hubbub1_wm_change_req_wa(dc->res_pool->hubbub); - - if (dc->debug.sanity_checks) { - /* pstate stuck check after watermark update */ - dcn10_verify_allow_pstate_change_high(dc); - } - } -/* DC_LOG_BANDWIDTH_CALCS(dc->ctx->logger, - "\n============== Watermark parameters ==============\n" - "a.urgent_ns: %d \n" - "a.cstate_enter_plus_exit: %d \n" - "a.cstate_exit: %d \n" - "a.pstate_change: %d \n" - "a.pte_meta_urgent: %d \n" - "b.urgent_ns: %d \n" - "b.cstate_enter_plus_exit: %d \n" - "b.cstate_exit: %d \n" - "b.pstate_change: %d \n" - "b.pte_meta_urgent: %d \n", - context->bw.dcn.watermarks.a.urgent_ns, - context->bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns, - context->bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns, - context->bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns, - context->bw.dcn.watermarks.a.pte_meta_urgent_ns, - context->bw.dcn.watermarks.b.urgent_ns, - context->bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns, - context->bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns, - context->bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns, - context->bw.dcn.watermarks.b.pte_meta_urgent_ns - ); - DC_LOG_BANDWIDTH_CALCS(dc->ctx->logger, - "\nc.urgent_ns: %d \n" - "c.cstate_enter_plus_exit: %d \n" - "c.cstate_exit: %d \n" - "c.pstate_change: %d \n" - "c.pte_meta_urgent: %d \n" - "d.urgent_ns: %d \n" - "d.cstate_enter_plus_exit: %d \n" - "d.cstate_exit: %d \n" - "d.pstate_change: %d \n" - "d.pte_meta_urgent: %d \n" - "========================================================\n", - context->bw.dcn.watermarks.c.urgent_ns, - context->bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns, - context->bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns, - context->bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns, - context->bw.dcn.watermarks.c.pte_meta_urgent_ns, - context->bw.dcn.watermarks.d.urgent_ns, - context->bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns, - context->bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns, - context->bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns, - context->bw.dcn.watermarks.d.pte_meta_urgent_ns - ); -*/ + if (dc->hwseq->wa.DEGVIDCN10_254) + hubbub1_wm_change_req_wa(dc->res_pool->hubbub); } static void dcn10_set_bandwidth( struct dc *dc, struct dc_state *context, - bool decrease_allowed) + bool safe_to_lower) { if (dc->debug.sanity_checks) dcn10_verify_allow_pstate_change_high(dc); - if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) - return; + if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { + if (context->stream_count == 0) + context->bw.dcn.clk.phyclk_khz = 0; - if (context->stream_count == 0) - context->bw.dcn.clk.phyclk_khz = 0; + dc->res_pool->dccg->funcs->update_clocks( + dc->res_pool->dccg, + &context->bw.dcn.clk, + safe_to_lower); - dc->res_pool->dccg->funcs->update_clocks( - dc->res_pool->dccg, - &context->bw.dcn.clk, - decrease_allowed); + dcn10_pplib_apply_display_requirements(dc, context); + } - dcn10_pplib_apply_display_requirements(dc, context); + hubbub1_program_watermarks(dc->res_pool->hubbub, + &context->bw.dcn.watermarks, + dc->res_pool->ref_clock_inKhz / 1000, + true); if (dc->debug.sanity_checks) dcn10_verify_allow_pstate_change_high(dc); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 1c94dae6bbde..2506601120af 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -172,7 +172,7 @@ struct hw_sequencer_funcs { void (*set_bandwidth)( struct dc *dc, struct dc_state *context, - bool decrease_allowed); + bool safe_to_lower); void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes, int vmin, int vmax); From bf28c2e205b1c37e412cb6785a34f10de944bae1 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Tue, 5 Jun 2018 07:33:10 -0400 Subject: [PATCH 049/133] drm/amd/display: remove soc_bounding_box.c Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/Makefile | 3 +- .../drm/amd/display/dc/dml/display_mode_lib.h | 1 - .../amd/display/dc/dml/display_mode_structs.h | 3 +- .../drm/amd/display/dc/dml/soc_bounding_box.c | 79 ------------------- .../drm/amd/display/dc/dml/soc_bounding_box.h | 35 -------- 5 files changed, 2 insertions(+), 119 deletions(-) delete mode 100644 drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c delete mode 100644 drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index f83a608f93e9..d97ca6528f9d 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -36,11 +36,10 @@ CFLAGS_display_mode_lib.o := $(dml_ccflags) CFLAGS_display_pipe_clocks.o := $(dml_ccflags) CFLAGS_dml1_display_rq_dlg_calc.o := $(dml_ccflags) CFLAGS_display_rq_dlg_helpers.o := $(dml_ccflags) -CFLAGS_soc_bounding_box.o := $(dml_ccflags) CFLAGS_dml_common_defs.o := $(dml_ccflags) DML = display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \ - soc_bounding_box.o dml_common_defs.o + dml_common_defs.o AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML)) diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h index 3c2abcb8a1b0..635206248889 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h @@ -27,7 +27,6 @@ #include "dml_common_defs.h" -#include "soc_bounding_box.h" #include "dml1_display_rq_dlg_calc.h" enum dml_project { diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h index 7fa0375939ae..6943801c5fd3 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h @@ -64,10 +64,9 @@ struct _vcs_dpi_voltage_scaling_st { double dscclk_mhz; double dcfclk_mhz; double socclk_mhz; - double dram_speed_mhz; + double dram_speed_mts; double fabricclk_mhz; double dispclk_mhz; - double dram_bw_per_chan_gbps; double phyclk_mhz; double dppclk_mhz; }; diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c deleted file mode 100644 index 324239c77958..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2017 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ -#include "soc_bounding_box.h" -#include "display_mode_lib.h" -#include "dc_features.h" - -#include "dml_inline_defs.h" - -/* - * NOTE: - * This file is gcc-parseable HW gospel, coming straight from HW engineers. - * - * It doesn't adhere to Linux kernel style and sometimes will do things in odd - * ways. Unless there is something clearly wrong with it the code should - * remain as-is as it provides us with a guarantee from HW that it is correct. - */ - -void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box) -{ - to_box->dram_clock_change_latency_us = from_box->dram_clock_change_latency_us; - to_box->sr_exit_time_us = from_box->sr_exit_time_us; - to_box->sr_enter_plus_exit_time_us = from_box->sr_enter_plus_exit_time_us; - to_box->urgent_latency_us = from_box->urgent_latency_us; - to_box->writeback_latency_us = from_box->writeback_latency_us; -} - -voltage_scaling_st dml_socbb_voltage_scaling( - const soc_bounding_box_st *soc, - enum voltage_state voltage) -{ - const voltage_scaling_st *voltage_state; - const voltage_scaling_st * const voltage_end = soc->clock_limits + DC__VOLTAGE_STATES; - - for (voltage_state = soc->clock_limits; - voltage_state < voltage_end && voltage_state->state != voltage; - voltage_state++) { - } - - if (voltage_state < voltage_end) - return *voltage_state; - return soc->clock_limits[DC__VOLTAGE_STATES - 1]; -} - -double dml_socbb_return_bw_mhz(soc_bounding_box_st *box, enum voltage_state voltage) -{ - double return_bw; - - voltage_scaling_st state = dml_socbb_voltage_scaling(box, voltage); - - return_bw = dml_min((double) box->return_bus_width_bytes * state.dcfclk_mhz, - state.dram_bw_per_chan_gbps * 1000.0 * (double) box->num_chans - * box->ideal_dram_bw_after_urgent_percent / 100.0); - - return_bw = dml_min((double) box->return_bus_width_bytes * state.fabricclk_mhz, return_bw); - - return return_bw; -} diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h deleted file mode 100644 index 7a65206a6d21..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2017 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#ifndef __SOC_BOUNDING_BOX_H__ -#define __SOC_BOUNDING_BOX_H__ - -#include "dml_common_defs.h" - -void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box); -voltage_scaling_st dml_socbb_voltage_scaling(const soc_bounding_box_st *box, enum voltage_state voltage); -double dml_socbb_return_bw_mhz(soc_bounding_box_st *box, enum voltage_state voltage); - -#endif From b6c3053a8f431a032a1473dc0e0069ca7fd0b0e5 Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Fri, 8 Jun 2018 13:07:53 -0500 Subject: [PATCH 050/133] drm/amd/display: Check scaling ration not viewports params. In case of roation, width and height in viewport is difference between viewport and h_active and v_active, while this is not scaling. The right way is check ratios in scaling data, to determine it is a scaling case or not. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index c69fa4bfab0a..742fd497ed00 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c @@ -145,10 +145,10 @@ static bool dpp_get_optimal_number_of_taps( pixel_width = scl_data->viewport.width; /* Some ASICs does not support FP16 scaling, so we reject modes require this*/ - if (scl_data->viewport.width != scl_data->h_active && - scl_data->viewport.height != scl_data->v_active && + if (scl_data->format == PIXEL_FORMAT_FP16 && dpp->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT && - scl_data->format == PIXEL_FORMAT_FP16) + scl_data->ratios.horz.value != dc_fixpt_one.value && + scl_data->ratios.vert.value != dc_fixpt_one.value) return false; if (scl_data->viewport.width > scl_data->h_active && From c1aaea99a43e39c7c8dc6c71b84589c89d5bcbf2 Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Tue, 5 Jun 2018 09:14:36 -0400 Subject: [PATCH 051/133] drm/amd/display: dal 3.1.52 Signed-off-by: Tony Cheng Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index cbcdbd9b9910..74e6653b9852 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,7 +38,7 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.51" +#define DC_VER "3.1.52" #define MAX_SURFACES 3 #define MAX_STREAMS 6 From 7f93c1de64693dc18afe55559f14cee6b5403c6c Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Sat, 9 Jun 2018 19:33:14 -0400 Subject: [PATCH 052/133] drm/amd/display: add valid regoffset and NULL pointer check Signed-off-by: Charlene Liu Reviewed-by: Dmytro Laktyushkin Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 8 +++--- .../gpu/drm/amd/display/dc/core/dc_link_dp.c | 9 ++++--- .../display/dc/dce110/dce110_hw_sequencer.c | 7 ++--- .../drm/amd/display/dc/dcn10/dcn10_hubbub.c | 5 ++++ .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 26 ++++++++++++++----- 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 8eb8b8768465..fa56c0fc02bf 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -33,6 +33,7 @@ #include "dc_link_dp.h" #include "dc_link_ddc.h" #include "link_hwss.h" +#include "opp.h" #include "link_encoder.h" #include "hw_sequencer.h" @@ -2382,9 +2383,10 @@ void core_link_enable_stream( core_dc->hwss.enable_audio_stream(pipe_ctx); /* turn off otg test pattern if enable */ - pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, - CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, - COLOR_DEPTH_UNDEFINED); + if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) + pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, + CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, + COLOR_DEPTH_UNDEFINED); core_dc->hwss.enable_stream(pipe_ctx); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 509f265663d2..049fc5cce1d2 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -3,6 +3,7 @@ #include "dc.h" #include "dc_link_dp.h" #include "dm_helpers.h" +#include "opp.h" #include "inc/core_types.h" #include "link_hwss.h" @@ -2511,8 +2512,8 @@ static void set_crtc_test_pattern(struct dc_link *link, pipe_ctx->stream->bit_depth_params = params; pipe_ctx->stream_res.opp->funcs-> opp_program_bit_depth_reduction(pipe_ctx->stream_res.opp, ¶ms); - - pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, + if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) + pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, controller_test_pattern, color_depth); } break; @@ -2524,8 +2525,8 @@ static void set_crtc_test_pattern(struct dc_link *link, pipe_ctx->stream->bit_depth_params = params; pipe_ctx->stream_res.opp->funcs-> opp_program_bit_depth_reduction(pipe_ctx->stream_res.opp, ¶ms); - - pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, + if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) + pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, color_depth); } diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 3b983b3f3423..9cbd5036db07 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1475,7 +1475,7 @@ static void power_down_controllers(struct dc *dc) { int i; - for (i = 0; i < dc->res_pool->pipe_count; i++) { + for (i = 0; i < dc->res_pool->timing_generator_count; i++) { dc->res_pool->timing_generators[i]->funcs->disable_crtc( dc->res_pool->timing_generators[i]); } @@ -1515,12 +1515,13 @@ static void disable_vga_and_power_gate_all_controllers( struct timing_generator *tg; struct dc_context *ctx = dc->ctx; - for (i = 0; i < dc->res_pool->pipe_count; i++) { + for (i = 0; i < dc->res_pool->timing_generator_count; i++) { tg = dc->res_pool->timing_generators[i]; if (tg->funcs->disable_vga) tg->funcs->disable_vga(tg); - + } + for (i = 0; i < dc->res_pool->pipe_count; i++) { /* Enable CLOCK gating for each pipe BEFORE controller * powergating. */ enable_display_pipe_clock_gating(ctx, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c index 623db09389b5..1ea91e153d3a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c @@ -483,6 +483,11 @@ void hubbub1_update_dchub( struct hubbub *hubbub, struct dchub_init_data *dh_data) { + if (REG(DCHUBBUB_SDPIF_FB_TOP) == 0) { + ASSERT(false); + /*should not come here*/ + return; + } /* TODO: port code from dal2 */ switch (dh_data->fb_mode) { case FRAME_BUFFER_MODE_ZFB_ONLY: diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 21b45e8d49f7..3b2cb2d3b8a6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -415,6 +415,8 @@ static void dpp_pg_control( if (hws->ctx->dc->debug.disable_dpp_power_gate) return; + if (REG(DOMAIN1_PG_CONFIG) == 0) + return; switch (dpp_inst) { case 0: /* DPP0 */ @@ -465,6 +467,8 @@ static void hubp_pg_control( if (hws->ctx->dc->debug.disable_hubp_power_gate) return; + if (REG(DOMAIN0_PG_CONFIG) == 0) + return; switch (hubp_inst) { case 0: /* DCHUBP0 */ @@ -865,7 +869,8 @@ void hwss1_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx) return; mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove); - opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true; + if (opp != NULL) + opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true; dc->optimized_required = true; @@ -1343,10 +1348,11 @@ static void dcn10_enable_per_frame_crtc_position_reset( DC_SYNC_INFO("Setting up\n"); for (i = 0; i < group_size; i++) - grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset( - grouped_pipes[i]->stream_res.tg, - grouped_pipes[i]->stream->triggered_crtc_reset.event_source->status.primary_otg_inst, - &grouped_pipes[i]->stream->triggered_crtc_reset); + if (grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset) + grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset( + grouped_pipes[i]->stream_res.tg, + grouped_pipes[i]->stream->triggered_crtc_reset.event_source->status.primary_otg_inst, + &grouped_pipes[i]->stream->triggered_crtc_reset); DC_SYNC_INFO("Waiting for trigger\n"); @@ -2496,8 +2502,14 @@ static void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx) static void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data) { - if (hws->ctx->dc->res_pool->hubbub != NULL) - hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data); + if (hws->ctx->dc->res_pool->hubbub != NULL) { + struct hubp *hubp = hws->ctx->dc->res_pool->hubps[0]; + + if (hubp->funcs->hubp_update_dchub) + hubp->funcs->hubp_update_dchub(hubp, dh_data); + else + hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data); + } } static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) From 1eeedbcc20d64ff2ef7eb9823f85bbb1c2545064 Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Wed, 30 May 2018 15:44:50 -0400 Subject: [PATCH 053/133] drm/amd/display: get board layout for edid emulation Signed-off-by: Samson Tam Reviewed-by: Aric Cyr Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/bios/bios_parser.c | 196 ++++++++++++++++ .../drm/amd/display/dc/bios/bios_parser2.c | 218 +++++++++++++++++- .../gpu/drm/amd/display/dc/dc_bios_types.h | 4 + .../amd/display/include/grph_object_defs.h | 46 ++++ .../drm/amd/display/include/grph_object_id.h | 11 + 5 files changed, 474 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c index c7f0b27e457e..be8a2494355a 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c @@ -3762,6 +3762,200 @@ static struct integrated_info *bios_parser_create_integrated_info( return NULL; } +enum bp_result update_slot_layout_info( + struct dc_bios *dcb, + unsigned int i, + struct slot_layout_info *slot_layout_info, + unsigned int record_offset) +{ + unsigned int j; + struct bios_parser *bp; + ATOM_BRACKET_LAYOUT_RECORD *record; + ATOM_COMMON_RECORD_HEADER *record_header; + enum bp_result result = BP_RESULT_NORECORD; + + bp = BP_FROM_DCB(dcb); + record = NULL; + record_header = NULL; + + for (;;) { + + record_header = (ATOM_COMMON_RECORD_HEADER *) + GET_IMAGE(ATOM_COMMON_RECORD_HEADER, record_offset); + if (record_header == NULL) { + result = BP_RESULT_BADBIOSTABLE; + break; + } + + /* the end of the list */ + if (record_header->ucRecordType == 0xff || + record_header->ucRecordSize == 0) { + break; + } + + if (record_header->ucRecordType == + ATOM_BRACKET_LAYOUT_RECORD_TYPE && + sizeof(ATOM_BRACKET_LAYOUT_RECORD) + <= record_header->ucRecordSize) { + record = (ATOM_BRACKET_LAYOUT_RECORD *) + (record_header); + result = BP_RESULT_OK; + break; + } + + record_offset += record_header->ucRecordSize; + } + + /* return if the record not found */ + if (result != BP_RESULT_OK) + return result; + + /* get slot sizes */ + slot_layout_info->length = record->ucLength; + slot_layout_info->width = record->ucWidth; + + /* get info for each connector in the slot */ + slot_layout_info->num_of_connectors = record->ucConnNum; + for (j = 0; j < slot_layout_info->num_of_connectors; ++j) { + slot_layout_info->connectors[j].connector_type = + (enum connector_layout_type) + (record->asConnInfo[j].ucConnectorType); + switch (record->asConnInfo[j].ucConnectorType) { + case CONNECTOR_TYPE_DVI_D: + slot_layout_info->connectors[j].connector_type = + CONNECTOR_LAYOUT_TYPE_DVI_D; + slot_layout_info->connectors[j].length = + CONNECTOR_SIZE_DVI; + break; + + case CONNECTOR_TYPE_HDMI: + slot_layout_info->connectors[j].connector_type = + CONNECTOR_LAYOUT_TYPE_HDMI; + slot_layout_info->connectors[j].length = + CONNECTOR_SIZE_HDMI; + break; + + case CONNECTOR_TYPE_DISPLAY_PORT: + slot_layout_info->connectors[j].connector_type = + CONNECTOR_LAYOUT_TYPE_DP; + slot_layout_info->connectors[j].length = + CONNECTOR_SIZE_DP; + break; + + case CONNECTOR_TYPE_MINI_DISPLAY_PORT: + slot_layout_info->connectors[j].connector_type = + CONNECTOR_LAYOUT_TYPE_MINI_DP; + slot_layout_info->connectors[j].length = + CONNECTOR_SIZE_MINI_DP; + break; + + default: + slot_layout_info->connectors[j].connector_type = + CONNECTOR_LAYOUT_TYPE_UNKNOWN; + slot_layout_info->connectors[j].length = + CONNECTOR_SIZE_UNKNOWN; + } + + slot_layout_info->connectors[j].position = + record->asConnInfo[j].ucPosition; + slot_layout_info->connectors[j].connector_id = + object_id_from_bios_object_id( + record->asConnInfo[j].usConnectorObjectId); + } + return result; +} + + +enum bp_result get_bracket_layout_record( + struct dc_bios *dcb, + unsigned int bracket_layout_id, + struct slot_layout_info *slot_layout_info) +{ + unsigned int i; + unsigned int record_offset; + struct bios_parser *bp; + enum bp_result result; + ATOM_OBJECT *object; + ATOM_OBJECT_TABLE *object_table; + unsigned int genericTableOffset; + + bp = BP_FROM_DCB(dcb); + object = NULL; + if (slot_layout_info == NULL) { + DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n"); + return BP_RESULT_BADINPUT; + } + + + genericTableOffset = bp->object_info_tbl_offset + + bp->object_info_tbl.v1_3->usMiscObjectTableOffset; + object_table = (ATOM_OBJECT_TABLE *) + GET_IMAGE(ATOM_OBJECT_TABLE, genericTableOffset); + if (!object_table) + return BP_RESULT_FAILURE; + + result = BP_RESULT_NORECORD; + for (i = 0; i < object_table->ucNumberOfObjects; ++i) { + + if (bracket_layout_id == + object_table->asObjects[i].usObjectID) { + + object = &object_table->asObjects[i]; + record_offset = object->usRecordOffset + + bp->object_info_tbl_offset; + + result = update_slot_layout_info(dcb, i, + slot_layout_info, record_offset); + break; + } + } + return result; +} + +static enum bp_result bios_get_board_layout_info( + struct dc_bios *dcb, + struct board_layout_info *board_layout_info) +{ + unsigned int i; + struct bios_parser *bp; + enum bp_result record_result; + + const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = { + GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1, + GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2, + 0, 0 + }; + + bp = BP_FROM_DCB(dcb); + if (board_layout_info == NULL) { + DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n"); + return BP_RESULT_BADINPUT; + } + + board_layout_info->num_of_slots = 0; + + for (i = 0; i < MAX_BOARD_SLOTS; ++i) { + record_result = get_bracket_layout_record(dcb, + slot_index_to_vbios_id[i], + &board_layout_info->slots[i]); + + if (record_result == BP_RESULT_NORECORD && i > 0) + break; /* no more slots present in bios */ + else if (record_result != BP_RESULT_OK) + return record_result; /* fail */ + + ++board_layout_info->num_of_slots; + } + + /* all data is valid */ + board_layout_info->is_number_of_slots_valid = 1; + board_layout_info->is_slots_size_valid = 1; + board_layout_info->is_connector_offsets_valid = 1; + board_layout_info->is_connector_lengths_valid = 1; + + return BP_RESULT_OK; +} + /******************************************************************************/ static const struct dc_vbios_funcs vbios_funcs = { @@ -3836,6 +4030,8 @@ static const struct dc_vbios_funcs vbios_funcs = { .post_init = bios_parser_post_init, /* patch vbios table for mxm module by reading i2c */ .bios_parser_destroy = bios_parser_destroy, + + .get_board_layout_info = bios_get_board_layout_info, }; static bool bios_parser_construct( diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index b8cef7af3c4a..aeb56e402ccc 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -43,6 +43,29 @@ #include "bios_parser_interface.h" #include "bios_parser_common.h" + +/* Temporarily add in defines until ObjectID.h patch is updated in a few days */ +#ifndef GENERIC_OBJECT_ID_BRACKET_LAYOUT +#define GENERIC_OBJECT_ID_BRACKET_LAYOUT 0x05 +#endif /* GENERIC_OBJECT_ID_BRACKET_LAYOUT */ + +#ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 +#define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 \ + (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT) +#endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 */ + +#ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 +#define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 \ + (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT) +#endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 */ + +#define DC_LOGGER \ + bp->base.ctx->logger + #define LAST_RECORD_TYPE 0xff #define SMU9_SYSPLL0_ID 0 @@ -86,7 +109,6 @@ static struct atom_encoder_caps_record *get_encoder_cap_record( #define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table) - static void destruct(struct bios_parser *bp) { kfree(bp->base.bios_local_image); @@ -1854,6 +1876,198 @@ static struct integrated_info *bios_parser_create_integrated_info( return NULL; } +static enum bp_result update_slot_layout_info( + struct dc_bios *dcb, + unsigned int i, + struct slot_layout_info *slot_layout_info) +{ + unsigned int record_offset; + unsigned int j; + struct atom_display_object_path_v2 *object; + struct atom_bracket_layout_record *record; + struct atom_common_record_header *record_header; + enum bp_result result; + struct bios_parser *bp; + struct object_info_table *tbl; + struct display_object_info_table_v1_4 *v1_4; + + record = NULL; + record_header = NULL; + result = BP_RESULT_NORECORD; + + bp = BP_FROM_DCB(dcb); + tbl = &bp->object_info_tbl; + v1_4 = tbl->v1_4; + + object = &v1_4->display_path[i]; + record_offset = (unsigned int) + (object->disp_recordoffset) + + (unsigned int)(bp->object_info_tbl_offset); + + for (;;) { + + record_header = (struct atom_common_record_header *) + GET_IMAGE(struct atom_common_record_header, + record_offset); + if (record_header == NULL) { + result = BP_RESULT_BADBIOSTABLE; + break; + } + + /* the end of the list */ + if (record_header->record_type == 0xff || + record_header->record_size == 0) { + break; + } + + if (record_header->record_type == + ATOM_BRACKET_LAYOUT_RECORD_TYPE && + sizeof(struct atom_bracket_layout_record) + <= record_header->record_size) { + record = (struct atom_bracket_layout_record *) + (record_header); + result = BP_RESULT_OK; + break; + } + + record_offset += record_header->record_size; + } + + /* return if the record not found */ + if (result != BP_RESULT_OK) + return result; + + /* get slot sizes */ + slot_layout_info->length = record->bracketlen; + slot_layout_info->width = record->bracketwidth; + + /* get info for each connector in the slot */ + slot_layout_info->num_of_connectors = record->conn_num; + for (j = 0; j < slot_layout_info->num_of_connectors; ++j) { + slot_layout_info->connectors[j].connector_type = + (enum connector_layout_type) + (record->conn_info[j].connector_type); + switch (record->conn_info[j].connector_type) { + case CONNECTOR_TYPE_DVI_D: + slot_layout_info->connectors[j].connector_type = + CONNECTOR_LAYOUT_TYPE_DVI_D; + slot_layout_info->connectors[j].length = + CONNECTOR_SIZE_DVI; + break; + + case CONNECTOR_TYPE_HDMI: + slot_layout_info->connectors[j].connector_type = + CONNECTOR_LAYOUT_TYPE_HDMI; + slot_layout_info->connectors[j].length = + CONNECTOR_SIZE_HDMI; + break; + + case CONNECTOR_TYPE_DISPLAY_PORT: + slot_layout_info->connectors[j].connector_type = + CONNECTOR_LAYOUT_TYPE_DP; + slot_layout_info->connectors[j].length = + CONNECTOR_SIZE_DP; + break; + + case CONNECTOR_TYPE_MINI_DISPLAY_PORT: + slot_layout_info->connectors[j].connector_type = + CONNECTOR_LAYOUT_TYPE_MINI_DP; + slot_layout_info->connectors[j].length = + CONNECTOR_SIZE_MINI_DP; + break; + + default: + slot_layout_info->connectors[j].connector_type = + CONNECTOR_LAYOUT_TYPE_UNKNOWN; + slot_layout_info->connectors[j].length = + CONNECTOR_SIZE_UNKNOWN; + } + + slot_layout_info->connectors[j].position = + record->conn_info[j].position; + slot_layout_info->connectors[j].connector_id = + object_id_from_bios_object_id( + record->conn_info[j].connectorobjid); + } + return result; +} + + +static enum bp_result get_bracket_layout_record( + struct dc_bios *dcb, + unsigned int bracket_layout_id, + struct slot_layout_info *slot_layout_info) +{ + unsigned int i; + struct bios_parser *bp = BP_FROM_DCB(dcb); + enum bp_result result; + struct object_info_table *tbl; + struct display_object_info_table_v1_4 *v1_4; + + if (slot_layout_info == NULL) { + DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n"); + return BP_RESULT_BADINPUT; + } + tbl = &bp->object_info_tbl; + v1_4 = tbl->v1_4; + + result = BP_RESULT_NORECORD; + for (i = 0; i < v1_4->number_of_path; ++i) { + + if (bracket_layout_id == + v1_4->display_path[i].display_objid) { + result = update_slot_layout_info(dcb, i, + slot_layout_info); + break; + } + } + return result; +} + +static enum bp_result bios_get_board_layout_info( + struct dc_bios *dcb, + struct board_layout_info *board_layout_info) +{ + unsigned int i; + struct bios_parser *bp; + enum bp_result record_result; + + const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = { + GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1, + GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2, + 0, 0 + }; + + bp = BP_FROM_DCB(dcb); + if (board_layout_info == NULL) { + DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n"); + return BP_RESULT_BADINPUT; + } + + board_layout_info->num_of_slots = 0; + + for (i = 0; i < MAX_BOARD_SLOTS; ++i) { + record_result = get_bracket_layout_record(dcb, + slot_index_to_vbios_id[i], + &board_layout_info->slots[i]); + + if (record_result == BP_RESULT_NORECORD && i > 0) + break; /* no more slots present in bios */ + else if (record_result != BP_RESULT_OK) + return record_result; /* fail */ + + ++board_layout_info->num_of_slots; + } + + /* all data is valid */ + board_layout_info->is_number_of_slots_valid = 1; + board_layout_info->is_slots_size_valid = 1; + board_layout_info->is_connector_offsets_valid = 1; + board_layout_info->is_connector_lengths_valid = 1; + + return BP_RESULT_OK; +} + static const struct dc_vbios_funcs vbios_funcs = { .get_connectors_number = bios_parser_get_connectors_number, @@ -1925,6 +2139,8 @@ static const struct dc_vbios_funcs vbios_funcs = { .bios_parser_destroy = firmware_parser_destroy, .get_smu_clock_info = bios_parser_get_smu_clock_info, + + .get_board_layout_info = bios_get_board_layout_info, }; static bool bios_parser_construct( diff --git a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h index d9b84ec7954c..90082bab71f0 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h @@ -198,6 +198,10 @@ struct dc_vbios_funcs { void (*post_init)(struct dc_bios *bios); void (*bios_parser_destroy)(struct dc_bios **dcb); + + enum bp_result (*get_board_layout_info)( + struct dc_bios *dcb, + struct board_layout_info *board_layout_info); }; struct bios_registers { diff --git a/drivers/gpu/drm/amd/display/include/grph_object_defs.h b/drivers/gpu/drm/amd/display/include/grph_object_defs.h index 2941b882b0b6..58bb42ed85ca 100644 --- a/drivers/gpu/drm/amd/display/include/grph_object_defs.h +++ b/drivers/gpu/drm/amd/display/include/grph_object_defs.h @@ -37,6 +37,10 @@ * ******************************************************************** */ +#define MAX_CONNECTOR_NUMBER_PER_SLOT (16) +#define MAX_BOARD_SLOTS (4) +#define INVALID_CONNECTOR_INDEX ((unsigned int)(-1)) + /* HPD unit id - HW direct translation */ enum hpd_source_id { HPD_SOURCEID1 = 0, @@ -136,5 +140,47 @@ enum sync_source { SYNC_SOURCE_DUAL_GPU_PIN }; +/* connector sizes in millimeters - from BiosParserTypes.hpp */ +#define CONNECTOR_SIZE_DVI 40 +#define CONNECTOR_SIZE_VGA 32 +#define CONNECTOR_SIZE_HDMI 16 +#define CONNECTOR_SIZE_DP 16 +#define CONNECTOR_SIZE_MINI_DP 9 +#define CONNECTOR_SIZE_UNKNOWN 30 +enum connector_layout_type { + CONNECTOR_LAYOUT_TYPE_UNKNOWN, + CONNECTOR_LAYOUT_TYPE_DVI_D, + CONNECTOR_LAYOUT_TYPE_DVI_I, + CONNECTOR_LAYOUT_TYPE_VGA, + CONNECTOR_LAYOUT_TYPE_HDMI, + CONNECTOR_LAYOUT_TYPE_DP, + CONNECTOR_LAYOUT_TYPE_MINI_DP, +}; +struct connector_layout_info { + struct graphics_object_id connector_id; + enum connector_layout_type connector_type; + unsigned int length; + unsigned int position; /* offset in mm from right side of the board */ +}; + +/* length and width in mm */ +struct slot_layout_info { + unsigned int length; + unsigned int width; + unsigned int num_of_connectors; + struct connector_layout_info connectors[MAX_CONNECTOR_NUMBER_PER_SLOT]; +}; + +struct board_layout_info { + unsigned int num_of_slots; + + /* indicates valid information in bracket layout structure. */ + unsigned int is_number_of_slots_valid : 1; + unsigned int is_slots_size_valid : 1; + unsigned int is_connector_offsets_valid : 1; + unsigned int is_connector_lengths_valid : 1; + + struct slot_layout_info slots[MAX_BOARD_SLOTS]; +}; #endif diff --git a/drivers/gpu/drm/amd/display/include/grph_object_id.h b/drivers/gpu/drm/amd/display/include/grph_object_id.h index 92cc6c112ea6..33b3d755fe65 100644 --- a/drivers/gpu/drm/amd/display/include/grph_object_id.h +++ b/drivers/gpu/drm/amd/display/include/grph_object_id.h @@ -292,4 +292,15 @@ static inline enum engine_id dal_graphics_object_id_get_engine_id( return (enum engine_id) id.id; return ENGINE_ID_UNKNOWN; } + +static inline bool dal_graphics_object_id_equal( + struct graphics_object_id id_1, + struct graphics_object_id id_2) +{ + if ((id_1.id == id_2.id) && (id_1.enum_id == id_2.enum_id) && + (id_1.type == id_2.type)) { + return true; + } + return false; +} #endif From f3efec54ed6ac05ba63be1bd93bd741d41b6eb37 Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Fri, 8 Jun 2018 17:36:26 -0400 Subject: [PATCH 054/133] drm/amd/display: Allow option to use worst-case watermark use worse case watermark (consider both DCC and VM) to keep golden consistent regardless of DCC Signed-off-by: Tony Cheng Reviewed-by: Aric Cyr Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 23 ++++++++++++++++++- drivers/gpu/drm/amd/display/dc/dc.h | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 12261fbc25e0..e44b8d3d6891 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -31,6 +31,8 @@ #include "resource.h" #include "dcn10/dcn10_resource.h" +#include "dcn10/dcn10_hubbub.h" + #include "dcn_calc_math.h" #define DC_LOGGER \ @@ -889,7 +891,26 @@ bool dcn_validate_bandwidth( ASSERT(pipe->plane_res.scl_data.ratios.vert.value != dc_fixpt_one.value || v->scaler_rec_out_width[input_idx] == v->viewport_height[input_idx]); } - v->dcc_enable[input_idx] = pipe->plane_state->dcc.enable ? dcn_bw_yes : dcn_bw_no; + + if (dc->debug.optimized_watermark) { + /* + * this method requires us to always re-calculate watermark when dcc change + * between flip. + */ + v->dcc_enable[input_idx] = pipe->plane_state->dcc.enable ? dcn_bw_yes : dcn_bw_no; + } else { + /* + * allow us to disable dcc on the fly without re-calculating WM + * + * extra overhead for DCC is quite small. for 1080p WM without + * DCC is only 0.417us lower (urgent goes from 6.979us to 6.562us) + */ + unsigned int bpe; + + v->dcc_enable[input_idx] = dc->res_pool->hubbub->funcs->dcc_support_pixel_format( + pipe->plane_state->format, &bpe) ? dcn_bw_yes : dcn_bw_no; + } + v->source_pixel_format[input_idx] = tl_pixel_format_to_bw_defs( pipe->plane_state->format); v->source_surface_mode[input_idx] = tl_sw_mode_to_bw_defs( diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 74e6653b9852..0cb7e10d2505 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -233,6 +233,7 @@ struct dc_debug { int urgent_latency_ns; int percent_of_ideal_drambw; int dram_clock_change_latency_ns; + bool optimized_watermark; int always_scale; bool disable_pplib_clock_request; bool disable_clock_gate; From 180fc134d712a93a2bbc3d11ed657b5208e6f90f Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Tue, 5 Jun 2018 12:43:23 -0400 Subject: [PATCH 055/133] drm/scheduler: Rename cleanup functions v2. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Everything in the flush code path (i.e. waiting for SW queue to become empty) names with *_flush() and everything in the release code path names *_fini() This patch also effect the amdgpu and etnaviv drivers which use those functions. v2: Also pplay the change to vd3. Signed-off-by: Andrey Grodzovsky Suggested-by: Christian König Acked-by: Lucas Stach Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 8 ++++---- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 2 +- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 4 ++-- drivers/gpu/drm/scheduler/gpu_scheduler.c | 18 +++++++++--------- drivers/gpu/drm/v3d/v3d_drv.c | 2 +- include/drm/gpu_scheduler.h | 6 +++--- 11 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 64b3a1ed04dc..c0f06c02f2de 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -104,7 +104,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, failed: for (j = 0; j < i; j++) - drm_sched_entity_fini(&adev->rings[j]->sched, + drm_sched_entity_destroy(&adev->rings[j]->sched, &ctx->rings[j].entity); kfree(ctx->fences); ctx->fences = NULL; @@ -178,7 +178,7 @@ static void amdgpu_ctx_do_release(struct kref *ref) if (ctx->adev->rings[i] == &ctx->adev->gfx.kiq.ring) continue; - drm_sched_entity_fini(&ctx->adev->rings[i]->sched, + drm_sched_entity_destroy(&ctx->adev->rings[i]->sched, &ctx->rings[i].entity); } @@ -466,7 +466,7 @@ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr) if (ctx->adev->rings[i] == &ctx->adev->gfx.kiq.ring) continue; - max_wait = drm_sched_entity_do_release(&ctx->adev->rings[i]->sched, + max_wait = drm_sched_entity_flush(&ctx->adev->rings[i]->sched, &ctx->rings[i].entity, max_wait); } } @@ -492,7 +492,7 @@ void amdgpu_ctx_mgr_entity_cleanup(struct amdgpu_ctx_mgr *mgr) continue; if (kref_read(&ctx->refcount) == 1) - drm_sched_entity_cleanup(&ctx->adev->rings[i]->sched, + drm_sched_entity_fini(&ctx->adev->rings[i]->sched, &ctx->rings[i].entity); else DRM_ERROR("ctx %p is still alive\n", ctx); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 0c084d3d0865..0246cb87d9e4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -162,7 +162,7 @@ static int amdgpu_ttm_global_init(struct amdgpu_device *adev) static void amdgpu_ttm_global_fini(struct amdgpu_device *adev) { if (adev->mman.mem_global_referenced) { - drm_sched_entity_fini(adev->mman.entity.sched, + drm_sched_entity_destroy(adev->mman.entity.sched, &adev->mman.entity); mutex_destroy(&adev->mman.gtt_window_lock); drm_global_item_unref(&adev->mman.bo_global_ref.ref); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index cc15d3230402..0b46ea1c6290 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -309,7 +309,7 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { kfree(adev->uvd.inst[j].saved_bo); - drm_sched_entity_fini(&adev->uvd.inst[j].ring.sched, &adev->uvd.inst[j].entity); + drm_sched_entity_destroy(&adev->uvd.inst[j].ring.sched, &adev->uvd.inst[j].entity); amdgpu_bo_free_kernel(&adev->uvd.inst[j].vcpu_bo, &adev->uvd.inst[j].gpu_addr, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 23d960ec1cf2..b0dcdfd85f5b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -222,7 +222,7 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev) if (adev->vce.vcpu_bo == NULL) return 0; - drm_sched_entity_fini(&adev->vce.ring[0].sched, &adev->vce.entity); + drm_sched_entity_destroy(&adev->vce.ring[0].sched, &adev->vce.entity); amdgpu_bo_free_kernel(&adev->vce.vcpu_bo, &adev->vce.gpu_addr, (void **)&adev->vce.cpu_addr); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 590db78b8c72..837066076ccf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2643,7 +2643,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, vm->root.base.bo = NULL; error_free_sched_entity: - drm_sched_entity_fini(&ring->sched, &vm->entity); + drm_sched_entity_destroy(&ring->sched, &vm->entity); return r; } @@ -2780,7 +2780,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); } - drm_sched_entity_fini(vm->entity.sched, &vm->entity); + drm_sched_entity_destroy(vm->entity.sched, &vm->entity); if (!RB_EMPTY_ROOT(&vm->va.rb_root)) { dev_err(adev->dev, "still active bo inside vm\n"); diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index bfddf97dd13e..1df1c6115341 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -470,7 +470,7 @@ static int uvd_v6_0_sw_fini(void *handle) return r; if (uvd_v6_0_enc_support(adev)) { - drm_sched_entity_fini(&adev->uvd.inst->ring_enc[0].sched, &adev->uvd.inst->entity_enc); + drm_sched_entity_destroy(&adev->uvd.inst->ring_enc[0].sched, &adev->uvd.inst->entity_enc); for (i = 0; i < adev->uvd.num_enc_rings; ++i) amdgpu_ring_fini(&adev->uvd.inst->ring_enc[i]); diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index 57d32f21b3a6..ba244d3b74db 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c @@ -491,7 +491,7 @@ static int uvd_v7_0_sw_fini(void *handle) return r; for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { - drm_sched_entity_fini(&adev->uvd.inst[j].ring_enc[0].sched, &adev->uvd.inst[j].entity_enc); + drm_sched_entity_destroy(&adev->uvd.inst[j].ring_enc[0].sched, &adev->uvd.inst[j].entity_enc); for (i = 0; i < adev->uvd.num_enc_rings; ++i) amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index e5013a999147..45bfdf4cc107 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -78,8 +78,8 @@ static void etnaviv_postclose(struct drm_device *dev, struct drm_file *file) gpu->lastctx = NULL; mutex_unlock(&gpu->lock); - drm_sched_entity_fini(&gpu->sched, - &ctx->sched_entity[i]); + drm_sched_entity_destroy(&gpu->sched, + &ctx->sched_entity[i]); } } diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c b/drivers/gpu/drm/scheduler/gpu_scheduler.c index 6a316701da73..7d2560699b84 100644 --- a/drivers/gpu/drm/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c @@ -256,7 +256,7 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f, /** - * drm_sched_entity_do_release - Destroy a context entity + * drm_sched_entity_flush - Flush a context entity * * @sched: scheduler instance * @entity: scheduler entity @@ -267,7 +267,7 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f, * * Returns the remaining time in jiffies left from the input timeout */ -long drm_sched_entity_do_release(struct drm_gpu_scheduler *sched, +long drm_sched_entity_flush(struct drm_gpu_scheduler *sched, struct drm_sched_entity *entity, long timeout) { long ret = timeout; @@ -294,7 +294,7 @@ long drm_sched_entity_do_release(struct drm_gpu_scheduler *sched, return ret; } -EXPORT_SYMBOL(drm_sched_entity_do_release); +EXPORT_SYMBOL(drm_sched_entity_flush); /** * drm_sched_entity_cleanup - Destroy a context entity @@ -306,7 +306,7 @@ EXPORT_SYMBOL(drm_sched_entity_do_release); * entity and signals all jobs with an error code if the process was killed. * */ -void drm_sched_entity_cleanup(struct drm_gpu_scheduler *sched, +void drm_sched_entity_fini(struct drm_gpu_scheduler *sched, struct drm_sched_entity *entity) { @@ -357,7 +357,7 @@ void drm_sched_entity_cleanup(struct drm_gpu_scheduler *sched, dma_fence_put(entity->last_scheduled); entity->last_scheduled = NULL; } -EXPORT_SYMBOL(drm_sched_entity_cleanup); +EXPORT_SYMBOL(drm_sched_entity_fini); /** * drm_sched_entity_fini - Destroy a context entity @@ -367,13 +367,13 @@ EXPORT_SYMBOL(drm_sched_entity_cleanup); * * Calls drm_sched_entity_do_release() and drm_sched_entity_cleanup() */ -void drm_sched_entity_fini(struct drm_gpu_scheduler *sched, +void drm_sched_entity_destroy(struct drm_gpu_scheduler *sched, struct drm_sched_entity *entity) { - drm_sched_entity_do_release(sched, entity, MAX_WAIT_SCHED_ENTITY_Q_EMPTY); - drm_sched_entity_cleanup(sched, entity); + drm_sched_entity_flush(sched, entity, MAX_WAIT_SCHED_ENTITY_Q_EMPTY); + drm_sched_entity_fini(sched, entity); } -EXPORT_SYMBOL(drm_sched_entity_fini); +EXPORT_SYMBOL(drm_sched_entity_destroy); static void drm_sched_entity_wakeup(struct dma_fence *f, struct dma_fence_cb *cb) { diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index cdb582043b4f..567f7d46d912 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -151,7 +151,7 @@ v3d_postclose(struct drm_device *dev, struct drm_file *file) enum v3d_queue q; for (q = 0; q < V3D_MAX_QUEUES; q++) { - drm_sched_entity_fini(&v3d->queue[q].sched, + drm_sched_entity_destroy(&v3d->queue[q].sched, &v3d_priv->sched_entity[q]); } diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index 7c2dfd6cc1af..4214ceb71c05 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -284,12 +284,12 @@ int drm_sched_entity_init(struct drm_gpu_scheduler *sched, struct drm_sched_entity *entity, struct drm_sched_rq *rq, atomic_t *guilty); -long drm_sched_entity_do_release(struct drm_gpu_scheduler *sched, +long drm_sched_entity_flush(struct drm_gpu_scheduler *sched, struct drm_sched_entity *entity, long timeout); -void drm_sched_entity_cleanup(struct drm_gpu_scheduler *sched, - struct drm_sched_entity *entity); void drm_sched_entity_fini(struct drm_gpu_scheduler *sched, struct drm_sched_entity *entity); +void drm_sched_entity_destroy(struct drm_gpu_scheduler *sched, + struct drm_sched_entity *entity); void drm_sched_entity_push_job(struct drm_sched_job *sched_job, struct drm_sched_entity *entity); void drm_sched_entity_set_rq(struct drm_sched_entity *entity, From c49d82800bbf04a6d7d6843c6f2c2ea5746eb26e Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Tue, 5 Jun 2018 12:56:26 -0400 Subject: [PATCH 056/133] drm/amdgpu: Rename entity cleanup finctions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Everything in the flush code path (i.e. waiting for SW queue to become empty) names with *_flush() and everything in the release code path names *_fini() Signed-off-by: Andrey Grodzovsky Suggested-by: Christian König Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 6 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index fb17838114c3..86e4d8bd52a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -683,8 +683,8 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx, unsigned ring_id); void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr); -void amdgpu_ctx_mgr_entity_cleanup(struct amdgpu_ctx_mgr *mgr); void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr); +void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr); void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index c0f06c02f2de..0120b24fae1b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -444,7 +444,7 @@ void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr) idr_init(&mgr->ctx_handles); } -void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr) +void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr) { struct amdgpu_ctx *ctx; struct idr *idp; @@ -473,7 +473,7 @@ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr) mutex_unlock(&mgr->lock); } -void amdgpu_ctx_mgr_entity_cleanup(struct amdgpu_ctx_mgr *mgr) +void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr) { struct amdgpu_ctx *ctx; struct idr *idp; @@ -506,7 +506,7 @@ void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr) struct idr *idp; uint32_t id; - amdgpu_ctx_mgr_entity_cleanup(mgr); + amdgpu_ctx_mgr_entity_fini(mgr); idp = &mgr->ctx_handles; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index a549483032b0..684149741427 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -860,7 +860,7 @@ static int amdgpu_flush(struct file *f, fl_owner_t id) struct drm_file *file_priv = f->private_data; struct amdgpu_fpriv *fpriv = file_priv->driver_priv; - amdgpu_ctx_mgr_entity_fini(&fpriv->ctx_mgr); + amdgpu_ctx_mgr_entity_flush(&fpriv->ctx_mgr); return 0; } From d6258eaa41fc531277d44fbbee670c866025bfdc Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Sun, 17 Jun 2018 10:53:38 +0200 Subject: [PATCH 057/133] drm/amd/display: don't initialize result The wrong enum type is used to initialize the result, leading to a warning when using clang: drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_link_dp.c:1998:26: warning: implicit conversion from enumeration type 'enum ddc_result' to different enumeration type 'enum dc_status' [-Wenum-conversion] enum dc_status result = DDC_RESULT_UNKNOWN; ~~~~~~ ^~~~~~~~~~~~~~~~~~ 1 warning generated. Initialization of result is unnecessary anyway, just drop the initialization. Signed-off-by: Stefan Agner Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 049fc5cce1d2..84586b679d73 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -2000,7 +2000,7 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd { union hpd_irq_data hpd_irq_dpcd_data = {{{{0}}}}; union device_service_irq device_service_clear = { { 0 } }; - enum dc_status result = DDC_RESULT_UNKNOWN; + enum dc_status result; bool status = false; /* For use cases related to down stream connection status change, * PSR and device auto test, refer to function handle_sst_hpd_irq From cc450654291bb40c2d67a04d7e2fb42bff7e162a Mon Sep 17 00:00:00 2001 From: Flora Cui Date: Wed, 27 Jun 2018 13:53:53 +0800 Subject: [PATCH 058/133] drm/amdgpu: remove duplicated codes the fence_context and seqno is init in amdgpu_vm_manager_init() & amdgpu_vmid_mgr_init(). remove the amdgpu_vmid_mgr_init() copy. Signed-off-by: Flora Cui Reviewed-by: Junwei Zhang Reviewed-by: Chunming Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c index a1c78f90eadf..3a072a7a39f0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c @@ -578,11 +578,6 @@ void amdgpu_vmid_mgr_init(struct amdgpu_device *adev) list_add_tail(&id_mgr->ids[j].list, &id_mgr->ids_lru); } } - - adev->vm_manager.fence_context = - dma_fence_context_alloc(AMDGPU_MAX_RINGS); - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) - adev->vm_manager.seqno[i] = 0; } /** From f0626896bb2f09e8ce6438f380ac7f6511b72f84 Mon Sep 17 00:00:00 2001 From: rex zhu Date: Wed, 27 Jun 2018 17:35:40 +0800 Subject: [PATCH 059/133] drm/amd/display: Drop unnecessary header file powerplay implement hwmgr_function table for all supported asics in order to conceal the asic's detail infomation. so no need to include the smu10_hwmgr.h. Reviewed-by: Alex Deucher Reviewed-by: Harry Wentland Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 1 - 1 file changed, 1 deletion(-) 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 ad96e2a2b3cf..2acbcc7a9412 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 @@ -34,7 +34,6 @@ #include "amdgpu_pm.h" #include "dm_pp_smu.h" #include "../../powerplay/inc/hwmgr.h" -#include "../../powerplay/hwmgr/smu10_hwmgr.h" bool dm_pp_apply_display_requirements( From 66917e56dcfe8d2ba00f2d86c7dfbf953e0604ae Mon Sep 17 00:00:00 2001 From: rex zhu Date: Wed, 27 Jun 2018 17:34:37 +0800 Subject: [PATCH 060/133] drm/amd/display: Fix dm-pp clks type convert error fix a typo when convert displayphyclk type. Reviewed-by: Alex Deucher Reviewed-by: Harry Wentland Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 3 +++ 1 file changed, 3 insertions(+) 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 2acbcc7a9412..cf92d7a24f33 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 @@ -167,6 +167,9 @@ static enum amd_pp_clock_type dc_to_pp_clock_type( amd_pp_clk_type = amd_pp_f_clock; break; case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: + amd_pp_clk_type = amd_pp_phy_clock; + break; + case DM_PP_CLOCK_TYPE_DPPCLK: amd_pp_clk_type = amd_pp_dpp_clock; break; default: From a8da8ff3332b1f92588d22a8a643965409d1892d Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 5 Jun 2018 10:07:53 +0800 Subject: [PATCH 061/133] drm/amdgpu: Rename set_mmhub_powergating_by_smu to powergate_mmhub In order to keep consistent with powergate_uvd/vce. Reviewed-by: Evan Quan Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h | 4 ++-- drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c | 4 ++-- drivers/gpu/drm/amd/include/kgd_pp_interface.h | 2 +- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 8 ++++---- drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 4 ++-- drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h index 9acfbee91c40..c6d692625687 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h @@ -359,8 +359,8 @@ enum amdgpu_pcie_gen { ((adev)->powerplay.pp_funcs->odn_edit_dpm_table(\ (adev)->powerplay.pp_handle, type, parameter, size)) -#define amdgpu_dpm_set_mmhub_powergating_by_smu(adev) \ - ((adev)->powerplay.pp_funcs->set_mmhub_powergating_by_smu( \ +#define amdgpu_dpm_powergate_mmhub(adev) \ + ((adev)->powerplay.pp_funcs->powergate_mmhub( \ (adev)->powerplay.pp_handle)) struct amdgpu_dpm { diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c index 3d53c4413f13..377f5362a3df 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c @@ -471,8 +471,8 @@ void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev, RENG_EXECUTE_ON_REG_UPDATE, 1); WREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_EXECUTE, pctl1_reng_execute); - if (adev->powerplay.pp_funcs->set_mmhub_powergating_by_smu) - amdgpu_dpm_set_mmhub_powergating_by_smu(adev); + if (adev->powerplay.pp_funcs->powergate_mmhub) + amdgpu_dpm_powergate_mmhub(adev); } else { pctl0_reng_execute = REG_SET_FIELD(pctl0_reng_execute, diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 06f08f34a110..0f9886298a84 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -269,7 +269,7 @@ struct amd_pm_funcs { int (*get_power_profile_mode)(void *handle, char *buf); int (*set_power_profile_mode)(void *handle, long *input, uint32_t size); int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size); - int (*set_mmhub_powergating_by_smu)(void *handle); + int (*powergate_mmhub)(void *handle); }; #endif diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index d567be49c31b..da98208cd130 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -1168,19 +1168,19 @@ static int pp_get_display_mode_validation_clocks(void *handle, return ret; } -static int pp_set_mmhub_powergating_by_smu(void *handle) +static int pp_dpm_powergate_mmhub(void *handle) { struct pp_hwmgr *hwmgr = handle; if (!hwmgr || !hwmgr->pm_en) return -EINVAL; - if (hwmgr->hwmgr_func->set_mmhub_powergating_by_smu == NULL) { + if (hwmgr->hwmgr_func->powergate_mmhub == NULL) { pr_info("%s was not implemented.\n", __func__); return 0; } - return hwmgr->hwmgr_func->set_mmhub_powergating_by_smu(hwmgr); + return hwmgr->hwmgr_func->powergate_mmhub(hwmgr); } static const struct amd_pm_funcs pp_dpm_funcs = { @@ -1227,5 +1227,5 @@ static const struct amd_pm_funcs pp_dpm_funcs = { .set_watermarks_for_clocks_ranges = pp_set_watermarks_for_clocks_ranges, .display_clock_voltage_request = pp_display_clock_voltage_request, .get_display_mode_validation_clocks = pp_get_display_mode_validation_clocks, - .set_mmhub_powergating_by_smu = pp_set_mmhub_powergating_by_smu, + .powergate_mmhub = pp_dpm_powergate_mmhub, }; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c index d4bc83e81389..0f8352cf6567 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c @@ -1126,7 +1126,7 @@ static int smu10_smus_notify_pwe(struct pp_hwmgr *hwmgr) return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_SetRccPfcPmeRestoreRegister); } -static int smu10_set_mmhub_powergating_by_smu(struct pp_hwmgr *hwmgr) +static int smu10_powergate_mmhub(struct pp_hwmgr *hwmgr) { return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerGateMmHub); } @@ -1182,7 +1182,7 @@ static const struct pp_hwmgr_func smu10_hwmgr_funcs = { .asic_setup = smu10_setup_asic_task, .power_state_set = smu10_set_power_state_tasks, .dynamic_state_management_disable = smu10_disable_dpm_tasks, - .set_mmhub_powergating_by_smu = smu10_set_mmhub_powergating_by_smu, + .powergate_mmhub = smu10_powergate_mmhub, .smus_notify_pwe = smu10_smus_notify_pwe, .gfx_off_control = smu10_gfx_off_control, .display_clock_voltage_request = smu10_display_clock_voltage_request, diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 40c98ca5feb7..9b07d6e14ec6 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -327,7 +327,7 @@ struct pp_hwmgr_func { enum PP_OD_DPM_TABLE_COMMAND type, long *input, uint32_t size); int (*set_power_limit)(struct pp_hwmgr *hwmgr, uint32_t n); - int (*set_mmhub_powergating_by_smu)(struct pp_hwmgr *hwmgr); + int (*powergate_mmhub)(struct pp_hwmgr *hwmgr); int (*smus_notify_pwe)(struct pp_hwmgr *hwmgr); }; From 3eb6e4795de3171d5c59f9368f48bb770087de77 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 5 Jun 2018 11:28:03 +0800 Subject: [PATCH 062/133] drm/amd/pp: Rename enable_per_cu_power_gating to powergate_gfx keep consistent with powergate_uvd/vce/mmhub Reviewed-by: Evan Quan Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 6 +++--- drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c | 2 +- drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.h | 2 +- drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 2 +- drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index da98208cd130..b69da116b30c 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -236,13 +236,13 @@ static int pp_set_powergating_state(void *handle, pr_err("gfx off control failed!\n"); } - if (hwmgr->hwmgr_func->enable_per_cu_power_gating == NULL) { - pr_debug("%s was not implemented.\n", __func__); + if (hwmgr->hwmgr_func->powergate_gfx == NULL) { + pr_info("%s was not implemented.\n", __func__); return 0; } /* Enable/disable GFX per cu powergating through SMU */ - return hwmgr->hwmgr_func->enable_per_cu_power_gating(hwmgr, + return hwmgr->hwmgr_func->powergate_gfx(hwmgr, state == AMD_PG_STATE_GATE); } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c index 41495621d94a..683b29a99366 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c @@ -416,7 +416,7 @@ int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr, * Powerplay will only control the static per CU Power Gating. * Dynamic per CU Power Gating will be done in gfx. */ -int smu7_enable_per_cu_power_gating(struct pp_hwmgr *hwmgr, bool enable) +int smu7_powergate_gfx(struct pp_hwmgr *hwmgr, bool enable) { struct amdgpu_device *adev = hwmgr->adev; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.h b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.h index be7f66d2b234..fc8f8a6acc72 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.h @@ -33,6 +33,6 @@ int smu7_powergate_acp(struct pp_hwmgr *hwmgr, bool bgate); int smu7_disable_clock_power_gating(struct pp_hwmgr *hwmgr); int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr, const uint32_t *msg_id); -int smu7_enable_per_cu_power_gating(struct pp_hwmgr *hwmgr, bool enable); +int smu7_powergate_gfx(struct pp_hwmgr *hwmgr, bool enable); #endif diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index b89d6fb8559b..de295b7442b7 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -5044,7 +5044,7 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = { .get_fan_control_mode = smu7_get_fan_control_mode, .force_clock_level = smu7_force_clock_level, .print_clock_levels = smu7_print_clock_levels, - .enable_per_cu_power_gating = smu7_enable_per_cu_power_gating, + .powergate_gfx = smu7_powergate_gfx, .get_sclk_od = smu7_get_sclk_od, .set_sclk_od = smu7_set_sclk_od, .get_mclk_od = smu7_get_mclk_od, diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 9b07d6e14ec6..95e29a22e445 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -302,7 +302,7 @@ struct pp_hwmgr_func { int (*power_off_asic)(struct pp_hwmgr *hwmgr); int (*force_clock_level)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, uint32_t mask); int (*print_clock_levels)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, char *buf); - int (*enable_per_cu_power_gating)(struct pp_hwmgr *hwmgr, bool enable); + int (*powergate_gfx)(struct pp_hwmgr *hwmgr, bool enable); int (*get_sclk_od)(struct pp_hwmgr *hwmgr); int (*set_sclk_od)(struct pp_hwmgr *hwmgr, uint32_t value); int (*get_mclk_od)(struct pp_hwmgr *hwmgr); From b92c628712ed3a1cf5d4a144290e8ffc170bf51e Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 5 Jun 2018 13:06:11 +0800 Subject: [PATCH 063/133] drm/amd/pp: Unify powergate_uvd/vce/mmhub to set_powergating_by_smu Some HW ip blocks need call SMU to enter/leave power gate state. So export common set_powergating_by_smu interface. 1. keep consistent with set_clockgating_by_smu 2. scales easily to powergate other ip(gfx) if necessary Reviewed-by: Evan Quan Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h | 14 +++------ drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 8 ++--- drivers/gpu/drm/amd/amdgpu/ci_dpm.c | 15 +++++++++- drivers/gpu/drm/amd/amdgpu/kv_dpm.c | 15 +++++++++- drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c | 4 +-- .../gpu/drm/amd/include/kgd_pp_interface.h | 5 ++-- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 29 +++++++++++++++++-- 7 files changed, 66 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h index c6d692625687..ff24e1cc5b65 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h @@ -287,12 +287,6 @@ enum amdgpu_pcie_gen { #define amdgpu_dpm_force_performance_level(adev, l) \ ((adev)->powerplay.pp_funcs->force_performance_level((adev)->powerplay.pp_handle, (l))) -#define amdgpu_dpm_powergate_uvd(adev, g) \ - ((adev)->powerplay.pp_funcs->powergate_uvd((adev)->powerplay.pp_handle, (g))) - -#define amdgpu_dpm_powergate_vce(adev, g) \ - ((adev)->powerplay.pp_funcs->powergate_vce((adev)->powerplay.pp_handle, (g))) - #define amdgpu_dpm_get_current_power_state(adev) \ ((adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle)) @@ -347,6 +341,10 @@ enum amdgpu_pcie_gen { ((adev)->powerplay.pp_funcs->set_clockgating_by_smu(\ (adev)->powerplay.pp_handle, msg_id)) +#define amdgpu_dpm_set_powergating_by_smu(adev, block_type, gate) \ + ((adev)->powerplay.pp_funcs->set_powergating_by_smu(\ + (adev)->powerplay.pp_handle, block_type, gate)) + #define amdgpu_dpm_get_power_profile_mode(adev, buf) \ ((adev)->powerplay.pp_funcs->get_power_profile_mode(\ (adev)->powerplay.pp_handle, buf)) @@ -359,10 +357,6 @@ enum amdgpu_pcie_gen { ((adev)->powerplay.pp_funcs->odn_edit_dpm_table(\ (adev)->powerplay.pp_handle, type, parameter, size)) -#define amdgpu_dpm_powergate_mmhub(adev) \ - ((adev)->powerplay.pp_funcs->powergate_mmhub( \ - (adev)->powerplay.pp_handle)) - struct amdgpu_dpm { struct amdgpu_ps *ps; /* number of valid power states */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index fdb399821915..a003fd881a89 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1729,10 +1729,10 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev) void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) { - if (adev->powerplay.pp_funcs->powergate_uvd) { + if (adev->powerplay.pp_funcs->set_powergating_by_smu) { /* enable/disable UVD */ mutex_lock(&adev->pm.mutex); - amdgpu_dpm_powergate_uvd(adev, !enable); + amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable); mutex_unlock(&adev->pm.mutex); } else { if (enable) { @@ -1751,10 +1751,10 @@ void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable) { - if (adev->powerplay.pp_funcs->powergate_vce) { + if (adev->powerplay.pp_funcs->set_powergating_by_smu) { /* enable/disable VCE */ mutex_lock(&adev->pm.mutex); - amdgpu_dpm_powergate_vce(adev, !enable); + amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable); mutex_unlock(&adev->pm.mutex); } else { if (enable) { diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index c9d45cffca56..7c4ff71e7476 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c @@ -6767,6 +6767,19 @@ static int ci_dpm_read_sensor(void *handle, int idx, } } +static int ci_set_powergating_by_smu(void *handle, + uint32_t block_type, bool gate) +{ + switch (block_type) { + case AMD_IP_BLOCK_TYPE_UVD: + ci_dpm_powergate_uvd(handle, gate); + break; + default: + break; + } + return 0; +} + static const struct amd_ip_funcs ci_dpm_ip_funcs = { .name = "ci_dpm", .early_init = ci_dpm_early_init, @@ -6804,7 +6817,7 @@ static const struct amd_pm_funcs ci_dpm_funcs = { .debugfs_print_current_performance_level = &ci_dpm_debugfs_print_current_performance_level, .force_performance_level = &ci_dpm_force_performance_level, .vblank_too_short = &ci_dpm_vblank_too_short, - .powergate_uvd = &ci_dpm_powergate_uvd, + .set_powergating_by_smu = &ci_set_powergating_by_smu, .set_fan_control_mode = &ci_dpm_set_fan_control_mode, .get_fan_control_mode = &ci_dpm_get_fan_control_mode, .set_fan_speed_percent = &ci_dpm_set_fan_speed_percent, diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index 46de1fd18a7b..3f57f6463dc8 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c @@ -3306,6 +3306,19 @@ static int kv_dpm_read_sensor(void *handle, int idx, } } +static int kv_set_powergating_by_smu(void *handle, + uint32_t block_type, bool gate) +{ + switch (block_type) { + case AMD_IP_BLOCK_TYPE_UVD: + kv_dpm_powergate_uvd(handle, gate); + break; + default: + break; + } + return 0; +} + static const struct amd_ip_funcs kv_dpm_ip_funcs = { .name = "kv_dpm", .early_init = kv_dpm_early_init, @@ -3342,7 +3355,7 @@ static const struct amd_pm_funcs kv_dpm_funcs = { .print_power_state = &kv_dpm_print_power_state, .debugfs_print_current_performance_level = &kv_dpm_debugfs_print_current_performance_level, .force_performance_level = &kv_dpm_force_performance_level, - .powergate_uvd = &kv_dpm_powergate_uvd, + .set_powergating_by_smu = kv_set_powergating_by_smu, .enable_bapm = &kv_dpm_enable_bapm, .get_vce_clock_state = amdgpu_get_vce_clock_state, .check_state_equal = kv_check_state_equal, diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c index 377f5362a3df..e70a0d4d6db4 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c @@ -471,8 +471,8 @@ void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev, RENG_EXECUTE_ON_REG_UPDATE, 1); WREG32_SOC15(MMHUB, 0, mmPCTL1_RENG_EXECUTE, pctl1_reng_execute); - if (adev->powerplay.pp_funcs->powergate_mmhub) - amdgpu_dpm_powergate_mmhub(adev); + if (adev->powerplay.pp_funcs->set_powergating_by_smu) + amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GMC, true); } else { pctl0_reng_execute = REG_SET_FIELD(pctl0_reng_execute, diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 0f9886298a84..4535756428f9 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -232,13 +232,13 @@ struct amd_pm_funcs { void (*debugfs_print_current_performance_level)(void *handle, struct seq_file *m); int (*switch_power_profile)(void *handle, enum PP_SMC_POWER_PROFILE type, bool en); /* export to amdgpu */ - void (*powergate_uvd)(void *handle, bool gate); - void (*powergate_vce)(void *handle, bool gate); struct amd_vce_state *(*get_vce_clock_state)(void *handle, u32 idx); int (*dispatch_tasks)(void *handle, enum amd_pp_task task_id, enum amd_pm_state_type *user_state); int (*load_firmware)(void *handle); int (*wait_for_fw_loading_complete)(void *handle); + int (*set_powergating_by_smu)(void *handle, + uint32_t block_type, bool gate); int (*set_clockgating_by_smu)(void *handle, uint32_t msg_id); int (*set_power_limit)(void *handle, uint32_t n); int (*get_power_limit)(void *handle, uint32_t *limit, bool default_limit); @@ -269,7 +269,6 @@ struct amd_pm_funcs { int (*get_power_profile_mode)(void *handle, char *buf); int (*set_power_profile_mode)(void *handle, long *input, uint32_t size); int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size); - int (*powergate_mmhub)(void *handle); }; #endif diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index b69da116b30c..f68551ffb1e2 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -244,6 +244,7 @@ static int pp_set_powergating_state(void *handle, /* Enable/disable GFX per cu powergating through SMU */ return hwmgr->hwmgr_func->powergate_gfx(hwmgr, state == AMD_PG_STATE_GATE); + } static int pp_suspend(void *handle) @@ -1183,14 +1184,36 @@ static int pp_dpm_powergate_mmhub(void *handle) return hwmgr->hwmgr_func->powergate_mmhub(hwmgr); } +static int pp_set_powergating_by_smu(void *handle, + uint32_t block_type, bool gate) +{ + int ret = 0; + + switch (block_type) { + case AMD_IP_BLOCK_TYPE_UVD: + case AMD_IP_BLOCK_TYPE_VCN: + pp_dpm_powergate_uvd(handle, gate); + break; + case AMD_IP_BLOCK_TYPE_VCE: + pp_dpm_powergate_vce(handle, gate); + break; + case AMD_IP_BLOCK_TYPE_GMC: + pp_dpm_powergate_mmhub(handle); + break; + case AMD_IP_BLOCK_TYPE_GFX: + break; + default: + break; + } + return ret; +} + static const struct amd_pm_funcs pp_dpm_funcs = { .load_firmware = pp_dpm_load_fw, .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete, .force_performance_level = pp_dpm_force_performance_level, .get_performance_level = pp_dpm_get_performance_level, .get_current_power_state = pp_dpm_get_current_power_state, - .powergate_vce = pp_dpm_powergate_vce, - .powergate_uvd = pp_dpm_powergate_uvd, .dispatch_tasks = pp_dpm_dispatch_tasks, .set_fan_control_mode = pp_dpm_set_fan_control_mode, .get_fan_control_mode = pp_dpm_get_fan_control_mode, @@ -1210,6 +1233,7 @@ static const struct amd_pm_funcs pp_dpm_funcs = { .get_vce_clock_state = pp_dpm_get_vce_clock_state, .switch_power_profile = pp_dpm_switch_power_profile, .set_clockgating_by_smu = pp_set_clockgating_by_smu, + .set_powergating_by_smu = pp_set_powergating_by_smu, .get_power_profile_mode = pp_get_power_profile_mode, .set_power_profile_mode = pp_set_power_profile_mode, .odn_edit_dpm_table = pp_odn_edit_dpm_table, @@ -1227,5 +1251,4 @@ static const struct amd_pm_funcs pp_dpm_funcs = { .set_watermarks_for_clocks_ranges = pp_set_watermarks_for_clocks_ranges, .display_clock_voltage_request = pp_display_clock_voltage_request, .get_display_mode_validation_clocks = pp_get_display_mode_validation_clocks, - .powergate_mmhub = pp_dpm_powergate_mmhub, }; From 85f80cb3af10f5daf79eee28300c3bbc55a70666 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Thu, 14 Jun 2018 13:07:19 +0800 Subject: [PATCH 064/133] drm/amd/pp: Add gfx pg support in smu through set_powergating_by_smu gfx ip block can call set_powergating_by_smu to set gfx pg state if necessary. Reviewed-by: Evan Quan Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 10 +++----- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 25 +++++++++++++------ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 4201f3dfaece..e69fbc944956 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -5606,14 +5606,12 @@ static int gfx_v8_0_late_init(void *handle) static void gfx_v8_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *adev, bool enable) { - if ((adev->asic_type == CHIP_POLARIS11) || + if (((adev->asic_type == CHIP_POLARIS11) || (adev->asic_type == CHIP_POLARIS12) || - (adev->asic_type == CHIP_VEGAM)) + (adev->asic_type == CHIP_VEGAM)) && + adev->powerplay.pp_funcs->set_powergating_by_smu) /* Send msg to SMU via Powerplay */ - amdgpu_device_ip_set_powergating_state(adev, - AMD_IP_BLOCK_TYPE_SMC, - enable ? - AMD_PG_STATE_GATE : AMD_PG_STATE_UNGATE); + amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, enable); WREG32_FIELD(RLC_PG_CNTL, STATIC_PER_CU_PG_ENABLE, enable ? 1 : 0); } diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index f68551ffb1e2..ef4884b0ddff 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -236,14 +236,7 @@ static int pp_set_powergating_state(void *handle, pr_err("gfx off control failed!\n"); } - if (hwmgr->hwmgr_func->powergate_gfx == NULL) { - pr_info("%s was not implemented.\n", __func__); - return 0; - } - - /* Enable/disable GFX per cu powergating through SMU */ - return hwmgr->hwmgr_func->powergate_gfx(hwmgr, - state == AMD_PG_STATE_GATE); + return 0; } @@ -1184,6 +1177,21 @@ static int pp_dpm_powergate_mmhub(void *handle) return hwmgr->hwmgr_func->powergate_mmhub(hwmgr); } +static int pp_dpm_powergate_gfx(void *handle, bool gate) +{ + struct pp_hwmgr *hwmgr = handle; + + if (!hwmgr || !hwmgr->pm_en) + return 0; + + if (hwmgr->hwmgr_func->powergate_gfx == NULL) { + pr_info("%s was not implemented.\n", __func__); + return 0; + } + + return hwmgr->hwmgr_func->powergate_gfx(hwmgr, gate); +} + static int pp_set_powergating_by_smu(void *handle, uint32_t block_type, bool gate) { @@ -1201,6 +1209,7 @@ static int pp_set_powergating_by_smu(void *handle, pp_dpm_powergate_mmhub(handle); break; case AMD_IP_BLOCK_TYPE_GFX: + ret = pp_dpm_powergate_gfx(handle, gate); break; default: break; From a214e1c415e70f5cbc7835180cb9ed5c8e4aa35e Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 5 Jun 2018 13:55:04 +0800 Subject: [PATCH 065/133] drm/amd/pp: Add powergate_gfx backend function on Raven Raven support gfx off feature instand of gfx powergate, so use smu10_gfx_off_control as the powergate_gfx backend function. Reviewed-by: Evan Quan Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c index 0f8352cf6567..0bbf11d464dd 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c @@ -1186,6 +1186,7 @@ static const struct pp_hwmgr_func smu10_hwmgr_funcs = { .smus_notify_pwe = smu10_smus_notify_pwe, .gfx_off_control = smu10_gfx_off_control, .display_clock_voltage_request = smu10_display_clock_voltage_request, + .powergate_gfx = smu10_gfx_off_control, }; int smu10_init_function_pointers(struct pp_hwmgr *hwmgr) From 9134c6d7f288f902d932e7cf57fab2f49e8ad70b Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 5 Jun 2018 11:46:35 +0800 Subject: [PATCH 066/133] drm/amdgpu: Add gfx_off support in smu through pp_set_powergating_by_smu we can take gfx off feature as gfx power gate. gfx off feature is also controled by smu. so add gfx_off support in pp_set_powergating_by_smu. Reviewed-by: Evan Quan Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 19 +++++++------------ drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 4 ++++ drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 16 ---------------- 3 files changed, 11 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index d82d0d314285..c33a41ace028 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1730,16 +1730,11 @@ static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev) } } - if (adev->powerplay.pp_feature & PP_GFXOFF_MASK) { + if (adev->powerplay.pp_feature & PP_GFXOFF_MASK) /* enable gfx powergating */ amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_GFX, AMD_PG_STATE_GATE); - /* enable gfxoff */ - amdgpu_device_ip_set_powergating_state(adev, - AMD_IP_BLOCK_TYPE_SMC, - AMD_PG_STATE_GATE); - } return 0; } @@ -1812,6 +1807,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) adev->ip_blocks[i].version->funcs->name, r); return r; } + if (adev->powerplay.pp_funcs->set_powergating_by_smu) + amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false); r = adev->ip_blocks[i].version->funcs->hw_fini((void *)adev); /* XXX handle errors */ if (r) { @@ -1921,12 +1918,6 @@ int amdgpu_device_ip_suspend(struct amdgpu_device *adev) if (amdgpu_sriov_vf(adev)) amdgpu_virt_request_full_gpu(adev, false); - /* ungate SMC block powergating */ - if (adev->powerplay.pp_feature & PP_GFXOFF_MASK) - amdgpu_device_ip_set_powergating_state(adev, - AMD_IP_BLOCK_TYPE_SMC, - AMD_PG_STATE_UNGATE); - /* ungate SMC block first */ r = amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_SMC, AMD_CG_STATE_UNGATE); @@ -1934,6 +1925,10 @@ int amdgpu_device_ip_suspend(struct amdgpu_device *adev) DRM_ERROR("set_clockgating_state(ungate) SMC failed %d\n", r); } + /* call smu to disable gfx off feature first when suspend */ + if (adev->powerplay.pp_funcs->set_powergating_by_smu) + amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false); + for (i = adev->num_ip_blocks - 1; i >= 0; i--) { if (!adev->ip_blocks[i].status.valid) continue; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index a69153435ea7..ac46eabe3bcd 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -3714,6 +3714,10 @@ static int gfx_v9_0_set_powergating_state(void *handle, /* update mgcg state */ gfx_v9_0_update_gfx_mg_power_gating(adev, enable); + + /* set gfx off through smu */ + if (enable && adev->powerplay.pp_funcs->set_powergating_by_smu) + amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true); break; default: break; diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index ef4884b0ddff..387a1eb6678d 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -221,23 +221,7 @@ static int pp_sw_reset(void *handle) static int pp_set_powergating_state(void *handle, enum amd_powergating_state state) { - struct amdgpu_device *adev = handle; - struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; - int ret; - - if (!hwmgr || !hwmgr->pm_en) - return 0; - - if (hwmgr->hwmgr_func->gfx_off_control) { - /* Enable/disable GFX off through SMU */ - ret = hwmgr->hwmgr_func->gfx_off_control(hwmgr, - state == AMD_PG_STATE_GATE); - if (ret) - pr_err("gfx off control failed!\n"); - } - return 0; - } static int pp_suspend(void *handle) From c9f96fd5063150dce7e71ecc508989f5ff055039 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 13 Jun 2018 19:30:40 +0800 Subject: [PATCH 067/133] drm/amdgpu: Split set_pg_state into separate function 1. add amdgpu_device_ip_late_set_pg_state function for set pg state. 2. delete duplicate pg state setting on gfx_v8_0's late_init. Reviewed-by: Evan Quan Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 33 ++++++++++++++++++---- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 4 --- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index c33a41ace028..e38564e7c5ec 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1730,12 +1730,34 @@ static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev) } } - if (adev->powerplay.pp_feature & PP_GFXOFF_MASK) - /* enable gfx powergating */ - amdgpu_device_ip_set_powergating_state(adev, - AMD_IP_BLOCK_TYPE_GFX, - AMD_PG_STATE_GATE); + return 0; +} +static int amdgpu_device_ip_late_set_pg_state(struct amdgpu_device *adev) +{ + int i = 0, r; + + if (amdgpu_emu_mode == 1) + return 0; + + for (i = 0; i < adev->num_ip_blocks; i++) { + if (!adev->ip_blocks[i].status.valid) + continue; + /* skip CG for VCE/UVD, it's handled specially */ + if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && + adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE && + adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCN && + adev->ip_blocks[i].version->funcs->set_powergating_state) { + /* enable powergating to save power */ + r = adev->ip_blocks[i].version->funcs->set_powergating_state((void *)adev, + AMD_PG_STATE_GATE); + if (r) { + DRM_ERROR("set_powergating_state(gate) of IP block <%s> failed %d\n", + adev->ip_blocks[i].version->funcs->name, r); + return r; + } + } + } return 0; } @@ -1898,6 +1920,7 @@ static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work) struct amdgpu_device *adev = container_of(work, struct amdgpu_device, late_init_work.work); amdgpu_device_ip_late_set_cg_state(adev); + amdgpu_device_ip_late_set_pg_state(adev); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index e69fbc944956..551f21bad6d3 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -5596,10 +5596,6 @@ static int gfx_v8_0_late_init(void *handle) return r; } - amdgpu_device_ip_set_powergating_state(adev, - AMD_IP_BLOCK_TYPE_GFX, - AMD_PG_STATE_GATE); - return 0; } From 916ac57ffbe952c02fcd883dee28970e39366eca Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 6 Jun 2018 13:42:42 +0800 Subject: [PATCH 068/133] drm/amdgpu: Move CG/PG setting out of delay worker thread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Partially revert commit 2dc80b00652f ("drm/amdgpu: optimize amdgpu driver load & resume time")' 1. CG/PG enablement are part of gpu hw ip initialize, we should wait for them complete. otherwise, there are some potential conflicts, for example, Suspend and CG enablement concurrently. 2. better run ib test after hw initialize completely. That is to say, ib test should be after CG/PG enablement. otherwise, the test will not cover the cg/pg/poweroff enable case. Reviewed-by: Evan Quan Reviewed-by: Christian König Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index e38564e7c5ec..c35db859f050 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1707,10 +1707,6 @@ static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev) if (amdgpu_emu_mode == 1) return 0; - r = amdgpu_ib_ring_tests(adev); - if (r) - DRM_ERROR("ib ring test failed (%d).\n", r); - for (i = 0; i < adev->num_ip_blocks; i++) { if (!adev->ip_blocks[i].status.valid) continue; @@ -1791,6 +1787,9 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev) } } + amdgpu_device_ip_late_set_cg_state(adev); + amdgpu_device_ip_late_set_pg_state(adev); + queue_delayed_work(system_wq, &adev->late_init_work, msecs_to_jiffies(AMDGPU_RESUME_MS)); @@ -1919,8 +1918,11 @@ static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work) { struct amdgpu_device *adev = container_of(work, struct amdgpu_device, late_init_work.work); - amdgpu_device_ip_late_set_cg_state(adev); - amdgpu_device_ip_late_set_pg_state(adev); + int r; + + r = amdgpu_ib_ring_tests(adev); + if (r) + DRM_ERROR("ib ring test failed (%d).\n", r); } /** From 22994e16dd025aefd7f97a863f13ae23d8853601 Mon Sep 17 00:00:00 2001 From: rex zhu Date: Wed, 27 Jun 2018 18:08:43 +0800 Subject: [PATCH 069/133] drm/amdgpu: Add stutter mode ctrl in module parameter Enable stutter mode can save power in low DRAM use cases including but not limited to productivity application use, web browsing, and video playback. Currently this feature is disabled by default. Make bit 17 in module parameter amdgpu_pp_feature_mask as stutter mode mask, so user can enable/disable this feature easily. Reviewed-by: Alex Deucher Reviewed-by: Huang Rui Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++- drivers/gpu/drm/amd/include/amd_shared.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 684149741427..dcdc97d6dc44 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -122,7 +122,8 @@ uint amdgpu_pg_mask = 0xffffffff; uint amdgpu_sdma_phase_quantum = 32; char *amdgpu_disable_cu = NULL; char *amdgpu_virtual_display = NULL; -uint amdgpu_pp_feature_mask = 0xffff3fff; /* gfxoff (bit 15) disabled by default */ +/* 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; diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index b178176b72ac..d6f487497397 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h @@ -128,6 +128,7 @@ enum PP_FEATURE_MASK { PP_OVERDRIVE_MASK = 0x4000, PP_GFXOFF_MASK = 0x8000, PP_ACG_MASK = 0x10000, + PP_STUTTER_MODE = 0x20000, }; struct amd_ip_funcs { From e856ec3c292ecd6c15e38f2c6c22b350dc0daa17 Mon Sep 17 00:00:00 2001 From: rex zhu Date: Wed, 27 Jun 2018 18:19:08 +0800 Subject: [PATCH 070/133] drm/amd/display: Ctrl stutter mode through module parameter use ppfeaturemask to enable/disable stutter mode. Reviewed-by: Alex Deucher Reviewed-by: Huang Rui Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 356ac27d0180..74683071fa81 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1535,7 +1535,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) /* * Temporary disable until pplib/smu interaction is implemented */ - dm->dc->debug.disable_stutter = true; + dm->dc->debug.disable_stutter = amdgpu_pp_feature_mask & PP_STUTTER_MODE ? false : true; break; #endif default: From b1c6fddb583f70892f2dd6de8c63af3aa4600a7b Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 20 Jun 2018 12:52:43 +0800 Subject: [PATCH 071/133] drm/amd/display: Fix a typo in wm_min_memg_clk_in_khz change wm_min_memg_clk_in_khz -> wm_min_mem_clk_in_khz Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c | 8 ++++---- drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c | 8 ++++---- drivers/gpu/drm/amd/display/dc/dm_services_types.h | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index 752910035e81..9e1afb11e6ad 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c @@ -1000,7 +1000,7 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) eng_clks.data[0].clocks_in_khz; clk_ranges.wm_clk_ranges[0].wm_max_eng_clk_in_khz = eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1; - clk_ranges.wm_clk_ranges[0].wm_min_memg_clk_in_khz = + clk_ranges.wm_clk_ranges[0].wm_min_mem_clk_in_khz = mem_clks.data[0].clocks_in_khz; clk_ranges.wm_clk_ranges[0].wm_max_mem_clk_in_khz = mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1; @@ -1010,7 +1010,7 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz; /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */ clk_ranges.wm_clk_ranges[1].wm_max_eng_clk_in_khz = 5000000; - clk_ranges.wm_clk_ranges[1].wm_min_memg_clk_in_khz = + clk_ranges.wm_clk_ranges[1].wm_min_mem_clk_in_khz = mem_clks.data[0].clocks_in_khz; clk_ranges.wm_clk_ranges[1].wm_max_mem_clk_in_khz = mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1; @@ -1020,7 +1020,7 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) eng_clks.data[0].clocks_in_khz; clk_ranges.wm_clk_ranges[2].wm_max_eng_clk_in_khz = eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1; - clk_ranges.wm_clk_ranges[2].wm_min_memg_clk_in_khz = + clk_ranges.wm_clk_ranges[2].wm_min_mem_clk_in_khz = mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz; /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */ clk_ranges.wm_clk_ranges[2].wm_max_mem_clk_in_khz = 5000000; @@ -1030,7 +1030,7 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz; /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */ clk_ranges.wm_clk_ranges[3].wm_max_eng_clk_in_khz = 5000000; - clk_ranges.wm_clk_ranges[3].wm_min_memg_clk_in_khz = + clk_ranges.wm_clk_ranges[3].wm_min_mem_clk_in_khz = mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz; /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */ clk_ranges.wm_clk_ranges[3].wm_max_mem_clk_in_khz = 5000000; diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c index 13c388a608c4..8381f27a2361 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c @@ -775,7 +775,7 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) eng_clks.data[0].clocks_in_khz; clk_ranges.wm_clk_ranges[0].wm_max_eng_clk_in_khz = eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1; - clk_ranges.wm_clk_ranges[0].wm_min_memg_clk_in_khz = + clk_ranges.wm_clk_ranges[0].wm_min_mem_clk_in_khz = mem_clks.data[0].clocks_in_khz; clk_ranges.wm_clk_ranges[0].wm_max_mem_clk_in_khz = mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1; @@ -785,7 +785,7 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz; /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */ clk_ranges.wm_clk_ranges[1].wm_max_eng_clk_in_khz = 5000000; - clk_ranges.wm_clk_ranges[1].wm_min_memg_clk_in_khz = + clk_ranges.wm_clk_ranges[1].wm_min_mem_clk_in_khz = mem_clks.data[0].clocks_in_khz; clk_ranges.wm_clk_ranges[1].wm_max_mem_clk_in_khz = mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1; @@ -795,7 +795,7 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) eng_clks.data[0].clocks_in_khz; clk_ranges.wm_clk_ranges[2].wm_max_eng_clk_in_khz = eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1; - clk_ranges.wm_clk_ranges[2].wm_min_memg_clk_in_khz = + clk_ranges.wm_clk_ranges[2].wm_min_mem_clk_in_khz = mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz; /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */ clk_ranges.wm_clk_ranges[2].wm_max_mem_clk_in_khz = 5000000; @@ -805,7 +805,7 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz; /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */ clk_ranges.wm_clk_ranges[3].wm_max_eng_clk_in_khz = 5000000; - clk_ranges.wm_clk_ranges[3].wm_min_memg_clk_in_khz = + clk_ranges.wm_clk_ranges[3].wm_min_mem_clk_in_khz = mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz; /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */ clk_ranges.wm_clk_ranges[3].wm_max_mem_clk_in_khz = 5000000; diff --git a/drivers/gpu/drm/amd/display/dc/dm_services_types.h b/drivers/gpu/drm/amd/display/dc/dm_services_types.h index ab8c77d4e6df..2b83f922ac02 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_services_types.h +++ b/drivers/gpu/drm/amd/display/dc/dm_services_types.h @@ -137,7 +137,7 @@ struct dm_pp_clock_range_for_wm_set { enum dm_pp_wm_set_id wm_set_id; uint32_t wm_min_eng_clk_in_khz; uint32_t wm_max_eng_clk_in_khz; - uint32_t wm_min_memg_clk_in_khz; + uint32_t wm_min_mem_clk_in_khz; uint32_t wm_max_mem_clk_in_khz; }; @@ -150,7 +150,7 @@ struct dm_pp_clock_range_for_dmif_wm_set_soc15 { enum dm_pp_wm_set_id wm_set_id; uint32_t wm_min_dcfclk_clk_in_khz; uint32_t wm_max_dcfclk_clk_in_khz; - uint32_t wm_min_memg_clk_in_khz; + uint32_t wm_min_mem_clk_in_khz; uint32_t wm_max_mem_clk_in_khz; }; @@ -158,7 +158,7 @@ struct dm_pp_clock_range_for_mcif_wm_set_soc15 { enum dm_pp_wm_set_id wm_set_id; uint32_t wm_min_socclk_clk_in_khz; uint32_t wm_max_socclk_clk_in_khz; - uint32_t wm_min_memg_clk_in_khz; + uint32_t wm_min_mem_clk_in_khz; uint32_t wm_max_mem_clk_in_khz; }; From acee16f4deab484b9b78876b8b292174e95ccf88 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 28 May 2018 08:59:16 +0800 Subject: [PATCH 072/133] drm/amd/powerplay: correct vega12 bootup values settings The vbios firmware structure changed between v3_1 and v3_2. So, the code to setup bootup values needs different paths based on header version. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../drm/amd/powerplay/hwmgr/ppatomfwctrl.c | 94 ++++++++++++++++--- .../drm/amd/powerplay/hwmgr/ppatomfwctrl.h | 3 + .../drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 3 + .../drm/amd/powerplay/hwmgr/vega12_hwmgr.h | 3 + 4 files changed, 91 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c index 5325661fedff..aa2faffef034 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c @@ -512,14 +512,82 @@ int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, BIOS_CLKI return 0; } +static void pp_atomfwctrl_copy_vbios_bootup_values_3_2(struct pp_hwmgr *hwmgr, + struct pp_atomfwctrl_bios_boot_up_values *boot_values, + struct atom_firmware_info_v3_2 *fw_info) +{ + uint32_t frequency = 0; + + boot_values->ulRevision = fw_info->firmware_revision; + boot_values->ulGfxClk = fw_info->bootup_sclk_in10khz; + boot_values->ulUClk = fw_info->bootup_mclk_in10khz; + boot_values->usVddc = fw_info->bootup_vddc_mv; + boot_values->usVddci = fw_info->bootup_vddci_mv; + boot_values->usMvddc = fw_info->bootup_mvddc_mv; + boot_values->usVddGfx = fw_info->bootup_vddgfx_mv; + boot_values->ucCoolingID = fw_info->coolingsolution_id; + boot_values->ulSocClk = 0; + boot_values->ulDCEFClk = 0; + + if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_SOCCLK_ID, &frequency)) + boot_values->ulSocClk = frequency; + + if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCEFCLK_ID, &frequency)) + boot_values->ulDCEFClk = frequency; + + if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_ECLK_ID, &frequency)) + boot_values->ulEClk = frequency; + + if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_VCLK_ID, &frequency)) + boot_values->ulVClk = frequency; + + if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCLK_ID, &frequency)) + boot_values->ulDClk = frequency; +} + +static void pp_atomfwctrl_copy_vbios_bootup_values_3_1(struct pp_hwmgr *hwmgr, + struct pp_atomfwctrl_bios_boot_up_values *boot_values, + struct atom_firmware_info_v3_1 *fw_info) +{ + uint32_t frequency = 0; + + boot_values->ulRevision = fw_info->firmware_revision; + boot_values->ulGfxClk = fw_info->bootup_sclk_in10khz; + boot_values->ulUClk = fw_info->bootup_mclk_in10khz; + boot_values->usVddc = fw_info->bootup_vddc_mv; + boot_values->usVddci = fw_info->bootup_vddci_mv; + boot_values->usMvddc = fw_info->bootup_mvddc_mv; + boot_values->usVddGfx = fw_info->bootup_vddgfx_mv; + boot_values->ucCoolingID = fw_info->coolingsolution_id; + boot_values->ulSocClk = 0; + boot_values->ulDCEFClk = 0; + + if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_SOCCLK_ID, &frequency)) + boot_values->ulSocClk = frequency; + + if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCEFCLK_ID, &frequency)) + boot_values->ulDCEFClk = frequency; + + if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_ECLK_ID, &frequency)) + boot_values->ulEClk = frequency; + + if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_VCLK_ID, &frequency)) + boot_values->ulVClk = frequency; + + if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCLK_ID, &frequency)) + boot_values->ulDClk = frequency; +} + int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr, struct pp_atomfwctrl_bios_boot_up_values *boot_values) { - struct atom_firmware_info_v3_1 *info = NULL; + struct atom_firmware_info_v3_2 *fwinfo_3_2; + struct atom_firmware_info_v3_1 *fwinfo_3_1; + struct atom_common_table_header *info = NULL; uint16_t ix; ix = GetIndexIntoMasterDataTable(firmwareinfo); - info = (struct atom_firmware_info_v3_1 *) + info = (struct atom_common_table_header *) smu_atom_get_data_table(hwmgr->adev, ix, NULL, NULL, NULL); @@ -528,16 +596,18 @@ int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr, return -EINVAL; } - boot_values->ulRevision = info->firmware_revision; - boot_values->ulGfxClk = info->bootup_sclk_in10khz; - boot_values->ulUClk = info->bootup_mclk_in10khz; - boot_values->usVddc = info->bootup_vddc_mv; - boot_values->usVddci = info->bootup_vddci_mv; - boot_values->usMvddc = info->bootup_mvddc_mv; - boot_values->usVddGfx = info->bootup_vddgfx_mv; - boot_values->ucCoolingID = info->coolingsolution_id; - boot_values->ulSocClk = 0; - boot_values->ulDCEFClk = 0; + if ((info->format_revision == 3) && (info->content_revision == 2)) { + fwinfo_3_2 = (struct atom_firmware_info_v3_2 *)info; + pp_atomfwctrl_copy_vbios_bootup_values_3_2(hwmgr, + boot_values, fwinfo_3_2); + } else if ((info->format_revision == 3) && (info->content_revision == 1)) { + fwinfo_3_1 = (struct atom_firmware_info_v3_1 *)info; + pp_atomfwctrl_copy_vbios_bootup_values_3_1(hwmgr, + boot_values, fwinfo_3_1); + } else { + pr_info("Fw info table revision does not match!"); + return -EINVAL; + } return 0; } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h index fe10aa4db5e6..745bd3809549 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h @@ -136,6 +136,9 @@ struct pp_atomfwctrl_bios_boot_up_values { uint32_t ulUClk; uint32_t ulSocClk; uint32_t ulDCEFClk; + uint32_t ulEClk; + uint32_t ulVClk; + uint32_t ulDClk; uint16_t usVddc; uint16_t usVddci; uint16_t usMvddc; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 782e2098824d..e81661cc9bae 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -803,6 +803,9 @@ static int vega12_init_smc_table(struct pp_hwmgr *hwmgr) data->vbios_boot_state.soc_clock = boot_up_values.ulSocClk; data->vbios_boot_state.dcef_clock = boot_up_values.ulDCEFClk; data->vbios_boot_state.uc_cooling_id = boot_up_values.ucCoolingID; + data->vbios_boot_state.eclock = boot_up_values.ulEClk; + data->vbios_boot_state.dclock = boot_up_values.ulDClk; + data->vbios_boot_state.vclock = boot_up_values.ulVClk; smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetMinDeepSleepDcefclk, (uint32_t)(data->vbios_boot_state.dcef_clock / 100)); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h index e81ded1ec198..49b38df8c7f2 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h @@ -167,6 +167,9 @@ struct vega12_vbios_boot_state { uint32_t mem_clock; uint32_t soc_clock; uint32_t dcef_clock; + uint32_t eclock; + uint32_t dclock; + uint32_t vclock; }; #define DPMTABLE_OD_UPDATE_SCLK 0x00000001 From 77564c9dff26f2a90d089dfb282906ec7be7c144 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 11 Jun 2018 15:20:39 +0800 Subject: [PATCH 073/133] drm/amd/powerplay: smc_dpm_info structure change A new member Vr2_I2C_address is added. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/atomfirmware.h | 5 ++++- drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c | 2 ++ drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h | 2 ++ drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c | 2 ++ drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h | 5 ++++- 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h index 092d800b703a..33b4de4ad66e 100644 --- a/drivers/gpu/drm/amd/include/atomfirmware.h +++ b/drivers/gpu/drm/amd/include/atomfirmware.h @@ -1433,7 +1433,10 @@ struct atom_smc_dpm_info_v4_1 uint8_t acggfxclkspreadpercent; uint16_t acggfxclkspreadfreq; - uint32_t boardreserved[10]; + uint8_t Vr2_I2C_address; + uint8_t padding_vr2[3]; + + uint32_t boardreserved[9]; }; /* diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c index aa2faffef034..d27c1c9df286 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c @@ -699,5 +699,7 @@ int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr, param->acggfxclkspreadpercent = info->acggfxclkspreadpercent; param->acggfxclkspreadfreq = info->acggfxclkspreadfreq; + param->Vr2_I2C_address = info->Vr2_I2C_address; + return 0; } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h index 745bd3809549..22e21668c93a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h @@ -210,6 +210,8 @@ struct pp_atomfwctrl_smc_dpm_parameters uint8_t acggfxclkspreadenabled; uint8_t acggfxclkspreadpercent; uint16_t acggfxclkspreadfreq; + + uint8_t Vr2_I2C_address; }; int pp_atomfwctrl_get_gpu_pll_dividers_vega10(struct pp_hwmgr *hwmgr, diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c index 888ddca902d8..29914700ee82 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c @@ -230,6 +230,8 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable ppsmc_pptable->AcgThresholdFreqLow = 0xFFFF; } + ppsmc_pptable->Vr2_I2C_address = smc_dpm_table.Vr2_I2C_address; + return 0; } diff --git a/drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h b/drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h index 2f8a3b983cce..b08526fd1619 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h +++ b/drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h @@ -499,7 +499,10 @@ typedef struct { uint8_t AcgGfxclkSpreadPercent; uint16_t AcgGfxclkSpreadFreq; - uint32_t BoardReserved[10]; + uint8_t Vr2_I2C_address; + uint8_t padding_vr2[3]; + + uint32_t BoardReserved[9]; uint32_t MmHubPadding[7]; From 9bf40d787924f45d6a0fa49d3e69d772c2aa5b19 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 11 Jun 2018 17:38:54 +0800 Subject: [PATCH 074/133] drm/amd/powerplay: drop the acg fix This workaround is not needed any more. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c index 29914700ee82..f4f366b26fd1 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c @@ -224,12 +224,6 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable ppsmc_pptable->AcgGfxclkSpreadPercent = smc_dpm_table.acggfxclkspreadpercent; ppsmc_pptable->AcgGfxclkSpreadFreq = smc_dpm_table.acggfxclkspreadfreq; - /* 0xFFFF will disable the ACG feature */ - if (!(hwmgr->feature_mask & PP_ACG_MASK)) { - ppsmc_pptable->AcgThresholdFreqHigh = 0xFFFF; - ppsmc_pptable->AcgThresholdFreqLow = 0xFFFF; - } - ppsmc_pptable->Vr2_I2C_address = smc_dpm_table.Vr2_I2C_address; return 0; From 3b579c5483286fba6e13bc4b2f1d8a6627410371 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 11 Jun 2018 15:25:37 +0800 Subject: [PATCH 075/133] drm/amd/powerplay: revise default dpm tables setup Initialize the soft/hard min/max level correctly and handle the dpm disabled situation. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 334 +++++++----------- 1 file changed, 132 insertions(+), 202 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index e81661cc9bae..bc976e1d22c5 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -453,37 +453,30 @@ static int vega12_setup_asic_task(struct pp_hwmgr *hwmgr) */ static void vega12_init_dpm_state(struct vega12_dpm_state *dpm_state) { - dpm_state->soft_min_level = 0xff; - dpm_state->soft_max_level = 0xff; - dpm_state->hard_min_level = 0xff; - dpm_state->hard_max_level = 0xff; + dpm_state->soft_min_level = 0x0; + dpm_state->soft_max_level = 0xffff; + dpm_state->hard_min_level = 0x0; + dpm_state->hard_max_level = 0xffff; } -static int vega12_get_number_dpm_level(struct pp_hwmgr *hwmgr, - PPCLK_e clkID, uint32_t *num_dpm_level) +static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr, + PPCLK_e clk_id, uint32_t *num_of_levels) { - int result; - /* - * SMU expects the Clock ID to be in the top 16 bits. - * Lower 16 bits specify the level however 0xFF is a - * special argument the returns the total number of levels - */ - PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_GetDpmFreqByIndex, (clkID << 16 | 0xFF)) == 0, - "[GetNumberDpmLevel] Failed to get DPM levels from SMU for CLKID!", - return -EINVAL); + int ret = 0; - result = vega12_read_arg_from_smc(hwmgr, num_dpm_level); + ret = smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_GetDpmFreqByIndex, + (clk_id << 16 | 0xFF)); + PP_ASSERT_WITH_CODE(!ret, + "[GetNumOfDpmLevel] failed to get dpm levels!", + return ret); - PP_ASSERT_WITH_CODE(*num_dpm_level < MAX_REGULAR_DPM_NUMBER, - "[GetNumberDPMLevel] Number of DPM levels is greater than limit", - return -EINVAL); + vega12_read_arg_from_smc(hwmgr, num_of_levels); + PP_ASSERT_WITH_CODE(*num_of_levels > 0, + "[GetNumOfDpmLevel] number of clk levels is invalid!", + return -EINVAL); - PP_ASSERT_WITH_CODE(*num_dpm_level != 0, - "[GetNumberDPMLevel] Number of CLK Levels is zero!", - return -EINVAL); - - return result; + return ret; } static int vega12_get_dpm_frequency_by_index(struct pp_hwmgr *hwmgr, @@ -509,6 +502,31 @@ static int vega12_get_dpm_frequency_by_index(struct pp_hwmgr *hwmgr, return result; } +static int vega12_setup_single_dpm_table(struct pp_hwmgr *hwmgr, + struct vega12_single_dpm_table *dpm_table, PPCLK_e clk_id) +{ + int ret = 0; + uint32_t i, num_of_levels, clk; + + ret = vega12_get_number_of_dpm_level(hwmgr, clk_id, &num_of_levels); + PP_ASSERT_WITH_CODE(!ret, + "[SetupSingleDpmTable] failed to get clk levels!", + return ret); + + dpm_table->count = num_of_levels; + + for (i = 0; i < num_of_levels; i++) { + ret = vega12_get_dpm_frequency_by_index(hwmgr, clk_id, i, &clk); + PP_ASSERT_WITH_CODE(!ret, + "[SetupSingleDpmTable] failed to get clk of specific level!", + return ret); + dpm_table->dpm_levels[i].value = clk; + dpm_table->dpm_levels[i].enabled = true; + } + + return ret; +} + /* * This function is to initialize all DPM state tables * for SMU based on the dependency table. @@ -519,224 +537,136 @@ static int vega12_get_dpm_frequency_by_index(struct pp_hwmgr *hwmgr, */ static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) { - uint32_t num_levels, i, clock; struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); - struct vega12_single_dpm_table *dpm_table; + int ret = 0; memset(&data->dpm_table, 0, sizeof(data->dpm_table)); - /* Initialize Sclk DPM and SOC DPM table based on allow Sclk values */ + /* socclk */ dpm_table = &(data->dpm_table.soc_table); - - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_SOCCLK, - &num_levels) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for SOCCLK!", - return -EINVAL); - - dpm_table->count = num_levels; - - for (i = 0; i < num_levels; i++) { - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, - PPCLK_SOCCLK, i, &clock) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for SOCCLK!", - return -EINVAL); - - dpm_table->dpm_levels[i].value = clock; - dpm_table->dpm_levels[i].enabled = true; + if (data->smu_features[GNLD_DPM_SOCCLK].enabled) { + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_SOCCLK); + PP_ASSERT_WITH_CODE(!ret, + "[SetupDefaultDpmTable] failed to get socclk dpm levels!", + return ret); + } else { + dpm_table->count = 1; + dpm_table->dpm_levels[0].value = data->vbios_boot_state.soc_clock / 100; } - vega12_init_dpm_state(&(dpm_table->dpm_state)); + /* gfxclk */ dpm_table = &(data->dpm_table.gfx_table); - - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_GFXCLK, - &num_levels) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for GFXCLK!", - return -EINVAL); - - dpm_table->count = num_levels; - for (i = 0; i < num_levels; i++) { - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, - PPCLK_GFXCLK, i, &clock) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for GFXCLK!", - return -EINVAL); - - dpm_table->dpm_levels[i].value = clock; - dpm_table->dpm_levels[i].enabled = true; + if (data->smu_features[GNLD_DPM_GFXCLK].enabled) { + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_GFXCLK); + PP_ASSERT_WITH_CODE(!ret, + "[SetupDefaultDpmTable] failed to get gfxclk dpm levels!", + return ret); + } else { + dpm_table->count = 1; + dpm_table->dpm_levels[0].value = data->vbios_boot_state.gfx_clock / 100; } - vega12_init_dpm_state(&(dpm_table->dpm_state)); - /* Initialize Mclk DPM table based on allow Mclk values */ + + /* memclk */ dpm_table = &(data->dpm_table.mem_table); - - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_UCLK, - &num_levels) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for UCLK!", - return -EINVAL); - - dpm_table->count = num_levels; - - for (i = 0; i < num_levels; i++) { - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, - PPCLK_UCLK, i, &clock) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for UCLK!", - return -EINVAL); - - dpm_table->dpm_levels[i].value = clock; - dpm_table->dpm_levels[i].enabled = true; + if (data->smu_features[GNLD_DPM_UCLK].enabled) { + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_UCLK); + PP_ASSERT_WITH_CODE(!ret, + "[SetupDefaultDpmTable] failed to get memclk dpm levels!", + return ret); + } else { + dpm_table->count = 1; + dpm_table->dpm_levels[0].value = data->vbios_boot_state.mem_clock / 100; } - vega12_init_dpm_state(&(dpm_table->dpm_state)); + /* eclk */ dpm_table = &(data->dpm_table.eclk_table); - - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_ECLK, - &num_levels) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for ECLK!", - return -EINVAL); - - dpm_table->count = num_levels; - - for (i = 0; i < num_levels; i++) { - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, - PPCLK_ECLK, i, &clock) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for ECLK!", - return -EINVAL); - - dpm_table->dpm_levels[i].value = clock; - dpm_table->dpm_levels[i].enabled = true; + if (data->smu_features[GNLD_DPM_VCE].enabled) { + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_ECLK); + PP_ASSERT_WITH_CODE(!ret, + "[SetupDefaultDpmTable] failed to get eclk dpm levels!", + return ret); + } else { + dpm_table->count = 1; + dpm_table->dpm_levels[0].value = data->vbios_boot_state.eclock / 100; } - vega12_init_dpm_state(&(dpm_table->dpm_state)); + /* vclk */ dpm_table = &(data->dpm_table.vclk_table); - - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_VCLK, - &num_levels) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for VCLK!", - return -EINVAL); - - dpm_table->count = num_levels; - - for (i = 0; i < num_levels; i++) { - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, - PPCLK_VCLK, i, &clock) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for VCLK!", - return -EINVAL); - - dpm_table->dpm_levels[i].value = clock; - dpm_table->dpm_levels[i].enabled = true; + if (data->smu_features[GNLD_DPM_UVD].enabled) { + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_VCLK); + PP_ASSERT_WITH_CODE(!ret, + "[SetupDefaultDpmTable] failed to get vclk dpm levels!", + return ret); + } else { + dpm_table->count = 1; + dpm_table->dpm_levels[0].value = data->vbios_boot_state.vclock / 100; } - vega12_init_dpm_state(&(dpm_table->dpm_state)); + /* dclk */ dpm_table = &(data->dpm_table.dclk_table); - - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_DCLK, - &num_levels) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DCLK!", - return -EINVAL); - - dpm_table->count = num_levels; - - for (i = 0; i < num_levels; i++) { - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, - PPCLK_DCLK, i, &clock) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DCLK!", - return -EINVAL); - - dpm_table->dpm_levels[i].value = clock; - dpm_table->dpm_levels[i].enabled = true; + if (data->smu_features[GNLD_DPM_UVD].enabled) { + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_DCLK); + PP_ASSERT_WITH_CODE(!ret, + "[SetupDefaultDpmTable] failed to get dclk dpm levels!", + return ret); + } else { + dpm_table->count = 1; + dpm_table->dpm_levels[0].value = data->vbios_boot_state.dclock / 100; } - vega12_init_dpm_state(&(dpm_table->dpm_state)); - /* Assume there is no headless Vega12 for now */ + /* dcefclk */ dpm_table = &(data->dpm_table.dcef_table); - - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, - PPCLK_DCEFCLK, &num_levels) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DCEFCLK!", - return -EINVAL); - - dpm_table->count = num_levels; - - for (i = 0; i < num_levels; i++) { - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, - PPCLK_DCEFCLK, i, &clock) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DCEFCLK!", - return -EINVAL); - - dpm_table->dpm_levels[i].value = clock; - dpm_table->dpm_levels[i].enabled = true; + if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) { + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_DCEFCLK); + PP_ASSERT_WITH_CODE(!ret, + "[SetupDefaultDpmTable] failed to get dcefclk dpm levels!", + return ret); + } else { + dpm_table->count = 1; + dpm_table->dpm_levels[0].value = data->vbios_boot_state.dcef_clock / 100; } - vega12_init_dpm_state(&(dpm_table->dpm_state)); + /* pixclk */ dpm_table = &(data->dpm_table.pixel_table); - - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, - PPCLK_PIXCLK, &num_levels) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for PIXCLK!", - return -EINVAL); - - dpm_table->count = num_levels; - - for (i = 0; i < num_levels; i++) { - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, - PPCLK_PIXCLK, i, &clock) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for PIXCLK!", - return -EINVAL); - - dpm_table->dpm_levels[i].value = clock; - dpm_table->dpm_levels[i].enabled = true; - } - + if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) { + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_PIXCLK); + PP_ASSERT_WITH_CODE(!ret, + "[SetupDefaultDpmTable] failed to get pixclk dpm levels!", + return ret); + } else + dpm_table->count = 0; vega12_init_dpm_state(&(dpm_table->dpm_state)); + /* dispclk */ dpm_table = &(data->dpm_table.display_table); - - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, - PPCLK_DISPCLK, &num_levels) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DISPCLK!", - return -EINVAL); - - dpm_table->count = num_levels; - - for (i = 0; i < num_levels; i++) { - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, - PPCLK_DISPCLK, i, &clock) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DISPCLK!", - return -EINVAL); - - dpm_table->dpm_levels[i].value = clock; - dpm_table->dpm_levels[i].enabled = true; - } - + if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) { + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_DISPCLK); + PP_ASSERT_WITH_CODE(!ret, + "[SetupDefaultDpmTable] failed to get dispclk dpm levels!", + return ret); + } else + dpm_table->count = 0; vega12_init_dpm_state(&(dpm_table->dpm_state)); + /* phyclk */ dpm_table = &(data->dpm_table.phy_table); - - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, - PPCLK_PHYCLK, &num_levels) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for PHYCLK!", - return -EINVAL); - - dpm_table->count = num_levels; - - for (i = 0; i < num_levels; i++) { - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, - PPCLK_PHYCLK, i, &clock) == 0, - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for PHYCLK!", - return -EINVAL); - - dpm_table->dpm_levels[i].value = clock; - dpm_table->dpm_levels[i].enabled = true; - } - + if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) { + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_PHYCLK); + PP_ASSERT_WITH_CODE(!ret, + "[SetupDefaultDpmTable] failed to get phyclk dpm levels!", + return ret); + } else + dpm_table->count = 0; vega12_init_dpm_state(&(dpm_table->dpm_state)); /* save a copy of the default DPM table */ From 70fef5741c6b82ad293a225f116006565646fb72 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 11 Jun 2018 15:41:44 +0800 Subject: [PATCH 076/133] drm/amd/powerplay: retrieve all clock ranges on startup So that we do not need to use PPSMC_MSG_GetMin/MaxDpmFreq to get the clock ranges on runtime. Since that causes some problems. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 69 ++++++++++++++----- .../drm/amd/powerplay/hwmgr/vega12_hwmgr.h | 8 +++ 2 files changed, 61 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index bc976e1d22c5..d3e898306ced 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -856,6 +856,48 @@ static int vega12_power_control_set_level(struct pp_hwmgr *hwmgr) return result; } +static int vega12_get_all_clock_ranges_helper(struct pp_hwmgr *hwmgr, + PPCLK_e clkid, struct vega12_clock_range *clock) +{ + /* AC Max */ + PP_ASSERT_WITH_CODE( + smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMaxDpmFreq, (clkid << 16)) == 0, + "[GetClockRanges] Failed to get max ac clock from SMC!", + return -EINVAL); + vega12_read_arg_from_smc(hwmgr, &(clock->ACMax)); + + /* AC Min */ + PP_ASSERT_WITH_CODE( + smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMinDpmFreq, (clkid << 16)) == 0, + "[GetClockRanges] Failed to get min ac clock from SMC!", + return -EINVAL); + vega12_read_arg_from_smc(hwmgr, &(clock->ACMin)); + + /* DC Max */ + PP_ASSERT_WITH_CODE( + smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetDcModeMaxDpmFreq, (clkid << 16)) == 0, + "[GetClockRanges] Failed to get max dc clock from SMC!", + return -EINVAL); + vega12_read_arg_from_smc(hwmgr, &(clock->DCMax)); + + return 0; +} + +static int vega12_get_all_clock_ranges(struct pp_hwmgr *hwmgr) +{ + struct vega12_hwmgr *data = + (struct vega12_hwmgr *)(hwmgr->backend); + uint32_t i; + + for (i = 0; i < PPCLK_COUNT; i++) + PP_ASSERT_WITH_CODE(!vega12_get_all_clock_ranges_helper(hwmgr, + i, &(data->clk_range[i])), + "Failed to get clk range from SMC!", + return -EINVAL); + + return 0; +} + static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr) { int tmp_result, result = 0; @@ -883,6 +925,11 @@ static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr) "Failed to power control set level!", result = tmp_result); + result = vega12_get_all_clock_ranges(hwmgr); + PP_ASSERT_WITH_CODE(!result, + "Failed to get all clock ranges!", + return result); + result = vega12_odn_initialize_default_settings(hwmgr); PP_ASSERT_WITH_CODE(!result, "Failed to power control set level!", @@ -1472,24 +1519,14 @@ static int vega12_get_clock_ranges(struct pp_hwmgr *hwmgr, PPCLK_e clock_select, bool max) { - int result; - *clock = 0; + struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); - if (max) { - PP_ASSERT_WITH_CODE( - smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMaxDpmFreq, (clock_select << 16)) == 0, - "[GetClockRanges] Failed to get max clock from SMC!", - return -1); - result = vega12_read_arg_from_smc(hwmgr, clock); - } else { - PP_ASSERT_WITH_CODE( - smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMinDpmFreq, (clock_select << 16)) == 0, - "[GetClockRanges] Failed to get min clock from SMC!", - return -1); - result = vega12_read_arg_from_smc(hwmgr, clock); - } + if (max) + *clock = data->clk_range[clock_select].ACMax; + else + *clock = data->clk_range[clock_select].ACMin; - return result; + return 0; } static int vega12_get_sclks(struct pp_hwmgr *hwmgr, diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h index 49b38df8c7f2..e18c08308602 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h @@ -304,6 +304,12 @@ struct vega12_odn_fan_table { bool force_fan_pwm; }; +struct vega12_clock_range { + uint32_t ACMax; + uint32_t ACMin; + uint32_t DCMax; +}; + struct vega12_hwmgr { struct vega12_dpm_table dpm_table; struct vega12_dpm_table golden_dpm_table; @@ -385,6 +391,8 @@ struct vega12_hwmgr { uint32_t smu_version; struct smu_features smu_features[GNLD_FEATURES_MAX]; struct vega12_smc_state_table smc_state_table; + + struct vega12_clock_range clk_range[PPCLK_COUNT]; }; #define VEGA12_DPM2_NEAR_TDP_DEC 10 From 8fd26361701187e6fbb56c7c8bf22b4ab763b082 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 11 Jun 2018 16:04:17 +0800 Subject: [PATCH 077/133] drm/amd/powerplay: revise clock level setup Make sure the clock level set only on dpm enabled. Also uvd/vce/soc clock also changed correspondingly. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 318 ++++++++++++------ 1 file changed, 211 insertions(+), 107 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index d3e898306ced..45c8f2ddaa95 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -958,76 +958,172 @@ static uint32_t vega12_find_lowest_dpm_level( break; } + if (i >= table->count) { + i = 0; + table->dpm_levels[i].enabled = true; + } + return i; } static uint32_t vega12_find_highest_dpm_level( struct vega12_single_dpm_table *table) { - uint32_t i = 0; + int32_t i = 0; + PP_ASSERT_WITH_CODE(table->count <= MAX_REGULAR_DPM_NUMBER, + "[FindHighestDPMLevel] DPM Table has too many entries!", + return MAX_REGULAR_DPM_NUMBER - 1); - if (table->count <= MAX_REGULAR_DPM_NUMBER) { - for (i = table->count; i > 0; i--) { - if (table->dpm_levels[i - 1].enabled) - return i - 1; - } - } else { - pr_info("DPM Table Has Too Many Entries!"); - return MAX_REGULAR_DPM_NUMBER - 1; + for (i = table->count - 1; i >= 0; i--) { + if (table->dpm_levels[i].enabled) + break; } - return i; + if (i < 0) { + i = 0; + table->dpm_levels[i].enabled = true; + } + + return (uint32_t)i; } static int vega12_upload_dpm_min_level(struct pp_hwmgr *hwmgr) { struct vega12_hwmgr *data = hwmgr->backend; - if (data->smc_state_table.gfx_boot_level != - data->dpm_table.gfx_table.dpm_state.soft_min_level) { - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SetSoftMinByFreq, - PPCLK_GFXCLK<<16 | data->dpm_table.gfx_table.dpm_levels[data->smc_state_table.gfx_boot_level].value); - data->dpm_table.gfx_table.dpm_state.soft_min_level = - data->smc_state_table.gfx_boot_level; + uint32_t min_freq; + int ret = 0; + + if (data->smu_features[GNLD_DPM_GFXCLK].enabled) { + min_freq = data->dpm_table.gfx_table.dpm_state.soft_min_level; + PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter( + hwmgr, PPSMC_MSG_SetSoftMinByFreq, + (PPCLK_GFXCLK << 16) | (min_freq & 0xffff))), + "Failed to set soft min gfxclk !", + return ret); } - if (data->smc_state_table.mem_boot_level != - data->dpm_table.mem_table.dpm_state.soft_min_level) { - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SetSoftMinByFreq, - PPCLK_UCLK<<16 | data->dpm_table.mem_table.dpm_levels[data->smc_state_table.mem_boot_level].value); - data->dpm_table.mem_table.dpm_state.soft_min_level = - data->smc_state_table.mem_boot_level; + if (data->smu_features[GNLD_DPM_UCLK].enabled) { + min_freq = data->dpm_table.mem_table.dpm_state.soft_min_level; + PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter( + hwmgr, PPSMC_MSG_SetSoftMinByFreq, + (PPCLK_UCLK << 16) | (min_freq & 0xffff))), + "Failed to set soft min memclk !", + return ret); + + min_freq = data->dpm_table.mem_table.dpm_state.hard_min_level; + PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter( + hwmgr, PPSMC_MSG_SetHardMinByFreq, + (PPCLK_UCLK << 16) | (min_freq & 0xffff))), + "Failed to set hard min memclk !", + return ret); } - return 0; + if (data->smu_features[GNLD_DPM_UVD].enabled) { + min_freq = data->dpm_table.vclk_table.dpm_state.soft_min_level; + + PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter( + hwmgr, PPSMC_MSG_SetSoftMinByFreq, + (PPCLK_VCLK << 16) | (min_freq & 0xffff))), + "Failed to set soft min vclk!", + return ret); + + min_freq = data->dpm_table.dclk_table.dpm_state.soft_min_level; + + PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter( + hwmgr, PPSMC_MSG_SetSoftMinByFreq, + (PPCLK_DCLK << 16) | (min_freq & 0xffff))), + "Failed to set soft min dclk!", + return ret); + } + + if (data->smu_features[GNLD_DPM_VCE].enabled) { + min_freq = data->dpm_table.eclk_table.dpm_state.soft_min_level; + + PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter( + hwmgr, PPSMC_MSG_SetSoftMinByFreq, + (PPCLK_ECLK << 16) | (min_freq & 0xffff))), + "Failed to set soft min eclk!", + return ret); + } + + if (data->smu_features[GNLD_DPM_SOCCLK].enabled) { + min_freq = data->dpm_table.soc_table.dpm_state.soft_min_level; + + PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter( + hwmgr, PPSMC_MSG_SetSoftMinByFreq, + (PPCLK_SOCCLK << 16) | (min_freq & 0xffff))), + "Failed to set soft min socclk!", + return ret); + } + + return ret; } static int vega12_upload_dpm_max_level(struct pp_hwmgr *hwmgr) { struct vega12_hwmgr *data = hwmgr->backend; - if (data->smc_state_table.gfx_max_level != - data->dpm_table.gfx_table.dpm_state.soft_max_level) { - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SetSoftMaxByFreq, - /* plus the vale by 1 to align the resolution */ - PPCLK_GFXCLK<<16 | (data->dpm_table.gfx_table.dpm_levels[data->smc_state_table.gfx_max_level].value + 1)); - data->dpm_table.gfx_table.dpm_state.soft_max_level = - data->smc_state_table.gfx_max_level; + uint32_t max_freq; + int ret = 0; + + if (data->smu_features[GNLD_DPM_GFXCLK].enabled) { + max_freq = data->dpm_table.gfx_table.dpm_state.soft_max_level; + + PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter( + hwmgr, PPSMC_MSG_SetSoftMaxByFreq, + (PPCLK_GFXCLK << 16) | (max_freq & 0xffff))), + "Failed to set soft max gfxclk!", + return ret); } - if (data->smc_state_table.mem_max_level != - data->dpm_table.mem_table.dpm_state.soft_max_level) { - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_SetSoftMaxByFreq, - /* plus the vale by 1 to align the resolution */ - PPCLK_UCLK<<16 | (data->dpm_table.mem_table.dpm_levels[data->smc_state_table.mem_max_level].value + 1)); - data->dpm_table.mem_table.dpm_state.soft_max_level = - data->smc_state_table.mem_max_level; + if (data->smu_features[GNLD_DPM_UCLK].enabled) { + max_freq = data->dpm_table.mem_table.dpm_state.soft_max_level; + + PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter( + hwmgr, PPSMC_MSG_SetSoftMaxByFreq, + (PPCLK_UCLK << 16) | (max_freq & 0xffff))), + "Failed to set soft max memclk!", + return ret); } - return 0; + if (data->smu_features[GNLD_DPM_UVD].enabled) { + max_freq = data->dpm_table.vclk_table.dpm_state.soft_max_level; + + PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter( + hwmgr, PPSMC_MSG_SetSoftMaxByFreq, + (PPCLK_VCLK << 16) | (max_freq & 0xffff))), + "Failed to set soft max vclk!", + return ret); + + max_freq = data->dpm_table.dclk_table.dpm_state.soft_max_level; + PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter( + hwmgr, PPSMC_MSG_SetSoftMaxByFreq, + (PPCLK_DCLK << 16) | (max_freq & 0xffff))), + "Failed to set soft max dclk!", + return ret); + } + + if (data->smu_features[GNLD_DPM_VCE].enabled) { + max_freq = data->dpm_table.eclk_table.dpm_state.soft_max_level; + + PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter( + hwmgr, PPSMC_MSG_SetSoftMaxByFreq, + (PPCLK_ECLK << 16) | (max_freq & 0xffff))), + "Failed to set soft max eclk!", + return ret); + } + + if (data->smu_features[GNLD_DPM_SOCCLK].enabled) { + max_freq = data->dpm_table.soc_table.dpm_state.soft_max_level; + + PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter( + hwmgr, PPSMC_MSG_SetSoftMaxByFreq, + (PPCLK_SOCCLK << 16) | (max_freq & 0xffff))), + "Failed to set soft max socclk!", + return ret); + } + + return ret; } int vega12_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable) @@ -1330,12 +1426,19 @@ static int vega12_force_dpm_highest(struct pp_hwmgr *hwmgr) struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); - data->smc_state_table.gfx_boot_level = - data->smc_state_table.gfx_max_level = - vega12_find_highest_dpm_level(&(data->dpm_table.gfx_table)); - data->smc_state_table.mem_boot_level = - data->smc_state_table.mem_max_level = - vega12_find_highest_dpm_level(&(data->dpm_table.mem_table)); + uint32_t soft_level; + + soft_level = vega12_find_highest_dpm_level(&(data->dpm_table.gfx_table)); + + data->dpm_table.gfx_table.dpm_state.soft_min_level = + data->dpm_table.gfx_table.dpm_state.soft_max_level = + data->dpm_table.gfx_table.dpm_levels[soft_level].value; + + soft_level = vega12_find_highest_dpm_level(&(data->dpm_table.mem_table)); + + data->dpm_table.mem_table.dpm_state.soft_min_level = + data->dpm_table.mem_table.dpm_state.soft_max_level = + data->dpm_table.mem_table.dpm_levels[soft_level].value; PP_ASSERT_WITH_CODE(!vega12_upload_dpm_min_level(hwmgr), "Failed to upload boot level to highest!", @@ -1352,13 +1455,19 @@ static int vega12_force_dpm_lowest(struct pp_hwmgr *hwmgr) { struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); + uint32_t soft_level; - data->smc_state_table.gfx_boot_level = - data->smc_state_table.gfx_max_level = - vega12_find_lowest_dpm_level(&(data->dpm_table.gfx_table)); - data->smc_state_table.mem_boot_level = - data->smc_state_table.mem_max_level = - vega12_find_lowest_dpm_level(&(data->dpm_table.mem_table)); + soft_level = vega12_find_lowest_dpm_level(&(data->dpm_table.gfx_table)); + + data->dpm_table.gfx_table.dpm_state.soft_min_level = + data->dpm_table.gfx_table.dpm_state.soft_max_level = + data->dpm_table.gfx_table.dpm_levels[soft_level].value; + + soft_level = vega12_find_lowest_dpm_level(&(data->dpm_table.mem_table)); + + data->dpm_table.mem_table.dpm_state.soft_min_level = + data->dpm_table.mem_table.dpm_state.soft_max_level = + data->dpm_table.mem_table.dpm_levels[soft_level].value; PP_ASSERT_WITH_CODE(!vega12_upload_dpm_min_level(hwmgr), "Failed to upload boot level to highest!", @@ -1374,17 +1483,6 @@ static int vega12_force_dpm_lowest(struct pp_hwmgr *hwmgr) static int vega12_unforce_dpm_levels(struct pp_hwmgr *hwmgr) { - struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); - - data->smc_state_table.gfx_boot_level = - vega12_find_lowest_dpm_level(&(data->dpm_table.gfx_table)); - data->smc_state_table.gfx_max_level = - vega12_find_highest_dpm_level(&(data->dpm_table.gfx_table)); - data->smc_state_table.mem_boot_level = - vega12_find_lowest_dpm_level(&(data->dpm_table.mem_table)); - data->smc_state_table.mem_max_level = - vega12_find_highest_dpm_level(&(data->dpm_table.mem_table)); - PP_ASSERT_WITH_CODE(!vega12_upload_dpm_min_level(hwmgr), "Failed to upload DPM Bootup Levels!", return -1); @@ -1392,22 +1490,28 @@ static int vega12_unforce_dpm_levels(struct pp_hwmgr *hwmgr) PP_ASSERT_WITH_CODE(!vega12_upload_dpm_max_level(hwmgr), "Failed to upload DPM Max Levels!", return -1); + return 0; } -#if 0 static int vega12_get_profiling_clk_mask(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level, uint32_t *sclk_mask, uint32_t *mclk_mask, uint32_t *soc_mask) { - struct phm_ppt_v2_information *table_info = - (struct phm_ppt_v2_information *)(hwmgr->pptable); + struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); + struct vega12_single_dpm_table *gfx_dpm_table = &(data->dpm_table.gfx_table); + struct vega12_single_dpm_table *mem_dpm_table = &(data->dpm_table.mem_table); + struct vega12_single_dpm_table *soc_dpm_table = &(data->dpm_table.soc_table); - if (table_info->vdd_dep_on_sclk->count > VEGA12_UMD_PSTATE_GFXCLK_LEVEL && - table_info->vdd_dep_on_socclk->count > VEGA12_UMD_PSTATE_SOCCLK_LEVEL && - table_info->vdd_dep_on_mclk->count > VEGA12_UMD_PSTATE_MCLK_LEVEL) { + *sclk_mask = 0; + *mclk_mask = 0; + *soc_mask = 0; + + if (gfx_dpm_table->count > VEGA12_UMD_PSTATE_GFXCLK_LEVEL && + mem_dpm_table->count > VEGA12_UMD_PSTATE_MCLK_LEVEL && + soc_dpm_table->count > VEGA12_UMD_PSTATE_SOCCLK_LEVEL) { *sclk_mask = VEGA12_UMD_PSTATE_GFXCLK_LEVEL; - *soc_mask = VEGA12_UMD_PSTATE_SOCCLK_LEVEL; *mclk_mask = VEGA12_UMD_PSTATE_MCLK_LEVEL; + *soc_mask = VEGA12_UMD_PSTATE_SOCCLK_LEVEL; } if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) { @@ -1415,13 +1519,13 @@ static int vega12_get_profiling_clk_mask(struct pp_hwmgr *hwmgr, enum amd_dpm_fo } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) { *mclk_mask = 0; } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) { - *sclk_mask = table_info->vdd_dep_on_sclk->count - 1; - *soc_mask = table_info->vdd_dep_on_socclk->count - 1; - *mclk_mask = table_info->vdd_dep_on_mclk->count - 1; + *sclk_mask = gfx_dpm_table->count - 1; + *mclk_mask = mem_dpm_table->count - 1; + *soc_mask = soc_dpm_table->count - 1; } + return 0; } -#endif static void vega12_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode) { @@ -1445,11 +1549,9 @@ static int vega12_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level) { int ret = 0; -#if 0 uint32_t sclk_mask = 0; uint32_t mclk_mask = 0; uint32_t soc_mask = 0; -#endif switch (level) { case AMD_DPM_FORCED_LEVEL_HIGH: @@ -1465,27 +1567,18 @@ static int vega12_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: -#if 0 ret = vega12_get_profiling_clk_mask(hwmgr, level, &sclk_mask, &mclk_mask, &soc_mask); if (ret) return ret; - vega12_force_clock_level(hwmgr, PP_SCLK, 1<dpm_level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) - vega12_set_fan_control_mode(hwmgr, AMD_FAN_CTRL_NONE); - else if (level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) - vega12_set_fan_control_mode(hwmgr, AMD_FAN_CTRL_AUTO); - } -#endif + return ret; } @@ -1745,37 +1838,48 @@ static int vega12_force_clock_level(struct pp_hwmgr *hwmgr, enum pp_clock_type type, uint32_t mask) { struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); - - if (hwmgr->request_dpm_level & (AMD_DPM_FORCED_LEVEL_AUTO | - AMD_DPM_FORCED_LEVEL_LOW | - AMD_DPM_FORCED_LEVEL_HIGH)) - return -EINVAL; + uint32_t soft_min_level, soft_max_level; + int ret = 0; switch (type) { case PP_SCLK: - data->smc_state_table.gfx_boot_level = mask ? (ffs(mask) - 1) : 0; - data->smc_state_table.gfx_max_level = mask ? (fls(mask) - 1) : 0; + soft_min_level = mask ? (ffs(mask) - 1) : 0; + soft_max_level = mask ? (fls(mask) - 1) : 0; - PP_ASSERT_WITH_CODE(!vega12_upload_dpm_min_level(hwmgr), + data->dpm_table.gfx_table.dpm_state.soft_min_level = + data->dpm_table.gfx_table.dpm_levels[soft_min_level].value; + data->dpm_table.gfx_table.dpm_state.soft_max_level = + data->dpm_table.gfx_table.dpm_levels[soft_max_level].value; + + ret = vega12_upload_dpm_min_level(hwmgr); + PP_ASSERT_WITH_CODE(!ret, "Failed to upload boot level to lowest!", - return -EINVAL); + return ret); - PP_ASSERT_WITH_CODE(!vega12_upload_dpm_max_level(hwmgr), + ret = vega12_upload_dpm_max_level(hwmgr); + PP_ASSERT_WITH_CODE(!ret, "Failed to upload dpm max level to highest!", - return -EINVAL); + return ret); break; case PP_MCLK: - data->smc_state_table.mem_boot_level = mask ? (ffs(mask) - 1) : 0; - data->smc_state_table.mem_max_level = mask ? (fls(mask) - 1) : 0; + soft_min_level = mask ? (ffs(mask) - 1) : 0; + soft_max_level = mask ? (fls(mask) - 1) : 0; - PP_ASSERT_WITH_CODE(!vega12_upload_dpm_min_level(hwmgr), + data->dpm_table.mem_table.dpm_state.soft_min_level = + data->dpm_table.mem_table.dpm_levels[soft_min_level].value; + data->dpm_table.mem_table.dpm_state.soft_max_level = + data->dpm_table.mem_table.dpm_levels[soft_max_level].value; + + ret = vega12_upload_dpm_min_level(hwmgr); + PP_ASSERT_WITH_CODE(!ret, "Failed to upload boot level to lowest!", - return -EINVAL); + return ret); - PP_ASSERT_WITH_CODE(!vega12_upload_dpm_max_level(hwmgr), + ret = vega12_upload_dpm_max_level(hwmgr); + PP_ASSERT_WITH_CODE(!ret, "Failed to upload dpm max level to highest!", - return -EINVAL); + return ret); break; From f74aa69d0aed89b5ea283f4a6f86f0505407021e Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 11 Jun 2018 16:25:14 +0800 Subject: [PATCH 078/133] drm/amd/powerplay: initialize uvd/vce powergate status v4 On UVD/VCE dpm enabled/disabled, the powergate status will be set as false/true. So that we will not try to ungate/gate them( enable/disable their dpm) again. v2: added check for uvd/vce powergate status before gating v3: fix typo in description v4: warning fix (Alex) Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- .../drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 45c8f2ddaa95..8176b231c38b 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -777,6 +777,21 @@ static int vega12_set_allowed_featuresmask(struct pp_hwmgr *hwmgr) return 0; } +static void vega12_init_powergate_state(struct pp_hwmgr *hwmgr) +{ + struct vega12_hwmgr *data = + (struct vega12_hwmgr *)(hwmgr->backend); + + data->uvd_power_gated = true; + data->vce_power_gated = true; + + if (data->smu_features[GNLD_DPM_UVD].enabled) + data->uvd_power_gated = false; + + if (data->smu_features[GNLD_DPM_VCE].enabled) + data->vce_power_gated = false; +} + static int vega12_enable_all_smu_features(struct pp_hwmgr *hwmgr) { struct vega12_hwmgr *data = @@ -801,6 +816,8 @@ static int vega12_enable_all_smu_features(struct pp_hwmgr *hwmgr) } } + vega12_init_powergate_state(hwmgr); + return 0; } @@ -1985,6 +2002,9 @@ static void vega12_power_gate_vce(struct pp_hwmgr *hwmgr, bool bgate) { struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); + if (data->vce_power_gated == bgate) + return; + data->vce_power_gated = bgate; vega12_enable_disable_vce_dpm(hwmgr, !bgate); } @@ -1993,6 +2013,9 @@ static void vega12_power_gate_uvd(struct pp_hwmgr *hwmgr, bool bgate) { struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); + if (data->uvd_power_gated == bgate) + return; + data->uvd_power_gated = bgate; vega12_enable_disable_uvd_dpm(hwmgr, !bgate); } From ac32b06acee88ab4c9f3336be5aea4a050b0d4e5 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Wed, 20 Jun 2018 12:24:29 +0800 Subject: [PATCH 079/133] drm/amd/powerplay: correct smc display config for multi monitor Need to take into account multi-head with synced displays. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 8176b231c38b..824d9e15d712 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -1401,7 +1401,8 @@ static int vega12_notify_smc_display_config_after_ps_adjustment( struct pp_display_clock_request clock_req; uint32_t clk_request; - if (hwmgr->display_config->num_display > 1) + if ((hwmgr->display_config->num_display > 1) && + !hwmgr->display_config->multi_monitor_in_sync) vega12_notify_smc_display_change(hwmgr, false); else vega12_notify_smc_display_change(hwmgr, true); From 30222561808f8fdf6d56c22ccfe3d9140fd0a169 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Wed, 20 Jun 2018 12:28:10 +0800 Subject: [PATCH 080/133] drm/amd/powerplay: drop unnecessary uclk hard min setting We don't need to set uclk hard min here because this will be set with other clocks on power state change. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 824d9e15d712..8222383009da 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -1399,7 +1399,6 @@ static int vega12_notify_smc_display_config_after_ps_adjustment( (struct vega12_hwmgr *)(hwmgr->backend); struct PP_Clocks min_clocks = {0}; struct pp_display_clock_request clock_req; - uint32_t clk_request; if ((hwmgr->display_config->num_display > 1) && !hwmgr->display_config->multi_monitor_in_sync) @@ -1427,15 +1426,6 @@ static int vega12_notify_smc_display_config_after_ps_adjustment( } } - if (data->smu_features[GNLD_DPM_UCLK].enabled) { - clk_request = (PPCLK_UCLK << 16) | (min_clocks.memoryClock) / 100; - PP_ASSERT_WITH_CODE( - smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetHardMinByFreq, clk_request) == 0, - "[PhwVega12_NotifySMCDisplayConfigAfterPowerStateAdjustment] Attempt to set UCLK HardMin Failed!", - return -1); - data->dpm_table.mem_table.dpm_state.hard_min_level = min_clocks.memoryClock; - } - return 0; } From a0a59c8fc7af37287228a0c89b0a71a1ffadc29b Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 11 Jun 2018 16:33:40 +0800 Subject: [PATCH 081/133] drm/amd/powerplay: correct vega12 max num of dpm level Use MAX_NUM_CLOCKS instead of VG12_PSUEDO* macros for the max number of dpm levels. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 8222383009da..d1bab9845b08 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -1642,8 +1642,8 @@ static int vega12_get_sclks(struct pp_hwmgr *hwmgr, return -1; dpm_table = &(data->dpm_table.gfx_table); - ucount = (dpm_table->count > VG12_PSUEDO_NUM_GFXCLK_DPM_LEVELS) ? - VG12_PSUEDO_NUM_GFXCLK_DPM_LEVELS : dpm_table->count; + ucount = (dpm_table->count > MAX_NUM_CLOCKS) ? + MAX_NUM_CLOCKS : dpm_table->count; for (i = 0; i < ucount; i++) { clocks->data[i].clocks_in_khz = @@ -1674,11 +1674,12 @@ static int vega12_get_memclocks(struct pp_hwmgr *hwmgr, return -1; dpm_table = &(data->dpm_table.mem_table); - ucount = (dpm_table->count > VG12_PSUEDO_NUM_UCLK_DPM_LEVELS) ? - VG12_PSUEDO_NUM_UCLK_DPM_LEVELS : dpm_table->count; + ucount = (dpm_table->count > MAX_NUM_CLOCKS) ? + MAX_NUM_CLOCKS : dpm_table->count; for (i = 0; i < ucount; i++) { clocks->data[i].clocks_in_khz = + data->mclk_latency_table.entries[i].frequency = dpm_table->dpm_levels[i].value * 100; clocks->data[i].latency_in_us = @@ -1704,8 +1705,8 @@ static int vega12_get_dcefclocks(struct pp_hwmgr *hwmgr, dpm_table = &(data->dpm_table.dcef_table); - ucount = (dpm_table->count > VG12_PSUEDO_NUM_DCEFCLK_DPM_LEVELS) ? - VG12_PSUEDO_NUM_DCEFCLK_DPM_LEVELS : dpm_table->count; + ucount = (dpm_table->count > MAX_NUM_CLOCKS) ? + MAX_NUM_CLOCKS : dpm_table->count; for (i = 0; i < ucount; i++) { clocks->data[i].clocks_in_khz = @@ -1732,8 +1733,8 @@ static int vega12_get_socclocks(struct pp_hwmgr *hwmgr, dpm_table = &(data->dpm_table.soc_table); - ucount = (dpm_table->count > VG12_PSUEDO_NUM_SOCCLK_DPM_LEVELS) ? - VG12_PSUEDO_NUM_SOCCLK_DPM_LEVELS : dpm_table->count; + ucount = (dpm_table->count > MAX_NUM_CLOCKS) ? + MAX_NUM_CLOCKS : dpm_table->count; for (i = 0; i < ucount; i++) { clocks->data[i].clocks_in_khz = From e17c7f92b2b7c2f14934c305a8d72bbb0bf6f362 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 11 Jun 2018 16:40:57 +0800 Subject: [PATCH 082/133] drm/amd/powerplay: apply clocks adjust rules on power state change This add the apply_clocks_adjust_rules callback which is used to validate the clock settings on a power state change. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 162 ++++++++++++++++++ .../drm/amd/powerplay/hwmgr/vega12_hwmgr.h | 2 + 2 files changed, 164 insertions(+) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index d1bab9845b08..d28227efe906 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -1950,6 +1950,166 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, return size; } +static int vega12_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr) +{ + struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); + struct vega12_single_dpm_table *dpm_table; + bool vblank_too_short = false; + bool disable_mclk_switching; + uint32_t i, latency; + + disable_mclk_switching = ((1 < hwmgr->display_config->num_display) && + !hwmgr->display_config->multi_monitor_in_sync) || + vblank_too_short; + latency = hwmgr->display_config->dce_tolerable_mclk_in_active_latency; + + /* gfxclk */ + dpm_table = &(data->dpm_table.gfx_table); + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + + if (PP_CAP(PHM_PlatformCaps_UMDPState)) { + if (VEGA12_UMD_PSTATE_GFXCLK_LEVEL < dpm_table->count) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[VEGA12_UMD_PSTATE_GFXCLK_LEVEL].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[VEGA12_UMD_PSTATE_GFXCLK_LEVEL].value; + } + + if (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[0].value; + } + + if (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + } + } + + /* memclk */ + dpm_table = &(data->dpm_table.mem_table); + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + + if (PP_CAP(PHM_PlatformCaps_UMDPState)) { + if (VEGA12_UMD_PSTATE_MCLK_LEVEL < dpm_table->count) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[VEGA12_UMD_PSTATE_MCLK_LEVEL].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[VEGA12_UMD_PSTATE_MCLK_LEVEL].value; + } + + if (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[0].value; + } + + if (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + } + } + + /* honour DAL's UCLK Hardmin */ + if (dpm_table->dpm_state.hard_min_level < (hwmgr->display_config->min_mem_set_clock / 100)) + dpm_table->dpm_state.hard_min_level = hwmgr->display_config->min_mem_set_clock / 100; + + /* Hardmin is dependent on displayconfig */ + if (disable_mclk_switching) { + dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + for (i = 0; i < data->mclk_latency_table.count - 1; i++) { + if (data->mclk_latency_table.entries[i].latency <= latency) { + if (dpm_table->dpm_levels[i].value >= (hwmgr->display_config->min_mem_set_clock / 100)) { + dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[i].value; + break; + } + } + } + } + + if (hwmgr->display_config->nb_pstate_switch_disable) + dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + + /* vclk */ + dpm_table = &(data->dpm_table.vclk_table); + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + + if (PP_CAP(PHM_PlatformCaps_UMDPState)) { + if (VEGA12_UMD_PSTATE_UVDCLK_LEVEL < dpm_table->count) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[VEGA12_UMD_PSTATE_UVDCLK_LEVEL].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[VEGA12_UMD_PSTATE_UVDCLK_LEVEL].value; + } + + if (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + } + } + + /* dclk */ + dpm_table = &(data->dpm_table.dclk_table); + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + + if (PP_CAP(PHM_PlatformCaps_UMDPState)) { + if (VEGA12_UMD_PSTATE_UVDCLK_LEVEL < dpm_table->count) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[VEGA12_UMD_PSTATE_UVDCLK_LEVEL].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[VEGA12_UMD_PSTATE_UVDCLK_LEVEL].value; + } + + if (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + } + } + + /* socclk */ + dpm_table = &(data->dpm_table.soc_table); + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + + if (PP_CAP(PHM_PlatformCaps_UMDPState)) { + if (VEGA12_UMD_PSTATE_SOCCLK_LEVEL < dpm_table->count) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[VEGA12_UMD_PSTATE_SOCCLK_LEVEL].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[VEGA12_UMD_PSTATE_SOCCLK_LEVEL].value; + } + + if (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + } + } + + /* eclk */ + dpm_table = &(data->dpm_table.eclk_table); + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; + dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + + if (PP_CAP(PHM_PlatformCaps_UMDPState)) { + if (VEGA12_UMD_PSTATE_VCEMCLK_LEVEL < dpm_table->count) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[VEGA12_UMD_PSTATE_VCEMCLK_LEVEL].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[VEGA12_UMD_PSTATE_VCEMCLK_LEVEL].value; + } + + if (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) { + dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + } + } + + return 0; +} + static int vega12_display_configuration_changed_task(struct pp_hwmgr *hwmgr) { struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); @@ -2202,6 +2362,8 @@ static const struct pp_hwmgr_func vega12_hwmgr_funcs = { .display_clock_voltage_request = vega12_display_clock_voltage_request, .force_clock_level = vega12_force_clock_level, .print_clock_levels = vega12_print_clock_levels, + .apply_clocks_adjust_rules = + vega12_apply_clocks_adjust_rules, .display_config_changed = vega12_display_configuration_changed_task, .powergate_uvd = vega12_power_gate_uvd, .powergate_vce = vega12_power_gate_vce, diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h index e18c08308602..e17237c90eea 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h @@ -443,6 +443,8 @@ struct vega12_hwmgr { #define VEGA12_UMD_PSTATE_GFXCLK_LEVEL 0x3 #define VEGA12_UMD_PSTATE_SOCCLK_LEVEL 0x3 #define VEGA12_UMD_PSTATE_MCLK_LEVEL 0x2 +#define VEGA12_UMD_PSTATE_UVDCLK_LEVEL 0x3 +#define VEGA12_UMD_PSTATE_VCEMCLK_LEVEL 0x3 int vega12_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable); From 28a7b4f4498546c0d4d41c084abd0496f9922bf3 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 11 Jun 2018 17:22:33 +0800 Subject: [PATCH 083/133] drm/amd/powerplay: set vega12 pre display configurations Set num_displays to 0 and force uclk high as part of the mode set sequence. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index d28227efe906..e899a0cdbb0d 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -2110,6 +2110,45 @@ static int vega12_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr) return 0; } +static int vega12_set_uclk_to_highest_dpm_level(struct pp_hwmgr *hwmgr, + struct vega12_single_dpm_table *dpm_table) +{ + struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); + int ret = 0; + + if (data->smu_features[GNLD_DPM_UCLK].enabled) { + PP_ASSERT_WITH_CODE(dpm_table->count > 0, + "[SetUclkToHightestDpmLevel] Dpm table has no entry!", + return -EINVAL); + PP_ASSERT_WITH_CODE(dpm_table->count <= NUM_UCLK_DPM_LEVELS, + "[SetUclkToHightestDpmLevel] Dpm table has too many entries!", + return -EINVAL); + + dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + 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)), + "[SetUclkToHightestDpmLevel] Set hard min uclk failed!", + return ret); + } + + return ret; +} + +static int vega12_pre_display_configuration_changed_task(struct pp_hwmgr *hwmgr) +{ + struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); + int ret = 0; + + smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_NumOfDisplays, 0); + + ret = vega12_set_uclk_to_highest_dpm_level(hwmgr, + &data->dpm_table.mem_table); + + return ret; +} + static int vega12_display_configuration_changed_task(struct pp_hwmgr *hwmgr) { struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); @@ -2364,6 +2403,8 @@ static const struct pp_hwmgr_func vega12_hwmgr_funcs = { .print_clock_levels = vega12_print_clock_levels, .apply_clocks_adjust_rules = vega12_apply_clocks_adjust_rules, + .pre_display_config_changed = + vega12_pre_display_configuration_changed_task, .display_config_changed = vega12_display_configuration_changed_task, .powergate_uvd = vega12_power_gate_uvd, .powergate_vce = vega12_power_gate_vce, From 6ad87101f3a34ea2b955a09dde085e4e9901bab9 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 11 Jun 2018 16:46:40 +0800 Subject: [PATCH 084/133] drm/amd/powerplay: correct vega12 thermal support as true Thermal support is enabled on vega12. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index e899a0cdbb0d..6bc5f253ce8d 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -81,6 +81,7 @@ static void vega12_set_default_registry_data(struct pp_hwmgr *hwmgr) data->registry_data.disallowed_features = 0x0; data->registry_data.od_state_in_dc_support = 0; + data->registry_data.thermal_support = 1; data->registry_data.skip_baco_hardware = 0; data->registry_data.log_avfs_param = 0; From 0c3d01744511f053c5f67737cb7a6a99c0216a84 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 11 Jun 2018 16:48:43 +0800 Subject: [PATCH 085/133] drm/amd/powerplay: cosmetic fix Fix coding style and drop unused variable. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 10 +++------- .../amd/powerplay/inc/vega12/smu9_driver_if.h | 18 +++++++++--------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 6bc5f253ce8d..a86777954ea7 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -811,9 +811,6 @@ static int vega12_enable_all_smu_features(struct pp_hwmgr *hwmgr) enabled = (features_enabled & data->smu_features[i].smu_feature_bitmap) ? true : false; data->smu_features[i].enabled = enabled; data->smu_features[i].supported = enabled; - PP_ASSERT( - !data->smu_features[i].allowed || enabled, - "[EnableAllSMUFeatures] Enabled feature is different from allowed, expected disabled!"); } } @@ -1230,8 +1227,8 @@ static int vega12_get_current_gfx_clk_freq(struct pp_hwmgr *hwmgr, uint32_t *gfx *gfx_freq = 0; - PP_ASSERT_WITH_CODE( - smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetDpmClockFreq, (PPCLK_GFXCLK << 16)) == 0, + PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_GetDpmClockFreq, (PPCLK_GFXCLK << 16)) == 0, "[GetCurrentGfxClkFreq] Attempt to get Current GFXCLK Frequency Failed!", return -1); PP_ASSERT_WITH_CODE( @@ -1790,7 +1787,6 @@ static int vega12_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, { struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); Watermarks_t *table = &(data->smc_state_table.water_marks_table); - int result = 0; uint32_t i; if (!data->registry_data.disable_water_mark && @@ -1841,7 +1837,7 @@ static int vega12_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, data->water_marks_bitmap &= ~WaterMarksLoaded; } - return result; + return 0; } static int vega12_force_clock_level(struct pp_hwmgr *hwmgr, diff --git a/drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h b/drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h index b08526fd1619..b6ffd08784e7 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h +++ b/drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h @@ -412,10 +412,10 @@ typedef struct { QuadraticInt_t ReservedEquation2; QuadraticInt_t ReservedEquation3; - uint16_t MinVoltageUlvGfx; - uint16_t MinVoltageUlvSoc; + uint16_t MinVoltageUlvGfx; + uint16_t MinVoltageUlvSoc; - uint32_t Reserved[14]; + uint32_t Reserved[14]; @@ -483,9 +483,9 @@ typedef struct { uint8_t padding8_4; - uint8_t PllGfxclkSpreadEnabled; - uint8_t PllGfxclkSpreadPercent; - uint16_t PllGfxclkSpreadFreq; + uint8_t PllGfxclkSpreadEnabled; + uint8_t PllGfxclkSpreadPercent; + uint16_t PllGfxclkSpreadFreq; uint8_t UclkSpreadEnabled; uint8_t UclkSpreadPercent; @@ -495,9 +495,9 @@ typedef struct { uint8_t SocclkSpreadPercent; uint16_t SocclkSpreadFreq; - uint8_t AcgGfxclkSpreadEnabled; - uint8_t AcgGfxclkSpreadPercent; - uint16_t AcgGfxclkSpreadFreq; + uint8_t AcgGfxclkSpreadEnabled; + uint8_t AcgGfxclkSpreadPercent; + uint16_t AcgGfxclkSpreadFreq; uint8_t Vr2_I2C_address; uint8_t padding_vr2[3]; From 102c16a0246d77043e555e1e5b5de316bc068cbc Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Mon, 25 Jun 2018 21:09:04 -0400 Subject: [PATCH 086/133] drm/amdgpu: Make struct amdgpu_atif private to amdgpu_acpi.c Currently, there is nothing in amdgpu that actually uses these structs other than amdgpu_acpi.c. Additionally, since we're about to start saving the correct ACPI handle to use for calling ATIF in this struct this saves us from having to handle making sure that the acpi_handle (and by proxy, the type definition for acpi_handle and all of the other acpi headers) doesn't need to be included within the amdgpu_drv struct itself. This follows the example set by amdgpu_atpx_handler.c. Signed-off-by: Lyude Paul Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 40 +----------------- drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 54 ++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 86e4d8bd52a6..219fea72beeb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -190,6 +190,7 @@ struct amdgpu_job; struct amdgpu_irq_src; struct amdgpu_fpriv; struct amdgpu_bo_va_mapping; +struct amdgpu_atif; enum amdgpu_cp_irq { AMDGPU_CP_IRQ_GFX_EOP = 0, @@ -1278,43 +1279,6 @@ struct amdgpu_vram_scratch { /* * ACPI */ -struct amdgpu_atif_notification_cfg { - bool enabled; - int command_code; -}; - -struct amdgpu_atif_notifications { - bool display_switch; - bool expansion_mode_change; - bool thermal_state; - bool forced_power_state; - bool system_power_state; - bool display_conf_change; - bool px_gfx_switch; - bool brightness_change; - bool dgpu_display_event; -}; - -struct amdgpu_atif_functions { - bool system_params; - bool sbios_requests; - bool select_active_disp; - bool lid_state; - bool get_tv_standard; - bool set_tv_standard; - bool get_panel_expansion_mode; - bool set_panel_expansion_mode; - bool temperature_change; - bool graphics_device_types; -}; - -struct amdgpu_atif { - struct amdgpu_atif_notifications notifications; - struct amdgpu_atif_functions functions; - struct amdgpu_atif_notification_cfg notification_cfg; - struct amdgpu_encoder *encoder_for_bl; -}; - struct amdgpu_atcs_functions { bool get_ext_state; bool pcie_perf_req; @@ -1475,7 +1439,7 @@ struct amdgpu_device { #if defined(CONFIG_DEBUG_FS) struct dentry *debugfs_regs[AMDGPU_DEBUGFS_MAX_COMPONENTS]; #endif - struct amdgpu_atif atif; + struct amdgpu_atif *atif; struct amdgpu_atcs atcs; struct mutex srbm_mutex; /* GRBM index mutex. Protects concurrent access to GRBM index */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c index 8fa850a070e0..22c7e8ec0b9a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c @@ -34,6 +34,43 @@ #include "amd_acpi.h" #include "atom.h" +struct amdgpu_atif_notification_cfg { + bool enabled; + int command_code; +}; + +struct amdgpu_atif_notifications { + bool display_switch; + bool expansion_mode_change; + bool thermal_state; + bool forced_power_state; + bool system_power_state; + bool display_conf_change; + bool px_gfx_switch; + bool brightness_change; + bool dgpu_display_event; +}; + +struct amdgpu_atif_functions { + bool system_params; + bool sbios_requests; + bool select_active_disp; + bool lid_state; + bool get_tv_standard; + bool set_tv_standard; + bool get_panel_expansion_mode; + bool set_panel_expansion_mode; + bool temperature_change; + bool graphics_device_types; +}; + +struct amdgpu_atif { + struct amdgpu_atif_notifications notifications; + struct amdgpu_atif_functions functions; + struct amdgpu_atif_notification_cfg notification_cfg; + struct amdgpu_encoder *encoder_for_bl; +}; + /* Call the ATIF method */ /** @@ -292,7 +329,7 @@ static int amdgpu_atif_get_sbios_requests(acpi_handle handle, static int amdgpu_atif_handler(struct amdgpu_device *adev, struct acpi_bus_event *event) { - struct amdgpu_atif *atif = &adev->atif; + struct amdgpu_atif *atif = adev->atif; struct atif_sbios_requests req; acpi_handle handle; int count; @@ -303,7 +340,8 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev, if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0) return NOTIFY_DONE; - if (!atif->notification_cfg.enabled || + if (!atif || + !atif->notification_cfg.enabled || event->type != atif->notification_cfg.command_code) /* Not our event */ return NOTIFY_DONE; @@ -642,7 +680,7 @@ static int amdgpu_acpi_event(struct notifier_block *nb, int amdgpu_acpi_init(struct amdgpu_device *adev) { acpi_handle handle; - struct amdgpu_atif *atif = &adev->atif; + struct amdgpu_atif *atif; struct amdgpu_atcs *atcs = &adev->atcs; int ret; @@ -659,11 +697,19 @@ int amdgpu_acpi_init(struct amdgpu_device *adev) } /* Call the ATIF method */ + atif = kzalloc(sizeof(*atif), GFP_KERNEL); + if (!atif) { + DRM_WARN("Not enough memory to initialize ATIF\n"); + goto out; + } + ret = amdgpu_atif_verify_interface(handle, atif); if (ret) { DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret); + kfree(atif); goto out; } + adev->atif = atif; if (atif->notifications.brightness_change) { struct drm_encoder *tmp; @@ -720,4 +766,6 @@ int amdgpu_acpi_init(struct amdgpu_device *adev) void amdgpu_acpi_fini(struct amdgpu_device *adev) { unregister_acpi_notifier(&adev->acpi_nb); + if (adev->atif) + kfree(adev->atif); } From aa03c075d02f89ae5acae10df1c8a3b095a440e7 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Mon, 25 Jun 2018 21:09:05 -0400 Subject: [PATCH 087/133] drm/amdgpu: s/disp_detetion_ports/disp_detection_ports/ Fix typo. Reviewed-by: Jim Qu Signed-off-by: Lyude Paul Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index daa06e7c5bb7..a3896412a019 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -32,7 +32,7 @@ struct amdgpu_atpx_functions { bool switch_start; bool switch_end; bool disp_connectors_mapping; - bool disp_detetion_ports; + bool disp_detection_ports; }; struct amdgpu_atpx { @@ -156,7 +156,7 @@ static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mas f->switch_start = mask & ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED; f->switch_end = mask & ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED; f->disp_connectors_mapping = mask & ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED; - f->disp_detetion_ports = mask & ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED; + f->disp_detection_ports = mask & ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED; } /** From 24aeefcdee255d21cc43bb511d5fdb760062199d Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Mon, 25 Jun 2018 21:09:06 -0400 Subject: [PATCH 088/133] drm/amdgpu: Add amdgpu_atpx_get_dhandle() Since it seems that some vendors are storing the ATIF ACPI methods under the same handle that ATPX lives under instead of the device's own handle, we're going to need to be able to retrieve this handle later so we can probe for ATIF there. Signed-off-by: Lyude Paul Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 6 ++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 219fea72beeb..8a440b9fa0fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1867,6 +1867,12 @@ static inline bool amdgpu_atpx_dgpu_req_power_for_displays(void) { return false; static inline bool amdgpu_has_atpx(void) { return false; } #endif +#if defined(CONFIG_VGA_SWITCHEROO) && defined(CONFIG_ACPI) +void *amdgpu_atpx_get_dhandle(void); +#else +static inline void *amdgpu_atpx_get_dhandle(void) { return NULL; } +#endif + /* * KMS */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index a3896412a019..b33f1680c9a3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -90,6 +90,12 @@ bool amdgpu_atpx_dgpu_req_power_for_displays(void) { return amdgpu_atpx_priv.atpx.dgpu_req_power_for_displays; } +#if defined(CONFIG_ACPI) +void *amdgpu_atpx_get_dhandle(void) { + return amdgpu_atpx_priv.dhandle; +} +#endif + /** * amdgpu_atpx_call - call an ATPX method * From 280cf1a94b822dfa2b505afcd24979dae643d6bf Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Mon, 25 Jun 2018 21:09:07 -0400 Subject: [PATCH 089/133] drm/amdgpu: Dynamically probe for ATIF handle (v2) The other day I was testing one of the HP laptops at my office with an i915/amdgpu hybrid setup and noticed that hotplugging was non-functional on almost all of the display outputs. I eventually discovered that all of the external outputs were connected to the amdgpu device instead of i915, and that the hotplugs weren't being detected so long as the GPU was in runtime suspend. After some talking with folks at AMD, I learned that amdgpu is actually supposed to support hotplug detection in runtime suspend so long as the OEM has implemented it properly in the firmware. On this HP ZBook 15 G4 (the machine in question), amdgpu wasn't managing to find the ATIF handle at all despite the fact that I could see acpi events being sent in response to any hotplugging. After going through dumps of the firmware, I discovered that this machine did in fact support ATIF, but that it's ATIF method lived in an entirely different namespace than this device's handle (the device handle was \_SB_.PCI0.PEG0.PEGP, but ATIF lives in ATPX's handle at \_SB_.PCI0.GFX0). So, fix this by probing ATPX's ACPI parent's namespace if we can't find ATIF elsewhere, along with storing a pointer to the proper handle to use for ATIF and using that instead of the device's handle. This fixes HPD detection while in runtime suspend for this ZBook! v2: Update the comment to reflect how the namespaces are arranged based on the system configuration. (Alex) Signed-off-by: Lyude Paul Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 79 +++++++++++++++++------- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c index 22c7e8ec0b9a..0d8c3fc6eace 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c @@ -65,6 +65,8 @@ struct amdgpu_atif_functions { }; struct amdgpu_atif { + acpi_handle handle; + struct amdgpu_atif_notifications notifications; struct amdgpu_atif_functions functions; struct amdgpu_atif_notification_cfg notification_cfg; @@ -83,8 +85,9 @@ struct amdgpu_atif { * Executes the requested ATIF function (all asics). * Returns a pointer to the acpi output buffer. */ -static union acpi_object *amdgpu_atif_call(acpi_handle handle, int function, - struct acpi_buffer *params) +static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif, + int function, + struct acpi_buffer *params) { acpi_status status; union acpi_object atif_arg_elements[2]; @@ -107,7 +110,8 @@ static union acpi_object *amdgpu_atif_call(acpi_handle handle, int function, atif_arg_elements[1].integer.value = 0; } - status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer); + status = acpi_evaluate_object(atif->handle, NULL, &atif_arg, + &buffer); /* Fail only if calling the method fails and ATIF is supported */ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { @@ -178,15 +182,14 @@ static void amdgpu_atif_parse_functions(struct amdgpu_atif_functions *f, u32 mas * (all asics). * returns 0 on success, error on failure. */ -static int amdgpu_atif_verify_interface(acpi_handle handle, - struct amdgpu_atif *atif) +static int amdgpu_atif_verify_interface(struct amdgpu_atif *atif) { union acpi_object *info; struct atif_verify_interface output; size_t size; int err = 0; - info = amdgpu_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); + info = amdgpu_atif_call(atif, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); if (!info) return -EIO; @@ -213,6 +216,35 @@ static int amdgpu_atif_verify_interface(acpi_handle handle, return err; } +static acpi_handle amdgpu_atif_probe_handle(acpi_handle dhandle) +{ + acpi_handle handle = NULL; + char acpi_method_name[255] = { 0 }; + struct acpi_buffer buffer = { sizeof(acpi_method_name), acpi_method_name }; + acpi_status status; + + /* For PX/HG systems, ATIF and ATPX are in the iGPU's namespace, on dGPU only + * systems, ATIF is in the dGPU's namespace. + */ + status = acpi_get_handle(dhandle, "ATIF", &handle); + if (ACPI_SUCCESS(status)) + goto out; + + if (amdgpu_has_atpx()) { + status = acpi_get_handle(amdgpu_atpx_get_dhandle(), "ATIF", + &handle); + if (ACPI_SUCCESS(status)) + goto out; + } + + DRM_DEBUG_DRIVER("No ATIF handle found\n"); + return NULL; +out: + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + DRM_DEBUG_DRIVER("Found ATIF handle %s\n", acpi_method_name); + return handle; +} + /** * amdgpu_atif_get_notification_params - determine notify configuration * @@ -225,15 +257,16 @@ static int amdgpu_atif_verify_interface(acpi_handle handle, * where n is specified in the result if a notifier is used. * Returns 0 on success, error on failure. */ -static int amdgpu_atif_get_notification_params(acpi_handle handle, - struct amdgpu_atif_notification_cfg *n) +static int amdgpu_atif_get_notification_params(struct amdgpu_atif *atif) { union acpi_object *info; + struct amdgpu_atif_notification_cfg *n = &atif->notification_cfg; struct atif_system_params params; size_t size; int err = 0; - info = amdgpu_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL); + info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, + NULL); if (!info) { err = -EIO; goto out; @@ -287,14 +320,15 @@ static int amdgpu_atif_get_notification_params(acpi_handle handle, * (all asics). * Returns 0 on success, error on failure. */ -static int amdgpu_atif_get_sbios_requests(acpi_handle handle, - struct atif_sbios_requests *req) +static int amdgpu_atif_get_sbios_requests(struct amdgpu_atif *atif, + struct atif_sbios_requests *req) { union acpi_object *info; size_t size; int count = 0; - info = amdgpu_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL); + info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, + NULL); if (!info) return -EIO; @@ -327,11 +361,10 @@ static int amdgpu_atif_get_sbios_requests(acpi_handle handle, * Returns NOTIFY code */ static int amdgpu_atif_handler(struct amdgpu_device *adev, - struct acpi_bus_event *event) + struct acpi_bus_event *event) { struct amdgpu_atif *atif = adev->atif; struct atif_sbios_requests req; - acpi_handle handle; int count; DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n", @@ -347,8 +380,7 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev, return NOTIFY_DONE; /* Check pending SBIOS requests */ - handle = ACPI_HANDLE(&adev->pdev->dev); - count = amdgpu_atif_get_sbios_requests(handle, &req); + count = amdgpu_atif_get_sbios_requests(atif, &req); if (count <= 0) return NOTIFY_DONE; @@ -679,7 +711,7 @@ static int amdgpu_acpi_event(struct notifier_block *nb, */ int amdgpu_acpi_init(struct amdgpu_device *adev) { - acpi_handle handle; + acpi_handle handle, atif_handle; struct amdgpu_atif *atif; struct amdgpu_atcs *atcs = &adev->atcs; int ret; @@ -696,14 +728,20 @@ int amdgpu_acpi_init(struct amdgpu_device *adev) DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret); } - /* Call the ATIF method */ + /* Probe for ATIF, and initialize it if found */ + atif_handle = amdgpu_atif_probe_handle(handle); + if (!atif_handle) + goto out; + atif = kzalloc(sizeof(*atif), GFP_KERNEL); if (!atif) { DRM_WARN("Not enough memory to initialize ATIF\n"); goto out; } + atif->handle = atif_handle; - ret = amdgpu_atif_verify_interface(handle, atif); + /* Call the ATIF method */ + ret = amdgpu_atif_verify_interface(atif); if (ret) { DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret); kfree(atif); @@ -739,8 +777,7 @@ int amdgpu_acpi_init(struct amdgpu_device *adev) } if (atif->functions.system_params) { - ret = amdgpu_atif_get_notification_params(handle, - &atif->notification_cfg); + ret = amdgpu_atif_get_notification_params(atif); if (ret) { DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n", ret); From 9735bf1930e658b074d72ea46bb317ad12483692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 15 Jun 2018 16:37:03 +0200 Subject: [PATCH 090/133] drm/amdgpu: Use gmc_vram_full_visible in vram_mgr_bo_invisible_size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michel Dänzer Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c index b6333f92ba45..f7a4bd5885a3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -112,7 +112,7 @@ u64 amdgpu_vram_mgr_bo_invisible_size(struct amdgpu_bo *bo) unsigned pages = mem->num_pages; u64 usage = 0; - if (adev->gmc.visible_vram_size == adev->gmc.real_vram_size) + if (amdgpu_gmc_vram_full_visible(&adev->gmc)) return 0; if (mem->start >= adev->gmc.visible_vram_size >> PAGE_SHIFT) From 463d2fe85b0eacb3760febe100994d4eb8fedde9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 22 Jun 2018 18:54:03 +0200 Subject: [PATCH 091/133] drm/amdgpu: Add AMDGPU_GPU_PAGES_IN_CPU_PAGE define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To hopefully make the code dealing with GPU vs CPU pages a little clearer. Suggested-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 8 ++++---- drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 8 ++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index dd11b7313ca0..36113cb60ca2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -234,7 +234,7 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset, } t = offset / AMDGPU_GPU_PAGE_SIZE; - p = t / (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); + p = t / AMDGPU_GPU_PAGES_IN_CPU_PAGE; for (i = 0; i < pages; i++, p++) { #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS adev->gart.pages[p] = NULL; @@ -243,7 +243,7 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset, if (!adev->gart.ptr) continue; - for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) { + for (j = 0; j < AMDGPU_GPU_PAGES_IN_CPU_PAGE; j++, t++) { amdgpu_gmc_set_pte_pde(adev, adev->gart.ptr, t, page_base, flags); page_base += AMDGPU_GPU_PAGE_SIZE; @@ -282,7 +282,7 @@ int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset, for (i = 0; i < pages; i++) { page_base = dma_addr[i]; - for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) { + for (j = 0; j < AMDGPU_GPU_PAGES_IN_CPU_PAGE; j++, t++) { amdgpu_gmc_set_pte_pde(adev, dst, t, page_base, flags); page_base += AMDGPU_GPU_PAGE_SIZE; } @@ -319,7 +319,7 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset, #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS t = offset / AMDGPU_GPU_PAGE_SIZE; - p = t / (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); + p = t / AMDGPU_GPU_PAGES_IN_CPU_PAGE; for (i = 0; i < pages; i++, p++) adev->gart.pages[p] = pagelist ? pagelist[i] : NULL; #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h index 456295c00291..9f9e9dc87da1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h @@ -37,6 +37,8 @@ struct amdgpu_bo; #define AMDGPU_GPU_PAGE_SHIFT 12 #define AMDGPU_GPU_PAGE_ALIGN(a) (((a) + AMDGPU_GPU_PAGE_MASK) & ~AMDGPU_GPU_PAGE_MASK) +#define AMDGPU_GPU_PAGES_IN_CPU_PAGE (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE) + struct amdgpu_gart { u64 table_addr; struct amdgpu_bo *robj; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 837066076ccf..712af5c1a5d6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1567,7 +1567,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, if (nodes) { addr = nodes->start << PAGE_SHIFT; max_entries = (nodes->size - pfn) * - (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); + AMDGPU_GPU_PAGES_IN_CPU_PAGE; } else { addr = 0; max_entries = S64_MAX; @@ -1578,7 +1578,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, max_entries = min(max_entries, 16ull * 1024ull); for (count = 1; - count < max_entries / (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); + count < max_entries / AMDGPU_GPU_PAGES_IN_CPU_PAGE; ++count) { uint64_t idx = pfn + count; @@ -1592,7 +1592,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, dma_addr = pages_addr; } else { addr = pages_addr[pfn]; - max_entries = count * (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); + max_entries = count * AMDGPU_GPU_PAGES_IN_CPU_PAGE; } } else if (flags & AMDGPU_PTE_VALID) { @@ -1607,7 +1607,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, if (r) return r; - pfn += (last - start + 1) / (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); + pfn += (last - start + 1) / AMDGPU_GPU_PAGES_IN_CPU_PAGE; if (nodes && nodes->size == pfn) { pfn = 0; ++nodes; From 3f37e29626b0b5dbfcdf964ef2858b36a4c2cd67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 29 Jun 2018 11:27:11 +0200 Subject: [PATCH 092/133] drm/amdgpu: Remove amdgpu_gem_map_attach target_dev documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The parameter was removed. Fixes: a19741e5e5a9 "dma_buf: remove device parameter from attach callback v2" Reviewed-by: Junwei Zhang Signed-off-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c index b2286bc41aec..df7226ad64b5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c @@ -191,7 +191,6 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev, /** * amdgpu_gem_map_attach - &dma_buf_ops.attach implementation * @dma_buf: shared DMA buffer - * @target_dev: target device * @attach: DMA-buf attachment * * Makes sure that the shared DMA buffer can be accessed by the target device. From 3413accb3eac9182ee0fc0b350a5f18247d8ac9d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 28 Jun 2018 12:38:53 -0500 Subject: [PATCH 093/133] drm/amdgpu: fix swapped emit_ib_size in vce3 The phys and vm versions had the values swapped. Reviewed-by: Junwei Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 0999c843f623..a71b97519cc0 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -900,7 +900,7 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_phys_funcs = { .emit_frame_size = 4 + /* vce_v3_0_emit_pipeline_sync */ 6, /* amdgpu_vce_ring_emit_fence x1 no user fence */ - .emit_ib_size = 5, /* vce_v3_0_ring_emit_ib */ + .emit_ib_size = 4, /* amdgpu_vce_ring_emit_ib */ .emit_ib = amdgpu_vce_ring_emit_ib, .emit_fence = amdgpu_vce_ring_emit_fence, .test_ring = amdgpu_vce_ring_test_ring, @@ -924,7 +924,7 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_vm_funcs = { 6 + /* vce_v3_0_emit_vm_flush */ 4 + /* vce_v3_0_emit_pipeline_sync */ 6 + 6, /* amdgpu_vce_ring_emit_fence x2 vm fence */ - .emit_ib_size = 4, /* amdgpu_vce_ring_emit_ib */ + .emit_ib_size = 5, /* vce_v3_0_ring_emit_ib */ .emit_ib = vce_v3_0_ring_emit_ib, .emit_vm_flush = vce_v3_0_emit_vm_flush, .emit_pipeline_sync = vce_v3_0_emit_pipeline_sync, From 70eb46db101b55acdf432187800915f72962a564 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 28 Jun 2018 12:44:25 -0500 Subject: [PATCH 094/133] drm/amdgpu/pm: fix display count in non-DC path new_active_crtcs is a bitmask, new_active_crtc_count is the actual count. Reviewed-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index a003fd881a89..f1404adc3a90 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1959,7 +1959,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) if (!amdgpu_device_has_dc_support(adev)) { mutex_lock(&adev->pm.mutex); amdgpu_dpm_get_active_displays(adev); - adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtcs; + adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtc_count; adev->pm.pm_display_cfg.vrefresh = amdgpu_dpm_get_vrefresh(adev); adev->pm.pm_display_cfg.min_vblank_time = amdgpu_dpm_get_vblank_time(adev); /* we have issues with mclk switching with refresh rates over 120 hz on the non-DC code. */ From c9037d44390cc1ef7ec490c63ec8a4ee92a57925 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 28 Jun 2018 12:48:10 -0500 Subject: [PATCH 095/133] drm/amdgpu/pp: add missing byte swapping in process_pptables_v1_0.c Values need to be swapped on big endian. Reviewed-by: Rex Zhu Signed-off-by: Alex Deucher --- .../gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c b/drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c index 35bd9870ab10..4e1fd5393845 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c @@ -183,10 +183,10 @@ static int get_vddc_lookup_table( ATOM_Tonga_Voltage_Lookup_Record, entries, vddc_lookup_pp_tables, i); record->us_calculated = 0; - record->us_vdd = atom_record->usVdd; - record->us_cac_low = atom_record->usCACLow; - record->us_cac_mid = atom_record->usCACMid; - record->us_cac_high = atom_record->usCACHigh; + record->us_vdd = le16_to_cpu(atom_record->usVdd); + record->us_cac_low = le16_to_cpu(atom_record->usCACLow); + record->us_cac_mid = le16_to_cpu(atom_record->usCACMid); + record->us_cac_high = le16_to_cpu(atom_record->usCACHigh); } *lookup_table = table; From 594c34cc6f31807f23aae5c9cec6dea31d782f90 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 28 Jun 2018 12:51:06 -0500 Subject: [PATCH 096/133] drm/amdgpu/pp: fix endian swapping in atomctrl_get_voltage_range Need to swap before doing arthimetic on the values. Reviewed-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c index 7047e29755c3..01dc46dc9c8a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c @@ -1544,14 +1544,14 @@ void atomctrl_get_voltage_range(struct pp_hwmgr *hwmgr, uint32_t *max_vddc, switch (hwmgr->chip_id) { case CHIP_TONGA: case CHIP_FIJI: - *max_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_3 *)profile)->ulMaxVddc/4); - *min_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_3 *)profile)->ulMinVddc/4); + *max_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_3 *)profile)->ulMaxVddc) / 4; + *min_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_3 *)profile)->ulMinVddc) / 4; return; case CHIP_POLARIS11: case CHIP_POLARIS10: case CHIP_POLARIS12: - *max_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_6 *)profile)->ulMaxVddc/100); - *min_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_6 *)profile)->ulMinVddc/100); + *max_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_6 *)profile)->ulMaxVddc) / 100; + *min_vddc = le32_to_cpu(((ATOM_ASIC_PROFILING_INFO_V3_6 *)profile)->ulMinVddc) / 100; return; default: break; From 9861023c29dbc069e49dc85fb21f01da9f75ff06 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 28 Jun 2018 12:52:43 -0500 Subject: [PATCH 097/133] drm/amdgpu/pp: fix copy paste typo in smu7_init_dpm_defaults Should be mclk rather than sclk. Reviewed-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index de295b7442b7..e5c27d12aa49 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -1578,7 +1578,7 @@ static void smu7_init_dpm_defaults(struct pp_hwmgr *hwmgr) data->current_profile_setting.sclk_up_hyst = 0; data->current_profile_setting.sclk_down_hyst = 100; data->current_profile_setting.sclk_activity = SMU7_SCLK_TARGETACTIVITY_DFLT; - data->current_profile_setting.bupdate_sclk = 1; + data->current_profile_setting.bupdate_mclk = 1; data->current_profile_setting.mclk_up_hyst = 0; data->current_profile_setting.mclk_down_hyst = 100; data->current_profile_setting.mclk_activity = SMU7_MCLK_TARGETACTIVITY_DFLT; From ed54d954e5c1d8bad453fb86109075b3577152b7 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 28 Jun 2018 13:21:12 -0500 Subject: [PATCH 098/133] drm/amdgpu/pp: fix copy paste typo in smu7_get_pp_table_entry_callback_func_v1 Should be using PCIELaneLow for the low clock level. Reviewed-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index e5c27d12aa49..077b79938528 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -3183,7 +3183,7 @@ static int smu7_get_pp_table_entry_callback_func_v1(struct pp_hwmgr *hwmgr, performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, state_entry->ucPCIEGenLow); performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap, - state_entry->ucPCIELaneHigh); + state_entry->ucPCIELaneLow); performance_level = &(smu7_power_state->performance_levels [smu7_power_state->performance_level_count++]); From 1cf0abb6c983d90ec541ebba79934a9c4786df1d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 25 Jun 2018 12:24:10 -0500 Subject: [PATCH 099/133] drm/amdgpu/sdma: simplify sdma instance setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set the me instance in early init and use that rather than calculating the instance based on the ring pointer. Reviewed-by: James Zhu Reviewed-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/cik_sdma.c | 12 ++++++------ drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | 12 ++++++------ drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 14 ++++++-------- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 23 +++++++++++------------ 4 files changed, 29 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index a7576255cc30..dbd553a8d584 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c @@ -177,9 +177,8 @@ static uint64_t cik_sdma_ring_get_rptr(struct amdgpu_ring *ring) static uint64_t cik_sdma_ring_get_wptr(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; - u32 me = (ring == &adev->sdma.instance[0].ring) ? 0 : 1; - return (RREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[me]) & 0x3fffc) >> 2; + return (RREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[ring->me]) & 0x3fffc) >> 2; } /** @@ -192,9 +191,8 @@ static uint64_t cik_sdma_ring_get_wptr(struct amdgpu_ring *ring) static void cik_sdma_ring_set_wptr(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; - u32 me = (ring == &adev->sdma.instance[0].ring) ? 0 : 1; - WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[me], + WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[ring->me], (lower_32_bits(ring->wptr) << 2) & 0x3fffc); } @@ -248,7 +246,7 @@ static void cik_sdma_ring_emit_hdp_flush(struct amdgpu_ring *ring) SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */ u32 ref_and_mask; - if (ring == &ring->adev->sdma.instance[0].ring) + if (ring->me == 0) ref_and_mask = GPU_HDP_FLUSH_DONE__SDMA0_MASK; else ref_and_mask = GPU_HDP_FLUSH_DONE__SDMA1_MASK; @@ -1290,8 +1288,10 @@ static void cik_sdma_set_ring_funcs(struct amdgpu_device *adev) { int i; - for (i = 0; i < adev->sdma.num_instances; i++) + for (i = 0; i < adev->sdma.num_instances; i++) { adev->sdma.instance[i].ring.funcs = &cik_sdma_ring_funcs; + adev->sdma.instance[i].ring.me = i; + } } static const struct amdgpu_irq_src_funcs cik_sdma_trap_irq_funcs = { diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index c7190c39c4f5..cee4fae76d20 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c @@ -202,8 +202,7 @@ static uint64_t sdma_v2_4_ring_get_rptr(struct amdgpu_ring *ring) static uint64_t sdma_v2_4_ring_get_wptr(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; - int me = (ring == &ring->adev->sdma.instance[0].ring) ? 0 : 1; - u32 wptr = RREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[me]) >> 2; + u32 wptr = RREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[ring->me]) >> 2; return wptr; } @@ -218,9 +217,8 @@ static uint64_t sdma_v2_4_ring_get_wptr(struct amdgpu_ring *ring) static void sdma_v2_4_ring_set_wptr(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; - int me = (ring == &ring->adev->sdma.instance[0].ring) ? 0 : 1; - WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[me], lower_32_bits(ring->wptr) << 2); + WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[ring->me], lower_32_bits(ring->wptr) << 2); } static void sdma_v2_4_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) @@ -273,7 +271,7 @@ static void sdma_v2_4_ring_emit_hdp_flush(struct amdgpu_ring *ring) { u32 ref_and_mask = 0; - if (ring == &ring->adev->sdma.instance[0].ring) + if (ring->me == 0) ref_and_mask = REG_SET_FIELD(ref_and_mask, GPU_HDP_FLUSH_DONE, SDMA0, 1); else ref_and_mask = REG_SET_FIELD(ref_and_mask, GPU_HDP_FLUSH_DONE, SDMA1, 1); @@ -1213,8 +1211,10 @@ static void sdma_v2_4_set_ring_funcs(struct amdgpu_device *adev) { int i; - for (i = 0; i < adev->sdma.num_instances; i++) + for (i = 0; i < adev->sdma.num_instances; i++) { adev->sdma.instance[i].ring.funcs = &sdma_v2_4_ring_funcs; + adev->sdma.instance[i].ring.me = i; + } } static const struct amdgpu_irq_src_funcs sdma_v2_4_trap_irq_funcs = { diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index aa9ab299fd32..99616dd9594f 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -365,9 +365,7 @@ static uint64_t sdma_v3_0_ring_get_wptr(struct amdgpu_ring *ring) /* XXX check if swapping is necessary on BE */ wptr = ring->adev->wb.wb[ring->wptr_offs] >> 2; } else { - int me = (ring == &ring->adev->sdma.instance[0].ring) ? 0 : 1; - - wptr = RREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[me]) >> 2; + wptr = RREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[ring->me]) >> 2; } return wptr; @@ -394,9 +392,7 @@ static void sdma_v3_0_ring_set_wptr(struct amdgpu_ring *ring) WRITE_ONCE(*wb, (lower_32_bits(ring->wptr) << 2)); } else { - int me = (ring == &ring->adev->sdma.instance[0].ring) ? 0 : 1; - - WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[me], lower_32_bits(ring->wptr) << 2); + WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[ring->me], lower_32_bits(ring->wptr) << 2); } } @@ -450,7 +446,7 @@ static void sdma_v3_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) { u32 ref_and_mask = 0; - if (ring == &ring->adev->sdma.instance[0].ring) + if (ring->me == 0) ref_and_mask = REG_SET_FIELD(ref_and_mask, GPU_HDP_FLUSH_DONE, SDMA0, 1); else ref_and_mask = REG_SET_FIELD(ref_and_mask, GPU_HDP_FLUSH_DONE, SDMA1, 1); @@ -1655,8 +1651,10 @@ static void sdma_v3_0_set_ring_funcs(struct amdgpu_device *adev) { int i; - for (i = 0; i < adev->sdma.num_instances; i++) + for (i = 0; i < adev->sdma.num_instances; i++) { adev->sdma.instance[i].ring.funcs = &sdma_v3_0_ring_funcs; + adev->sdma.instance[i].ring.me = i; + } } static const struct amdgpu_irq_src_funcs sdma_v3_0_trap_irq_funcs = { diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index ca53b3fba422..572ca63cf676 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -296,13 +296,12 @@ static uint64_t sdma_v4_0_ring_get_wptr(struct amdgpu_ring *ring) DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", wptr); } else { u32 lowbit, highbit; - int me = (ring == &adev->sdma.instance[0].ring) ? 0 : 1; - lowbit = RREG32(sdma_v4_0_get_reg_offset(adev, me, mmSDMA0_GFX_RB_WPTR)) >> 2; - highbit = RREG32(sdma_v4_0_get_reg_offset(adev, me, mmSDMA0_GFX_RB_WPTR_HI)) >> 2; + lowbit = RREG32(sdma_v4_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR)) >> 2; + highbit = RREG32(sdma_v4_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI)) >> 2; DRM_DEBUG("wptr [%i]high== 0x%08x low==0x%08x\n", - me, highbit, lowbit); + ring->me, highbit, lowbit); wptr = highbit; wptr = wptr << 32; wptr |= lowbit; @@ -339,17 +338,15 @@ static void sdma_v4_0_ring_set_wptr(struct amdgpu_ring *ring) ring->doorbell_index, ring->wptr << 2); WDOORBELL64(ring->doorbell_index, ring->wptr << 2); } else { - int me = (ring == &ring->adev->sdma.instance[0].ring) ? 0 : 1; - DRM_DEBUG("Not using doorbell -- " "mmSDMA%i_GFX_RB_WPTR == 0x%08x " "mmSDMA%i_GFX_RB_WPTR_HI == 0x%08x\n", - me, + ring->me, lower_32_bits(ring->wptr << 2), - me, + ring->me, upper_32_bits(ring->wptr << 2)); - WREG32(sdma_v4_0_get_reg_offset(adev, me, mmSDMA0_GFX_RB_WPTR), lower_32_bits(ring->wptr << 2)); - WREG32(sdma_v4_0_get_reg_offset(adev, me, mmSDMA0_GFX_RB_WPTR_HI), upper_32_bits(ring->wptr << 2)); + WREG32(sdma_v4_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR), lower_32_bits(ring->wptr << 2)); + WREG32(sdma_v4_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI), upper_32_bits(ring->wptr << 2)); } } @@ -430,7 +427,7 @@ static void sdma_v4_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) u32 ref_and_mask = 0; const struct nbio_hdp_flush_reg *nbio_hf_reg = adev->nbio_funcs->hdp_flush_reg; - if (ring == &ring->adev->sdma.instance[0].ring) + if (ring->me == 0) ref_and_mask = nbio_hf_reg->ref_and_mask_sdma0; else ref_and_mask = nbio_hf_reg->ref_and_mask_sdma1; @@ -1651,8 +1648,10 @@ static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev) { int i; - for (i = 0; i < adev->sdma.num_instances; i++) + for (i = 0; i < adev->sdma.num_instances; i++) { adev->sdma.instance[i].ring.funcs = &sdma_v4_0_ring_funcs; + adev->sdma.instance[i].ring.me = i; + } } static const struct amdgpu_irq_src_funcs sdma_v4_0_trap_irq_funcs = { From 5d4af988f39052b77f8fdd9ed5cb61ca1645a3a6 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 25 Jun 2018 12:41:21 -0500 Subject: [PATCH 100/133] drm/amdgpu/vce: simplify vce instance setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set the me instance in early init and use that rather than calculating the instance based on the ring pointer. Reviewed-by: James Zhu Reviewed-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vce_v2_0.c | 10 ++++++---- drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 20 ++++++++++++-------- drivers/gpu/drm/amd/amdgpu/vce_v4_0.c | 16 +++++++++------- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c index 47f70827195b..d48e877b682e 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c @@ -56,7 +56,7 @@ static uint64_t vce_v2_0_ring_get_rptr(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; - if (ring == &adev->vce.ring[0]) + if (ring->me == 0) return RREG32(mmVCE_RB_RPTR); else return RREG32(mmVCE_RB_RPTR2); @@ -73,7 +73,7 @@ static uint64_t vce_v2_0_ring_get_wptr(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; - if (ring == &adev->vce.ring[0]) + if (ring->me == 0) return RREG32(mmVCE_RB_WPTR); else return RREG32(mmVCE_RB_WPTR2); @@ -90,7 +90,7 @@ static void vce_v2_0_ring_set_wptr(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; - if (ring == &adev->vce.ring[0]) + if (ring->me == 0) WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr)); else WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr)); @@ -627,8 +627,10 @@ static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev) { int i; - for (i = 0; i < adev->vce.num_rings; i++) + for (i = 0; i < adev->vce.num_rings; i++) { adev->vce.ring[i].funcs = &vce_v2_0_ring_funcs; + adev->vce.ring[i].me = i; + } } static const struct amdgpu_irq_src_funcs vce_v2_0_irq_funcs = { diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index a71b97519cc0..99604d0262ad 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -86,9 +86,9 @@ static uint64_t vce_v3_0_ring_get_rptr(struct amdgpu_ring *ring) else if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(1)); - if (ring == &adev->vce.ring[0]) + if (ring->me == 0) v = RREG32(mmVCE_RB_RPTR); - else if (ring == &adev->vce.ring[1]) + else if (ring->me == 1) v = RREG32(mmVCE_RB_RPTR2); else v = RREG32(mmVCE_RB_RPTR3); @@ -118,9 +118,9 @@ static uint64_t vce_v3_0_ring_get_wptr(struct amdgpu_ring *ring) else if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(1)); - if (ring == &adev->vce.ring[0]) + if (ring->me == 0) v = RREG32(mmVCE_RB_WPTR); - else if (ring == &adev->vce.ring[1]) + else if (ring->me == 1) v = RREG32(mmVCE_RB_WPTR2); else v = RREG32(mmVCE_RB_WPTR3); @@ -149,9 +149,9 @@ static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring) else if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(1)); - if (ring == &adev->vce.ring[0]) + if (ring->me == 0) WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr)); - else if (ring == &adev->vce.ring[1]) + else if (ring->me == 1) WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr)); else WREG32(mmVCE_RB_WPTR3, lower_32_bits(ring->wptr)); @@ -942,12 +942,16 @@ static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev) int i; if (adev->asic_type >= CHIP_STONEY) { - for (i = 0; i < adev->vce.num_rings; i++) + for (i = 0; i < adev->vce.num_rings; i++) { adev->vce.ring[i].funcs = &vce_v3_0_ring_vm_funcs; + adev->vce.ring[i].me = i; + } DRM_INFO("VCE enabled in VM mode\n"); } else { - for (i = 0; i < adev->vce.num_rings; i++) + for (i = 0; i < adev->vce.num_rings; i++) { adev->vce.ring[i].funcs = &vce_v3_0_ring_phys_funcs; + adev->vce.ring[i].me = i; + } DRM_INFO("VCE enabled in physical mode\n"); } } diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c index 8fd1b742985a..575bf9709389 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c @@ -60,9 +60,9 @@ static uint64_t vce_v4_0_ring_get_rptr(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; - if (ring == &adev->vce.ring[0]) + if (ring->me == 0) return RREG32(SOC15_REG_OFFSET(VCE, 0, mmVCE_RB_RPTR)); - else if (ring == &adev->vce.ring[1]) + else if (ring->me == 1) return RREG32(SOC15_REG_OFFSET(VCE, 0, mmVCE_RB_RPTR2)); else return RREG32(SOC15_REG_OFFSET(VCE, 0, mmVCE_RB_RPTR3)); @@ -82,9 +82,9 @@ static uint64_t vce_v4_0_ring_get_wptr(struct amdgpu_ring *ring) if (ring->use_doorbell) return adev->wb.wb[ring->wptr_offs]; - if (ring == &adev->vce.ring[0]) + if (ring->me == 0) return RREG32(SOC15_REG_OFFSET(VCE, 0, mmVCE_RB_WPTR)); - else if (ring == &adev->vce.ring[1]) + else if (ring->me == 1) return RREG32(SOC15_REG_OFFSET(VCE, 0, mmVCE_RB_WPTR2)); else return RREG32(SOC15_REG_OFFSET(VCE, 0, mmVCE_RB_WPTR3)); @@ -108,10 +108,10 @@ static void vce_v4_0_ring_set_wptr(struct amdgpu_ring *ring) return; } - if (ring == &adev->vce.ring[0]) + if (ring->me == 0) WREG32(SOC15_REG_OFFSET(VCE, 0, mmVCE_RB_WPTR), lower_32_bits(ring->wptr)); - else if (ring == &adev->vce.ring[1]) + else if (ring->me == 1) WREG32(SOC15_REG_OFFSET(VCE, 0, mmVCE_RB_WPTR2), lower_32_bits(ring->wptr)); else @@ -1088,8 +1088,10 @@ static void vce_v4_0_set_ring_funcs(struct amdgpu_device *adev) { int i; - for (i = 0; i < adev->vce.num_rings; i++) + for (i = 0; i < adev->vce.num_rings; i++) { adev->vce.ring[i].funcs = &vce_v4_0_ring_vm_funcs; + adev->vce.ring[i].me = i; + } DRM_INFO("VCE enabled in VM mode\n"); } From c3c18309c8319ab4600830bc010d916cb4e529de Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 28 Jun 2018 16:10:25 +0200 Subject: [PATCH 101/133] drm/amd: Replace drm_dev_unref with drm_dev_put This patch unifies the naming of DRM functions for reference counting of struct drm_device. The resulting code is more aligned with the rest of the Linux kernel interfaces. Signed-off-by: Thomas Zimmermann Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index dcdc97d6dc44..963578c34c47 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -665,7 +665,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, err_pci: pci_disable_device(pdev); err_free: - drm_dev_unref(dev); + drm_dev_put(dev); return ret; } @@ -675,7 +675,7 @@ amdgpu_pci_remove(struct pci_dev *pdev) struct drm_device *dev = pci_get_drvdata(pdev); drm_dev_unregister(dev); - drm_dev_unref(dev); + drm_dev_put(dev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); } From 9f87830f61e79d5e2ae2529cd225cb123f7742b2 Mon Sep 17 00:00:00 2001 From: "Dirk Hohndel (VMware)" Date: Mon, 7 May 2018 01:16:20 +0200 Subject: [PATCH 102/133] drm/amd: add SPDX identifier and clarify license This is dual licensed under GPL-2.0 or MIT. Acked-by: Thomas Gleixner Signed-off-by: Dirk Hohndel (VMware) Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c index e3878256743a..57b14dccd8e0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT /* * Copyright 2009 VMware, Inc. * From da5fd66c0eb79e01501578bfc69352cc5e2e979d Mon Sep 17 00:00:00 2001 From: "Dirk Hohndel (VMware)" Date: Mon, 7 May 2018 01:16:23 +0200 Subject: [PATCH 103/133] drm/radeon: add SPDX identifier and clarify license This is dual licensed under GPL-2.0 or MIT. Acked-by: Thomas Gleixner Signed-off-by: Dirk Hohndel (VMware) Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 48f4b273e316..0c7f228db6e3 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT /* * Copyright 2009 VMware, Inc. * From f8ddb39a15100076884a625e97c91f3578c686f5 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Thu, 28 Jun 2018 14:38:21 +0800 Subject: [PATCH 104/133] drm/amdgpu: fix the wrong type of gem object creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We still use legacy type of gem_object_create, it should update to ttm_bo_type now. Signed-off-by: Huang Rui Reviewed-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index bc5fd8ebab5d..811c62927c38 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -146,7 +146,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | AMDGPU_GEM_CREATE_VRAM_CLEARED, - true, NULL, &gobj); + ttm_bo_type_kernel, NULL, &gobj); if (ret) { pr_err("failed to allocate framebuffer (%d)\n", aligned_size); return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 89743cdc1c2c..bcbdcf997d20 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -265,7 +265,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data, r = amdgpu_gem_object_create(adev, size, args->in.alignment, (u32)(0xffffffff & args->in.domains), - flags, false, resv, &gobj); + flags, ttm_bo_type_device, resv, &gobj); if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) { if (!r) { struct amdgpu_bo *abo = gem_to_amdgpu_bo(gobj); @@ -317,7 +317,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, /* create a gem object to contain this object in */ r = amdgpu_gem_object_create(adev, args->size, 0, AMDGPU_GEM_DOMAIN_CPU, - 0, 0, NULL, &gobj); + 0, ttm_bo_type_device, NULL, &gobj); if (r) return r; @@ -766,7 +766,7 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv, amdgpu_display_supported_domains(adev)); r = amdgpu_gem_object_create(adev, args->size, 0, domain, AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, - false, NULL, &gobj); + ttm_bo_type_device, NULL, &gobj); if (r) return -ENOMEM; From afb1436c7b44ab928e6369a4d48e3abb8215241e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 28 Jun 2018 12:32:27 -0500 Subject: [PATCH 105/133] drm/amdgpu: update uvd_v6_0_ring_vm_funcs to use new nop packet Was missed when updating the uvd 6 module. Fixes: 1aac3c9180 (drm/amdgpu: fix insert nop for UVD6 ring) Reviewed-by: Leo Liu Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 1df1c6115341..8ee1c2eaaa14 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -1569,7 +1569,6 @@ static const struct amdgpu_ring_funcs uvd_v6_0_ring_phys_funcs = { static const struct amdgpu_ring_funcs uvd_v6_0_ring_vm_funcs = { .type = AMDGPU_RING_TYPE_UVD, .align_mask = 0xf, - .nop = PACKET0(mmUVD_NO_OP, 0), .support_64bit_ptrs = false, .get_rptr = uvd_v6_0_ring_get_rptr, .get_wptr = uvd_v6_0_ring_get_wptr, @@ -1587,7 +1586,7 @@ static const struct amdgpu_ring_funcs uvd_v6_0_ring_vm_funcs = { .emit_hdp_flush = uvd_v6_0_ring_emit_hdp_flush, .test_ring = uvd_v6_0_ring_test_ring, .test_ib = amdgpu_uvd_ring_test_ib, - .insert_nop = amdgpu_ring_insert_nop, + .insert_nop = uvd_v6_0_ring_insert_nop, .pad_ib = amdgpu_ring_generic_pad_ib, .begin_use = amdgpu_uvd_ring_begin_use, .end_use = amdgpu_uvd_ring_end_use, From 23ec3d1479fd79658cd52c47618d8ddd2f32550b Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 18 Jun 2018 18:15:15 +0800 Subject: [PATCH 106/133] drm/amd/pp: Convert clock unit to KHz as defined Convert clock unit 10KHz to KHz as the data sturct defined. e.g. struct pp_clock_with_latency { uint32_t clocks_in_khz; uint32_t latency_in_us; }; Meanwhile revert the same conversion in display side. Acked-by: Alex Deucher Acked-by: Harry Wentland Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- .../amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 18 ++++------ .../gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 4 +-- .../drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 34 +++++++++---------- .../drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 20 +++++------ 4 files changed, 34 insertions(+), 42 deletions(-) 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 cf92d7a24f33..596d49d7f919 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 @@ -203,8 +203,7 @@ static void pp_to_dc_clock_levels( for (i = 0; i < dc_clks->num_levels; i++) { DRM_INFO("DM_PPLIB:\t %d\n", pp_clks->clock[i]); - /* translate 10kHz to kHz */ - dc_clks->clocks_in_khz[i] = pp_clks->clock[i] * 10; + dc_clks->clocks_in_khz[i] = pp_clks->clock[i]; } } @@ -229,9 +228,8 @@ static void pp_to_dc_clock_levels_with_latency( DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); for (i = 0; i < clk_level_info->num_levels; i++) { - DRM_DEBUG("DM_PPLIB:\t %d in 10kHz\n", pp_clks->data[i].clocks_in_khz); - /* translate 10kHz to kHz */ - clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz * 10; + DRM_DEBUG("DM_PPLIB:\t %d in kHz\n", pp_clks->data[i].clocks_in_khz); + clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz; clk_level_info->data[i].latency_in_us = pp_clks->data[i].latency_in_us; } } @@ -257,9 +255,8 @@ static void pp_to_dc_clock_levels_with_voltage( DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); for (i = 0; i < clk_level_info->num_levels; i++) { - DRM_INFO("DM_PPLIB:\t %d in 10kHz\n", pp_clks->data[i].clocks_in_khz); - /* translate 10kHz to kHz */ - clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz * 10; + DRM_INFO("DM_PPLIB:\t %d in kHz\n", pp_clks->data[i].clocks_in_khz); + clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz; clk_level_info->data[i].voltage_in_mv = pp_clks->data[i].voltage_in_mv; } } @@ -434,9 +431,8 @@ bool dm_pp_get_static_clocks( return false; static_clk_info->max_clocks_state = pp_clk_info.max_clocks_state; - /* translate 10kHz to kHz */ - static_clk_info->max_mclk_khz = pp_clk_info.max_memory_clock * 10; - static_clk_info->max_sclk_khz = pp_clk_info.max_engine_clock * 10; + static_clk_info->max_mclk_khz = pp_clk_info.max_memory_clock; + static_clk_info->max_sclk_khz = pp_clk_info.max_engine_clock; return true; } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c index 0bbf11d464dd..07cc98c69c7d 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c @@ -993,7 +993,7 @@ static int smu10_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr, clocks->num_levels = 0; for (i = 0; i < pclk_vol_table->count; i++) { - clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk; + clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk * 10; clocks->data[i].latency_in_us = latency_required ? smu10_get_mem_latency(hwmgr, pclk_vol_table->entries[i].clk) : @@ -1044,7 +1044,7 @@ static int smu10_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr, clocks->num_levels = 0; for (i = 0; i < pclk_vol_table->count; i++) { - clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk; + clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk * 10; clocks->data[i].voltage_in_mv = pclk_vol_table->entries[i].vol; clocks->num_levels++; } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 3b8d36df52e9..37c2e5c15d62 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -4064,10 +4064,11 @@ static void vega10_get_sclks(struct pp_hwmgr *hwmgr, table_info->vdd_dep_on_sclk; uint32_t i; + clocks->num_levels = 0; for (i = 0; i < dep_table->count; i++) { if (dep_table->entries[i].clk) { clocks->data[clocks->num_levels].clocks_in_khz = - dep_table->entries[i].clk; + dep_table->entries[i].clk * 10; clocks->num_levels++; } } @@ -4094,26 +4095,23 @@ static void vega10_get_memclocks(struct pp_hwmgr *hwmgr, struct phm_ppt_v1_clock_voltage_dependency_table *dep_table = table_info->vdd_dep_on_mclk; struct vega10_hwmgr *data = hwmgr->backend; + uint32_t j = 0; uint32_t i; - clocks->num_levels = 0; - data->mclk_latency_table.count = 0; - for (i = 0; i < dep_table->count; i++) { if (dep_table->entries[i].clk) { - clocks->data[clocks->num_levels].clocks_in_khz = - data->mclk_latency_table.entries - [data->mclk_latency_table.count].frequency = - dep_table->entries[i].clk; - clocks->data[clocks->num_levels].latency_in_us = - data->mclk_latency_table.entries - [data->mclk_latency_table.count].latency = - vega10_get_mem_latency(hwmgr, - dep_table->entries[i].clk); - clocks->num_levels++; - data->mclk_latency_table.count++; + clocks->data[j].clocks_in_khz = + dep_table->entries[i].clk * 10; + data->mclk_latency_table.entries[j].frequency = + dep_table->entries[i].clk; + clocks->data[j].latency_in_us = + data->mclk_latency_table.entries[j].latency = + vega10_get_mem_latency(hwmgr, + dep_table->entries[i].clk); + j++; } } + clocks->num_levels = data->mclk_latency_table.count = j; } static void vega10_get_dcefclocks(struct pp_hwmgr *hwmgr, @@ -4126,7 +4124,7 @@ static void vega10_get_dcefclocks(struct pp_hwmgr *hwmgr, uint32_t i; for (i = 0; i < dep_table->count; i++) { - clocks->data[i].clocks_in_khz = dep_table->entries[i].clk; + clocks->data[i].clocks_in_khz = dep_table->entries[i].clk * 10; clocks->data[i].latency_in_us = 0; clocks->num_levels++; } @@ -4142,7 +4140,7 @@ static void vega10_get_socclocks(struct pp_hwmgr *hwmgr, uint32_t i; for (i = 0; i < dep_table->count; i++) { - clocks->data[i].clocks_in_khz = dep_table->entries[i].clk; + clocks->data[i].clocks_in_khz = dep_table->entries[i].clk * 10; clocks->data[i].latency_in_us = 0; clocks->num_levels++; } @@ -4202,7 +4200,7 @@ static int vega10_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr, } for (i = 0; i < dep_table->count; i++) { - clocks->data[i].clocks_in_khz = dep_table->entries[i].clk; + clocks->data[i].clocks_in_khz = dep_table->entries[i].clk * 10; clocks->data[i].voltage_in_mv = (uint32_t)(table_info->vddc_lookup_table-> entries[dep_table->entries[i].vddInd].us_vdd); clocks->num_levels++; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index a86777954ea7..4cf257043a2c 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -1645,7 +1645,7 @@ static int vega12_get_sclks(struct pp_hwmgr *hwmgr, for (i = 0; i < ucount; 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; } @@ -1676,10 +1676,8 @@ static int vega12_get_memclocks(struct pp_hwmgr *hwmgr, MAX_NUM_CLOCKS : dpm_table->count; for (i = 0; i < ucount; i++) { - clocks->data[i].clocks_in_khz = - data->mclk_latency_table.entries[i].frequency = - dpm_table->dpm_levels[i].value * 100; - + clocks->data[i].clocks_in_khz = dpm_table->dpm_levels[i].value * 1000; + data->mclk_latency_table.entries[i].frequency = dpm_table->dpm_levels[i].value * 100; clocks->data[i].latency_in_us = data->mclk_latency_table.entries[i].latency = vega12_get_mem_latency(hwmgr, dpm_table->dpm_levels[i].value); @@ -1708,7 +1706,7 @@ static int vega12_get_dcefclocks(struct pp_hwmgr *hwmgr, for (i = 0; i < ucount; 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; } @@ -1736,7 +1734,7 @@ static int vega12_get_socclocks(struct pp_hwmgr *hwmgr, for (i = 0; i < ucount; 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; } @@ -1918,8 +1916,8 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, return -1); for (i = 0; i < clocks.num_levels; i++) size += sprintf(buf + size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 100, - (clocks.data[i].clocks_in_khz == now) ? "*" : ""); + i, clocks.data[i].clocks_in_khz / 1000, + (clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : ""); break; case PP_MCLK: @@ -1934,8 +1932,8 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, return -1); for (i = 0; i < clocks.num_levels; i++) size += sprintf(buf + size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 100, - (clocks.data[i].clocks_in_khz == now) ? "*" : ""); + i, clocks.data[i].clocks_in_khz / 1000, + (clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : ""); break; case PP_PCIE: From 6eb9d6030479c5e079a1374941b77ac205b10912 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 18 Jun 2018 18:49:07 +0800 Subject: [PATCH 107/133] drm/amd/pp: Memory Latency is always 25us on Vega10 For HBM, 25us latency is enough for memory clock switch. Acked-by: Alex Deucher Acked-by: Harry Wentland Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- .../drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 37c2e5c15d62..7fdd9ede96c7 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -55,12 +55,6 @@ static const uint32_t channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2}; -#define MEM_FREQ_LOW_LATENCY 25000 -#define MEM_FREQ_HIGH_LATENCY 80000 -#define MEM_LATENCY_HIGH 245 -#define MEM_LATENCY_LOW 35 -#define MEM_LATENCY_ERR 0xFFFF - #define mmDF_CS_AON0_DramBaseAddress0 0x0044 #define mmDF_CS_AON0_DramBaseAddress0_BASE_IDX 0 @@ -4075,18 +4069,6 @@ static void vega10_get_sclks(struct pp_hwmgr *hwmgr, } -static uint32_t vega10_get_mem_latency(struct pp_hwmgr *hwmgr, - uint32_t clock) -{ - if (clock >= MEM_FREQ_LOW_LATENCY && - clock < MEM_FREQ_HIGH_LATENCY) - return MEM_LATENCY_HIGH; - else if (clock >= MEM_FREQ_HIGH_LATENCY) - return MEM_LATENCY_LOW; - else - return MEM_LATENCY_ERR; -} - static void vega10_get_memclocks(struct pp_hwmgr *hwmgr, struct pp_clock_levels_with_latency *clocks) { @@ -4100,14 +4082,13 @@ static void vega10_get_memclocks(struct pp_hwmgr *hwmgr, for (i = 0; i < dep_table->count; i++) { if (dep_table->entries[i].clk) { + clocks->data[j].clocks_in_khz = dep_table->entries[i].clk * 10; data->mclk_latency_table.entries[j].frequency = dep_table->entries[i].clk; clocks->data[j].latency_in_us = - data->mclk_latency_table.entries[j].latency = - vega10_get_mem_latency(hwmgr, - dep_table->entries[i].clk); + data->mclk_latency_table.entries[j].latency = 25; j++; } } From 7d8d968dac88a98bd1d4503a020e8b114672611e Mon Sep 17 00:00:00 2001 From: rex zhu Date: Thu, 28 Jun 2018 13:55:46 +0800 Subject: [PATCH 108/133] drm/amd/pp: Switch the tolerable latency for display Select the lowest MCLK frequency that is within the tolerable latency defined in DISPALY Acked-by: Alex Deucher Acked-by: Harry Wentland Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 7fdd9ede96c7..e5b3abffefb6 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -3217,7 +3217,7 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, /* Find the lowest MCLK frequency that is within * the tolerable latency defined in DAL */ - latency = 0; + latency = hwmgr->display_config->dce_tolerable_mclk_in_active_latency; for (i = 0; i < data->mclk_latency_table.count; i++) { if ((data->mclk_latency_table.entries[i].latency <= latency) && (data->mclk_latency_table.entries[i].frequency >= From 3180fb676d7fd38a7c1effa2e5d9265779473c23 Mon Sep 17 00:00:00 2001 From: rex zhu Date: Mon, 2 Jul 2018 14:55:43 +0800 Subject: [PATCH 109/133] drm/amd/display: Notify powerplay the min_dcef clock powerplay can notify smu to recalculates the maximum deep-sleep divider display allowed. Acked-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 5 +++++ 1 file changed, 5 insertions(+) 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 596d49d7f919..2e801bab5a78 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 @@ -71,6 +71,11 @@ bool dm_pp_apply_display_requirements( adev->pm.pm_display_cfg.min_mem_set_clock = pp_display_cfg->min_memory_clock_khz/10; + adev->pm.pm_display_cfg.min_dcef_deep_sleep_set_clk = + pp_display_cfg->min_engine_clock_deep_sleep_khz/10; + adev->pm.pm_display_cfg.min_dcef_set_clk = + pp_display_cfg->min_dcfclock_khz/10; + adev->pm.pm_display_cfg.multi_monitor_in_sync = pp_display_cfg->all_displays_in_sync; adev->pm.pm_display_cfg.min_vblank_time = From d4d5eace210d3676202153c19e473aeb51a81909 Mon Sep 17 00:00:00 2001 From: rex zhu Date: Mon, 2 Jul 2018 16:20:56 +0800 Subject: [PATCH 110/133] drm/amd/display: Notify powerplay the display controller id powerplay can recalculate the number of active display Acked-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 7 +++++++ 1 file changed, 7 insertions(+) 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 2e801bab5a78..81845116cdcc 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 @@ -41,6 +41,7 @@ bool dm_pp_apply_display_requirements( const struct dm_pp_display_configuration *pp_display_cfg) { struct amdgpu_device *adev = ctx->driver_context; + int i; if (adev->pm.dpm_enabled) { @@ -95,6 +96,12 @@ bool dm_pp_apply_display_requirements( adev->pm.pm_display_cfg.crossfire_display_index = -1; adev->pm.pm_display_cfg.min_bus_bandwidth = 0; + for (i = 0; i < pp_display_cfg->display_count; i++) { + const struct dm_pp_single_disp_config *dc_cfg = + &pp_display_cfg->disp_configs[i]; + adev->pm.pm_display_cfg.displays[i].controller_id = dc_cfg->pipe_idx + 1; + } + /* TODO: complete implementation of * pp_display_configuration_change(). * Follow example of: From 99c5e27d3368eb92476f47530355a6f25bf486e8 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 22 Jun 2018 18:26:52 +0800 Subject: [PATCH 111/133] drm/amd/pp: Refine the interface exported to display use void * as function parameter type in order for extension. Acked-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/kgd_pp_interface.h | 3 +-- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 6 +++--- drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c | 4 ++-- drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 3 ++- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 3 ++- drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 3 ++- drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h | 2 +- drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 3 +-- 8 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 4535756428f9..99ee3edd1609 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -192,7 +192,6 @@ struct amd_pp_simple_clock_info; struct amd_pp_display_configuration; struct amd_pp_clock_info; struct pp_display_clock_request; -struct pp_wm_sets_with_clock_ranges_soc15; struct pp_clock_levels_with_voltage; struct pp_clock_levels_with_latency; struct amd_pp_clocks; @@ -261,7 +260,7 @@ struct amd_pm_funcs { enum amd_pp_clock_type type, struct pp_clock_levels_with_voltage *clocks); int (*set_watermarks_for_clocks_ranges)(void *handle, - struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges); + void *clock_ranges); int (*display_clock_voltage_request)(void *handle, struct pp_display_clock_request *clock); int (*get_display_mode_validation_clocks)(void *handle, diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 387a1eb6678d..b72cc644d4e7 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -1096,17 +1096,17 @@ static int pp_get_clock_by_type_with_voltage(void *handle, } static int pp_set_watermarks_for_clocks_ranges(void *handle, - struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges) + void *clock_ranges) { struct pp_hwmgr *hwmgr = handle; int ret = 0; - if (!hwmgr || !hwmgr->pm_en ||!wm_with_clock_ranges) + if (!hwmgr || !hwmgr->pm_en || !clock_ranges) return -EINVAL; mutex_lock(&hwmgr->smu_lock); ret = phm_set_watermarks_for_clocks_ranges(hwmgr, - wm_with_clock_ranges); + clock_ranges); mutex_unlock(&hwmgr->smu_lock); return ret; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c index a0bb921fac22..53207e76b0f3 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c @@ -435,7 +435,7 @@ int phm_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr, } int phm_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, - struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges) + void *clock_ranges) { PHM_FUNC_CHECK(hwmgr); @@ -443,7 +443,7 @@ int phm_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, return -EINVAL; return hwmgr->hwmgr_func->set_watermarks_for_clocks_ranges(hwmgr, - wm_with_clock_ranges); + clock_ranges); } int phm_display_clock_voltage_request(struct pp_hwmgr *hwmgr, diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c index 07cc98c69c7d..02fc0bc41e0a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c @@ -1108,9 +1108,10 @@ static int smu10_read_sensor(struct pp_hwmgr *hwmgr, int idx, } static int smu10_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, - struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges) + void *clock_ranges) { struct smu10_hwmgr *data = hwmgr->backend; + struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges = clock_ranges; Watermarks_t *table = &(data->water_marks_table); int result = 0; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index e5b3abffefb6..d515eb4fac9f 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -4194,9 +4194,10 @@ static int vega10_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr, } static int vega10_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, - struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges) + void *clock_range) { struct vega10_hwmgr *data = hwmgr->backend; + struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges = clock_range; Watermarks_t *table = &(data->smc_state_table.water_marks_table); int result = 0; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 4cf257043a2c..448014b173d5 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -1781,10 +1781,11 @@ static int vega12_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr, } static int vega12_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, - struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges) + void *clock_ranges) { struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); Watermarks_t *table = &(data->smc_state_table.water_marks_table); + struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges = clock_ranges; uint32_t i; if (!data->registry_data.disable_water_mark && diff --git a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h index a202247c9894..429c9c4322da 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h @@ -455,7 +455,7 @@ extern int phm_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type type, struct pp_clock_levels_with_voltage *clocks); extern int phm_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, - struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges); + void *clock_ranges); extern int phm_display_clock_voltage_request(struct pp_hwmgr *hwmgr, struct pp_display_clock_request *clock); diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 95e29a22e445..b3363f26039a 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -293,8 +293,7 @@ struct pp_hwmgr_func { int (*get_clock_by_type_with_voltage)(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type type, struct pp_clock_levels_with_voltage *clocks); - int (*set_watermarks_for_clocks_ranges)(struct pp_hwmgr *hwmgr, - struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges); + int (*set_watermarks_for_clocks_ranges)(struct pp_hwmgr *hwmgr, void *clock_ranges); int (*display_clock_voltage_request)(struct pp_hwmgr *hwmgr, struct pp_display_clock_request *clock); int (*get_max_high_clocks)(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks); From 860c15e903327f9af269d2ee7011454624dfcb90 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 20 Jun 2018 13:36:58 +0800 Subject: [PATCH 112/133] drm/amd/pp: Remove duplicate code in vega12_hwmgr.c use smu_helper function smu_set_watermarks_for_clocks_ranges in vega12_set_watermarks_for_clocks_ranges. Reviewed-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- .../drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 43 +------------------ 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 448014b173d5..0a090755545d 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -1786,52 +1786,11 @@ static int vega12_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); Watermarks_t *table = &(data->smc_state_table.water_marks_table); struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges = clock_ranges; - uint32_t i; if (!data->registry_data.disable_water_mark && data->smu_features[GNLD_DPM_DCEFCLK].supported && data->smu_features[GNLD_DPM_SOCCLK].supported) { - for (i = 0; i < wm_with_clock_ranges->num_wm_sets_dmif; i++) { - table->WatermarkRow[WM_DCEFCLK][i].MinClock = - cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_dmif[i].wm_min_dcefclk_in_khz) / - 100); - table->WatermarkRow[WM_DCEFCLK][i].MaxClock = - cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_dmif[i].wm_max_dcefclk_in_khz) / - 100); - table->WatermarkRow[WM_DCEFCLK][i].MinUclk = - cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_dmif[i].wm_min_memclk_in_khz) / - 100); - table->WatermarkRow[WM_DCEFCLK][i].MaxUclk = - cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_dmif[i].wm_max_memclk_in_khz) / - 100); - table->WatermarkRow[WM_DCEFCLK][i].WmSetting = (uint8_t) - wm_with_clock_ranges->wm_sets_dmif[i].wm_set_id; - } - - for (i = 0; i < wm_with_clock_ranges->num_wm_sets_mcif; i++) { - table->WatermarkRow[WM_SOCCLK][i].MinClock = - cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_mcif[i].wm_min_socclk_in_khz) / - 100); - table->WatermarkRow[WM_SOCCLK][i].MaxClock = - cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_mcif[i].wm_max_socclk_in_khz) / - 100); - table->WatermarkRow[WM_SOCCLK][i].MinUclk = - cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_mcif[i].wm_min_memclk_in_khz) / - 100); - table->WatermarkRow[WM_SOCCLK][i].MaxUclk = - cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_mcif[i].wm_max_memclk_in_khz) / - 100); - table->WatermarkRow[WM_SOCCLK][i].WmSetting = (uint8_t) - wm_with_clock_ranges->wm_sets_mcif[i].wm_set_id; - } + smu_set_watermarks_for_clocks_ranges(table, wm_with_clock_ranges); data->water_marks_bitmap |= WaterMarksExist; data->water_marks_bitmap &= ~WaterMarksLoaded; } From 9fc15f5fc836712b173f04e143b8d77fdded1a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolai=20H=C3=A4hnle?= Date: Fri, 29 Jun 2018 13:23:25 +0200 Subject: [PATCH 113/133] drm/amdgpu: fix user fence write race condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The buffer object backing the user fence is reserved using the non-user fence, i.e., as soon as the non-user fence is signaled, the user fence buffer object can be moved or even destroyed. Therefore, emit the user fence first. Both fences have the same cache invalidation behavior, so this should have no user-visible effect. Signed-off-by: Nicolai Hähnle Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 31f8170313b4..ce7739832d29 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -231,6 +231,12 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, if (ib->flags & AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE) fence_flags |= AMDGPU_FENCE_FLAG_TC_WB_ONLY; + /* wrap the last IB with fence */ + if (job && job->uf_addr) { + amdgpu_ring_emit_fence(ring, job->uf_addr, job->uf_sequence, + fence_flags | AMDGPU_FENCE_FLAG_64BIT); + } + r = amdgpu_fence_emit(ring, f, fence_flags); if (r) { dev_err(adev->dev, "failed to emit fence (%d)\n", r); @@ -243,12 +249,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, if (ring->funcs->insert_end) ring->funcs->insert_end(ring); - /* wrap the last IB with fence */ - if (job && job->uf_addr) { - amdgpu_ring_emit_fence(ring, job->uf_addr, job->uf_sequence, - fence_flags | AMDGPU_FENCE_FLAG_64BIT); - } - if (patch_offset != ~0 && ring->funcs->patch_cond_exec) amdgpu_ring_patch_cond_exec(ring, patch_offset); From ce206464e3c7a0936468f0190599d2e6070850f4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 2 Jul 2018 14:32:28 -0500 Subject: [PATCH 114/133] drm/amdgpu: switch firmware path for CIK parts (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use separate firmware path for amdgpu to avoid conflicts with radeon on CIK parts. v2: squash in logic simplification (Alex) Reviewed-by: Chunming Zhou Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 8 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 10 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 10 ++-- drivers/gpu/drm/amd/amdgpu/ci_dpm.c | 10 ++-- drivers/gpu/drm/amd/amdgpu/cik_sdma.c | 24 +++++----- drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 64 ++++++++++++------------- drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 9 ++-- 7 files changed, 66 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index e950730f1933..693ec5ea4950 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -314,17 +314,17 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, (adev->pdev->revision == 0x81) || (adev->pdev->device == 0x665f)) { info->is_kicker = true; - strcpy(fw_name, "radeon/bonaire_k_smc.bin"); + strcpy(fw_name, "amdgpu/bonaire_k_smc.bin"); } else { - strcpy(fw_name, "radeon/bonaire_smc.bin"); + strcpy(fw_name, "amdgpu/bonaire_smc.bin"); } break; case CHIP_HAWAII: if (adev->pdev->revision == 0x80) { info->is_kicker = true; - strcpy(fw_name, "radeon/hawaii_k_smc.bin"); + strcpy(fw_name, "amdgpu/hawaii_k_smc.bin"); } else { - strcpy(fw_name, "radeon/hawaii_smc.bin"); + strcpy(fw_name, "amdgpu/hawaii_smc.bin"); } break; case CHIP_TOPAZ: diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 0b46ea1c6290..3e70eb61a960 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -53,11 +53,11 @@ /* Firmware Names */ #ifdef CONFIG_DRM_AMDGPU_CIK -#define FIRMWARE_BONAIRE "radeon/bonaire_uvd.bin" -#define FIRMWARE_KABINI "radeon/kabini_uvd.bin" -#define FIRMWARE_KAVERI "radeon/kaveri_uvd.bin" -#define FIRMWARE_HAWAII "radeon/hawaii_uvd.bin" -#define FIRMWARE_MULLINS "radeon/mullins_uvd.bin" +#define FIRMWARE_BONAIRE "amdgpu/bonaire_uvd.bin" +#define FIRMWARE_KABINI "amdgpu/kabini_uvd.bin" +#define FIRMWARE_KAVERI "amdgpu/kaveri_uvd.bin" +#define FIRMWARE_HAWAII "amdgpu/hawaii_uvd.bin" +#define FIRMWARE_MULLINS "amdgpu/mullins_uvd.bin" #endif #define FIRMWARE_TONGA "amdgpu/tonga_uvd.bin" #define FIRMWARE_CARRIZO "amdgpu/carrizo_uvd.bin" diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index b0dcdfd85f5b..6ae1ad7e83b3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -40,11 +40,11 @@ /* Firmware Names */ #ifdef CONFIG_DRM_AMDGPU_CIK -#define FIRMWARE_BONAIRE "radeon/bonaire_vce.bin" -#define FIRMWARE_KABINI "radeon/kabini_vce.bin" -#define FIRMWARE_KAVERI "radeon/kaveri_vce.bin" -#define FIRMWARE_HAWAII "radeon/hawaii_vce.bin" -#define FIRMWARE_MULLINS "radeon/mullins_vce.bin" +#define FIRMWARE_BONAIRE "amdgpu/bonaire_vce.bin" +#define FIRMWARE_KABINI "amdgpu/kabini_vce.bin" +#define FIRMWARE_KAVERI "amdgpu/kaveri_vce.bin" +#define FIRMWARE_HAWAII "amdgpu/hawaii_vce.bin" +#define FIRMWARE_MULLINS "amdgpu/mullins_vce.bin" #endif #define FIRMWARE_TONGA "amdgpu/tonga_vce.bin" #define FIRMWARE_CARRIZO "amdgpu/carrizo_vce.bin" diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index 7c4ff71e7476..d79ad93b01c3 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c @@ -49,10 +49,10 @@ #include "gmc/gmc_7_1_d.h" #include "gmc/gmc_7_1_sh_mask.h" -MODULE_FIRMWARE("radeon/bonaire_smc.bin"); -MODULE_FIRMWARE("radeon/bonaire_k_smc.bin"); -MODULE_FIRMWARE("radeon/hawaii_smc.bin"); -MODULE_FIRMWARE("radeon/hawaii_k_smc.bin"); +MODULE_FIRMWARE("amdgpu/bonaire_smc.bin"); +MODULE_FIRMWARE("amdgpu/bonaire_k_smc.bin"); +MODULE_FIRMWARE("amdgpu/hawaii_smc.bin"); +MODULE_FIRMWARE("amdgpu/hawaii_k_smc.bin"); #define MC_CG_ARB_FREQ_F0 0x0a #define MC_CG_ARB_FREQ_F1 0x0b @@ -5815,7 +5815,7 @@ static int ci_dpm_init_microcode(struct amdgpu_device *adev) default: BUG(); } - snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_smc.bin", chip_name); err = request_firmware(&adev->pm.fw, fw_name, adev->dev); if (err) goto out; diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index dbd553a8d584..d0fa2aac2388 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c @@ -54,16 +54,16 @@ static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev); static void cik_sdma_set_vm_pte_funcs(struct amdgpu_device *adev); static int cik_sdma_soft_reset(void *handle); -MODULE_FIRMWARE("radeon/bonaire_sdma.bin"); -MODULE_FIRMWARE("radeon/bonaire_sdma1.bin"); -MODULE_FIRMWARE("radeon/hawaii_sdma.bin"); -MODULE_FIRMWARE("radeon/hawaii_sdma1.bin"); -MODULE_FIRMWARE("radeon/kaveri_sdma.bin"); -MODULE_FIRMWARE("radeon/kaveri_sdma1.bin"); -MODULE_FIRMWARE("radeon/kabini_sdma.bin"); -MODULE_FIRMWARE("radeon/kabini_sdma1.bin"); -MODULE_FIRMWARE("radeon/mullins_sdma.bin"); -MODULE_FIRMWARE("radeon/mullins_sdma1.bin"); +MODULE_FIRMWARE("amdgpu/bonaire_sdma.bin"); +MODULE_FIRMWARE("amdgpu/bonaire_sdma1.bin"); +MODULE_FIRMWARE("amdgpu/hawaii_sdma.bin"); +MODULE_FIRMWARE("amdgpu/hawaii_sdma1.bin"); +MODULE_FIRMWARE("amdgpu/kaveri_sdma.bin"); +MODULE_FIRMWARE("amdgpu/kaveri_sdma1.bin"); +MODULE_FIRMWARE("amdgpu/kabini_sdma.bin"); +MODULE_FIRMWARE("amdgpu/kabini_sdma1.bin"); +MODULE_FIRMWARE("amdgpu/mullins_sdma.bin"); +MODULE_FIRMWARE("amdgpu/mullins_sdma1.bin"); u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev); @@ -132,9 +132,9 @@ static int cik_sdma_init_microcode(struct amdgpu_device *adev) for (i = 0; i < adev->sdma.num_instances; i++) { if (i == 0) - snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma.bin", chip_name); else - snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma1.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma1.bin", chip_name); err = request_firmware(&adev->sdma.instance[i].fw, fw_name, adev->dev); if (err) goto out; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 42b6144c1fd5..95452c5a9df6 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c @@ -57,36 +57,36 @@ static void gfx_v7_0_set_ring_funcs(struct amdgpu_device *adev); static void gfx_v7_0_set_irq_funcs(struct amdgpu_device *adev); static void gfx_v7_0_set_gds_init(struct amdgpu_device *adev); -MODULE_FIRMWARE("radeon/bonaire_pfp.bin"); -MODULE_FIRMWARE("radeon/bonaire_me.bin"); -MODULE_FIRMWARE("radeon/bonaire_ce.bin"); -MODULE_FIRMWARE("radeon/bonaire_rlc.bin"); -MODULE_FIRMWARE("radeon/bonaire_mec.bin"); +MODULE_FIRMWARE("amdgpu/bonaire_pfp.bin"); +MODULE_FIRMWARE("amdgpu/bonaire_me.bin"); +MODULE_FIRMWARE("amdgpu/bonaire_ce.bin"); +MODULE_FIRMWARE("amdgpu/bonaire_rlc.bin"); +MODULE_FIRMWARE("amdgpu/bonaire_mec.bin"); -MODULE_FIRMWARE("radeon/hawaii_pfp.bin"); -MODULE_FIRMWARE("radeon/hawaii_me.bin"); -MODULE_FIRMWARE("radeon/hawaii_ce.bin"); -MODULE_FIRMWARE("radeon/hawaii_rlc.bin"); -MODULE_FIRMWARE("radeon/hawaii_mec.bin"); +MODULE_FIRMWARE("amdgpu/hawaii_pfp.bin"); +MODULE_FIRMWARE("amdgpu/hawaii_me.bin"); +MODULE_FIRMWARE("amdgpu/hawaii_ce.bin"); +MODULE_FIRMWARE("amdgpu/hawaii_rlc.bin"); +MODULE_FIRMWARE("amdgpu/hawaii_mec.bin"); -MODULE_FIRMWARE("radeon/kaveri_pfp.bin"); -MODULE_FIRMWARE("radeon/kaveri_me.bin"); -MODULE_FIRMWARE("radeon/kaveri_ce.bin"); -MODULE_FIRMWARE("radeon/kaveri_rlc.bin"); -MODULE_FIRMWARE("radeon/kaveri_mec.bin"); -MODULE_FIRMWARE("radeon/kaveri_mec2.bin"); +MODULE_FIRMWARE("amdgpu/kaveri_pfp.bin"); +MODULE_FIRMWARE("amdgpu/kaveri_me.bin"); +MODULE_FIRMWARE("amdgpu/kaveri_ce.bin"); +MODULE_FIRMWARE("amdgpu/kaveri_rlc.bin"); +MODULE_FIRMWARE("amdgpu/kaveri_mec.bin"); +MODULE_FIRMWARE("amdgpu/kaveri_mec2.bin"); -MODULE_FIRMWARE("radeon/kabini_pfp.bin"); -MODULE_FIRMWARE("radeon/kabini_me.bin"); -MODULE_FIRMWARE("radeon/kabini_ce.bin"); -MODULE_FIRMWARE("radeon/kabini_rlc.bin"); -MODULE_FIRMWARE("radeon/kabini_mec.bin"); +MODULE_FIRMWARE("amdgpu/kabini_pfp.bin"); +MODULE_FIRMWARE("amdgpu/kabini_me.bin"); +MODULE_FIRMWARE("amdgpu/kabini_ce.bin"); +MODULE_FIRMWARE("amdgpu/kabini_rlc.bin"); +MODULE_FIRMWARE("amdgpu/kabini_mec.bin"); -MODULE_FIRMWARE("radeon/mullins_pfp.bin"); -MODULE_FIRMWARE("radeon/mullins_me.bin"); -MODULE_FIRMWARE("radeon/mullins_ce.bin"); -MODULE_FIRMWARE("radeon/mullins_rlc.bin"); -MODULE_FIRMWARE("radeon/mullins_mec.bin"); +MODULE_FIRMWARE("amdgpu/mullins_pfp.bin"); +MODULE_FIRMWARE("amdgpu/mullins_me.bin"); +MODULE_FIRMWARE("amdgpu/mullins_ce.bin"); +MODULE_FIRMWARE("amdgpu/mullins_rlc.bin"); +MODULE_FIRMWARE("amdgpu/mullins_mec.bin"); static const struct amdgpu_gds_reg_offset amdgpu_gds_reg_offset[] = { @@ -925,7 +925,7 @@ static int gfx_v7_0_init_microcode(struct amdgpu_device *adev) default: BUG(); } - snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", chip_name); err = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev); if (err) goto out; @@ -933,7 +933,7 @@ static int gfx_v7_0_init_microcode(struct amdgpu_device *adev) if (err) goto out; - snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", chip_name); err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev); if (err) goto out; @@ -941,7 +941,7 @@ static int gfx_v7_0_init_microcode(struct amdgpu_device *adev) if (err) goto out; - snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce.bin", chip_name); err = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev); if (err) goto out; @@ -949,7 +949,7 @@ static int gfx_v7_0_init_microcode(struct amdgpu_device *adev) if (err) goto out; - snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name); err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev); if (err) goto out; @@ -958,7 +958,7 @@ static int gfx_v7_0_init_microcode(struct amdgpu_device *adev) goto out; if (adev->asic_type == CHIP_KAVERI) { - snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec2.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name); err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev); if (err) goto out; @@ -967,7 +967,7 @@ static int gfx_v7_0_init_microcode(struct amdgpu_device *adev) goto out; } - snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name); err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev); if (err) goto out; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 7147bfe25a23..78339309a00c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -47,8 +47,8 @@ static void gmc_v7_0_set_gmc_funcs(struct amdgpu_device *adev); static void gmc_v7_0_set_irq_funcs(struct amdgpu_device *adev); static int gmc_v7_0_wait_for_idle(void *handle); -MODULE_FIRMWARE("radeon/bonaire_mc.bin"); -MODULE_FIRMWARE("radeon/hawaii_mc.bin"); +MODULE_FIRMWARE("amdgpu/bonaire_mc.bin"); +MODULE_FIRMWARE("amdgpu/hawaii_mc.bin"); MODULE_FIRMWARE("amdgpu/topaz_mc.bin"); static const u32 golden_settings_iceland_a11[] = @@ -147,10 +147,7 @@ static int gmc_v7_0_init_microcode(struct amdgpu_device *adev) default: BUG(); } - if (adev->asic_type == CHIP_TOPAZ) - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mc.bin", chip_name); - else - snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mc.bin", chip_name); err = request_firmware(&adev->gmc.fw, fw_name, adev->dev); if (err) From 8eaf2b1faaf4358c6337785f2192055c6ef41e0d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 2 Jul 2018 14:35:36 -0500 Subject: [PATCH 115/133] drm/amdgpu: switch firmware path for SI parts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use separate firmware path for amdgpu to avoid conflicts with radeon on SI parts. Reviewed-by: Chunming Zhou Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c | 48 +++++++++++++-------------- drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 14 ++++---- drivers/gpu/drm/amd/amdgpu/si_dpm.c | 22 ++++++------ 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c index cd6bf291a853..de184a886057 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c @@ -44,30 +44,30 @@ static void gfx_v6_0_set_ring_funcs(struct amdgpu_device *adev); static void gfx_v6_0_set_irq_funcs(struct amdgpu_device *adev); static void gfx_v6_0_get_cu_info(struct amdgpu_device *adev); -MODULE_FIRMWARE("radeon/tahiti_pfp.bin"); -MODULE_FIRMWARE("radeon/tahiti_me.bin"); -MODULE_FIRMWARE("radeon/tahiti_ce.bin"); -MODULE_FIRMWARE("radeon/tahiti_rlc.bin"); +MODULE_FIRMWARE("amdgpu/tahiti_pfp.bin"); +MODULE_FIRMWARE("amdgpu/tahiti_me.bin"); +MODULE_FIRMWARE("amdgpu/tahiti_ce.bin"); +MODULE_FIRMWARE("amdgpu/tahiti_rlc.bin"); -MODULE_FIRMWARE("radeon/pitcairn_pfp.bin"); -MODULE_FIRMWARE("radeon/pitcairn_me.bin"); -MODULE_FIRMWARE("radeon/pitcairn_ce.bin"); -MODULE_FIRMWARE("radeon/pitcairn_rlc.bin"); +MODULE_FIRMWARE("amdgpu/pitcairn_pfp.bin"); +MODULE_FIRMWARE("amdgpu/pitcairn_me.bin"); +MODULE_FIRMWARE("amdgpu/pitcairn_ce.bin"); +MODULE_FIRMWARE("amdgpu/pitcairn_rlc.bin"); -MODULE_FIRMWARE("radeon/verde_pfp.bin"); -MODULE_FIRMWARE("radeon/verde_me.bin"); -MODULE_FIRMWARE("radeon/verde_ce.bin"); -MODULE_FIRMWARE("radeon/verde_rlc.bin"); +MODULE_FIRMWARE("amdgpu/verde_pfp.bin"); +MODULE_FIRMWARE("amdgpu/verde_me.bin"); +MODULE_FIRMWARE("amdgpu/verde_ce.bin"); +MODULE_FIRMWARE("amdgpu/verde_rlc.bin"); -MODULE_FIRMWARE("radeon/oland_pfp.bin"); -MODULE_FIRMWARE("radeon/oland_me.bin"); -MODULE_FIRMWARE("radeon/oland_ce.bin"); -MODULE_FIRMWARE("radeon/oland_rlc.bin"); +MODULE_FIRMWARE("amdgpu/oland_pfp.bin"); +MODULE_FIRMWARE("amdgpu/oland_me.bin"); +MODULE_FIRMWARE("amdgpu/oland_ce.bin"); +MODULE_FIRMWARE("amdgpu/oland_rlc.bin"); -MODULE_FIRMWARE("radeon/hainan_pfp.bin"); -MODULE_FIRMWARE("radeon/hainan_me.bin"); -MODULE_FIRMWARE("radeon/hainan_ce.bin"); -MODULE_FIRMWARE("radeon/hainan_rlc.bin"); +MODULE_FIRMWARE("amdgpu/hainan_pfp.bin"); +MODULE_FIRMWARE("amdgpu/hainan_me.bin"); +MODULE_FIRMWARE("amdgpu/hainan_ce.bin"); +MODULE_FIRMWARE("amdgpu/hainan_rlc.bin"); static u32 gfx_v6_0_get_csb_size(struct amdgpu_device *adev); static void gfx_v6_0_get_csb_buffer(struct amdgpu_device *adev, volatile u32 *buffer); @@ -335,7 +335,7 @@ static int gfx_v6_0_init_microcode(struct amdgpu_device *adev) default: BUG(); } - snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", chip_name); err = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev); if (err) goto out; @@ -346,7 +346,7 @@ static int gfx_v6_0_init_microcode(struct amdgpu_device *adev) adev->gfx.pfp_fw_version = le32_to_cpu(cp_hdr->header.ucode_version); adev->gfx.pfp_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); - snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", chip_name); err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev); if (err) goto out; @@ -357,7 +357,7 @@ static int gfx_v6_0_init_microcode(struct amdgpu_device *adev) adev->gfx.me_fw_version = le32_to_cpu(cp_hdr->header.ucode_version); adev->gfx.me_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); - snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce.bin", chip_name); err = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev); if (err) goto out; @@ -368,7 +368,7 @@ static int gfx_v6_0_init_microcode(struct amdgpu_device *adev) adev->gfx.ce_fw_version = le32_to_cpu(cp_hdr->header.ucode_version); adev->gfx.ce_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); - snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name); err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev); if (err) goto out; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index 79f9ac29019b..75317f283c69 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -41,11 +41,11 @@ static void gmc_v6_0_set_gmc_funcs(struct amdgpu_device *adev); static void gmc_v6_0_set_irq_funcs(struct amdgpu_device *adev); static int gmc_v6_0_wait_for_idle(void *handle); -MODULE_FIRMWARE("radeon/tahiti_mc.bin"); -MODULE_FIRMWARE("radeon/pitcairn_mc.bin"); -MODULE_FIRMWARE("radeon/verde_mc.bin"); -MODULE_FIRMWARE("radeon/oland_mc.bin"); -MODULE_FIRMWARE("radeon/si58_mc.bin"); +MODULE_FIRMWARE("amdgpu/tahiti_mc.bin"); +MODULE_FIRMWARE("amdgpu/pitcairn_mc.bin"); +MODULE_FIRMWARE("amdgpu/verde_mc.bin"); +MODULE_FIRMWARE("amdgpu/oland_mc.bin"); +MODULE_FIRMWARE("amdgpu/si58_mc.bin"); #define MC_SEQ_MISC0__MT__MASK 0xf0000000 #define MC_SEQ_MISC0__MT__GDDR1 0x10000000 @@ -134,9 +134,9 @@ static int gmc_v6_0_init_microcode(struct amdgpu_device *adev) is_58_fw = true; if (is_58_fw) - snprintf(fw_name, sizeof(fw_name), "radeon/si58_mc.bin"); + snprintf(fw_name, sizeof(fw_name), "amdgpu/si58_mc.bin"); else - snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mc.bin", chip_name); err = request_firmware(&adev->gmc.fw, fw_name, adev->dev); if (err) goto out; diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index d51318c695e6..3560b7dc1798 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c @@ -56,16 +56,16 @@ #define BIOS_SCRATCH_4 0x5cd -MODULE_FIRMWARE("radeon/tahiti_smc.bin"); -MODULE_FIRMWARE("radeon/pitcairn_smc.bin"); -MODULE_FIRMWARE("radeon/pitcairn_k_smc.bin"); -MODULE_FIRMWARE("radeon/verde_smc.bin"); -MODULE_FIRMWARE("radeon/verde_k_smc.bin"); -MODULE_FIRMWARE("radeon/oland_smc.bin"); -MODULE_FIRMWARE("radeon/oland_k_smc.bin"); -MODULE_FIRMWARE("radeon/hainan_smc.bin"); -MODULE_FIRMWARE("radeon/hainan_k_smc.bin"); -MODULE_FIRMWARE("radeon/banks_k_2_smc.bin"); +MODULE_FIRMWARE("amdgpu/tahiti_smc.bin"); +MODULE_FIRMWARE("amdgpu/pitcairn_smc.bin"); +MODULE_FIRMWARE("amdgpu/pitcairn_k_smc.bin"); +MODULE_FIRMWARE("amdgpu/verde_smc.bin"); +MODULE_FIRMWARE("amdgpu/verde_k_smc.bin"); +MODULE_FIRMWARE("amdgpu/oland_smc.bin"); +MODULE_FIRMWARE("amdgpu/oland_k_smc.bin"); +MODULE_FIRMWARE("amdgpu/hainan_smc.bin"); +MODULE_FIRMWARE("amdgpu/hainan_k_smc.bin"); +MODULE_FIRMWARE("amdgpu/banks_k_2_smc.bin"); static const struct amd_pm_funcs si_dpm_funcs; @@ -7667,7 +7667,7 @@ static int si_dpm_init_microcode(struct amdgpu_device *adev) default: BUG(); } - snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_smc.bin", chip_name); err = request_firmware(&adev->pm.fw, fw_name, adev->dev); if (err) goto out; From 576c7218a1546e0153480b208b125509cec71470 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 25 Jun 2018 13:17:41 -0500 Subject: [PATCH 116/133] PCI: Export pcie_get_speed_cap and pcie_get_width_cap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So drivers can use them. This can be used to replace duplicate code in the drm subsystem. Acked-by: Christian König Acked-by: Bjorn Helgaas Signed-off-by: Alex Deucher --- drivers/pci/pci.c | 2 ++ include/linux/pci.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 97acba712e4e..22adaf35b136 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5222,6 +5222,7 @@ enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev) return PCI_SPEED_UNKNOWN; } +EXPORT_SYMBOL(pcie_get_speed_cap); /** * pcie_get_width_cap - query for the PCI device's link width capability @@ -5240,6 +5241,7 @@ enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev) return PCIE_LNK_WIDTH_UNKNOWN; } +EXPORT_SYMBOL(pcie_get_width_cap); /** * pcie_bandwidth_capable - calculate a PCI device's link bandwidth capability diff --git a/include/linux/pci.h b/include/linux/pci.h index 340029b2fb38..6e0c0803b241 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -261,6 +261,9 @@ enum pci_bus_speed { PCI_SPEED_UNKNOWN = 0xff, }; +enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev); +enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev); + struct pci_cap_saved_data { u16 cap_nr; bool cap_extended; From 4976f1c8ccff0d682176851692976e3bf03267d6 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 25 Jun 2018 13:03:51 -0500 Subject: [PATCH 117/133] drm/amdgpu: update amd_pcie.h to include gen4 speeds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Internal header used by the driver to specify pcie gen speeds of the asic and chipset. Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/amd_pcie.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/include/amd_pcie.h b/drivers/gpu/drm/amd/include/amd_pcie.h index 5eb895fd98bf..9cb9ceb4d74d 100644 --- a/drivers/gpu/drm/amd/include/amd_pcie.h +++ b/drivers/gpu/drm/amd/include/amd_pcie.h @@ -27,6 +27,7 @@ #define CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 0x00010000 #define CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 0x00020000 #define CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3 0x00040000 +#define CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4 0x00080000 #define CAIL_PCIE_LINK_SPEED_SUPPORT_MASK 0xFFFF0000 #define CAIL_PCIE_LINK_SPEED_SUPPORT_SHIFT 16 @@ -34,6 +35,7 @@ #define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1 0x00000001 #define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2 0x00000002 #define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3 0x00000004 +#define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN4 0x00000008 #define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_MASK 0x0000FFFF #define CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_SHIFT 0 From 5d9a6330403271fbb1244f14380a7cc44662796f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 25 Jun 2018 13:07:50 -0500 Subject: [PATCH 118/133] drm/amdgpu: use pcie functions for link width and speed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the newly exported pci functions to get the link width and speed rather than using the drm duplicated versions. Also query the GPU link caps directly rather than hardcoding them. Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 83 +++++++++++++++------- drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c | 7 +- drivers/gpu/drm/amd/amdgpu/ci_dpm.c | 3 +- drivers/gpu/drm/amd/amdgpu/si_dpm.c | 3 +- 4 files changed, 65 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index c35db859f050..d43abbd2a3cc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3311,8 +3311,9 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, */ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev) { - u32 mask; - int ret; + struct pci_dev *pdev; + enum pci_bus_speed speed_cap; + enum pcie_link_width link_width; if (amdgpu_pcie_gen_cap) adev->pm.pcie_gen_mask = amdgpu_pcie_gen_cap; @@ -3330,27 +3331,61 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev) } if (adev->pm.pcie_gen_mask == 0) { - ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask); - if (!ret) { - adev->pm.pcie_gen_mask = (CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1 | + /* asic caps */ + pdev = adev->pdev; + speed_cap = pcie_get_speed_cap(pdev); + if (speed_cap == PCI_SPEED_UNKNOWN) { + adev->pm.pcie_gen_mask |= (CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1 | CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2 | CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3); - - if (mask & DRM_PCIE_SPEED_25) - adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1; - if (mask & DRM_PCIE_SPEED_50) - adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2; - if (mask & DRM_PCIE_SPEED_80) - adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3; } else { - adev->pm.pcie_gen_mask = AMDGPU_DEFAULT_PCIE_GEN_MASK; + if (speed_cap == PCIE_SPEED_16_0GT) + adev->pm.pcie_gen_mask |= (CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1 | + CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2 | + CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3 | + CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN4); + else if (speed_cap == PCIE_SPEED_8_0GT) + adev->pm.pcie_gen_mask |= (CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1 | + CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2 | + CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3); + else if (speed_cap == PCIE_SPEED_5_0GT) + adev->pm.pcie_gen_mask |= (CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1 | + CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2); + else + adev->pm.pcie_gen_mask |= CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1; + } + /* platform caps */ + pdev = adev->ddev->pdev->bus->self; + speed_cap = pcie_get_speed_cap(pdev); + if (speed_cap == PCI_SPEED_UNKNOWN) { + adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 | + CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2); + } else { + if (speed_cap == PCIE_SPEED_16_0GT) + adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 | + CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 | + CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3 | + CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4); + else if (speed_cap == PCIE_SPEED_8_0GT) + adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 | + CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 | + CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3); + else if (speed_cap == PCIE_SPEED_5_0GT) + adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 | + CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2); + else + adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1; + } } if (adev->pm.pcie_mlw_mask == 0) { - ret = drm_pcie_get_max_link_width(adev->ddev, &mask); - if (!ret) { - switch (mask) { - case 32: + pdev = adev->ddev->pdev->bus->self; + link_width = pcie_get_width_cap(pdev); + if (link_width == PCIE_LNK_WIDTH_UNKNOWN) { + adev->pm.pcie_mlw_mask |= AMDGPU_DEFAULT_PCIE_MLW_MASK; + } else { + switch (link_width) { + case PCIE_LNK_X32: adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 | @@ -3359,7 +3394,7 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev) CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X1); break; - case 16: + case PCIE_LNK_X16: adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 | @@ -3367,36 +3402,34 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev) CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X1); break; - case 12: + case PCIE_LNK_X12: adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X1); break; - case 8: + case PCIE_LNK_X8: adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X1); break; - case 4: + case PCIE_LNK_X4: adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X1); break; - case 2: + case PCIE_LNK_X2: adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 | CAIL_PCIE_LINK_WIDTH_SUPPORT_X1); break; - case 1: + case PCIE_LNK_X1: adev->pm.pcie_mlw_mask = CAIL_PCIE_LINK_WIDTH_SUPPORT_X1; break; default: break; } - } else { - adev->pm.pcie_mlw_mask = AMDGPU_DEFAULT_PCIE_MLW_MASK; } } } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c index 77ad59ade85c..1c4595562f8f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c @@ -28,6 +28,7 @@ #include "amdgpu_i2c.h" #include "amdgpu_dpm.h" #include "atom.h" +#include "amd_pcie.h" void amdgpu_dpm_print_class_info(u32 class, u32 class2) { @@ -936,9 +937,11 @@ enum amdgpu_pcie_gen amdgpu_get_pcie_gen_support(struct amdgpu_device *adev, case AMDGPU_PCIE_GEN3: return AMDGPU_PCIE_GEN3; default: - if ((sys_mask & DRM_PCIE_SPEED_80) && (default_gen == AMDGPU_PCIE_GEN3)) + if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) && + (default_gen == AMDGPU_PCIE_GEN3)) return AMDGPU_PCIE_GEN3; - else if ((sys_mask & DRM_PCIE_SPEED_50) && (default_gen == AMDGPU_PCIE_GEN2)) + else if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) && + (default_gen == AMDGPU_PCIE_GEN2)) return AMDGPU_PCIE_GEN2; else return AMDGPU_PCIE_GEN1; diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index d79ad93b01c3..d2469453dca2 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c @@ -5846,8 +5846,7 @@ static int ci_dpm_init(struct amdgpu_device *adev) adev->pm.dpm.priv = pi; pi->sys_pcie_mask = - (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_MASK) >> - CAIL_PCIE_LINK_SPEED_SUPPORT_SHIFT; + adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_MASK; pi->force_pcie_gen = AMDGPU_PCIE_GEN_INVALID; diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index 3560b7dc1798..db327b412562 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c @@ -7318,8 +7318,7 @@ static int si_dpm_init(struct amdgpu_device *adev) pi = &eg_pi->rv7xx; si_pi->sys_pcie_mask = - (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_MASK) >> - CAIL_PCIE_LINK_SPEED_SUPPORT_SHIFT; + adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_MASK; si_pi->force_pcie_gen = AMDGPU_PCIE_GEN_INVALID; si_pi->boot_pcie_gen = si_get_current_pcie_speed(adev); From 5f152a572c10cae4b08c2c5f2932a51684f454ba Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 25 Jun 2018 14:37:45 -0500 Subject: [PATCH 119/133] drm/radeon: use pcie functions for link width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the last user of drm_pcie_get_speed_cap_mask. Use the pci version so we can drop drm_pcie_get_speed_cap_mask. Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ci_dpm.c | 20 +++++++++++++++----- drivers/gpu/drm/radeon/cik.c | 22 ++++++++++++---------- drivers/gpu/drm/radeon/r600_dpm.c | 4 ++-- drivers/gpu/drm/radeon/radeon.h | 4 ++++ drivers/gpu/drm/radeon/si.c | 22 ++++++++++++---------- drivers/gpu/drm/radeon/si_dpm.c | 20 +++++++++++++++----- 6 files changed, 60 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index b9302c918271..d587779a80b4 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -5676,19 +5676,29 @@ int ci_dpm_init(struct radeon_device *rdev) u16 data_offset, size; u8 frev, crev; struct ci_power_info *pi; + enum pci_bus_speed speed_cap; + struct pci_dev *root = rdev->pdev->bus->self; int ret; - u32 mask; pi = kzalloc(sizeof(struct ci_power_info), GFP_KERNEL); if (pi == NULL) return -ENOMEM; rdev->pm.dpm.priv = pi; - ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask); - if (ret) + speed_cap = pcie_get_speed_cap(root); + if (speed_cap == PCI_SPEED_UNKNOWN) { pi->sys_pcie_mask = 0; - else - pi->sys_pcie_mask = mask; + } else { + if (speed_cap == PCIE_SPEED_8_0GT) + pi->sys_pcie_mask = RADEON_PCIE_SPEED_25 | + RADEON_PCIE_SPEED_50 | + RADEON_PCIE_SPEED_80; + else if (speed_cap == PCIE_SPEED_5_0GT) + pi->sys_pcie_mask = RADEON_PCIE_SPEED_25 | + RADEON_PCIE_SPEED_50; + else + pi->sys_pcie_mask = RADEON_PCIE_SPEED_25; + } pi->force_pcie_gen = RADEON_PCIE_GEN_INVALID; pi->pcie_gen_performance.max = RADEON_PCIE_GEN1; diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 7c73bc7e2f85..ebce4601a305 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -9499,9 +9499,10 @@ int cik_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk) static void cik_pcie_gen3_enable(struct radeon_device *rdev) { struct pci_dev *root = rdev->pdev->bus->self; + enum pci_bus_speed speed_cap; int bridge_pos, gpu_pos; - u32 speed_cntl, mask, current_data_rate; - int ret, i; + u32 speed_cntl, current_data_rate; + int i; u16 tmp16; if (pci_is_root_bus(rdev->pdev->bus)) @@ -9516,23 +9517,24 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev) if (!(rdev->flags & RADEON_IS_PCIE)) return; - ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask); - if (ret != 0) + speed_cap = pcie_get_speed_cap(root); + if (speed_cap == PCI_SPEED_UNKNOWN) return; - if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80))) + if ((speed_cap != PCIE_SPEED_8_0GT) && + (speed_cap != PCIE_SPEED_5_0GT)) return; speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >> LC_CURRENT_DATA_RATE_SHIFT; - if (mask & DRM_PCIE_SPEED_80) { + if (speed_cap == PCIE_SPEED_8_0GT) { if (current_data_rate == 2) { DRM_INFO("PCIE gen 3 link speeds already enabled\n"); return; } DRM_INFO("enabling PCIE gen 3 link speeds, disable with radeon.pcie_gen2=0\n"); - } else if (mask & DRM_PCIE_SPEED_50) { + } else if (speed_cap == PCIE_SPEED_5_0GT) { if (current_data_rate == 1) { DRM_INFO("PCIE gen 2 link speeds already enabled\n"); return; @@ -9548,7 +9550,7 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev) if (!gpu_pos) return; - if (mask & DRM_PCIE_SPEED_80) { + if (speed_cap == PCIE_SPEED_8_0GT) { /* re-try equalization if gen3 is not already enabled */ if (current_data_rate != 2) { u16 bridge_cfg, gpu_cfg; @@ -9636,9 +9638,9 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev) pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); tmp16 &= ~0xf; - if (mask & DRM_PCIE_SPEED_80) + if (speed_cap == PCIE_SPEED_8_0GT) tmp16 |= 3; /* gen3 */ - else if (mask & DRM_PCIE_SPEED_50) + else if (speed_cap == PCIE_SPEED_5_0GT) tmp16 |= 2; /* gen2 */ else tmp16 |= 1; /* gen1 */ diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c index 73d4c5348116..5e044c98fca2 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.c +++ b/drivers/gpu/drm/radeon/r600_dpm.c @@ -1327,9 +1327,9 @@ enum radeon_pcie_gen r600_get_pcie_gen_support(struct radeon_device *rdev, case RADEON_PCIE_GEN3: return RADEON_PCIE_GEN3; default: - if ((sys_mask & DRM_PCIE_SPEED_80) && (default_gen == RADEON_PCIE_GEN3)) + if ((sys_mask & RADEON_PCIE_SPEED_80) && (default_gen == RADEON_PCIE_GEN3)) return RADEON_PCIE_GEN3; - else if ((sys_mask & DRM_PCIE_SPEED_50) && (default_gen == RADEON_PCIE_GEN2)) + else if ((sys_mask & RADEON_PCIE_SPEED_50) && (default_gen == RADEON_PCIE_GEN2)) return RADEON_PCIE_GEN2; else return RADEON_PCIE_GEN1; diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 4a2eb409aacc..1a6f6edb3515 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1653,6 +1653,10 @@ struct radeon_pm { struct radeon_dpm dpm; }; +#define RADEON_PCIE_SPEED_25 1 +#define RADEON_PCIE_SPEED_50 2 +#define RADEON_PCIE_SPEED_80 4 + int radeon_pm_get_type_index(struct radeon_device *rdev, enum radeon_pm_state_type ps_type, int instance); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 1907c950d76f..85c604d29235 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -7082,9 +7082,10 @@ int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) static void si_pcie_gen3_enable(struct radeon_device *rdev) { struct pci_dev *root = rdev->pdev->bus->self; + enum pci_bus_speed speed_cap; int bridge_pos, gpu_pos; - u32 speed_cntl, mask, current_data_rate; - int ret, i; + u32 speed_cntl, current_data_rate; + int i; u16 tmp16; if (pci_is_root_bus(rdev->pdev->bus)) @@ -7099,23 +7100,24 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev) if (!(rdev->flags & RADEON_IS_PCIE)) return; - ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask); - if (ret != 0) + speed_cap = pcie_get_speed_cap(root); + if (speed_cap == PCI_SPEED_UNKNOWN) return; - if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80))) + if ((speed_cap != PCIE_SPEED_8_0GT) && + (speed_cap != PCIE_SPEED_5_0GT)) return; speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >> LC_CURRENT_DATA_RATE_SHIFT; - if (mask & DRM_PCIE_SPEED_80) { + if (speed_cap == PCIE_SPEED_8_0GT) { if (current_data_rate == 2) { DRM_INFO("PCIE gen 3 link speeds already enabled\n"); return; } DRM_INFO("enabling PCIE gen 3 link speeds, disable with radeon.pcie_gen2=0\n"); - } else if (mask & DRM_PCIE_SPEED_50) { + } else if (speed_cap == PCIE_SPEED_5_0GT) { if (current_data_rate == 1) { DRM_INFO("PCIE gen 2 link speeds already enabled\n"); return; @@ -7131,7 +7133,7 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev) if (!gpu_pos) return; - if (mask & DRM_PCIE_SPEED_80) { + if (speed_cap == PCIE_SPEED_8_0GT) { /* re-try equalization if gen3 is not already enabled */ if (current_data_rate != 2) { u16 bridge_cfg, gpu_cfg; @@ -7219,9 +7221,9 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev) pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); tmp16 &= ~0xf; - if (mask & DRM_PCIE_SPEED_80) + if (speed_cap == PCIE_SPEED_8_0GT) tmp16 |= 3; /* gen3 */ - else if (mask & DRM_PCIE_SPEED_50) + else if (speed_cap == PCIE_SPEED_5_0GT) tmp16 |= 2; /* gen2 */ else tmp16 |= 1; /* gen1 */ diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index fea88078cf8e..8fb60b3af015 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -6899,8 +6899,9 @@ int si_dpm_init(struct radeon_device *rdev) struct ni_power_info *ni_pi; struct si_power_info *si_pi; struct atom_clock_dividers dividers; + enum pci_bus_speed speed_cap; + struct pci_dev *root = rdev->pdev->bus->self; int ret; - u32 mask; si_pi = kzalloc(sizeof(struct si_power_info), GFP_KERNEL); if (si_pi == NULL) @@ -6910,11 +6911,20 @@ int si_dpm_init(struct radeon_device *rdev) eg_pi = &ni_pi->eg; pi = &eg_pi->rv7xx; - ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask); - if (ret) + speed_cap = pcie_get_speed_cap(root); + if (speed_cap == PCI_SPEED_UNKNOWN) { si_pi->sys_pcie_mask = 0; - else - si_pi->sys_pcie_mask = mask; + } else { + if (speed_cap == PCIE_SPEED_8_0GT) + si_pi->sys_pcie_mask = RADEON_PCIE_SPEED_25 | + RADEON_PCIE_SPEED_50 | + RADEON_PCIE_SPEED_80; + else if (speed_cap == PCIE_SPEED_5_0GT) + si_pi->sys_pcie_mask = RADEON_PCIE_SPEED_25 | + RADEON_PCIE_SPEED_50; + else + si_pi->sys_pcie_mask = RADEON_PCIE_SPEED_25; + } si_pi->force_pcie_gen = RADEON_PCIE_GEN_INVALID; si_pi->boot_pcie_gen = si_get_current_pcie_speed(rdev); From 289278cb7d32685ee75baf599857d7049c4b8030 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 25 Jun 2018 15:14:46 -0500 Subject: [PATCH 120/133] drm: drop drm_pcie_get_speed_cap_mask and drm_pcie_get_max_link_width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These functions duplicated functionality which was ultimately added to the pci core. All users of these functions have been ported to using the newly exposed pci functionality. These functions are no longer used, so drop them. Acked-by: Christian König Reviewed-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/drm_pci.c | 58 --------------------------------------- include/drm/drm_pci.h | 7 ----- 2 files changed, 65 deletions(-) diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 4db9c515b74f..896e42a34895 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -326,64 +326,6 @@ int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver) } EXPORT_SYMBOL(drm_legacy_pci_init); -int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask) -{ - struct pci_dev *root; - u32 lnkcap, lnkcap2; - - *mask = 0; - if (!dev->pdev) - return -EINVAL; - - root = dev->pdev->bus->self; - - /* we've been informed via and serverworks don't make the cut */ - if (root->vendor == PCI_VENDOR_ID_VIA || - root->vendor == PCI_VENDOR_ID_SERVERWORKS) - return -EINVAL; - - pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap); - pcie_capability_read_dword(root, PCI_EXP_LNKCAP2, &lnkcap2); - - if (lnkcap2) { /* PCIe r3.0-compliant */ - if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_2_5GB) - *mask |= DRM_PCIE_SPEED_25; - if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB) - *mask |= DRM_PCIE_SPEED_50; - if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB) - *mask |= DRM_PCIE_SPEED_80; - } else { /* pre-r3.0 */ - if (lnkcap & PCI_EXP_LNKCAP_SLS_2_5GB) - *mask |= DRM_PCIE_SPEED_25; - if (lnkcap & PCI_EXP_LNKCAP_SLS_5_0GB) - *mask |= (DRM_PCIE_SPEED_25 | DRM_PCIE_SPEED_50); - } - - DRM_INFO("probing gen 2 caps for device %x:%x = %x/%x\n", root->vendor, root->device, lnkcap, lnkcap2); - return 0; -} -EXPORT_SYMBOL(drm_pcie_get_speed_cap_mask); - -int drm_pcie_get_max_link_width(struct drm_device *dev, u32 *mlw) -{ - struct pci_dev *root; - u32 lnkcap; - - *mlw = 0; - if (!dev->pdev) - return -EINVAL; - - root = dev->pdev->bus->self; - - pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap); - - *mlw = (lnkcap & PCI_EXP_LNKCAP_MLW) >> 4; - - DRM_INFO("probing mlw for device %x:%x = %x\n", root->vendor, root->device, lnkcap); - return 0; -} -EXPORT_SYMBOL(drm_pcie_get_max_link_width); - #else void drm_pci_agp_destroy(struct drm_device *dev) {} diff --git a/include/drm/drm_pci.h b/include/drm/drm_pci.h index 674599025d7d..8181e9e7cf1d 100644 --- a/include/drm/drm_pci.h +++ b/include/drm/drm_pci.h @@ -58,11 +58,4 @@ static inline int drm_get_pci_dev(struct pci_dev *pdev, } #endif -#define DRM_PCIE_SPEED_25 1 -#define DRM_PCIE_SPEED_50 2 -#define DRM_PCIE_SPEED_80 4 - -int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *speed_mask); -int drm_pcie_get_max_link_width(struct drm_device *dev, u32 *mlw); - #endif /* _DRM_PCI_H_ */ From ea870e44415a5f5ed09b6e002e38d3e0de7f390e Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 22 Jun 2018 14:12:59 +0800 Subject: [PATCH 121/133] drm/amd/pp: Export notify_smu_enable_pwe to display Display can notify smu to enable pwe after gpu suspend. It is used in case when display resumes from S3 and wants to start audio driver by enabling pwe Acked-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- .../gpu/drm/amd/include/kgd_pp_interface.h | 7 ++++--- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 99ee3edd1609..6a41b81c7325 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -241,6 +241,9 @@ struct amd_pm_funcs { int (*set_clockgating_by_smu)(void *handle, uint32_t msg_id); int (*set_power_limit)(void *handle, uint32_t n); int (*get_power_limit)(void *handle, uint32_t *limit, bool default_limit); + int (*get_power_profile_mode)(void *handle, char *buf); + int (*set_power_profile_mode)(void *handle, long *input, uint32_t size); + int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size); /* export to DC */ u32 (*get_sclk)(void *handle, bool low); u32 (*get_mclk)(void *handle, bool low); @@ -265,9 +268,7 @@ struct amd_pm_funcs { struct pp_display_clock_request *clock); int (*get_display_mode_validation_clocks)(void *handle, struct amd_pp_simple_clock_info *clocks); - int (*get_power_profile_mode)(void *handle, char *buf); - int (*set_power_profile_mode)(void *handle, long *input, uint32_t size); - int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size); + int (*notify_smu_enable_pwe)(void *handle); }; #endif diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index b72cc644d4e7..145e5c403bea 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -1201,6 +1201,25 @@ static int pp_set_powergating_by_smu(void *handle, return ret; } +static int pp_notify_smu_enable_pwe(void *handle) +{ + struct pp_hwmgr *hwmgr = handle; + + if (!hwmgr || !hwmgr->pm_en) + return -EINVAL;; + + if (hwmgr->hwmgr_func->smus_notify_pwe == NULL) { + pr_info("%s was not implemented.\n", __func__); + return -EINVAL;; + } + + mutex_lock(&hwmgr->smu_lock); + hwmgr->hwmgr_func->smus_notify_pwe(hwmgr); + mutex_unlock(&hwmgr->smu_lock); + + return 0; +} + static const struct amd_pm_funcs pp_dpm_funcs = { .load_firmware = pp_dpm_load_fw, .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete, @@ -1244,4 +1263,5 @@ static const struct amd_pm_funcs pp_dpm_funcs = { .set_watermarks_for_clocks_ranges = pp_set_watermarks_for_clocks_ranges, .display_clock_voltage_request = pp_display_clock_voltage_request, .get_display_mode_validation_clocks = pp_get_display_mode_validation_clocks, + .notify_smu_enable_pwe = pp_notify_smu_enable_pwe, }; From b0a634ac68337b263e01d83359a023676e370cce Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 3 Jul 2018 16:31:35 +0800 Subject: [PATCH 122/133] drm/amd/display: Refine the implementation of dm_pp_get_funcs_rv powerplay/dpm export all interfaces in struct amd_pm_funcs. so call common exported interfaces instead of powerplay inner interfaces Also not include header file hwmgr.h Acked-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- .../amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) 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 81845116cdcc..9c105c07eb25 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 @@ -33,7 +33,6 @@ #include "amdgpu_dm_irq.h" #include "amdgpu_pm.h" #include "dm_pp_smu.h" -#include "../../powerplay/inc/hwmgr.h" bool dm_pp_apply_display_requirements( @@ -452,76 +451,77 @@ bool dm_pp_get_static_clocks( void pp_rv_set_display_requirement(struct pp_smu *pp, struct pp_smu_display_requirement_rv *req) { - struct amdgpu_device *adev = pp->ctx->driver_context; - struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; - int ret = 0; - if (hwmgr->hwmgr_func->set_deep_sleep_dcefclk) - ret = hwmgr->hwmgr_func->set_deep_sleep_dcefclk(hwmgr, req->hard_min_dcefclk_khz/10); - if (hwmgr->hwmgr_func->set_active_display_count) - ret = hwmgr->hwmgr_func->set_active_display_count(hwmgr, req->display_count); + struct dc_context *ctx = pp->ctx; + struct amdgpu_device *adev = ctx->driver_context; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - //store_cc6 is not yet implemented in SMU level + if (!pp_funcs || !pp_funcs->display_configuration_changed) + return; + + amdgpu_dpm_display_configuration_changed(adev); } void pp_rv_set_wm_ranges(struct pp_smu *pp, struct pp_smu_wm_range_sets *ranges) { - struct amdgpu_device *adev = pp->ctx->driver_context; - struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; - struct pp_wm_sets_with_clock_ranges_soc15 ranges_soc15 = {0}; - int i = 0; + struct dc_context *ctx = pp->ctx; + struct amdgpu_device *adev = ctx->driver_context; + void *pp_handle = adev->powerplay.pp_handle; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; + struct dm_pp_wm_sets_with_clock_ranges_soc15 wm_with_clock_ranges; + struct dm_pp_clock_range_for_dmif_wm_set_soc15 *wm_dce_clocks = wm_with_clock_ranges.wm_dmif_clocks_ranges; + struct dm_pp_clock_range_for_mcif_wm_set_soc15 *wm_soc_clocks = wm_with_clock_ranges.wm_mcif_clocks_ranges; + int32_t i; - if (!hwmgr->hwmgr_func->set_watermarks_for_clocks_ranges || - !pp || !ranges) - return; + 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; - //not entirely sure if thats a correct assignment - ranges_soc15.num_wm_sets_dmif = ranges->num_reader_wm_sets; - ranges_soc15.num_wm_sets_mcif = ranges->num_writer_wm_sets; - - for (i = 0; i < ranges_soc15.num_wm_sets_dmif; i++) { + for (i = 0; i < wm_with_clock_ranges.num_wm_dmif_sets; i++) { if (ranges->reader_wm_sets[i].wm_inst > 3) - ranges_soc15.wm_sets_dmif[i].wm_set_id = DC_WM_SET_A; + wm_dce_clocks[i].wm_set_id = WM_SET_A; else - ranges_soc15.wm_sets_dmif[i].wm_set_id = + wm_dce_clocks[i].wm_set_id = ranges->reader_wm_sets[i].wm_inst; - ranges_soc15.wm_sets_dmif[i].wm_max_dcefclk_in_khz = + wm_dce_clocks[i].wm_max_dcfclk_clk_in_khz = ranges->reader_wm_sets[i].max_drain_clk_khz; - ranges_soc15.wm_sets_dmif[i].wm_min_dcefclk_in_khz = + wm_dce_clocks[i].wm_min_dcfclk_clk_in_khz = ranges->reader_wm_sets[i].min_drain_clk_khz; - ranges_soc15.wm_sets_dmif[i].wm_max_memclk_in_khz = + wm_dce_clocks[i].wm_max_mem_clk_in_khz = ranges->reader_wm_sets[i].max_fill_clk_khz; - ranges_soc15.wm_sets_dmif[i].wm_min_memclk_in_khz = + wm_dce_clocks[i].wm_min_mem_clk_in_khz = ranges->reader_wm_sets[i].min_fill_clk_khz; } - for (i = 0; i < ranges_soc15.num_wm_sets_mcif; i++) { + for (i = 0; i < wm_with_clock_ranges.num_wm_mcif_sets; i++) { if (ranges->writer_wm_sets[i].wm_inst > 3) - ranges_soc15.wm_sets_dmif[i].wm_set_id = DC_WM_SET_A; + wm_soc_clocks[i].wm_set_id = WM_SET_A; else - ranges_soc15.wm_sets_mcif[i].wm_set_id = + wm_soc_clocks[i].wm_set_id = ranges->writer_wm_sets[i].wm_inst; - ranges_soc15.wm_sets_mcif[i].wm_max_socclk_in_khz = + wm_soc_clocks[i].wm_max_socclk_clk_in_khz = ranges->writer_wm_sets[i].max_fill_clk_khz; - ranges_soc15.wm_sets_mcif[i].wm_min_socclk_in_khz = + wm_soc_clocks[i].wm_min_socclk_clk_in_khz = ranges->writer_wm_sets[i].min_fill_clk_khz; - ranges_soc15.wm_sets_mcif[i].wm_max_memclk_in_khz = + wm_soc_clocks[i].wm_max_mem_clk_in_khz = ranges->writer_wm_sets[i].max_fill_clk_khz; - ranges_soc15.wm_sets_mcif[i].wm_min_memclk_in_khz = + wm_soc_clocks[i].wm_min_mem_clk_in_khz = ranges->writer_wm_sets[i].min_fill_clk_khz; } - hwmgr->hwmgr_func->set_watermarks_for_clocks_ranges(hwmgr, &ranges_soc15); - + pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, &wm_with_clock_ranges); } void pp_rv_set_pme_wa_enable(struct pp_smu *pp) { - struct amdgpu_device *adev = pp->ctx->driver_context; - struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; + struct dc_context *ctx = pp->ctx; + struct amdgpu_device *adev = ctx->driver_context; + void *pp_handle = adev->powerplay.pp_handle; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - if (hwmgr->hwmgr_func->smus_notify_pwe) - hwmgr->hwmgr_func->smus_notify_pwe(hwmgr); + if (!pp_funcs || !pp_funcs->notify_smu_enable_pwe) + return; + + pp_funcs->notify_smu_enable_pwe(pp_handle); } void dm_pp_get_funcs_rv( From 70b63170c3effc1d9a66fbfe4a5702c8cbbd31c3 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 3 Jul 2018 17:17:21 +0800 Subject: [PATCH 123/133] drm/amd/display: Fix copy error when set memory clocks Set memory clocks same as soc clocks Acked-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 9c105c07eb25..50e863024f58 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 @@ -503,9 +503,9 @@ void pp_rv_set_wm_ranges(struct pp_smu *pp, wm_soc_clocks[i].wm_min_socclk_clk_in_khz = ranges->writer_wm_sets[i].min_fill_clk_khz; wm_soc_clocks[i].wm_max_mem_clk_in_khz = - ranges->writer_wm_sets[i].max_fill_clk_khz; + ranges->writer_wm_sets[i].max_drain_clk_khz; wm_soc_clocks[i].wm_min_mem_clk_in_khz = - ranges->writer_wm_sets[i].min_fill_clk_khz; + ranges->writer_wm_sets[i].min_drain_clk_khz; } pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, &wm_with_clock_ranges); From 20582319bce482e65ee1f417b9867f028d058c12 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Wed, 20 Jun 2018 15:05:04 +0800 Subject: [PATCH 124/133] drm/amd/pp: Remove the same struct define in powerplay delete the same struct define in powerplay, share the struct with display. Acked-by: Alex Deucher Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/dm_pp_interface.h | 37 +--------------- .../gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 2 +- .../gpu/drm/amd/powerplay/hwmgr/smu_helper.c | 42 +++++++++---------- .../gpu/drm/amd/powerplay/hwmgr/smu_helper.h | 2 +- .../drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 2 +- .../drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 2 +- 6 files changed, 27 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/amd/include/dm_pp_interface.h b/drivers/gpu/drm/amd/include/dm_pp_interface.h index 7852952d1fde..1d93a0c574c9 100644 --- a/drivers/gpu/drm/amd/include/dm_pp_interface.h +++ b/drivers/gpu/drm/amd/include/dm_pp_interface.h @@ -23,6 +23,8 @@ #ifndef _DM_PP_INTERFACE_ #define _DM_PP_INTERFACE_ +#include "dm_services_types.h" + #define PP_MAX_CLOCK_LEVELS 16 enum amd_pp_display_config_type{ @@ -189,39 +191,4 @@ struct pp_display_clock_request { uint32_t clock_freq_in_khz; }; -#define PP_MAX_WM_SETS 4 - -enum pp_wm_set_id { - DC_WM_SET_A = 0, - DC_WM_SET_B, - DC_WM_SET_C, - DC_WM_SET_D, - DC_WM_SET_INVALID = 0xffff, -}; - -struct pp_wm_set_with_dmif_clock_range_soc15 { - enum pp_wm_set_id wm_set_id; - uint32_t wm_min_dcefclk_in_khz; - uint32_t wm_max_dcefclk_in_khz; - uint32_t wm_min_memclk_in_khz; - uint32_t wm_max_memclk_in_khz; -}; - -struct pp_wm_set_with_mcif_clock_range_soc15 { - enum pp_wm_set_id wm_set_id; - uint32_t wm_min_socclk_in_khz; - uint32_t wm_max_socclk_in_khz; - uint32_t wm_min_memclk_in_khz; - uint32_t wm_max_memclk_in_khz; -}; - -struct pp_wm_sets_with_clock_ranges_soc15 { - uint32_t num_wm_sets_dmif; - uint32_t num_wm_sets_mcif; - struct pp_wm_set_with_dmif_clock_range_soc15 - wm_sets_dmif[PP_MAX_WM_SETS]; - struct pp_wm_set_with_mcif_clock_range_soc15 - wm_sets_mcif[PP_MAX_WM_SETS]; -}; - #endif /* _DM_PP_INTERFACE_ */ diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c index 02fc0bc41e0a..a63e00653324 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c @@ -1111,7 +1111,7 @@ static int smu10_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, void *clock_ranges) { struct smu10_hwmgr *data = hwmgr->backend; - struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges = clock_ranges; + struct dm_pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges = clock_ranges; Watermarks_t *table = &(data->water_marks_table); int result = 0; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c index 93a3d022ba47..3effb5583d1f 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c @@ -652,7 +652,7 @@ int smu_get_voltage_dependency_table_ppt_v1( } int smu_set_watermarks_for_clocks_ranges(void *wt_table, - struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges) + struct dm_pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges) { uint32_t i; struct watermarks *table = wt_table; @@ -660,49 +660,49 @@ int smu_set_watermarks_for_clocks_ranges(void *wt_table, if (!table || !wm_with_clock_ranges) return -EINVAL; - if (wm_with_clock_ranges->num_wm_sets_dmif > 4 || wm_with_clock_ranges->num_wm_sets_mcif > 4) + if (wm_with_clock_ranges->num_wm_dmif_sets > 4 || wm_with_clock_ranges->num_wm_mcif_sets > 4) return -EINVAL; - for (i = 0; i < wm_with_clock_ranges->num_wm_sets_dmif; i++) { + for (i = 0; i < wm_with_clock_ranges->num_wm_dmif_sets; i++) { table->WatermarkRow[1][i].MinClock = cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_dmif[i].wm_min_dcefclk_in_khz) / - 100); + (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz) / + 1000); table->WatermarkRow[1][i].MaxClock = cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_dmif[i].wm_max_dcefclk_in_khz) / + (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz) / 100); table->WatermarkRow[1][i].MinUclk = cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_dmif[i].wm_min_memclk_in_khz) / - 100); + (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz) / + 1000); table->WatermarkRow[1][i].MaxUclk = cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_dmif[i].wm_max_memclk_in_khz) / - 100); + (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz) / + 1000); table->WatermarkRow[1][i].WmSetting = (uint8_t) - wm_with_clock_ranges->wm_sets_dmif[i].wm_set_id; + wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id; } - for (i = 0; i < wm_with_clock_ranges->num_wm_sets_mcif; i++) { + for (i = 0; i < wm_with_clock_ranges->num_wm_mcif_sets; i++) { table->WatermarkRow[0][i].MinClock = cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_mcif[i].wm_min_socclk_in_khz) / - 100); + (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz) / + 1000); table->WatermarkRow[0][i].MaxClock = cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_mcif[i].wm_max_socclk_in_khz) / - 100); + (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz) / + 1000); table->WatermarkRow[0][i].MinUclk = cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_mcif[i].wm_min_memclk_in_khz) / - 100); + (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz) / + 1000); table->WatermarkRow[0][i].MaxUclk = cpu_to_le16((uint16_t) - (wm_with_clock_ranges->wm_sets_mcif[i].wm_max_memclk_in_khz) / - 100); + (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz) / + 1000); table->WatermarkRow[0][i].WmSetting = (uint8_t) - wm_with_clock_ranges->wm_sets_mcif[i].wm_set_id; + wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id; } return 0; } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.h b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.h index 916cc01e7652..5454289d5226 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.h @@ -107,7 +107,7 @@ int smu_get_voltage_dependency_table_ppt_v1( struct phm_ppt_v1_clock_voltage_dependency_table *dep_table); int smu_set_watermarks_for_clocks_ranges(void *wt_table, - struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges); + struct dm_pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges); #define PHM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT #define PHM_FIELD_MASK(reg, field) reg##__##field##_MASK diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index d515eb4fac9f..5e771bc119d6 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -4197,7 +4197,7 @@ static int vega10_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, void *clock_range) { struct vega10_hwmgr *data = hwmgr->backend; - struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges = clock_range; + struct dm_pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges = clock_range; Watermarks_t *table = &(data->smc_state_table.water_marks_table); int result = 0; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 0a090755545d..57492878874f 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -1785,7 +1785,7 @@ static int vega12_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, { struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); Watermarks_t *table = &(data->smc_state_table.water_marks_table); - struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges = clock_ranges; + struct dm_pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges = clock_ranges; if (!data->registry_data.disable_water_mark && data->smu_features[GNLD_DPM_DCEFCLK].supported && From 5d908944c5ba4fc8d301e1332635c64c1b77d843 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 4 Jul 2018 12:46:15 +0300 Subject: [PATCH 125/133] drm/amd/display: off by one in find_irq_source_info() The ->info[] array has DAL_IRQ_SOURCES_NUMBER elements so this condition should be >= instead of > or we could read one element beyond the end of the array. Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)") Signed-off-by: Dan Carpenter Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/irq/irq_service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c index dcdfa0f01551..604bea01fc13 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c +++ b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c @@ -78,7 +78,7 @@ const struct irq_source_info *find_irq_source_info( struct irq_service *irq_service, enum dc_irq_source source) { - if (source > DAL_IRQ_SOURCES_NUMBER || source < DC_IRQ_SOURCE_INVALID) + if (source >= DAL_IRQ_SOURCES_NUMBER || source < DC_IRQ_SOURCE_INVALID) return NULL; return &irq_service->info[source]; From 25177e7f94a3deeda410edaf9313d0f1a2bb68e0 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Wed, 4 Jul 2018 13:47:07 -0400 Subject: [PATCH 126/133] Revert "drm/amd/display: Fix indentation in dcn10 resource constructor" That change was a merge gone bad. This reverts commit cb1d7eacb58f7d1b7d0e57b26dc02d45eada4a3c. Signed-off-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 68be66eabc40..771e0cf29bba 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1068,8 +1068,7 @@ static bool construct( ctx->dc_bios->regs = &bios_regs; - pool->base.res_cap = &res_cap; - + pool->base.res_cap = &res_cap; pool->base.funcs = &dcn10_res_pool_funcs; /* From 4c1ac53eb867670883f1518f620b19c2fed7e516 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 4 Jul 2018 10:27:30 -0700 Subject: [PATCH 127/133] drm/amd/display: Use 2-factor allocator calls As already done treewide, switch from open-coded multiplication to 2-factor allocation helper. Signed-off-by: Kees Cook Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/modules/color/color_gamma.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c index 98edaefa2b47..ee69c949bfbf 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c @@ -1723,8 +1723,8 @@ bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans, kvfree(rgb_regamma); } else if (trans == TRANSFER_FUNCTION_HLG || trans == TRANSFER_FUNCTION_HLG12) { - rgb_regamma = kvzalloc(sizeof(*rgb_regamma) * - (MAX_HW_POINTS + _EXTRA_POINTS), + rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, + sizeof(*rgb_regamma), GFP_KERNEL); if (!rgb_regamma) goto rgb_regamma_alloc_fail; @@ -1802,8 +1802,8 @@ bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans, kvfree(rgb_degamma); } else if (trans == TRANSFER_FUNCTION_HLG || trans == TRANSFER_FUNCTION_HLG12) { - rgb_degamma = kvzalloc(sizeof(*rgb_degamma) * - (MAX_HW_POINTS + _EXTRA_POINTS), + rgb_degamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, + sizeof(*rgb_degamma), GFP_KERNEL); if (!rgb_degamma) goto rgb_degamma_alloc_fail; From 6f3472a993e7cb63cde5d818dcabc8e42fc03744 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 4 Jul 2018 08:22:11 -0500 Subject: [PATCH 128/133] drm/amd/display/dc/dce: Fix multiple potential integer overflows Add suffix ULL to constant 5 and cast variables target_pix_clk_khz and feedback_divider to uint64_t in order to avoid multiple potential integer overflows and give the compiler complete information about the proper arithmetic to use. Notice that such constant and variables are used in contexts that expect expressions of type uint64_t (64 bits, unsigned). The current casts to uint64_t effectively apply to each expression as a whole, but they do not prevent them from being evaluated using 32-bit arithmetic instead of 64-bit arithmetic. Also, once the expressions are properly evaluated using 64-bit arithmentic, there is no need for the parentheses that enclose them. Addresses-Coverity-ID: 1460245 ("Unintentional integer overflow") Addresses-Coverity-ID: 1460286 ("Unintentional integer overflow") Addresses-Coverity-ID: 1460401 ("Unintentional integer overflow") Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)") Signed-off-by: Gustavo A. R. Silva Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c index 88b09dd758ba..ca137757a69e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c @@ -133,7 +133,7 @@ static bool calculate_fb_and_fractional_fb_divider( uint64_t feedback_divider; feedback_divider = - (uint64_t)(target_pix_clk_khz * ref_divider * post_divider); + (uint64_t)target_pix_clk_khz * ref_divider * post_divider; feedback_divider *= 10; /* additional factor, since we divide by 10 afterwards */ feedback_divider *= (uint64_t)(calc_pll_cs->fract_fb_divider_factor); @@ -145,8 +145,8 @@ static bool calculate_fb_and_fractional_fb_divider( * of fractional feedback decimal point and the fractional FB Divider precision * is 2 then the equation becomes (ullfeedbackDivider + 5*100) / (10*100))*/ - feedback_divider += (uint64_t) - (5 * calc_pll_cs->fract_fb_divider_precision_factor); + feedback_divider += 5ULL * + calc_pll_cs->fract_fb_divider_precision_factor; feedback_divider = div_u64(feedback_divider, calc_pll_cs->fract_fb_divider_precision_factor * 10); @@ -203,8 +203,8 @@ static bool calc_fb_divider_checking_tolerance( &fract_feedback_divider); /*Actual calculated value*/ - actual_calc_clk_khz = (uint64_t)(feedback_divider * - calc_pll_cs->fract_fb_divider_factor) + + actual_calc_clk_khz = (uint64_t)feedback_divider * + calc_pll_cs->fract_fb_divider_factor + fract_feedback_divider; actual_calc_clk_khz *= calc_pll_cs->ref_freq_khz; actual_calc_clk_khz = From 87e3f1366eaa82c78b826b38008987406470b03d Mon Sep 17 00:00:00 2001 From: Darren Powell Date: Mon, 25 Jun 2018 19:04:03 -0400 Subject: [PATCH 129/133] drm/amd: Remove errors from sphinx documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eliminating the warnings produced by sphinx when processing the sphinx comments in amdgpu_device.c & amdgpu_mn.c Signed-off-by: Darren Powell Reviewed-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 20 ++++++++++++-------- drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | 5 +++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index d43abbd2a3cc..9883fa9bb41b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1076,7 +1076,7 @@ static const struct vga_switcheroo_client_ops amdgpu_switcheroo_ops = { /** * amdgpu_device_ip_set_clockgating_state - set the CG state * - * @adev: amdgpu_device pointer + * @dev: amdgpu_device pointer * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) * @state: clockgating state (gate or ungate) * @@ -1110,7 +1110,7 @@ int amdgpu_device_ip_set_clockgating_state(void *dev, /** * amdgpu_device_ip_set_powergating_state - set the PG state * - * @adev: amdgpu_device pointer + * @dev: amdgpu_device pointer * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) * @state: powergating state (gate or ungate) * @@ -1221,7 +1221,7 @@ bool amdgpu_device_ip_is_idle(struct amdgpu_device *adev, * amdgpu_device_ip_get_ip_block - get a hw IP pointer * * @adev: amdgpu_device pointer - * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) + * @type: Type of hardware IP (SMU, GFX, UVD, etc.) * * Returns a pointer to the hardware IP block structure * if it exists for the asic, otherwise NULL. @@ -2229,7 +2229,7 @@ bool amdgpu_device_has_dc_support(struct amdgpu_device *adev) * amdgpu_device_init - initialize the driver * * @adev: amdgpu_device pointer - * @pdev: drm dev pointer + * @ddev: drm dev pointer * @pdev: pci dev pointer * @flags: driver flags * @@ -2602,8 +2602,9 @@ void amdgpu_device_fini(struct amdgpu_device *adev) /** * amdgpu_device_suspend - initiate device suspend * - * @pdev: drm dev pointer - * @state: suspend state + * @dev: drm dev pointer + * @suspend: suspend state + * @fbcon : notify the fbdev of suspend * * Puts the hw in the suspend state (all asics). * Returns 0 for success or an error on failure. @@ -2701,7 +2702,9 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) /** * amdgpu_device_resume - initiate device resume * - * @pdev: drm dev pointer + * @dev: drm dev pointer + * @resume: resume state + * @fbcon : notify the fbdev of resume * * Bring the hw back to operating state (all asics). * Returns 0 for success or an error on failure. @@ -3164,6 +3167,7 @@ static int amdgpu_device_reset(struct amdgpu_device *adev) * amdgpu_device_reset_sriov - reset ASIC for SR-IOV vf * * @adev: amdgpu device pointer + * @from_hypervisor: request from hypervisor * * do VF FLR and reinitialize Asic * return 0 means successed otherwise failed @@ -3211,7 +3215,7 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, * * @adev: amdgpu device pointer * @job: which job trigger hang - * @force forces reset regardless of amdgpu_gpu_recovery + * @force: forces reset regardless of amdgpu_gpu_recovery * * Attempt to reset the GPU if it has hung (all asics). * Returns 0 for success or an error on failure. diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c index 72a3e8c68876..a365ea2383d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c @@ -58,7 +58,8 @@ * * @adev: amdgpu device pointer * @mm: process address space - * @mn: MMU notifier structur + * @mn: MMU notifier structure + * @type: type of MMU notifier * @work: destruction work item * @node: hash table node to find structure by adev and mn * @lock: rw semaphore protecting the notifier nodes @@ -266,7 +267,7 @@ static void amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn, * amdgpu_mn_invalidate_range_start_hsa - callback to notify about mm change * * @mn: our notifier - * @mn: the mm this callback is about + * @mm: the mm this callback is about * @start: start of updated range * @end: end of updated range * From fe61a2f1a57fea5d7b3d27d019fa67e1bc5b7079 Mon Sep 17 00:00:00 2001 From: Mikita Lipski Date: Wed, 4 Jul 2018 09:27:02 -0400 Subject: [PATCH 130/133] drm/amd/display: adding ycbcr420 pixel encoding for hdmi [why] HDMI EDID's VSDB contains spectial timings for specifically YCbCr 4:2:0 colour space. In those cases we need to verify if the mode provided is one of the special ones has to use YCbCr 4:2:0 pixel encoding for display info. [how] Verify if the mode is using specific ycbcr420 colour space with the help of DRM helper function and assign the mode to use ycbcr420 pixel encoding. Signed-off-by: Mikita Lipski Tested-by: Mike Lothian Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 74683071fa81..1386c857546d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2184,6 +2184,7 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream, const struct drm_connector *connector) { struct dc_crtc_timing *timing_out = &stream->timing; + const struct drm_display_info *info = &connector->display_info; memset(timing_out, 0, sizeof(struct dc_crtc_timing)); @@ -2192,8 +2193,10 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream, timing_out->v_border_top = 0; timing_out->v_border_bottom = 0; /* TODO: un-hardcode */ - - if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB444) + if (drm_mode_is_420_only(info, mode_in) + && stream->sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) + timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420; + else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB444) && stream->sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444; else From 400443e894c5a7f63f3ace3664640ec3ea4e1585 Mon Sep 17 00:00:00 2001 From: Mikita Lipski Date: Tue, 3 Jul 2018 09:42:51 -0400 Subject: [PATCH 131/133] drm/amd/display: add a check for display depth validity [why] HDMI 2.0 fails to validate 4K@60 timing with 10 bpc [how] Adding a helper function that would verify if the display depth assigned would pass a bandwidth validation. Drop the display depth by one level till calculated pixel clk is lower than maximum TMDS clk. Bugzilla: https://bugs.freedesktop.org/106959 Signed-off-by: Mikita Lipski Tested-by: Mike Lothian Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) 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 1386c857546d..ca017c1dd4da 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2176,6 +2176,46 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing) return color_space; } +static void reduce_mode_colour_depth(struct dc_crtc_timing *timing_out) +{ + if (timing_out->display_color_depth <= COLOR_DEPTH_888) + return; + + timing_out->display_color_depth--; +} + +static void adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_out, + const struct drm_display_info *info) +{ + int normalized_clk; + if (timing_out->display_color_depth <= COLOR_DEPTH_888) + return; + do { + normalized_clk = timing_out->pix_clk_khz; + /* YCbCr 4:2:0 requires additional adjustment of 1/2 */ + if (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420) + normalized_clk /= 2; + /* Adjusting pix clock following on HDMI spec based on colour depth */ + switch (timing_out->display_color_depth) { + case COLOR_DEPTH_101010: + normalized_clk = (normalized_clk * 30) / 24; + break; + case COLOR_DEPTH_121212: + normalized_clk = (normalized_clk * 36) / 24; + break; + case COLOR_DEPTH_161616: + normalized_clk = (normalized_clk * 48) / 24; + break; + default: + return; + } + if (normalized_clk <= info->max_tmds_clock) + return; + reduce_mode_colour_depth(timing_out); + + } while (timing_out->display_color_depth > COLOR_DEPTH_888); + +} /*****************************************************************************/ static void @@ -2232,6 +2272,8 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream, stream->out_transfer_func->type = TF_TYPE_PREDEFINED; stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB; + if (stream->sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) + adjust_colour_depth_from_display_info(timing_out, info); } static void fill_audio_info(struct audio_info *audio_info, From 8405cf39e8bd034be29971342fca49b01e772da2 Mon Sep 17 00:00:00 2001 From: Sonny Jiang Date: Tue, 26 Jun 2018 15:48:34 -0400 Subject: [PATCH 132/133] drm/amdgpu: update documentation for amdgpu_drv.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sonny Jiang Acked-by: Junwei Zhang Acked-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- Documentation/gpu/amdgpu.rst | 7 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 232 +++++++++++++++++++++++- 2 files changed, 232 insertions(+), 7 deletions(-) diff --git a/Documentation/gpu/amdgpu.rst b/Documentation/gpu/amdgpu.rst index 765c2a32938f..a740e491dfcc 100644 --- a/Documentation/gpu/amdgpu.rst +++ b/Documentation/gpu/amdgpu.rst @@ -5,6 +5,13 @@ The drm/amdgpu driver supports all AMD Radeon GPUs based on the Graphics Core Next (GCN) architecture. +Module Parameters +================= + +The amdgpu driver supports the following module parameters: + +.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c + Core Driver Infrastructure ========================== diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 963578c34c47..06aede194bf8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -1,10 +1,3 @@ -/** - * \file amdgpu_drv.c - * AMD Amdgpu driver - * - * \author Gareth Hughes - */ - /* * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. @@ -136,102 +129,239 @@ int amdgpu_gpu_recovery = -1; /* auto */ int amdgpu_emu_mode = 0; uint amdgpu_smu_memory_pool_size = 0; +/** + * DOC: vramlimit (int) + * Restrict the total amount of VRAM in MiB for testing. The default is 0 (Use full VRAM). + */ MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes"); module_param_named(vramlimit, amdgpu_vram_limit, int, 0600); +/** + * DOC: vis_vramlimit (int) + * Restrict the amount of CPU visible VRAM in MiB for testing. The default is 0 (Use full CPU visible VRAM). + */ MODULE_PARM_DESC(vis_vramlimit, "Restrict visible VRAM for testing, in megabytes"); module_param_named(vis_vramlimit, amdgpu_vis_vram_limit, int, 0444); +/** + * DOC: gartsize (uint) + * Restrict the size of GART in Mib (32, 64, etc.) for testing. The default is -1 (The size depends on asic). + */ MODULE_PARM_DESC(gartsize, "Size of GART to setup in megabytes (32, 64, etc., -1=auto)"); module_param_named(gartsize, amdgpu_gart_size, uint, 0600); +/** + * DOC: gttsize (int) + * Restrict the size of GTT domain in MiB for testing. The default is -1 (It's VRAM size if 3GB < VRAM < 3/4 RAM, + * otherwise 3/4 RAM size). + */ MODULE_PARM_DESC(gttsize, "Size of the GTT domain in megabytes (-1 = auto)"); module_param_named(gttsize, amdgpu_gtt_size, int, 0600); +/** + * DOC: moverate (int) + * Set maximum buffer migration rate in MB/s. The default is -1 (8 MB/s). + */ MODULE_PARM_DESC(moverate, "Maximum buffer migration rate in MB/s. (32, 64, etc., -1=auto, 0=1=disabled)"); module_param_named(moverate, amdgpu_moverate, int, 0600); +/** + * DOC: benchmark (int) + * Run benchmarks. The default is 0 (Skip benchmarks). + */ MODULE_PARM_DESC(benchmark, "Run benchmark"); module_param_named(benchmark, amdgpu_benchmarking, int, 0444); +/** + * DOC: test (int) + * Test BO GTT->VRAM and VRAM->GTT GPU copies. The default is 0 (Skip test, only set 1 to run test). + */ MODULE_PARM_DESC(test, "Run tests"); module_param_named(test, amdgpu_testing, int, 0444); +/** + * DOC: audio (int) + * Set HDMI/DPAudio. Only affects non-DC display handling. The default is -1 (Enabled), set 0 to disabled it. + */ MODULE_PARM_DESC(audio, "Audio enable (-1 = auto, 0 = disable, 1 = enable)"); module_param_named(audio, amdgpu_audio, int, 0444); +/** + * DOC: disp_priority (int) + * Set display Priority (1 = normal, 2 = high). Only affects non-DC display handling. The default is 0 (auto). + */ MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)"); module_param_named(disp_priority, amdgpu_disp_priority, int, 0444); +/** + * DOC: hw_i2c (int) + * To enable hw i2c engine. Only affects non-DC display handling. The default is 0 (Disabled). + */ MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)"); module_param_named(hw_i2c, amdgpu_hw_i2c, int, 0444); +/** + * DOC: pcie_gen2 (int) + * To disable PCIE Gen2/3 mode (0 = disable, 1 = enable). The default is -1 (auto, enabled). + */ MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (-1 = auto, 0 = disable, 1 = enable)"); module_param_named(pcie_gen2, amdgpu_pcie_gen2, int, 0444); +/** + * DOC: msi (int) + * To disable Message Signaled Interrupts (MSI) functionality (1 = enable, 0 = disable). The default is -1 (auto, enabled). + */ MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)"); module_param_named(msi, amdgpu_msi, int, 0444); +/** + * DOC: lockup_timeout (int) + * Set GPU scheduler timeout value in ms. Value 0 is invalidated, will be adjusted to 10000. + * Negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET). The default is 10000. + */ MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms > 0 (default 10000)"); module_param_named(lockup_timeout, amdgpu_lockup_timeout, int, 0444); +/** + * DOC: dpm (int) + * Override for dynamic power management setting (1 = enable, 0 = disable). The default is -1 (auto). + */ MODULE_PARM_DESC(dpm, "DPM support (1 = enable, 0 = disable, -1 = auto)"); module_param_named(dpm, amdgpu_dpm, int, 0444); +/** + * DOC: fw_load_type (int) + * Set different firmware loading type for debugging (0 = direct, 1 = SMU, 2 = PSP). The default is -1 (auto). + */ MODULE_PARM_DESC(fw_load_type, "firmware loading type (0 = direct, 1 = SMU, 2 = PSP, -1 = auto)"); module_param_named(fw_load_type, amdgpu_fw_load_type, int, 0444); +/** + * DOC: aspm (int) + * To disable ASPM (1 = enable, 0 = disable). The default is -1 (auto, enabled). + */ MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)"); module_param_named(aspm, amdgpu_aspm, int, 0444); +/** + * DOC: runpm (int) + * Override for runtime power management control for dGPUs in PX/HG laptops. The amdgpu driver can dynamically power down + * the dGPU on PX/HG laptops when it is idle. The default is -1 (auto enable). Setting the value to 0 disables this functionality. + */ MODULE_PARM_DESC(runpm, "PX runtime pm (1 = force enable, 0 = disable, -1 = PX only default)"); module_param_named(runpm, amdgpu_runtime_pm, int, 0444); +/** + * DOC: ip_block_mask (uint) + * Override what IP blocks are enabled on the GPU. Each GPU is a collection of IP blocks (gfx, display, video, etc.). + * Use this parameter to disable specific blocks. Note that the IP blocks do not have a fixed index. Some asics may not have + * some IPs or may include multiple instances of an IP so the ordering various from asic to asic. See the driver output in + * the kernel log for the list of IPs on the asic. The default is 0xffffffff (enable all blocks on a device). + */ MODULE_PARM_DESC(ip_block_mask, "IP Block Mask (all blocks enabled (default))"); module_param_named(ip_block_mask, amdgpu_ip_block_mask, uint, 0444); +/** + * DOC: bapm (int) + * Bidirectional Application Power Management (BAPM) used to dynamically share TDP between CPU and GPU. Set value 0 to disable it. + * The default -1 (auto, enabled) + */ MODULE_PARM_DESC(bapm, "BAPM support (1 = enable, 0 = disable, -1 = auto)"); module_param_named(bapm, amdgpu_bapm, int, 0444); +/** + * DOC: deep_color (int) + * Set 1 to enable Deep Color support. Only affects non-DC display handling. The default is 0 (disabled). + */ MODULE_PARM_DESC(deep_color, "Deep Color support (1 = enable, 0 = disable (default))"); module_param_named(deep_color, amdgpu_deep_color, int, 0444); +/** + * DOC: vm_size (int) + * Override the size of the GPU's per client virtual address space in GiB. The default is -1 (automatic for each asic). + */ MODULE_PARM_DESC(vm_size, "VM address space size in gigabytes (default 64GB)"); module_param_named(vm_size, amdgpu_vm_size, int, 0444); +/** + * DOC: vm_fragment_size (int) + * Override VM fragment size in bits (4, 5, etc. 4 = 64K, 9 = 2M). The default is -1 (automatic for each asic). + */ MODULE_PARM_DESC(vm_fragment_size, "VM fragment size in bits (4, 5, etc. 4 = 64K (default), Max 9 = 2M)"); module_param_named(vm_fragment_size, amdgpu_vm_fragment_size, int, 0444); +/** + * DOC: vm_block_size (int) + * Override VM page table size in bits (default depending on vm_size and hw setup). The default is -1 (automatic for each asic). + */ MODULE_PARM_DESC(vm_block_size, "VM page table size in bits (default depending on vm_size)"); module_param_named(vm_block_size, amdgpu_vm_block_size, int, 0444); +/** + * DOC: vm_fault_stop (int) + * Stop on VM fault for debugging (0 = never, 1 = print first, 2 = always). The default is 0 (No stop). + */ MODULE_PARM_DESC(vm_fault_stop, "Stop on VM fault (0 = never (default), 1 = print first, 2 = always)"); module_param_named(vm_fault_stop, amdgpu_vm_fault_stop, int, 0444); +/** + * DOC: vm_debug (int) + * Debug VM handling (0 = disabled, 1 = enabled). The default is 0 (Disabled). + */ MODULE_PARM_DESC(vm_debug, "Debug VM handling (0 = disabled (default), 1 = enabled)"); module_param_named(vm_debug, amdgpu_vm_debug, int, 0644); +/** + * DOC: vm_update_mode (int) + * Override VM update mode. VM updated by using CPU (0 = never, 1 = Graphics only, 2 = Compute only, 3 = Both). The default + * is -1 (Only in large BAR(LB) systems Compute VM tables will be updated by CPU, otherwise 0, never). + */ MODULE_PARM_DESC(vm_update_mode, "VM update using CPU (0 = never (default except for large BAR(LB)), 1 = Graphics only, 2 = Compute only (default for LB), 3 = Both"); module_param_named(vm_update_mode, amdgpu_vm_update_mode, int, 0444); +/** + * DOC: vram_page_split (int) + * Override the number of pages after we split VRAM allocations (default 512, -1 = disable). The default is 512. + */ MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 512, -1 = disable)"); module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444); +/** + * DOC: exp_hw_support (int) + * Enable experimental hw support (1 = enable). The default is 0 (disabled). + */ MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))"); module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444); +/** + * DOC: dc (int) + * Disable/Enable Display Core driver for debugging (1 = enable, 0 = disable). The default is -1 (automatic for each asic). + */ MODULE_PARM_DESC(dc, "Display Core driver (1 = enable, 0 = disable, -1 = auto (default))"); module_param_named(dc, amdgpu_dc, int, 0444); MODULE_PARM_DESC(dc_log, "Display Core Log Level (0 = minimal (default), 1 = chatty"); module_param_named(dc_log, amdgpu_dc_log, int, 0444); +/** + * DOC: sched_jobs (int) + * Override the max number of jobs supported in the sw queue. The default is 32. + */ MODULE_PARM_DESC(sched_jobs, "the max number of jobs supported in the sw queue (default 32)"); module_param_named(sched_jobs, amdgpu_sched_jobs, int, 0444); +/** + * DOC: sched_hw_submission (int) + * Override the max number of HW submissions. The default is 2. + */ MODULE_PARM_DESC(sched_hw_submission, "the max number of HW submissions (default 2)"); module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444); +/** + * DOC: ppfeaturemask (uint) + * Override power features enabled. See enum PP_FEATURE_MASK in drivers/gpu/drm/amd/include/amd_shared.h. + * The default is the current set of stable power features. + */ MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))"); module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, uint, 0444); @@ -241,58 +371,135 @@ module_param_named(no_evict, amdgpu_no_evict, int, 0444); MODULE_PARM_DESC(direct_gma_size, "Direct GMA size in megabytes (max 96MB)"); module_param_named(direct_gma_size, amdgpu_direct_gma_size, int, 0444); +/** + * DOC: pcie_gen_cap (uint) + * Override PCIE gen speed capabilities. See the CAIL flags in drivers/gpu/drm/amd/include/amd_pcie.h. + * The default is 0 (automatic for each asic). + */ MODULE_PARM_DESC(pcie_gen_cap, "PCIE Gen Caps (0: autodetect (default))"); module_param_named(pcie_gen_cap, amdgpu_pcie_gen_cap, uint, 0444); +/** + * DOC: pcie_lane_cap (uint) + * Override PCIE lanes capabilities. See the CAIL flags in drivers/gpu/drm/amd/include/amd_pcie.h. + * The default is 0 (automatic for each asic). + */ MODULE_PARM_DESC(pcie_lane_cap, "PCIE Lane Caps (0: autodetect (default))"); module_param_named(pcie_lane_cap, amdgpu_pcie_lane_cap, uint, 0444); +/** + * DOC: cg_mask (uint) + * Override Clockgating features enabled on GPU (0 = disable clock gating). See the AMD_CG_SUPPORT flags in + * drivers/gpu/drm/amd/include/amd_shared.h. The default is 0xffffffff (all enabled). + */ MODULE_PARM_DESC(cg_mask, "Clockgating flags mask (0 = disable clock gating)"); module_param_named(cg_mask, amdgpu_cg_mask, uint, 0444); +/** + * DOC: pg_mask (uint) + * Override Powergating features enabled on GPU (0 = disable power gating). See the AMD_PG_SUPPORT flags in + * drivers/gpu/drm/amd/include/amd_shared.h. The default is 0xffffffff (all enabled). + */ MODULE_PARM_DESC(pg_mask, "Powergating flags mask (0 = disable power gating)"); module_param_named(pg_mask, amdgpu_pg_mask, uint, 0444); +/** + * DOC: sdma_phase_quantum (uint) + * Override SDMA context switch phase quantum (x 1K GPU clock cycles, 0 = no change). The default is 32. + */ MODULE_PARM_DESC(sdma_phase_quantum, "SDMA context switch phase quantum (x 1K GPU clock cycles, 0 = no change (default 32))"); module_param_named(sdma_phase_quantum, amdgpu_sdma_phase_quantum, uint, 0444); +/** + * DOC: disable_cu (charp) + * Set to disable CUs (It's set like se.sh.cu,...). The default is NULL. + */ MODULE_PARM_DESC(disable_cu, "Disable CUs (se.sh.cu,...)"); module_param_named(disable_cu, amdgpu_disable_cu, charp, 0444); +/** + * DOC: virtual_display (charp) + * Set to enable virtual display feature. This feature provides a virtual display hardware on headless boards + * or in virtualized environments. It will be set like xxxx:xx:xx.x,x;xxxx:xx:xx.x,x. It's the pci address of + * the device, plus the number of crtcs to expose. E.g., 0000:26:00.0,4 would enable 4 virtual crtcs on the pci + * device at 26:00.0. The default is NULL. + */ MODULE_PARM_DESC(virtual_display, "Enable virtual display feature (the virtual_display will be set like xxxx:xx:xx.x,x;xxxx:xx:xx.x,x)"); module_param_named(virtual_display, amdgpu_virtual_display, charp, 0444); +/** + * DOC: ngg (int) + * Set to enable Next Generation Graphics (1 = enable). The default is 0 (disabled). + */ MODULE_PARM_DESC(ngg, "Next Generation Graphics (1 = enable, 0 = disable(default depending on gfx))"); module_param_named(ngg, amdgpu_ngg, int, 0444); +/** + * DOC: prim_buf_per_se (int) + * Override the size of Primitive Buffer per Shader Engine in Byte. The default is 0 (depending on gfx). + */ MODULE_PARM_DESC(prim_buf_per_se, "the size of Primitive Buffer per Shader Engine (default depending on gfx)"); module_param_named(prim_buf_per_se, amdgpu_prim_buf_per_se, int, 0444); +/** + * DOC: pos_buf_per_se (int) + * Override the size of Position Buffer per Shader Engine in Byte. The default is 0 (depending on gfx). + */ MODULE_PARM_DESC(pos_buf_per_se, "the size of Position Buffer per Shader Engine (default depending on gfx)"); module_param_named(pos_buf_per_se, amdgpu_pos_buf_per_se, int, 0444); +/** + * DOC: cntl_sb_buf_per_se (int) + * Override the size of Control Sideband per Shader Engine in Byte. The default is 0 (depending on gfx). + */ MODULE_PARM_DESC(cntl_sb_buf_per_se, "the size of Control Sideband per Shader Engine (default depending on gfx)"); module_param_named(cntl_sb_buf_per_se, amdgpu_cntl_sb_buf_per_se, int, 0444); +/** + * DOC: param_buf_per_se (int) + * Override the size of Off-Chip Pramater Cache per Shader Engine in Byte. The default is 0 (depending on gfx). + */ MODULE_PARM_DESC(param_buf_per_se, "the size of Off-Chip Pramater Cache per Shader Engine (default depending on gfx)"); module_param_named(param_buf_per_se, amdgpu_param_buf_per_se, int, 0444); +/** + * DOC: job_hang_limit (int) + * Set how much time allow a job hang and not drop it. The default is 0. + */ MODULE_PARM_DESC(job_hang_limit, "how much time allow a job hang and not drop it (default 0)"); module_param_named(job_hang_limit, amdgpu_job_hang_limit, int ,0444); +/** + * DOC: lbpw (int) + * Override Load Balancing Per Watt (LBPW) support (1 = enable, 0 = disable). The default is -1 (auto, enabled). + */ MODULE_PARM_DESC(lbpw, "Load Balancing Per Watt (LBPW) support (1 = enable, 0 = disable, -1 = auto)"); module_param_named(lbpw, amdgpu_lbpw, int, 0444); MODULE_PARM_DESC(compute_multipipe, "Force compute queues to be spread across pipes (1 = enable, 0 = disable, -1 = auto)"); module_param_named(compute_multipipe, amdgpu_compute_multipipe, int, 0444); +/** + * DOC: gpu_recovery (int) + * Set to enable GPU recovery mechanism (1 = enable, 0 = disable). The default is -1 (auto, disabled except SRIOV). + */ MODULE_PARM_DESC(gpu_recovery, "Enable GPU recovery mechanism, (1 = enable, 0 = disable, -1 = auto)"); module_param_named(gpu_recovery, amdgpu_gpu_recovery, int, 0444); +/** + * DOC: emu_mode (int) + * Set value 1 to enable emulation mode. This is only needed when running on an emulator. The default is 0 (disabled). + */ MODULE_PARM_DESC(emu_mode, "Emulation mode, (1 = enable, 0 = disable)"); module_param_named(emu_mode, amdgpu_emu_mode, int, 0444); +/** + * DOC: si_support (int) + * Set SI support driver. This parameter works after set config CONFIG_DRM_AMDGPU_SI. For SI asic, when radeon driver is enabled, + * set value 0 to use radeon driver, while set value 1 to use amdgpu driver. The default is using radeon driver when it available, + * otherwise using amdgpu driver. + */ #ifdef CONFIG_DRM_AMDGPU_SI #if defined(CONFIG_DRM_RADEON) || defined(CONFIG_DRM_RADEON_MODULE) @@ -306,6 +513,12 @@ MODULE_PARM_DESC(si_support, "SI support (1 = enabled (default), 0 = disabled)") module_param_named(si_support, amdgpu_si_support, int, 0444); #endif +/** + * DOC: cik_support (int) + * Set CIK support driver. This parameter works after set config CONFIG_DRM_AMDGPU_CIK. For CIK asic, when radeon driver is enabled, + * set value 0 to use radeon driver, while set value 1 to use amdgpu driver. The default is using radeon driver when it available, + * otherwise using amdgpu driver. + */ #ifdef CONFIG_DRM_AMDGPU_CIK #if defined(CONFIG_DRM_RADEON) || defined(CONFIG_DRM_RADEON_MODULE) @@ -319,6 +532,11 @@ MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled) module_param_named(cik_support, amdgpu_cik_support, int, 0444); #endif +/** + * DOC: smu_memory_pool_size (uint) + * It is used to reserve gtt for smu debug usage, setting value 0 to disable it. The actual size is value * 256MiB. + * E.g. 0x1 = 256Mbyte, 0x2 = 512Mbyte, 0x4 = 1 Gbyte, 0x8 = 2GByte. The default is 0 (disabled). + */ MODULE_PARM_DESC(smu_memory_pool_size, "reserve gtt for smu debug usage, 0 = disable," "0x1 = 256Mbyte, 0x2 = 512Mbyte, 0x4 = 1 Gbyte, 0x8 = 2GByte"); From 43911fb68b19f7c37ab69eff8e6a3c1370bc0cb5 Mon Sep 17 00:00:00 2001 From: Darren Powell Date: Wed, 27 Jun 2018 17:05:20 -0400 Subject: [PATCH 133/133] drm/amd: Add sphinx documentation for amd_ip_funcs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Darren Powell Reviewed-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/amd_shared.h | 45 ++++++++++++++---------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index d6f487497397..265621d8945c 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h @@ -131,45 +131,54 @@ enum PP_FEATURE_MASK { PP_STUTTER_MODE = 0x20000, }; +/** + * struct amd_ip_funcs - general hooks for managing amdgpu IP Blocks + */ struct amd_ip_funcs { - /* Name of IP block */ + /** @name: Name of IP block */ char *name; - /* sets up early driver state (pre sw_init), does not configure hw - Optional */ + /** + * @early_init: + * + * sets up early driver state (pre sw_init), + * does not configure hw - Optional + */ int (*early_init)(void *handle); - /* sets up late driver/hw state (post hw_init) - Optional */ + /** @late_init: sets up late driver/hw state (post hw_init) - Optional */ int (*late_init)(void *handle); - /* sets up driver state, does not configure hw */ + /** @sw_init: sets up driver state, does not configure hw */ int (*sw_init)(void *handle); - /* tears down driver state, does not configure hw */ + /** @sw_fini: tears down driver state, does not configure hw */ int (*sw_fini)(void *handle); - /* sets up the hw state */ + /** @hw_init: sets up the hw state */ int (*hw_init)(void *handle); - /* tears down the hw state */ + /** @hw_fini: tears down the hw state */ int (*hw_fini)(void *handle); + /** @late_fini: final cleanup */ void (*late_fini)(void *handle); - /* handles IP specific hw/sw changes for suspend */ + /** @suspend: handles IP specific hw/sw changes for suspend */ int (*suspend)(void *handle); - /* handles IP specific hw/sw changes for resume */ + /** @resume: handles IP specific hw/sw changes for resume */ int (*resume)(void *handle); - /* returns current IP block idle status */ + /** @is_idle: returns current IP block idle status */ bool (*is_idle)(void *handle); - /* poll for idle */ + /** @wait_for_idle: poll for idle */ int (*wait_for_idle)(void *handle); - /* check soft reset the IP block */ + /** @check_soft_reset: check soft reset the IP block */ bool (*check_soft_reset)(void *handle); - /* pre soft reset the IP block */ + /** @pre_soft_reset: pre soft reset the IP block */ int (*pre_soft_reset)(void *handle); - /* soft reset the IP block */ + /** @soft_reset: soft reset the IP block */ int (*soft_reset)(void *handle); - /* post soft reset the IP block */ + /** @post_soft_reset: post soft reset the IP block */ int (*post_soft_reset)(void *handle); - /* enable/disable cg for the IP block */ + /** @set_clockgating_state: enable/disable cg for the IP block */ int (*set_clockgating_state)(void *handle, enum amd_clockgating_state state); - /* enable/disable pg for the IP block */ + /** @set_powergating_state: enable/disable pg for the IP block */ int (*set_powergating_state)(void *handle, enum amd_powergating_state state); - /* get current clockgating status */ + /** @get_clockgating_state: get current clockgating status */ void (*get_clockgating_state)(void *handle, u32 *flags); };